1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-12-26 23:38:08 +02:00

Compare commits

..

8 Commits

Author SHA1 Message Date
Laurent Cozic
b519d55abf Merge branch 'dev' into table_editor 2022-06-14 00:43:23 +01:00
Laurent Cozic
5a862443d8 Merge branch 'dev' into table_editor 2022-06-07 18:30:40 +01:00
Laurent
30e191663d Merge branch 'dev' into table_editor 2022-04-17 12:42:46 +01:00
Laurent
70cd2395fb Merge branch 'dev' into table_editor 2022-04-12 23:31:35 +01:00
Laurent
2f1b6fbee1 Merge branch 'dev' into table_editor 2022-04-12 15:25:01 +01:00
Laurent
8c0d4a0f71 Merge branch 'dev' into table_editor 2022-04-11 20:04:24 +01:00
Laurent
bc08c6dcc3 Merge branch 'dev' into table_editor 2022-04-05 19:17:37 +01:00
Laurent Cozic
a06365039d table editor init 2022-03-07 17:17:41 +00:00
584 changed files with 27783 additions and 58543 deletions

View File

@@ -6,7 +6,6 @@ _releases/
*.min.js
**/commands/index.ts
**/node_modules/
packages/generator-joplin/generators/app/templates/api/
Assets/
docs/
highlight.pack.js
@@ -47,7 +46,7 @@ packages/app-desktop/packageInfo.js
packages/app-desktop/services/electron-context-menu.js
packages/app-desktop/vendor/lib/
packages/app-mobile/android
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.bundle.js
packages/app-mobile/components/NoteEditor/CodeMirror.bundle.js
packages/app-mobile/ios
packages/app-mobile/lib/rnInjectedJs/
packages/app-mobile/locales
@@ -70,7 +69,6 @@ packages/tools/node_modules
packages/tools/PortableAppsLauncher
packages/turndown-plugin-gfm/
packages/turndown/
packages/pdf-viewer/dist
plugin_types/
readme/
@@ -78,12 +76,6 @@ readme/
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map
packages/app-cli/app/base-command.d.ts
packages/app-cli/app/base-command.js
packages/app-cli/app/base-command.js.map
packages/app-cli/app/command-done.test.d.ts
packages/app-cli/app/command-done.test.js
packages/app-cli/app/command-done.test.js.map
packages/app-cli/app/command-e2ee.d.ts
packages/app-cli/app/command-e2ee.js
packages/app-cli/app/command-e2ee.js.map
@@ -99,12 +91,6 @@ packages/app-cli/app/command-testing.js.map
packages/app-cli/app/services/plugins/PluginRunner.d.ts
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/services/plugins/PluginRunner.js.map
packages/app-cli/app/setupCommand.d.ts
packages/app-cli/app/setupCommand.js
packages/app-cli/app/setupCommand.js.map
packages/app-cli/app/utils/testUtils.d.ts
packages/app-cli/app/utils/testUtils.js
packages/app-cli/app/utils/testUtils.js.map
packages/app-cli/tests/HtmlToMd.d.ts
packages/app-cli/tests/HtmlToMd.js
packages/app-cli/tests/HtmlToMd.js.map
@@ -129,9 +115,6 @@ packages/app-cli/tests/services/plugins/api/JoplinViewMenuItem.js.map
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.d.ts
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js.map
packages/app-cli/tests/services/plugins/defaultPluginsUtils.d.ts
packages/app-cli/tests/services/plugins/defaultPluginsUtils.js
packages/app-cli/tests/services/plugins/defaultPluginsUtils.js.map
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
packages/app-cli/tests/services/plugins/sandboxProxy.js
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
@@ -264,9 +247,6 @@ packages/app-desktop/gui/EditFolderDialog/Dialog.js.map
packages/app-desktop/gui/EditFolderDialog/IconSelector.d.ts
packages/app-desktop/gui/EditFolderDialog/IconSelector.js
packages/app-desktop/gui/EditFolderDialog/IconSelector.js.map
packages/app-desktop/gui/EmojiBox.d.ts
packages/app-desktop/gui/EmojiBox.js
packages/app-desktop/gui/EmojiBox.js.map
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.d.ts
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
@@ -348,9 +328,6 @@ packages/app-desktop/gui/MainScreen/commands/openItem.js.map
packages/app-desktop/gui/MainScreen/commands/openNote.d.ts
packages/app-desktop/gui/MainScreen/commands/openNote.js
packages/app-desktop/gui/MainScreen/commands/openNote.js.map
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.d.ts
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js.map
packages/app-desktop/gui/MainScreen/commands/openTag.d.ts
packages/app-desktop/gui/MainScreen/commands/openTag.js
packages/app-desktop/gui/MainScreen/commands/openTag.js.map
@@ -444,6 +421,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/styles/index.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js.map
@@ -552,9 +532,6 @@ packages/app-desktop/gui/NoteEditor/utils/types.js.map
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.d.ts
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js.map
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.d.ts
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js.map
packages/app-desktop/gui/NoteEditor/utils/useFolder.d.ts
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
packages/app-desktop/gui/NoteEditor/utils/useFolder.js.map
@@ -618,9 +595,6 @@ packages/app-desktop/gui/OneDriveLoginScreen.js.map
packages/app-desktop/gui/PasswordInput/PasswordInput.d.ts
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js.map
packages/app-desktop/gui/PdfViewer.d.ts
packages/app-desktop/gui/PdfViewer.js
packages/app-desktop/gui/PdfViewer.js.map
packages/app-desktop/gui/ResizableLayout/MoveButtons.d.ts
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
packages/app-desktop/gui/ResizableLayout/MoveButtons.js.map
@@ -717,6 +691,9 @@ packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js.map
packages/app-desktop/gui/SyncWizard/Dialog.d.ts
packages/app-desktop/gui/SyncWizard/Dialog.js
packages/app-desktop/gui/SyncWizard/Dialog.js.map
packages/app-desktop/gui/TableEditorDialog/Dialog.d.ts
packages/app-desktop/gui/TableEditorDialog/Dialog.js
packages/app-desktop/gui/TableEditorDialog/Dialog.js.map
packages/app-desktop/gui/TagList.d.ts
packages/app-desktop/gui/TagList.js
packages/app-desktop/gui/TagList.js.map
@@ -870,15 +847,6 @@ packages/app-mobile/components/BackButtonDialogBox.js.map
packages/app-mobile/components/CameraView.d.ts
packages/app-mobile/components/CameraView.js
packages/app-mobile/components/CameraView.js.map
packages/app-mobile/components/CustomButton.d.ts
packages/app-mobile/components/CustomButton.js
packages/app-mobile/components/CustomButton.js.map
packages/app-mobile/components/Dropdown.d.ts
packages/app-mobile/components/Dropdown.js
packages/app-mobile/components/Dropdown.js.map
packages/app-mobile/components/ExtendedWebView.d.ts
packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/ExtendedWebView.js.map
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.d.ts
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js.map
@@ -891,102 +859,15 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js.ma
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.d.ts
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.js
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/types.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/types.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js.map
packages/app-mobile/components/NoteEditor/EditLinkDialog.d.ts
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js.map
packages/app-mobile/components/NoteEditor/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/NoteEditor.d.ts
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/NoteEditor.js.map
packages/app-mobile/components/NoteEditor/SearchPanel.d.ts
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/SearchPanel.js.map
packages/app-mobile/components/NoteEditor/SelectionFormatting.d.ts
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
packages/app-mobile/components/NoteEditor/SelectionFormatting.js.map
packages/app-mobile/components/NoteEditor/types.d.ts
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteEditor/types.js.map
packages/app-mobile/components/ScreenHeader.d.ts
packages/app-mobile/components/ScreenHeader.js
packages/app-mobile/components/ScreenHeader.js.map
packages/app-mobile/components/SelectDateTimeDialog.d.ts
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SelectDateTimeDialog.js.map
packages/app-mobile/components/SideMenu.d.ts
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenu.js.map
packages/app-mobile/components/getResponsiveValue.d.ts
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/getResponsiveValue.js.map
packages/app-mobile/components/getResponsiveValue.test.d.ts
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.test.js.map
packages/app-mobile/components/screens/ConfigScreen.d.ts
packages/app-mobile/components/screens/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen.js.map
@@ -999,12 +880,6 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
packages/app-mobile/components/screens/encryption-config.d.ts
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/encryption-config.js.map
packages/app-mobile/components/side-menu-content.d.ts
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/side-menu-content.js.map
packages/app-mobile/gulpfile.d.ts
packages/app-mobile/gulpfile.js
packages/app-mobile/gulpfile.js.map
packages/app-mobile/root.d.ts
packages/app-mobile/root.js
packages/app-mobile/root.js.map
@@ -1020,9 +895,6 @@ packages/app-mobile/services/e2ee/RSA.react-native.js.map
packages/app-mobile/setupQuickActions.d.ts
packages/app-mobile/setupQuickActions.js
packages/app-mobile/setupQuickActions.js.map
packages/app-mobile/tools/buildInjectedJs.d.ts
packages/app-mobile/tools/buildInjectedJs.js
packages/app-mobile/tools/buildInjectedJs.js.map
packages/app-mobile/utils/ShareExtension.d.ts
packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareExtension.js.map
@@ -1035,9 +907,6 @@ packages/app-mobile/utils/TlsUtils.js.map
packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/debounce.d.ts
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/debounce.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
@@ -1047,9 +916,6 @@ packages/app-mobile/utils/setupNotifications.js.map
packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map
packages/app-mobile/utils/types.d.ts
packages/app-mobile/utils/types.js
packages/app-mobile/utils/types.js.map
packages/fork-htmlparser2/src/CollectingHandler.d.ts
packages/fork-htmlparser2/src/CollectingHandler.js
packages/fork-htmlparser2/src/CollectingHandler.js.map
@@ -1128,12 +994,6 @@ packages/lib/ClipperServer.js.map
packages/lib/CssUtils.d.ts
packages/lib/CssUtils.js
packages/lib/CssUtils.js.map
packages/lib/EventDispatcher.d.ts
packages/lib/EventDispatcher.js
packages/lib/EventDispatcher.js.map
packages/lib/EventDispatcher.test.d.ts
packages/lib/EventDispatcher.test.js
packages/lib/EventDispatcher.test.js.map
packages/lib/HtmlToMd.d.ts
packages/lib/HtmlToMd.js
packages/lib/HtmlToMd.js.map
@@ -1614,9 +1474,6 @@ packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js.map
packages/lib/services/interop/InteropService_Importer_Raw.d.ts
packages/lib/services/interop/InteropService_Importer_Raw.js
packages/lib/services/interop/InteropService_Importer_Raw.js.map
packages/lib/services/interop/InteropService_Importer_Raw.test.d.ts
packages/lib/services/interop/InteropService_Importer_Raw.test.js
packages/lib/services/interop/InteropService_Importer_Raw.test.js.map
packages/lib/services/interop/types.d.ts
packages/lib/services/interop/types.js
packages/lib/services/interop/types.js.map
@@ -1638,9 +1495,6 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js.map
packages/lib/services/keychain/KeychainServiceDriverBase.d.ts
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/keychain/KeychainServiceDriverBase.js.map
packages/lib/services/plugins/BasePlatformImplementation.d.ts
packages/lib/services/plugins/BasePlatformImplementation.js
packages/lib/services/plugins/BasePlatformImplementation.js.map
packages/lib/services/plugins/BasePluginRunner.d.ts
packages/lib/services/plugins/BasePluginRunner.js
packages/lib/services/plugins/BasePluginRunner.js.map
@@ -1725,12 +1579,6 @@ packages/lib/services/plugins/api/JoplinWorkspace.js.map
packages/lib/services/plugins/api/types.d.ts
packages/lib/services/plugins/api/types.js
packages/lib/services/plugins/api/types.js.map
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.d.ts
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js.map
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.d.ts
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js.map
packages/lib/services/plugins/reducer.d.ts
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/reducer.js.map
@@ -2037,60 +1885,6 @@ packages/lib/uuid.js.map
packages/lib/versionInfo.d.ts
packages/lib/versionInfo.js
packages/lib/versionInfo.js.map
packages/pdf-viewer/FullViewer.d.ts
packages/pdf-viewer/FullViewer.js
packages/pdf-viewer/FullViewer.js.map
packages/pdf-viewer/Page.d.ts
packages/pdf-viewer/Page.js
packages/pdf-viewer/Page.js.map
packages/pdf-viewer/PdfDocument.d.ts
packages/pdf-viewer/PdfDocument.js
packages/pdf-viewer/PdfDocument.js.map
packages/pdf-viewer/VerticalPages.d.ts
packages/pdf-viewer/VerticalPages.js
packages/pdf-viewer/VerticalPages.js.map
packages/pdf-viewer/hooks/useIsFocused.d.ts
packages/pdf-viewer/hooks/useIsFocused.js
packages/pdf-viewer/hooks/useIsFocused.js.map
packages/pdf-viewer/hooks/useIsVisible.d.ts
packages/pdf-viewer/hooks/useIsVisible.js
packages/pdf-viewer/hooks/useIsVisible.js.map
packages/pdf-viewer/hooks/usePdfDocument.d.ts
packages/pdf-viewer/hooks/usePdfDocument.js
packages/pdf-viewer/hooks/usePdfDocument.js.map
packages/pdf-viewer/hooks/useScaledSize.d.ts
packages/pdf-viewer/hooks/useScaledSize.js
packages/pdf-viewer/hooks/useScaledSize.js.map
packages/pdf-viewer/hooks/useScrollSaver.d.ts
packages/pdf-viewer/hooks/useScrollSaver.js
packages/pdf-viewer/hooks/useScrollSaver.js.map
packages/pdf-viewer/hooks/useVisibleOnSelect.d.ts
packages/pdf-viewer/hooks/useVisibleOnSelect.js
packages/pdf-viewer/hooks/useVisibleOnSelect.js.map
packages/pdf-viewer/main.d.ts
packages/pdf-viewer/main.js
packages/pdf-viewer/main.js.map
packages/pdf-viewer/messageService.d.ts
packages/pdf-viewer/messageService.js
packages/pdf-viewer/messageService.js.map
packages/pdf-viewer/miniViewer.d.ts
packages/pdf-viewer/miniViewer.js
packages/pdf-viewer/miniViewer.js.map
packages/pdf-viewer/pdfSource.test.d.ts
packages/pdf-viewer/pdfSource.test.js
packages/pdf-viewer/pdfSource.test.js.map
packages/pdf-viewer/types.d.ts
packages/pdf-viewer/types.js
packages/pdf-viewer/types.js.map
packages/pdf-viewer/ui/GotoPage.d.ts
packages/pdf-viewer/ui/GotoPage.js
packages/pdf-viewer/ui/GotoPage.js.map
packages/pdf-viewer/ui/IconButtons.d.ts
packages/pdf-viewer/ui/IconButtons.js
packages/pdf-viewer/ui/IconButtons.js.map
packages/pdf-viewer/ui/ZoomControls.d.ts
packages/pdf-viewer/ui/ZoomControls.js
packages/pdf-viewer/ui/ZoomControls.js.map
packages/plugin-repo-cli/commands/updateRelease.d.ts
packages/plugin-repo-cli/commands/updateRelease.js
packages/plugin-repo-cli/commands/updateRelease.js.map
@@ -2142,9 +1936,6 @@ packages/plugins/ToggleSidebars/api/types.js.map
packages/plugins/ToggleSidebars/src/index.d.ts
packages/plugins/ToggleSidebars/src/index.js
packages/plugins/ToggleSidebars/src/index.js.map
packages/react-native-saf-x/src/index.d.ts
packages/react-native-saf-x/src/index.js
packages/react-native-saf-x/src/index.js.map
packages/renderer/HtmlToHtml.d.ts
packages/renderer/HtmlToHtml.js
packages/renderer/HtmlToHtml.js.map
@@ -2241,12 +2032,6 @@ packages/tools/buildServerDocker.js.map
packages/tools/buildServerDocker.test.d.ts
packages/tools/buildServerDocker.test.js
packages/tools/buildServerDocker.test.js.map
packages/tools/bundleDefaultPlugins.d.ts
packages/tools/bundleDefaultPlugins.js
packages/tools/bundleDefaultPlugins.js.map
packages/tools/bundleDefaultPlugins.test.d.ts
packages/tools/bundleDefaultPlugins.test.js
packages/tools/bundleDefaultPlugins.test.js.map
packages/tools/checkLibPaths.d.ts
packages/tools/checkLibPaths.js
packages/tools/checkLibPaths.js.map

