You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-26 23:38:08 +02:00
Compare commits
78 Commits
release-1.
...
ui_update
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8390d75293 | ||
|
|
75e62b86a1 | ||
|
|
840d3e9c60 | ||
|
|
a2b747c63d | ||
|
|
374ee3baf5 | ||
|
|
58574a2d0e | ||
|
|
96ac6887ce | ||
|
|
d4cc7ba85b | ||
|
|
6919be2908 | ||
|
|
cc6d7cebfa | ||
|
|
7ac224df52 | ||
|
|
a2861e476b | ||
|
|
76f44fe09f | ||
|
|
6f1e8fba2c | ||
|
|
fa65e29fb0 | ||
|
|
277fa0827e | ||
|
|
0907cf6e88 | ||
|
|
85296a8c09 | ||
|
|
b9a88c9c44 | ||
|
|
e4ffebbbc4 | ||
|
|
427e90fbf7 | ||
|
|
204be519c1 | ||
|
|
20bd001878 | ||
|
|
f016d6d6e5 | ||
|
|
96960a7407 | ||
|
|
7b233084fe | ||
|
|
74355d5320 | ||
|
|
fbfd5942ce | ||
|
|
eaca80d6c8 | ||
|
|
68f5494e3c | ||
|
|
cf462b7e03 | ||
|
|
73a7b683d1 | ||
|
|
1cc348d620 | ||
|
|
25ab1704c6 | ||
|
|
cb12c54eb7 | ||
|
|
3959a441da | ||
|
|
ab26949ad4 | ||
|
|
af4a93c9d1 | ||
|
|
e364ae9133 | ||
|
|
a66c40e999 | ||
|
|
016943f7eb | ||
|
|
2dee827bb8 | ||
|
|
27700028ee | ||
|
|
56ba7663fd | ||
|
|
64413405d7 | ||
|
|
f2469c9bf7 | ||
|
|
81140debdd | ||
|
|
274861fdeb | ||
|
|
8b76699949 | ||
|
|
1f301cc841 | ||
|
|
8bcf096840 | ||
|
|
d2a31f0ef2 | ||
|
|
02a8b22163 | ||
|
|
15d55d537e | ||
|
|
488ba01f60 | ||
|
|
d7efc4aaca | ||
|
|
19ed685a36 | ||
|
|
184e22937a | ||
|
|
5b81aa1fdb | ||
|
|
7bb3ba9f3e | ||
|
|
54ef47120b | ||
|
|
f83129cf2f | ||
|
|
9ec5030830 | ||
|
|
4758035b45 | ||
|
|
33895bbc4e | ||
|
|
3b36cac7f5 | ||
|
|
3acb1a2836 | ||
|
|
9348499b63 | ||
|
|
9c61cfd39b | ||
|
|
6445361bd9 | ||
|
|
7ad0c0b9bd | ||
|
|
a405a67367 | ||
|
|
fc6f29636a | ||
|
|
ac4e885748 | ||
|
|
c120c6095a | ||
|
|
af762f7839 | ||
|
|
31a44ac319 | ||
|
|
3ff8fa87a8 |
@@ -119,7 +119,6 @@ ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
|
||||
@@ -146,7 +145,6 @@ ElectronClient/gui/NoteList/NoteList.js
|
||||
ElectronClient/gui/NoteListControls/commands/focusSearch.js
|
||||
ElectronClient/gui/NoteListControls/NoteListControls.js
|
||||
ElectronClient/gui/NoteListItem.js
|
||||
ElectronClient/gui/NoteTextViewer.js
|
||||
ElectronClient/gui/NoteToolbar/NoteToolbar.js
|
||||
ElectronClient/gui/OneDriveLoginScreen.js
|
||||
ElectronClient/gui/ResizableLayout/hooks/useLayoutItemSizes.js
|
||||
@@ -166,7 +164,6 @@ ElectronClient/gui/style/StyledInput.js
|
||||
ElectronClient/gui/style/StyledTextInput.js
|
||||
ElectronClient/gui/ToggleEditorsButton/styles/index.js
|
||||
ElectronClient/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||
ElectronClient/gui/ToolbarBase.js
|
||||
ElectronClient/gui/ToolbarButton/styles/index.js
|
||||
ElectronClient/gui/ToolbarButton/ToolbarButton.js
|
||||
ReactNativeClient/lib/AsyncActionQueue.js
|
||||
@@ -178,7 +175,6 @@ ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
||||
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||
ReactNativeClient/lib/hooks/usePrevious.js
|
||||
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||
@@ -186,7 +182,6 @@ ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
||||
ReactNativeClient/lib/JoplinServerApi.js
|
||||
ReactNativeClient/lib/ntpDate.js
|
||||
ReactNativeClient/lib/services/CommandService.js
|
||||
ReactNativeClient/lib/services/debug/populateDatabase.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainService.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -50,8 +50,8 @@ joplin-webclipper-source.zip
|
||||
Tools/commit_hook.txt
|
||||
.vscode/*
|
||||
*.map
|
||||
ReactNativeClient/lib/sql-extensions/spellfix.so
|
||||
ReactNativeClient/lib/sql-extensions/spellfix.dylib
|
||||
ReactNativeClient/lib/sql-extensions/
|
||||
!ReactNativeClient/lib/sql-extensions/spellfix.dll
|
||||
|
||||
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
|
||||
CliClient/app/LinkSelector.js
|
||||
@@ -112,7 +112,6 @@ ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/types.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useCursorUtils.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearch.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useJoplinMode.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useKeymap.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useLineSorting.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useListIdent.js
|
||||
ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollUtils.js
|
||||
@@ -139,7 +138,6 @@ ElectronClient/gui/NoteList/NoteList.js
|
||||
ElectronClient/gui/NoteListControls/commands/focusSearch.js
|
||||
ElectronClient/gui/NoteListControls/NoteListControls.js
|
||||
ElectronClient/gui/NoteListItem.js
|
||||
ElectronClient/gui/NoteTextViewer.js
|
||||
ElectronClient/gui/NoteToolbar/NoteToolbar.js
|
||||
ElectronClient/gui/OneDriveLoginScreen.js
|
||||
ElectronClient/gui/ResizableLayout/hooks/useLayoutItemSizes.js
|
||||
@@ -159,7 +157,6 @@ ElectronClient/gui/style/StyledInput.js
|
||||
ElectronClient/gui/style/StyledTextInput.js
|
||||
ElectronClient/gui/ToggleEditorsButton/styles/index.js
|
||||
ElectronClient/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||
ElectronClient/gui/ToolbarBase.js
|
||||
ElectronClient/gui/ToolbarButton/styles/index.js
|
||||
ElectronClient/gui/ToolbarButton/ToolbarButton.js
|
||||
ReactNativeClient/lib/AsyncActionQueue.js
|
||||
@@ -171,7 +168,6 @@ ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js
|
||||
ReactNativeClient/lib/hooks/useEffectDebugger.js
|
||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||
ReactNativeClient/lib/hooks/usePrevious.js
|
||||
ReactNativeClient/lib/hooks/usePropsDebugger.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||
@@ -179,7 +175,6 @@ ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
||||
ReactNativeClient/lib/JoplinServerApi.js
|
||||
ReactNativeClient/lib/ntpDate.js
|
||||
ReactNativeClient/lib/services/CommandService.js
|
||||
ReactNativeClient/lib/services/debug/populateDatabase.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainService.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
File diff suppressed because it is too large
Load Diff
@@ -13,10 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
#: CliClient/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -106,9 +104,9 @@ msgid "Do not ask for confirmation."
|
||||
msgstr "Ne pas demander de confirmation."
|
||||
|
||||
#: CliClient/app/command-import.js:27
|
||||
#, javascript-format
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Output format: %s"
|
||||
msgstr "Format de la sortie : %s"
|
||||
msgstr "Format de la source : %s"
|
||||
|
||||
#: CliClient/app/command-import.js:47 ElectronClient/gui/ImportScreen.min.js:69
|
||||
#, javascript-format
|
||||
@@ -319,7 +317,7 @@ msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:35
|
||||
msgid "Upgrade the sync target to the latest version."
|
||||
msgstr "Mettre à jour la cible de synchronisation."
|
||||
msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
|
||||
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
|
||||
@@ -378,6 +376,7 @@ msgid "Synchronisation target: %s (%s)"
|
||||
msgstr "Cible de la synchronisation : %s (%s)"
|
||||
|
||||
#: CliClient/app/command-sync.js:177
|
||||
#, fuzzy
|
||||
msgid "Cannot initialise synchroniser."
|
||||
msgstr "Impossible d'initialiser la synchronisation."
|
||||
|
||||
@@ -814,16 +813,14 @@ msgstr "Annuler"
|
||||
msgid ""
|
||||
"The app is now going to close. Please relaunch it to complete the process."
|
||||
msgstr ""
|
||||
"L'application va maintenance fermer. Veuillez la relancer pour terminer "
|
||||
"l'opération."
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:446
|
||||
msgid ""
|
||||
"Type a note title or part of its content to jump to it. Or type # followed "
|
||||
"by a tag name, or @ followed by a notebook name."
|
||||
msgstr ""
|
||||
"Entrez le titre d’une note, ou entrez # suivi du nom d’une étiquette, ou @ "
|
||||
"suivi du nom d’un carnet."
|
||||
"Entrez le titre d’une note, ou entrez # suivit du nom d’une étiquette, ou @ "
|
||||
"suivit du nom d’un carnet."
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:486
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:20
|
||||
@@ -1024,6 +1021,7 @@ msgid "strong text"
|
||||
msgstr "texte en gras"
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.js:147
|
||||
#, fuzzy
|
||||
msgid "emphasised text"
|
||||
msgstr "texte en italique"
|
||||
|
||||
@@ -1178,14 +1176,13 @@ msgstr "Création de %s..."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr "Les changements sur les éléments suivants sont monitorés :"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
|
||||
msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr ""
|
||||
"Les pièces jointes ne seront plus monitorées lorsque vous changerez de note."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
|
||||
msgid "Select all"
|
||||
@@ -1311,11 +1308,12 @@ msgstr "Importer"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
|
||||
msgid "Command"
|
||||
msgstr "Commande"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcut"
|
||||
msgstr "Raccourci"
|
||||
msgstr "Mode de clavier"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
|
||||
#: ElectronClient/app.js:690
|
||||
@@ -1338,8 +1336,9 @@ msgid "Website and documentation"
|
||||
msgstr "Documentation en ligne"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
|
||||
#, fuzzy
|
||||
msgid "Hide Joplin"
|
||||
msgstr "Cacher Joplin"
|
||||
msgstr "A propos de Joplin"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
|
||||
#: ElectronClient/app.js:703
|
||||
@@ -1347,8 +1346,9 @@ msgid "Close Window"
|
||||
msgstr "Fermer la fenêtre"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#, fuzzy
|
||||
msgid "Preferences"
|
||||
msgstr "Préférences"
|
||||
msgstr "Préférences…"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#: ElectronClient/gui/Root.min.js:92 ElectronClient/app.js:572
|
||||
@@ -1357,15 +1357,13 @@ msgstr "Options"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid "Press the shortcut"
|
||||
msgstr "Taper le raccourci"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid ""
|
||||
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
|
||||
"shortcut."
|
||||
msgstr ""
|
||||
"Tapez le raccourci et appuyez sur ENTREE. Ou, appuyez sur la touche de "
|
||||
"retour arrière pour supprimer le raccourci."
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
|
||||
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
|
||||
@@ -1379,13 +1377,11 @@ msgid ""
|
||||
"may take a few minutes to complete and the app needs to be restarted. To "
|
||||
"proceed please click on the link."
|
||||
msgstr ""
|
||||
"La cible de synchronisation doit être mise à jour. L'opération peut prendre "
|
||||
"plusieurs minutes et l'application devra être re-démarrée. Pour continuer, "
|
||||
"veuillez cliquer sur le lien."
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
|
||||
#, fuzzy
|
||||
msgid "Restart and upgrade"
|
||||
msgstr "Redémarrer et mettre à jour"
|
||||
msgstr "Clefs maîtres qui peuvent être mise à niveau"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
|
||||
msgid "Some items cannot be synchronised."
|
||||
@@ -1410,10 +1406,12 @@ msgid "Set the password"
|
||||
msgstr "Définir le mot de passe"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:349
|
||||
#, fuzzy
|
||||
msgid "One of your master keys use an obsolete encryption method."
|
||||
msgstr "L'une des clefs maîtres utilise une méthode de chiffrement obsolète."
|
||||
msgstr "L'une des clefs maîtres requiert un mot de passe."
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:361
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The default encryption method has been changed, you should re-encrypt your "
|
||||
"data."
|
||||
@@ -1422,6 +1420,7 @@ msgstr ""
|
||||
"l'appliquer à vos données."
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:366
|
||||
#, fuzzy
|
||||
msgid "More info"
|
||||
msgstr "Plus d'information"
|
||||
|
||||
@@ -1762,8 +1761,9 @@ msgid "Icon"
|
||||
msgstr "Icône"
|
||||
|
||||
#: ElectronClient/gui/FolderPropertiesDialog.min.js:272
|
||||
#, fuzzy
|
||||
msgid "Notebook properties"
|
||||
msgstr "Propriétés du carnet"
|
||||
msgstr "Propriétés de la note"
|
||||
|
||||
#: ElectronClient/gui/NoteText.min.js:781
|
||||
#, javascript-format
|
||||
@@ -1936,7 +1936,7 @@ msgstr "Statistiques"
|
||||
#: ElectronClient/gui/NoteContentPropertiesDialog.js:111
|
||||
#, javascript-format
|
||||
msgid "Read time: %s min"
|
||||
msgstr "Temps de lecture : %s min"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteContentPropertiesDialog.js:112
|
||||
#: ElectronClient/gui/ShareNoteDialog.js:175
|
||||
@@ -2151,8 +2151,9 @@ msgid "Templates"
|
||||
msgstr "Modèles"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "Tout exporter"
|
||||
msgstr "Exporter"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2252,7 +2253,7 @@ msgstr "Paramètre inconnu : %s"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
|
||||
msgid "AWS S3"
|
||||
msgstr "AWS S3"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
|
||||
msgid "Dropbox"
|
||||
@@ -2396,15 +2397,15 @@ msgstr "WebDAV : Mot de passe"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:195
|
||||
msgid "AWS S3 bucket"
|
||||
msgstr "AWS S3: bucket"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:206
|
||||
msgid "AWS key"
|
||||
msgstr "AWS : Clef"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:216
|
||||
msgid "AWS secret"
|
||||
msgstr "AWS : Secret"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:230
|
||||
msgid "Attachment download behaviour"
|
||||
@@ -2625,6 +2626,7 @@ msgid "Editor font family"
|
||||
msgstr "Police de l'éditeur"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:553
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"This should be a *monospace* font or some elements will render incorrectly. "
|
||||
"If the font is incorrect or empty, it will default to a generic monospace "
|
||||
@@ -2865,8 +2867,9 @@ msgid "Web Clipper"
|
||||
msgstr "Web Clipper"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Raccourcis clavier"
|
||||
msgstr "Mode de clavier"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -3022,8 +3025,6 @@ msgstr "Certains objets ne peuvent être synchronisés."
|
||||
#: ReactNativeClient/lib/components/screen-header.js:453
|
||||
msgid "The sync target needs to be upgraded. Press this banner to proceed."
|
||||
msgstr ""
|
||||
"La cible de synchronisation doit être mise à jour. Veuillez appuyer sur "
|
||||
"cette bannière pour commencer."
|
||||
|
||||
#: ReactNativeClient/lib/components/side-menu-content.js:126
|
||||
#, javascript-format
|
||||
@@ -3150,7 +3151,7 @@ msgstr "Rafraîchir"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
|
||||
msgid "Sync Target Upgrade"
|
||||
msgstr "Mise à jour de la cible de synchro"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
|
||||
msgid "New tags:"
|
||||
@@ -3552,6 +3553,7 @@ msgid "Forward"
|
||||
msgstr "Vers l'avant"
|
||||
|
||||
#: ReactNativeClient/lib/commands/synchronize.js:17
|
||||
#, fuzzy
|
||||
msgid "Synchronize"
|
||||
msgstr "Synchroniser"
|
||||
|
||||
@@ -3791,11 +3793,9 @@ msgid "Directory"
|
||||
msgstr "Dossier"
|
||||
|
||||
#: ReactNativeClient/lib/services/InteropService.js:174
|
||||
#, javascript-format
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\" and output \"%s\""
|
||||
msgstr ""
|
||||
"Impossible de charger module \"%s\" pour le format d'entrée \"%s\" et de "
|
||||
"sortie \"%s\""
|
||||
msgstr "Impossible de charger module \"%s\" pour le format \"%s\""
|
||||
|
||||
#: ReactNativeClient/lib/services/InteropService.js:232
|
||||
#, javascript-format
|
||||
|
||||
@@ -15,8 +15,6 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.4\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
#: CliClient/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -314,7 +312,7 @@ msgstr "指定のターゲットと同期します。(標準: sync.targetの
|
||||
|
||||
#: CliClient/app/command-sync.js:35
|
||||
msgid "Upgrade the sync target to the latest version."
|
||||
msgstr "同期先を最新バージョンにアップグレード。"
|
||||
msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
|
||||
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
|
||||
@@ -798,8 +796,6 @@ msgstr "キャンセル"
|
||||
msgid ""
|
||||
"The app is now going to close. Please relaunch it to complete the process."
|
||||
msgstr ""
|
||||
"まもなくアプリケーションは終了します。もう一度起動して処理を完了させてくださ"
|
||||
"い。"
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:446
|
||||
msgid ""
|
||||
@@ -1161,13 +1157,13 @@ msgstr "新しい %s を作成中..."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr "下記の添付ファイルが変更されたかどうかを監視中です。"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
|
||||
msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr "添付ファイルの監視は他のノートに移動すると終了します。"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
|
||||
msgid "Select all"
|
||||
@@ -1278,7 +1274,7 @@ msgstr "ノートのプロパティ"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
|
||||
msgid "An unexpected error occured while importing the keymap!"
|
||||
msgstr "キーマップのインポート中に予期しないエラーが発生しました!"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
|
||||
@@ -1293,11 +1289,12 @@ msgstr "インポート"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
|
||||
msgid "Command"
|
||||
msgstr "コマンド"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcut"
|
||||
msgstr "ショートカットキー"
|
||||
msgstr "キーバインド"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
|
||||
#: ElectronClient/app.js:690
|
||||
@@ -1320,8 +1317,9 @@ msgid "Website and documentation"
|
||||
msgstr "Webサイトとドキュメント"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
|
||||
#, fuzzy
|
||||
msgid "Hide Joplin"
|
||||
msgstr "Joplinを隠す"
|
||||
msgstr "Joplinについて"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
|
||||
#: ElectronClient/app.js:703
|
||||
@@ -1329,6 +1327,7 @@ msgid "Close Window"
|
||||
msgstr "ウィンドウを閉じる"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#, fuzzy
|
||||
msgid "Preferences"
|
||||
msgstr "環境設定"
|
||||
|
||||
@@ -1339,15 +1338,13 @@ msgstr "オプション"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid "Press the shortcut"
|
||||
msgstr "ショートカットキーを押してください"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid ""
|
||||
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
|
||||
"shortcut."
|
||||
msgstr ""
|
||||
"ショートカットキーに続けてENTERを押すことで設定します。ショートカットを削除す"
|
||||
"るにはBACKSPACEを押してください。"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
|
||||
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
|
||||
@@ -1361,13 +1358,11 @@ msgid ""
|
||||
"may take a few minutes to complete and the app needs to be restarted. To "
|
||||
"proceed please click on the link."
|
||||
msgstr ""
|
||||
"同期するには同期先をアップグレードする必要があります。アップグレードには数分"
|
||||
"かかるかもしれません。またアプリケーションの再起動が必要です。アップグレード"
|
||||
"するにはリンクをクリックしてください。"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
|
||||
#, fuzzy
|
||||
msgid "Restart and upgrade"
|
||||
msgstr "再起動してアップグレード"
|
||||
msgstr "アップグレードが必要なマスターキー"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
|
||||
msgid "Some items cannot be synchronised."
|
||||
@@ -2119,8 +2114,9 @@ msgid "Templates"
|
||||
msgstr "テンプレート"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "すべてをエクスポート"
|
||||
msgstr "エクスポート"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2219,7 +2215,7 @@ msgstr "不明なレベルID: %s"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
|
||||
msgid "AWS S3"
|
||||
msgstr "AWS S3"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
|
||||
msgid "Dropbox"
|
||||
@@ -2364,15 +2360,15 @@ msgstr "WevDAV パスワード"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:195
|
||||
msgid "AWS S3 bucket"
|
||||
msgstr "AWS S3 バケット"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:206
|
||||
msgid "AWS key"
|
||||
msgstr "AWS アクセスキーID"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:216
|
||||
msgid "AWS secret"
|
||||
msgstr "AWS シークレットアクセスキー"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:230
|
||||
msgid "Attachment download behaviour"
|
||||
@@ -2827,8 +2823,9 @@ msgid "Web Clipper"
|
||||
msgstr "Webクリッパー"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "キーボードショートカット"
|
||||
msgstr "キーバインド"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -2983,8 +2980,6 @@ msgstr "いくつかの項目は同期されませんでした。詳細はクリ
|
||||
#: ReactNativeClient/lib/components/screen-header.js:453
|
||||
msgid "The sync target needs to be upgraded. Press this banner to proceed."
|
||||
msgstr ""
|
||||
"同期先をアップグレードする必要があります。アップグレードするにはバナーをク"
|
||||
"リックしてください。"
|
||||
|
||||
#: ReactNativeClient/lib/components/side-menu-content.js:126
|
||||
#, javascript-format
|
||||
@@ -3029,8 +3024,8 @@ msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
"エラーです。URL、ユーザー名、パスワードなどを修正し、同期先にアクセスできるか"
|
||||
"を確認してください。次が報告されたエラーです:"
|
||||
"エラーです。URL、ユーザー名、パスワードなどを修正し、同期するターゲットにアク"
|
||||
"セスできるかを確認してください。次が報告されたエラーです:"
|
||||
|
||||
#: ReactNativeClient/lib/components/shared/dropbox-login-shared.js:39
|
||||
msgid "The application has been authorised!"
|
||||
@@ -3107,7 +3102,7 @@ msgstr "更新"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
|
||||
msgid "Sync Target Upgrade"
|
||||
msgstr "同期先のアップグレード"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
|
||||
msgid "New tags:"
|
||||
@@ -3156,10 +3151,10 @@ msgid ""
|
||||
"password as, for security purposes, this will be the *only* way to decrypt "
|
||||
"the data! To enable encryption, please enter your password below."
|
||||
msgstr ""
|
||||
"暗号化を有効にするとは、*すべて*のノートや添付ファイルを再同期し、同期先に暗"
|
||||
"号化した状態で送ることを意味します。パスワードはなくさないようにしてくださ"
|
||||
"い。セキュリティ上、このパスワードがデータを復号する*唯一*の方法になるためで"
|
||||
"す! 暗号化を有効にするには、下にパスワードを入力してください。"
|
||||
"暗号化を有効にするとは、*すべて*のノートや添付ファイルを再同期し、同期ター"
|
||||
"ゲットに暗号化した状態で送ることを意味します。パスワードはなくさないようにし"
|
||||
"てください。セキュリティ上、このパスワードがデータを復号する*唯一*の方法にな"
|
||||
"るためです! 暗号化を有効にするには、下にパスワードを入力してください。"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/encryption-config.js:177
|
||||
msgid "Enable"
|
||||
@@ -3551,35 +3546,32 @@ msgstr "ノートをどのノートブックにインポートするのか指定
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:124
|
||||
#, javascript-format
|
||||
msgid "Error loading the keymap from file: %s"
|
||||
msgstr "キーマップ読み込みエラー(ファイル: %s)"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:141
|
||||
#, javascript-format
|
||||
msgid "Error saving the keymap to file: %s"
|
||||
msgstr "キーマップ書き出しエラー(ファイル: %s)"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:204
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"command\" property."
|
||||
msgstr ""
|
||||
"キーマップアイテム %s は必須の \"command\" プロパティを持っていません。"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:207
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid command."
|
||||
msgstr "キーマップアイテム %s は %s が有効なコマンドでないため無効です。"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:210
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"accelerator\" property."
|
||||
msgstr ""
|
||||
"キーマップアイテム %s は必須の \"accelerator\" プロパティを持っていません。"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:217
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid accelerator."
|
||||
msgstr ""
|
||||
"キーマップアイテム %s は %s が有効なショートカットキーでないため無効です。"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:235
|
||||
#, javascript-format
|
||||
@@ -3587,13 +3579,11 @@ msgid ""
|
||||
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to "
|
||||
"unexpected behaviour."
|
||||
msgstr ""
|
||||
"ショートカットキー \"%s\" は \"%s\" コマンドと \"%s\" コマンドで使われていま"
|
||||
"す。これにより予想外の動作が起こる可能性があります。"
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:260
|
||||
#, javascript-format
|
||||
msgid "Accelerator \"%s\" is not valid."
|
||||
msgstr "ショートカットキー \"%s\" は無効です。"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/report.js:121
|
||||
msgid "Items that cannot be synchronised"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,9 +14,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.4.1\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
|
||||
#: CliClient/app/command-cp.js:13
|
||||
msgid ""
|
||||
@@ -321,7 +319,7 @@ msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:35
|
||||
msgid "Upgrade the sync target to the latest version."
|
||||
msgstr "Senkronizasyon hedefini en son sürüme yükseltin"
|
||||
msgstr ""
|
||||
|
||||
#: CliClient/app/command-sync.js:81 CliClient/app/command-sync.js:95
|
||||
#: ElectronClient/gui/OneDriveLoginScreen.min.js:40
|
||||
@@ -815,8 +813,6 @@ msgstr "İptal et"
|
||||
msgid ""
|
||||
"The app is now going to close. Please relaunch it to complete the process."
|
||||
msgstr ""
|
||||
"Uygulama şimdi kapanacak. İşlemi tamamlamak için lütfen uygulamayı "
|
||||
"kapandıktan sonar yeniden çalıştırın."
|
||||
|
||||
#: ElectronClient/plugins/GotoAnything.min.js:446
|
||||
msgid ""
|
||||
@@ -1177,13 +1173,13 @@ msgstr "Yeni %s oluşturuluyor..."
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:344
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr "Şu ek dosyaları değişiklikler için izlenmekte:"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/NoteEditor.js:347
|
||||
msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr "Eğer başka bir not'a geçerseniz ek dosyalar artık izlenmeyecek."
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/NoteEditor/commands/editorCommandDeclarations.js:25
|
||||
msgid "Select all"
|
||||
@@ -1294,7 +1290,7 @@ msgstr "Not özellikleri"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:62
|
||||
msgid "An unexpected error occured while importing the keymap!"
|
||||
msgstr "Tuş dizimini içe aktarırken bir hata oluştu!"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:119
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:437
|
||||
@@ -1309,11 +1305,12 @@ msgstr "İçe aktar"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:125
|
||||
msgid "Command"
|
||||
msgstr "Komut"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/KeymapConfigScreen.js:126
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcut"
|
||||
msgstr "Klavye Kısayolu"
|
||||
msgstr "Klavye modu"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:14
|
||||
#: ElectronClient/app.js:690
|
||||
@@ -1336,8 +1333,9 @@ msgid "Website and documentation"
|
||||
msgstr "Web sitesi ve dökümanlar"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:24
|
||||
#, fuzzy
|
||||
msgid "Hide Joplin"
|
||||
msgstr "Joplin'i Gizle"
|
||||
msgstr "Joplin hakkında"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:26
|
||||
#: ElectronClient/app.js:703
|
||||
@@ -1345,8 +1343,9 @@ msgid "Close Window"
|
||||
msgstr "Pencereyi Kapat"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#, fuzzy
|
||||
msgid "Preferences"
|
||||
msgstr "Tercihler"
|
||||
msgstr "Tercihler..."
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/utils/getLabel.js:28
|
||||
#: ElectronClient/gui/Root.min.js:92 ElectronClient/app.js:572
|
||||
@@ -1355,15 +1354,13 @@ msgstr "Seçenekler"
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid "Press the shortcut"
|
||||
msgstr "Kısayolu girin"
|
||||
msgstr ""
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:48
|
||||
msgid ""
|
||||
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the "
|
||||
"shortcut."
|
||||
msgstr ""
|
||||
"Kısayolu girin ve ardından ENTER tuşuna basın. Veya BACKSPACE tuşuna basarak "
|
||||
"kısayolu temizleyin."
|
||||
|
||||
#: ElectronClient/gui/KeymapConfig/ShortcutRecorder.js:49
|
||||
#: ElectronClient/gui/EncryptionConfigScreen.min.js:95
|
||||
@@ -1377,14 +1374,11 @@ msgid ""
|
||||
"may take a few minutes to complete and the app needs to be restarted. To "
|
||||
"proceed please click on the link."
|
||||
msgstr ""
|
||||
"Senkronizasyon hedefi'nin Joplin senkronizasyona yeniden başlamadan once "
|
||||
"güncellenmesi gerekir. Bu işlem notlarınızıın yoğunluğuna göre birkaç dakika "
|
||||
"sürebilir, ve de bu işlem ardından uygulama yeniden başlatılacaktır. Bu "
|
||||
"işlemi başlatmak için lütfen linke tıklayın."
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:306
|
||||
#, fuzzy
|
||||
msgid "Restart and upgrade"
|
||||
msgstr "Yeniden başlat ve güncelle"
|
||||
msgstr "Ana anahtarların güncellenmesi lazım"
|
||||
|
||||
#: ElectronClient/gui/MainScreen/MainScreen.min.js:313
|
||||
msgid "Some items cannot be synchronised."
|
||||
@@ -2144,8 +2138,9 @@ msgid "Templates"
|
||||
msgstr "Şablonlar"
|
||||
|
||||
#: ElectronClient/app.js:668
|
||||
#, fuzzy
|
||||
msgid "Export all"
|
||||
msgstr "Tümünü dışa aktar"
|
||||
msgstr "Dışa aktar"
|
||||
|
||||
#: ElectronClient/app.js:683
|
||||
#, javascript-format
|
||||
@@ -2246,7 +2241,7 @@ msgstr "Bilinmeyen ID seviyesi: %s"
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetAmazonS3.js:28
|
||||
msgid "AWS S3"
|
||||
msgstr "AWS S3"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/SyncTargetDropbox.js:25
|
||||
msgid "Dropbox"
|
||||
@@ -2389,15 +2384,15 @@ msgstr "WebDAV şifresi"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:195
|
||||
msgid "AWS S3 bucket"
|
||||
msgstr "AWS S3 deposu"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:206
|
||||
msgid "AWS key"
|
||||
msgstr "AWS anahtarı"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:216
|
||||
msgid "AWS secret"
|
||||
msgstr "AWS gizli anahtarı"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:230
|
||||
msgid "Attachment download behaviour"
|
||||
@@ -2855,8 +2850,9 @@ msgid "Web Clipper"
|
||||
msgstr "Web Alıntılayıcısı"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1259
|
||||
#, fuzzy
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Klavye Kısayolları"
|
||||
msgstr "Klavye modu"
|
||||
|
||||
#: ReactNativeClient/lib/models/Setting.js:1264
|
||||
msgid ""
|
||||
@@ -3012,8 +3008,6 @@ msgstr "Bazı öğeler senkronize edilemiyor. Detayları için tıklayın."
|
||||
#: ReactNativeClient/lib/components/screen-header.js:453
|
||||
msgid "The sync target needs to be upgraded. Press this banner to proceed."
|
||||
msgstr ""
|
||||
"Senkronizasyon hedefinin güncellenmesi gerekmekte. Bu banner'a tıklayarak "
|
||||
"devam edebilirsiniz."
|
||||
|
||||
#: ReactNativeClient/lib/components/side-menu-content.js:126
|
||||
#, javascript-format
|
||||
@@ -3135,7 +3129,7 @@ msgstr "Yenile"
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/UpgradeSyncTargetScreen.js:42
|
||||
msgid "Sync Target Upgrade"
|
||||
msgstr "Senkronizasyon Hedefi Güncellemesi"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/components/screens/NoteTagsDialog.js:163
|
||||
msgid "New tags:"
|
||||
@@ -3584,37 +3578,32 @@ msgstr "Lütfen notların alınacağı not defterini belirtin."
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:124
|
||||
#, javascript-format
|
||||
msgid "Error loading the keymap from file: %s"
|
||||
msgstr "%s dosyasından tuş haritası yüklenemedi"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:141
|
||||
#, javascript-format
|
||||
msgid "Error saving the keymap to file: %s"
|
||||
msgstr "%s dosyasına tuş haritası kaydedilemedi"
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:204
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"command\" property."
|
||||
msgstr ""
|
||||
"%s tuş haritası, işlemler için gerekli olan \"command\" özelliğini "
|
||||
"barındırmıyor."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:207
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid command."
|
||||
msgstr "%s tuş haritası geçersizdir, çünkü %s geçerli bir komut değildir."
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:210
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is missing the required \"accelerator\" property."
|
||||
msgstr ""
|
||||
"%s tuş haritası, işlemler için gerekli olan \"accelerator\" özelliğini "
|
||||
"barındırmıyor."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:217
|
||||
#, javascript-format
|
||||
msgid "Keymap item %s is invalid because %s is not a valid accelerator."
|
||||
msgstr ""
|
||||
"%s tuş haritası geçersizdir, çünkü %s geçerli bir accelerator değildir."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:235
|
||||
#, javascript-format
|
||||
@@ -3622,13 +3611,11 @@ msgid ""
|
||||
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to "
|
||||
"unexpected behaviour."
|
||||
msgstr ""
|
||||
"Kısayol \"%s\", \"%s\" ve \"%s\" komutları için kullanılıyor. Bu beklenmeyen "
|
||||
"sonuçlara sebep verebilir."
|
||||
|
||||
#: ReactNativeClient/lib/services/KeymapService.js:260
|
||||
#, javascript-format
|
||||
msgid "Accelerator \"%s\" is not valid."
|
||||
msgstr "Kısayol \"%s\" geçersiz."
|
||||
msgstr ""
|
||||
|
||||
#: ReactNativeClient/lib/services/report.js:121
|
||||
msgid "Items that cannot be synchronised"
|
||||
@@ -3962,7 +3949,7 @@ msgstr ""
|
||||
#~ "Şu anda not defteriniz yok. (+) butonuna tıklayarak bir tane oluşturun."
|
||||
|
||||
#~ msgid "Welcome"
|
||||
#~ msgstr "Hoş Geldiniz"
|
||||
#~ msgstr "Hoşgeldiniz"
|
||||
|
||||
#~ msgid "Separate each tag by a comma."
|
||||
#~ msgstr "Her etiketi virgülle ayırın."
|
||||
|
||||
20
CliClient/package-lock.json
generated
20
CliClient/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "joplin",
|
||||
"version": "1.2.3",
|
||||
"version": "1.0.168",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -5880,11 +5880,6 @@
|
||||
"is-fullwidth-code-point": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"slug": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/slug/-/slug-3.5.0.tgz",
|
||||
"integrity": "sha512-+pZLDhMtmAc+ZcojQSMlUKDZBYmvhZiZmK8Ffx/D3Q/MIMHPDBAMbWvWN8vJb9xl2MfbDdRWxFzrdOhBiyVpow=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
@@ -6747,6 +6742,11 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unpack-string": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz",
|
||||
@@ -6849,6 +6849,14 @@
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "1.2.3",
|
||||
"version": "1.0.168",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
@@ -98,7 +98,6 @@
|
||||
"sax": "^1.2.4",
|
||||
"server-destroy": "^1.0.1",
|
||||
"sharp": "^0.23.2",
|
||||
"slug": "^3.5.0",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"sqlite3": "^4.1.1",
|
||||
"string-padding": "^1.0.2",
|
||||
@@ -110,6 +109,7 @@
|
||||
"terminal-kit": "^1.30.0",
|
||||
"tkwidgets": "^0.5.26",
|
||||
"url-parse": "^1.4.7",
|
||||
"uslug": "^1.0.4",
|
||||
"uuid": "^3.0.1",
|
||||
"valid-url": "^1.0.9",
|
||||
"word-wrap": "^1.2.3",
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint prefer-const: 0*/
|
||||
|
||||
// require('app-module-path').addPath(__dirname);
|
||||
require('app-module-path').addPath(__dirname);
|
||||
|
||||
// const { time } = require('lib/time-utils.js');
|
||||
// const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('test-utils.js');
|
||||
// const SearchEngine = require('lib/services/searchengine/SearchEngine');
|
||||
// const Note = require('lib/models/Note');
|
||||
// const Folder = require('lib/models/Folder');
|
||||
// const Tag = require('lib/models/Tag');
|
||||
// const ItemChange = require('lib/models/ItemChange');
|
||||
// const Setting = require('lib/models/Setting');
|
||||
// const Resource = require('lib/models/Resource.js');
|
||||
// const { shim } = require('lib/shim');
|
||||
// const ResourceService = require('lib/services/ResourceService.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, asyncTest, db, synchronizer, fileApi, sleep, createNTestNotes, switchClient, createNTestFolders } = require('test-utils.js');
|
||||
const SearchEngine = require('lib/services/searchengine/SearchEngine');
|
||||
const Note = require('lib/models/Note');
|
||||
const Folder = require('lib/models/Folder');
|
||||
const Tag = require('lib/models/Tag');
|
||||
const ItemChange = require('lib/models/ItemChange');
|
||||
const Setting = require('lib/models/Setting');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const ResourceService = require('lib/services/ResourceService.js');
|
||||
|
||||
|
||||
// process.on('unhandledRejection', (reason, p) => {
|
||||
// console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
// });
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
// let engine = null;
|
||||
let engine = null;
|
||||
|
||||
// const ids = (array) => array.map(a => a.id);
|
||||
const ids = (array) => array.map(a => a.id);
|
||||
|
||||
// describe('services_SearchFuzzy', function() {
|
||||
// beforeEach(async (done) => {
|
||||
// await setupDatabaseAndSynchronizer(1);
|
||||
// await switchClient(1);
|
||||
describe('services_SearchFuzzy', function() {
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
|
||||
// engine = new SearchEngine();
|
||||
// engine.setDb(db());
|
||||
engine = new SearchEngine();
|
||||
engine.setDb(db());
|
||||
|
||||
// Setting.setValue('db.fuzzySearchEnabled', 1);
|
||||
// done();
|
||||
// });
|
||||
Setting.setValue('db.fuzzySearchEnabled', 1);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
// it('should return note almost matching title', asyncTest(async () => {
|
||||
// let rows;
|
||||
// const n1 = await Note.save({ title: 'If It Ain\'t Baroque, Don\'t Fix It' });
|
||||
// const n2 = await Note.save({ title: 'Important note' });
|
||||
it('should return note almost matching title', asyncTest(async () => {
|
||||
let rows;
|
||||
const n1 = await Note.save({ title: 'If It Ain\'t Baroque, Don\'t Fix It' });
|
||||
const n2 = await Note.save({ title: 'Important note' });
|
||||
|
||||
// await engine.syncTables();
|
||||
// rows = await engine.search('Broke', { fuzzy: false });
|
||||
// expect(rows.length).toBe(0);
|
||||
await engine.syncTables();
|
||||
rows = await engine.search('Broke', { fuzzy: false });
|
||||
expect(rows.length).toBe(0);
|
||||
|
||||
// rows = await engine.search('Broke', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
rows = await engine.search('Broke', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
|
||||
|
||||
// rows = await engine.search('title:Broke', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
rows = await engine.search('title:Broke', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
|
||||
// rows = await engine.search('title:"Broke"', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
rows = await engine.search('title:"Broke"', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
|
||||
// rows = await engine.search('Imprtant', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n2.id);
|
||||
// }));
|
||||
rows = await engine.search('Imprtant', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n2.id);
|
||||
}));
|
||||
|
||||
|
||||
// it('should order results by min fuzziness', asyncTest(async () => {
|
||||
// let rows;
|
||||
// const n1 = await Note.save({ title: 'I demand you take me to him' });
|
||||
// const n2 = await Note.save({ title: 'He demanded an answer' });
|
||||
// const n3 = await Note.save({ title: 'Don\'t you make demands of me' });
|
||||
// const n4 = await Note.save({ title: 'No drama for me' });
|
||||
// const n5 = await Note.save({ title: 'Just minding my own business' });
|
||||
it('should order results by min fuzziness', asyncTest(async () => {
|
||||
let rows;
|
||||
const n1 = await Note.save({ title: 'I demand you take me to him' });
|
||||
const n2 = await Note.save({ title: 'He demanded an answer' });
|
||||
const n3 = await Note.save({ title: 'Don\'t you make demands of me' });
|
||||
const n4 = await Note.save({ title: 'No drama for me' });
|
||||
const n5 = await Note.save({ title: 'Just minding my own business' });
|
||||
|
||||
// await engine.syncTables();
|
||||
// rows = await engine.search('demand', { fuzzy: false });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
await engine.syncTables();
|
||||
rows = await engine.search('demand', { fuzzy: false });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
|
||||
|
||||
// rows = await engine.search('demand', { fuzzy: true });
|
||||
// expect(rows.length).toBe(3);
|
||||
// expect(rows[0].id).toBe(n1.id);
|
||||
// expect(rows[1].id).toBe(n3.id);
|
||||
// expect(rows[2].id).toBe(n2.id);
|
||||
// }));
|
||||
rows = await engine.search('demand', { fuzzy: true });
|
||||
expect(rows.length).toBe(3);
|
||||
expect(rows[0].id).toBe(n1.id);
|
||||
expect(rows[1].id).toBe(n3.id);
|
||||
expect(rows[2].id).toBe(n2.id);
|
||||
}));
|
||||
|
||||
// it('should consider any:1', asyncTest(async () => {
|
||||
// let rows;
|
||||
// const n1 = await Note.save({ title: 'cat' });
|
||||
// const n2 = await Note.save({ title: 'cats' });
|
||||
// const n3 = await Note.save({ title: 'cot' });
|
||||
it('should consider any:1', asyncTest(async () => {
|
||||
let rows;
|
||||
const n1 = await Note.save({ title: 'cat' });
|
||||
const n2 = await Note.save({ title: 'cats' });
|
||||
const n3 = await Note.save({ title: 'cot' });
|
||||
|
||||
// const n4 = await Note.save({ title: 'defenestrate' });
|
||||
// const n5 = await Note.save({ title: 'defenstrate' });
|
||||
// const n6 = await Note.save({ title: 'defenestrated' });
|
||||
const n4 = await Note.save({ title: 'defenestrate' });
|
||||
const n5 = await Note.save({ title: 'defenstrate' });
|
||||
const n6 = await Note.save({ title: 'defenestrated' });
|
||||
|
||||
// const n7 = await Note.save({ title: 'he defenestrated the cat' });
|
||||
const n7 = await Note.save({ title: 'he defenestrated the cat' });
|
||||
|
||||
// await engine.syncTables();
|
||||
await engine.syncTables();
|
||||
|
||||
// rows = await engine.search('defenestrated cat', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
rows = await engine.search('defenestrated cat', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
|
||||
// rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
|
||||
// expect(rows.length).toBe(7);
|
||||
// }));
|
||||
rows = await engine.search('any:1 defenestrated cat', { fuzzy: true });
|
||||
expect(rows.length).toBe(7);
|
||||
}));
|
||||
|
||||
// it('should leave phrase searches alone', asyncTest(async () => {
|
||||
// let rows;
|
||||
// const n1 = await Note.save({ title: 'abc def' });
|
||||
// const n2 = await Note.save({ title: 'def ghi' });
|
||||
// const n3 = await Note.save({ title: 'ghi jkl' });
|
||||
// const n4 = await Note.save({ title: 'def abc' });
|
||||
// const n5 = await Note.save({ title: 'mno pqr ghi jkl' });
|
||||
it('should leave phrase searches alone', asyncTest(async () => {
|
||||
let rows;
|
||||
const n1 = await Note.save({ title: 'abc def' });
|
||||
const n2 = await Note.save({ title: 'def ghi' });
|
||||
const n3 = await Note.save({ title: 'ghi jkl' });
|
||||
const n4 = await Note.save({ title: 'def abc' });
|
||||
const n5 = await Note.save({ title: 'mno pqr ghi jkl' });
|
||||
|
||||
// await engine.syncTables();
|
||||
await engine.syncTables();
|
||||
|
||||
// rows = await engine.search('abc def', { fuzzy: true });
|
||||
// expect(rows.length).toBe(2);
|
||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n4.id);
|
||||
rows = await engine.search('abc def', { fuzzy: true });
|
||||
expect(rows.length).toBe(2);
|
||||
expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n4.id);
|
||||
|
||||
// rows = await engine.search('"abc def"', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
rows = await engine.search('"abc def"', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
|
||||
// rows = await engine.search('"ghi jkl"', { fuzzy: true });
|
||||
// expect(rows.length).toBe(2);
|
||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
rows = await engine.search('"ghi jkl"', { fuzzy: true });
|
||||
expect(rows.length).toBe(2);
|
||||
expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
|
||||
// rows = await engine.search('"ghi jkl" mno', { fuzzy: true });
|
||||
// expect(rows.length).toBe(1);
|
||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
rows = await engine.search('"ghi jkl" mno', { fuzzy: true });
|
||||
expect(rows.length).toBe(1);
|
||||
expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
|
||||
// rows = await engine.search('any:1 "ghi jkl" mno', { fuzzy: true });
|
||||
// expect(rows.length).toBe(2);
|
||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
// }));
|
||||
rows = await engine.search('any:1 "ghi jkl" mno', { fuzzy: true });
|
||||
expect(rows.length).toBe(2);
|
||||
expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n5.id);
|
||||
}));
|
||||
|
||||
// it('should leave wild card searches alone', asyncTest(async () => {
|
||||
// let rows;
|
||||
// const n1 = await Note.save({ title: 'abc def' });
|
||||
// const n2 = await Note.save({ title: 'abcc ghi' });
|
||||
// const n3 = await Note.save({ title: 'abccc ghi' });
|
||||
// const n4 = await Note.save({ title: 'abcccc ghi' });
|
||||
// const n5 = await Note.save({ title: 'wxy zzz' });
|
||||
it('should leave wild card searches alone', asyncTest(async () => {
|
||||
let rows;
|
||||
const n1 = await Note.save({ title: 'abc def' });
|
||||
const n2 = await Note.save({ title: 'abcc ghi' });
|
||||
const n3 = await Note.save({ title: 'abccc ghi' });
|
||||
const n4 = await Note.save({ title: 'abcccc ghi' });
|
||||
const n5 = await Note.save({ title: 'wxy zzz' });
|
||||
|
||||
// await engine.syncTables();
|
||||
await engine.syncTables();
|
||||
|
||||
// rows = await engine.search('abc*', { fuzzy: true });
|
||||
rows = await engine.search('abc*', { fuzzy: true });
|
||||
|
||||
// expect(rows.length).toBe(4);
|
||||
// expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n2.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
// expect(rows.map(r=>r.id)).toContain(n4.id);
|
||||
// }));
|
||||
expect(rows.length).toBe(4);
|
||||
expect(rows.map(r=>r.id)).toContain(n1.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n2.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n3.id);
|
||||
expect(rows.map(r=>r.id)).toContain(n4.id);
|
||||
}));
|
||||
|
||||
// });
|
||||
});
|
||||
|
||||
@@ -51,9 +51,9 @@ describe('timeUtils', function() {
|
||||
expect(time.goForwardInTime(startDate, 1, 'day')).toBe(endDate.getTime().toString());
|
||||
|
||||
|
||||
// startDate = new Date('9 Aug 2020');
|
||||
// endDate = new Date('9 Aug 2020'); // week start;
|
||||
// expect(time.goForwardInTime(startDate, 0, 'week')).toBe(endDate.getTime().toString());
|
||||
startDate = new Date('9 Aug 2020');
|
||||
endDate = new Date('9 Aug 2020'); // week start;
|
||||
expect(time.goForwardInTime(startDate, 0, 'week')).toBe(endDate.getTime().toString());
|
||||
|
||||
startDate = new Date('02 Jan 2020');
|
||||
endDate = new Date('01 Feb 2020');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Joplin Web Clipper [DEV]",
|
||||
"version": "1.2.0",
|
||||
"version": "1.0.25",
|
||||
"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'",
|
||||
|
||||
@@ -34,7 +34,6 @@ const KeymapService = require('lib/services/KeymapService').default;
|
||||
const TemplateUtils = require('lib/TemplateUtils');
|
||||
const CssUtils = require('lib/CssUtils');
|
||||
const resourceEditWatcherReducer = require('lib/services/ResourceEditWatcher/reducer').default;
|
||||
// const populateDatabase = require('lib/services/debug/populateDatabase').default;
|
||||
const versionInfo = require('lib/versionInfo').default;
|
||||
|
||||
const commands = [
|
||||
@@ -100,8 +99,6 @@ const appDefaultState = Object.assign({}, defaultState, {
|
||||
watchedNoteFiles: [],
|
||||
lastEditorScrollPercents: {},
|
||||
devToolsVisible: false,
|
||||
visibleDialogs: {}, // empty object if no dialog is visible. Otherwise contains the list of visible dialogs.
|
||||
focusedField: null,
|
||||
});
|
||||
|
||||
class Application extends BaseApplication {
|
||||
@@ -283,31 +280,6 @@ class Application extends BaseApplication {
|
||||
newState.devToolsVisible = action.value;
|
||||
break;
|
||||
|
||||
case 'VISIBLE_DIALOGS_ADD':
|
||||
newState = Object.assign({}, state);
|
||||
newState.visibleDialogs[state.name] = true;
|
||||
break;
|
||||
|
||||
case 'VISIBLE_DIALOGS_REMOVE':
|
||||
newState = Object.assign({}, state);
|
||||
delete newState.visibleDialogs[state.name];
|
||||
break;
|
||||
|
||||
case 'FOCUS_SET':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.focusedField = action.field;
|
||||
break;
|
||||
|
||||
case 'FOCUS_CLEAR':
|
||||
|
||||
// A field can only clear its own state
|
||||
if (action.field === state.focusedField) {
|
||||
newState = Object.assign({}, state);
|
||||
newState.focusedField = null;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = `In reducer: ${error.message} Action: ${JSON.stringify(action)}`;
|
||||
@@ -405,7 +377,7 @@ class Application extends BaseApplication {
|
||||
await this.updateMenu(screen);
|
||||
}
|
||||
|
||||
async updateMenu(screen, updateStates = true) {
|
||||
async updateMenu(screen) {
|
||||
if (this.lastMenuScreen_ === screen) return;
|
||||
|
||||
const cmdService = CommandService.instance();
|
||||
@@ -768,6 +740,7 @@ class Application extends BaseApplication {
|
||||
const separator = () => {
|
||||
return {
|
||||
type: 'separator',
|
||||
screens: ['Main'],
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1015,8 +988,6 @@ class Application extends BaseApplication {
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
||||
this.lastMenuScreen_ = screen;
|
||||
|
||||
if (updateStates) await this.updateMenuItemStates();
|
||||
}
|
||||
|
||||
async updateMenuItemStates(state = null) {
|
||||
@@ -1126,7 +1097,7 @@ class Application extends BaseApplication {
|
||||
try {
|
||||
await keymapService.loadCustomKeymap(`${dir}/keymap-desktop.json`);
|
||||
} catch (err) {
|
||||
reg.logger().error(err.message);
|
||||
bridge().showErrorMessageBox(err.message);
|
||||
}
|
||||
|
||||
AlarmService.setDriver(new AlarmServiceDriverNode({ appName: packageInfo.build.appId }));
|
||||
@@ -1159,7 +1130,7 @@ class Application extends BaseApplication {
|
||||
CommandService.instance().registerDeclaration(declaration);
|
||||
}
|
||||
|
||||
this.updateMenu('Main', false);
|
||||
this.updateMenu('Main');
|
||||
|
||||
// Since the settings need to be loaded before the store is created, it will never
|
||||
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
|
||||
@@ -1284,8 +1255,6 @@ class Application extends BaseApplication {
|
||||
};
|
||||
|
||||
bridge().addEventListener('nativeThemeUpdated', this.bridge_nativeThemeUpdated);
|
||||
|
||||
// await populateDatabase(reg.db());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,14 +27,10 @@ export const runtime = ():CommandRuntime => {
|
||||
// await comp.saveNoteAndWait(comp.formNote);
|
||||
},
|
||||
isEnabled: (props:any) => {
|
||||
if (props.routeName !== 'Main') return false;
|
||||
return !!props.noteId;
|
||||
},
|
||||
mapStateToProps: (state:any) => {
|
||||
return {
|
||||
noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null,
|
||||
routeName: state.route.routeName,
|
||||
};
|
||||
return { noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null };
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -18,11 +18,10 @@ export const runtime = ():CommandRuntime => {
|
||||
ExternalEditWatcher.instance().stopWatching(props.noteId);
|
||||
},
|
||||
isEnabled: (props:any) => {
|
||||
if (props.routeName !== 'Main') return false;
|
||||
return !!props.noteId;
|
||||
},
|
||||
mapStateToProps: (state:any) => {
|
||||
return { noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null, routeName: state.route.routeName };
|
||||
return { noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null };
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -526,7 +526,7 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
||||
const label = [md.label()];
|
||||
if (md.unitLabel) label.push(`(${md.unitLabel()})`);
|
||||
|
||||
const inputStyle:any = Object.assign({}, textInputBaseStyle);
|
||||
const inputStyle = Object.assign({}, textInputBaseStyle);
|
||||
|
||||
return (
|
||||
<div key={key} style={rowStyle}>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const KeymapConfigScreen = ({ themeId }: KeymapConfigScreenProps) => {
|
||||
const keymapFile = await shim.fsDriver().readFile(actualFilePath, 'utf-8');
|
||||
overrideKeymapItems(JSON.parse(keymapFile));
|
||||
} catch (err) {
|
||||
bridge().showErrorMessageBox(_('Error: %s', err.message));
|
||||
bridge().showErrorMessageBox(`${_('An unexpected error occured while importing the keymap!')}\n${err.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -224,7 +224,7 @@ class MainScreenComponent extends React.Component<any, any> {
|
||||
}) });
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps:any, prevState:any) {
|
||||
componentDidUpdate(prevProps:any) {
|
||||
if (this.props.noteListVisibility !== prevProps.noteListVisibility || this.props.sidebarVisibility !== prevProps.sidebarVisibility) {
|
||||
this.setState({ layout: produce(this.state.layout, (draftState:any) => {
|
||||
const noteListColumn = findItemByKey(draftState, 'noteListColumn');
|
||||
@@ -238,27 +238,6 @@ class MainScreenComponent extends React.Component<any, any> {
|
||||
if (prevProps.style.width !== this.props.style.width || prevProps.style.height !== this.props.style.height) {
|
||||
this.updateRootLayoutSize();
|
||||
}
|
||||
|
||||
if (this.state.notePropertiesDialogOptions !== prevState.notePropertiesDialogOptions) {
|
||||
this.props.dispatch({
|
||||
type: this.state.notePropertiesDialogOptions && this.state.notePropertiesDialogOptions.visible ? 'VISIBLE_DIALOGS_ADD' : 'VISIBLE_DIALOGS_REMOVE',
|
||||
name: 'noteProperties',
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.noteContentPropertiesDialogOptions !== prevState.noteContentPropertiesDialogOptions) {
|
||||
this.props.dispatch({
|
||||
type: this.state.noteContentPropertiesDialogOptions && this.state.noteContentPropertiesDialogOptions.visible ? 'VISIBLE_DIALOGS_ADD' : 'VISIBLE_DIALOGS_REMOVE',
|
||||
name: 'noteContentProperties',
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.shareNoteDialogOptions !== prevState.shareNoteDialogOptions) {
|
||||
this.props.dispatch({
|
||||
type: this.state.shareNoteDialogOptions && this.state.shareNoteDialogOptions.visible ? 'VISIBLE_DIALOGS_ADD' : 'VISIBLE_DIALOGS_REMOVE',
|
||||
name: 'shareNote',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -566,7 +545,7 @@ class MainScreenComponent extends React.Component<any, any> {
|
||||
const bodyEditor = this.props.settingEditorCodeView ? 'CodeMirror' : 'TinyMCE';
|
||||
return <NoteEditor key={key} bodyEditor={bodyEditor} />;
|
||||
} else if (key === 'noteListControls') {
|
||||
return <NoteListControls key={key} showNewNoteButtons={this.props.focusedField !== 'globalSearch'} />;
|
||||
return <NoteListControls key={key} />;
|
||||
}
|
||||
|
||||
throw new Error(`Invalid layout component: ${key}`);
|
||||
@@ -650,7 +629,6 @@ const mapStateToProps = (state:any) => {
|
||||
customCss: state.customCss,
|
||||
editorNoteStatuses: state.editorNoteStatuses,
|
||||
hasNotesBeingSaved: stateUtils.hasNotesBeingSaved(state),
|
||||
focusedField: state.focusedField,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { CommandRuntime, CommandDeclaration } from '../../../lib/services/CommandService';
|
||||
const Note = require('lib/models/Note');
|
||||
const BaseModel = require('lib/BaseModel');
|
||||
// const { _ } = require('lib/locale');
|
||||
const { uuid } = require('lib/uuid.js');
|
||||
|
||||
export const declaration:CommandDeclaration = {
|
||||
@@ -29,18 +31,14 @@ export const runtime = (comp:any):CommandRuntime => {
|
||||
id: comp.searchId_,
|
||||
});
|
||||
} else {
|
||||
// Note: Normally there's no need to do anything when the search query
|
||||
// is cleared as the reducer should handle all state changes.
|
||||
// https://github.com/laurent22/joplin/issues/3748
|
||||
|
||||
// const note = await Note.load(comp.props.selectedNoteId);
|
||||
// if (note) {
|
||||
// comp.props.dispatch({
|
||||
// type: 'FOLDER_AND_NOTE_SELECT',
|
||||
// folderId: note.parent_id,
|
||||
// noteId: note.id,
|
||||
// });
|
||||
// }
|
||||
const note = await Note.load(comp.props.selectedNoteId);
|
||||
if (note) {
|
||||
comp.props.dispatch({
|
||||
type: 'FOLDER_AND_NOTE_SELECT',
|
||||
folderId: note.parent_id,
|
||||
noteId: note.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -152,8 +152,6 @@ export default function NoteContentPropertiesDialog(props:NoteContentPropertiesD
|
||||
textAlign: 'center',
|
||||
};
|
||||
|
||||
const readTimeLabel = _('Read time: %s min', formatReadTime(strippedReadTime));
|
||||
|
||||
return (
|
||||
<div style={theme.dialogModalLayer}>
|
||||
<div style={theme.dialogBox}>
|
||||
@@ -166,8 +164,8 @@ export default function NoteContentPropertiesDialog(props:NoteContentPropertiesD
|
||||
{tableBodyComps}
|
||||
</tbody>
|
||||
</table>
|
||||
<div style={{ ...labelCompStyle, marginTop: 10 }}>
|
||||
{readTimeLabel}
|
||||
<div style={labelCompStyle}>
|
||||
{_('Read time: %s min', formatReadTime(strippedReadTime))}
|
||||
</div>
|
||||
<DialogButtonRow themeId={props.themeId} onClick={buttonRow_click} okButtonShow={false} cancelButtonLabel={_('Close')}/>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,6 @@ import { useScrollHandler, usePrevious, cursorPositionToTextOffset, useRootSize
|
||||
import Toolbar from './Toolbar';
|
||||
import styles_ from './styles';
|
||||
import { RenderedBody, defaultRenderedBody } from './utils/types';
|
||||
import NoteTextViewer from '../../../NoteTextViewer';
|
||||
import Editor from './Editor';
|
||||
|
||||
// @ts-ignore
|
||||
@@ -18,6 +17,7 @@ const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { clipboard } = require('electron');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const NoteTextViewer = require('../../../NoteTextViewer.min');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
@@ -37,7 +37,6 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
const [renderedBody, setRenderedBody] = useState<RenderedBody>(defaultRenderedBody()); // Viewer content
|
||||
const [webviewReady, setWebviewReady] = useState(false);
|
||||
|
||||
const previousContent = usePrevious(props.content);
|
||||
const previousRenderedBody = usePrevious(renderedBody);
|
||||
const previousSearchMarkers = usePrevious(props.searchMarkers);
|
||||
const previousContentKey = usePrevious(props.contentKey);
|
||||
@@ -360,7 +359,6 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
/* These must be important to prevent the codemirror defaults from taking over*/
|
||||
.CodeMirror {
|
||||
font-family: monospace;
|
||||
font-size: ${theme.editorFontSize}px;
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
color: inherit !important;
|
||||
@@ -374,37 +372,37 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
/* be applied to the viewer. */
|
||||
padding-bottom: 400px !important;
|
||||
}
|
||||
|
||||
|
||||
.cm-header-1 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
|
||||
.cm-header-2 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
|
||||
.cm-header-3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
|
||||
.cm-header-4, .cm-header-5, .cm-header-6 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
|
||||
.cm-header-1, .cm-header-2, .cm-header-3, .cm-header-4, .cm-header-5, .cm-header-6 {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
|
||||
.cm-search-marker {
|
||||
background: ${theme.searchMarkerBackgroundColor};
|
||||
color: ${theme.searchMarkerColor} !important;
|
||||
}
|
||||
|
||||
|
||||
.cm-search-marker-selected {
|
||||
background: ${theme.selectedColor2};
|
||||
color: ${theme.color2} !important;
|
||||
}
|
||||
|
||||
|
||||
.cm-search-marker-scrollbar {
|
||||
background: ${theme.searchMarkerBackgroundColor};
|
||||
-moz-box-sizing: border-box;
|
||||
@@ -418,27 +416,6 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
background-color: inherit !important;
|
||||
border-bottom: 1px dotted #dc322f;
|
||||
}
|
||||
|
||||
/* The default dark theme colors don't have enough contrast with the background */
|
||||
.cm-s-nord span.cm-comment {
|
||||
color: #9aa4b6 !important;
|
||||
}
|
||||
|
||||
.cm-s-dracula span.cm-comment {
|
||||
color: #a1abc9 !important;
|
||||
}
|
||||
|
||||
.cm-s-monokai span.cm-comment {
|
||||
color: #908b74 !important;
|
||||
}
|
||||
|
||||
.cm-s-material-darker span.cm-comment {
|
||||
color: #878787 !important;
|
||||
}
|
||||
|
||||
.cm-s-solarized.cm-s-dark span.cm-comment {
|
||||
color: #8ba1a7 !important;
|
||||
}
|
||||
`));
|
||||
|
||||
return () => {
|
||||
@@ -502,18 +479,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
}, [renderedBody, webviewReady]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.searchMarkers) return;
|
||||
|
||||
// If there is a currently active search, it's important to re-search the text as the user
|
||||
// types. However this is slow for performance so we ONLY want it to happen when there is
|
||||
// a search
|
||||
|
||||
// Note that since the CodeMirror component also needs to handle the viewer pane, we need
|
||||
// to check if the rendered body has changed too (it will be changed with a delay after
|
||||
// props.content has been updated).
|
||||
const textChanged = props.searchMarkers.keywords.length > 0 && (props.content !== previousContent || renderedBody !== previousRenderedBody);
|
||||
|
||||
if (props.searchMarkers !== previousSearchMarkers || textChanged) {
|
||||
if (props.searchMarkers !== previousSearchMarkers || renderedBody !== previousRenderedBody) {
|
||||
webviewRef.current.wrappedInstance.send('setMarkers', props.searchMarkers.keywords, props.searchMarkers.options);
|
||||
|
||||
if (editorRef.current) {
|
||||
@@ -522,7 +488,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
props.setLocalSearchResultCount(matches);
|
||||
}
|
||||
}
|
||||
}, [props.searchMarkers, previousSearchMarkers, props.setLocalSearchResultCount, props.content, previousContent, renderedBody, previousRenderedBody, renderedBody]);
|
||||
}, [props.searchMarkers, props.setLocalSearchResultCount, renderedBody]);
|
||||
|
||||
const cellEditorStyle = useMemo(() => {
|
||||
const output = { ...styles.cellEditor };
|
||||
@@ -574,13 +540,14 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
editorRef.current.refresh();
|
||||
}, [rootSize, styles.editor, props.visiblePanes]);
|
||||
|
||||
const editorReadOnly = props.visiblePanes.indexOf('editor') < 0;
|
||||
|
||||
function renderEditor() {
|
||||
|
||||
return (
|
||||
<div style={cellEditorStyle}>
|
||||
<Editor
|
||||
value={props.content}
|
||||
searchMarkers={props.searchMarkers}
|
||||
ref={editorRef}
|
||||
mode={props.contentMarkupLanguage === Note.MARKUP_LANGUAGE_HTML ? 'xml' : 'joplin-markdown'}
|
||||
codeMirrorTheme={styles.editor.codeMirrorTheme}
|
||||
@@ -616,6 +583,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
|
||||
<Toolbar
|
||||
themeId={props.themeId}
|
||||
dispatch={props.dispatch}
|
||||
disabled={editorReadOnly}
|
||||
/>
|
||||
{props.noteToolbar}
|
||||
</div>
|
||||
|
||||
@@ -17,17 +17,18 @@ import useCursorUtils from './utils/useCursorUtils';
|
||||
import useLineSorting from './utils/useLineSorting';
|
||||
import useEditorSearch from './utils/useEditorSearch';
|
||||
import useJoplinMode from './utils/useJoplinMode';
|
||||
import useKeymap from './utils/useKeymap';
|
||||
|
||||
import 'codemirror/keymap/emacs';
|
||||
import 'codemirror/keymap/vim';
|
||||
import 'codemirror/keymap/sublime'; // Used for swapLineUp and swapLineDown
|
||||
|
||||
import 'codemirror/mode/meta';
|
||||
const { shim } = require('lib/shim.js');
|
||||
|
||||
const { reg } = require('lib/registry.js');
|
||||
|
||||
// Based on http://pypl.github.io/PYPL.html
|
||||
// +XML (HTML) +CSS and Markdown added
|
||||
const topLanguages = [
|
||||
'python',
|
||||
'clike',
|
||||
@@ -50,16 +51,8 @@ const topLanguages = [
|
||||
'haskell',
|
||||
'pascal',
|
||||
'css',
|
||||
|
||||
// Additional languages, not in the PYPL list
|
||||
'xml', // For HTML too
|
||||
'xml',
|
||||
'markdown',
|
||||
'yaml',
|
||||
'shell',
|
||||
'dockerfile',
|
||||
'diff',
|
||||
'erlang',
|
||||
'sql',
|
||||
];
|
||||
// Load Top Modes
|
||||
for (let i = 0; i < topLanguages.length; i++) {
|
||||
@@ -74,7 +67,6 @@ for (let i = 0; i < topLanguages.length; i++) {
|
||||
|
||||
export interface EditorProps {
|
||||
value: string,
|
||||
searchMarkers: any,
|
||||
mode: string,
|
||||
style: any,
|
||||
codeMirrorTheme: any,
|
||||
@@ -99,7 +91,6 @@ function Editor(props: EditorProps, ref: any) {
|
||||
useLineSorting(CodeMirror);
|
||||
useEditorSearch(CodeMirror);
|
||||
useJoplinMode(CodeMirror);
|
||||
useKeymap(CodeMirror);
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return editor;
|
||||
@@ -142,6 +133,83 @@ function Editor(props: EditorProps, ref: any) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
CodeMirror.keyMap.basic = {
|
||||
'Left': 'goCharLeft',
|
||||
'Right': 'goCharRight',
|
||||
'Up': 'goLineUp',
|
||||
'Down': 'goLineDown',
|
||||
'End': 'goLineRight',
|
||||
'Home': 'goLineLeftSmart',
|
||||
'PageUp': 'goPageUp',
|
||||
'PageDown': 'goPageDown',
|
||||
'Delete': 'delCharAfter',
|
||||
'Backspace': 'delCharBefore',
|
||||
'Shift-Backspace': 'delCharBefore',
|
||||
'Tab': 'smartListIndent',
|
||||
'Shift-Tab': 'smartListUnindent',
|
||||
'Enter': 'insertListElement',
|
||||
'Insert': 'toggleOverwrite',
|
||||
'Esc': 'singleSelection',
|
||||
};
|
||||
|
||||
if (shim.isMac()) {
|
||||
CodeMirror.keyMap.default = {
|
||||
// MacOS
|
||||
'Cmd-A': 'selectAll',
|
||||
'Cmd-D': 'deleteLine',
|
||||
'Cmd-Z': 'undo',
|
||||
'Shift-Cmd-Z': 'redo',
|
||||
'Cmd-Y': 'redo',
|
||||
'Cmd-Home': 'goDocStart',
|
||||
'Cmd-Up': 'goDocStart',
|
||||
'Cmd-End': 'goDocEnd',
|
||||
'Cmd-Down': 'goDocEnd',
|
||||
'Cmd-Left': 'goLineLeft',
|
||||
'Cmd-Right': 'goLineRight',
|
||||
'Alt-Left': 'goGroupLeft',
|
||||
'Alt-Right': 'goGroupRight',
|
||||
'Alt-Backspace': 'delGroupBefore',
|
||||
'Alt-Delete': 'delGroupAfter',
|
||||
'Cmd-[': 'indentLess',
|
||||
'Cmd-]': 'indentMore',
|
||||
'Cmd-/': 'toggleComment',
|
||||
'Cmd-Opt-S': 'sortSelectedLines',
|
||||
'Opt-Up': 'swapLineUp',
|
||||
'Opt-Down': 'swapLineDown',
|
||||
|
||||
'fallthrough': 'basic',
|
||||
};
|
||||
} else {
|
||||
CodeMirror.keyMap.default = {
|
||||
// Windows/linux
|
||||
'Ctrl-A': 'selectAll',
|
||||
'Ctrl-D': 'deleteLine',
|
||||
'Ctrl-Z': 'undo',
|
||||
'Shift-Ctrl-Z': 'redo',
|
||||
'Ctrl-Y': 'redo',
|
||||
'Ctrl-Home': 'goDocStart',
|
||||
'Ctrl-End': 'goDocEnd',
|
||||
'Ctrl-Up': 'goLineUp',
|
||||
'Ctrl-Down': 'goLineDown',
|
||||
'Ctrl-Left': 'goGroupLeft',
|
||||
'Ctrl-Right': 'goGroupRight',
|
||||
'Alt-Left': 'goLineStart',
|
||||
'Alt-Right': 'goLineEnd',
|
||||
'Ctrl-Backspace': 'delGroupBefore',
|
||||
'Ctrl-Delete': 'delGroupAfter',
|
||||
'Ctrl-[': 'indentLess',
|
||||
'Ctrl-]': 'indentMore',
|
||||
'Ctrl-/': 'toggleComment',
|
||||
'Ctrl-Alt-S': 'sortSelectedLines',
|
||||
'Alt-Up': 'swapLineUp',
|
||||
'Alt-Down': 'swapLineDown',
|
||||
|
||||
'fallthrough': 'basic',
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editorParent.current) return () => {};
|
||||
|
||||
@@ -170,11 +238,6 @@ function Editor(props: EditorProps, ref: any) {
|
||||
cm.on('drop', editor_drop);
|
||||
cm.on('dragover', editor_drag);
|
||||
|
||||
// It's possible for searchMarkers to be available before the editor
|
||||
// In these cases we set the markers asap so the user can see them as
|
||||
// soon as the editor is ready
|
||||
if (props.searchMarkers) { cm.setMarkers(props.searchMarkers.keywords, props.searchMarkers.options); }
|
||||
|
||||
return () => {
|
||||
// Clean up codemirror
|
||||
cm.off('change', editor_change);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import CommandService from 'lib/services/CommandService';
|
||||
import ToolbarBase from '../../../ToolbarBase';
|
||||
import CommandService from '../../../../lib/services/CommandService';
|
||||
|
||||
const ToolbarBase = require('../../../Toolbar.min.js');
|
||||
const { buildStyle } = require('lib/theme');
|
||||
|
||||
interface ToolbarProps {
|
||||
themeId: number,
|
||||
dispatch: Function,
|
||||
disabled: boolean,
|
||||
}
|
||||
|
||||
function styles_(props:ToolbarProps) {
|
||||
@@ -47,5 +49,5 @@ export default function Toolbar(props:ToolbarProps) {
|
||||
cmdService.commandToToolbarButton('toggleEditors'),
|
||||
];
|
||||
|
||||
return <ToolbarBase style={styles.root} items={toolbarItems} />;
|
||||
return <ToolbarBase disabled={props.disabled} style={styles.root} items={toolbarItems} />;
|
||||
}
|
||||
|
||||
@@ -119,8 +119,7 @@ export default function useEditorSearch(CodeMirror: any) {
|
||||
// We only want to highlight all matches when there is only 1 search term
|
||||
if (keywords.length !== 1 || keywords[0].value == '') {
|
||||
clearOverlay(this);
|
||||
const prev = keywords.length > 1 ? keywords[0].value : '';
|
||||
setPreviousKeywordValue(prev);
|
||||
setPreviousKeywordValue('');
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@ export default function useJoplinMode(CodeMirror: any) {
|
||||
|
||||
const inlineKatexOpenRE = /(?<!\S)\$(?=[^\s$].*?[^\\\s$]\$(?!\S))/;
|
||||
const inlineKatexCloseRE = /(?<![\\\s$])\$(?!\S)/;
|
||||
const blockKatexOpenRE = /(?<!\S)\$\$/;
|
||||
const blockKatexCloseRE = /(?<![\\\s])\$\$/;
|
||||
const blockKatexRE = /(?<!\\)\$\$/;
|
||||
|
||||
// Find token will search for a valid katex start or end token
|
||||
// If found then it will return the index, otherwise -1
|
||||
@@ -56,19 +55,19 @@ export default function useJoplinMode(CodeMirror: any) {
|
||||
let nextTokenPos = stream.string.length;
|
||||
let closing = false;
|
||||
|
||||
const blockPos = findToken(stream, blockKatexRE);
|
||||
|
||||
if (state.openCharacter) {
|
||||
currentMode = stex;
|
||||
currentState = state.inner;
|
||||
tokenLabel = 'katex-marker-close';
|
||||
closing = true;
|
||||
|
||||
const blockPos = findToken(stream, blockKatexCloseRE);
|
||||
const inlinePos = findToken(stream, inlineKatexCloseRE);
|
||||
|
||||
if (state.openCharacter === '$$' && blockPos !== -1) nextTokenPos = blockPos;
|
||||
if (state.openCharacter === '$' && inlinePos !== -1) nextTokenPos = inlinePos;
|
||||
} else if (!currentState.code) {
|
||||
const blockPos = findToken(stream, blockKatexOpenRE);
|
||||
} else {
|
||||
const inlinePos = findToken(stream, inlineKatexOpenRE);
|
||||
|
||||
if (blockPos !== -1) nextTokenPos = blockPos;
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useEffect } from 'react';
|
||||
import CommandService from 'lib/services/CommandService';
|
||||
const { shim } = require('lib/shim.js');
|
||||
|
||||
export default function useKeymap(CodeMirror: any) {
|
||||
|
||||
function save() {
|
||||
CommandService.instance().execute('synchronize');
|
||||
}
|
||||
|
||||
function setupEmacs() {
|
||||
CodeMirror.keyMap.emacs['Tab'] = 'smartListIndent';
|
||||
CodeMirror.keyMap.emacs['Enter'] = 'insertListElement';
|
||||
CodeMirror.keyMap.emacs['Shift-Tab'] = 'smartListUnindent';
|
||||
}
|
||||
|
||||
function setupVim() {
|
||||
CodeMirror.Vim.defineAction('swapLineDown', CodeMirror.commands.swapLineDown);
|
||||
CodeMirror.Vim.mapCommand('<A-j>', 'action', 'swapLineDown', {}, { context: 'normal', isEdit: true });
|
||||
CodeMirror.Vim.defineAction('swapLineUp', CodeMirror.commands.swapLineUp);
|
||||
CodeMirror.Vim.mapCommand('<A-k>', 'action', 'swapLineUp', {}, { context: 'normal', isEdit: true });
|
||||
CodeMirror.Vim.defineAction('insertListElement', CodeMirror.commands.vimInsertListElement);
|
||||
CodeMirror.Vim.mapCommand('o', 'action', 'insertListElement', { after: true }, { context: 'normal', isEdit: true, interlaceInsertRepeat: true });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// This enables the special modes (emacs and vim) to initiate sync by the save action
|
||||
CodeMirror.commands.save = save;
|
||||
|
||||
CodeMirror.keyMap.basic = {
|
||||
'Left': 'goCharLeft',
|
||||
'Right': 'goCharRight',
|
||||
'Up': 'goLineUp',
|
||||
'Down': 'goLineDown',
|
||||
'End': 'goLineRight',
|
||||
'Home': 'goLineLeftSmart',
|
||||
'PageUp': 'goPageUp',
|
||||
'PageDown': 'goPageDown',
|
||||
'Delete': 'delCharAfter',
|
||||
'Backspace': 'delCharBefore',
|
||||
'Shift-Backspace': 'delCharBefore',
|
||||
'Tab': 'smartListIndent',
|
||||
'Shift-Tab': 'smartListUnindent',
|
||||
'Enter': 'insertListElement',
|
||||
'Insert': 'toggleOverwrite',
|
||||
'Esc': 'singleSelection',
|
||||
};
|
||||
|
||||
if (shim.isMac()) {
|
||||
CodeMirror.keyMap.default = {
|
||||
// MacOS
|
||||
'Cmd-A': 'selectAll',
|
||||
'Cmd-D': 'deleteLine',
|
||||
'Cmd-Z': 'undo',
|
||||
'Shift-Cmd-Z': 'redo',
|
||||
'Cmd-Y': 'redo',
|
||||
'Cmd-Home': 'goDocStart',
|
||||
'Cmd-Up': 'goDocStart',
|
||||
'Cmd-End': 'goDocEnd',
|
||||
'Cmd-Down': 'goDocEnd',
|
||||
'Cmd-Left': 'goLineLeft',
|
||||
'Cmd-Right': 'goLineRight',
|
||||
'Alt-Left': 'goGroupLeft',
|
||||
'Alt-Right': 'goGroupRight',
|
||||
'Alt-Backspace': 'delGroupBefore',
|
||||
'Alt-Delete': 'delGroupAfter',
|
||||
'Cmd-[': 'indentLess',
|
||||
'Cmd-]': 'indentMore',
|
||||
'Cmd-/': 'toggleComment',
|
||||
'Cmd-Opt-S': 'sortSelectedLines',
|
||||
'Opt-Up': 'swapLineUp',
|
||||
'Opt-Down': 'swapLineDown',
|
||||
|
||||
'fallthrough': 'basic',
|
||||
};
|
||||
} else {
|
||||
CodeMirror.keyMap.default = {
|
||||
// Windows/linux
|
||||
'Ctrl-A': 'selectAll',
|
||||
'Ctrl-D': 'deleteLine',
|
||||
'Ctrl-Z': 'undo',
|
||||
'Shift-Ctrl-Z': 'redo',
|
||||
'Ctrl-Y': 'redo',
|
||||
'Ctrl-Home': 'goDocStart',
|
||||
'Ctrl-End': 'goDocEnd',
|
||||
'Ctrl-Up': 'goLineUp',
|
||||
'Ctrl-Down': 'goLineDown',
|
||||
'Ctrl-Left': 'goGroupLeft',
|
||||
'Ctrl-Right': 'goGroupRight',
|
||||
'Alt-Left': 'goLineStart',
|
||||
'Alt-Right': 'goLineEnd',
|
||||
'Ctrl-Backspace': 'delGroupBefore',
|
||||
'Ctrl-Delete': 'delGroupAfter',
|
||||
'Ctrl-[': 'indentLess',
|
||||
'Ctrl-]': 'indentMore',
|
||||
'Ctrl-/': 'toggleComment',
|
||||
'Ctrl-Alt-S': 'sortSelectedLines',
|
||||
'Alt-Up': 'swapLineUp',
|
||||
'Alt-Down': 'swapLineDown',
|
||||
|
||||
'fallthrough': 'basic',
|
||||
};
|
||||
}
|
||||
setupEmacs();
|
||||
setupVim();
|
||||
}, []);
|
||||
}
|
||||
@@ -126,24 +126,6 @@ export default function useListIdent(CodeMirror: any) {
|
||||
});
|
||||
};
|
||||
|
||||
// This is a special case of insertList element because it happens when
|
||||
// vim is in normal mode and input is disabled and the cursor is not
|
||||
// necessarily at the end of line (but it should pretend it is
|
||||
CodeMirror.commands.vimInsertListElement = function(cm: any) {
|
||||
cm.setOption('disableInput', false);
|
||||
|
||||
const ranges = cm.listSelections();
|
||||
if (ranges.length === 0) return;
|
||||
const { anchor } = ranges[0];
|
||||
|
||||
// Need to move the cursor to end of line as this is the vim behavior
|
||||
const line = cm.getLine(anchor.line);
|
||||
cm.setCursor({ line: anchor.line, ch: line.length });
|
||||
|
||||
cm.execCommand('insertListElement');
|
||||
cm.setOption('disableInput', true);
|
||||
};
|
||||
|
||||
CodeMirror.commands.insertListElement = function(cm: any) {
|
||||
if (cm.getOption('disableInput')) return CodeMirror.Pass;
|
||||
|
||||
|
||||
@@ -338,8 +338,12 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
}
|
||||
|
||||
function renderNoteToolbar() {
|
||||
// const theme = themeStyle(props.themeId);
|
||||
|
||||
const toolbarStyle = {
|
||||
marginBottom: 0,
|
||||
// paddingTop: theme.mainPadding,
|
||||
// paddingBottom: theme.mainPadding,
|
||||
};
|
||||
|
||||
return <NoteToolbar
|
||||
@@ -359,12 +363,16 @@ function NoteEditor(props: NoteEditorProps) {
|
||||
|
||||
function renderTagBar() {
|
||||
const theme = themeStyle(props.themeId);
|
||||
const noteIds = [formNote.id];
|
||||
const instructions = <span onClick={() => { CommandService.instance().execute('setTags', { noteIds }); }} style={{ ...theme.clickableTextStyle, whiteSpace: 'nowrap' }}>Click to add tags...</span>;
|
||||
const tagList = props.selectedNoteTags.length ? <TagList items={props.selectedNoteTags} /> : null;
|
||||
let control = null;
|
||||
if (!props.selectedNoteTags.length) {
|
||||
const noteIds = [formNote.id];
|
||||
control = <span onClick={() => { CommandService.instance().execute('setTags', { noteIds }); }} style={theme.clickableTextStyle}>Click to add some tags...</span>;
|
||||
} else {
|
||||
control = <TagList items={props.selectedNoteTags} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ paddingLeft: 8, display: 'flex', flexDirection: 'row', alignItems: 'center' }}>{tagList}{instructions}</div>
|
||||
<div style={{ paddingLeft: 8 }}>{control}</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ function editorCommandRuntime(declaration:CommandDeclaration, editorRef:any):Com
|
||||
}
|
||||
},
|
||||
isEnabled: (props:any) => {
|
||||
if (props.routeName !== 'Main' || props.isDialogVisible) return false;
|
||||
if (props.markdownEditorViewerOnly) return false;
|
||||
if (!props.noteId) return false;
|
||||
const note = BaseModel.byId(props.notes, props.noteId);
|
||||
@@ -59,8 +58,6 @@ function editorCommandRuntime(declaration:CommandDeclaration, editorRef:any):Com
|
||||
noteVisiblePanes: state.noteVisiblePanes,
|
||||
notes: state.notes,
|
||||
noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null,
|
||||
routeName: state.route.routeName,
|
||||
isDialogVisible: !!Object.keys(state.visibleDialogs).length,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,12 +6,9 @@ import CommandService from 'lib/services/CommandService';
|
||||
import { runtime as focusSearchRuntime } from './commands/focusSearch';
|
||||
const styled = require('styled-components').default;
|
||||
|
||||
interface Props {
|
||||
showNewNoteButtons: boolean,
|
||||
}
|
||||
|
||||
const StyledRoot = styled.div`
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: ${(props:any) => props.theme.mainPadding}px;
|
||||
@@ -22,12 +19,7 @@ const StyledButton = styled(Button)`
|
||||
margin-left: 8px;
|
||||
`;
|
||||
|
||||
const ButtonContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
`;
|
||||
|
||||
export default function NoteListControls(props:Props) {
|
||||
export default function NoteListControls() {
|
||||
const searchBarRef = useRef(null);
|
||||
|
||||
useEffect(function() {
|
||||
@@ -46,31 +38,21 @@ export default function NoteListControls(props:Props) {
|
||||
CommandService.instance().execute('newNote');
|
||||
}
|
||||
|
||||
function renderNewNoteButtons() {
|
||||
if (!props.showNewNoteButtons) return null;
|
||||
|
||||
return (
|
||||
<ButtonContainer>
|
||||
<StyledButton
|
||||
tooltip={CommandService.instance().title('newTodo')}
|
||||
iconName="far fa-check-square"
|
||||
level={ButtonLevel.Primary}
|
||||
onClick={onNewTodoButtonClick}
|
||||
/>
|
||||
<StyledButton
|
||||
tooltip={CommandService.instance().title('newNote')}
|
||||
iconName="icon-note"
|
||||
level={ButtonLevel.Primary}
|
||||
onClick={onNewNoteButtonClick}
|
||||
/>
|
||||
</ButtonContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledRoot>
|
||||
<SearchBar inputRef={searchBarRef}/>
|
||||
{renderNewNoteButtons()}
|
||||
<StyledButton
|
||||
tooltip={CommandService.instance().title('newTodo')}
|
||||
iconName="far fa-check-square"
|
||||
level={ButtonLevel.Primary}
|
||||
onClick={onNewTodoButtonClick}
|
||||
/>
|
||||
<StyledButton
|
||||
tooltip={CommandService.instance().title('newNote')}
|
||||
iconName="icon-note"
|
||||
level={ButtonLevel.Primary}
|
||||
onClick={onNewNoteButtonClick}
|
||||
/>
|
||||
</StyledRoot>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('lib/theme');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const NoteTextViewer = require('./NoteTextViewer').default;
|
||||
const NoteTextViewer = require('./NoteTextViewer.min');
|
||||
const HelpButton = require('./HelpButton.min');
|
||||
const BaseModel = require('lib/BaseModel');
|
||||
const Revision = require('lib/models/Revision');
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
import * as React from 'react';
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { reg } = require('lib/registry.js');
|
||||
|
||||
interface Props {
|
||||
onDomReady: Function,
|
||||
onIpcMessage: Function,
|
||||
viewerStyle: any,
|
||||
}
|
||||
class NoteTextViewerComponent extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
|
||||
private initialized_:boolean = false;
|
||||
private domReady_:boolean = false;
|
||||
private webviewRef_:any;
|
||||
private webviewListeners_:any = null;
|
||||
|
||||
constructor(props:any) {
|
||||
super(props);
|
||||
this.initialized_ = false;
|
||||
this.domReady_ = false;
|
||||
|
||||
this.webviewRef_ = React.createRef();
|
||||
this.webviewListeners_ = null;
|
||||
|
||||
this.webview_domReady = this.webview_domReady.bind(this);
|
||||
this.webview_ipcMessage = this.webview_ipcMessage.bind(this);
|
||||
@@ -26,20 +17,20 @@ class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
this.webview_message = this.webview_message.bind(this);
|
||||
}
|
||||
|
||||
webview_domReady(event:any) {
|
||||
webview_domReady(event) {
|
||||
this.domReady_ = true;
|
||||
if (this.props.onDomReady) this.props.onDomReady(event);
|
||||
}
|
||||
|
||||
webview_ipcMessage(event:any) {
|
||||
webview_ipcMessage(event) {
|
||||
if (this.props.onIpcMessage) this.props.onIpcMessage(event);
|
||||
}
|
||||
|
||||
webview_load() {
|
||||
this.webview_domReady({});
|
||||
this.webview_domReady();
|
||||
}
|
||||
|
||||
webview_message(event:any) {
|
||||
webview_message(event) {
|
||||
if (!event.data || event.data.target !== 'main') return;
|
||||
|
||||
const callName = event.data.name;
|
||||
@@ -87,14 +78,7 @@ class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
wv.removeEventListener(n, fn);
|
||||
}
|
||||
|
||||
try {
|
||||
// It seems this can throw a cross-origin error in a way that is hard to replicate so just wrap
|
||||
// it in try/catch since it's not critical.
|
||||
// https://github.com/laurent22/joplin/issues/3835
|
||||
this.webviewRef_.current.contentWindow.removeEventListener('message', this.webview_message);
|
||||
} catch (error) {
|
||||
reg.logger().warn('Error destroying note viewer', error);
|
||||
}
|
||||
this.webviewRef_.current.contentWindow.removeEventListener('message', this.webview_message);
|
||||
|
||||
this.initialized_ = false;
|
||||
this.domReady_ = false;
|
||||
@@ -123,7 +107,7 @@ class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
// Wrap WebView functions
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
send(channel:string, arg0:any = null, arg1:any = null) {
|
||||
send(channel, arg0 = null, arg1 = null) {
|
||||
const win = this.webviewRef_.current.contentWindow;
|
||||
|
||||
if (channel === 'setHtml') {
|
||||
@@ -143,6 +127,36 @@ class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
}
|
||||
}
|
||||
|
||||
printToPDF() { // options, callback) {
|
||||
// In Electron 4x, printToPDF is broken so need to use this hack:
|
||||
// https://github.com/electron/electron/issues/16171#issuecomment-451090245
|
||||
|
||||
// return this.webviewRef_.current.printToPDF(options, callback);
|
||||
// return this.webviewRef_.current.getWebContents().printToPDF(options, callback);
|
||||
}
|
||||
|
||||
print() {
|
||||
// In Electron 4x, print is broken so need to use this hack:
|
||||
// https://github.com/electron/electron/issues/16219#issuecomment-451454948
|
||||
// Note that this is not a perfect workaround since it means the options are ignored
|
||||
// In particular it means that background images and colours won't be printed (printBackground property will be ignored)
|
||||
|
||||
// return this.webviewRef_.current.getWebContents().print({});
|
||||
return this.webviewRef_.current.getWebContents().executeJavaScript('window.print()');
|
||||
}
|
||||
|
||||
openDevTools() {
|
||||
// return this.webviewRef_.current.openDevTools();
|
||||
}
|
||||
|
||||
closeDevTools() {
|
||||
// return this.webviewRef_.current.closeDevTools();
|
||||
}
|
||||
|
||||
isDevToolsOpened() {
|
||||
// return this.webviewRef_.current.isDevToolsOpened();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Wrap WebView functions (END)
|
||||
// ----------------------------------------------------------------
|
||||
@@ -153,7 +167,7 @@ class NoteTextViewerComponent extends React.Component<Props, any> {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state:any) => {
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
themeId: state.settings.theme,
|
||||
};
|
||||
@@ -166,4 +180,4 @@ const NoteTextViewer = connect(
|
||||
{ withRef: true }
|
||||
)(NoteTextViewerComponent);
|
||||
|
||||
export default NoteTextViewer;
|
||||
module.exports = NoteTextViewer;
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import CommandService from '../../lib/services/CommandService';
|
||||
import ToolbarBase from '../ToolbarBase';
|
||||
const { connect } = require('react-redux');
|
||||
const { buildStyle } = require('lib/theme');
|
||||
const Toolbar = require('../Toolbar.min.js');
|
||||
// const Folder = require('lib/models/Folder');
|
||||
// const { _ } = require('lib/locale');
|
||||
// const { substrWithEllipsis } = require('lib/string-utils');
|
||||
@@ -40,12 +40,21 @@ function styles_(props:NoteToolbarProps) {
|
||||
function NoteToolbar(props:NoteToolbarProps) {
|
||||
const styles = styles_(props);
|
||||
const [toolbarItems, setToolbarItems] = useState([]);
|
||||
// const selectedNoteFolder = Folder.byId(props.folders, props.note.parent_id);
|
||||
// const folderId = selectedNoteFolder ? selectedNoteFolder.id : '';
|
||||
// const folderTitle = selectedNoteFolder && selectedNoteFolder.title ? selectedNoteFolder.title : '';
|
||||
|
||||
const cmdService = CommandService.instance();
|
||||
|
||||
function updateToolbarItems() {
|
||||
const output = [];
|
||||
|
||||
// if (props.watchedNoteFiles.indexOf(props.note.id) >= 0) {
|
||||
// output.push(cmdService.commandToToolbarButton('stopExternalEditing'));
|
||||
// } else {
|
||||
// output.push(cmdService.commandToToolbarButton('startExternalEditing'));
|
||||
// }
|
||||
|
||||
output.push(cmdService.commandToToolbarButton('editAlarm'));
|
||||
output.push(cmdService.commandToToolbarButton('toggleVisiblePanes'));
|
||||
output.push(cmdService.commandToToolbarButton('showNoteProperties'));
|
||||
@@ -61,7 +70,7 @@ function NoteToolbar(props:NoteToolbarProps) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <ToolbarBase style={styles.root} items={toolbarItems} />;
|
||||
return <Toolbar style={styles.root} items={toolbarItems} />;
|
||||
}
|
||||
|
||||
const mapStateToProps = (state:any) => {
|
||||
|
||||
@@ -24,7 +24,7 @@ const { bridge } = require('electron').remote.require('./bridge');
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
div, span, a {
|
||||
color: ${(props) => props.theme.color};
|
||||
/*font-size: ${(props) => props.theme.fontSize}px;*/
|
||||
font-size: ${(props) => props.theme.fontSize}px;
|
||||
font-family: ${(props) => props.theme.fontFamily};
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -10,42 +10,15 @@ const { _ } = require('lib/locale.js');
|
||||
interface Props {
|
||||
inputRef?: any,
|
||||
notesParentType: string,
|
||||
dispatch?: Function,
|
||||
}
|
||||
|
||||
function SearchBar(props:Props) {
|
||||
const [query, setQuery] = useState('');
|
||||
const iconName = !query ? CommandService.instance().iconName('search') : 'fa fa-times';
|
||||
|
||||
function onChange(event:any) {
|
||||
const onChange = (event:any) => {
|
||||
setQuery(event.currentTarget.value);
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
props.dispatch({
|
||||
type: 'FOCUS_SET',
|
||||
field: 'globalSearch',
|
||||
});
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
// Do it after a delay so that the "Clear" button
|
||||
// can be clicked on (otherwise the field loses focus
|
||||
// and is resized before the click event has been processed)
|
||||
setTimeout(() => {
|
||||
props.dispatch({
|
||||
type: 'FOCUS_CLEAR',
|
||||
field: 'globalSearch',
|
||||
});
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function onKeyDown(event:any) {
|
||||
if (event.key === 'Escape') {
|
||||
setQuery('');
|
||||
if (document.activeElement) (document.activeElement as any).blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onSearchButtonClick = useCallback(() => {
|
||||
setQuery('');
|
||||
@@ -61,16 +34,7 @@ function SearchBar(props:Props) {
|
||||
|
||||
return (
|
||||
<Root>
|
||||
<SearchInput
|
||||
ref={props.inputRef}
|
||||
value={query}
|
||||
type="text"
|
||||
placeholder={_('Search...')}
|
||||
onChange={onChange}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
<SearchInput ref={props.inputRef} value={query} type="text" placeholder={_('Search...')} onChange={onChange}/>
|
||||
<SearchButton onClick={onSearchButtonClick}>
|
||||
<SearchButtonIcon className={iconName}/>
|
||||
</SearchButton>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { StyledRoot, StyledAddButton, StyledHeader, StyledHeaderIcon, StyledAllNotesIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
|
||||
import { StyledRoot, StyledAddButton, StyledHeader, StyledHeaderIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
|
||||
import { ButtonLevel } from '../Button/Button';
|
||||
import CommandService from 'lib/services/CommandService';
|
||||
|
||||
@@ -45,52 +45,6 @@ const commands = [
|
||||
require('./commands/focusElementSideBar'),
|
||||
];
|
||||
|
||||
function ExpandIcon(props:any) {
|
||||
const theme = themeStyle(props.themeId);
|
||||
const style:any = { width: 16, maxWidth: 16, opacity: 0.5, fontSize: Math.round(theme.toolbarIconSize * 0.8), display: 'flex', justifyContent: 'center' };
|
||||
if (!props.isVisible) style.visibility = 'hidden';
|
||||
return <i className={props.isExpanded ? 'fas fa-caret-down' : 'fas fa-caret-right'} style={style}></i>;
|
||||
}
|
||||
|
||||
function ExpandLink(props:any) {
|
||||
return props.hasChildren ? (
|
||||
<StyledExpandLink href="#" data-folder-id={props.folderId} onClick={props.onClick}>
|
||||
<ExpandIcon themeId={props.themeId} isVisible={true} isExpanded={props.isExpanded}/>
|
||||
</StyledExpandLink>
|
||||
) : (
|
||||
<StyledExpandLink><ExpandIcon themeId={props.themeId} isVisible={false} isExpanded={false}/></StyledExpandLink>
|
||||
);
|
||||
}
|
||||
|
||||
function FolderItem(props:any) {
|
||||
const { hasChildren, isExpanded, depth, selected, folderId, folderTitle, anchorRef, noteCount, onFolderDragStart_, onFolderDragOver_, onFolderDrop_, itemContextMenu, folderItem_click, onFolderToggleClick_ } = props;
|
||||
|
||||
const noteCountComp = noteCount ? <StyledNoteCount>{noteCount}</StyledNoteCount> : null;
|
||||
|
||||
return (
|
||||
<StyledListItem depth={depth} selected={selected} className={`list-item-container list-item-depth-${depth}`} onDragStart={onFolderDragStart_} onDragOver={onFolderDragOver_} onDrop={onFolderDrop_} draggable={true} data-folder-id={folderId}>
|
||||
<ExpandLink themeId={props.themeId} hasChildren={hasChildren} folderId={folderId} onClick={onFolderToggleClick_} isExpanded={isExpanded}/>
|
||||
<StyledListItemAnchor
|
||||
ref={anchorRef}
|
||||
className="list-item"
|
||||
isConflictFolder={folderId === Folder.conflictFolderId()}
|
||||
href="#"
|
||||
selected={selected}
|
||||
data-id={folderId}
|
||||
data-type={BaseModel.TYPE_FOLDER}
|
||||
onContextMenu={itemContextMenu}
|
||||
data-folder-id={folderId}
|
||||
onClick={() => {
|
||||
folderItem_click(folderId);
|
||||
}}
|
||||
onDoubleClick={onFolderToggleClick_}
|
||||
>
|
||||
{folderTitle} {noteCountComp}
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
);
|
||||
}
|
||||
|
||||
class SideBarComponent extends React.Component<Props, State> {
|
||||
|
||||
private folderItemsOrder_:any[] = [];
|
||||
@@ -114,8 +68,6 @@ class SideBarComponent extends React.Component<Props, State> {
|
||||
this.onAllNotesClick_ = this.onAllNotesClick_.bind(this);
|
||||
this.header_contextMenu = this.header_contextMenu.bind(this);
|
||||
this.onAddFolderButtonClick = this.onAddFolderButtonClick.bind(this);
|
||||
this.folderItem_click = this.folderItem_click.bind(this);
|
||||
this.itemContextMenu = this.itemContextMenu.bind(this);
|
||||
}
|
||||
|
||||
onFolderDragStart_(event:any) {
|
||||
@@ -305,10 +257,10 @@ class SideBarComponent extends React.Component<Props, State> {
|
||||
menu.popup(bridge().window());
|
||||
}
|
||||
|
||||
folderItem_click(folderId:string) {
|
||||
folderItem_click(folder:any) {
|
||||
this.props.dispatch({
|
||||
type: 'FOLDER_SELECT',
|
||||
id: folderId ? folderId : null,
|
||||
id: folder ? folder.id : null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -339,7 +291,7 @@ class SideBarComponent extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
renderNoteCount(count:number) {
|
||||
return count ? <StyledNoteCount>{count}</StyledNoteCount> : null;
|
||||
return <StyledNoteCount>{count}</StyledNoteCount>;
|
||||
}
|
||||
|
||||
renderExpandIcon(isExpanded:boolean, isVisible:boolean = true) {
|
||||
@@ -353,41 +305,57 @@ class SideBarComponent extends React.Component<Props, State> {
|
||||
return (
|
||||
<StyledListItem key="allNotesHeader" selected={selected} className={'list-item-container list-item-depth-0'} isSpecialItem={true}>
|
||||
<StyledExpandLink>{this.renderExpandIcon(false, false)}</StyledExpandLink>
|
||||
<StyledAllNotesIcon className="icon-notes"/>
|
||||
<StyledListItemAnchor
|
||||
className="list-item"
|
||||
isSpecialItem={true}
|
||||
href="#"
|
||||
selected={selected}
|
||||
onClick={this.onAllNotesClick_}
|
||||
onClick={() => {
|
||||
this.onAllNotesClick_();
|
||||
}}
|
||||
>
|
||||
{_('All notes')}
|
||||
({_('All notes')})
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
);
|
||||
}
|
||||
|
||||
renderFolderItem(folder:any, selected:boolean, hasChildren:boolean, depth:number) {
|
||||
const anchorRef = this.anchorItemRef('folder', folder.id);
|
||||
const isExpanded = this.props.collapsedFolderIds.indexOf(folder.id) < 0;
|
||||
const expandIcon = this.renderExpandIcon(isExpanded, hasChildren);
|
||||
const expandLink = hasChildren ? (
|
||||
<StyledExpandLink href="#" data-folder-id={folder.id} onClick={this.onFolderToggleClick_}>
|
||||
{expandIcon}
|
||||
</StyledExpandLink>
|
||||
) : (
|
||||
<StyledExpandLink>{expandIcon}</StyledExpandLink>
|
||||
);
|
||||
|
||||
return <FolderItem
|
||||
key={folder.id}
|
||||
folderId={folder.id}
|
||||
folderTitle={Folder.displayTitle(folder)}
|
||||
themeId={this.props.themeId}
|
||||
depth={depth}
|
||||
selected={selected}
|
||||
isExpanded={this.props.collapsedFolderIds.indexOf(folder.id) < 0}
|
||||
hasChildren={hasChildren}
|
||||
anchorRef={anchorRef}
|
||||
noteCount={folder.note_count}
|
||||
onFolderDragStart_={this.onFolderDragStart_}
|
||||
onFolderDragOver_={this.onFolderDragOver_}
|
||||
onFolderDrop_={this.onFolderDrop_}
|
||||
itemContextMenu={this.itemContextMenu}
|
||||
folderItem_click={this.folderItem_click}
|
||||
onFolderToggleClick_={this.onFolderToggleClick_}
|
||||
/>;
|
||||
const anchorRef = this.anchorItemRef('folder', folder.id);
|
||||
const noteCount = folder.note_count ? this.renderNoteCount(folder.note_count) : '';
|
||||
|
||||
return (
|
||||
<StyledListItem depth={depth} selected={selected} className={`list-item-container list-item-depth-${depth}`} key={folder.id} onDragStart={this.onFolderDragStart_} onDragOver={this.onFolderDragOver_} onDrop={this.onFolderDrop_} draggable={true} data-folder-id={folder.id}>
|
||||
{expandLink}
|
||||
<StyledListItemAnchor
|
||||
ref={anchorRef}
|
||||
className="list-item"
|
||||
isConflictFolder={folder.id === Folder.conflictFolderId()}
|
||||
href="#"
|
||||
selected={selected}
|
||||
data-id={folder.id}
|
||||
data-type={BaseModel.TYPE_FOLDER}
|
||||
onContextMenu={(event:any) => this.itemContextMenu(event)}
|
||||
data-folder-id={folder.id}
|
||||
onClick={() => {
|
||||
this.folderItem_click(folder);
|
||||
}}
|
||||
onDoubleClick={this.onFolderToggleClick_}
|
||||
>
|
||||
{Folder.displayTitle(folder)} {noteCount}
|
||||
</StyledListItemAnchor>
|
||||
</StyledListItem>
|
||||
);
|
||||
}
|
||||
|
||||
renderTag(tag:any, selected:boolean) {
|
||||
@@ -404,7 +372,7 @@ class SideBarComponent extends React.Component<Props, State> {
|
||||
selected={selected}
|
||||
data-id={tag.id}
|
||||
data-type={BaseModel.TYPE_TAG}
|
||||
onContextMenu={this.itemContextMenu}
|
||||
onContextMenu={(event:any) => this.itemContextMenu(event)}
|
||||
onClick={() => {
|
||||
this.tagItem_click(tag);
|
||||
}}
|
||||
|
||||
@@ -31,12 +31,6 @@ export const StyledHeaderIcon = styled.i`
|
||||
margin-right: 8px;
|
||||
`;
|
||||
|
||||
export const StyledAllNotesIcon = styled(StyledHeaderIcon)`
|
||||
font-size: ${(props:any) => props.theme.toolbarIconSize * 0.8}px;
|
||||
color: ${(props:any) => props.theme.colorFaded2};
|
||||
margin-right: 8px;
|
||||
`;
|
||||
|
||||
export const StyledHeaderLabel = styled.span`
|
||||
flex: 1;
|
||||
color: ${(props:any) => props.theme.color2};
|
||||
@@ -49,10 +43,9 @@ export const StyledListItem = styled.div`
|
||||
height: 25px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding-left: ${(props:any) => props.theme.mainPadding + ('depth' in props ? props.depth : 0) * 16}px;
|
||||
background: ${(props:any) => props.selected ? props.theme.selectedColor2 : 'none'};
|
||||
/*text-transform: ${(props:any) => props.isSpecialItem ? 'uppercase' : 'none'};*/
|
||||
text-transform: ${(props:any) => props.isSpecialItem ? 'uppercase' : 'none'};
|
||||
transition: 0.1s;
|
||||
|
||||
&:hover {
|
||||
@@ -78,7 +71,6 @@ export const StyledListItemAnchor = styled.a`
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export const StyledExpandLink = styled.a`
|
||||
@@ -92,7 +84,6 @@ export const StyledExpandLink = styled.a`
|
||||
width: 16px;
|
||||
max-width: 16px;
|
||||
min-width: 16px;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export const StyledNoteCount = styled.div`
|
||||
|
||||
@@ -5,18 +5,11 @@ const ToolbarButton = require('./ToolbarButton/ToolbarButton.js').default;
|
||||
const ToolbarSpace = require('./ToolbarSpace.min.js');
|
||||
const ToggleEditorsButton = require('./ToggleEditorsButton/ToggleEditorsButton.js').default;
|
||||
|
||||
interface Props {
|
||||
themeId: number,
|
||||
style: any,
|
||||
items: any[],
|
||||
}
|
||||
|
||||
class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
|
||||
class ToolbarComponent extends React.Component {
|
||||
render() {
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
const style:any = Object.assign({
|
||||
const style = Object.assign({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxSizing: 'border-box',
|
||||
@@ -25,15 +18,15 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
paddingRight: theme.mainPadding,
|
||||
}, this.props.style);
|
||||
|
||||
const groupStyle:any = {
|
||||
const groupStyle = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
boxSizing: 'border-box',
|
||||
};
|
||||
|
||||
const leftItemComps:any[] = [];
|
||||
const centerItemComps:any[] = [];
|
||||
const rightItemComps:any[] = [];
|
||||
const leftItemComps = [];
|
||||
const centerItemComps = [];
|
||||
const rightItemComps = [];
|
||||
|
||||
if (this.props.items) {
|
||||
for (let i = 0; i < this.props.items.length; i++) {
|
||||
@@ -52,6 +45,8 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
o
|
||||
);
|
||||
|
||||
if (this.props.disabled) props.disabled = true;
|
||||
|
||||
if (o.name === 'toggleEditors') {
|
||||
rightItemComps.push(<ToggleEditorsButton
|
||||
key={o.name}
|
||||
@@ -84,8 +79,10 @@ class ToolbarBaseComponent extends React.Component<Props, any> {
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state:any) => {
|
||||
const mapStateToProps = state => {
|
||||
return { themeId: state.settings.theme };
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(ToolbarBaseComponent);
|
||||
const Toolbar = connect(mapStateToProps)(ToolbarComponent);
|
||||
|
||||
module.exports = Toolbar;
|
||||
221
ElectronClient/package-lock.json
generated
221
ElectronClient/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Joplin",
|
||||
"version": "1.2.6",
|
||||
"version": "1.1.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1535,7 +1535,7 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -1701,7 +1701,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
@@ -1817,7 +1817,7 @@
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.8",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
@@ -1970,44 +1970,6 @@
|
||||
"source-map": "^0.5.6"
|
||||
}
|
||||
},
|
||||
"babel-eslint": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
|
||||
"integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@babel/parser": "^7.7.0",
|
||||
"@babel/traverse": "^7.7.0",
|
||||
"@babel/types": "^7.7.0",
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"resolve": "^1.12.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/types": {
|
||||
"version": "7.11.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz",
|
||||
"integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.10.4",
|
||||
"lodash": "^4.17.19",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-generator": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
|
||||
@@ -3626,9 +3588,9 @@
|
||||
}
|
||||
},
|
||||
"d3": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-5.16.0.tgz",
|
||||
"integrity": "sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-5.15.0.tgz",
|
||||
"integrity": "sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg==",
|
||||
"requires": {
|
||||
"d3-array": "1",
|
||||
"d3-axis": "1",
|
||||
@@ -3674,9 +3636,9 @@
|
||||
"integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
|
||||
},
|
||||
"d3-brush": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.6.tgz",
|
||||
"integrity": "sha512-7RW+w7HfMCPyZLifTz/UnJmI5kdkXtpCbombUSs8xniAyo0vIbrDzDwUJB6eJOgl9u5DQOt2TQlYumxzD1SvYA==",
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz",
|
||||
"integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-drag": "1",
|
||||
@@ -3700,9 +3662,9 @@
|
||||
"integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A=="
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
|
||||
"integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
|
||||
},
|
||||
"d3-contour": {
|
||||
"version": "1.3.2",
|
||||
@@ -3737,14 +3699,14 @@
|
||||
}
|
||||
},
|
||||
"d3-ease": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.7.tgz",
|
||||
"integrity": "sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ=="
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz",
|
||||
"integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ=="
|
||||
},
|
||||
"d3-fetch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.2.0.tgz",
|
||||
"integrity": "sha512-yC78NBVcd2zFAyR/HnUiBS7Lf6inSCoWcSxFfw8FYL7ydiqe80SazNwoffcqOfs95XaLo7yebsmQqDKSsXUtvA==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz",
|
||||
"integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==",
|
||||
"requires": {
|
||||
"d3-dsv": "1"
|
||||
}
|
||||
@@ -3761,14 +3723,14 @@
|
||||
}
|
||||
},
|
||||
"d3-format": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz",
|
||||
"integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ=="
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.3.tgz",
|
||||
"integrity": "sha512-mm/nE2Y9HgGyjP+rKIekeITVgBtX97o1nrvHCWX8F/yBYyevUTvu9vb5pUnKwrcSw7o7GuwMOWjS9gFDs4O+uQ=="
|
||||
},
|
||||
"d3-geo": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz",
|
||||
"integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==",
|
||||
"version": "1.11.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.9.tgz",
|
||||
"integrity": "sha512-9edcH6J3s/Aa3KJITWqFJbyB/8q3mMlA9Fi7z6yy+FAYMnRaxmC7jBhUnsINxVWD14GmqX3DK8uk7nV6/Ekt4A==",
|
||||
"requires": {
|
||||
"d3-array": "1"
|
||||
}
|
||||
@@ -3829,9 +3791,9 @@
|
||||
}
|
||||
},
|
||||
"d3-selection": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
|
||||
"integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.1.tgz",
|
||||
"integrity": "sha512-BTIbRjv/m5rcVTfBs4AMBLKs4x8XaaLkwm28KWu9S2vKNqXkXt2AH2Qf0sdPZHjFxcWg/YL53zcqAz+3g4/7PA=="
|
||||
},
|
||||
"d3-shape": {
|
||||
"version": "1.3.7",
|
||||
@@ -3847,9 +3809,9 @@
|
||||
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
|
||||
},
|
||||
"d3-time-format": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
|
||||
"integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
|
||||
"integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
|
||||
"requires": {
|
||||
"d3-time": "1"
|
||||
}
|
||||
@@ -4701,14 +4663,6 @@
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
|
||||
"integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
|
||||
},
|
||||
"entity-decode": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/entity-decode/-/entity-decode-2.0.2.tgz",
|
||||
"integrity": "sha512-5CCY/3ci4MC1m2jlumNjWd7VBFt4VfFnmSqSNmVcXq4gxM3Vmarxtt+SvmBnzwLS669MWdVuXboNVj1qN2esVg==",
|
||||
"requires": {
|
||||
"he": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"env-paths": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
|
||||
@@ -4789,6 +4743,11 @@
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"escaper": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/escaper/-/escaper-2.5.3.tgz",
|
||||
"integrity": "sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ=="
|
||||
},
|
||||
"escodegen": {
|
||||
"version": "1.14.3",
|
||||
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
|
||||
@@ -4809,11 +4768,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-visitor-keys": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
|
||||
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
@@ -6122,7 +6076,7 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": false,
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
@@ -7193,6 +7147,11 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-regexp": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
|
||||
"integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk="
|
||||
},
|
||||
"is-relative": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
|
||||
@@ -7601,11 +7560,6 @@
|
||||
"json-buffer": "3.0.0"
|
||||
}
|
||||
},
|
||||
"khroma": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/khroma/-/khroma-1.1.0.tgz",
|
||||
"integrity": "sha512-aTO+YX22tYOLEQJYFiatAj1lc5QZ+H5sHWFRBWNCiKwc5NWNUJZyeSeiHEPeURJ2a1GEVYcmyMUwGjjLe5ec5A=="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
@@ -8073,22 +8027,31 @@
|
||||
"integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
|
||||
},
|
||||
"mermaid": {
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.8.0.tgz",
|
||||
"integrity": "sha512-SbMzt5T6+XMkHRUECHUneq26H8bvjF752YZCKCJ4G8UU7qI2OmmxYdj4ZJnda7JIx3EuNeN4xSLuLCBJ5ByzSQ==",
|
||||
"version": "8.4.6",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.4.6.tgz",
|
||||
"integrity": "sha512-6YQBkXfvhfjKIzRhtqbCics3pJurGrJAYEeqgyRcDZeTHQ/WCB2Bh/4wdAOho1Uffe0jXB+HjmHT5kEUOxudJw==",
|
||||
"requires": {
|
||||
"@braintree/sanitize-url": "^3.1.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"crypto-random-string": "^3.0.1",
|
||||
"d3": "^5.7.0",
|
||||
"dagre": "^0.8.4",
|
||||
"dagre-d3": "^0.6.4",
|
||||
"entity-decode": "^2.0.2",
|
||||
"graphlib": "^2.1.7",
|
||||
"he": "^1.2.0",
|
||||
"khroma": "^1.1.0",
|
||||
"lodash": "^4.17.11",
|
||||
"minify": "^4.1.1",
|
||||
"moment-mini": "^2.22.1",
|
||||
"stylis": "^3.5.2"
|
||||
"scope-css": "^1.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-random-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-3.1.0.tgz",
|
||||
"integrity": "sha512-Tip3yGB+bA7B0W8E4K4mNf2rZhu5r2G5Tb89/utEl5tP1QuLjTF/S9a1b8ifDrR4ORc9Utf6tscpSEtBY3YcPQ==",
|
||||
"requires": {
|
||||
"type-fest": "^0.8.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
@@ -8249,11 +8212,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
|
||||
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
@@ -8368,9 +8331,9 @@
|
||||
"integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y="
|
||||
},
|
||||
"moment-mini": {
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
|
||||
"integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ=="
|
||||
"version": "2.22.1",
|
||||
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.22.1.tgz",
|
||||
"integrity": "sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
@@ -10465,6 +10428,16 @@
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"scope-css": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/scope-css/-/scope-css-1.2.1.tgz",
|
||||
"integrity": "sha512-UjLRmyEYaDNiOS673xlVkZFlVCtckJR/dKgr434VMm7Lb+AOOqXKdAcY7PpGlJYErjXXJzKN7HWo4uRPiZZG0Q==",
|
||||
"requires": {
|
||||
"escaper": "^2.5.3",
|
||||
"slugify": "^1.3.1",
|
||||
"strip-css-comments": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
@@ -10669,10 +10642,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"slug": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/slug/-/slug-3.5.0.tgz",
|
||||
"integrity": "sha512-+pZLDhMtmAc+ZcojQSMlUKDZBYmvhZiZmK8Ffx/D3Q/MIMHPDBAMbWvWN8vJb9xl2MfbDdRWxFzrdOhBiyVpow=="
|
||||
"slugify": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.6.tgz",
|
||||
"integrity": "sha512-wA9XS475ZmGNlEnYYLPReSfuz/c3VQsEMoU43mi6OnKMCdbnFXd4/Yg7J0lBv8jkPolacMpOrWEaoYxuE1+hoQ=="
|
||||
},
|
||||
"smalltalk": {
|
||||
"version": "2.5.1",
|
||||
@@ -11036,6 +11009,14 @@
|
||||
"is-utf8": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"strip-css-comments": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-css-comments/-/strip-css-comments-3.0.0.tgz",
|
||||
"integrity": "sha1-elYl7/iisibPiUehElTaluE9rok=",
|
||||
"requires": {
|
||||
"is-regexp": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
@@ -11316,9 +11297,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
|
||||
"integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.6.1",
|
||||
@@ -11336,9 +11317,9 @@
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.19",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
|
||||
"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
@@ -11604,8 +11585,7 @@
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
@@ -11731,6 +11711,11 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unset-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
@@ -11922,6 +11907,14 @@
|
||||
"integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
|
||||
"dev": true
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"utf8-byte-length": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Joplin",
|
||||
"version": "1.2.6",
|
||||
"version": "1.1.1",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
@@ -169,7 +169,7 @@
|
||||
"md5": "^2.2.1",
|
||||
"md5-file": "^4.0.0",
|
||||
"memory-cache": "^0.2.0",
|
||||
"mermaid": "^8.8.0",
|
||||
"mermaid": "^8.4.6",
|
||||
"moment": "^2.22.2",
|
||||
"multiparty": "^4.2.1",
|
||||
"mustache": "^3.0.1",
|
||||
@@ -193,7 +193,6 @@
|
||||
"roboto-fontface": "^0.10.0",
|
||||
"sax": "^1.2.4",
|
||||
"server-destroy": "^1.0.1",
|
||||
"slug": "^3.5.0",
|
||||
"smalltalk": "^2.5.1",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"sqlite3": "^4.1.1",
|
||||
@@ -208,6 +207,7 @@
|
||||
"tinymce": "^5.2.0",
|
||||
"uglifycss": "0.0.29",
|
||||
"url-parse": "^1.4.3",
|
||||
"uslug": "^1.0.4",
|
||||
"uuid": "^3.2.1",
|
||||
"valid-url": "^1.0.9",
|
||||
"xml2js": "^0.4.19"
|
||||
|
||||
@@ -120,21 +120,11 @@ class Dialog extends React.PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.onKeyDown);
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'VISIBLE_DIALOGS_ADD',
|
||||
name: 'gotoAnything',
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.listUpdateIID_) clearTimeout(this.listUpdateIID_);
|
||||
document.removeEventListener('keydown', this.onKeyDown);
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'VISIBLE_DIALOGS_REMOVE',
|
||||
name: 'gotoAnything',
|
||||
});
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
|
||||
@@ -20,15 +20,15 @@ Three types of applications are available: for the **desktop** (Windows, macOS a
|
||||
|
||||
Operating System | Download | Alternative
|
||||
-----------------|--------|-------------------
|
||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-Setup-1.1.4.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a> | Or get the <a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/JoplinPortable.exe'>Portable version</a><br><br>The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-1.1.4.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a> | You can also use Homebrew (unsupported): `brew cask install joplin`
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-1.1.4.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a> | An Arch Linux package (unsupported) [is also available](#terminal-application).<br><br>If it works with your distribution (it has been tested on Ubuntu, Fedora, and Mint; the desktop environments supported are GNOME, KDE, Xfce, MATE, LXQT, LXDE, Unity, Cinnamon, Deepin and Pantheon), the recommended way is to use this script as it will handle the desktop icon too:<br><br> `wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh \| bash`
|
||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-Setup-1.0.241.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a> | Or get the <a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/JoplinPortable.exe'>Portable version</a><br><br>The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-1.0.241.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a> | You can also use Homebrew (unsupported): `brew cask install joplin`
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-1.0.241.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a> | An Arch Linux package (unsupported) [is also available](#terminal-application).<br><br>If it works with your distribution (it has been tested on Ubuntu, Fedora, and Mint; the desktop environments supported are GNOME, KDE, Xfce, MATE, LXQT, LXDE, Unity, Cinnamon, Deepin and Pantheon), the recommended way is to use this script as it will handle the desktop icon too:<br><br> `wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh \| bash`
|
||||
|
||||
## Mobile applications
|
||||
|
||||
Operating System | Download | Alt. Download
|
||||
-----------------|----------|----------------
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.2.6/joplin-v1.2.6.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.2.6/joplin-v1.2.6-32bit.apk)
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.1.1/joplin-v1.1.1.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.1.1/joplin-v1.1.1-32bit.apk)
|
||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://joplinapp.org/images/BadgeIOS.png'/></a> | -
|
||||
|
||||
## Terminal application
|
||||
|
||||
@@ -125,8 +125,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097583
|
||||
versionName "1.2.6"
|
||||
versionCode 2097577
|
||||
versionName "1.1.1"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
||||
@@ -80,19 +80,8 @@
|
||||
<!-- END RN-push-notitication -->
|
||||
<!-- ============================= -->
|
||||
|
||||
<!--
|
||||
2018-12-16: Changed android:launchMode from "singleInstance" to "singleTop" for Firebase notification
|
||||
Previously singleInstance was necessary to prevent multiple instance of the RN app from running at the same time, but maybe no longer needed.
|
||||
|
||||
2020-10-06: Changed back again to "singleInstance" and notifications still seem to work. Changing to singleInstance
|
||||
to try to fix this bug: https://discourse.joplinapp.org/t/joplin-android-app-looses-nextcloud-sync-settings/10997/6
|
||||
Users would lose their settings, and it's possibly due to multiple instances of the app running at the same time, perhaps
|
||||
due to sharing with the app. When checking the log, it would show "saving settings", then the app startup message, and after the app
|
||||
has started, it would show "setting saved". So basically the app, or one instance of it, has started while settings were being saved
|
||||
|
||||
2020-10-08: Changed back again to "singleTop" as it has worked so far. The multiple instance bug was "fixed" in a different way
|
||||
See ReactNativeClient/root.js for more info about the bug.
|
||||
-->
|
||||
<!-- 2018-12-16: Changed android:launchMode from "singleInstance" to "singleTop" for Firebase notification -->
|
||||
<!-- Previously singleInstance was necessary to prevent multiple instance of the RN app from running at the same time, but maybe no longer needed. -->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
|
||||
BIN
ReactNativeClient/images/StartUpIcon.png
Normal file
BIN
ReactNativeClient/images/StartUpIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
BIN
ReactNativeClient/images/StartUpIcon@2x.png
Normal file
BIN
ReactNativeClient/images/StartUpIcon@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
ReactNativeClient/images/StartUpIcon@3x.png
Normal file
BIN
ReactNativeClient/images/StartUpIcon@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -337,7 +337,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 55;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -357,7 +357,7 @@
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
MARKETING_VERSION = 10.2.1;
|
||||
MARKETING_VERSION = 10.1.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -380,7 +380,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 55;
|
||||
CURRENT_PROJECT_VERSION = 53;
|
||||
DEVELOPMENT_TEAM = A9BXAFS6CT;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -393,7 +393,7 @@
|
||||
INFOPLIST_FILE = Joplin/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
MARKETING_VERSION = 10.2.1;
|
||||
MARKETING_VERSION = 10.1.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
||||
@@ -300,10 +300,12 @@ class BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
this.store().dispatch({
|
||||
type: 'SET_HIGHLIGHTED',
|
||||
words: highlightedWords,
|
||||
});
|
||||
if (highlightedWords.length) {
|
||||
this.store().dispatch({
|
||||
type: 'SET_HIGHLIGHTED',
|
||||
words: highlightedWords,
|
||||
});
|
||||
}
|
||||
|
||||
this.store().dispatch({
|
||||
type: 'NOTE_UPDATE_ALL',
|
||||
@@ -467,7 +469,7 @@ class BaseApplication {
|
||||
refreshNotesUseSelectedNoteId = true;
|
||||
}
|
||||
|
||||
if (action.type == 'HISTORY_BACKWARD' || action.type == 'HISTORY_FORWARD' || action.type == 'FOLDER_SELECT' || action.type === 'FOLDER_DELETE' || action.type === 'FOLDER_AND_NOTE_SELECT' || (action.type === 'SEARCH_UPDATE' && newState.notesParentType === 'Folder')) {
|
||||
if (action.type == 'FOLDER_SELECT' || action.type === 'FOLDER_DELETE' || action.type === 'FOLDER_AND_NOTE_SELECT' || (action.type === 'SEARCH_UPDATE' && newState.notesParentType === 'Folder')) {
|
||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||
this.currentFolder_ = newState.selectedFolderId ? await Folder.load(newState.selectedFolderId) : null;
|
||||
refreshNotes = true;
|
||||
@@ -499,11 +501,7 @@ class BaseApplication {
|
||||
refreshNotesUseSelectedNoteId = true;
|
||||
}
|
||||
|
||||
// Should refresh the notes when:
|
||||
// - A tag is selected, to show the notes for that tag
|
||||
// - When a tag is updated so that when searching by tags, the search results are updated
|
||||
// https://github.com/laurent22/joplin/issues/3754
|
||||
if (['TAG_SELECT', 'TAG_DELETE', 'TAG_UPDATE_ONE', 'NOTE_TAG_REMOVE'].includes(action.type)) {
|
||||
if (action.type == 'TAG_SELECT' || action.type === 'TAG_DELETE') {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
@@ -740,23 +738,10 @@ class BaseApplication {
|
||||
setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
// if (Setting.value('db.fuzzySearchEnabled') === -1) {
|
||||
// const fuzzySearchEnabled = await this.database_.fuzzySearchEnabled();
|
||||
// Setting.setValue('db.fuzzySearchEnabled', fuzzySearchEnabled ? 1 : 0);
|
||||
// }
|
||||
|
||||
// // Always disable on CLI because building and packaging the extension is not working
|
||||
// // and is too error-prone - requires gcc on the machine, or we should package the .so
|
||||
// // and dylib files, but it's not sure it would work everywhere if not built from
|
||||
// // source on the target machine.
|
||||
// if (Setting.value('appType') !== 'desktop') {
|
||||
// Setting.setValue('db.fuzzySearchEnabled', 0);
|
||||
// }
|
||||
|
||||
// For now always disable fuzzy search due to performance issues:
|
||||
// https://discourse.joplinapp.org/t/1-1-4-keyboard-locks-up-while-typing/11231/11
|
||||
// https://discourse.joplinapp.org/t/serious-lagging-when-there-are-tens-of-thousands-of-notes/11215/23
|
||||
Setting.setValue('db.fuzzySearchEnabled', 0);
|
||||
if (Setting.value('db.fuzzySearchEnabled') === -1) {
|
||||
const fuzzySearchEnabled = await this.database_.fuzzySearchEnabled();
|
||||
Setting.setValue('db.fuzzySearchEnabled', fuzzySearchEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
if (Setting.value('encryption.shouldReencrypt') < 0) {
|
||||
// We suggest re-encryption if the user has at least one notebook
|
||||
|
||||
@@ -4,7 +4,7 @@ const { reg } = require('lib/registry.js');
|
||||
|
||||
export const declaration:CommandDeclaration = {
|
||||
name: 'synchronize',
|
||||
label: () => _('Synchronise'),
|
||||
label: () => _('Synchronize'),
|
||||
iconName: 'fa-sync-alt',
|
||||
};
|
||||
|
||||
|
||||
@@ -208,10 +208,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
};
|
||||
|
||||
this.useBetaEditor = () => {
|
||||
return Setting.value('editor.beta') && Platform.OS !== 'android';
|
||||
};
|
||||
|
||||
this.takePhoto_onPress = this.takePhoto_onPress.bind(this);
|
||||
this.cameraView_onPhoto = this.cameraView_onPhoto.bind(this);
|
||||
this.cameraView_onCancel = this.cameraView_onCancel.bind(this);
|
||||
@@ -407,9 +403,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
this.saveActionQueue(this.state.note.id).processAllNow();
|
||||
|
||||
// It cannot theoretically be undefined, since componentDidMount should always be called before
|
||||
// componentWillUnmount, but with React Native the impossible often becomes possible.
|
||||
if (this.undoRedoService_) this.undoRedoService_.off('stackChange', this.undoRedoService_stackChange);
|
||||
this.undoRedoService_.off('stackChange', this.undoRedoService_stackChange);
|
||||
}
|
||||
|
||||
title_changeText(text) {
|
||||
@@ -650,7 +644,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const newNote = Object.assign({}, this.state.note);
|
||||
|
||||
if (this.state.mode == 'edit' && !this.useBetaEditor() && !!this.selection) {
|
||||
if (this.state.mode == 'edit' && !Setting.value('editor.beta') && !!this.selection) {
|
||||
const prefix = newNote.body.substring(0, this.selection.start);
|
||||
const suffix = newNote.body.substring(this.selection.end);
|
||||
newNote.body = `${prefix}\n${resourceTag}\n${suffix}`;
|
||||
@@ -972,7 +966,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
let bodyComponent = null;
|
||||
if (this.state.mode == 'view' && !this.useBetaEditor()) {
|
||||
if (this.state.mode == 'view' && !Setting.value('editor.beta')) {
|
||||
const onCheckboxChange = newBody => {
|
||||
this.saveOneProperty('body', newBody);
|
||||
};
|
||||
@@ -1027,7 +1021,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.saveOneProperty('body', newBody);
|
||||
};
|
||||
|
||||
bodyComponent = this.useBetaEditor()
|
||||
bodyComponent = Setting.value('editor.beta')
|
||||
// Note: blurOnSubmit is necessary to get multiline to work.
|
||||
// See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997
|
||||
? <MarkdownEditor
|
||||
@@ -1176,7 +1170,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
/>
|
||||
{titleComp}
|
||||
{bodyComponent}
|
||||
{!this.useBetaEditor() && actionButtonComp}
|
||||
{!Setting.value('editor.beta') && actionButtonComp}
|
||||
|
||||
<SelectDateTimeDialog shown={this.state.alarmDialogShown} date={dueDate} onAccept={this.onAlarmDialogAccept} onReject={this.onAlarmDialogReject} />
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ const { BaseScreenComponent } = require('lib/components/base-screen.js');
|
||||
const { themeStyle } = require('lib/components/global-style.js');
|
||||
const DialogBox = require('react-native-dialogbox').default;
|
||||
const SearchEngineUtils = require('lib/services/searchengine/SearchEngineUtils');
|
||||
const SearchEngine = require('lib/services/searchengine/SearchEngine');
|
||||
|
||||
Icon.loadFont();
|
||||
|
||||
@@ -73,6 +72,18 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
this.isMounted_ = false;
|
||||
}
|
||||
|
||||
// UNSAFE_componentWillReceiveProps(newProps) {
|
||||
// console.info('UNSAFE_componentWillReceiveProps', newProps);
|
||||
|
||||
// let newState = {};
|
||||
// if ('query' in newProps && !this.state.query) newState.query = newProps.query;
|
||||
|
||||
// if (Object.getOwnPropertyNames(newState).length) {
|
||||
// this.setState(newState);
|
||||
// this.refreshSearch(newState.query);
|
||||
// }
|
||||
// }
|
||||
|
||||
searchTextInput_submit() {
|
||||
const query = this.state.query.trim();
|
||||
if (!query) return;
|
||||
@@ -123,14 +134,6 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
|
||||
if (!this.isMounted_) return;
|
||||
|
||||
const parsedQuery = await SearchEngine.instance().parseQuery(query);
|
||||
const highlightedWords = SearchEngine.instance().allParsedQueryTerms(parsedQuery);
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'SET_HIGHLIGHTED',
|
||||
words: highlightedWords,
|
||||
});
|
||||
|
||||
this.setState({ notes: notes });
|
||||
}
|
||||
|
||||
|
||||
@@ -37,15 +37,7 @@ class DatabaseDriverNode {
|
||||
}
|
||||
|
||||
loadExtension(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db_.loadExtension(path, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
return this.db_.loadExtension(path);
|
||||
}
|
||||
|
||||
selectAll(sql, params = null) {
|
||||
|
||||
@@ -9,8 +9,6 @@ class Database {
|
||||
this.logger_ = new Logger();
|
||||
this.logExcludedQueryTypes_ = [];
|
||||
this.batchTransactionMutex_ = new Mutex();
|
||||
this.profilingEnabled_ = false;
|
||||
this.queryId_ = 1;
|
||||
}
|
||||
|
||||
setLogExcludedQueryTypes(v) {
|
||||
@@ -73,30 +71,10 @@ class Database {
|
||||
|
||||
let waitTime = 50;
|
||||
let totalWaitTime = 0;
|
||||
const callStartTime = Date.now();
|
||||
let profilingTimeoutId = null;
|
||||
while (true) {
|
||||
try {
|
||||
this.logQuery(sql, params);
|
||||
|
||||
const queryId = this.queryId_++;
|
||||
if (this.profilingEnabled_) {
|
||||
console.info(`SQL START ${queryId}`, sql, params);
|
||||
|
||||
profilingTimeoutId = setInterval(() => {
|
||||
console.warn(`SQL ${queryId} has been running for ${Date.now() - callStartTime}: ${sql}`);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
const result = await this.driver()[callName](sql, params);
|
||||
|
||||
if (this.profilingEnabled_) {
|
||||
clearInterval(profilingTimeoutId);
|
||||
profilingTimeoutId = null;
|
||||
const elapsed = Date.now() - callStartTime;
|
||||
if (elapsed > 10) console.info(`SQL END ${queryId}`, elapsed, sql, params);
|
||||
}
|
||||
|
||||
return result; // No exception was thrown
|
||||
} catch (error) {
|
||||
if (error && (error.code == 'SQLITE_IOERR' || error.code == 'SQLITE_BUSY')) {
|
||||
@@ -111,8 +89,6 @@ class Database {
|
||||
} else {
|
||||
throw this.sqliteErrorToJsError(error, sql, params);
|
||||
}
|
||||
} finally {
|
||||
if (profilingTimeoutId) clearInterval(profilingTimeoutId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,16 +97,14 @@ class Database {
|
||||
return this.tryCall('selectOne', sql, params);
|
||||
}
|
||||
|
||||
async loadExtension(/* path */) {
|
||||
return; // Disabled for now as fuzzy search extension is not in use
|
||||
|
||||
// let result = null;
|
||||
// try {
|
||||
// result = await this.driver().loadExtension(path);
|
||||
// return result;
|
||||
// } catch (e) {
|
||||
// throw new Error(`Could not load extension ${path}`);
|
||||
// }
|
||||
async loadExtension(path) {
|
||||
let result = null;
|
||||
try {
|
||||
result = await this.driver().loadExtension(path);
|
||||
return result;
|
||||
} catch (e) {
|
||||
throw new Error(`Could not load extension ${path}`);
|
||||
}
|
||||
}
|
||||
|
||||
async selectAll(sql, params = null) {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import useEffectDebugger from './useEffectDebugger';
|
||||
|
||||
export default function usePropsDebugger(effectHook:any, props:any) {
|
||||
const dependencies:any[] = [];
|
||||
const dependencyNames:string[] = [];
|
||||
|
||||
for (const k in props) {
|
||||
dependencies.push(props[k]);
|
||||
dependencyNames.push(k);
|
||||
}
|
||||
|
||||
useEffectDebugger(effectHook, dependencies, dependencyNames);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ const { Database } = require('lib/database.js');
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const Resource = require('lib/models/Resource');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const EventEmitter = require('events');
|
||||
|
||||
const structureSql = `
|
||||
CREATE TABLE folders (
|
||||
@@ -126,6 +127,11 @@ class JoplinDatabase extends Database {
|
||||
this.version_ = null;
|
||||
this.tableFieldNames_ = {};
|
||||
this.extensionToLoad = './build/lib/sql-extensions/spellfix';
|
||||
this.eventEmitter_ = new EventEmitter();
|
||||
}
|
||||
|
||||
eventEmitter() {
|
||||
return this.eventEmitter_;
|
||||
}
|
||||
|
||||
initialized() {
|
||||
@@ -343,8 +349,6 @@ class JoplinDatabase extends Database {
|
||||
+ `Expected version: ${existingDatabaseVersions[existingDatabaseVersions.length - 1]}`);
|
||||
}
|
||||
|
||||
this.logger().info(`Upgrading database from version ${fromVersion}`);
|
||||
|
||||
if (currentVersionIndex == existingDatabaseVersions.length - 1) return fromVersion;
|
||||
|
||||
let latestVersion = fromVersion;
|
||||
@@ -355,6 +359,8 @@ class JoplinDatabase extends Database {
|
||||
|
||||
let queries = [];
|
||||
|
||||
this.eventEmitter_.emit('startMigration', { version: targetVersion });
|
||||
|
||||
if (targetVersion == 1) {
|
||||
queries = this.wrapQueries(this.sqlStringToLines(structureSql));
|
||||
}
|
||||
@@ -850,32 +856,18 @@ class JoplinDatabase extends Database {
|
||||
queries.push('CREATE VIRTUAL TABLE notes_spellfix USING spellfix1');
|
||||
}
|
||||
|
||||
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
|
||||
|
||||
queries.push(updateVersionQuery);
|
||||
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
|
||||
|
||||
try {
|
||||
await this.transactionExecBatch(queries);
|
||||
} catch (error) {
|
||||
// In some cases listed below, when the upgrade fail it is acceptable (a fallback will be used)
|
||||
// and in those cases, even though it fails, we still want to set the version number so that the
|
||||
// migration is not repeated on next upgrade.
|
||||
let saveVersionAgain = false;
|
||||
|
||||
if (targetVersion === 15 || targetVersion === 18 || targetVersion === 33) {
|
||||
this.logger().warn('Could not upgrade to database v15 or v18 or v33 - FTS feature will not be used', error);
|
||||
saveVersionAgain = true;
|
||||
} else if (targetVersion === 34) {
|
||||
this.logger().warn('Could not upgrade to database v34 - fuzzy search will not be used', error);
|
||||
saveVersionAgain = true;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (saveVersionAgain) {
|
||||
this.logger().info('Migration failed with fallback and will not be repeated - saving version number');
|
||||
await this.transactionExecBatch([updateVersionQuery]);
|
||||
}
|
||||
}
|
||||
|
||||
latestVersion = targetVersion;
|
||||
@@ -918,12 +910,9 @@ class JoplinDatabase extends Database {
|
||||
this.logger().info('Checking for database schema update...');
|
||||
|
||||
try {
|
||||
// Note that the only extension that can be loaded as of now is spellfix.
|
||||
// If it fails here, it will fail on the fuzzySearchEnabled() check above
|
||||
// too, thus disabling spellfix for the app.
|
||||
await this.loadExtension(this.extensionToLoad);
|
||||
} catch (error) {
|
||||
this.logger().error(error);
|
||||
console.info(error);
|
||||
}
|
||||
|
||||
let versionRow = null;
|
||||
@@ -934,20 +923,17 @@ class JoplinDatabase extends Database {
|
||||
if (error.message && error.message.indexOf('no such table: version') >= 0) {
|
||||
// Ignore
|
||||
} else {
|
||||
this.logger().info(error);
|
||||
console.info(error);
|
||||
}
|
||||
}
|
||||
|
||||
const version = !versionRow ? 0 : versionRow.version;
|
||||
const tableFieldsVersion = !versionRow ? 0 : versionRow.table_fields_version;
|
||||
this.version_ = version;
|
||||
this.logger().info('Current database version', versionRow);
|
||||
this.logger().info('Current database version', version);
|
||||
|
||||
const newVersion = await this.upgradeDatabase(version);
|
||||
this.version_ = newVersion;
|
||||
|
||||
this.logger().info(`New version: ${newVersion}. Previously recorded version: ${tableFieldsVersion}`);
|
||||
|
||||
if (newVersion !== tableFieldsVersion) await this.refreshTableFields(newVersion);
|
||||
|
||||
this.tableFields_ = {};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
const htmlUtils = require('./htmlUtils');
|
||||
const utils = require('./utils');
|
||||
const noteStyle = require('./noteStyle');
|
||||
const Setting = require('lib/models/Setting');
|
||||
const { themeStyle } = require('lib/theme');
|
||||
const memoryCache = require('memory-cache');
|
||||
const md5 = require('md5');
|
||||
|
||||
@@ -46,10 +44,7 @@ class HtmlToHtml {
|
||||
return []; // TODO
|
||||
}
|
||||
|
||||
// Note: the "theme" variable is ignored and instead the light theme is
|
||||
// always used for HTML notes.
|
||||
// See: https://github.com/laurent22/joplin/issues/3698
|
||||
async render(markup, _theme, options) {
|
||||
async render(markup, theme, options) {
|
||||
options = Object.assign({}, {
|
||||
splitted: false,
|
||||
}, options);
|
||||
@@ -89,8 +84,7 @@ class HtmlToHtml {
|
||||
};
|
||||
}
|
||||
|
||||
const lightTheme = themeStyle(Setting.THEME_LIGHT);
|
||||
let cssStrings = noteStyle(lightTheme);
|
||||
let cssStrings = noteStyle(theme);
|
||||
|
||||
if (options.splitted) {
|
||||
const splitted = this.splitHtml(html);
|
||||
|
||||
@@ -21,7 +21,7 @@ const rules = {
|
||||
|
||||
const setupLinkify = require('./MdToHtml/setupLinkify');
|
||||
const hljs = require('highlight.js');
|
||||
const nodeSlug = require('slug');
|
||||
const uslug = require('uslug');
|
||||
const markdownItAnchor = require('markdown-it-anchor');
|
||||
// The keys must match the corresponding entry in Setting.js
|
||||
const plugins = {
|
||||
@@ -34,13 +34,13 @@ const plugins = {
|
||||
emoji: { module: require('markdown-it-emoji') },
|
||||
insert: { module: require('markdown-it-ins') },
|
||||
multitable: { module: require('markdown-it-multimd-table'), options: { multiline: true, rowspan: true, headerless: true } },
|
||||
toc: { module: require('markdown-it-toc-done-right'), options: { listType: 'ul', slugify: slugify } },
|
||||
toc: { module: require('markdown-it-toc-done-right'), options: { listType: 'ul', slugify: uslugify } },
|
||||
expand_tabs: { module: require('markdown-it-expand-tabs'), options: { tabWidth: 4 } },
|
||||
};
|
||||
const defaultNoteStyle = require('./defaultNoteStyle');
|
||||
|
||||
function slugify(s) {
|
||||
return nodeSlug(s);
|
||||
function uslugify(s) {
|
||||
return uslug(s);
|
||||
}
|
||||
|
||||
class MdToHtml {
|
||||
@@ -295,7 +295,7 @@ class MdToHtml {
|
||||
markdownIt.use(ruleInstall(context, { ...ruleOptions }));
|
||||
}
|
||||
|
||||
markdownIt.use(markdownItAnchor, { slugify: slugify });
|
||||
markdownIt.use(markdownItAnchor, { slugify: uslugify });
|
||||
|
||||
for (const key in plugins) {
|
||||
if (this.pluginEnabled(key)) markdownIt.use(plugins[key].module, plugins[key].options);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -286,7 +286,6 @@ module.exports = function(theme) {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.jop-tinymce ul.joplin-checklist .checked,
|
||||
.md-checkbox .checkbox-label-checked {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"markdown-it-toc-done-right": "^4.1.0",
|
||||
"md5": "^2.2.1",
|
||||
"memory-cache": "^0.2.0",
|
||||
"mermaid": "^8.8.0",
|
||||
"slug": "^3.5.0"
|
||||
"mermaid": "^8.4.6",
|
||||
"uslug": "^1.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,8 +156,6 @@ class BaseItem extends BaseModel {
|
||||
}
|
||||
|
||||
static async loadItemsByIds(ids) {
|
||||
if (!ids.length) return [];
|
||||
|
||||
const classes = this.syncItemClassNames();
|
||||
let output = [];
|
||||
for (let i = 0; i < classes.length; i++) {
|
||||
|
||||
@@ -595,7 +595,7 @@ class Setting extends BaseModel {
|
||||
description: () => 'CSS file support is provided for your convenience, but they are advanced settings, and styles you define may break from one version to the next. If you want to use them, please know that it might require regular development work from you to keep them working. The Joplin team cannot make a commitment to keep the application HTML structure stable.',
|
||||
},
|
||||
|
||||
autoUpdateEnabled: { value: false, type: Setting.TYPE_BOOL, section: 'application', public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') },
|
||||
autoUpdateEnabled: { value: true, type: Setting.TYPE_BOOL, section: 'application', public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') },
|
||||
'autoUpdate.includePreReleases': { value: false, type: Setting.TYPE_BOOL, section: 'application', public: true, appTypes: ['desktop'], label: () => _('Get pre-releases when checking for updates'), description: () => _('See the pre-release page for more details: %s', 'https://joplinapp.org/prereleases') },
|
||||
'clipperServer.autoStart': { value: false, type: Setting.TYPE_BOOL, public: false },
|
||||
'sync.interval': {
|
||||
|
||||
@@ -109,7 +109,6 @@ class Tag extends BaseItem {
|
||||
|
||||
static async tagsByNoteId(noteId) {
|
||||
const tagIds = await NoteTag.tagIdsByNoteId(noteId);
|
||||
if (!tagIds.length) return [];
|
||||
return this.modelSelectAll(`SELECT * FROM tags WHERE id IN ("${tagIds.join('","')}")`);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,7 @@ function isHidden(path) {
|
||||
}
|
||||
|
||||
function safeFileExtension(e, maxLength = null) {
|
||||
// In theory the file extension can have any length but in practice Joplin
|
||||
// expects a fixed length, so we limit it to 20 which should cover most cases.
|
||||
// Note that it means that a file extension longer than 20 will break
|
||||
// external editing (since the extension would be truncated).
|
||||
// https://discourse.joplinapp.org/t/troubles-with-webarchive-files-on-ios/10447
|
||||
if (maxLength === null) maxLength = 20;
|
||||
if (maxLength === null) maxLength = 8;
|
||||
if (!e || !e.replace) return '';
|
||||
return e.replace(/[^a-zA-Z0-9]/g, '').substr(0, maxLength);
|
||||
}
|
||||
@@ -58,7 +53,7 @@ function safeFilename(e, maxLength = null, allowSpaces = false) {
|
||||
return output.substr(0, maxLength);
|
||||
}
|
||||
|
||||
let friendlySafeFilename_blackListChars = '/<>:\'"\\|?*#';
|
||||
let friendlySafeFilename_blackListChars = '/<>:\'"\\|?*';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
friendlySafeFilename_blackListChars += String.fromCharCode(i);
|
||||
}
|
||||
|
||||
@@ -313,9 +313,7 @@ function updateSelectedNotesFromExistingNotes(state) {
|
||||
function defaultNotesParentType(state, exclusion) {
|
||||
let newNotesParentType = null;
|
||||
|
||||
if (exclusion !== 'SmartFilter' && state.selectedSmartFilterId) {
|
||||
newNotesParentType = 'SmartFilter';
|
||||
} else if (exclusion !== 'Folder' && state.selectedFolderId) {
|
||||
if (exclusion !== 'Folder' && state.selectedFolderId) {
|
||||
newNotesParentType = 'Folder';
|
||||
} else if (exclusion !== 'Tag' && state.selectedTagId) {
|
||||
newNotesParentType = 'Tag';
|
||||
@@ -545,7 +543,7 @@ function handleHistory(state, action) {
|
||||
}
|
||||
|
||||
const reducer = (state = defaultState, action) => {
|
||||
// if (!['SIDE_MENU_OPEN_PERCENT'].includes(action.type)) console.info('Action', action.type, action);
|
||||
// if (!['SIDE_MENU_OPEN_PERCENT'].includes(action.type)) console.info('Action', action.type);
|
||||
|
||||
let newState = state;
|
||||
|
||||
|
||||
@@ -360,10 +360,7 @@ class InteropService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.encryption_applied || item.encryption_blob_encrypted) {
|
||||
result.warnings.push(sprintf('This item is currently encrypted: %s "%s" (%s) and was not exported. You may wait for it to be decrypted and try again.', BaseModel.modelTypeToName(itemType), item.title ? item.title : item.id, item.id));
|
||||
continue;
|
||||
}
|
||||
if (item.encryption_applied || item.encryption_blob_encrypted) throw new Error(_('This item is currently encrypted: %s "%s". Please wait for all items to be decrypted and try again.', BaseModel.modelTypeToName(itemType), item.title ? item.title : item.id));
|
||||
|
||||
try {
|
||||
if (itemType == BaseModel.TYPE_RESOURCE) {
|
||||
|
||||
@@ -4,7 +4,6 @@ const BaseModel = require('lib/BaseModel');
|
||||
const Folder = require('lib/models/Folder');
|
||||
const Note = require('lib/models/Note');
|
||||
const { shim } = require('lib/shim');
|
||||
const markdownUtils = require('lib/markdownUtils');
|
||||
|
||||
class InteropService_Exporter_Md extends InteropService_Exporter_Base {
|
||||
async init(destDir) {
|
||||
@@ -54,7 +53,7 @@ class InteropService_Exporter_Md extends InteropService_Exporter_Base {
|
||||
const notePaths = this.context() && this.context().notePaths ? this.context().notePaths : {};
|
||||
|
||||
const createRelativePath = function(notePath) {
|
||||
return markdownUtils.escapeLinkUrl(`${relativePathToRoot}${notePath}`.trim());
|
||||
return encodeURI(`${relativePathToRoot}${notePath}`.trim());
|
||||
};
|
||||
return await this.replaceItemIdsByRelativePaths_(noteBody, linkedNoteIds, notePaths, createRelativePath);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ export default class KeymapService extends BaseService {
|
||||
this.overrideKeymap(JSON.parse(customKeymapFile));
|
||||
} catch (err) {
|
||||
const message = err.message || '';
|
||||
throw new Error(_('Error: %s', message));
|
||||
throw new Error(`${_('Error loading the keymap from file: %s', customKeymapPath)}\n${message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ export default class KeymapService extends BaseService {
|
||||
eventManager.emit('keymapChange');
|
||||
} catch (err) {
|
||||
const message = err.message || '';
|
||||
throw new Error(_('Error: %s', message));
|
||||
throw new Error(`${_('Error saving the keymap to file: %s', customKeymapPath)}\n${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,18 +227,18 @@ export default class KeymapService extends BaseService {
|
||||
|
||||
private validateKeymapItem(item: KeymapItem) {
|
||||
if (!item.hasOwnProperty('command')) {
|
||||
throw new Error(_('"%s" is missing the required "%s" property.', JSON.stringify(item), 'command'));
|
||||
throw new Error(_('Keymap item %s is missing the required "command" property.', JSON.stringify(item)));
|
||||
} else if (!this.keymap.hasOwnProperty(item.command)) {
|
||||
throw new Error(_('Invalid %s: %s.', 'command', item.command));
|
||||
throw new Error(_('Keymap item %s is invalid because %s is not a valid command.', JSON.stringify(item), item.command));
|
||||
}
|
||||
|
||||
if (!item.hasOwnProperty('accelerator')) {
|
||||
throw new Error(_('"%s" is missing the required "%s" property.', JSON.stringify(item), 'accelerator'));
|
||||
throw new Error(_('Keymap item %s is missing the required "accelerator" property.', JSON.stringify(item)));
|
||||
} else if (item.accelerator !== null) {
|
||||
try {
|
||||
this.validateAccelerator(item.accelerator);
|
||||
} catch {
|
||||
throw new Error(_('Invalid %s: %s.', 'accelerator', item.command));
|
||||
throw new Error(_('Keymap item %s is invalid because %s is not a valid accelerator.', JSON.stringify(item), item.accelerator));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
const Folder = require('lib/models/Folder');
|
||||
const Note = require('lib/models/Note');
|
||||
|
||||
function randomIndex(array:any[]):number {
|
||||
return Math.round(Math.random() * (array.length - 1));
|
||||
}
|
||||
|
||||
export default async function populateDatabase(db:any) {
|
||||
await db.clearForTesting();
|
||||
|
||||
const folderCount = 2000;
|
||||
const noteCount = 20000;
|
||||
|
||||
const createdFolderIds:string[] = [];
|
||||
const createdNoteIds:string[] = [];
|
||||
|
||||
for (let i = 0; i < folderCount; i++) {
|
||||
const folder:any = {
|
||||
title: `folder${i}`,
|
||||
};
|
||||
|
||||
const isRoot = Math.random() <= 0.1 || i === 0;
|
||||
|
||||
if (!isRoot) {
|
||||
const parentIndex = randomIndex(createdFolderIds);
|
||||
folder.parent_id = createdFolderIds[parentIndex];
|
||||
}
|
||||
|
||||
const savedFolder = await Folder.save(folder);
|
||||
createdFolderIds.push(savedFolder.id);
|
||||
|
||||
console.info(`Folders: ${i} / ${folderCount}`);
|
||||
}
|
||||
|
||||
let noteBatch = [];
|
||||
for (let i = 0; i < noteCount; i++) {
|
||||
const note:any = { title: `note${i}`, body: `This is note num. ${i}` };
|
||||
const parentIndex = randomIndex(createdFolderIds);
|
||||
note.parent_id = createdFolderIds[parentIndex];
|
||||
|
||||
noteBatch.push(Note.save(note, { dispatchUpdateAction: false }).then((savedNote:any) => {
|
||||
createdNoteIds.push(savedNote.id);
|
||||
console.info(`Notes: ${i} / ${noteCount}`);
|
||||
}));
|
||||
|
||||
if (noteBatch.length > 1000) {
|
||||
await Promise.all(noteBatch);
|
||||
noteBatch = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (noteBatch.length) {
|
||||
await Promise.all(noteBatch);
|
||||
noteBatch = [];
|
||||
}
|
||||
}
|
||||
@@ -460,15 +460,6 @@ class SearchEngine {
|
||||
const fuzzyTitle = await this.fuzzifier(titleTerms.filter(x => !x.wildcard).map(x => trimQuotes(x.value)));
|
||||
const fuzzyBody = await this.fuzzifier(bodyTerms.filter(x => !x.wildcard).map(x => trimQuotes(x.value)));
|
||||
|
||||
// Floor the fuzzy scores to 0, 1 and 2.
|
||||
const floorFuzzyScore = (matches) => {
|
||||
for (let i = 0; i < matches.length; i++) matches[i].score = i;
|
||||
};
|
||||
|
||||
fuzzyText.forEach(floorFuzzyScore);
|
||||
fuzzyTitle.forEach(floorFuzzyScore);
|
||||
fuzzyBody.forEach(floorFuzzyScore);
|
||||
|
||||
const phraseTextSearch = textTerms.filter(x => x.quoted);
|
||||
const wildCardSearch = textTerms.concat(titleTerms).concat(bodyTerms).filter(x => x.wildcard);
|
||||
|
||||
|
||||
24
ReactNativeClient/package-lock.json
generated
24
ReactNativeClient/package-lock.json
generated
@@ -8078,9 +8078,9 @@
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
|
||||
},
|
||||
"patch-package": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.2.tgz",
|
||||
"integrity": "sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.2.1.tgz",
|
||||
"integrity": "sha512-dfCtQor63PPij6DDYtCzBRoO5nNAcMSg7Cmh+DLhR+s3t0OLQBdvFxJksZHBe1J2MjsSWDjTF4+oQKFbdkssIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@yarnpkg/lockfile": "^1.1.0",
|
||||
@@ -9992,11 +9992,6 @@
|
||||
"resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
|
||||
"integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc="
|
||||
},
|
||||
"slug": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/slug/-/slug-3.5.0.tgz",
|
||||
"integrity": "sha512-+pZLDhMtmAc+ZcojQSMlUKDZBYmvhZiZmK8Ffx/D3Q/MIMHPDBAMbWvWN8vJb9xl2MfbDdRWxFzrdOhBiyVpow=="
|
||||
},
|
||||
"slugify": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.6.tgz",
|
||||
@@ -10655,6 +10650,11 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
@@ -10742,6 +10742,14 @@
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"utf8": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz",
|
||||
|
||||
@@ -83,13 +83,13 @@
|
||||
"redux": "4.0.0",
|
||||
"reselect": "^4.0.0",
|
||||
"rn-fetch-blob": "^0.12.0",
|
||||
"slug": "^3.5.0",
|
||||
"stream": "0.0.2",
|
||||
"string-natural-compare": "^2.0.2",
|
||||
"string-padding": "^1.0.2",
|
||||
"timers": "^0.1.1",
|
||||
"url": "^0.11.0",
|
||||
"url-parse": "^1.4.7",
|
||||
"uslug": "^1.0.4",
|
||||
"uuid": "^3.0.1",
|
||||
"valid-url": "^1.0.9",
|
||||
"word-wrap": "^1.2.3",
|
||||
@@ -104,7 +104,7 @@
|
||||
"gulp": "^4.0.2",
|
||||
"jetifier": "^1.6.5",
|
||||
"metro-react-native-babel-preset": "^0.54.1",
|
||||
"patch-package": "^6.2.2",
|
||||
"patch-package": "^6.2.1",
|
||||
"react-test-renderer": "^16.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import setUpQuickActions from './setUpQuickActions';
|
||||
import PluginAssetsLoader from './PluginAssetsLoader';
|
||||
|
||||
const React = require('react');
|
||||
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
|
||||
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar, Text, Image } = require('react-native');
|
||||
const SafeAreaView = require('lib/components/SafeAreaView');
|
||||
const { connect, Provider } = require('react-redux');
|
||||
const { BackButtonService } = require('lib/services/back-button.js');
|
||||
@@ -376,7 +376,7 @@ function decryptionWorker_resourceMetadataButNotBlobDecrypted() {
|
||||
ResourceFetcher.instance().scheduleAutoAddResources();
|
||||
}
|
||||
|
||||
async function initialize(dispatch) {
|
||||
async function initialize(dispatch, messageHandler) {
|
||||
shimInit();
|
||||
|
||||
Setting.setConstant('env', __DEV__ ? 'dev' : 'prod');
|
||||
@@ -415,8 +415,13 @@ async function initialize(dispatch) {
|
||||
dbLogger.setLevel(Logger.LEVEL_INFO);
|
||||
}
|
||||
|
||||
const db_startUpgrade = (event) => {
|
||||
messageHandler(`Upgrading database to v${event.version}...`);
|
||||
};
|
||||
|
||||
const db = new JoplinDatabase(new DatabaseDriverReactNative());
|
||||
db.setLogger(dbLogger);
|
||||
db.eventEmitter().on('startMigration', db_startUpgrade);
|
||||
reg.setDb(db);
|
||||
|
||||
reg.dispatch = dispatch;
|
||||
@@ -453,9 +458,13 @@ async function initialize(dispatch) {
|
||||
// await db.clearForTesting();
|
||||
}
|
||||
|
||||
db.eventEmitter().removeListener('startMigration', db_startUpgrade);
|
||||
|
||||
reg.logger().info('Database is ready.');
|
||||
reg.logger().info('Loading settings...');
|
||||
|
||||
messageHandler('Initialising application...');
|
||||
|
||||
await loadKeychainServiceAndSettings(KeychainServiceDriverMobile);
|
||||
|
||||
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
|
||||
@@ -602,6 +611,7 @@ class AppComponent extends React.Component {
|
||||
|
||||
this.state = {
|
||||
sideMenuContentOpacity: new Animated.Value(0),
|
||||
initMessage: '',
|
||||
};
|
||||
|
||||
this.lastSyncStarted_ = defaultState.syncStarted;
|
||||
@@ -615,66 +625,52 @@ class AppComponent extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
// 2020-10-08: It seems the initialisation code is quite fragile in general and should be kept simple.
|
||||
// For example, adding a loading screen as was done in this commit: https://github.com/laurent22/joplin/commit/569355a3182bc12e50a54249882e3d68a72c2b28.
|
||||
// had for effect that sharing with the app would create multiple instances of the app, thus breaking
|
||||
// database access and so on. It's unclear why it happens and how to fix it but reverting that commit
|
||||
// fixed the issue for now.
|
||||
//
|
||||
// Changing app launch mode doesn't help.
|
||||
//
|
||||
// It's possible that it's a bug in React Native, or perhaps the framework expects that the whole app can be
|
||||
// mounted/unmounted or multiple ones can be running at the same time, but the app was not designed in this
|
||||
// way.
|
||||
//
|
||||
// More reports and info about the multiple instance bug:
|
||||
//
|
||||
// https://github.com/laurent22/joplin/issues/3800
|
||||
// https://github.com/laurent22/joplin/issues/3804
|
||||
// https://github.com/laurent22/joplin/issues/3807
|
||||
// https://discourse.joplinapp.org/t/webdav-config-encryption-config-randomly-lost-on-android/11364
|
||||
// https://discourse.joplinapp.org/t/android-keeps-on-resetting-my-sync-and-theme/11443
|
||||
async componentDidMount() {
|
||||
if (this.props.appState == 'starting') {
|
||||
componentDidMount() {
|
||||
setTimeout(async () => {
|
||||
// We run initialization code with a small delay to give time
|
||||
// to the view to render "please wait" messages.
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'APP_STATE_SET',
|
||||
state: 'initializing',
|
||||
});
|
||||
|
||||
await initialize(this.props.dispatch);
|
||||
await initialize(this.props.dispatch, (message) => {
|
||||
this.setState({ initMessage: message });
|
||||
});
|
||||
|
||||
BackButtonService.initialize(this.backButtonHandler_);
|
||||
|
||||
AlarmService.setInAppNotificationHandler(async (alarmId) => {
|
||||
const alarm = await Alarm.load(alarmId);
|
||||
const notification = await Alarm.makeNotification(alarm);
|
||||
this.dropdownAlert_.alertWithType('info', notification.title, notification.body ? notification.body : '');
|
||||
});
|
||||
|
||||
AppState.addEventListener('change', this.onAppStateChange_);
|
||||
|
||||
const sharedData = await ShareExtension.data();
|
||||
if (sharedData) {
|
||||
reg.logger().info('Received shared data');
|
||||
if (this.props.selectedFolderId) {
|
||||
handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
|
||||
} else {
|
||||
reg.logger.info('Cannot handle share - default folder id is not set');
|
||||
}
|
||||
}
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'APP_STATE_SET',
|
||||
state: 'ready',
|
||||
});
|
||||
}
|
||||
|
||||
BackButtonService.initialize(this.backButtonHandler_);
|
||||
|
||||
AlarmService.setInAppNotificationHandler(async (alarmId) => {
|
||||
const alarm = await Alarm.load(alarmId);
|
||||
const notification = await Alarm.makeNotification(alarm);
|
||||
this.dropdownAlert_.alertWithType('info', notification.title, notification.body ? notification.body : '');
|
||||
});
|
||||
|
||||
AppState.addEventListener('change', this.onAppStateChange_);
|
||||
|
||||
const sharedData = await ShareExtension.data();
|
||||
if (sharedData) {
|
||||
reg.logger().info('Received shared data');
|
||||
if (this.props.selectedFolderId) {
|
||||
handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
|
||||
} else {
|
||||
reg.logger.info('Cannot handle share - default folder id is not set');
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
AppState.removeEventListener('change', this.onAppStateChange_);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
async componentDidUpdate(prevProps) {
|
||||
if (this.props.showSideMenu !== prevProps.showSideMenu) {
|
||||
Animated.timing(this.state.sideMenuContentOpacity, {
|
||||
toValue: this.props.showSideMenu ? 0.5 : 0,
|
||||
@@ -719,8 +715,19 @@ class AppComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
renderStartupScreen() {
|
||||
return (
|
||||
<View style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}>
|
||||
<View style={{ alignItems: 'center' }}>
|
||||
<Image style={{ marginBottom: 5 }} source={require('./images/StartUpIcon.png')} />
|
||||
<Text style={{ color: '#444444' }}>{this.state.initMessage}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.appState != 'ready') return null;
|
||||
if (this.props.appState != 'ready') return this.renderStartupScreen();
|
||||
const theme = themeStyle(this.props.themeId);
|
||||
|
||||
let sideMenuContent = null;
|
||||
|
||||
@@ -281,6 +281,29 @@ const operations = [
|
||||
iconWidth: 46,
|
||||
iconHeight: 46,
|
||||
},
|
||||
|
||||
// ============================================================================
|
||||
// Mobile startup icon
|
||||
// ============================================================================
|
||||
|
||||
{
|
||||
source: 7,
|
||||
dest: 'ReactNativeClient/images/StartUpIcon.png',
|
||||
width: 64,
|
||||
height: 64,
|
||||
},
|
||||
{
|
||||
source: 7,
|
||||
dest: 'ReactNativeClient/images/StartUpIcon@2x.png',
|
||||
width: 128,
|
||||
height: 128,
|
||||
},
|
||||
{
|
||||
source: 7,
|
||||
dest: 'ReactNativeClient/images/StartUpIcon@3x.png',
|
||||
width: 192,
|
||||
height: 192,
|
||||
},
|
||||
];
|
||||
|
||||
async function main() {
|
||||
|
||||
@@ -34,11 +34,6 @@ async function gitLog(sinceTag) {
|
||||
return output;
|
||||
}
|
||||
|
||||
async function gitTags() {
|
||||
const lines = await execCommand('git tag --sort=committerdate');
|
||||
return lines.split('\n').map(l => l.trim());
|
||||
}
|
||||
|
||||
function platformFromTag(tagName) {
|
||||
if (tagName.indexOf('v') === 0) return 'desktop';
|
||||
if (tagName.indexOf('android') >= 0) return 'android';
|
||||
@@ -48,15 +43,6 @@ function platformFromTag(tagName) {
|
||||
throw new Error(`Could not determine platform from tag: ${tagName}`);
|
||||
}
|
||||
|
||||
// function tagPrefixFromPlatform(platform) {
|
||||
// if (platform === 'desktop') return '';
|
||||
// if (platform === 'android') return 'android-';
|
||||
// if (platform === 'ios') return 'ios-';
|
||||
// if (platform === 'clipper') return 'clipper-';
|
||||
// if (platform === 'cli') return 'cli-';
|
||||
// throw new Error(`Could not determine tag prefix from platform: ${platform}`);
|
||||
// }
|
||||
|
||||
function filterLogs(logs, platform) {
|
||||
const output = [];
|
||||
const revertedLogs = [];
|
||||
@@ -211,6 +197,8 @@ function formatCommitMessage(msg, author, options) {
|
||||
|
||||
const commitMessage = parseCommitMessage(output, subModule);
|
||||
|
||||
console.info(commitMessage);
|
||||
|
||||
const messagePieces = [];
|
||||
messagePieces.push(`${capitalizeFirstLetter(commitMessage.type)}`);
|
||||
if (commitMessage.subModule) messagePieces.push(`${capitalizeFirstLetter(commitMessage.subModule)}`);
|
||||
@@ -261,42 +249,25 @@ function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
// function decreaseTagVersion(tag) {
|
||||
// const s = tag.split('.');
|
||||
|
||||
// let updated = false;
|
||||
|
||||
// for (let tokenIndex = s.length - 1; tokenIndex >= 0; tokenIndex--) {
|
||||
// const token = s[tokenIndex];
|
||||
// const s2 = token.split('-');
|
||||
// let num = Number(s2[0]);
|
||||
// num--;
|
||||
// if (num >= 0) {
|
||||
// updated = true;
|
||||
// s[tokenIndex] = num;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!updated) throw new Error(`Cannot decrease tag version: ${tag}`);
|
||||
|
||||
// return s.join('.');
|
||||
// }
|
||||
function decreaseTagVersion(tag) {
|
||||
const s = tag.split('.');
|
||||
const lastToken = s.pop();
|
||||
const s2 = lastToken.split('-');
|
||||
let num = Number(s2[0]);
|
||||
num--;
|
||||
if (num < 0) throw new Error(`Cannot decrease tag version: ${tag}`);
|
||||
s.push(`${num}`);
|
||||
return s.join('.');
|
||||
}
|
||||
|
||||
// This function finds the first relevant tag starting from the given tag.
|
||||
// The first "relevant tag" is the one that exists, and from which there are changes.
|
||||
async function findFirstRelevantTag(baseTag, platform, allTags) {
|
||||
let baseTagIndex = allTags.indexOf(baseTag);
|
||||
if (baseTagIndex < 0) baseTagIndex = allTags.length;
|
||||
|
||||
for (let i = baseTagIndex - 1; i >= 0; i--) {
|
||||
const tag = allTags[i];
|
||||
if (platformFromTag(tag) !== platform) continue;
|
||||
|
||||
async function findFirstRelevantTag(baseTag) {
|
||||
let tag = decreaseTagVersion(baseTag);
|
||||
while (true) {
|
||||
try {
|
||||
const logs = await gitLog(tag);
|
||||
const filteredLogs = filterLogs(logs, platform);
|
||||
if (filteredLogs.length) return tag;
|
||||
if (logs.length) return tag;
|
||||
} catch (error) {
|
||||
if (error.message.indexOf('unknown revision') >= 0) {
|
||||
// We skip the error - it means this particular tag has never been created
|
||||
@@ -304,22 +275,21 @@ async function findFirstRelevantTag(baseTag, platform, allTags) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Could not find previous tag for: ${baseTag}`);
|
||||
tag = decreaseTagVersion(tag);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const argv = require('yargs').argv;
|
||||
if (!argv._.length) throw new Error('Tag name must be specified. Provide the tag of the new version and git-changelog will walk backward to find the changes to the previous relevant tag.');
|
||||
|
||||
const allTags = await gitTags();
|
||||
const fromTagName = argv._[0];
|
||||
let toTagName = argv._.length >= 2 ? argv._[1] : '';
|
||||
|
||||
const platform = platformFromTag(fromTagName);
|
||||
|
||||
if (!toTagName) toTagName = await findFirstRelevantTag(fromTagName, platform, allTags);
|
||||
if (!toTagName) toTagName = await findFirstRelevantTag(fromTagName);
|
||||
|
||||
const logsSinceTags = await gitLog(toTagName);
|
||||
|
||||
|
||||
@@ -45,11 +45,6 @@ async function main() {
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
|
||||
await fs.remove(`${dest}/sqlite.tar.gz`);
|
||||
await fs.remove(`${dest}/amalgamation.tar.gz`);
|
||||
await fs.remove(`${dest}/sqlite`);
|
||||
await fs.remove(`${dest}/sqlite-autoconf-3330000`);
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
const utils = require('../utils');
|
||||
const rootDir = utils.rootDir();
|
||||
const fs = require('fs-extra');
|
||||
|
||||
module.exports = {
|
||||
src: '',
|
||||
fn: async function() {
|
||||
await fs.remove(`${rootDir}/CliClient/tests-build`);
|
||||
await fs.remove(`${rootDir}/CliClient/build`);
|
||||
},
|
||||
};
|
||||
407
Tools/package-lock.json
generated
407
Tools/package-lock.json
generated
@@ -4,11 +4,6 @@
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/color-name": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
|
||||
@@ -25,30 +20,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"app-module-path": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz",
|
||||
@@ -157,6 +128,11 @@
|
||||
"upper-case": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
@@ -176,43 +152,13 @@
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.1.tgz",
|
||||
"integrity": "sha512-rcvHOWyGyid6I1WjT/3NatKj2kDt9OdSHSXpyLXaMWFbKpGACNW8pRhhdPUq9MWUOdwn8Rz9AVETjF4105rZZQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
|
||||
"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
"string-width": "^2.1.1",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
@@ -274,6 +220,18 @@
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"requires": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
"semver": "^5.5.0",
|
||||
"shebang-command": "^1.2.0",
|
||||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
@@ -282,6 +240,11 @@
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
@@ -319,11 +282,6 @@
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
@@ -345,10 +303,19 @@
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
|
||||
"integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.0.tgz",
|
||||
"integrity": "sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig=="
|
||||
"execa": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
|
||||
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
|
||||
"requires": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"get-stream": "^4.0.0",
|
||||
"is-stream": "^1.1.0",
|
||||
"npm-run-path": "^2.0.0",
|
||||
"p-finally": "^1.0.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"strip-eof": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"expand-template": {
|
||||
"version": "2.0.3",
|
||||
@@ -375,6 +342,14 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
@@ -462,9 +437,17 @@
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
|
||||
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
@@ -561,6 +544,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
|
||||
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
@@ -586,6 +574,11 @@
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
@@ -630,6 +623,14 @@
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
|
||||
"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
|
||||
"requires": {
|
||||
"invert-kv": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz",
|
||||
@@ -638,11 +639,28 @@
|
||||
"uc.micro": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lower-case": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
|
||||
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
|
||||
},
|
||||
"map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
|
||||
"requires": {
|
||||
"p-defer": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz",
|
||||
@@ -665,6 +683,16 @@
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||
},
|
||||
"mem": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz",
|
||||
"integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==",
|
||||
"requires": {
|
||||
"map-age-cleaner": "^0.1.1",
|
||||
"mimic-fn": "^1.0.0",
|
||||
"p-is-promise": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
|
||||
@@ -678,6 +706,11 @@
|
||||
"mime-db": "1.43.0"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
@@ -738,6 +771,11 @@
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
|
||||
},
|
||||
"no-case": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
|
||||
@@ -773,6 +811,14 @@
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
|
||||
"requires": {
|
||||
"path-key": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
@@ -807,6 +853,52 @@
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
|
||||
"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
|
||||
"requires": {
|
||||
"execa": "^1.0.0",
|
||||
"lcid": "^2.0.0",
|
||||
"mem": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
|
||||
},
|
||||
"p-is-promise": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
|
||||
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
|
||||
"integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
|
||||
"integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ=="
|
||||
},
|
||||
"param-case": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
|
||||
@@ -815,6 +907,16 @@
|
||||
"no-case": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
},
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||
},
|
||||
"pct-encode": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pct-encode/-/pct-encode-1.0.2.tgz",
|
||||
@@ -945,6 +1047,11 @@
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
@@ -988,6 +1095,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
|
||||
"requires": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
@@ -1072,6 +1192,11 @@
|
||||
"ansi-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
@@ -1221,6 +1346,19 @@
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
@@ -1235,41 +1373,43 @@
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1280,9 +1420,9 @@
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.1.tgz",
|
||||
"integrity": "sha512-/jJ831jEs4vGDbYPQp4yGKDYPSCCEQ45uZWJHE1AoYBzqdZi8+LDWas0z4HrmJXmKdpFsTiowSHXdxyFhpmdMg=="
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
@@ -1290,53 +1430,32 @@
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.0.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.0.3.tgz",
|
||||
"integrity": "sha512-6+nLw8xa9uK1BOEOykaiYAJVh6/CjxWXK/q9b5FpRgNslt8s22F2xMBqVIKgCRjNgGvGPBy8Vog7WN7yh4amtA==",
|
||||
"version": "12.0.5",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
|
||||
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
|
||||
"requires": {
|
||||
"cliui": "^7.0.0",
|
||||
"escalade": "^3.0.2",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"cliui": "^4.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^1.0.1",
|
||||
"os-locale": "^3.0.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.1",
|
||||
"yargs-parser": "^20.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
"require-main-filename": "^1.0.1",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^2.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^3.2.1 || ^4.0.0",
|
||||
"yargs-parser": "^11.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.0.tgz",
|
||||
"integrity": "sha512-2agPoRFPoIcFzOIp6656gcvsg2ohtscpw2OINr/q46+Sq41xz2OYLqx5HRHabmFU1OARIPAYH5uteICE7mn/5A=="
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
|
||||
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
"sharp": "^0.25.2",
|
||||
"string-padding": "^1.0.2",
|
||||
"uri-template": "^1.0.1",
|
||||
"yargs": "^16.0.3"
|
||||
"yargs": "^12.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,9 +151,7 @@ async function createRelease(name, tagName, version) {
|
||||
async function main() {
|
||||
const argv = require('yargs').argv;
|
||||
|
||||
if (!['release', 'prerelease'].includes(argv.type)) throw new Error('Must specify release type. Either --type=release or --type=prerelease');
|
||||
|
||||
const isPreRelease = argv.type === 'prerelease';
|
||||
const isPreRelease = !!argv.prerelease;
|
||||
|
||||
if (isPreRelease) console.info('Creating pre-release');
|
||||
console.info('Updating version numbers in build.gradle...');
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
const rootDir = path.dirname(__dirname);
|
||||
|
||||
async function updatePackageVersion(packageFilePath, majorMinorVersion) {
|
||||
const contentText = await fs.readFile(packageFilePath, 'utf8');
|
||||
const content = JSON.parse(contentText);
|
||||
|
||||
if (content.version.indexOf(majorMinorVersion) === 0) return;
|
||||
|
||||
content.version = `${majorMinorVersion}.0`;
|
||||
await fs.writeFile(packageFilePath, `${JSON.stringify(content, null, 2)}\n`, 'utf8');
|
||||
}
|
||||
|
||||
async function updateGradleVersion(filePath, majorMinorVersion) {
|
||||
const contentText = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
const newContent = contentText.replace(/(versionName\s+")(\d+?\.\d+?)(\.\d+")/, function(match, prefix, version, suffix) {
|
||||
if (version === majorMinorVersion) return prefix + version + suffix;
|
||||
return `${prefix + majorMinorVersion}.0"`;
|
||||
});
|
||||
|
||||
if (newContent === contentText) return;
|
||||
|
||||
await fs.writeFile(filePath, newContent, 'utf8');
|
||||
}
|
||||
|
||||
async function updateCodeProjVersion(filePath, majorMinorVersion) {
|
||||
const contentText = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
// MARKETING_VERSION = 10.1.0;
|
||||
const newContent = contentText.replace(/(MARKETING_VERSION = )(\d+\.\d+)(\.\d+;)/g, function(match, prefix, version, suffix) {
|
||||
if (version === majorMinorVersion) return prefix + version + suffix;
|
||||
return `${prefix + majorMinorVersion}.0;`;
|
||||
});
|
||||
|
||||
if (newContent === contentText) return;
|
||||
|
||||
await fs.writeFile(filePath, newContent, 'utf8');
|
||||
}
|
||||
|
||||
async function updateClipperManifestVersion(manifestPath, majorMinorVersion) {
|
||||
const manifestText = await fs.readFile(manifestPath, 'utf8');
|
||||
const manifest = JSON.parse(manifestText);
|
||||
const versionText = manifest.version;
|
||||
|
||||
if (versionText.indexOf(majorMinorVersion) === 0) return;
|
||||
|
||||
manifest.version = `${majorMinorVersion}.0`;
|
||||
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 4));
|
||||
}
|
||||
|
||||
// Need this hack to transform 1.x.x into 10.x.x due to some mistake
|
||||
// on one of the release and the App Store won't allow decreasing
|
||||
// the major version number.
|
||||
function iosVersionHack(majorMinorVersion) {
|
||||
const p = majorMinorVersion.split('.');
|
||||
p[0] = `${p[0]}0`;
|
||||
return p.join('.');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const argv = require('yargs').parserConfiguration({
|
||||
'parse-numbers': false,
|
||||
}).argv;
|
||||
|
||||
if (!argv._ || !argv._.length) throw new Error('Please specify the major.minor version, eg. 1.2');
|
||||
|
||||
const majorMinorVersion = argv._[0];
|
||||
|
||||
await updatePackageVersion(`${rootDir}/ElectronClient/package.json`, majorMinorVersion);
|
||||
await updatePackageVersion(`${rootDir}/CliClient/package.json`, majorMinorVersion);
|
||||
await updateGradleVersion(`${rootDir}/ReactNativeClient/android/app/build.gradle`, majorMinorVersion);
|
||||
await updateCodeProjVersion(`${rootDir}/ReactNativeClient/ios/Joplin.xcodeproj/project.pbxproj`, iosVersionHack(majorMinorVersion));
|
||||
await updateClipperManifestVersion(`${rootDir}/Clipper/manifest.json`, majorMinorVersion);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Fatal error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/api.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/changelog.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
@@ -351,64 +351,6 @@ https://github.com/laurent22/joplin/blob/master/readme/changelog.md
|
||||
</ul>
|
||||
</div>
|
||||
<h1>Joplin changelog<a name="joplin-changelog" href="#joplin-changelog" class="heading-anchor">🔗</a></h1>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.1.4">v1.1.4</a> - 2020-09-21T11:20:09Z<a name="v1-1-4-https-github-com-laurent22-joplin-releases-tag-v1-1-4-2020-09-21t11-20-09z" href="#v1-1-4-https-github-com-laurent22-joplin-releases-tag-v1-1-4-2020-09-21t11-20-09z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add keyboard shortcut editor (<a href="https://github.com/laurent22/joplin/issues/3525">#3525</a> by Anjula Karunarathne)</li>
|
||||
<li>New: Add log statement to try to fix issue <a href="https://github.com/laurent22/joplin/issues/3536">#3536</a></li>
|
||||
<li>Improved: Change codemirror default home and end to be visual line based (<a href="https://github.com/laurent22/joplin/issues/3672">#3672</a> by Caleb John)</li>
|
||||
<li>Improved: Clarifies labels of certain actions, and added shortcut for note list toggle</li>
|
||||
<li>Improved: Do not prevent export when one item is still encrypted</li>
|
||||
<li>Improved: Fuzzy search (<a href="https://github.com/laurent22/joplin/issues/3632">#3632</a> by Naveen M V)</li>
|
||||
<li>Improved: Make codemirror the default code editor (<a href="https://github.com/laurent22/joplin/issues/3703">#3703</a>) (<a href="https://github.com/laurent22/joplin/issues/3560">#3560</a> by Caleb John)</li>
|
||||
<li>Improved: Rename menu item from "Export" to "Export all" to clarify what it does</li>
|
||||
<li>Improved: Sync immediately on startup</li>
|
||||
<li>Security: Disallow EMBED tags to prevent XSS vulnerability (CVE-2020-15930, vulnerability found by Ademar Nowasky Junior)</li>
|
||||
<li>Security: Upgrade packages to fix vulnerabilities</li>
|
||||
<li>Fixed: Creating a note after backward redirection places it in a wrong notebook (<a href="https://github.com/laurent22/joplin/issues/3759">#3759</a> by Naveen M V)</li>
|
||||
<li>Fixed: Fix applying tags to multiple notes (<a href="https://github.com/laurent22/joplin/issues/3710">#3710</a>)</li>
|
||||
<li>Fixed: Fix bug with quotes when searching (<a href="https://github.com/laurent22/joplin/issues/3735">#3735</a> by Naveen M V)</li>
|
||||
<li>Fixed: Fix wildcard search (<a href="https://github.com/laurent22/joplin/issues/3713">#3713</a> by Naveen M V)</li>
|
||||
<li>Fixed: Fixed clock sync logic when creating new sync target</li>
|
||||
<li>Fixed: Fixed copying link in Rich Text editor (<a href="https://github.com/laurent22/joplin/issues/3697">#3697</a>)</li>
|
||||
<li>Fixed: Fixed note export when there are folders with non-existing parents. Also fixed long path issue on Windows. (<a href="https://github.com/laurent22/joplin/issues/3689">#3689</a>)</li>
|
||||
<li>Fixed: Fixed viewer font size, in particular for inline code (<a href="https://github.com/laurent22/joplin/issues/3553">#3553</a>)</li>
|
||||
<li>Fixed: Increased file extension limit to 20 to prevent issue when using external editors (<a href="https://github.com/laurent22/joplin/issues/3696">#3696</a>)</li>
|
||||
<li>Fixed: Use joplin list handling in emacs mode (<a href="https://github.com/laurent22/joplin/issues/3758">#3758</a>) (<a href="https://github.com/laurent22/joplin/issues/3749">#3749</a> by Caleb John)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.1.3">v1.1.3</a> - 2020-09-17T10:30:37Z<a name="v1-1-3-https-github-com-laurent22-joplin-releases-tag-v1-1-3-2020-09-17t10-30-37z" href="#v1-1-3-https-github-com-laurent22-joplin-releases-tag-v1-1-3-2020-09-17t10-30-37z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Improved: Do not prevent export when one item is still encrypted</li>
|
||||
<li>Fixed: Creating a note after backward redirection places it in a wrong notebook (<a href="https://github.com/laurent22/joplin/issues/3759">#3759</a> by Naveen M V)</li>
|
||||
<li>Fixed: Increased file extension limit to 20 to prevent issue when using external editors (<a href="https://github.com/laurent22/joplin/issues/3696">#3696</a>)</li>
|
||||
<li>Fixed: Use joplin list handling in emacs mode (<a href="https://github.com/laurent22/joplin/issues/3758">#3758</a>) (<a href="https://github.com/laurent22/joplin/issues/3749">#3749</a> by Caleb John)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.1.2">v1.1.2</a> - 2020-09-15T12:58:38Z<a name="v1-1-2-https-github-com-laurent22-joplin-releases-tag-v1-1-2-2020-09-15t12-58-38z" href="#v1-1-2-https-github-com-laurent22-joplin-releases-tag-v1-1-2-2020-09-15t12-58-38z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Improved: Clarifies labels of certain actions, and added shortcut for note list toggle</li>
|
||||
<li>Security: Upgrade packages to fix vulnerabilities</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.1.1">v1.1.1</a> - 2020-09-11T23:32:47Z<a name="v1-1-1-https-github-com-laurent22-joplin-releases-tag-v1-1-1-2020-09-11t23-32-47z" href="#v1-1-1-https-github-com-laurent22-joplin-releases-tag-v1-1-1-2020-09-11t23-32-47z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add keyboard shortcut editor (<a href="https://github.com/laurent22/joplin/issues/3525">#3525</a> by Anjula Karunarathne)</li>
|
||||
<li>Improved: Change CodeMirror default home and end to be visual line based (<a href="https://github.com/laurent22/joplin/issues/3672">#3672</a> by Caleb John)</li>
|
||||
<li>Improved: Added support for fuzzy search (<a href="https://github.com/laurent22/joplin/issues/3632">#3632</a> by Naveen M V)</li>
|
||||
<li>Improved: Make CodeMirror the default code editor (<a href="https://github.com/laurent22/joplin/issues/3703">#3703</a>) (<a href="https://github.com/laurent22/joplin/issues/3560">#3560</a> by Caleb John)</li>
|
||||
<li>Improved: Rename menu item from "Export" to "Export all" to clarify what it does</li>
|
||||
<li>Improved: Sync immediately on startup</li>
|
||||
<li>Security: Disallow EMBED tags to prevent XSS vulnerability (CVE-2020-15930, vulnerability found by Ademar Nowasky Junior)</li>
|
||||
<li>Fixed: Fix applying tags to multiple notes (<a href="https://github.com/laurent22/joplin/issues/3710">#3710</a>)</li>
|
||||
<li>Fixed: Fix bug with quotes when searching (<a href="https://github.com/laurent22/joplin/issues/3735">#3735</a> by Naveen M V)</li>
|
||||
<li>Fixed: Fix wildcard search (<a href="https://github.com/laurent22/joplin/issues/3713">#3713</a> by Naveen M V)</li>
|
||||
<li>Fixed: Fixed copying link in Rich Text editor (<a href="https://github.com/laurent22/joplin/issues/3697">#3697</a>)</li>
|
||||
<li>Fixed: Fixed note export when there are folders with non-existing parents. Also fixed long path issue on Windows. (<a href="https://github.com/laurent22/joplin/issues/3689">#3689</a>)</li>
|
||||
<li>Fixed: Fixed viewer font size, in particular for inline code (<a href="https://github.com/laurent22/joplin/issues/3553">#3553</a>)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.245">v1.0.245</a> - 2020-09-09T12:56:10Z<a name="v1-0-245-https-github-com-laurent22-joplin-releases-tag-v1-0-245-2020-09-09t12-56-10z" href="#v1-0-245-https-github-com-laurent22-joplin-releases-tag-v1-0-245-2020-09-09t12-56-10z" class="heading-anchor">🔗</a></h2>
|
||||
<p>This release is to fix the sync lock issues on devices that have an incorrect clock. Specifically, it should fix this error: "Cannot acquire sync lock: either the lock could be written but not read back. Or it was expired before it was read again".</p>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.242">v1.0.242</a> - 2020-09-04T22:00:34Z<a name="v1-0-242-https-github-com-laurent22-joplin-releases-tag-v1-0-242-2020-09-04t22-00-34z" href="#v1-0-242-https-github-com-laurent22-joplin-releases-tag-v1-0-242-2020-09-04t22-00-34z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Fixes sync target upgrade issue when custom TLS settings are used</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.241">v1.0.241</a> - 2020-09-04T18:06:00Z<a name="v1-0-241-https-github-com-laurent22-joplin-releases-tag-v1-0-241-2020-09-04t18-06-00z" href="#v1-0-241-https-github-com-laurent22-joplin-releases-tag-v1-0-241-2020-09-04t18-06-00z" class="heading-anchor">🔗</a></h2>
|
||||
<p>This release will ask you to upgrade your sync target and, once it is done, only the latest clients will be able to sync with this sync target. So please make sure you upgrade your other clients too (mobile, cli, etc.).</p>
|
||||
<p>This version also includes an update to the search engine and as a result starting the app the first might be SLOW, as the search engine indexes all your notes. It might take from a few seconds to several minutes depending on how large your note collection is. This is a one off operation.</p>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/changelog_cli.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
@@ -351,17 +351,6 @@ https://github.com/laurent22/joplin/blob/master/readme/changelog_cli.md
|
||||
</ul>
|
||||
</div>
|
||||
<h1>Joplin terminal app changelog<a name="joplin-terminal-app-changelog" href="#joplin-terminal-app-changelog" class="heading-anchor">🔗</a></h1>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/cli-v1.1.8">cli-v1.1.8</a> - 2020-09-21T12:02:29Z<a name="cli-v1-1-8-https-github-com-laurent22-joplin-releases-tag-cli-v1-1-8-2020-09-21t12-02-29z" href="#cli-v1-1-8-https-github-com-laurent22-joplin-releases-tag-cli-v1-1-8-2020-09-21t12-02-29z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Improved: Do not prevent export when one item is still encrypted</li>
|
||||
<li>Improved: Fix keytar library being loaded up in FreeBSD. (#3712) (#3711 by Jose Esteve)</li>
|
||||
<li>Fixed: Fixed note export when there are folders with non-existing parents. Also fixed long path issue on Windows. (#3689)</li>
|
||||
<li>Fixed: Increased file extension limit to 20 to prevent issue when using external editors (#3696)</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/cli-v1.0.168">cli-v1.0.168</a> - 2020-09-14T08:47:08Z<a name="cli-v1-0-168-https-github-com-laurent22-joplin-releases-tag-cli-v1-0-168-2020-09-14t08-47-08z" href="#cli-v1-0-168-https-github-com-laurent22-joplin-releases-tag-cli-v1-0-168-2020-09-14t08-47-08z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>Improved: Implemented reliable way to sync device and server clocks</li>
|
||||
</ul>
|
||||
<h2><a href="https://github.com/laurent22/joplin/releases/tag/cli-v1.0.167">cli-v1.0.167</a> - 2020-09-04T17:15:49Z<a name="cli-v1-0-167-https-github-com-laurent22-joplin-releases-tag-cli-v1-0-167-2020-09-04t17-15-49z" href="#cli-v1-0-167-https-github-com-laurent22-joplin-releases-tag-cli-v1-0-167-2020-09-04t17-15-49z" class="heading-anchor">🔗</a></h2>
|
||||
<ul>
|
||||
<li>New: Add mechanism to lock and upgrade sync targets (#3524)</li>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/clipper.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/conflict.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/debugging.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/desktop.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/donate.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
@@ -367,6 +367,7 @@ https://github.com/laurent22/joplin/blob/master/readme/donate.md
|
||||
<li>Consider rating the app on <a href="https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1">Google Play</a> or <a href="https://itunes.apple.com/us/app/joplin/id1315599797">App Store</a>.</li>
|
||||
<li><a href="https://joplinapp.org/#localisation">Create or update a translation</a>.</li>
|
||||
<li>Vote for or review the app on <a href="https://alternativeto.net/software/joplin/">alternativeTo</a> or <a href="https://www.producthunt.com/posts/joplin">Product Hunt</a>.</li>
|
||||
<li>Help improve <a href="https://en.wikipedia.org/wiki/Draft:Joplin_(software)">the Wikipedia article</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="bottom-links">
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/e2ee.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/faq.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/gsoc2020/ideas.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/gsoc2020/index.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/gsod2020/ideas.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/gsod2020/index.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/README.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
@@ -371,17 +371,17 @@ https://github.com/laurent22/joplin/blob/master/README.md
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Windows (32 and 64-bit)</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-Setup-1.1.4.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
||||
<td>Or get the <a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/JoplinPortable.exe'>Portable version</a><br><br>The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-Setup-1.0.241.exe'><img alt='Get it on Windows' width="134px" src='https://joplinapp.org/images/BadgeWindows.png'/></a></td>
|
||||
<td>Or get the <a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/JoplinPortable.exe'>Portable version</a><br><br>The <a href="https://en.wikipedia.org/wiki/Portable_application">portable application</a> allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>macOS</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-1.1.4.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-1.0.241.dmg'><img alt='Get it on macOS' width="134px" src='https://joplinapp.org/images/BadgeMacOS.png'/></a></td>
|
||||
<td>You can also use Homebrew (unsupported): <code>brew cask install joplin</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.1.4/Joplin-1.1.4.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.0.241/Joplin-1.0.241.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||
<td>An Arch Linux package (unsupported) <a href="#terminal-application">is also available</a>.<br><br>If it works with your distribution (it has been tested on Ubuntu, Fedora, and Mint; the desktop environments supported are GNOME, KDE, Xfce, MATE, LXQT, LXDE, Unity, Cinnamon, Deepin and Pantheon), the recommended way is to use this script as it will handle the desktop icon too:<br><br> <code>wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh | bash</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -399,7 +399,7 @@ https://github.com/laurent22/joplin/blob/master/README.md
|
||||
<tr>
|
||||
<td>Android</td>
|
||||
<td><a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a></td>
|
||||
<td>or download the APK file: <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.1.1/joplin-v1.1.1.apk">64-bit</a> <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.1.1/joplin-v1.1.1-32bit.apk">32-bit</a></td>
|
||||
<td>or download the APK file: <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.0.340/joplin-v1.0.340.apk">64-bit</a> <a href="https://github.com/laurent22/joplin-android/releases/download/android-v1.0.340/joplin-v1.0.340-32bit.apk">32-bit</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>iOS</td>
|
||||
@@ -469,11 +469,6 @@ https://github.com/laurent22/joplin/blob/master/README.md
|
||||
<td style="text-align:center"><img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br><a href="https://github.com/fbloise">Frank Bloise</a></td>
|
||||
<td style="text-align:center"><img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br><a href="https://github.com/thomasbroussard">Thomas Broussard</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:center"><img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br><a href="https://github.com/dbrandonjohnson">Brandon Johnson</a></td>
|
||||
<td style="text-align:center"></td>
|
||||
<td style="text-align:center"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h1>Features<a name="features" href="#features" class="heading-anchor">🔗</a></h1>
|
||||
@@ -829,35 +824,35 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Arabic</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ar.po">ar</a></td>
|
||||
<td>أحمد باشا إبراهيم (<a href="mailto:fi_ahmed_bacha@esi.dz">fi_ahmed_bacha@esi.dz</a>)</td>
|
||||
<td>80%</td>
|
||||
<td>82%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/basque_country.png" alt=""></td>
|
||||
<td>Basque</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/eu.po">eu</a></td>
|
||||
<td>juan.abasolo@ehu.eus</td>
|
||||
<td>34%</td>
|
||||
<td>35%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ba.png" alt=""></td>
|
||||
<td>Bosnian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/bs_BA.po">bs_BA</a></td>
|
||||
<td>Derviš T. (<a href="mailto:dervis.t@pm.me">dervis.t@pm.me</a>)</td>
|
||||
<td>83%</td>
|
||||
<td>85%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/bg.png" alt=""></td>
|
||||
<td>Bulgarian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/bg_BG.po">bg_BG</a></td>
|
||||
<td></td>
|
||||
<td>66%</td>
|
||||
<td>68%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/catalonia.png" alt=""></td>
|
||||
<td>Catalan</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ca.po">ca</a></td>
|
||||
<td>jmontane, 2019</td>
|
||||
<td>53%</td>
|
||||
<td>54%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/hr.png" alt=""></td>
|
||||
@@ -871,28 +866,28 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Czech</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/cs_CZ.po">cs_CZ</a></td>
|
||||
<td>Lukas Helebrandt (<a href="mailto:lukas@aiya.cz">lukas@aiya.cz</a>)</td>
|
||||
<td>82%</td>
|
||||
<td>84%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/dk.png" alt=""></td>
|
||||
<td>Dansk</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/da_DK.po">da_DK</a></td>
|
||||
<td>Morten Juhl-Johansen Zölde-Fejér (mjjzf@syntaktisk.</td>
|
||||
<td>74%</td>
|
||||
<td>76%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/de.png" alt=""></td>
|
||||
<td>Deutsch</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/de_DE.po">de_DE</a></td>
|
||||
<td>Eike (<a href="mailto:ei-ke@users.noreply.github.com">ei-ke@users.noreply.github.com</a>)</td>
|
||||
<td>95%</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ee.png" alt=""></td>
|
||||
<td>Eesti Keel</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/et_EE.po">et_EE</a></td>
|
||||
<td></td>
|
||||
<td>66%</td>
|
||||
<td>68%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/gb.png" alt=""></td>
|
||||
@@ -913,182 +908,182 @@ Eg. <code>:search -- "-tag:tag1"</code>.</p>
|
||||
<td>Español</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/es_ES.po">es_ES</a></td>
|
||||
<td>Fernando Pindado (<a href="mailto:fpindado@gmail.com">fpindado@gmail.com</a>)</td>
|
||||
<td>95%</td>
|
||||
<td>91%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/esperanto.png" alt=""></td>
|
||||
<td>Esperanto</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/eo.po">eo</a></td>
|
||||
<td>Marton Paulo</td>
|
||||
<td>38%</td>
|
||||
<td>39%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/fr.png" alt=""></td>
|
||||
<td>Français</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/fr_FR.po">fr_FR</a></td>
|
||||
<td>Laurent Cozic</td>
|
||||
<td>94%</td>
|
||||
<td>97%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/es/galicia.png" alt=""></td>
|
||||
<td>Galician</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/gl_ES.po">gl_ES</a></td>
|
||||
<td>Marcos Lans (<a href="mailto:marcoslansgarza@gmail.com">marcoslansgarza@gmail.com</a>)</td>
|
||||
<td>43%</td>
|
||||
<td>44%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/id.png" alt=""></td>
|
||||
<td>Indonesian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/id_ID.po">id_ID</a></td>
|
||||
<td>Fathy AR (<a href="mailto:16875937+fathyar@users.noreply.github.com">16875937+fathyar@users.noreply.github.com</a>)</td>
|
||||
<td>93%</td>
|
||||
<td>95%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/it.png" alt=""></td>
|
||||
<td>Italiano</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/it_IT.po">it_IT</a></td>
|
||||
<td>StarFang208</td>
|
||||
<td>91%</td>
|
||||
<td>93%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/nl.png" alt=""></td>
|
||||
<td>Nederlands</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/nl_NL.po">nl_NL</a></td>
|
||||
<td>MetBril (<a href="mailto:metbril@users.noreply.github.com">metbril@users.noreply.github.com</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/be.png" alt=""></td>
|
||||
<td>Nederlands</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/nl_BE.po">nl_BE</a></td>
|
||||
<td></td>
|
||||
<td>34%</td>
|
||||
<td>35%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/no.png" alt=""></td>
|
||||
<td>Norwegian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/nb_NO.po">nb_NO</a></td>
|
||||
<td>Mats Estensen (<a href="mailto:code@mxe.no">code@mxe.no</a>)</td>
|
||||
<td>88%</td>
|
||||
<td>91%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ir.png" alt=""></td>
|
||||
<td>Persian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/fa.po">fa</a></td>
|
||||
<td>Kourosh Firoozbakht (<a href="mailto:kourox@protonmail.com">kourox@protonmail.com</a>)</td>
|
||||
<td>80%</td>
|
||||
<td>Mehrad Mahmoudian (<a href="mailto:mehrad@mahmoudian.me">mehrad@mahmoudian.me</a>)</td>
|
||||
<td>34%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/pl.png" alt=""></td>
|
||||
<td>Polski</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/pl_PL.po">pl_PL</a></td>
|
||||
<td></td>
|
||||
<td>96%</td>
|
||||
<td>87%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/pt.png" alt=""></td>
|
||||
<td>Português</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/pt_PT.po">pt_PT</a></td>
|
||||
<td>Diogo Caveiro</td>
|
||||
<td>89%</td>
|
||||
<td>91%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/br.png" alt=""></td>
|
||||
<td>Português (Brasil)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/pt_BR.po">pt_BR</a></td>
|
||||
<td>Renato Nunes Bastos (<a href="mailto:rnbastos@gmail.com">rnbastos@gmail.com</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>98%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ro.png" alt=""></td>
|
||||
<td>Română</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ro.po">ro</a></td>
|
||||
<td>Cristi Duluta (<a href="mailto:cristi.duluta@gmail.com">cristi.duluta@gmail.com</a>)</td>
|
||||
<td>78%</td>
|
||||
<td></td>
|
||||
<td>35%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/si.png" alt=""></td>
|
||||
<td>Slovenian</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/sl_SI.po">sl_SI</a></td>
|
||||
<td></td>
|
||||
<td>42%</td>
|
||||
<td>44%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/se.png" alt=""></td>
|
||||
<td>Svenska</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/sv.po">sv</a></td>
|
||||
<td>Jonatan Nyberg (<a href="mailto:jonatan@autistici.org">jonatan@autistici.org</a>)</td>
|
||||
<td>71%</td>
|
||||
<td>73%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/th.png" alt=""></td>
|
||||
<td>Thai</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/th_TH.po">th_TH</a></td>
|
||||
<td></td>
|
||||
<td>52%</td>
|
||||
<td>54%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/.png" alt=""></td>
|
||||
<td>Tiếng Việt</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/vi.po">vi</a></td>
|
||||
<td></td>
|
||||
<td>85%</td>
|
||||
<td>88%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/tr.png" alt=""></td>
|
||||
<td>Türkçe</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/tr_TR.po">tr_TR</a></td>
|
||||
<td>Arda Kılıçdağı (<a href="mailto:arda@kilicdagi.com">arda@kilicdagi.com</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/gr.png" alt=""></td>
|
||||
<td>Ελληνικά</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/el_GR.po">el_GR</a></td>
|
||||
<td>Harris Arvanitis (<a href="mailto:xaris@tuta.io">xaris@tuta.io</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>93%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/ru.png" alt=""></td>
|
||||
<td>Русский</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ru_RU.po">ru_RU</a></td>
|
||||
<td>Sergey Segeda (<a href="mailto:thesermanarm@gmail.com">thesermanarm@gmail.com</a>)</td>
|
||||
<td>95%</td>
|
||||
<td>90%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/rs.png" alt=""></td>
|
||||
<td>српски језик</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/sr_RS.po">sr_RS</a></td>
|
||||
<td></td>
|
||||
<td>72%</td>
|
||||
<td>74%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/cn.png" alt=""></td>
|
||||
<td>中文 (简体)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/zh_CN.po">zh_CN</a></td>
|
||||
<td>WhiredPlanck (<a href="mailto:fungdaat31@outlook.com">fungdaat31@outlook.com</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>yaozeye (<a href="mailto:yaozeye@outlook.com">yaozeye@outlook.com</a>)</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/tw.png" alt=""></td>
|
||||
<td>中文 (繁體)</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/zh_TW.po">zh_TW</a></td>
|
||||
<td>Yaoze Ye (<a href="mailto:yaozeye@yahoo.co.jp">yaozeye@yahoo.co.jp</a>)</td>
|
||||
<td>95%</td>
|
||||
<td>98%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/jp.png" alt=""></td>
|
||||
<td>日本語</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ja_JP.po">ja_JP</a></td>
|
||||
<td>genneko (<a href="mailto:genneko217@gmail.com">genneko217@gmail.com</a>)</td>
|
||||
<td>96%</td>
|
||||
<td>99%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://joplinapp.org/images/flags/country-4x3/kr.png" alt=""></td>
|
||||
<td>한국어</td>
|
||||
<td><a href="https://github.com/laurent22/joplin/blob/master/CliClient/locales/ko.po">ko</a></td>
|
||||
<td></td>
|
||||
<td>86%</td>
|
||||
<td>89%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/markdown.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -327,7 +327,7 @@ https://github.com/laurent22/joplin/blob/master/readme/mobile.md
|
||||
<li>
|
||||
<p>Development</p>
|
||||
<ul>
|
||||
<li><a href="https://joplinapp.org/spec/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/e2ee/">End-to-end encryption spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/history/">Note History spec</a></li>
|
||||
<li><a href="https://joplinapp.org/spec/sync_lock/">Sync Lock spec</a></li>
|
||||
</ul>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user