You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-10 22:11:50 +02:00
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
This commit is contained in:
@@ -157,6 +157,8 @@ packages/app-desktop/app.reducer.js
|
||||
packages/app-desktop/app.js
|
||||
packages/app-desktop/bridge.js
|
||||
packages/app-desktop/checkForUpdates.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.test.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.js
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyToClipboard.js
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
@@ -197,6 +199,7 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||
packages/app-desktop/gui/ConversionNotification/ConversionNotification.js
|
||||
packages/app-desktop/gui/Dialog.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
@@ -1151,6 +1154,8 @@ packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/clipperUtils.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.test.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.js
|
||||
packages/lib/commands/deleteNote.js
|
||||
packages/lib/commands/historyBackward.js
|
||||
packages/lib/commands/historyForward.js
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -130,6 +130,8 @@ packages/app-desktop/app.reducer.js
|
||||
packages/app-desktop/app.js
|
||||
packages/app-desktop/bridge.js
|
||||
packages/app-desktop/checkForUpdates.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.test.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.js
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyToClipboard.js
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
@@ -170,6 +172,7 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||
packages/app-desktop/gui/ConversionNotification/ConversionNotification.js
|
||||
packages/app-desktop/gui/Dialog.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
@@ -1124,6 +1127,8 @@ packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/clipperUtils.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.test.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.js
|
||||
packages/lib/commands/deleteNote.js
|
||||
packages/lib/commands/historyBackward.js
|
||||
packages/lib/commands/historyForward.js
|
||||
|
96
packages/app-desktop/commands/convertNoteToMarkdown.test.ts
Normal file
96
packages/app-desktop/commands/convertNoteToMarkdown.test.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as convertHtmlToMarkdown from './convertNoteToMarkdown';
|
||||
import { AppState, createAppDefaultState } from '../app.reducer';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import { NoteEntity } from '@joplin/lib/services/database/types';
|
||||
|
||||
describe('convertNoteToMarkdown', () => {
|
||||
let state: AppState = undefined;
|
||||
|
||||
beforeEach(async () => {
|
||||
state = createAppDefaultState({});
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
});
|
||||
|
||||
it('should set the original note to be trashed', async () => {
|
||||
const folder = await Folder.save({ title: 'test_folder' });
|
||||
const htmlNote = await Note.save({ title: 'test', body: '<p>Hello</p>', parent_id: folder.id, markup_language: MarkupLanguage.Html });
|
||||
state.selectedNoteIds = [htmlNote.id];
|
||||
|
||||
await convertHtmlToMarkdown.runtime().execute({ state, dispatch: () => {} });
|
||||
|
||||
const refreshedNote = await Note.load(htmlNote.id);
|
||||
|
||||
expect(htmlNote.deleted_time).toBe(0);
|
||||
expect(refreshedNote.deleted_time).not.toBe(0);
|
||||
});
|
||||
|
||||
it('should recreate a new note that is a clone of the original', async () => {
|
||||
let noteConvertedToMarkdownId = '';
|
||||
const dispatchFn = jest.fn()
|
||||
.mockImplementationOnce(() => {})
|
||||
.mockImplementationOnce(action => {
|
||||
noteConvertedToMarkdownId = action.id;
|
||||
});
|
||||
|
||||
const folder = await Folder.save({ title: 'test_folder' });
|
||||
const htmlNoteProperties = {
|
||||
title: 'test',
|
||||
body: '<p>Hello</p>',
|
||||
parent_id: folder.id,
|
||||
markup_language: MarkupLanguage.Html,
|
||||
author: 'test-author',
|
||||
is_todo: 1,
|
||||
todo_completed: 1,
|
||||
};
|
||||
const htmlNote = await Note.save(htmlNoteProperties);
|
||||
state.selectedNoteIds = [htmlNote.id];
|
||||
|
||||
await convertHtmlToMarkdown.runtime().execute({ state, dispatch: dispatchFn });
|
||||
|
||||
expect(dispatchFn).toHaveBeenCalledTimes(2);
|
||||
expect(noteConvertedToMarkdownId).not.toBe('');
|
||||
|
||||
const markdownNote = await Note.load(noteConvertedToMarkdownId);
|
||||
|
||||
const fields: (keyof NoteEntity)[] = ['parent_id', 'title', 'author', 'is_todo', 'todo_completed'];
|
||||
for (const field of fields) {
|
||||
expect(htmlNote[field]).toEqual(markdownNote[field]);
|
||||
}
|
||||
});
|
||||
|
||||
it('should generate action to trigger notification', async () => {
|
||||
let originalHtmlNoteId = '';
|
||||
let actionType = '';
|
||||
const dispatchFn = jest.fn()
|
||||
.mockImplementationOnce(action => {
|
||||
originalHtmlNoteId = action.value;
|
||||
actionType = action.type;
|
||||
})
|
||||
.mockImplementationOnce(() => {});
|
||||
|
||||
const folder = await Folder.save({ title: 'test_folder' });
|
||||
const htmlNoteProperties = {
|
||||
title: 'test',
|
||||
body: '<p>Hello</p>',
|
||||
parent_id: folder.id,
|
||||
markup_language: MarkupLanguage.Html,
|
||||
author: 'test-author',
|
||||
is_todo: 1,
|
||||
todo_completed: 1,
|
||||
};
|
||||
const htmlNote = await Note.save(htmlNoteProperties);
|
||||
state.selectedNoteIds = [htmlNote.id];
|
||||
|
||||
await convertHtmlToMarkdown.runtime().execute({ state, dispatch: dispatchFn });
|
||||
|
||||
expect(dispatchFn).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(originalHtmlNoteId).toBe(htmlNote.id);
|
||||
expect(actionType).toBe('NOTE_HTML_TO_MARKDOWN_DONE');
|
||||
});
|
||||
|
||||
});
|
52
packages/app-desktop/commands/convertNoteToMarkdown.ts
Normal file
52
packages/app-desktop/commands/convertNoteToMarkdown.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { stateUtils } from '@joplin/lib/reducer';
|
||||
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import { runtime as convertHtmlToMarkdown } from '@joplin/lib/commands/convertHtmlToMarkdown';
|
||||
import bridge from '../services/bridge';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'convertNoteToMarkdown',
|
||||
label: () => _('Convert note to Markdown'),
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext, noteId: string = null) => {
|
||||
noteId = noteId || stateUtils.selectedNoteId(context.state);
|
||||
|
||||
const note = await Note.load(noteId);
|
||||
|
||||
if (!note) return;
|
||||
|
||||
try {
|
||||
const markdownBody = await convertHtmlToMarkdown().execute(context, note.body);
|
||||
|
||||
const newNote = await Note.duplicate(note.id);
|
||||
|
||||
newNote.body = markdownBody;
|
||||
newNote.markup_language = MarkupLanguage.Markdown;
|
||||
|
||||
await Note.save(newNote);
|
||||
|
||||
await Note.delete(note.id, { toTrash: true });
|
||||
|
||||
context.dispatch({
|
||||
type: 'NOTE_HTML_TO_MARKDOWN_DONE',
|
||||
value: note.id,
|
||||
});
|
||||
|
||||
context.dispatch({
|
||||
type: 'NOTE_SELECT',
|
||||
id: newNote.id,
|
||||
});
|
||||
} catch (error) {
|
||||
bridge().showErrorMessageBox(_('Could not convert note to Markdown: %s', error.message));
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
enabledCondition: 'oneNoteSelected && noteIsHtml && !noteIsReadOnly',
|
||||
};
|
||||
};
|
@@ -1,4 +1,5 @@
|
||||
// AUTO-GENERATED using `gulp buildScriptIndexes`
|
||||
import * as convertNoteToMarkdown from './convertNoteToMarkdown';
|
||||
import * as copyDevCommand from './copyDevCommand';
|
||||
import * as copyToClipboard from './copyToClipboard';
|
||||
import * as editProfileConfig from './editProfileConfig';
|
||||
@@ -24,6 +25,7 @@ import * as toggleSafeMode from './toggleSafeMode';
|
||||
import * as toggleTabMovesFocus from './toggleTabMovesFocus';
|
||||
|
||||
const index: any[] = [
|
||||
convertNoteToMarkdown,
|
||||
copyDevCommand,
|
||||
copyToClipboard,
|
||||
editProfileConfig,
|
||||
|
@@ -0,0 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { Dispatch } from 'redux';
|
||||
import { PopupNotificationContext } from '../PopupNotification/PopupNotificationProvider';
|
||||
import { NotificationType } from '../PopupNotification/types';
|
||||
|
||||
interface Props {
|
||||
noteId: string;
|
||||
dispatch: Dispatch;
|
||||
}
|
||||
|
||||
export default (props: Props) => {
|
||||
const popupManager = useContext(PopupNotificationContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.noteId || props.noteId === '') return;
|
||||
|
||||
props.dispatch({ type: 'NOTE_HTML_TO_MARKDOWN_DONE', value: '' });
|
||||
|
||||
const notification = popupManager.createPopup(() => (
|
||||
<div>{_('The note has been converted to Markdown and the original note has been moved to the trash')}</div>
|
||||
), { type: NotificationType.Success });
|
||||
notification.scheduleDismiss();
|
||||
}, [props.dispatch, popupManager, props.noteId]);
|
||||
|
||||
return <div style={{ display: 'none' }}/>;
|
||||
};
|
@@ -38,12 +38,14 @@ import restart from '../services/restart';
|
||||
import { connect } from 'react-redux';
|
||||
import { NoteListColumns } from '@joplin/lib/services/plugins/api/noteListType';
|
||||
import validateColumns from './NoteListHeader/utils/validateColumns';
|
||||
import ConversionNotification from './ConversionNotification/ConversionNotification';
|
||||
import TrashNotification from './TrashNotification/TrashNotification';
|
||||
import UpdateNotification from './UpdateNotification/UpdateNotification';
|
||||
import NoteEditor from './NoteEditor/NoteEditor';
|
||||
import PluginNotification from './PluginNotification/PluginNotification';
|
||||
import { Toast } from '@joplin/lib/services/plugins/api/types';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
import { Dispatch } from 'redux';
|
||||
|
||||
const ipcRenderer = require('electron').ipcRenderer;
|
||||
|
||||
@@ -84,6 +86,7 @@ interface Props {
|
||||
showInvalidJoplinCloudCredential: boolean;
|
||||
toast: Toast;
|
||||
shouldSwitchToAppleSiliconVersion: boolean;
|
||||
noteHtmlToMarkdownDone: string;
|
||||
}
|
||||
|
||||
interface ShareFolderDialogOptions {
|
||||
@@ -797,6 +800,10 @@ class MainScreenComponent extends React.Component<Props, State> {
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<ConversionNotification
|
||||
noteId={this.props.noteHtmlToMarkdownDone}
|
||||
dispatch={this.props.dispatch as Dispatch}
|
||||
/>
|
||||
<TrashNotification
|
||||
lastDeletion={this.props.lastDeletion}
|
||||
lastDeletionNotificationTime={this.props.lastDeletionNotificationTime}
|
||||
@@ -853,6 +860,7 @@ const mapStateToProps = (state: AppState) => {
|
||||
showInvalidJoplinCloudCredential: state.settings['sync.target'] === 10 && state.mustAuthenticate,
|
||||
toast: state.toast,
|
||||
shouldSwitchToAppleSiliconVersion: shim.isAppleSilicon() && process.arch !== 'arm64',
|
||||
noteHtmlToMarkdownDone: state.noteHtmlToMarkdownDone,
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -907,6 +907,7 @@ function useMenu(props: Props) {
|
||||
separator(),
|
||||
menuItemDic.setTags,
|
||||
menuItemDic.showShareNoteDialog,
|
||||
menuItemDic.convertNoteToMarkdown,
|
||||
separator(),
|
||||
menuItemDic.showNoteProperties,
|
||||
menuItemDic.showNoteContentProperties,
|
||||
|
@@ -466,6 +466,7 @@ function NoteEditorContent(props: NoteEditorProps) {
|
||||
// It is currently used to remember pdf scroll position for each attachments of each note uniquely.
|
||||
noteId: props.noteId,
|
||||
watchedNoteFiles: props.watchedNoteFiles,
|
||||
enableHtmlToMarkdownBanner: props.enableHtmlToMarkdownBanner,
|
||||
};
|
||||
|
||||
let editor = null;
|
||||
@@ -488,6 +489,17 @@ function NoteEditorContent(props: NoteEditorProps) {
|
||||
setShowRevisions(false);
|
||||
}, []);
|
||||
|
||||
const onBannerConvertItToMarkdown = useCallback(async (event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
event.preventDefault();
|
||||
if (!props.selectedNoteIds || props.selectedNoteIds.length === 0) return;
|
||||
await CommandService.instance().execute('convertNoteToMarkdown', props.selectedNoteIds[0]);
|
||||
}, [props.selectedNoteIds]);
|
||||
|
||||
const onHideBannerConvertItToMarkdown = async (event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
event.preventDefault();
|
||||
Setting.setValue('editor.enableHtmlToMarkdownBanner', false);
|
||||
};
|
||||
|
||||
const onBannerResourceClick = useCallback(async (event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
event.preventDefault();
|
||||
const resourceId = event.currentTarget.getAttribute('data-resource-id');
|
||||
@@ -632,9 +644,30 @@ function NoteEditorContent(props: NoteEditorProps) {
|
||||
|
||||
const theme = themeStyle(props.themeId);
|
||||
|
||||
function renderConvertHtmlToMarkdown(): React.ReactNode {
|
||||
if (!props.enableHtmlToMarkdownBanner) return null;
|
||||
|
||||
const note = props.notes.find(n => n.id === props.selectedNoteIds[0]);
|
||||
if (!note) return null;
|
||||
if (note.markup_language !== MarkupLanguage.Html) return null;
|
||||
|
||||
return (
|
||||
<div style={styles.resourceWatchBanner}>
|
||||
<p style={styles.resourceWatchBannerLine}>
|
||||
{_('This note is in HTML format. Convert it to Markdown to edit it more easily.')}
|
||||
|
||||
<a href="#" style={styles.resourceWatchBannerAction} onClick={onBannerConvertItToMarkdown}>{`${_('Convert it')}`}</a>
|
||||
{' / '}
|
||||
<a href="#" style={styles.resourceWatchBannerAction} onClick={onHideBannerConvertItToMarkdown}>{_('Don\'t show this message again')}</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={styles.root} onDragOver={onDragOver} onDrop={onDrop} ref={containerRef}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
|
||||
{renderConvertHtmlToMarkdown()}
|
||||
{renderResourceWatchingNotification()}
|
||||
{renderResourceInSearchResultsNotification()}
|
||||
<NoteTitleBar
|
||||
@@ -722,6 +755,7 @@ const mapStateToProps = (state: AppState, ownProps: ConnectProps) => {
|
||||
syncUserId: state.settings['sync.userId'],
|
||||
shareCacheSetting: state.settings['sync.shareCache'],
|
||||
searchResults: state.searchResults,
|
||||
enableHtmlToMarkdownBanner: state.settings['editor.enableHtmlToMarkdownBanner'],
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -69,6 +69,10 @@ export default function styles(props: NoteEditorProps) {
|
||||
marginTop: 0,
|
||||
marginBottom: 10,
|
||||
},
|
||||
resourceWatchBannerAction: {
|
||||
textDecoration: 'underline',
|
||||
color: theme.colorWarnUrl,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@ export interface NoteEditorProps {
|
||||
onTitleChange?: (title: string)=> void;
|
||||
bodyEditor: string;
|
||||
startupPluginsLoaded: boolean;
|
||||
enableHtmlToMarkdownBanner: boolean;
|
||||
}
|
||||
|
||||
export interface NoteBodyEditorRef {
|
||||
@@ -138,6 +139,7 @@ export interface NoteBodyEditorProps {
|
||||
noteId: string;
|
||||
useCustomPdfViewer: boolean;
|
||||
watchedNoteFiles: string[];
|
||||
enableHtmlToMarkdownBanner: boolean;
|
||||
}
|
||||
|
||||
export interface NoteBodyEditorPropsAndRef extends NoteBodyEditorProps {
|
||||
|
@@ -79,6 +79,7 @@ export default function() {
|
||||
'switchProfile3',
|
||||
'pasteAsText',
|
||||
'showNoteProperties',
|
||||
'convertNoteToMarkdown',
|
||||
'toggleEditors',
|
||||
];
|
||||
}
|
||||
|
30
packages/lib/commands/convertHtmlToMarkdown.test.ts
Normal file
30
packages/lib/commands/convertHtmlToMarkdown.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { runtime } from './convertHtmlToMarkdown';
|
||||
import { CommandContext } from '../services/CommandService';
|
||||
import { defaultState } from '../reducer';
|
||||
|
||||
const command = runtime();
|
||||
|
||||
const makeContext = (): CommandContext => {
|
||||
return {
|
||||
state: defaultState,
|
||||
dispatch: ()=>{},
|
||||
};
|
||||
};
|
||||
|
||||
describe('convertHtmlToMarkdown', () => {
|
||||
|
||||
it.each([
|
||||
['<b>test</b>', '**test**'],
|
||||
['<a href="https://joplin.org">Joplin</a>', '[Joplin](https://joplin.org)'],
|
||||
['<h1>Title</h1>\n<h2>Subtitle</h2>', '# Title\n\n## Subtitle'],
|
||||
['<ul><li>One</li><li>Two</li></ul>', '- One\n- Two'],
|
||||
['<p>First paragraph</p><p>This is the second paragraph</p>', 'First paragraph\n\nThis is the second paragraph'],
|
||||
['<p>A paragraph with <strong>bold</strong> and <em>italic</em></p>', 'A paragraph with **bold** and *italic*'],
|
||||
])('should turn HTML into Markdown', async (html, markdown) => {
|
||||
const context = makeContext();
|
||||
const result: string = await command.execute(context, html);
|
||||
|
||||
expect(result).toBe(markdown);
|
||||
});
|
||||
|
||||
});
|
22
packages/lib/commands/convertHtmlToMarkdown.ts
Normal file
22
packages/lib/commands/convertHtmlToMarkdown.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import HtmlToMd from '../HtmlToMd';
|
||||
import { CommandContext, CommandRuntime, CommandDeclaration } from '../services/CommandService';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'convertHtmlToMarkdown',
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (_context: CommandContext, html: string) => {
|
||||
const htmlToMdParser = new HtmlToMd();
|
||||
|
||||
const markdown = await htmlToMdParser.parse(`<div>${html}</div>`, {
|
||||
baseUrl: '',
|
||||
anchorNames: [],
|
||||
convertEmbeddedPdfsToLinks: true,
|
||||
});
|
||||
|
||||
return markdown;
|
||||
},
|
||||
};
|
||||
};
|
@@ -1,4 +1,5 @@
|
||||
// AUTO-GENERATED using `gulp buildScriptIndexes`
|
||||
import * as convertHtmlToMarkdown from './convertHtmlToMarkdown';
|
||||
import * as deleteNote from './deleteNote';
|
||||
import * as historyBackward from './historyBackward';
|
||||
import * as historyForward from './historyForward';
|
||||
@@ -12,6 +13,7 @@ import * as toggleAllFolders from './toggleAllFolders';
|
||||
import * as toggleEditorPlugin from './toggleEditorPlugin';
|
||||
|
||||
const index: any[] = [
|
||||
convertHtmlToMarkdown,
|
||||
deleteNote,
|
||||
historyBackward,
|
||||
historyForward,
|
||||
|
@@ -731,6 +731,17 @@ const builtInMetadata = (Setting: typeof SettingType) => {
|
||||
storage: SettingStorage.File,
|
||||
isGlobal: true,
|
||||
},
|
||||
'editor.enableHtmlToMarkdownBanner': {
|
||||
value: true,
|
||||
advanced: true,
|
||||
type: SettingItemType.Bool,
|
||||
public: true,
|
||||
section: 'note',
|
||||
appTypes: [AppType.Desktop],
|
||||
label: () => _('Enable HTML-to-Markdown conversion banner'),
|
||||
storage: SettingStorage.File,
|
||||
isGlobal: true,
|
||||
},
|
||||
'editor.pastePreserveColors': {
|
||||
value: false,
|
||||
type: SettingItemType.Bool,
|
||||
|
@@ -173,6 +173,7 @@ export interface State extends WindowState {
|
||||
editorNoteReloadTimeRequest: number;
|
||||
|
||||
allowSelectionInOtherFolders: boolean;
|
||||
noteHtmlToMarkdownDone: string;
|
||||
|
||||
// Extra reducer keys go here:
|
||||
pluginService: PluginServiceState;
|
||||
@@ -243,6 +244,7 @@ export const defaultState: State = {
|
||||
mustAuthenticate: false,
|
||||
allowSelectionInOtherFolders: false,
|
||||
editorNoteReloadTimeRequest: 0,
|
||||
noteHtmlToMarkdownDone: '',
|
||||
|
||||
pluginService: pluginServiceDefaultState,
|
||||
shareService: shareServiceDefaultState,
|
||||
@@ -1073,6 +1075,10 @@ const reducer = produce((draft: Draft<State> = defaultState, action: any) => {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'NOTE_HTML_TO_MARKDOWN_DONE':
|
||||
draft.noteHtmlToMarkdownDone = action.value;
|
||||
break;
|
||||
|
||||
case 'ITEMS_TRASHED':
|
||||
|
||||
draft.lastDeletion = {
|
||||
|
Reference in New Issue
Block a user