View File

@@ -76,22 +76,17 @@ module.exports = {
'no-array-constructor': ['error'],
'radix': ['error'],
'eqeqeq': ['error', 'always'],
// Warn only for now because fixing everything would take too much
// refactoring, but new code should try to stick to it.
// 'complexity': ['warn', { max: 10 }],
// Checks rules of Hooks
'@seiyab/react-hooks/rules-of-hooks': 'error',
'@seiyab/react-hooks/exhaustive-deps': ['error', { 'ignoreThisDependency': 'props' }],
'react-hooks/rules-of-hooks': 'error',
// Checks effect dependencies
// Disable because of this: https://github.com/facebook/react/issues/16265
// "react-hooks/exhaustive-deps": "warn",
'promise/prefer-await-to-then': 'error',
// -------------------------------
// Formatting
// -------------------------------
@@ -138,12 +133,8 @@ module.exports = {
'plugins': [
'react',
'@typescript-eslint',
// Need to use a fork of the official rules of hooks because of this bug:
// https://github.com/facebook/react/issues/16265
'@seiyab/eslint-plugin-react-hooks',
// 'react-hooks',
'react-hooks',
'import',
'promise',
],
'overrides': [
{

View File

@@ -57,11 +57,6 @@ echo "Yarn $( yarn -v )"
cd "$ROOT_DIR"
yarn install
testResult=$?
if [ $testResult -ne 0 ]; then
echo "Yarn installation failed. Search for 'exit code 1' in the log for more information."
exit $testResult
fi
# =============================================================================
# Run test units. Only do it for pull requests and dev branch because we don't
@@ -130,11 +125,12 @@ fi
# =============================================================================
# Check that we didn't lose any string due to gettext not being able to parse
# newly modified or added scripts. This is convenient to quickly view on GitHub
# what commit may have broken translation building.
# what commit may have broken translation building. We run this on macOS because
# we need the latest version of gettext (and stable Ubuntu doesn't have it).
# =============================================================================
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
if [ "$IS_MACOS" == "1" ]; then
echo "Step: Checking for lost translation strings..."
xgettext --version
@@ -174,9 +170,6 @@ cd "$ROOT_DIR/packages/app-desktop"
if [[ $GIT_TAG_NAME = v* ]]; then
echo "Step: Building and publishing desktop application..."
# cd "$ROOT_DIR/packages/tools"
# node bundleDefaultPlugins.js
cd "$ROOT_DIR/packages/app-desktop"
USE_HARD_LINKS=false yarn run dist
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
echo "Step: Building Docker Image..."

View File

@@ -5,6 +5,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Removed windows-2016 for now - discontinued by GitHub
os: [macos-latest, ubuntu-latest, windows-2019]
steps:
@@ -21,6 +22,13 @@ jobs:
sudo apt-get install -y libsecret-1-dev
sudo apt-get install -y translate-toolkit
- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
brew update
brew install gettext
brew install translate-toolkit
- name: Install Docker Engine
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
if: runner.os == 'Linux'
@@ -68,8 +76,6 @@ jobs:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
IS_CONTINUOUS_INTEGRATION: 1
BUILD_SEQUENCIAL: 1
SERVER_REPOSITORY: joplin/server
SERVER_TAG_PREFIX: server
run: |
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"

234
.gitignore vendored
View File

@@ -66,12 +66,6 @@ docs/**/*.mustache
packages/app-cli/app/LinkSelector.d.ts
packages/app-cli/app/LinkSelector.js
packages/app-cli/app/LinkSelector.js.map
packages/app-cli/app/base-command.d.ts
packages/app-cli/app/base-command.js
packages/app-cli/app/base-command.js.map
packages/app-cli/app/command-done.test.d.ts
packages/app-cli/app/command-done.test.js
packages/app-cli/app/command-done.test.js.map
packages/app-cli/app/command-e2ee.d.ts
packages/app-cli/app/command-e2ee.js
packages/app-cli/app/command-e2ee.js.map
@@ -87,12 +81,6 @@ packages/app-cli/app/command-testing.js.map
packages/app-cli/app/services/plugins/PluginRunner.d.ts
packages/app-cli/app/services/plugins/PluginRunner.js
packages/app-cli/app/services/plugins/PluginRunner.js.map
packages/app-cli/app/setupCommand.d.ts
packages/app-cli/app/setupCommand.js
packages/app-cli/app/setupCommand.js.map
packages/app-cli/app/utils/testUtils.d.ts
packages/app-cli/app/utils/testUtils.js
packages/app-cli/app/utils/testUtils.js.map
packages/app-cli/tests/HtmlToMd.d.ts
packages/app-cli/tests/HtmlToMd.js
packages/app-cli/tests/HtmlToMd.js.map
@@ -117,9 +105,6 @@ packages/app-cli/tests/services/plugins/api/JoplinViewMenuItem.js.map
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.d.ts
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js
packages/app-cli/tests/services/plugins/api/JoplinWorkspace.js.map
packages/app-cli/tests/services/plugins/defaultPluginsUtils.d.ts
packages/app-cli/tests/services/plugins/defaultPluginsUtils.js
packages/app-cli/tests/services/plugins/defaultPluginsUtils.js.map
packages/app-cli/tests/services/plugins/sandboxProxy.d.ts
packages/app-cli/tests/services/plugins/sandboxProxy.js
packages/app-cli/tests/services/plugins/sandboxProxy.js.map
@@ -252,9 +237,6 @@ packages/app-desktop/gui/EditFolderDialog/Dialog.js.map
packages/app-desktop/gui/EditFolderDialog/IconSelector.d.ts
packages/app-desktop/gui/EditFolderDialog/IconSelector.js
packages/app-desktop/gui/EditFolderDialog/IconSelector.js.map
packages/app-desktop/gui/EmojiBox.d.ts
packages/app-desktop/gui/EmojiBox.js
packages/app-desktop/gui/EmojiBox.js.map
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.d.ts
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
@@ -336,9 +318,6 @@ packages/app-desktop/gui/MainScreen/commands/openItem.js.map
packages/app-desktop/gui/MainScreen/commands/openNote.d.ts
packages/app-desktop/gui/MainScreen/commands/openNote.js
packages/app-desktop/gui/MainScreen/commands/openNote.js.map
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.d.ts
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js
packages/app-desktop/gui/MainScreen/commands/openPdfViewer.js.map
packages/app-desktop/gui/MainScreen/commands/openTag.d.ts
packages/app-desktop/gui/MainScreen/commands/openTag.js
packages/app-desktop/gui/MainScreen/commands/openTag.js.map
@@ -432,6 +411,9 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/styles/index.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/index.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/tables.js.map
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.d.ts
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js.map
@@ -540,9 +522,6 @@ packages/app-desktop/gui/NoteEditor/utils/types.js.map
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.d.ts
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js.map
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.d.ts
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js.map
packages/app-desktop/gui/NoteEditor/utils/useFolder.d.ts
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
packages/app-desktop/gui/NoteEditor/utils/useFolder.js.map
@@ -606,9 +585,6 @@ packages/app-desktop/gui/OneDriveLoginScreen.js.map
packages/app-desktop/gui/PasswordInput/PasswordInput.d.ts
packages/app-desktop/gui/PasswordInput/PasswordInput.js
packages/app-desktop/gui/PasswordInput/PasswordInput.js.map
packages/app-desktop/gui/PdfViewer.d.ts
packages/app-desktop/gui/PdfViewer.js
packages/app-desktop/gui/PdfViewer.js.map
packages/app-desktop/gui/ResizableLayout/MoveButtons.d.ts
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
packages/app-desktop/gui/ResizableLayout/MoveButtons.js.map
@@ -705,6 +681,9 @@ packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js.map
packages/app-desktop/gui/SyncWizard/Dialog.d.ts
packages/app-desktop/gui/SyncWizard/Dialog.js
packages/app-desktop/gui/SyncWizard/Dialog.js.map
packages/app-desktop/gui/TableEditorDialog/Dialog.d.ts
packages/app-desktop/gui/TableEditorDialog/Dialog.js
packages/app-desktop/gui/TableEditorDialog/Dialog.js.map
packages/app-desktop/gui/TagList.d.ts
packages/app-desktop/gui/TagList.js
packages/app-desktop/gui/TagList.js.map
@@ -858,15 +837,6 @@ packages/app-mobile/components/BackButtonDialogBox.js.map
packages/app-mobile/components/CameraView.d.ts
packages/app-mobile/components/CameraView.js
packages/app-mobile/components/CameraView.js.map
packages/app-mobile/components/CustomButton.d.ts
packages/app-mobile/components/CustomButton.js
packages/app-mobile/components/CustomButton.js.map
packages/app-mobile/components/Dropdown.d.ts
packages/app-mobile/components/Dropdown.js
packages/app-mobile/components/Dropdown.js.map
packages/app-mobile/components/ExtendedWebView.d.ts
packages/app-mobile/components/ExtendedWebView.js
packages/app-mobile/components/ExtendedWebView.js.map
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.d.ts
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js.map
@@ -879,102 +849,15 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js.ma
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.d.ts
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.js
packages/app-mobile/components/NoteEditor/CodeMirror/createEditor.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.bulletedVsChecklist.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownCommands.toggleList.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.js
packages/app-mobile/components/NoteEditor/CodeMirror/markdownReformatter.test.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/types.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/types.js
packages/app-mobile/components/NoteEditor/CodeMirror/types.js.map
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js
packages/app-mobile/components/NoteEditor/CodeMirror/webviewLogger.js.map
packages/app-mobile/components/NoteEditor/EditLinkDialog.d.ts
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
packages/app-mobile/components/NoteEditor/EditLinkDialog.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/MarkdownToolbar.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleOverflowButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToggleSpaceButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/Toolbar.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarButton.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/ToolbarOverflowRows.js.map
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.d.ts
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js
packages/app-mobile/components/NoteEditor/MarkdownToolbar/types.js.map
packages/app-mobile/components/NoteEditor/CodeMirror.d.ts
packages/app-mobile/components/NoteEditor/CodeMirror.js
packages/app-mobile/components/NoteEditor/CodeMirror.js.map
packages/app-mobile/components/NoteEditor/NoteEditor.d.ts
packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/NoteEditor.js.map
packages/app-mobile/components/NoteEditor/SearchPanel.d.ts
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/SearchPanel.js.map
packages/app-mobile/components/NoteEditor/SelectionFormatting.d.ts
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
packages/app-mobile/components/NoteEditor/SelectionFormatting.js.map
packages/app-mobile/components/NoteEditor/types.d.ts
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteEditor/types.js.map
packages/app-mobile/components/ScreenHeader.d.ts
packages/app-mobile/components/ScreenHeader.js
packages/app-mobile/components/ScreenHeader.js.map
packages/app-mobile/components/SelectDateTimeDialog.d.ts
packages/app-mobile/components/SelectDateTimeDialog.js
packages/app-mobile/components/SelectDateTimeDialog.js.map
packages/app-mobile/components/SideMenu.d.ts
packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/SideMenu.js.map
packages/app-mobile/components/getResponsiveValue.d.ts
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/getResponsiveValue.js.map
packages/app-mobile/components/getResponsiveValue.test.d.ts
packages/app-mobile/components/getResponsiveValue.test.js
packages/app-mobile/components/getResponsiveValue.test.js.map
packages/app-mobile/components/screens/ConfigScreen.d.ts
packages/app-mobile/components/screens/ConfigScreen.js
packages/app-mobile/components/screens/ConfigScreen.js.map
@@ -987,12 +870,6 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
packages/app-mobile/components/screens/encryption-config.d.ts
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/encryption-config.js.map
packages/app-mobile/components/side-menu-content.d.ts
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/side-menu-content.js.map
packages/app-mobile/gulpfile.d.ts
packages/app-mobile/gulpfile.js
packages/app-mobile/gulpfile.js.map
packages/app-mobile/root.d.ts
packages/app-mobile/root.js
packages/app-mobile/root.js.map
@@ -1008,9 +885,6 @@ packages/app-mobile/services/e2ee/RSA.react-native.js.map
packages/app-mobile/setupQuickActions.d.ts
packages/app-mobile/setupQuickActions.js
packages/app-mobile/setupQuickActions.js.map
packages/app-mobile/tools/buildInjectedJs.d.ts
packages/app-mobile/tools/buildInjectedJs.js
packages/app-mobile/tools/buildInjectedJs.js.map
packages/app-mobile/utils/ShareExtension.d.ts
packages/app-mobile/utils/ShareExtension.js
packages/app-mobile/utils/ShareExtension.js.map
@@ -1023,9 +897,6 @@ packages/app-mobile/utils/TlsUtils.js.map
packages/app-mobile/utils/checkPermissions.d.ts
packages/app-mobile/utils/checkPermissions.js
packages/app-mobile/utils/checkPermissions.js.map
packages/app-mobile/utils/debounce.d.ts
packages/app-mobile/utils/debounce.js
packages/app-mobile/utils/debounce.js.map
packages/app-mobile/utils/fs-driver-rn.d.ts
packages/app-mobile/utils/fs-driver-rn.js
packages/app-mobile/utils/fs-driver-rn.js.map
@@ -1035,9 +906,6 @@ packages/app-mobile/utils/setupNotifications.js.map
packages/app-mobile/utils/shareHandler.d.ts
packages/app-mobile/utils/shareHandler.js
packages/app-mobile/utils/shareHandler.js.map
packages/app-mobile/utils/types.d.ts
packages/app-mobile/utils/types.js
packages/app-mobile/utils/types.js.map
packages/fork-htmlparser2/src/CollectingHandler.d.ts
packages/fork-htmlparser2/src/CollectingHandler.js
packages/fork-htmlparser2/src/CollectingHandler.js.map
@@ -1116,12 +984,6 @@ packages/lib/ClipperServer.js.map
packages/lib/CssUtils.d.ts
packages/lib/CssUtils.js
packages/lib/CssUtils.js.map
packages/lib/EventDispatcher.d.ts
packages/lib/EventDispatcher.js
packages/lib/EventDispatcher.js.map
packages/lib/EventDispatcher.test.d.ts
packages/lib/EventDispatcher.test.js
packages/lib/EventDispatcher.test.js.map
packages/lib/HtmlToMd.d.ts
packages/lib/HtmlToMd.js
packages/lib/HtmlToMd.js.map
@@ -1602,9 +1464,6 @@ packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.js.map
packages/lib/services/interop/InteropService_Importer_Raw.d.ts
packages/lib/services/interop/InteropService_Importer_Raw.js
packages/lib/services/interop/InteropService_Importer_Raw.js.map
packages/lib/services/interop/InteropService_Importer_Raw.test.d.ts
packages/lib/services/interop/InteropService_Importer_Raw.test.js
packages/lib/services/interop/InteropService_Importer_Raw.test.js.map
packages/lib/services/interop/types.d.ts
packages/lib/services/interop/types.js
packages/lib/services/interop/types.js.map
@@ -1626,9 +1485,6 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js.map
packages/lib/services/keychain/KeychainServiceDriverBase.d.ts
packages/lib/services/keychain/KeychainServiceDriverBase.js
packages/lib/services/keychain/KeychainServiceDriverBase.js.map
packages/lib/services/plugins/BasePlatformImplementation.d.ts
packages/lib/services/plugins/BasePlatformImplementation.js
packages/lib/services/plugins/BasePlatformImplementation.js.map
packages/lib/services/plugins/BasePluginRunner.d.ts
packages/lib/services/plugins/BasePluginRunner.js
packages/lib/services/plugins/BasePluginRunner.js.map
@@ -1713,12 +1569,6 @@ packages/lib/services/plugins/api/JoplinWorkspace.js.map
packages/lib/services/plugins/api/types.d.ts
packages/lib/services/plugins/api/types.js
packages/lib/services/plugins/api/types.js.map
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.d.ts
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js
packages/lib/services/plugins/defaultPlugins/defaultPluginsUtils.js.map
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.d.ts
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js
packages/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo.js.map
packages/lib/services/plugins/reducer.d.ts
packages/lib/services/plugins/reducer.js
packages/lib/services/plugins/reducer.js.map
@@ -2025,60 +1875,6 @@ packages/lib/uuid.js.map
packages/lib/versionInfo.d.ts
packages/lib/versionInfo.js
packages/lib/versionInfo.js.map
packages/pdf-viewer/FullViewer.d.ts
packages/pdf-viewer/FullViewer.js
packages/pdf-viewer/FullViewer.js.map
packages/pdf-viewer/Page.d.ts
packages/pdf-viewer/Page.js
packages/pdf-viewer/Page.js.map
packages/pdf-viewer/PdfDocument.d.ts
packages/pdf-viewer/PdfDocument.js
packages/pdf-viewer/PdfDocument.js.map
packages/pdf-viewer/VerticalPages.d.ts
packages/pdf-viewer/VerticalPages.js
packages/pdf-viewer/VerticalPages.js.map
packages/pdf-viewer/hooks/useIsFocused.d.ts
packages/pdf-viewer/hooks/useIsFocused.js
packages/pdf-viewer/hooks/useIsFocused.js.map
packages/pdf-viewer/hooks/useIsVisible.d.ts
packages/pdf-viewer/hooks/useIsVisible.js
packages/pdf-viewer/hooks/useIsVisible.js.map
packages/pdf-viewer/hooks/usePdfDocument.d.ts
packages/pdf-viewer/hooks/usePdfDocument.js
packages/pdf-viewer/hooks/usePdfDocument.js.map
packages/pdf-viewer/hooks/useScaledSize.d.ts
packages/pdf-viewer/hooks/useScaledSize.js
packages/pdf-viewer/hooks/useScaledSize.js.map
packages/pdf-viewer/hooks/useScrollSaver.d.ts
packages/pdf-viewer/hooks/useScrollSaver.js
packages/pdf-viewer/hooks/useScrollSaver.js.map
packages/pdf-viewer/hooks/useVisibleOnSelect.d.ts
packages/pdf-viewer/hooks/useVisibleOnSelect.js
packages/pdf-viewer/hooks/useVisibleOnSelect.js.map
packages/pdf-viewer/main.d.ts
packages/pdf-viewer/main.js
packages/pdf-viewer/main.js.map
packages/pdf-viewer/messageService.d.ts
packages/pdf-viewer/messageService.js
packages/pdf-viewer/messageService.js.map
packages/pdf-viewer/miniViewer.d.ts
packages/pdf-viewer/miniViewer.js
packages/pdf-viewer/miniViewer.js.map
packages/pdf-viewer/pdfSource.test.d.ts
packages/pdf-viewer/pdfSource.test.js
packages/pdf-viewer/pdfSource.test.js.map
packages/pdf-viewer/types.d.ts
packages/pdf-viewer/types.js
packages/pdf-viewer/types.js.map
packages/pdf-viewer/ui/GotoPage.d.ts
packages/pdf-viewer/ui/GotoPage.js
packages/pdf-viewer/ui/GotoPage.js.map
packages/pdf-viewer/ui/IconButtons.d.ts
packages/pdf-viewer/ui/IconButtons.js
packages/pdf-viewer/ui/IconButtons.js.map
packages/pdf-viewer/ui/ZoomControls.d.ts
packages/pdf-viewer/ui/ZoomControls.js
packages/pdf-viewer/ui/ZoomControls.js.map
packages/plugin-repo-cli/commands/updateRelease.d.ts
packages/plugin-repo-cli/commands/updateRelease.js
packages/plugin-repo-cli/commands/updateRelease.js.map
@@ -2130,9 +1926,6 @@ packages/plugins/ToggleSidebars/api/types.js.map
packages/plugins/ToggleSidebars/src/index.d.ts
packages/plugins/ToggleSidebars/src/index.js
packages/plugins/ToggleSidebars/src/index.js.map
packages/react-native-saf-x/src/index.d.ts
packages/react-native-saf-x/src/index.js
packages/react-native-saf-x/src/index.js.map
packages/renderer/HtmlToHtml.d.ts
packages/renderer/HtmlToHtml.js
packages/renderer/HtmlToHtml.js.map
@@ -2229,12 +2022,6 @@ packages/tools/buildServerDocker.js.map
packages/tools/buildServerDocker.test.d.ts
packages/tools/buildServerDocker.test.js
packages/tools/buildServerDocker.test.js.map
packages/tools/bundleDefaultPlugins.d.ts
packages/tools/bundleDefaultPlugins.js
packages/tools/bundleDefaultPlugins.js.map
packages/tools/bundleDefaultPlugins.test.d.ts
packages/tools/bundleDefaultPlugins.test.js
packages/tools/bundleDefaultPlugins.test.js.map
packages/tools/checkLibPaths.d.ts
packages/tools/checkLibPaths.js
packages/tools/checkLibPaths.js.map
@@ -2329,6 +2116,3 @@ packages/tools/website/utils/types.d.ts
packages/tools/website/utils/types.js
packages/tools/website/utils/types.js.map
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
packages/app-mobile/components/get-responsive-value.test.js
packages/app-mobile/components/get-responsive-value.test.js
packages/app-mobile/components/get-responsive-value.test.js

View File

@@ -9,13 +9,11 @@ import PluginManager from 'tinymce/core/api/PluginManager';
import * as Api from './api/Api';
import * as Commands from './api/Commands';
import * as Keyboard from './core/Keyboard';
import * as Mouse from './core/Mouse'
import * as Buttons from './ui/Buttons';
export default function () {
PluginManager.add('joplinLists', function (editor) {
Keyboard.setup(editor);
Mouse.setup(editor);
Buttons.register(editor);
Commands.register(editor);

View File

@@ -1,26 +0,0 @@
import { isJoplinChecklistItem } from '../listModel/JoplinListUtil';
const setup = function (editor) {
const editorClickHandler = (event) => {
if (!isJoplinChecklistItem(event.target)) return;
// We only process the click if it's within the checkbox itself (and not the label).
// That checkbox, based on
// the current styling is in the negative margin, so offsetX is negative when clicking
// on the checkbox itself, and positive when clicking on the label. This is strongly
// dependent on how the checkbox is styled, so if the style is changed, this might need
// to be updated too.
// For the styling, see:
// packages/renderer/MdToHtml/rules/checkbox.ts
//
// The previous solution was to use "pointer-event: none", which mostly work, however
// it means that links are no longer clickable when they are within the checkbox label.
if (event.offsetX >= 0) return;
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
}
editor.on('click', editorClickHandler);
};
export { setup };

View File

@@ -10,7 +10,7 @@ import * as Settings from '../api/Settings';
import * as NodeType from '../core/NodeType';
import Editor from 'tinymce/core/api/Editor';
import { isCustomList } from '../core/Util';
import { findContainerListTypeFromEvent } from '../listModel/JoplinListUtil';
import { findContainerListTypeFromEvent, isJoplinChecklistItem } from '../listModel/JoplinListUtil';
const findIndex = function (list, predicate) {
for (let index = 0; index < list.length; index++) {
@@ -38,11 +38,37 @@ const listState = function (editor: Editor, listName, options:any = {}) {
buttonApi.setActive(listType === options.listType && lists.length > 0 && lists[0].nodeName === listName && !isCustomList(lists[0]));
};
const editorClickHandler = (event) => {
if (!isJoplinChecklistItem(event.target)) return;
// We only process the click if it's within the checkbox itself (and not the label).
// That checkbox, based on
// the current styling is in the negative margin, so offsetX is negative when clicking
// on the checkbox itself, and positive when clicking on the label. This is strongly
// dependent on how the checkbox is styled, so if the style is changed, this might need
// to be updated too.
// For the styling, see:
// packages/renderer/MdToHtml/rules/checkbox.ts
//
// The previous solution was to use "pointer-event: none", which mostly work, however
// it means that links are no longer clickable when they are within the checkbox label.
if (event.offsetX >= 0) return;
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
}
if (options.listType === 'joplinChecklist') {
editor.on('click', editorClickHandler);
}
editor.on('NodeChange', nodeChangeHandler);
return () => {
if (options.listType === 'joplinChecklist') {
editor.off('click', editorClickHandler);
}
editor.off('NodeChange', nodeChangeHandler);
}
}
};
};

View File

@@ -1,21 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Oct 2022 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Wed, 12 Oct 2022 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin Cloud is now part of the Joplin company]]></title><description><![CDATA[<p>As some of you may know Joplin Cloud so far has been operating under my own single-person limited company in the UK. This was mostly for convenience since it meant I could get things going quickly without having to setup a special structure for it.</p>
<p>Now that Joplin Cloud is becoming more mature however a proper company, simply called Joplin, has been created. This company will be based in France, and will be used mainly to handle the commercial part of the project, which currently is mostly Joplin Cloud. I'm still heading the company so there won't be any major change to the way the project is managed.</p>
<h2>What does it mean for Joplin Cloud?<a name="what-does-it-mean-for-joplin-cloud" href="#what-does-it-mean-for-joplin-cloud" class="heading-anchor">🔗</a></h2>
<p>There will be no significant change - the website ownership simply moves from one company in the UK to one in France. The new company is still owned by myself so I will keep following the same roadmap.</p>
<h2>What does it mean for the open source apps?<a name="what-does-it-mean-for-the-open-source-apps" href="#what-does-it-mean-for-the-open-source-apps" class="heading-anchor">🔗</a></h2>
<p>On the short term, the only visible change will be moving the non-open source assets, such as logo or trademark from the UK company to the French one. So expect a few changes in copyright notices here and there.</p>
<p>In the medium to long term, I would like to hire one or two software developers to help me with the Joplin Cloud development, because we reached a point where managing the whole project is difficult for a single person, so some help is needed. Some of their work might also touch the open source apps since both are quite related - but of course that work will remain open source too.</p>
<p>As a general rule, there will be a permanent commitment to keep the apps open source and to derive value from Joplin Cloud/Server.</p>
<p>Longer term I would like to create a non-profit organisation to handle the open source applications and to make decisions about the project, as well as to decide how to allocate any funding we receive (for example from GSoC).</p>
<h2>Looking forward<a name="looking-forward" href="#looking-forward" class="heading-anchor">🔗</a></h2>
<p>Those past 6 years of developing Joplin have been an exciting and rewarding experience, thank you to all of you of the friendly and vibrant Joplin community for your contribution toward making Joplin the software it is today, and looking forward to continuing the journey together!</p>
]]></description><link>https://joplinapp.org/news/20221012-Joplin-Company/</link><guid isPermaLink="false">20221012-Joplin-Company</guid><pubDate>Wed, 12 Oct 2022 00:00:00 GMT</pubDate><twitter-text>Joplin Cloud is now operated by the Joplin company! More info on the announcement post.</twitter-text></item><item><title><![CDATA[Joplin interview on Website Planet]]></title><description><![CDATA[<p>Website Planet has recently conducted an interview about Joplin - it may give you some insight on the current status of the project, our priorities, and future plans! More on the article page - <a href="https://www.websiteplanet.com/blog/interview-joplin/">Organise Your Thoughts with Open Source Note-Taking App, Joplin</a></p>
]]></description><link>https://joplinapp.org/news/20220906-interview-websiteplanet/</link><guid isPermaLink="false">20220906-interview-websiteplanet</guid><pubDate>Tue, 06 Sep 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin first meetup on 30 August!]]></title><description><![CDATA[<p>We are glad to announce <a href="https://www.meetup.com/joplin/events/287611873/">the first Joplin Meetup</a> that will take place on 30 August 2022 in London!</p>
<p>This is an opportunity to meet other Joplin users as well as some of the main contributors, to discuss the apps, or to ask questions and exchange tips and tricks on how to use the app, develop plugins or contribute to the application. Everybody, technical or not, is welcome!</p>
<p>We will meet at the Old Thameside Inn next to London Bridge. If the weather allows we will be on the terrace outside, if not inside.</p>
<p>More information on the official Meetup page:</p>
<p><a href="https://www.meetup.com/joplin/events/287611873/">https://www.meetup.com/joplin/events/287611873/</a></p>
]]></description><link>https://joplinapp.org/news/20220808-first-meetup/</link><guid isPermaLink="false">20220808-first-meetup</guid><pubDate>Mon, 08 Aug 2022 00:00:00 GMT</pubDate><twitter-text>Joplin will have its first Meetup on 30 August! Come and join us at the Old Thameside Inn next to London Bridge! https://www.meetup.com/joplin/events/287611873/</twitter-text></item><item><title><![CDATA[Joplin 2.8 is available!]]></title><description><![CDATA[<p>As always a lot of changes and new features in this new version available on both desktop and mobile.</p>
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Mon, 06 Jun 2022 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 06 Jun 2022 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin 2.8 is available!]]></title><description><![CDATA[<p>As always a lot of changes and new features in this new version available on both desktop and mobile.</p>
<h1>Multiple profile support<a name="multiple-profile-support" href="#multiple-profile-support" class="heading-anchor">🔗</a></h1>
<p>Perhaps the most visible change in this version is the support for multiple profiles. You can now create as many application profile as you wish, each with their own settings, and easily switch from one to another. The main use case is to support for example a &quot;work&quot; profile and a &quot;personal&quot; profile, to allow you to keep things independent, and each profile can sync with a different sync target.</p>
<p>To create a new profile, open <strong>File &gt; Switch profile</strong> and select <strong>Create new profile</strong>, enter the profile name and press OK. The app will automatically switch to this new profile, which you can now configure.</p>
@@ -268,4 +251,11 @@
</li>
</ul>
<p>Also many thanks to everyone who voted and contributed to the tagline discussion! It helped narrow down what the tagline should be, along with the equally important description below. If you have any question or notice any issue with the website let me know!</p>
]]></description><link>https://joplinapp.org/news/20210711-095626/</link><guid isPermaLink="false">20210711-095626</guid><pubDate>Sun, 11 Jul 2021 09:56:26 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
]]></description><link>https://joplinapp.org/news/20210711-095626/</link><guid isPermaLink="false">20210711-095626</guid><pubDate>Sun, 11 Jul 2021 09:56:26 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Poll: What should Joplin tagline be?]]></title><description><![CDATA[<p>Thanks everyone for your tagline suggestions - there were lots of good ideas in there. I've compiled a few of them and create a poll in the forum, so please cast your vote! And if you have any other suggestions on what would make a good tagline, feel free to post over there or here.</p>
<p><a href="https://discourse.joplinapp.org/t/poll-what-should-joplin-tagline-be/18487">https://discourse.joplinapp.org/t/poll-what-should-joplin-tagline-be/18487</a></p>
]]></description><link>https://joplinapp.org/news/20210706-140228/</link><guid isPermaLink="false">20210706-140228</guid><pubDate>Tue, 06 Jul 2021 14:02:28 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Any ideas for a Joplin tagline?]]></title><description><![CDATA[<p>I'm going to update the website front page to better showcase the application. I have most of the sections right, but the part I'm still not sure about is the top tagline, so I'm wondering if anyone had any suggestion about it?</p>
<p>From what I can see on Google Keep or Evernote for example it should be something like &quot;Use our app to get X or Y benefit&quot;, it should be a sentence that directly speaks to the user essentially.</p>
<p>So far I have &quot;Your notes, anywhere you are&quot; but I'm not certain that's particularly inspiring. Any other idea about what tagline could be used?</p>
]]></description><link>https://joplinapp.org/news/20210705-094247/</link><guid isPermaLink="false">20210705-094247</guid><pubDate>Mon, 05 Jul 2021 09:42:47 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Poll: What's the size of your note collection?]]></title><description><![CDATA[<p>Poll is on the forum:</p>
<p><a href="https://discourse.joplinapp.org/t/poll-whats-the-size-of-your-note-collection/18191">https://discourse.joplinapp.org/t/poll-whats-the-size-of-your-note-collection/18191</a></p>
]]></description><link>https://joplinapp.org/news/20210624-171844/</link><guid isPermaLink="false">20210624-171844</guid><pubDate>Thu, 24 Jun 2021 17:18:44 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>

View File

@@ -1,7 +1,5 @@
<!-- Monthly/Yearly plan A/B testing -->
<!--
<script src="https://www.googleoptimize.com/optimize.js?id=OPT-PW3ZPK3"></script>
-->
<!-- Donate button A/B testing -->
<!--

View File

@@ -116,21 +116,16 @@
});
};
const applyPeriod = (period) => {
subscriptionPeriod = period;
$('.plan-group').removeClass(period === 'monthly' ? 'plan-prices-yearly' : 'plan-prices-monthly');
$('.plan-group').addClass('plan-prices-' + period);
$("#pay-" + period + '-radio').prop('checked', true);
}
$(() => {
$("input[name='pay-radio']").change(function() {
const period = $("input[type='radio'][name='pay-radio']:checked").val();
applyPeriod(period);
subscriptionPeriod = period;
$('.plan-group').removeClass(period === 'monthly' ? 'plan-prices-yearly' : 'plan-prices-monthly');
$('.plan-group').addClass('plan-prices-' + period);
});
setupBetaHandling(urlQuery);
applyPeriod('yearly');
});
</script>
</div>

View File

@@ -31,7 +31,7 @@ Joplin is available in multiple languages thanks to the help of its users. You c
If you want to start contributing to the project's code, please follow these guidelines before creating a pull request:
- The top post of the pull request should contain a full, self-contained explanation of the feature: what it does, how it does it, with examples of usage and screenshots. Also explain why you want to add this - what problem does it solve. Do not simply add a text `Implement feature #4345` or link to forum posts, because the information there will most likely be outdated or confusing (multiple discussions and opinions). The pull request needs to be self-contained.
- Explain WHY you want to add this change. Explain it inside the pull request and you may link to an issue for additional information, but the PR should give a clear overview of why you want to add this.
- Bug fixes are always welcome. Start by reviewing the [list of bugs](https://github.com/laurent22/joplin/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
- A good way to easily start contributing is to pick and work on a [good first issue](https://github.com/laurent22/joplin/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). We try to make these issues as clear as possible and provide basic info on how the code should be changed, and if something is unclear feel free to ask for more information on the issue.
- Before adding a new feature, ask about it in the [Github Issue Tracker](https://github.com/laurent22/joplin/issues?utf8=%E2%9C%93&q=is%3Aissue) or the [Joplin Forum](https://discourse.joplinapp.org/), or check if existing discussions exist to make sure the new functionality is desired.
@@ -45,11 +45,11 @@ Building the apps is relatively easy - please [see the build instructions](https
## Coding style
Please see [readme/coding_style.md](readme/coding_style.md).
Coding style is enforced by a pre-commit hook that runs eslint. This hook is installed whenever running `yarn install` on any of the application directory. If for some reason the pre-commit hook didn't get installed, you can manually install it by running `yarn install` at the root of the repository.
## GUI style
For new React components, please use [React Hooks](https://reactjs.org/docs/hooks-intro.html). For new code in general, please use TypeScript. Even if you are modifying a file that was originally in JavaScript you should ideally convert it first to TypeScript before modifying it. Doing so is relatively easy and it helps maintain code quality.
For changes made to the Desktop and mobile clients that affect the user interface, refer to `packages/lib/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
For changes made to the Desktop client that affect the user interface, refer to `packages/app-desktop/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
## Automated tests

View File

@@ -10,7 +10,7 @@ under that directory is licensed under the default license, which is MIT.
* * *
Joplin® is a trademark of JOPLIN SAS registered in the European Union, with
Joplin® is a trademark of Cozic Ltd registered in the European Union, with
filing number 018544315.
* * *

View File

@@ -4,10 +4,6 @@
* * *
Joplin will have [its first Meetup on 30 August 2022](https://discourse.joplinapp.org/t/joplin-first-meetup-on-30-august/26808)! Come and join us at the Old Thameside Inn next to London Bridge!
* * *
🌞 Joplin participates in **Google Summer of Code 2022**! More info on [the announcement post](https://github.com/laurent22/joplin/blob/dev/readme/news/20220308-gsoc2022-start.md). 🌞
* * *
@@ -85,11 +81,10 @@ A community maintained list of these distributions can be found here: [Unofficia
| <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/3061769?s=96&v=4"/></br>[c-nagy](https://github.com/c-nagy) | <img width="50" src="https://avatars2.githubusercontent.com/u/70780798?s=96&v=4"/></br>[cabottech](https://github.com/cabottech) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/4862947?s=96&v=4"/></br>[chrootlogin](https://github.com/chrootlogin) | <img width="50" src="https://avatars2.githubusercontent.com/u/82579431?s=96&v=4"/></br>[clmntsl](https://github.com/clmntsl) | <img width="50" src="https://avatars2.githubusercontent.com/u/808091?s=96&v=4"/></br>[cuongtransc](https://github.com/cuongtransc) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[fbloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/49439044?s=96&v=4"/></br>[fourstepper](https://github.com/fourstepper) | <img width="50" src="https://avatars2.githubusercontent.com/u/38898566?s=96&v=4"/></br>[h4sh5](https://github.com/h4sh5) | <img width="50" src="https://avatars2.githubusercontent.com/u/3266447?s=96&v=4"/></br>[iamwillbar](https://github.com/iamwillbar) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) | <img width="50" src="https://avatars2.githubusercontent.com/u/1310474?s=96&v=4"/></br>[jknowles](https://github.com/jknowles) | <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/5588131?s=96&v=4"/></br>[kianenigma](https://github.com/kianenigma) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/77214738?s=96&v=4"/></br>[Polymathic-Company](https://github.com/Polymathic-Company) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/327998?s=96&v=4"/></br>[sif](https://github.com/sif) | <img width="50" src="https://avatars2.githubusercontent.com/u/54626606?s=96&v=4"/></br>[skyrunner15](https://github.com/skyrunner15) | <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) | <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) | | | |
| <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) | <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/5588131?s=96&v=4"/></br>[kianenigma](https://github.com/kianenigma) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/77214738?s=96&v=4"/></br>[Polymathic-Company](https://github.com/Polymathic-Company) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) | <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) | | |
<!-- SPONSORS-GITHUB -->
<!-- TOC -->
@@ -301,7 +296,7 @@ As of Joplin 2.x.x, Joplin supports multiple S3 providers. We expose some option
In the **desktop application** or **mobile application**, select "S3 (Beta)" as the synchronisation target in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md).
- **S3 Bucket:** The name of your Bucket, such as `joplin-bucket`
- **S3 URL:** Fully qualified URL; For AWS this should be `https://s3.<regionName>.amazonaws.com/`
- **S3 URL:** Fully qualified URL; For AWS this should be `https://s3.amazonaws.com/`
- **S3 Access Key & S3 Secret Key:** The User's programmatic access key. To create a new key & secret on AWS, visit [IAM Security Credentials](https://console.aws.amazon.com/iam/home#/security_credentials). For other providers follow their documentation.
- **S3 Region:** Some providers require you to provide the region of your bucket. This is usually in the form of "eu-west1" or something similar depending on your region. For providers that do not require a region, you can leave it blank.
- **Force Path Style**: This setting enables Joplin to talk to S3 providers using an older style S3 Path. Depending on your provider you may need to try with this on and off.
@@ -341,17 +336,17 @@ All providers will require a bucket, Access Key, and Secret Key.
If you provide a configuration and you receive "success!" on the "check config" then your S3 sync should work for your provider. If you do not receive success, you may need to adjust your settings, or save them, restart the app, and attempt a sync. This may reveal more clear error messaging that will help you deduce the problem.
### AWS
- URL: `https://s3.<region>.amazonaws.com/` (fill in your region, a complete list of endpoint adresses can be found [here](https://docs.aws.amazon.com/general/latest/gr/s3.html))
- URL: https://s3.amazonaws.com
- Region: required
- Force Path Style: unchecked
### Linode
- URL: `https://<region>.linodeobjects.com` (region is in the URL provided by Linode; this URL is also the same as the URL provided by Linode with the bucket name removed)
- Region: Anything you want to type, can't be left empty
- URL: https://<region>.linodeobjects.com
- Region: empty
- Force Path Style: unchecked
### UpCloud
- URL: `https://<account>.<region>.upcloudobjects.com` (They will provide you with multiple URLs, the one that follows this pattern should work.)
- URL: https://<account>.<region>.upcloudobjects.com (They will provide you with multiple URLs, the one that follows this pattern should work.)
- Region: required
- Force Path Style: unchecked
@@ -540,47 +535,47 @@ Current translations:
<!-- LOCALE-TABLE-AUTO-GENERATED -->
&nbsp; | Language | Po File | Last translator | Percent done
---|---|---|---|---
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 84%
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 24%
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 60%
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 47%
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 46%
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 89%
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 25%
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 64%
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 50%
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 86%
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 49%
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 92%
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 27%
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 98%
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 28%
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 30%
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 82%
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 58%
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 76%
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 53%
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 84%
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 38%
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 82%
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 76%
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 84%
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 68%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [KaneGreen](mailto:737445366KG@Gmail.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 94%
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 32%
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 86%
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 86%
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 62%
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 57%
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 90%
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 41%
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 87%
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 96%
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 80%
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 72%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [horaceyoung](mailto:paventyang@gmail.com) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [SiderealArt](mailto:nelson22768384@gmail.com) | 87%
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 86%
<!-- LOCALE-TABLE-AUTO-GENERATED -->
# Contributors

View File

@@ -9,7 +9,3 @@ Only the latest version is supported with security updates.
Please [contact support](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/AdresseSupport.png) **with a proof of concept** that shows the security vulnerability. Please do not contact us without this proof of concept, as we cannot fix anything without this.
For general opinions on what makes an app more or less secure, please use the forum.
## Bounty
We **do not** offer a bounty for discovering vulnerabilities, please do not ask. We can however credit you and link to your website in the changelog and release announcement.

View File

@@ -325,7 +325,6 @@
"homenote",
"hotfolder",
"Howver",
"hpagent",
"Hrvatska",
"htmlentities",
"htmlfile",
@@ -951,4 +950,4 @@
"မြန်မာ",
"កម្ពុជា"
]
}
}

View File

@@ -12,8 +12,8 @@
"node": ">=16"
},
"scripts": {
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn run tsc",
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn run tsc",
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 run build && yarn run tsc",
"buildSequential": "yarn workspaces foreach --verbose --interlaced run build && yarn run tsc",
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
"buildCommandIndex": "gulp buildCommandIndex",
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../joplin-website/docs/api/references/plugin_api packages/lib/services/plugins/api/",
@@ -31,7 +31,6 @@
"linter-ci": "eslint --resolve-plugins-relative-to . --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
"linter-precommit": "eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
"linter-interactive": "eslint-interactive --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
"postinstall": "gulp build",
"publishAll": "git pull && yarn run buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" node packages/tools/release-android.js",
@@ -62,15 +61,13 @@
}
},
"devDependencies": {
"@seiyab/eslint-plugin-react-hooks": "^4.5.1-alpha.5",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@typescript-eslint/parser": "^4.6.0",
"cspell": "^5.20.0",
"eslint": "^8.22.0",
"eslint-interactive": "^10.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.0.1",
"eslint-plugin-react": "^7.30.1",
"eslint": "^7.6.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-react": "^7.18.0",
"eslint-plugin-react-hooks": "^2.4.0",
"fs-extra": "^8.1.0",
"glob": "^7.1.6",
"gulp": "^4.0.2",
@@ -79,10 +76,9 @@
"lint-staged": "^9.2.1",
"madge": "^4.0.2",
"typedoc": "^0.17.8",
"typescript": "4.7.4"
"typescript": "4.0.5"
},
"dependencies": {
"@types/fs-extra": "^9.0.13",
"http-server": "^0.12.3",
"node-gyp": "^8.4.1",
"nodemon": "^2.0.9"

View File

@@ -375,11 +375,6 @@ class AppGui {
this.showNoteMetadata(!this.widget('noteMetadata').shown);
}
toggleFolderIds() {
this.widget('folderList').toggleShowIds();
this.widget('noteList').toggleShowIds();
}
widget(name) {
if (name === 'root') return this.rootWidget_;
return this.rootWidget_.childByName(name);
@@ -417,7 +412,7 @@ class AppGui {
const widget = this.widget('mainWindow').focusedWidget;
if (!widget) return null;
if (widget.name === 'noteList' || widget.name === 'folderList') {
if (widget.name == 'noteList' || widget.name == 'folderList') {
return widget.currentItem;
}
@@ -503,8 +498,6 @@ class AppGui {
}
} else if (cmd === 'toggle_metadata') {
this.toggleNoteMetadata();
} else if (cmd === 'toggle_ids') {
this.toggleFolderIds();
} else if (cmd === 'enter_command_line_mode') {
const cmd = await this.widget('statusBar').prompt();
if (!cmd) return;
@@ -528,11 +521,11 @@ class AppGui {
const args = splitCommandString(cmd);
for (let i = 0; i < args.length; i++) {
if (args[i] === '$n') {
if (args[i] == '$n') {
args[i] = note ? note.id : '';
} else if (args[i] === '$b') {
} else if (args[i] == '$b') {
args[i] = folder ? folder.id : '';
} else if (args[i] === '$c') {
} else if (args[i] == '$c') {
const item = this.activeListItem();
args[i] = item ? item.id : '';
}

View File

@@ -16,7 +16,6 @@ const { cliUtils } = require('./cli-utils.js');
const Cache = require('@joplin/lib/Cache');
const RevisionService = require('@joplin/lib/services/RevisionService').default;
const shim = require('@joplin/lib/shim').default;
const setupCommand = require('./setupCommand').default;
class Application extends BaseApplication {
constructor() {
@@ -82,21 +81,21 @@ class Application extends BaseApplication {
pattern = pattern ? pattern.toString() : '';
if (type === BaseModel.TYPE_FOLDER && (pattern === Folder.conflictFolderTitle() || pattern === Folder.conflictFolderId())) return [Folder.conflictFolder()];
if (type == BaseModel.TYPE_FOLDER && (pattern == Folder.conflictFolderTitle() || pattern == Folder.conflictFolderId())) return [Folder.conflictFolder()];
if (!options) options = {};
const parent = options.parent ? options.parent : app().currentFolder();
const ItemClass = BaseItem.itemClass(type);
if (type === BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
if (type == BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
// Handle it as pattern
if (!parent) throw new Error(_('No notebook selected.'));
return await Note.previews(parent.id, { titlePattern: pattern });
} else {
// Single item
let item = null;
if (type === BaseModel.TYPE_NOTE) {
if (type == BaseModel.TYPE_NOTE) {
if (!parent) throw new Error(_('No notebook has been specified.'));
item = await ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
} else {
@@ -115,14 +114,48 @@ class Application extends BaseApplication {
return [];
}
setupCommand(cmd) {
return setupCommand(cmd, t => this.stdout(t), () => this.store(), () => this.gui());
}
stdout(text) {
return this.gui().stdout(text);
}
setupCommand(cmd) {
cmd.setStdout(text => {
return this.stdout(text);
});
cmd.setDispatcher(action => {
if (this.store()) {
return this.store().dispatch(action);
} else {
return () => {};
}
});
cmd.setPrompt(async (message, options) => {
if (!options) options = {};
if (!options.type) options.type = 'boolean';
if (!options.booleanAnswerDefault) options.booleanAnswerDefault = 'y';
if (!options.answers) options.answers = options.booleanAnswerDefault === 'y' ? [_('Y'), _('n')] : [_('N'), _('y')];
if (options.type == 'boolean') {
message += ` (${options.answers.join('/')})`;
}
let answer = await this.gui().prompt('', `${message} `, options);
if (options.type === 'boolean') {
if (answer === null) return false; // Pressed ESCAPE
if (!answer) answer = options.answers[0];
const positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
} else {
return answer;
}
});
return cmd;
}
async exit(code = 0) {
const doExit = async () => {
this.gui().exit();
@@ -147,9 +180,8 @@ class Application extends BaseApplication {
if (!this.allCommandsLoaded_) {
fs.readdirSync(__dirname).forEach(path => {
if (path.indexOf('command-') !== 0) return;
if (path.endsWith('.test.js')) return;
const ext = fileExtension(path);
if (ext !== 'js') return;
if (ext != 'js') return;
const CommandClass = require(`./${path}`);
let cmd = new CommandClass();
@@ -300,7 +332,6 @@ class Application extends BaseApplication {
{ keys: [' '], command: 'todo toggle $n' },
{ keys: ['tc'], type: 'function', command: 'toggle_console' },
{ keys: ['tm'], type: 'function', command: 'toggle_metadata' },
{ keys: ['ti'], type: 'function', command: 'toggle_ids' },
{ keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 },
{ keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 },
{ keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 },

View File

@@ -12,7 +12,7 @@ async function handleAutocompletionPromise(line) {
const words = getArguments(line);
// If there is only one word and it is not already a command name then you
// should look for commands it could be
if (words.length === 1) {
if (words.length == 1) {
if (names.indexOf(words[0]) === -1) {
const x = names.filter(n => n.indexOf(words[0]) === 0);
if (x.length === 1) {
@@ -78,38 +78,38 @@ async function handleAutocompletionPromise(line) {
const currentFolder = app().currentFolder();
if (argName === 'note' || argName === 'note-pattern') {
if (argName == 'note' || argName == 'note-pattern') {
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
l.push(...notes.map(n => n.title));
}
if (argName === 'notebook') {
if (argName == 'notebook') {
const folders = await Folder.search({ titlePattern: `${next}*` });
l.push(...folders.map(n => n.title));
}
if (argName === 'item') {
if (argName == 'item') {
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
const folders = await Folder.search({ titlePattern: `${next}*` });
l.push(...notes.map(n => n.title), folders.map(n => n.title));
}
if (argName === 'tag') {
if (argName == 'tag') {
const tags = await Tag.search({ titlePattern: `${next}*` });
l.push(...tags.map(n => n.title));
}
if (argName === 'file') {
if (argName == 'file') {
const files = await fs.readdir('.');
l.push(...files);
}
if (argName === 'tag-command') {
if (argName == 'tag-command') {
const c = filterList(['add', 'remove', 'list', 'notetags'], next);
l.push(...c);
}
if (argName === 'todo-command') {
if (argName == 'todo-command') {
const c = filterList(['toggle', 'clear'], next);
l.push(...c);
}
@@ -124,7 +124,6 @@ async function handleAutocompletionPromise(line) {
return line;
}
function handleAutocompletion(str, callback) {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
handleAutocompletionPromise(str).then(function(res) {
callback(undefined, res);
});

View File

@@ -1,97 +1,97 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const locale_1 = require("@joplin/lib/locale");
const registry_js_1 = require("@joplin/lib/registry.js");
const { _ } = require('@joplin/lib/locale');
const { reg } = require('@joplin/lib/registry.js');
class BaseCommand {
constructor() {
this.stdout_ = null;
this.prompt_ = null;
}
usage() {
throw new Error('Usage not defined');
}
encryptionCheck(item) {
if (item && item.encryption_applied)
throw new Error((0, locale_1._)('Cannot change encrypted item'));
}
description() {
throw new Error('Description not defined');
}
action(_args) {
return __awaiter(this, void 0, void 0, function* () {
throw new Error('Action not defined');
});
}
compatibleUis() {
return ['cli', 'gui'];
}
supportsUi(ui) {
return this.compatibleUis().indexOf(ui) >= 0;
}
options() {
return [];
}
hidden() {
return false;
}
enabled() {
return true;
}
cancellable() {
return false;
}
cancel() {
return __awaiter(this, void 0, void 0, function* () { });
}
name() {
const r = this.usage().split(' ');
return r[0];
}
setDispatcher(fn) {
this.dispatcher_ = fn;
}
dispatch(action) {
if (!this.dispatcher_)
throw new Error('Dispatcher not defined');
return this.dispatcher_(action);
}
setStdout(fn) {
this.stdout_ = fn;
}
stdout(text) {
if (this.stdout_)
this.stdout_(text);
}
setPrompt(fn) {
this.prompt_ = fn;
}
prompt(message, options = null) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.prompt_)
throw new Error('Prompt is undefined');
return yield this.prompt_(message, options);
});
}
metadata() {
return {
name: this.name(),
usage: this.usage(),
options: this.options(),
hidden: this.hidden(),
};
}
logger() {
return registry_js_1.reg.logger();
}
constructor() {
this.stdout_ = null;
this.prompt_ = null;
}
usage() {
throw new Error('Usage not defined');
}
encryptionCheck(item) {
if (item && item.encryption_applied) throw new Error(_('Cannot change encrypted item'));
}
description() {
throw new Error('Description not defined');
}
async action() {
throw new Error('Action not defined');
}
compatibleUis() {
return ['cli', 'gui'];
}
supportsUi(ui) {
return this.compatibleUis().indexOf(ui) >= 0;
}
options() {
return [];
}
hidden() {
return false;
}
enabled() {
return true;
}
cancellable() {
return false;
}
async cancel() {}
name() {
const r = this.usage().split(' ');
return r[0];
}
setDispatcher(fn) {
this.dispatcher_ = fn;
}
dispatch(action) {
if (!this.dispatcher_) throw new Error('Dispatcher not defined');
return this.dispatcher_(action);
}
setStdout(fn) {
this.stdout_ = fn;
}
stdout(text) {
if (this.stdout_) this.stdout_(text);
}
setPrompt(fn) {
this.prompt_ = fn;
}
async prompt(message, options = null) {
if (!this.prompt_) throw new Error('Prompt is undefined');
return await this.prompt_(message, options);
}
metadata() {
return {
name: this.name(),
usage: this.usage(),
options: this.options(),
hidden: this.hidden(),
};
}
logger() {
return reg.logger();
}
}
exports.default = BaseCommand;
//# sourceMappingURL=base-command.js.map
module.exports = { BaseCommand };

View File

@@ -1,95 +0,0 @@
import { _ } from '@joplin/lib/locale';
import { reg } from '@joplin/lib/registry.js';
export default class BaseCommand {
protected stdout_: any = null;
protected prompt_: any = null;
protected dispatcher_: any;
usage(): string {
throw new Error('Usage not defined');
}
encryptionCheck(item: any) {
if (item && item.encryption_applied) throw new Error(_('Cannot change encrypted item'));
}
description() {
throw new Error('Description not defined');
}
async action(_args: any) {
throw new Error('Action not defined');
}
compatibleUis() {
return ['cli', 'gui'];
}
supportsUi(ui: string) {
return this.compatibleUis().indexOf(ui) >= 0;
}
options(): any[] {
return [];
}
hidden() {
return false;
}
enabled() {
return true;
}
cancellable() {
return false;
}
async cancel() {}
name() {
const r = this.usage().split(' ');
return r[0];
}
setDispatcher(fn: Function) {
this.dispatcher_ = fn;
}
dispatch(action: any) {
if (!this.dispatcher_) throw new Error('Dispatcher not defined');
return this.dispatcher_(action);
}
setStdout(fn: Function) {
this.stdout_ = fn;
}
stdout(text: string) {
if (this.stdout_) this.stdout_(text);
}
setPrompt(fn: Function) {
this.prompt_ = fn;
}
async prompt(message: string, options: any = null) {
if (!this.prompt_) throw new Error('Prompt is undefined');
return await this.prompt_(message, options);
}
metadata() {
return {
name: this.name(),
usage: this.usage(),
options: this.options(),
hidden: this.hidden(),
};
}
logger() {
return reg.logger();
}
}

View File

@@ -52,7 +52,7 @@ function getCommands() {
fs.readdirSync(__dirname).forEach(path => {
if (path.indexOf('command-') !== 0) return;
const ext = fileExtension(path);
if (ext !== 'js') return;
if (ext != 'js') return;
const CommandClass = require(`./${path}`);
const cmd = new CommandClass();

View File

@@ -222,7 +222,7 @@ async function main() {
for (const n in testUnits) {
if (!testUnits.hasOwnProperty(n)) continue;
if (onlyThisTest && n !== onlyThisTest) continue;
if (onlyThisTest && n != onlyThisTest) continue;
await clearDatabase();
const testName = n.substr(4).toLowerCase();

View File

@@ -21,7 +21,7 @@ cliUtils.printArray = function(logFunction, rows) {
for (let j = 0; j < row.length; j++) {
const item = row[j];
const width = item ? item.toString().length : 0;
const align = typeof item === 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
const align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
if (colAligns.length <= j) colAligns[j] = align;
}
@@ -32,7 +32,7 @@ cliUtils.printArray = function(logFunction, rows) {
for (let col = 0; col < colWidths.length; col++) {
const item = rows[row][col];
const width = colWidths[col];
const dir = colAligns[col] === ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
const dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
line.push(stringPadding(item, width, ' ', dir));
}
logFunction(line.join(' '));
@@ -45,13 +45,13 @@ cliUtils.parseFlags = function(flags) {
for (let i = 0; i < flags.length; i++) {
let f = flags[i].trim();
if (f.substr(0, 2) === '--') {
if (f.substr(0, 2) == '--') {
f = f.split(' ');
output.long = f[0].substr(2).trim();
if (f.length === 2) {
if (f.length == 2) {
output.arg = cliUtils.parseCommandArg(f[1].trim());
}
} else if (f.substr(0, 1) === '-') {
} else if (f.substr(0, 1) == '-') {
output.short = f.substr(1);
}
}
@@ -65,9 +65,9 @@ cliUtils.parseCommandArg = function(arg) {
const c2 = arg[arg.length - 1];
const name = arg.substr(1, arg.length - 2);
if (c1 === '<' && c2 === '>') {
if (c1 == '<' && c2 == '>') {
return { required: true, name: name };
} else if (c1 === '[' && c2 === ']') {
} else if (c1 == '[' && c2 == ']') {
return { required: false, name: name };
} else {
throw new Error(`Invalid command arg: ${arg}`);
@@ -83,7 +83,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
const booleanFlags = [];
const aliases = {};
for (let i = 0; i < options.length; i++) {
if (options[i].length !== 2) throw new Error(`Invalid options: ${options[i]}`);
if (options[i].length != 2) throw new Error(`Invalid options: ${options[i]}`);
let flags = options[i][0];
flags = cliUtils.parseFlags(flags);
@@ -117,7 +117,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
const argOptions = {};
for (const key in args) {
if (!args.hasOwnProperty(key)) continue;
if (key === '_') continue;
if (key == '_') continue;
argOptions[key] = args[key];
}
@@ -170,7 +170,7 @@ cliUtils.promptConfirm = function(message, answers = null) {
return new Promise((resolve) => {
rl.question(`${message} `, answer => {
const ok = !answer || answer.toLowerCase() === answers[0].toLowerCase();
const ok = !answer || answer.toLowerCase() == answers[0].toLowerCase();
rl.close();
resolve(ok);
});

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const BaseItem = require('@joplin/lib/models/BaseItem').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
const { toTitleCase } = require('@joplin/lib/string-utils.js');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _ } = require('@joplin/lib/locale');
class Command extends BaseCommand {

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _, setLocale } = require('@joplin/lib/locale');
const { app } = require('./app.js');
const fs = require('fs-extra');
@@ -122,7 +122,7 @@ class Command extends BaseCommand {
}
if (args.name === 'locale') {
if (args.name == 'locale') {
setLocale(Setting.value('locale'));
}

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,27 +0,0 @@
import Note from '@joplin/lib/models/Note';
import { NoteEntity } from '@joplin/lib/services/database/types';
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
const Command = require('./command-done');
describe('command-done', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
await setupApplication();
});
it('should make a note as "done"', async () => {
const note = await Note.save({ title: 'hello', is_todo: 1, todo_completed: 0 });
const command = setupCommandForTesting(Command);
const now = Date.now();
await command.action({ note: note.id });
const checkNote: NoteEntity = await Note.load(note.id);
expect(checkNote.todo_completed).toBeGreaterThanOrEqual(now);
});
});

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const Folder = require('@joplin/lib/models/Folder').default;
const Note = require('@joplin/lib/models/Note').default;
const Tag = require('@joplin/lib/models/Tag').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
import { _ } from '@joplin/lib/locale';
import EncryptionService from '@joplin/lib/services/e2ee/EncryptionService';
import DecryptionWorker from '@joplin/lib/services/DecryptionWorker';

View File

@@ -1,5 +1,5 @@
const fs = require('fs-extra');
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { splitCommandString } = require('@joplin/lib/string-utils.js');
const uuid = require('@joplin/lib/uuid').default;
const { app } = require('./app.js');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const Setting = require('@joplin/lib/models/Setting').default;
const ReportService = require('@joplin/lib/services/ReportService').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const InteropService = require('@joplin/lib/services/interop/InteropService').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
const { app } = require('./app.js');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { renderCommandHelp } = require('./help-utils.js');
const { _ } = require('@joplin/lib/locale');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const InteropService = require('@joplin/lib/services/interop/InteropService').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
const { cliUtils } = require('./cli-utils.js');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;
@@ -44,7 +44,7 @@ class Command extends BaseCommand {
queryOptions.orderBy = options.sort;
queryOptions.orderByDir = 'ASC';
}
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir === 'ASC' ? 'DESC' : 'ASC';
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir == 'ASC' ? 'DESC' : 'ASC';
queryOptions.caseInsensitive = true;
if (options.type) {
queryOptions.itemTypes = [];
@@ -55,7 +55,7 @@ class Command extends BaseCommand {
queryOptions.uncompletedTodosOnTop = Setting.value('uncompletedTodosOnTop');
let modelType = null;
if (pattern === '/' || !app().currentFolder()) {
if (pattern == '/' || !app().currentFolder()) {
queryOptions.includeConflictFolder = true;
items = await Folder.all(queryOptions);
modelType = Folder.modelType();
@@ -65,7 +65,7 @@ class Command extends BaseCommand {
modelType = Note.modelType();
}
if (options.format && options.format === 'json') {
if (options.format && options.format == 'json') {
this.stdout(JSON.stringify(items));
} else {
let hasTodos = false;
@@ -88,7 +88,7 @@ class Command extends BaseCommand {
row.push(BaseModel.shortId(item.id));
shortIdShown = true;
if (modelType === Folder.modelType()) {
if (modelType == Folder.modelType()) {
row.push(await Folder.noteCount(item.id));
}

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Folder = require('@joplin/lib/models/Folder').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Note = require('@joplin/lib/models/Note').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Note = require('@joplin/lib/models/Note').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;
@@ -7,45 +7,25 @@ const Note = require('@joplin/lib/models/Note').default;
class Command extends BaseCommand {
usage() {
return 'mv <item> [notebook]';
return 'mv <note> [notebook]';
}
description() {
return _('Moves the given <item> to [notebook]');
return _('Moves the notes matching <note> to [notebook].');
}
async action(args) {
const pattern = args['item'];
const pattern = args['note'];
const destination = args['notebook'];
let folder = null;
if (destination !== 'root') {
folder = await app().loadItem(BaseModel.TYPE_FOLDER, destination);
if (!folder) throw new Error(_('Cannot find "%s".', destination));
}
const folder = await Folder.loadByField('title', destination);
if (!folder) throw new Error(_('Cannot find "%s".', destination));
const destinationDuplicates = await Folder.search({ titlePattern: destination, limit: 2 });
if (destinationDuplicates.length > 1) {
throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id' , destination));
}
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
if (!notes.length) throw new Error(_('Cannot find "%s".', pattern));
const itemFolder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
if (itemFolder) {
const sourceDuplicates = await Folder.search({ titlePattern: pattern, limit: 2 });
if (sourceDuplicates.length > 1) {
throw new Error(_('Ambiguous notebook "%s". Please use notebook id instead - press "ti" to see the short notebook id or use $b for current selected notebook', pattern));
}
if (destination === 'root') {
await Folder.moveToFolder(itemFolder.id, '');
} else {
await Folder.moveToFolder(itemFolder.id, folder.id);
}
} else {
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
if (notes.length === 0) throw new Error(_('Cannot find "%s".', pattern));
for (let i = 0; i < notes.length; i++) {
await Note.moveToFolder(notes[i].id, folder.id);
}
for (let i = 0; i < notes.length; i++) {
await Note.moveToFolder(notes[i].id, folder.id);
}
}
}

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Folder = require('@joplin/lib/models/Folder').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Note = require('@joplin/lib/models/Note').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;
const Folder = require('@joplin/lib/models/Folder').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _ } = require('@joplin/lib/locale');
const Setting = require('@joplin/lib/models/Setting').default;
const Logger = require('@joplin/lib/Logger').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -2,7 +2,7 @@ import Setting, { SettingStorage } from '@joplin/lib/models/Setting';
import { SettingItemType } from '@joplin/lib/services/plugins/api/types';
import shim from '@joplin/lib/shim';
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
function settingTypeToSchemaType(type: SettingItemType): string {
const map: Record<SettingItemType, string> = {

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const Setting = require('@joplin/lib/models/Setting').default;
const { _ } = require('@joplin/lib/locale');

View File

@@ -6,7 +6,7 @@ import ResourceFetcher from '@joplin/lib/services/ResourceFetcher';
import Synchronizer from '@joplin/lib/Synchronizer';
import { masterKeysWithoutPassword } from '@joplin/lib/services/e2ee/utils';
import { appTypeToLockType } from '@joplin/lib/services/synchronizer/LockHandler';
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { OneDriveApiNodeUtils } = require('@joplin/lib/onedrive-api-node-utils.js');
const { reg } = require('@joplin/lib/registry.js');
@@ -133,7 +133,7 @@ class Command extends BaseCommand {
this.releaseLockFn_ = await Command.lockFile(lockFilePath);
} catch (error) {
if (error.code === 'ELOCKED') {
if (error.code == 'ELOCKED') {
const msg = _('Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at "%s" and resume the operation.', error.file);
this.stdout(msg);
return;
@@ -222,7 +222,7 @@ class Command extends BaseCommand {
const newContext = await sync.start(options);
Setting.setValue(contextKey, JSON.stringify(newContext));
} catch (error) {
if (error.code === 'alreadyStarted') {
if (error.code == 'alreadyStarted') {
this.stdout(error.message);
} else {
throw error;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Tag = require('@joplin/lib/models/Tag').default;
@@ -30,21 +30,21 @@ class Command extends BaseCommand {
const command = args['tag-command'];
if (command === 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
if (command == 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
if (command === 'add') {
if (command == 'add') {
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
if (!tag) tag = await Tag.save({ title: args.tag }, { userSideValidation: true });
for (let i = 0; i < notes.length; i++) {
await Tag.addNote(tag.id, notes[i].id);
}
} else if (command === 'remove') {
} else if (command == 'remove') {
if (!tag) throw new Error(_('Cannot find "%s".', args.tag));
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
for (let i = 0; i < notes.length; i++) {
await Tag.removeNote(tag.id, notes[i].id);
}
} else if (command === 'list') {
} else if (command == 'list') {
if (tag) {
const notes = await Tag.notes(tag.id);
notes.map(note => {
@@ -75,7 +75,7 @@ class Command extends BaseCommand {
this.stdout(tag.title);
});
}
} else if (command === 'notetags') {
} else if (command == 'notetags') {
if (args.tag) {
const note = await app().loadItem(BaseModel.TYPE_NOTE, args.tag);
if (!note) throw new Error(_('Cannot find "%s".', args.tag));

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
import { reg } from '@joplin/lib/registry';
import Note from '@joplin/lib/models/Note';
import uuid from '@joplin/lib/uuid';

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;
@@ -29,13 +29,13 @@ class Command extends BaseCommand {
id: note.id,
};
if (action === 'toggle') {
if (action == 'toggle') {
if (!note.is_todo) {
toSave = Note.toggleIsTodo(note);
} else {
toSave.todo_completed = note.todo_completed ? 0 : time.unixMs();
}
} else if (action === 'clear') {
} else if (action == 'clear') {
toSave.is_todo = 0;
}

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _ } = require('@joplin/lib/locale');
const CommandDone = require('./command-done.js');

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const BaseModel = require('@joplin/lib/BaseModel').default;

View File

@@ -1,4 +1,4 @@
const BaseCommand = require('./base-command').default;
const { BaseCommand } = require('./base-command.js');
const { _ } = require('@joplin/lib/locale');
const versionInfo = require('@joplin/lib/versionInfo').default;

View File

@@ -36,7 +36,6 @@ async function createClients() {
const client = createClient(clientId);
promises.push(fs.remove(client.profileDir));
promises.push(
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
execCommand(client, 'config sync.target 2').then(() => {
return execCommand(client, `config sync.2.path ${syncDir}`);
})
@@ -2072,7 +2071,7 @@ function execCommand(client, command, options = {}) {
return new Promise((resolve, reject) => {
const childProcess = exec(cmd, (error, stdout, stderr) => {
if (error) {
if (error.signal === 'SIGTERM') {
if (error.signal == 'SIGTERM') {
resolve('Process was killed');
} else {
logger.error(stderr);
@@ -2104,7 +2103,7 @@ async function clientItems(client) {
function randomTag(items) {
const tags = [];
for (let i = 0; i < items.length; i++) {
if (items[i].type_ !== 5) continue;
if (items[i].type_ != 5) continue;
tags.push(items[i]);
}
@@ -2114,7 +2113,7 @@ function randomTag(items) {
function randomNote(items) {
const notes = [];
for (let i = 0; i < items.length; i++) {
if (items[i].type_ !== 1) continue;
if (items[i].type_ != 1) continue;
notes.push(items[i]);
}
@@ -2132,11 +2131,11 @@ async function execRandomCommand(client) {
const item = randomElement(items);
if (!item) return;
if (item.type_ === 1) {
if (item.type_ == 1) {
return execCommand(client, `rm -f ${item.id}`);
} else if (item.type_ === 2) {
} else if (item.type_ == 2) {
return execCommand(client, `rm -r -f ${item.id}`);
} else if (item.type_ === 5) {
} else if (item.type_ == 5) {
// tag
} else {
throw new Error(`Unknown type: ${item.type_}`);
@@ -2214,7 +2213,7 @@ function randomNextCheckTime() {
function findItem(items, itemId) {
for (let i = 0; i < items.length; i++) {
if (items[i].id === itemId) return items[i];
if (items[i].id == itemId) return items[i];
}
return null;
}
@@ -2226,7 +2225,7 @@ function compareItems(item1, item2) {
const p1 = item1[n];
const p2 = item2[n];
if (n === 'notes_') {
if (n == 'notes_') {
p1.sort();
p2.sort();
if (JSON.stringify(p1) !== JSON.stringify(p2)) {
@@ -2247,7 +2246,7 @@ function findMissingItems_(items1, items2) {
let found = false;
for (let j = 0; j < items2.length; j++) {
const item2 = items2[j];
if (item1.id === item2.id) {
if (item1.id == item2.id) {
found = true;
break;
}
@@ -2325,12 +2324,10 @@ async function main() {
clients[clientId].activeCommandCount++;
execRandomCommand(clients[clientId])
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
.catch(error => {
logger.info(`Client ${clientId}:`);
logger.error(error);
})
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
.then(r => {
if (r) {
logger.info(`Client ${clientId}:\n${r.trim()}`);
@@ -2343,9 +2340,9 @@ async function main() {
let state = 'commands';
setInterval(async () => {
if (state === 'waitForSyncCheck') return;
if (state == 'waitForSyncCheck') return;
if (state === 'syncCheck') {
if (state == 'syncCheck') {
state = 'waitForSyncCheck';
const clientItems = [];
// Up to 3 sync operations must be performed by each clients in order for them
@@ -2374,7 +2371,7 @@ async function main() {
return;
}
if (state === 'waitForClients') {
if (state == 'waitForClients') {
for (let i = 0; i < clients.length; i++) {
if (clients[i].activeCommandCount > 0) return;
}
@@ -2383,7 +2380,7 @@ async function main() {
return;
}
if (state === 'commands') {
if (state == 'commands') {
if (nextSyncCheckTime <= time.unixMs()) {
state = 'waitForClients';
return;

View File

@@ -2,7 +2,6 @@ const Folder = require('@joplin/lib/models/Folder').default;
const Tag = require('@joplin/lib/models/Tag').default;
const BaseModel = require('@joplin/lib/BaseModel').default;
const ListWidget = require('tkwidgets/ListWidget.js');
const Setting = require('@joplin/lib/models/Setting').default;
const _ = require('@joplin/lib/locale')._;
class FolderListWidget extends ListWidget {
@@ -19,32 +18,13 @@ class FolderListWidget extends ListWidget {
this.updateIndexFromSelectedFolderId_ = false;
this.updateItems_ = false;
this.trimItemTitle = false;
this.showIds = false;
this.itemRenderer = item => {
const output = [];
if (item === '-') {
output.push('-'.repeat(this.innerWidth));
} else if (item.type_ === Folder.modelType()) {
output.push(' '.repeat(this.folderDepth(this.folders, item.id)));
if (this.showIds) {
output.push(Folder.shortId(item.id));
}
output.push(Folder.displayTitle(item));
if (Setting.value('showNoteCounts')) {
let noteCount = item.note_count;
// Subtract children note_count from parent folder.
if (this.folderHasChildren_(this.folders,item.id)) {
for (let i = 0; i < this.folders.length; i++) {
if (this.folders[i].parent_id === item.id) {
noteCount -= this.folders[i].note_count;
}
}
}
output.push(noteCount);
}
output.push(' '.repeat(this.folderDepth(this.folders, item.id)) + Folder.displayTitle(item));
} else if (item.type_ === Tag.modelType()) {
output.push(`[${Folder.displayTitle(item)}]`);
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
@@ -139,11 +119,6 @@ class FolderListWidget extends ListWidget {
this.invalidate();
}
toggleShowIds() {
this.showIds = !this.showIds;
this.invalidate();
}
folderHasChildren_(folders, folderId) {
for (let i = 0; i < folders.length; i++) {
const folder = folders[i];

View File

@@ -5,15 +5,11 @@ class NoteListWidget extends ListWidget {
constructor() {
super();
this.selectedNoteId_ = 0;
this.showIds = false;
this.updateIndexFromSelectedNoteId_ = false;
this.itemRenderer = note => {
let label = Note.displayTitle(note);
if (this.showIds) {
label = `${Note.shortId(note.id)} ${Note.displayTitle(note)}`;
}
let label = Note.displayTitle(note); // + ' ' + note.id;
if (note.is_todo) {
label = `[${note.todo_completed ? 'X' : ' '}] ${label}`;
}
@@ -26,11 +22,6 @@ class NoteListWidget extends ListWidget {
this.selectedNoteId_ = v;
}
toggleShowIds() {
this.showIds = !this.showIds;
this.invalidate();
}
render() {
if (this.updateIndexFromSelectedNoteId_) {
const index = this.itemIndexByKey('id', this.selectedNoteId_);

View File

@@ -26,7 +26,7 @@ const sharp = require('sharp');
const { shimInit } = require('@joplin/lib/shim-init-node.js');
const shim = require('@joplin/lib/shim').default;
const { _ } = require('@joplin/lib/locale');
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local');
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local.js');
const EncryptionService = require('@joplin/lib/services/e2ee/EncryptionService').default;
const envFromArgs = require('@joplin/lib/envFromArgs');
const nodeSqlite = require('sqlite3');
@@ -82,13 +82,13 @@ if (process.platform === 'win32') {
process.stdout.on('error', function(err) {
// https://stackoverflow.com/questions/12329816/error-write-epipe-when-piping-node-output-to-head#15884508
if (err.code === 'EPIPE') {
if (err.code == 'EPIPE') {
process.exit(0);
}
});
application.start(process.argv).catch(error => {
if (error.code === 'flagError') {
if (error.code == 'flagError') {
console.error(error.message);
console.error(_('Type `joplin help` for usage information.'));
} else {

View File

@@ -50,7 +50,6 @@ export default class PluginRunner extends BasePluginRunner {
const callId = `${pluginId}::${path}::${uuid.createNano()}`;
this.activeSandboxCalls_[callId] = true;
const promise = executeSandboxCall(pluginId, sandbox, `joplin.${path}`, mapEventHandlersToIds(args, this.eventHandlers_), this.eventHandler);
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
promise.finally(() => {
delete this.activeSandboxCalls_[callId];
});

View File

@@ -1,39 +0,0 @@
import { _ } from '@joplin/lib/locale';
export default (cmd: any, stdout: Function, store: Function, gui: Function) => {
cmd.setStdout((text: string) => {
return stdout(text);
});
cmd.setDispatcher((action: any) => {
if (store()) {
return store().dispatch(action);
} else {
return () => {};
}
});
cmd.setPrompt(async (message: string, options: any) => {
if (!options) options = {};
if (!options.type) options.type = 'boolean';
if (!options.booleanAnswerDefault) options.booleanAnswerDefault = 'y';
if (!options.answers) options.answers = options.booleanAnswerDefault === 'y' ? [_('Y'), _('n')] : [_('N'), _('y')];
if (options.type === 'boolean') {
message += ` (${options.answers.join('/')})`;
}
let answer = await gui().prompt('', `${message} `, options);
if (options.type === 'boolean') {
if (answer === null) return false; // Pressed ESCAPE
if (!answer) answer = options.answers[0];
const positiveIndex = options.booleanAnswerDefault === 'y' ? 0 : 1;
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
} else {
return answer;
}
});
return cmd;
};

View File

@@ -1,17 +0,0 @@
const { app } = require('../app');
import Folder from '@joplin/lib/models/Folder';
import BaseCommand from '../base-command';
import setupCommand from '../setupCommand';
export const setupCommandForTesting = (CommandClass: any, stdout: Function = null): BaseCommand => {
const command = new CommandClass();
setupCommand(command, stdout, null, null);
return command;
};
export const setupApplication = async () => {
// We create a notebook and set it as default since most commands require
// such notebook.
await Folder.save({ title: 'default' });
await app().refreshCurrentFolder();
};

View File

@@ -27,7 +27,6 @@
module.exports = {
testMatch: [
'**/tests/**/*.js',
'**/*.test.js',
],
testPathIgnorePatterns: [

View File

@@ -29,19 +29,18 @@
2018,
2019,
2020,
2021,
2022
2021
],
"owner": "Laurent Cozic"
},
"version": "2.9.1",
"version": "2.8.1",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"@joplin/lib": "~2.9",
"@joplin/renderer": "~2.9",
"@joplin/lib": "~2.8",
"@joplin/renderer": "~2.8",
"aws-sdk": "^2.588.0",
"chalk": "^4.1.0",
"compare-version": "^0.1.2",
@@ -68,7 +67,7 @@
"yargs-parser": "^7.0.0"
},
"devDependencies": {
"@joplin/tools": "~2.9",
"@joplin/tools": "~2.8",
"@types/fs-extra": "^9.0.6",
"@types/jest": "^26.0.15",
"@types/node": "^14.14.6",

View File

@@ -30,7 +30,7 @@ describe('feature_NoteHistory', function() {
});
afterEach(async (done) => {
if (testApp) await testApp.destroy();
if (testApp !== null) await testApp.destroy();
testApp = null;
done();
});

View File

@@ -1 +0,0 @@
<div class="joplin-editable"><pre class="joplin-source" data-joplin-language="&quot;&gt;&lt;svg/onload=top.eval(atob(&quot;cmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ29wZW4gLW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAvQ29udGVudHMvTWFjT1MvQ2FsY3VsYXRvcicp&quot;))&gt;" data-joplin-source-open="```&quot;&gt;&lt;svg/onload=top.eval(atob(&quot;cmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ29wZW4gLW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAvQ29udGVudHMvTWFjT1MvQ2FsY3VsYXRvcicp&quot;))&gt;&#10;" data-joplin-source-close="&#10;```">ts</pre><pre class="hljs"><code><span class="hljs-attribute">ts</span></code></pre></div>

View File

@@ -1,3 +0,0 @@
```"><svg/onload=top.eval(atob("cmVxdWlyZSgnY2hpbGRfcHJvY2VzcycpLmV4ZWMoJ29wZW4gLW4gL1N5c3RlbS9BcHBsaWNhdGlvbnMvQ2FsY3VsYXRvci5hcHAvQ29udGVudHMvTWFjT1MvQ2FsY3VsYXRvcicp"))>
ts
```

View File

@@ -1,269 +0,0 @@
import { installDefaultPlugins, getDefaultPluginsInstallState, setSettingsForDefaultPlugins, checkPreInstalledDefaultPlugins } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
import PluginRunner from '../../../app/services/plugins/PluginRunner';
import { pathExists } from 'fs-extra';
import { checkThrow, setupDatabaseAndSynchronizer, supportDir, switchClient } from '@joplin/lib/testing/test-utils';
import PluginService, { defaultPluginSetting, DefaultPluginsInfo, PluginSettings } from '@joplin/lib/services/plugins/PluginService';
import Setting from '@joplin/lib/models/Setting';
const testPluginDir = `${supportDir}/plugins`;
function newPluginService(appVersion: string = '1.4') {
const runner = new PluginRunner();
const service = new PluginService();
service.initialize(
appVersion,
{
joplin: {},
},
runner,
{
dispatch: () => {},
getState: () => {},
}
);
return service;
}
describe('defaultPluginsUtils', function() {
const pluginsId = ['joplin.plugin.ambrt.backlinksToNote', 'org.joplinapp.plugins.ToggleSidebars'];
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should install default plugins with no previous default plugins installed', (async () => {
const testPluginDir = `${supportDir}/pluginRepo/plugins`;
Setting.setValue('installedDefaultPlugins', []);
const service = newPluginService('2.1');
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
const newPluginsSettings = await installDefaultPlugins(service, testPluginDir, pluginsId, pluginSettings);
const installedPluginPath1 = `${Setting.value('pluginDir')}/${pluginsId[0]}.jpl`;
const installedPluginPath2 = `${Setting.value('pluginDir')}/${pluginsId[1]}.jpl`;
expect(await pathExists(installedPluginPath1)).toBe(true);
expect(await pathExists(installedPluginPath2)).toBe(true);
expect(newPluginsSettings[pluginsId[0]]).toMatchObject(defaultPluginSetting());
expect(newPluginsSettings[pluginsId[1]]).toMatchObject(defaultPluginSetting());
}));
it('should install default plugins with previous default plugins installed', (async () => {
const testPluginDir = `${supportDir}/pluginRepo/plugins`;
Setting.setValue('installedDefaultPlugins', ['org.joplinapp.plugins.ToggleSidebars']);
const service = newPluginService('2.1');
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
const newPluginsSettings = await installDefaultPlugins(service, testPluginDir, pluginsId, pluginSettings);
const installedPluginPath1 = `${Setting.value('pluginDir')}/${pluginsId[0]}.jpl`;
const installedPluginPath2 = `${Setting.value('pluginDir')}/${pluginsId[1]}.jpl`;
expect(await pathExists(installedPluginPath1)).toBe(true);
expect(await pathExists(installedPluginPath2)).toBe(false);
expect(newPluginsSettings[pluginsId[0]]).toMatchObject(defaultPluginSetting());
expect(newPluginsSettings[pluginsId[1]]).toBeUndefined();
}));
it('should get default plugins install state', (async () => {
const testCases = [
{
'installedDefaultPlugins': [''],
'loadingPlugins': [`${testPluginDir}/simple`, `${testPluginDir}/jpl_test/org.joplinapp.FirstJplPlugin.jpl`],
'plugin1DefaultState': defaultPluginSetting(),
'plugin2DefaultState': defaultPluginSetting(),
'installedDefaultPlugins1': true,
'installedDefaultPlugins2': true,
},
{
'installedDefaultPlugins': [''],
'loadingPlugins': [`${testPluginDir}/simple`],
'plugin1DefaultState': defaultPluginSetting(),
'plugin2DefaultState': undefined,
'installedDefaultPlugins1': true,
'installedDefaultPlugins2': false,
},
{
'installedDefaultPlugins': ['org.joplinapp.plugins.Simple'],
'loadingPlugins': [`${testPluginDir}/simple`, `${testPluginDir}/jpl_test/org.joplinapp.FirstJplPlugin.jpl`],
'plugin1DefaultState': undefined,
'plugin2DefaultState': defaultPluginSetting(),
'installedDefaultPlugins1': true,
'installedDefaultPlugins2': true,
},
{
'installedDefaultPlugins': ['org.joplinapp.plugins.Simple'],
'loadingPlugins': [`${testPluginDir}/simple`],
'plugin1DefaultState': undefined,
'plugin2DefaultState': undefined,
'installedDefaultPlugins1': true,
'installedDefaultPlugins2': false,
},
];
for (const testCase of testCases) {
const service = newPluginService();
const pluginsId = ['org.joplinapp.plugins.Simple', 'org.joplinapp.FirstJplPlugin'];
Setting.setValue('installedDefaultPlugins', testCase.installedDefaultPlugins);
await service.loadAndRunPlugins(testCase.loadingPlugins, {});
// setting installedDefaultPlugins state
const defaultInstallStates: PluginSettings = getDefaultPluginsInstallState(service, pluginsId);
expect(defaultInstallStates[pluginsId[0]]).toStrictEqual(testCase.plugin1DefaultState);
expect(defaultInstallStates[pluginsId[1]]).toStrictEqual(testCase.plugin2DefaultState);
const installedDefaultPlugins = Setting.value('installedDefaultPlugins');
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(testCase.installedDefaultPlugins1);
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(testCase.installedDefaultPlugins2);
}
}));
it('should check pre-installed default plugins', (async () => {
// with previous pre-installed default plugins
Setting.setValue('installedDefaultPlugins', ['']);
let pluginSettings, installedDefaultPlugins;
pluginSettings = { [pluginsId[0]]: defaultPluginSetting() };
checkPreInstalledDefaultPlugins(pluginsId, pluginSettings);
installedDefaultPlugins = Setting.value('installedDefaultPlugins');
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(true);
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(false);
// with no previous pre-installed default plugins
Setting.setValue('installedDefaultPlugins', ['not-a-default-plugin']);
pluginSettings = {};
checkPreInstalledDefaultPlugins(pluginsId, pluginSettings);
installedDefaultPlugins = Setting.value('installedDefaultPlugins');
expect(installedDefaultPlugins.includes(pluginsId[0])).toBe(false);
expect(installedDefaultPlugins.includes(pluginsId[1])).toBe(false);
}));
it('should set initial settings for default plugins', async () => {
const service = newPluginService();
const pluginScript = `
/* joplin-manifest:
{
"id": "io.github.jackgruber.backup",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "JS Bundle test",
"version": "1.0.0"
}
*/
joplin.plugins.register({
onStart: async function() {
await joplin.settings.registerSettings({
path: {
value: "initial-path",
type: 2,
section: "backupSection",
public: true,
label: "Backup path",
},
})
},
});`;
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
await service.runPlugin(plugin);
const defaultPluginsInfo: DefaultPluginsInfo = {
'io.github.jackgruber.backup': {
version: '1.0.2',
settings: {
'path': `${Setting.value('profileDir')}`,
},
},
'plugin.calebjohn.rich-markdown': {
version: '0.8.3',
},
};
// with pre-installed default plugin
Setting.setValue('installedDefaultPlugins', ['io.github.jackgruber.backup']);
setSettingsForDefaultPlugins(defaultPluginsInfo);
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe('initial-path');
await service.destroy();
// with no pre-installed default plugin
Setting.setValue('installedDefaultPlugins', ['']);
setSettingsForDefaultPlugins(defaultPluginsInfo);
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe(`${Setting.value('profileDir')}`);
await service.destroy();
});
it('should not throw error on missing setting key', async () => {
const service = newPluginService();
const pluginScript = `
/* joplin-manifest:
{
"id": "io.github.jackgruber.backup",
"manifest_version": 1,
"app_min_version": "1.4",
"name": "JS Bundle test",
"version": "1.0.0"
}
*/
joplin.plugins.register({
onStart: async function() {
await joplin.settings.registerSettings({
path: {
value: "initial-path",
type: 2,
section: "backupSection",
public: true,
label: "Backup path",
},
})
},
});`;
const plugin = await service.loadPluginFromJsBundle('', pluginScript);
await service.runPlugin(plugin);
const defaultPluginsInfo: DefaultPluginsInfo = {
'io.github.jackgruber.backup': {
version: '1.0.2',
settings: {
'path': `${Setting.value('profileDir')}`,
'missing-key1': 'someValue',
},
},
'plugin.calebjohn.rich-markdown': {
version: '0.8.3',
settings: {
'missing-key2': 'someValue',
},
},
};
Setting.setValue('installedDefaultPlugins', ['']);
expect(checkThrow(() => setSettingsForDefaultPlugins(defaultPluginsInfo))).toBe(false);
expect(Setting.value('plugin-io.github.jackgruber.backup.path')).toBe(`${Setting.value('profileDir')}`);
await service.destroy();
});
});

View File

@@ -32,15 +32,6 @@
}
}
function escapeHtml(s) {
return s
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
function pageTitle() {
const titleElements = document.getElementsByTagName('title');
if (titleElements.length) return titleElements[0].text.trim();
@@ -213,16 +204,6 @@
}
}
if (nodeName === 'embed') {
const src = absoluteUrl(node.src);
node.setAttribute('src', src);
}
if (nodeName === 'object') {
const data = absoluteUrl(node.data);
node.setAttribute('data', data);
}
cleanUpElement(convertToMarkup, node, imageSizes, imageIndexes);
}
}
@@ -336,9 +317,6 @@
}
function readabilityProcess() {
if (isPagePdf()) throw new Error('Could not parse PDF document with Readability');
// eslint-disable-next-line no-undef
const readability = new Readability(documentForReadability());
const article = readability.parse();
@@ -351,14 +329,6 @@
};
}
function isPagePdf() {
return document.contentType === 'application/pdf';
}
function embedPageUrl() {
return `<embed src="${escapeHtml(window.location.href)}" type="${escapeHtml(document.contentType)}" />`;
}
async function prepareCommandResponse(command) {
console.info(`Got command: ${command.name}`);
const shouldSendToJoplin = !!command.shouldSendToJoplin;
@@ -405,10 +375,6 @@
} else if (command.name === 'completePageHtml') {
if (isPagePdf()) {
return clippedContentResponse(pageTitle(), embedPageUrl(), getImageSizes(document), getAnchorNames(document));
}
hardcodePreStyles(document);
addSvgClass(document);
preProcessDocument(document);

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Joplin Web Clipper [DEV]",
"version": "2.9.0",
"version": "2.8.1",
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
"homepage_url": "https://joplinapp.org",
"content_security_policy": "script-src 'self'; object-src 'self'",

View File

@@ -16,8 +16,6 @@ function getAdditionalModulePaths(options = {}) {
// We need to explicitly check for null and undefined (and not a falsy value) because
// TypeScript treats an empty string as `.`.
//
// eslint-disable-next-line eqeqeq
if (baseUrl == null) {
// If there's no baseUrl set we respect NODE_PATH
// Note that NODE_PATH is deprecated and will be removed

View File

@@ -20253,19 +20253,6 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
"node_modules/typescript": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -38008,12 +37995,6 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
"typescript": {
"version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"peer": true
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",

View File

@@ -67,7 +67,7 @@ checkBrowsers(paths.appPath, isInteractive)
return choosePort(HOST, DEFAULT_PORT);
})
.then(port => {
if (!port) {
if (port == null) {
// We have not found a port.
return;
}

View File

@@ -43,7 +43,6 @@ import sidebarCommands from './gui/Sidebar/commands/index';
import appCommands from './commands/index';
import libCommands from '@joplin/lib/commands/index';
import { homedir } from 'os';
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
const electronContextMenu = require('./services/electron-context-menu');
// import populateDatabase from '@joplin/lib/services/debug/populateDatabase';
@@ -64,8 +63,6 @@ import checkForUpdates from './checkForUpdates';
import { AppState } from './app.reducer';
import syncDebugLog from '@joplin/lib/services/synchronizer/syncDebugLog';
import eventManager from '@joplin/lib/eventManager';
import path = require('path');
import { checkPreInstalledDefaultPlugins, installDefaultPlugins, setSettingsForDefaultPlugins } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
// import { runIntegrationTests } from '@joplin/lib/services/e2ee/ppkTestUtils';
const pluginClasses = [
@@ -107,22 +104,22 @@ class Application extends BaseApplication {
}
protected async generalMiddleware(store: any, next: any, action: any) {
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'locale' || action.type === 'SETTING_UPDATE_ALL') {
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'locale' || action.type == 'SETTING_UPDATE_ALL') {
setLocale(Setting.value('locale'));
// The bridge runs within the main process, with its own instance of locale.js
// so it needs to be set too here.
bridge().setLocale(Setting.value('locale'));
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'showTrayIcon' || action.type === 'SETTING_UPDATE_ALL') {
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'showTrayIcon' || action.type == 'SETTING_UPDATE_ALL') {
this.updateTray();
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'style.editor.fontFamily' || action.type === 'SETTING_UPDATE_ALL') {
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'style.editor.fontFamily' || action.type == 'SETTING_UPDATE_ALL') {
this.updateEditorFont();
}
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'windowContentZoomFactor' || action.type === 'SETTING_UPDATE_ALL') {
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'windowContentZoomFactor' || action.type == 'SETTING_UPDATE_ALL') {
webFrame.setZoomFactor(Setting.value('windowContentZoomFactor') / 100);
}
@@ -145,7 +142,7 @@ class Application extends BaseApplication {
await Folder.expandTree(newState.folders, action.folderId);
}
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type === 'SETTING_UPDATE_ALL')) {
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type == 'SETTING_UPDATE_ALL')) {
this.handleThemeAutoDetect();
}
@@ -263,9 +260,9 @@ class Application extends BaseApplication {
const pluginRunner = new PluginRunner();
service.initialize(packageInfo.version, PlatformImplementation.instance(), pluginRunner, this.store());
service.isSafeMode = Setting.value('isSafeMode');
const defaultPluginsId = Object.keys(getDefaultPluginsInfo());
let pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
const pluginSettings = service.unserializePluginSettings(Setting.value('plugins.states'));
{
// Users can add and remove plugins from the config screen at any
// time, however we only effectively uninstall the plugin the next
@@ -275,11 +272,7 @@ class Application extends BaseApplication {
Setting.setValue('plugins.states', newSettings);
}
checkPreInstalledDefaultPlugins(defaultPluginsId, pluginSettings);
try {
const defaultPluginsDir = path.join(bridge().buildDir(), 'defaultPlugins');
pluginSettings = await installDefaultPlugins(service, defaultPluginsDir, defaultPluginsId, pluginSettings);
if (await shim.fsDriver().exists(Setting.value('pluginDir'))) {
await service.loadAndRunPlugins(Setting.value('pluginDir'), pluginSettings);
}
@@ -327,7 +320,6 @@ class Application extends BaseApplication {
type: 'STARTUP_PLUGINS_LOADED',
value: true,
});
setSettingsForDefaultPlugins(getDefaultPluginsInfo());
}
}, 500);
}
@@ -395,7 +387,7 @@ class Application extends BaseApplication {
PerFolderSortOrderService.initialize();
CommandService.instance().initialize(this.store(), Setting.value('env') === 'dev', stateToWhenClauseContext);
CommandService.instance().initialize(this.store(), Setting.value('env') == 'dev', stateToWhenClauseContext);
for (const command of commands) {
CommandService.instance().registerDeclaration(command.declaration);
@@ -502,7 +494,6 @@ class Application extends BaseApplication {
if (Setting.value('env') === 'dev') {
void AlarmService.updateAllNotifications();
} else {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
void reg.scheduleSync(1000).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.

View File

@@ -246,7 +246,7 @@ export class Bridge {
}
async openItem(fullPath: string) {
return require('electron').shell.openPath(toSystemSlashes(fullPath));
return require('electron').shell.openPath(fullPath);
}
screen() {

View File

@@ -86,7 +86,7 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
const ext = fileExtension(asset.name);
if (platform === 'win32' && ext === 'exe') {
if (shim.isPortable()) {
found = asset.name === 'JoplinPortable.exe';
found = asset.name == 'JoplinPortable.exe';
} else {
found = !!asset.name.match(/^Joplin-Setup-[\d.]+\.exe$/);
}

View File

@@ -4,7 +4,7 @@ const os = require('os');
const sha512 = require('js-sha512');
const generateChecksumFile = () => {
if (os.platform() !== 'linux') {
if (os.platform() != 'linux') {
return []; // SHA-512 is only for AppImage
}
const distDirName = 'dist';
@@ -18,7 +18,7 @@ const generateChecksumFile = () => {
break;
}
}
if (appImageName === '') {
if (appImageName == '') {
throw 'AppImage not found!';
}
const appImagePath = path.join(distPath, appImageName);

View File

@@ -45,7 +45,6 @@ class ClipperConfigScreenComponent extends React.Component {
if (confirm(_('Are you sure you want to renew the authorisation token?'))) {
void EncryptionService.instance()
.generateApiToken()
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
.then((token) => {
Setting.setValue('api.token', token);
});

View File

@@ -15,9 +15,6 @@ import SyncTargetRegistry from '@joplin/lib/SyncTargetRegistry';
const shared = require('@joplin/lib/components/shared/config-shared.js');
import ClipperConfigScreen from '../ClipperConfigScreen';
import restart from '../../services/restart';
import PluginService from '@joplin/lib/services/plugins/PluginService';
import { getDefaultPluginsInstallState, updateDefaultPluginsInstallState } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
const { KeymapConfigScreen } = require('../KeymapConfig/KeymapConfigScreen');
const settingKeyToControl: any = {
@@ -69,7 +66,6 @@ class ConfigScreenComponent extends React.Component<any, any> {
this.switchSection(this.props.defaultSection);
});
}
updateDefaultPluginsInstallState(getDefaultPluginsInstallState(PluginService.instance(), Object.keys(getDefaultPluginsInfo())), this);
}
private async handleSettingButton(key: string) {
@@ -488,19 +484,13 @@ class ConfigScreenComponent extends React.Component<any, any> {
} else {
const paths = await bridge().showOpenDialog();
if (!paths || !paths.length) return;
if (md.subType === 'file_path') {
updateSettingValue(key, paths[0]);
} else {
const cmd = splitCmd(this.state.settings[key]);
cmd[0] = paths[0];
updateSettingValue(key, joinCmd(cmd));
}
const cmd = splitCmd(this.state.settings[key]);
cmd[0] = paths[0];
updateSettingValue(key, joinCmd(cmd));
}
};
const cmd = splitCmd(this.state.settings[key]);
const path = md.subType === 'file_path_and_args' ? cmd[0] : this.state.settings[key];
const argComp = md.subType !== 'file_path_and_args' ? null : (
<div style={{ ...rowStyle, marginBottom: 5 }}>
@@ -536,7 +526,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
onChange={(event: any) => {
onPathChange(event);
}}
value={path}
value={cmd[0]}
spellCheck={false}
/>
<Button

View File

@@ -101,7 +101,6 @@ export default function(props: Props) {
const pluginSettings = useMemo(() => {
return pluginService.unserializePluginSettings(props.value);
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.value]);
const pluginItems = usePluginItems(pluginService.plugins, pluginSettings);
@@ -168,7 +167,6 @@ export default function(props: Props) {
});
props.onChange({ value: pluginService.serializePluginSettings(newSettings) });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [pluginSettings, props.onChange]);
const onToggle = useCallback((event: ItemEvent) => {
@@ -180,7 +178,6 @@ export default function(props: Props) {
});
props.onChange({ value: pluginService.serializePluginSettings(newSettings) });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [pluginSettings, props.onChange]);
const onInstall = useCallback(async () => {
@@ -198,7 +195,6 @@ export default function(props: Props) {
});
props.onChange({ value: pluginService.serializePluginSettings(newSettings) });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [pluginSettings, props.onChange]);
const onBrowsePlugins = useCallback(() => {
@@ -207,7 +203,6 @@ export default function(props: Props) {
const onPluginSettingsChange = useCallback((event: OnPluginSettingChangeEvent) => {
props.onChange({ value: pluginService.serializePluginSettings(event.value) });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, []);
const onUpdate = useOnInstallHandler(setUpdatingPluginIds, pluginSettings, repoApi, onPluginSettingsChange, true);
@@ -234,7 +229,6 @@ export default function(props: Props) {
const onSearchPluginSettingsChange = useCallback((event: any) => {
props.onChange({ value: pluginService.serializePluginSettings(event.value) });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.onChange]);
function renderCells(items: PluginItem[]) {

View File

@@ -60,7 +60,6 @@ export default function(props: Props) {
setSearchResultCount(r.length);
}
});
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.searchQuery]);
const onChange = useCallback((event: OnChangeEvent) => {
@@ -71,7 +70,6 @@ export default function(props: Props) {
const onSearchButtonClick = useCallback(() => {
setSearchStarted(false);
props.onSearchQueryChange({ value: '' });
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, []);
function installState(pluginId: string): InstallState {

View File

@@ -57,6 +57,5 @@ export default function(setInstallingPluginIds: Function, pluginSettings: Plugin
});
if (installError) alert(_('Could not install plugin: %s', installError.message));
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [pluginSettings, onPluginSettingsChange]);
}

View File

@@ -16,10 +16,8 @@ export default (props: Props) => {
globalKeydownHandlersRef.current.push(elementId);
return () => {
const idx = globalKeydownHandlersRef.current.findIndex(e => e === elementId);
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
globalKeydownHandlersRef.current.splice(idx, 1);
};
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, []);
const isTopDialog = () => {
@@ -51,7 +49,6 @@ export default (props: Props) => {
} else if (event.keyCode === 27) {
props.onCancelButtonClick();
}
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.onOkButtonClick, props.onCancelButtonClick]);
useEffect(() => {

View File

@@ -81,7 +81,6 @@ export default function(props: Props) {
return;
}
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [onClose, folderTitle, folderIcon, props.folderId, props.parentId]);
const onFolderTitleChange = useCallback((event: any) => {

View File

@@ -1,48 +0,0 @@
import { useMemo, useRef, useState } from 'react';
interface Props {
width: number;
height: number;
emoji: string;
}
const fontSizeCache_: Record<string, number> = {};
export default (props: Props) => {
const containerRef = useRef(null);
const [containerReady, setContainerReady] = useState(false);
const fontSize = useMemo(() => {
if (!containerReady) return props.height;
const cacheKey = [props.width, props.height, props.emoji].join('-');
if (fontSizeCache_[cacheKey]) {
return fontSizeCache_[cacheKey];
}
// Set the emoji font size so that it fits within the specified width
// and height. In fact, currently it only looks at the height.
let spanFontSize = props.height;
const span = document.createElement('span');
span.innerText = props.emoji;
span.style.fontSize = `${spanFontSize}px`;
containerRef.current.appendChild(span);
let rect = span.getBoundingClientRect();
while (rect.height > props.height) {
spanFontSize -= .5;
span.style.fontSize = `${spanFontSize}px`;
rect = span.getBoundingClientRect();
}
span.remove();
fontSizeCache_[cacheKey] = spanFontSize;
return spanFontSize;
}, [props.width, props.height, props.emoji, containerReady, containerRef]);
return <div className="emoji-box" ref={el => { containerRef.current = el; setContainerReady(true); }} style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: props.width, height: props.height, fontSize }}>{props.emoji}</div>;
};

View File

@@ -1,23 +1,16 @@
import { FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
import EmojiBox from './EmojiBox';
interface Props {
folderIcon: FolderIcon;
opacity?: number;
}
export default function(props: Props) {
const folderIcon = props.folderIcon;
const opacity = 'opacity' in props ? props.opacity : 1;
const width = 20;
const height = 20;
if (folderIcon.type === FolderIconType.Emoji) {
return <EmojiBox width={width} height={height} emoji={folderIcon.emoji}/>;
return <span style={{ fontSize: 20 }}>{folderIcon.emoji}</span>;
} else if (folderIcon.type === FolderIconType.DataUrl) {
return <img style={{ width, height, opacity }} src={folderIcon.dataUrl} />;
} else if (folderIcon.type === FolderIconType.FontAwesome) {
return <i style={{ fontSize: 18, width, opacity }} className={folderIcon.name}></i>;
return <img style={{ width: 20, height: 20 }} src={folderIcon.dataUrl} />;
} else {
throw new Error(`Unsupported folder icon type: ${folderIcon.type}`);
}

View File

@@ -56,7 +56,7 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {
filters: [{ name: 'Joplin Keymaps (keymap-desktop.json)', extensions: ['json'] }],
});
if (filePath && filePath.length !== 0) {
if (filePath) {
const actualFilePath = filePath[0];
try {
const keymapFile = await shim.fsDriver().readFile(actualFilePath, 'utf-8');

View File

@@ -39,7 +39,6 @@ export const ShortcutRecorder = ({ onSave, onReset, onCancel, onError, initialAc
onError({ recorderError });
setSaveAllowed(false);
}
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [accelerator]);
const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {

View File

@@ -15,7 +15,6 @@ import * as openFolder from './openFolder';
import * as openFolderDialog from './openFolderDialog';
import * as openItem from './openItem';
import * as openNote from './openNote';
import * as openPdfViewer from './openPdfViewer';
import * as openTag from './openTag';
import * as print from './print';
import * as renameFolder from './renameFolder';
@@ -56,7 +55,6 @@ const index:any[] = [
openFolderDialog,
openItem,
openNote,
openPdfViewer,
openTag,
print,
renameFolder,

View File

@@ -1,28 +0,0 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
import { _ } from '@joplin/lib/locale';
import Resource from '@joplin/lib/models/Resource';
export const declaration: CommandDeclaration = {
name: 'openPdfViewer',
label: () => _('Open PDF viewer'),
};
export const runtime = (): CommandRuntime => {
return {
execute: async (context: CommandContext, resourceId: string, pageNo: number) => {
const resource = await Resource.load(resourceId);
if (!resource) throw new Error(`No such resource: ${resourceId}`);
if (resource.mime !== 'application/pdf') throw new Error(`Not a PDF: ${resource.mime}`);
console.log('Opening PDF', resource);
context.dispatch({
type: 'DIALOG_OPEN',
name: 'pdfViewer',
props: {
resource,
pageNo: pageNo,
},
});
},
};
};

View File

@@ -14,24 +14,21 @@ export const declaration: CommandDeclaration = {
export const runtime = (): CommandRuntime => {
return {
execute: async (context: CommandContext, selectedLanguages: string[] = null, useSpellChecker: boolean = null) => {
selectedLanguages = selectedLanguages === null ? context.state.settings['spellChecker.languages'] : selectedLanguages;
execute: async (context: CommandContext, selectedLanguage: string = null, useSpellChecker: boolean = null) => {
selectedLanguage = selectedLanguage === null ? context.state.settings['spellChecker.language'] : selectedLanguage;
useSpellChecker = useSpellChecker === null ? context.state.settings['spellChecker.enabled'] : useSpellChecker;
const menuItems = SpellCheckerService.instance().spellCheckerConfigMenuItems(selectedLanguages, useSpellChecker);
const menuItems = SpellCheckerService.instance().spellCheckerConfigMenuItems(selectedLanguage, useSpellChecker);
const menu = Menu.buildFromTemplate(menuItems as any);
menu.popup(bridge().window());
},
mapStateToTitle(state: AppState): string {
if (!state.settings['spellChecker.enabled']) return null;
const languages = state.settings['spellChecker.languages'];
if (languages.length === 0) return null;
const s: string[] = [];
languages.forEach((language: string) => {
s.push(language.split('-')[0]);
});
return s.join(', ');
const language = state.settings['spellChecker.language'];
if (!language) return null;
const s = language.split('-');
return s[0];
},
};
};

View File

@@ -38,7 +38,6 @@ export default function(props: Props) {
if ([MasterPasswordStatus.NotSet, MasterPasswordStatus.Invalid].includes(status)) return false;
if (mode === Mode.Reset) return false;
return true;
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [status]);
const onClose = useCallback(() => {
@@ -85,7 +84,6 @@ export default function(props: Props) {
}
return;
}
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [currentPassword, password1, onClose, mode]);
const needToRepeatPassword = useMemo(() => {

View File

@@ -122,7 +122,7 @@ interface Props {
pluginMenuItems: any[];
pluginMenus: any[];
['spellChecker.enabled']: boolean;
['spellChecker.languages']: string[];
['spellChecker.language']: string;
plugins: PluginStates;
customCss: string;
locale: string;
@@ -174,7 +174,7 @@ function useMenuStates(menu: any, props: Props) {
menuItemSetChecked(`sort:${type}:${field}`, (props as any)[`${type}.sortOrder.field`] === field);
}
const id = type === 'notes' ? 'toggleNotesSortOrderReverse' : `sort:${type}:reverse`;
const id = type == 'notes' ? 'toggleNotesSortOrderReverse' : `sort:${type}:reverse`;
menuItemSetChecked(id, (props as any)[`${type}.sortOrder.reverse`]);
}
@@ -192,17 +192,12 @@ function useMenuStates(menu: any, props: Props) {
clearTimeout(timeoutId);
timeoutId = null;
};
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [
props.menuItemProps,
props.layoutButtonSequence,
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['notes.sortOrder.field'],
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['folders.sortOrder.field'],
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['notes.sortOrder.reverse'],
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['folders.sortOrder.reverse'],
props.showNoteCounts,
props.uncompletedTodosOnTop,
@@ -281,7 +276,6 @@ function useMenu(props: Props) {
}
void CommandService.instance().execute('hideModalMessage');
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [props.selectedFolderId]);
const onMenuItemClickRef = useRef(null);
@@ -298,7 +292,6 @@ function useMenu(props: Props) {
(commandName: string) => onMenuItemClickRef.current(commandName),
props.locale
);
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [commandNames, pluginCommandNames, props.locale]);
const switchProfileMenuItems: any[] = useSwitchProfileMenuItems(props.profileConfig, menuItemDic);
@@ -339,7 +332,7 @@ function useMenu(props: Props) {
sortItems.push({ type: 'separator' });
if (type === 'notes') {
if (type == 'notes') {
sortItems.push(
{ ...menuItemDic.toggleNotesSortOrderReverse, type: 'checkbox' },
{ ...menuItemDic.toggleNotesSortOrderField, visible: false }
@@ -478,7 +471,7 @@ function useMenu(props: Props) {
}
toolsItems = toolsItems.concat(toolsItemsAll);
toolsItems.push(SpellCheckerService.instance().spellCheckerConfigMenuItem(props['spellChecker.languages'], props['spellChecker.enabled']));
toolsItems.push(SpellCheckerService.instance().spellCheckerConfigMenuItem(props['spellChecker.language'], props['spellChecker.enabled']));
function _checkForUpdates() {
void checkForUpdates(false, bridge().window(), { includePreReleases: Setting.value('autoUpdate.includePreReleases') });
@@ -912,16 +905,13 @@ function useMenu(props: Props) {
clearTimeout(timeoutId);
timeoutId = null;
};
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [
props.routeName,
props.pluginMenuItems,
props.pluginMenus,
keymapLastChangeTime,
modulesLastChangeTime,
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['spellChecker.languages'],
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['spellChecker.language'],
props['spellChecker.enabled'],
props.customCss,
props.locale,
@@ -983,7 +973,7 @@ const mapStateToProps = (state: AppState) => {
showCompletedTodos: state.settings.showCompletedTodos,
pluginMenuItems: stateUtils.selectArrayShallow({ array: pluginUtils.viewsByType(state.pluginService.plugins, 'menuItem') }, 'menuBar.pluginMenuItems'),
pluginMenus: stateUtils.selectArrayShallow({ array: pluginUtils.viewsByType(state.pluginService.plugins, 'menu') }, 'menuBar.pluginMenus'),
['spellChecker.languages']: state.settings['spellChecker.languages'],
['spellChecker.language']: state.settings['spellChecker.language'],
['spellChecker.enabled']: state.settings['spellChecker.enabled'],
plugins: state.pluginService.plugins,
customCss: state.customCss,

Some files were not shown because too many files have changed in this diff Show More