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

Compare commits

...

195 Commits

Author SHA1 Message Date
Laurent Cozic
3e2f4b163b Android 2.11.21 2023-05-14 12:20:01 +01:00
renovate[bot]
e0dbd198d8 Update dependency react-native-paper to v5.6.0 (#8181)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-13 18:40:18 +01:00
Laurent Cozic
a76c5c8746 Tools: Allow publishing varients 2023-05-13 18:25:29 +01:00
Laurent Cozic
20b43ce56e fix 2023-05-13 16:31:24 +01:00
Laurent Cozic
8215ce14c6 Tools: Allow different Android variants 2023-05-13 15:54:17 +01:00
renovate[bot]
3fead0a8a7 Update dependency styled-components to v5.3.10 (#8178)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-13 05:50:55 +00:00
Jonatan
c8bf3e8583 All: Translation: Update sv.po (#8169) 2023-05-12 13:57:39 -04:00
Dmitriy Q
42dee6c275 All: Translation: Update ru_RU.po (#8161) 2023-05-12 13:56:10 -04:00
Laurent Cozic
6f3f866f78 Android 2.11.16 2023-05-12 13:44:15 +01:00
Laurent Cozic
adf2e7322d fix 2023-05-12 13:18:29 +01:00
Laurent Cozic
0df170926a Tools: Restore content after patching Android app 2023-05-12 13:18:28 +01:00
Laurent Cozic
20a26732a9 Tools: Restore content after patching Android app 2023-05-12 13:18:27 +01:00
Laurent Cozic
0da3e91a29 Tools: Exclude Vosk model files when building regular app 2023-05-12 13:17:01 +01:00
renovate[bot]
9ad56dc373 Update dependency gettext-extractor to v3.7.2 (#8167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-12 05:32:43 +00:00
Arda Kılıçdağı
29dab26dce All: Translation: Update tr_TR.po (#8162)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2023-05-11 18:22:36 -04:00
github-actions[bot]
10e8fbcdab @Ardakilic has signed the CLA in laurent22/joplin#8162 2023-05-11 19:11:11 +00:00
Laurent Cozic
6c4f566765 Doc: Fix download links 2023-05-11 19:12:39 +01:00
Joplin Bot
78df302e86 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-11 17:55:45 +00:00
Laurent Cozic
f52dd4f098 Doc: Update download links 2023-05-11 18:44:50 +01:00
github-actions[bot]
dbab786c7b @marph91 has signed the CLA in laurent22/joplin#8163 2023-05-11 14:17:59 +00:00
Laurent Cozic
3eb44d27b2 Mobile: Sync as soon as the app starts, and immediately after changing a note 2023-05-11 14:58:19 +01:00
Laurent Cozic
52bea115ac Tools: Allow uploading Android version to different repo 2023-05-11 14:48:33 +01:00
Laurent Cozic
19bdda25c6 Desktop: Security: Prevent XSS and potential RCE when using a special HTML tag 2023-05-11 14:17:37 +01:00
Laurent Cozic
b26bc9ed5f Desktop: Security: Fixed possible XSS injection 2023-05-10 16:27:16 +01:00
Laurent Cozic
865cedc24f Android 2.11.14 2023-05-10 13:28:43 +01:00
Laurent Cozic
33f0811ad2 Server: Resolves #8153: Allow setting NTP server using NTP_SERVER env variable 2023-05-10 12:50:48 +01:00
Laurent Cozic
8cedf27fea Desktop, Mobile: Resolves #8154: Translate Welcome notes 2023-05-10 12:20:04 +01:00
Laurent Cozic
052a829167 Desktop: Auto-detect locale on startup 2023-05-10 12:20:03 +01:00
Laurent Cozic
5371c97ccd Chore: Refactor build-welcome script 2023-05-10 12:20:02 +01:00
Joplin Bot
c53b957293 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-09 18:17:54 +00:00
Laurent Cozic
e6f8dc96df Fixed CI 2023-05-09 17:21:40 +01:00
Laurent Cozic
21648b1b1b Desktop: Fixes #8149: Application cannot be installed on Windows 10 in some cases 2023-05-09 12:56:23 +01:00
Laurent Cozic
83db6f6596 Desktop release v2.11.2 2023-05-09 11:13:38 +01:00
Laurent Cozic
3adfa574c0 Desktop: Fixes #8149: Application cannot be installed on Windows 10 in some cases 2023-05-09 11:13:23 +01:00
Laurent Cozic
4d0ffc5beb clean up 2023-05-09 11:12:53 +01:00
Laurent Cozic
69f9b160dd Chore: Cleanup Android release script 2023-05-09 11:01:43 +01:00
Laurent Cozic
c17b02cfb5 Android 2.11.13 2023-05-09 08:49:00 +01:00
Laurent Cozic
6dd57b63a6 Chore: Enable Hermes again on Android to try to fix crash 2023-05-08 21:03:11 +01:00
Laurent Cozic
248c8014c8 Android 2.11.12 2023-05-08 21:02:28 +01:00
Joplin Bot
5fe2766a6b Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-08 18:16:06 +00:00
Laurent Cozic
000e0ad517 Chore: Android: Remove non longer needed joplin/react-native-vosk package 2023-05-08 18:54:23 +01:00
Laurent Cozic
c047375143 Chore: Android: Trying to fix random crash 2023-05-08 18:44:52 +01:00
Laurent Cozic
bd9e62cbd2 Android 2.11.11 2023-05-08 18:27:18 +01:00
Laurent Cozic
5ecae17538 Mobile: Tells whether Hermes engine is enabled or not 2023-05-08 17:50:19 +01:00
Laurent Cozic
35037e2dc9 fix tests 2023-05-08 17:30:30 +01:00
Laurent Cozic
059202be09 Desktop: Fixes #8072: Enter Key No Longer Saves and Closes The Tag Dialog 2023-05-08 17:07:55 +01:00
Laurent Cozic
6672f63981 Desktop: Fixes #8143: Fixes crash when using multiple profiles along with certain plugins 2023-05-08 16:45:18 +01:00
Laurent Cozic
f390eca4de Desktop: Fixes #8143: Fixes crash when using multiple profiles along with certain plugins 2023-05-08 15:34:38 +01:00
Joplin Bot
edc5e33559 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-08 13:12:39 +00:00
Laurent Cozic
a4b81edb5a Doc: Fix news page 2023-05-08 13:12:57 +01:00
Joplin Bot
fc5f338e16 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-08 11:38:41 +00:00
Laurent Cozic
767e380144 Doc: Release notes for 2.10 2023-05-08 12:24:55 +01:00
Laurent Cozic
60aff6ae77 Android 2.11.10 2023-05-08 12:09:28 +01:00
Laurent Cozic
345d9da7f2 Update translations 2023-05-08 10:56:16 +01:00
Laurent Cozic
98d45b1b81 Chore: Make text translatable 2023-05-08 10:38:52 +01:00
Joplin Bot
2cbf12bf0b Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-08 06:17:54 +00:00
Laurent Cozic
968529f7e8 Android 2.11.9 2023-05-07 20:04:55 +01:00
Laurent Cozic
b1b7c3903f Update renovate.json5 2023-05-07 18:58:56 +01:00
Laurent Cozic
530a620d68 Chore: Fix Android buiold 2023-05-07 18:29:10 +01:00
Laurent Cozic
1f2ecd08eb Android 2.11.8 2023-05-07 18:26:16 +01:00
Laurent Cozic
d5eeb12ce7 Android: Fix voice typing 2023-05-07 17:53:19 +01:00
Laurent Cozic
e9e9986978 Mobile: Disable Hermes engine 2023-05-07 17:52:58 +01:00
Laurent Cozic
d44f212b95 Android 2.11.7 2023-05-07 15:29:58 +01:00
Laurent Cozic
47be6bcde3 Chore: Mobile: Fixed typo 2023-05-07 14:56:02 +01:00
Laurent Cozic
ef256a82ab Android 2.11.6 2023-05-07 14:53:51 +01:00
Laurent Cozic
b4d56f42f7 Chore: Disable Hermes to try to debug crash
Ref: https://github.com/facebook/react-native/issues/29165
2023-05-07 14:24:40 +01:00
Laurent Cozic
c1598c1a59 Doc: Update Android changelog 2023-05-07 14:24:26 +01:00
Laurent Cozic
3b6decfaf6 lock file 2023-05-07 12:48:30 +01:00
Laurent Cozic
5494e8c3dc Mobile: Improved Vosk support (beta, fr only) (#8131) 2023-05-07 12:05:41 +01:00
renovate[bot]
39059ae6bf Update dependency reselect to v4.1.8 (#8137)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-07 02:10:24 +00:00
renovate[bot]
5773f63664 Update dependency react-native-share to v8.2.2 (#8130)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-04 18:03:17 +00:00
renovate[bot]
5698c30d1a Update dependency sharp to v0.32.0 (#8124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-04 12:12:27 +01:00
github-actions[bot]
218d69cf38 @cas-- has signed the CLA in laurent22/joplin#8126 2023-05-04 08:42:05 +00:00
renovate[bot]
00369fd613 Update dependency koa to v2.14.2 (#8111)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-03 16:11:52 +00:00
Laurent Cozic
ef86e01cd6 Android 2.11.4 2023-05-03 13:09:52 +01:00
Laurent Cozic
efd9f740ca Tools: Fixed git-changelog logic 2023-05-03 12:47:40 +01:00
Laurent Cozic
36c121523a Android: Add support for offline speech to text (Beta - FR only) (#8115) 2023-05-03 12:19:43 +01:00
Laurent Cozic
991c12025b Mobile: Fixes issue where the note body is not updated after attaching a file 2023-05-03 11:45:19 +01:00
renovate[bot]
f1d6945cd5 Update dependency sass to v1.60.0 (#8116)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-03 09:35:15 +01:00
Laurent Cozic
2ebebd1dfa Doc: Fix image 2023-05-03 09:33:22 +01:00
Linkosred
d955ed464e Update faq_joplin_cloud.md (#8113) 2023-05-02 14:42:38 +01:00
github-actions[bot]
b7695115da @Linkosred has signed the CLA in laurent22/joplin#8110 2023-05-02 09:54:29 +00:00
renovate[bot]
f274678ad7 Update dependency react-native-document-picker to v8.2.0 (#8107)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-01 15:01:06 +01:00
renovate[bot]
5ff0309586 Update aws (#8106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-01 07:36:51 +00:00
Joplin Bot
ffb6c25ce7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-05-01 00:39:43 +00:00
renovate[bot]
7237ae319a Update dependency gettext-extractor to v3.7.1 (#8102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-30 20:36:51 +00:00
Jonatan
cdd5a911a9 All: Translation: Update sv.po (#8103) 2023-04-30 11:01:25 -04:00
github-actions[bot]
66b53f013d @reportxx has signed the CLA in laurent22/joplin#8103 2023-04-30 11:19:00 +00:00
Laurent Cozic
4d9ffffe56 Doc: Update Paypal link 2023-04-30 10:50:14 +01:00
Laurent Cozic
c08f7de6bb Update architecture.md 2023-04-29 14:39:15 +01:00
Laurent Cozic
77789c0b17 Doc: Added architecture document 2023-04-29 11:40:13 +01:00
renovate[bot]
be7056ff59 Update dependency react-native-safe-area-context to v4.5.1 (#8097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-28 22:30:07 +00:00
renovate[bot]
274a55a31f Update dependency lint-staged to v13.2.1 (#8091)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-28 01:07:50 +00:00
Joplin Bot
32977c4e3f Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-27 12:21:00 +00:00
renovate[bot]
075b1626bd Update dependency @react-native-community/netinfo to v9.3.9 (#8086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-27 12:19:05 +00:00
Joplin Bot
fd6538fdc7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-27 00:42:00 +00:00
Torgny Bjers
b897191cc8 Doc: add note about reference links (#8036)
Co-authored-by: Helmut K. C. Tessarek <tessarek@evermeet.cx>
2023-04-26 19:01:25 -04:00
Laurent Cozic
31897581d3 Desktop: Resolves #8028: Remove custom PDF viewer to reduce application size 2023-04-26 21:45:02 +01:00
Douglas Leão
6c1820edc0 All: Translation: Update pt_BR.po (#8077) 2023-04-26 09:53:09 -04:00
github-actions[bot]
cfe4c8c6f4 @djunho has signed the CLA in laurent22/joplin#8079 2023-04-24 10:05:37 +00:00
github-actions[bot]
b83165f9e5 @DeeJayLSP has signed the CLA in laurent22/joplin#8077 2023-04-24 04:57:05 +00:00
Laurent Cozic
7706f9058b Chore: Trying to fix CI error "TypeError: Cannot redefine property: performance" 2023-04-23 22:58:43 +01:00
Laurent Cozic
03222ba1b2 Revert "Chore: Trying to fix CI error "TypeError: Cannot redefine property: performance""
This reverts commit d4f49db342.

Wrong fix
2023-04-23 22:56:24 +01:00
Laurent Cozic
d4f49db342 Chore: Trying to fix CI error "TypeError: Cannot redefine property: performance" 2023-04-23 22:43:10 +01:00
Laurent Cozic
40e1b0559e Doc: Allow translating documentation 2023-04-23 22:33:15 +01:00
Laurent Cozic
738f1decbb Chore: Add types to search engine 2023-04-23 10:07:38 +01:00
jcgurango
e5a364d052 Chore: Mobile: Convert note-list.js to NoteList.tsx (#8064) 2023-04-23 10:07:28 +01:00
Laurent Cozic
357a3e2e7b Chore: Add types to search engine 2023-04-23 10:05:13 +01:00
Joplin Bot
af91fd99cc Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-22 00:39:14 +00:00
Joplin Bot
3855f60a0d Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-21 18:18:40 +00:00
Arun Kumar
079b379e7a Desktop: Resolves #8028: Compress installer to reduce size (#8068) 2023-04-20 09:02:04 +01:00
github-actions[bot]
e23e036677 @Wladefant has signed the CLA in laurent22/joplin#8069 2023-04-19 12:28:56 +00:00
Arun Kumar
b824ff5457 Mobile: Fixes #8017: Fixed sync crash (#8056) 2023-04-17 15:17:15 +03:00
renovate[bot]
3669a1b5d6 Update dependency react-native-paper to v5.5.2 (#8054)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-16 23:41:05 +00:00
Laurent Cozic
b93f9aaf01 Update terminal.md 2023-04-16 13:13:06 +03:00
renovate[bot]
8679290206 Update dependency react-native-paper to v5.5.1 (#8037)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-14 22:36:08 +00:00
Joplin Bot
4acec5c6c7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-14 18:18:49 +00:00
Joplin Bot
f1b03453a4 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-14 12:20:07 +00:00
github-actions[bot]
7972dd5556 @simonla has signed the CLA in laurent22/joplin#8042 2023-04-11 19:03:07 +00:00
Laurent Cozic
4842500f0a Tools: Increase renovate stability days 2023-04-10 13:00:07 +02:00
renovate[bot]
84c7f28ec5 Update dependency react-native-paper to v5.5.0 (#8035)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-10 12:57:53 +02:00
github-actions[bot]
f3eea43d24 @tbjers has signed the CLA in laurent22/joplin#8036 2023-04-10 02:35:07 +00:00
Joplin Bot
8babaddbcb Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-09 12:21:18 +00:00
Laurent Cozic
13cdaabb17 Android 2.11.2 2023-04-09 14:07:14 +02:00
renovate[bot]
a94aa21088 Update dependency slugify to v1.6.6 (#8019)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2023-04-09 12:56:05 +01:00
Henry Heino
6116bed4e3 Mobile: Resolve #8022: Editor syntax highlighting was broken (#8023) 2023-04-09 12:55:47 +01:00
Arun Kumar
fabd0b4dda Desktop, Mobile: Fixes #7940: Removed MasterKey from Sync Status report (#8026) 2023-04-09 12:54:48 +01:00
Laurent Cozic
6b72f86e7b Mobile: Security: Prevent bypassing fingerprint lock on certain devices 2023-04-09 11:29:33 +02:00
Joplin Bot
02cf546124 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-09 06:17:13 +00:00
renovate[bot]
eecb012d64 Update dependency @react-native-community/netinfo to v9.3.8 (#8033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-09 03:02:24 +00:00
Laurent Cozic
04e9b40769 Android 2.11.1 2023-04-08 10:51:00 +02:00
Laurent Cozic
efdbaeb397 Mobile: Add log info for biometrics feature 2023-04-08 10:40:53 +02:00
Laurent Cozic
46425b920c Doc: Added some doc about Joplin Server items 2023-04-07 16:49:54 +02:00
Laurent Cozic
f5be43c2ac Doc: Add info about synchronisation process 2023-04-07 16:36:59 +02:00
github-actions[bot]
080541a2fe @Letty has signed the CLA in laurent22/joplin#8029 2023-04-07 10:05:21 +00:00
github-actions[bot]
7dc638edf4 @gitstart has signed the CLA in laurent22/joplin#8024 2023-04-06 21:46:34 +00:00
Laurent Cozic
3b686194d8 Tools: Pass APPLE_APP_SPECIFIC_PASSWORD to CI 2023-04-06 14:02:45 +02:00
Laurent Cozic
5c2640f88f Tools: Simplify root workspace build 2023-04-06 12:11:45 +02:00
Laurent Cozic
eca0f92dff Disable again 2023-04-06 11:46:06 +02:00
Laurent Cozic
260fa6c038 Clipper release v2.11.2 2023-04-06 11:44:55 +02:00
Laurent Cozic
8ec6bc9138 Tools: Simplify dependencies of root package 2023-04-06 11:29:59 +02:00
Laurent Cozic
93fa92369b Tools: Removing packages/tools dependency from root workspace 2023-04-06 11:02:22 +02:00
Laurent Cozic
bc6c5ab7a7 Chore: Make utils package a fixed version again (too many problems otherwise) 2023-04-06 10:02:49 +02:00
Laurent Cozic
1826625e4f lock file 2023-04-05 23:19:25 +02:00
Laurent Cozic
20b8fb2719 Missing package 2023-04-05 22:48:17 +02:00
Laurent Cozic
f813e71b29 Chore: Access utils lib with relative path 2023-04-05 22:35:47 +02:00
Laurent Cozic
02422a6e31 Chore: Access utils lib with relative path 2023-04-05 22:35:46 +02:00
renovate[bot]
69a34e87f3 Update dependency nanoid to v3.3.6 (#7973)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-05 21:16:55 +01:00
Joplin Bot
cbeaa16b61 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-05 18:18:02 +00:00
Joplin Bot
05917ac142 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-05 12:24:26 +00:00
Laurent Cozic
0c8de68b80 Desktop: Fixed issue with text disappearing within plugin-created zones when searching for text
Ref: https://github.com/joplin/plugin-abc-sheet-music/issues/5
2023-04-04 21:09:58 +02:00
Joplin Bot
44d93d52d3 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-04-04 18:30:09 +00:00
Laurent Cozic
073bec9e8c CI: Trying to fix website builder 2023-04-04 20:16:35 +02:00
Laurent Cozic
e6a8c2bea5 CI: Trying to fix website builder 2023-04-04 19:47:54 +02:00
Laurent Cozic
81c316cd2c CI: Trying to fix website builder 2023-04-04 19:24:03 +02:00
Laurent Cozic
659c851960 CI: Trying to fix website builder 2023-04-04 17:01:34 +02:00
Laurent Cozic
572701d9a0 Tools: Fix website builder 2023-04-04 12:04:42 +02:00
Laurent Cozic
66ef37bd4e Chore: Disable flaky test 2023-04-03 20:42:31 +02:00
Laurent Cozic
9ddf75604d Doc: Remove sponsor 2023-04-03 20:39:31 +02:00
Laurent Cozic
3ed7e1d7e8 Doc: Fix sponsor thumbnails 2023-04-03 20:39:31 +02:00
Laurent Cozic
b2b412105a Merge branch 'release-2.10' into dev 2023-04-03 18:30:55 +02:00
Laurent Cozic
60a3c4f65e lock file 2023-04-03 18:26:04 +02:00
Laurent Cozic
9645414c17 Desktop release v2.10.13 2023-04-03 18:10:54 +02:00
Henry Heino
af0136ef39 All: Fixes #7986: Fix OneDrive sync attempting to call method on null variable (#7987) 2023-04-03 18:09:52 +02:00
Self Not Found
b76586c4fd All: Fixes #7851: Encode the non-ASCII characters in OneDrive URI (#7868) 2023-04-03 18:09:10 +02:00
Laurent Cozic
376e4ebde0 Desktop: Fixed display of installed plugins in About box 2023-04-03 18:01:06 +02:00
renovate[bot]
1439b8787f Update dependency react-native-image-picker to v5.3.1 (#8015)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 11:51:02 +01:00
renovate[bot]
b8854a99be Update dependency @lezer/highlight to v1.1.4 (#8014)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 10:46:19 +00:00
renovate[bot]
6cf02173dc Update dependency gettext-extractor to v3.7.0 (#8012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 10:56:44 +01:00
renovate[bot]
4d8a53d8c9 Update dependency react-native-image-picker to v5.3.0 (#8010)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 10:56:25 +01:00
renovate[bot]
7f43718e1d Update dependency react-select to v5.7.2 (#8009)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-02 07:09:26 +00:00
renovate[bot]
690ce637b1 Update dependency nodemon to v2.0.22 (#8008)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-02 03:42:02 +00:00
renovate[bot]
4d023e679e Update dependency turndown to v7.1.2 (#8006)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-01 16:46:25 +00:00
renovate[bot]
6e220a978f Update dependency jsdom to v21.1.1 (#8007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-01 16:00:34 +02:00
renovate[bot]
39757cd90e Update dependency sass to v1.59.3 (#8005)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-01 05:46:20 +00:00
renovate[bot]
5ccbbea757 Update dependency react-native-paper to v5.4.1 (#8004)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-31 22:56:15 +00:00
Arun Kumar
309222c082 Desktop: Fixes #8000: Fixed Linux tag display issues (#8002) 2023-03-31 23:13:59 +02:00
renovate[bot]
50f5fe2c91 Update dependency sass to v1.59.2 (#8001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-31 23:12:25 +02:00
renovate[bot]
eacae83182 Update dependency react-native-paper to v5.4.0 (#7997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-31 23:12:05 +02:00
Laurent Cozic
403d770b1d Tools: Trying to prevent CI from running on forks 2023-03-30 22:57:58 +01:00
Laurent Cozic
a481bf1b53 Tools: Trying to prevent CI from running on forks 2023-03-30 22:55:14 +01:00
renovate[bot]
0d32570c9e Update dependency fs-extra to v11.1.1 (#7996)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-30 20:11:29 +00:00
Fejby
f017e99b02 All: Translation: Update cs_CZ.po (#7999) 2023-03-30 14:40:05 -04:00
github-actions[bot]
a89d64d435 @Fejby has signed the CLA in laurent22/joplin#7999 2023-03-30 18:21:47 +00:00
github-actions[bot]
3a27086534 @TahaNw has signed the CLA in laurent22/joplin#7998 2023-03-30 17:33:50 +00:00
Laurent Cozic
413c1e41b5 Revert "Chore: Mac binary signing tweaks for embedded plugins (#7988)"
This reverts commit cf4008951d.

Not working.

Ref: https://github.com/laurent22/joplin/issues/7934#issuecomment-1490632038
2023-03-30 18:24:25 +01:00
Henry Heino
8b879464b8 All: Fixes #7986: Fix OneDrive sync attempting to call method on null variable (#7987) 2023-03-30 17:41:29 +01:00
renovate[bot]
97c9bbc1fe Update dependency react-native-paper to v5.3.1 (#7977) 2023-03-30 17:38:18 +01:00
renovate[bot]
e5bebef7b2 Update dependency lint-staged to v13.2.0 (#7994) 2023-03-30 17:38:06 +01:00
renovate[bot]
73752c4b3f Update dependency pg to v8.10.0 (#7978) 2023-03-30 17:37:46 +01:00
Laurent Cozic
dcf7c9838d Desktop release v2.11.1 2023-03-30 17:13:20 +01:00
Laurent Cozic
f325e7694b Chore: Prepare v2.11 2023-03-30 17:13:06 +01:00
Arun Kumar
75d204c9ca Desktop: Resolves #6101: Added export graph button for Mermaid (#7958) 2023-03-30 16:58:48 +01:00
Arun Kumar
cf4008951d Chore: Mac binary signing tweaks for embedded plugins (#7988) 2023-03-30 16:57:22 +01:00
renovate[bot]
d67818d096 Update dependency react-select to v5.7.1 (#7993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-30 14:30:20 +00:00
226 changed files with 19860 additions and 19963 deletions

View File

@@ -74,6 +74,7 @@ packages/turndown/
packages/pdf-viewer/dist
plugin_types/
readme/
packages/react-native-vosk/lib/
# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
packages/app-cli/app/LinkSelector.js
@@ -396,6 +397,7 @@ packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
@@ -405,6 +407,7 @@ packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/app-nav.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/getResponsiveValue.test.js
@@ -415,12 +418,15 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/search.js
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
packages/app-mobile/gulpfile.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/vosk.dummy.js
packages/app-mobile/services/voiceTyping/vosk.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs.js
packages/app-mobile/utils/ShareExtension.js
@@ -477,6 +483,7 @@ packages/lib/SyncTargetOneDrive.js
packages/lib/SyncTargetRegistry.js
packages/lib/Synchronizer.js
packages/lib/TaskQueue.js
packages/lib/WelcomeUtils.js
packages/lib/array.js
packages/lib/callbackUrlUtils.js
packages/lib/callbackUrlUtils.test.js
@@ -512,6 +519,7 @@ packages/lib/import-enex-md-gen.js
packages/lib/import-enex-md-gen.test.js
packages/lib/import-enex.js
packages/lib/locale.js
packages/lib/locale.test.js
packages/lib/markdownUtils.js
packages/lib/markdownUtils.test.js
packages/lib/markdownUtils2.test.js
@@ -710,6 +718,7 @@ packages/lib/services/searchengine/SearchFilter.test.js
packages/lib/services/searchengine/filterParser.js
packages/lib/services/searchengine/filterParser.test.js
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
packages/lib/services/searchengine/gotoAnythingStyleQuery.test.js
packages/lib/services/searchengine/queryBuilder.js
packages/lib/services/share/ShareService.js
packages/lib/services/share/ShareService.test.js
@@ -837,6 +846,7 @@ packages/renderer/noteStyle.js
packages/renderer/pathUtils.js
packages/renderer/utils.js
packages/tools/build-release-stats.js
packages/tools/build-welcome.js
packages/tools/buildServerDocker.js
packages/tools/buildServerDocker.test.js
packages/tools/bundleDefaultPlugins.js
@@ -871,6 +881,8 @@ packages/tools/website/updateDownloadPage.js
packages/tools/website/updateNews.js
packages/tools/website/utils/applyTranslations.js
packages/tools/website/utils/applyTranslations.test.js
packages/tools/website/utils/convertLinksToLocale.js
packages/tools/website/utils/convertLinksToLocale.test.js
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/news.js
packages/tools/website/utils/openGraph.js

View File

@@ -183,12 +183,32 @@ if [[ $GIT_TAG_NAME = v* ]]; then
# cd "$ROOT_DIR/packages/tools"
# node bundleDefaultPlugins.js
cd "$ROOT_DIR/packages/app-desktop"
USE_HARD_LINKS=false yarn run dist
if [ "$IS_MACOS" == "1" ]; then
# This is to fix this error:
#
# Exit code: ENOENT. spawn /usr/bin/python ENOENT
#
# Ref: https://github.com/electron-userland/electron-builder/issues/6767#issuecomment-1096589528
#
# It can be removed once we upgrade to electron-builder@23, however we
# cannot currently do this due to this error:
# https://github.com/laurent22/joplin/issues/8149
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist
else
USE_HARD_LINKS=false yarn run dist
fi
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
echo "Step: Building Docker Image..."
cd "$ROOT_DIR"
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
else
echo "Step: Building but *not* publishing desktop application..."
USE_HARD_LINKS=false yarn run dist --publish=never
if [ "$IS_MACOS" == "1" ]; then
# See above why we need to specify Python
PYTHON_PATH=$(which python) USE_HARD_LINKS=false yarn run dist --publish=never
else
USE_HARD_LINKS=false yarn run dist --publish=never
fi
fi

View File

@@ -6,6 +6,7 @@ on: [push, pull_request]
jobs:
pre_job:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
@@ -16,6 +17,7 @@ jobs:
concurrent_skipping: 'same_content_newer'
BuildAndroidDebug:
if: github.repository == 'laurent22/joplin'
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest

View File

@@ -7,6 +7,7 @@ on:
jobs:
CLAAssistant:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"

View File

@@ -6,6 +6,7 @@ permissions:
issues: write
jobs:
ProcessStaleIssues:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4

View File

@@ -2,6 +2,7 @@ name: Joplin Continuous Integration
on: [push, pull_request]
jobs:
pre_job:
if: github.repository == 'laurent22/joplin'
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
@@ -14,7 +15,7 @@ jobs:
Main:
needs: pre_job
# We always process server or desktop release tags, because they also publish the release
if: needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/v')
if: github.repository == 'laurent22/joplin' && (needs.pre_job.outputs.should_skip != 'true' || startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/v'))
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -70,7 +71,9 @@ jobs:
- uses: olegtarasov/get-tag@v2.1
- uses: actions/setup-node@v2
with:
node-version: '18'
# We need to pin the version to 18.15, because 18.16+ fails with this error:
# https://github.com/facebook/react-native/issues/36440
node-version: '18.15.0'
- name: Install Yarn
run: |
@@ -92,6 +95,7 @@ jobs:
APPLE_ASC_PROVIDER: ${{ secrets.APPLE_ASC_PROVIDER }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
@@ -129,7 +133,7 @@ jobs:
ServerDockerImage:
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
if: github.repository == 'laurent22/joplin' && needs.pre_job.outputs.should_skip != 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:

11
.gitignore vendored
View File

@@ -383,6 +383,7 @@ packages/app-mobile/components/NoteEditor/NoteEditor.js
packages/app-mobile/components/NoteEditor/SearchPanel.js
packages/app-mobile/components/NoteEditor/SelectionFormatting.js
packages/app-mobile/components/NoteEditor/types.js
packages/app-mobile/components/NoteList.js
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
@@ -392,6 +393,7 @@ packages/app-mobile/components/SideMenu.js
packages/app-mobile/components/TextInput.js
packages/app-mobile/components/app-nav.js
packages/app-mobile/components/biometrics/BiometricPopup.js
packages/app-mobile/components/biometrics/biometricAuthenticate.js
packages/app-mobile/components/biometrics/sensorInfo.js
packages/app-mobile/components/getResponsiveValue.js
packages/app-mobile/components/getResponsiveValue.test.js
@@ -402,12 +404,15 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
packages/app-mobile/components/screens/encryption-config.js
packages/app-mobile/components/screens/search.js
packages/app-mobile/components/side-menu-content.js
packages/app-mobile/components/voiceTyping/VoiceTypingDialog.js
packages/app-mobile/gulpfile.js
packages/app-mobile/root.js
packages/app-mobile/services/AlarmServiceDriver.android.js
packages/app-mobile/services/AlarmServiceDriver.ios.js
packages/app-mobile/services/e2ee/RSA.react-native.js
packages/app-mobile/services/profiles/index.js
packages/app-mobile/services/voiceTyping/vosk.dummy.js
packages/app-mobile/services/voiceTyping/vosk.js
packages/app-mobile/setupQuickActions.js
packages/app-mobile/tools/buildInjectedJs.js
packages/app-mobile/utils/ShareExtension.js
@@ -464,6 +469,7 @@ packages/lib/SyncTargetOneDrive.js
packages/lib/SyncTargetRegistry.js
packages/lib/Synchronizer.js
packages/lib/TaskQueue.js
packages/lib/WelcomeUtils.js
packages/lib/array.js
packages/lib/callbackUrlUtils.js
packages/lib/callbackUrlUtils.test.js
@@ -499,6 +505,7 @@ packages/lib/import-enex-md-gen.js
packages/lib/import-enex-md-gen.test.js
packages/lib/import-enex.js
packages/lib/locale.js
packages/lib/locale.test.js
packages/lib/markdownUtils.js
packages/lib/markdownUtils.test.js
packages/lib/markdownUtils2.test.js
@@ -697,6 +704,7 @@ packages/lib/services/searchengine/SearchFilter.test.js
packages/lib/services/searchengine/filterParser.js
packages/lib/services/searchengine/filterParser.test.js
packages/lib/services/searchengine/gotoAnythingStyleQuery.js
packages/lib/services/searchengine/gotoAnythingStyleQuery.test.js
packages/lib/services/searchengine/queryBuilder.js
packages/lib/services/share/ShareService.js
packages/lib/services/share/ShareService.test.js
@@ -824,6 +832,7 @@ packages/renderer/noteStyle.js
packages/renderer/pathUtils.js
packages/renderer/utils.js
packages/tools/build-release-stats.js
packages/tools/build-welcome.js
packages/tools/buildServerDocker.js
packages/tools/buildServerDocker.test.js
packages/tools/bundleDefaultPlugins.js
@@ -858,6 +867,8 @@ packages/tools/website/updateDownloadPage.js
packages/tools/website/updateNews.js
packages/tools/website/utils/applyTranslations.js
packages/tools/website/utils/applyTranslations.test.js
packages/tools/website/utils/convertLinksToLocale.js
packages/tools/website/utils/convertLinksToLocale.test.js
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/news.js
packages/tools/website/utils/openGraph.js

View File

@@ -0,0 +1,127 @@
diff --git a/android/build.gradle b/android/build.gradle
index 6afcbbf0cc8ca2d69dd78077d61e59a90b2136bb..9f8d72b4ec5b2b3d290975d6a255917c95300854 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -67,19 +67,19 @@ repositories {
}
// Generate UUIDs for each models contained in android/src/main/assets/
-tasks.register('genUUID') {
- doLast {
- fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
- if (fileDetails.directory) {
- def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
- def ofile = file("$odir/uuid")
- mkdir odir
- ofile.text = UUID.randomUUID().toString()
- }
- }
- }
-}
-preBuild.dependsOn genUUID
+// tasks.register('genUUID') {
+// doLast {
+// fileTree(dir: "$rootDir/app/src/main/assets", exclude: ['*/*']).visit { fileDetails ->
+// if (fileDetails.directory) {
+// def odir = file("$rootDir/app/src/main/assets/$fileDetails.relativePath")
+// def ofile = file("$odir/uuid")
+// mkdir odir
+// ofile.text = UUID.randomUUID().toString()
+// }
+// }
+// }
+// }
+// preBuild.dependsOn genUUID
def kotlin_version = getExtOrDefault('kotlinVersion')
diff --git a/android/src/main/java/com/reactnativevosk/VoskModule.kt b/android/src/main/java/com/reactnativevosk/VoskModule.kt
index 0e2b6595b1b2cf1ee01c6c64239c4b0ea37fce19..f3da440bc2863a59db6d2d1691c54d8d4870cb3f 100644
--- a/android/src/main/java/com/reactnativevosk/VoskModule.kt
+++ b/android/src/main/java/com/reactnativevosk/VoskModule.kt
@@ -19,13 +19,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
return "Vosk"
}
+ @ReactMethod
+ fun addListener(type: String?) {
+ // Keep: Required for RN built in Event Emitter Calls.
+ }
+
+ @ReactMethod
+ fun removeListeners(type: Int?) {
+ // Keep: Required for RN built in Event Emitter Calls.
+ }
+
override fun onResult(hypothesis: String) {
// Get text data from string object
val text = getHypothesisText(hypothesis)
// Stop recording if data found
if (text != null && text.isNotEmpty()) {
- cleanRecognizer();
+ // Don't auto-stop the recogniser - we want to do that when the user
+ // presses on "stop" only.
+ // cleanRecognizer();
sendEvent("onResult", text)
}
}
@@ -153,6 +165,25 @@ class VoskModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
cleanRecognizer();
}
+ @ReactMethod
+ fun stopOnly() {
+ if (speechService != null) {
+ speechService!!.stop()
+ }
+ }
+
+ @ReactMethod
+ fun cleanup() {
+ if (speechService != null) {
+ speechService!!.shutdown();
+ speechService = null
+ }
+ if (recognizer != null) {
+ recognizer!!.close();
+ recognizer = null;
+ }
+ }
+
@ReactMethod
fun unload() {
cleanRecognizer();
diff --git a/lib/typescript/index.d.ts b/lib/typescript/index.d.ts
index 441e41cc402cca3a60b34978ef4fea976076259c..a173acebb4b314402550442ad471e0f7c706e3c4 100644
--- a/lib/typescript/index.d.ts
+++ b/lib/typescript/index.d.ts
@@ -10,6 +10,8 @@ export default class Vosk {
currentRegisteredEvents: EmitterSubscription[];
start: (grammar?: string[] | null) => Promise<String>;
stop: () => void;
+ stopOnly: () => void;
+ cleanup: () => void;
unload: () => void;
onResult: (onResult: (e: VoskEvent) => void) => EventSubscription;
onFinalResult: (onFinalResult: (e: VoskEvent) => void) => EventSubscription;
diff --git a/src/index.tsx b/src/index.tsx
index d9f90c921d89b1b4d85e145443ed3376546a368a..29e4068dbd7500828a73145bd25497a52c9bf638 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -69,6 +69,15 @@ export default class Vosk {
VoskModule.stop();
};
+ stopOnly = () => {
+ VoskModule.stopOnly();
+ };
+
+ cleanup = () => {
+ this.cleanListeners();
+ VoskModule.cleanup();
+ };
+
unload = () => {
this.cleanListeners();
VoskModule.unload();

View File

@@ -0,0 +1,30 @@
diff --git a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
index a8abd71833879201e3438b2fa51d712a311c4551..ffe9c2c6dfa5c703ba76b65d94d5dd6784102c19 100644
--- a/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
+++ b/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
@@ -591,7 +591,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
// ignored.printStackTrace();
}
- RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
+ RNFetchBlobFileResp rnFetchBlobFileResp = new RNFetchBlobFileResp(responseBody);
if(rnFetchBlobFileResp != null && !rnFetchBlobFileResp.isDownloadComplete()){
callback.invoke("Download interrupted.", null);
diff --git a/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java b/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
index 2470eef612308c15a89dfea5a1f16937469be29f..965f8becc195965907699182c764ec9e51811450 100644
--- a/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
+++ b/android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java
@@ -35,6 +35,12 @@ public class RNFetchBlobFileResp extends ResponseBody {
FileOutputStream ofStream;
boolean isEndMarkerReceived;
+ // ref: https://github.com/joltup/rn-fetch-blob/issues/490#issuecomment-990899440
+ public RNFetchBlobFileResp(ResponseBody body) {
+ super();
+ this.originalBody = body;
+ }
+
public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException {
super();
this.rctContext = ctx;

View File

@@ -0,0 +1,136 @@
<mxfile host="Electron" modified="2023-04-29T09:42:39.598Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="apmX4QvXCQymGu7gtKJn" version="21.2.1" type="device">
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
<mxGraphModel dx="1244" dy="759" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="93vzSs2z7RmF_nCAYhdf-1" value="Front end" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="465" y="120" width="170" height="60" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-4" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-5" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="490" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-6" value="Service" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="280" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-10" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-11" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="490" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-12" value="Model" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="430" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-14" value="SQLite database" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="490" y="580" width="122.5" height="100" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-19" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-20" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-21" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-22" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-23" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-24" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-25" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-26" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-11" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-27" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-12" target="93vzSs2z7RmF_nCAYhdf-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-28" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-10" target="93vzSs2z7RmF_nCAYhdf-14">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-29" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-30" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-14" target="93vzSs2z7RmF_nCAYhdf-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="700" y="440" as="sourcePoint" />
<mxPoint x="750" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-31" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-4" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-32" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-5" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-33" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-6" target="93vzSs2z7RmF_nCAYhdf-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="620" y="440" as="sourcePoint" />
<mxPoint x="670" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-37" value="BACKEND" style="swimlane;whiteSpace=wrap;html=1;swimlaneFillColor=none;shadow=0;" vertex="1" parent="1">
<mxGeometry x="280" y="230" width="560" height="480" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-38" value="JSON config file" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="1">
<mxGeometry x="910" y="420" width="80" height="100" as="geometry" />
</mxCell>
<mxCell id="93vzSs2z7RmF_nCAYhdf-39" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="93vzSs2z7RmF_nCAYhdf-37" target="93vzSs2z7RmF_nCAYhdf-38">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="830" y="480" as="sourcePoint" />
<mxPoint x="800" y="580" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -0,0 +1,70 @@
<mxfile host="Electron" modified="2023-04-29T10:24:42.580Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.2.1 Chrome/112.0.5615.87 Electron/24.1.2 Safari/537.36" etag="kcPEKHJGaBvNGFhEOF2g" version="21.2.1" type="device">
<diagram name="Page-1" id="5f0bae14-7c28-e335-631c-24af17079c00">
<mxGraphModel dx="1306" dy="797" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="t8PL5avYcYxuv0YEq-6K-7" value="Joplin Server" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="40" width="630" height="465" as="geometry">
<mxRectangle x="350" y="300" width="120" height="30" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-2" value="Server application" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="270" y="92.5" width="170" height="80" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-3" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="190" y="262.5" width="140" height="110" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-5" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-3" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="280" y="232.5" as="sourcePoint" />
<mxPoint x="330" y="182.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-11" value="Note metadata,&lt;br&gt;user accounts, etc." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-5">
<mxGeometry x="0.0586" y="1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-4" value="AWS S3" style="shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="430" y="277.5" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-6" value="Note and attachment&lt;br&gt;content" style="endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=0;exitY=0;exitDx=50;exitDy=0;exitPerimeter=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-4" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="390" y="242.5" as="sourcePoint" />
<mxPoint x="440" y="192.5" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-12" value="Reverse proxy" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="70" y="97.5" width="75" height="75" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-13" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-12" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="180" y="160" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="t8PL5avYcYxuv0YEq-6K-7" source="t8PL5avYcYxuv0YEq-6K-14" target="t8PL5avYcYxuv0YEq-6K-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-14" value="Env file (config)" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;" vertex="1" parent="t8PL5avYcYxuv0YEq-6K-7">
<mxGeometry x="540" y="90" width="60" height="85" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-8" value="Joplin Application (mobile, desktop, ...)" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="40" y="110" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-9" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="t8PL5avYcYxuv0YEq-6K-8" target="t8PL5avYcYxuv0YEq-6K-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="130" y="270" as="sourcePoint" />
<mxPoint x="310" y="230" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="t8PL5avYcYxuv0YEq-6K-10" value="HTTP REST requests" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="t8PL5avYcYxuv0YEq-6K-9">
<mxGeometry x="0.0435" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -657,6 +657,16 @@ footer .bottom-links-row p {
font-size: 1.1em;
}
.language-switcher {
display: inline;
}
.language-switcher > button {
border: none;
background-color: transparent;
color: #0557ba;
}
/*****************************************************************
WHAT'S NEW PAGE
*****************************************************************/

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,9 @@ function getOs() {
function getFilename(path) {
if (!path) return '';
const s = path.split('/');
return s.pop();
const urlWithParams = s.pop();
const s2 = urlWithParams.split('?');
return s2[0];
}
function getMobileOs() {

View File

@@ -1,4 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Thu, 02 Mar 2023 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Thu, 02 Mar 2023 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin will participate in JdLL 2023!]]></title><description><![CDATA[<p>On 1 and 2 April 2023, we will have a stand for Joplin at the <a href="https://www.jdll.org/">Journées du Logiciel Libre</a> in Lyon, France. The JdLL has been taking place in Lyon for 24 years and is a popular open source conference in France. We had a stand in 2020 and 2021 but that was cancelled due to Covid, so this year is a first for Joplin!</p>
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Mon, 08 May 2023 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 2.10]]></title><description><![CDATA[<p>Great news! Joplin 2.10 is here and we've made some amazing improvements and bug fixes, with a focus on the mobile app.</p>
<h1>New design for &quot;New note&quot; and &quot;New to-do&quot; buttons<a name="new-design-for-new-note-and-new-to-do-buttons" href="#new-design-for-new-note-and-new-to-do-buttons" class="heading-anchor">🔗</a></h1>
<p>We're excited to announce that we've made it even easier to create new notes and to-do lists with new designs for the &quot;New note&quot; and &quot;New to-do&quot; buttons.</p>
<p>If there is enough space, the button labels will be shown in full:</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-new-note-1.png" alt=""></p>
<p>While for those who prefer a more narrow note list, only the button icons will be shown:</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-new-note-2.png" alt=""></p>
<p>It's a small improvement, but we're confident it will make the app even more intuitive for new users.</p>
<h1>Fixes and improvements<a name="fixes-and-improvements" href="#fixes-and-improvements" class="heading-anchor">🔗</a></h1>
<p>This version includes 30 bug fixes and 16 general improvements. Let's dive into some of the highlights:</p>
<ul>
<li>
<p>Self Not Found and Pedro have been working tirelessly on improving the pasting of plain text in the application, and we're happy to say that there is now a brand new &quot;Paste as text&quot; option in the Edit menu.</p>
</li>
<li>
<p>For our amazing plugin developers out there, we have added a few new APIs and fixed a bug that was preventing certain plugins from starting. You can now get even more creative with your plugins!</p>
</li>
<li>
<p>Tao Klerks, has been hard at work fixing and improving the custom sort order of the note list. No more notes in the wrong position when you drop them! Plus, custom sort order is now synchronised too.</p>
</li>
<li>
<p>We've also fixed a few bugs with our Web Clipper, including an issue where certain pages wouldn't import their images. A new Web Clipper has also been released, so you can clip to your heart's content!</p>
</li>
</ul>
<p>Last but not least, we have modernised both the desktop and mobile application modules, just <a href="https://joplinapp.org/news/20221115-renovate/">as we previously announced</a>. Although these changes may not be visible to you, they required a lot of work! But the result is that our applications are now more stable and secure, and it will be easier to maintain them in the long run. We're using a tool called <a href="https://www.mend.io/free-developer-tools/renovate/">Renovate</a>, which will automatically propose package updates that we will review. In total, we've updated a whopping 633 packages so far!</p>
<h1>Android app is available in the Play Store<a name="android-app-is-available-in-the-play-store" href="#android-app-is-available-in-the-play-store" class="heading-anchor">🔗</a></h1>
<p>Our latest version, 2.10, is now back in the Play Store and ready for download! Although we had to skip 2.9 due to some of Google's requirements, we worked hard to ensure that our app complies with their standards, and we are excited to announce that we are back and better than ever! Our iOS version is also available, so you can continue to enjoy the app regardless of the platform you use.</p>
<h2>Biometrics support<a name="biometrics-support" href="#biometrics-support" class="heading-anchor">🔗</a></h2>
<p>To make your experience even more secure, our Android and iOS apps now support biometric unlock! With just a quick scan of your fingerprint or Face ID, you can unlock your app in no time. To enable this beta feature, just head over to the settings and click on &quot;Use biometrics to secure access to the app&quot;.</p>
<p>We've tested this feature thoroughly during prerelease, and have already fixed all known issues. However we still consider it as a beta feature for now, so if you run into any issues please let us know.</p>
<h2>Support for multiple profile<a name="support-for-multiple-profile" href="#support-for-multiple-profile" class="heading-anchor">🔗</a></h2>
<p>We're thrilled to announce that multiple profiles are now supported in our mobile app! To create a new profile, simply go to the Configuration screen and click on &quot;Manage profiles&quot; under the Tools section.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-1.png" alt=""></p>
<p>From there, you can easily add or remove profiles as needed.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-2.png" alt=""></p>
<p>Once multiple profiles are setup, you will see a new option in the sidebar to quickly toggle from one profile to another:</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230508-biometrics-3.png" alt=""></p>
<p>Once you've set up multiple profiles, you can easily toggle between them using the new option in the sidebar. This feature is perfect for separating your personal and work notes into independent collections.</p>
<h2>Support for realtime search<a name="support-for-realtime-search" href="#support-for-realtime-search" class="heading-anchor">🔗</a></h2>
<p>Our mobile app now has an improved search function that performs text searches in real time! No more waiting for the search results to load, they'll appear instantly as you type.</p>
<h2>Improved filesystem sync performance<a name="improved-filesystem-sync-performance" href="#improved-filesystem-sync-performance" class="heading-anchor">🔗</a></h2>
<p>Thanks to the hard work of jd1378, the sync no longer freezes during filesystem synchronisation. We know how frustrating that can be, and we're thrilled to have solved this issue. Getting filesystem sync to work on Android is never easy due to the restrictions put in place by Google, especially since they frequently change, but we're committed to delivering the best possible experience for our Android users.</p>
]]></description><link>https://joplinapp.org/news/20230508-release-2-10/</link><guid isPermaLink="false">20230508-release-2-10</guid><pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate><twitter-text>What&apos;s new in Joplin 2.10</twitter-text></item><item><title><![CDATA[Joplin will participate in JdLL 2023!]]></title><description><![CDATA[<p>On 1 and 2 April 2023, we will have a stand for Joplin at the <a href="https://www.jdll.org/">Journées du Logiciel Libre</a> in Lyon, France. The JdLL has been taking place in Lyon for 24 years and is a popular open source conference in France. We had a stand in 2020 and 2021 but that was cancelled due to Covid, so this year is a first for Joplin!</p>
<p>Admission is free, so don't hesitate to come and meet us, exchange ideas and learn more about Joplin!</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20230202-jdll.jpg" alt="Joplin at JdLL 2023"></p>
]]></description><link>https://joplinapp.org/news/20230302-jdll-2023/</link><guid isPermaLink="false">20230302-jdll-2023</guid><pubDate>Thu, 02 Mar 2023 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Introducing the "GitHub Actions Raw Log Viewer" extension for Chrome]]></title><description><![CDATA[<p>If you've ever used GitHub Actions, you will find that they provide by default a nice coloured output for the log. It looks good and it's even interactive! (You can click to collapse/expand blocks of text) But unfortunately it doesn't scale to large workflows, like we have for Joplin - the log can freeze and it will take forever to search for something. Indeed searching is done in &quot;real time&quot;... which mostly means it will freeze for a minute or two for each letter you type in the search box. Not great.</p>
@@ -271,30 +313,4 @@
<p>- <a href="https://community.letsencrypt.org/t/issues-with-electron-and-expired-root/160991">Issue with Electron and expired root</a> on Let's Encrypt</p>
<p>- <a href="https://github.com/electron/electron/issues/31212">Let's Encrypt root CA isn't working properly</a> on Electron GitHub repository</p>
<p><strong>Update:</strong> I have implemented a temporary fix on Joplin Cloud which should solve the issue for now. If you're still having some issues please let me know. An updated desktop app will be available later on with a more permanent fix.</p>
]]></description><link>https://joplinapp.org/news/20210930-163458/</link><guid isPermaLink="false">20210930-163458</guid><pubDate>Thu, 30 Sep 2021 16:34:58 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.4 is available!]]></title><description><![CDATA[<p>Joplin 2.4 is now available on desktop, mobile and CLI. Here's what's new in this release:</p>
<h3>Sync Wizard Dialog<a name="sync-wizard-dialog" href="#sync-wizard-dialog" class="heading-anchor">🔗</a></h3>
<p>A new Sync Wizard Dialog has been added to simplify setting up sync on new clients.</p>
<p>The dialog shows the main sync targets, their differences, and makes it easy to choose one and start synchronising. This is mostly aimed at new users or those perhaps less technical. Those who are self hosting or using complex setups will still easily find what they need from a link on that dialog (or in Config &gt; Synchronisation like before).</p>
<p>Sync setup on mobile has been slightly improved too - now on a new client, instead of asking you to sync with Dropbox directly (which may not be what you want), it jumps to the Config &gt; Synchronisation section where you can select the sync target</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_0.png" alt=""></p>
<h3>Disable synchronisation<a name="disable-synchronisation" href="#disable-synchronisation" class="heading-anchor">🔗</a></h3>
<p>It's a small change but something that's been asked many time - it's now possible to disable synchronisation entirely by selecting &quot;None&quot; as a sync target. Previously that could be done in a hacky way, by selecting a non-configured sync target. Now it's clearer and easier to do.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_1.png" alt=""></p>
<h3>Add back support for deprecated plugins<a name="add-back-support-for-deprecated-plugins" href="#add-back-support-for-deprecated-plugins" class="heading-anchor">🔗</a></h3>
<p>Recently some plugins stopped working because deprecated plugin APIs had been removed. It had been planned for a long time but I suspect the warnings weren't visible enough so plugin developers didn't act on them, and as a result many plugins stopped working.</p>
<p>This is now fixed in the latest version. A selected number of plugins will have access to these old deprecated APIs, which means they will start working again. This was mainly affecting ambrt's plugins such as &quot;Convert Text To New Note&quot; or the popular &quot;Embed Search&quot; plugin.</p>
<h3>Add support for recommended plugins<a name="add-support-for-recommended-plugins" href="#add-support-for-recommended-plugins" class="heading-anchor">🔗</a></h3>
<p>As mentioned in an earlier post, we now support <a href="https://www.patreon.com/posts/introducing-in-55618802">recommended plugins</a>. These recommended plugins appear on top when searching and are identified by a small crown.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_2.png" alt=""></p>
<h3>End to End Encryption improvements<a name="end-to-end-encryption-improvements" href="#end-to-end-encryption-improvements" class="heading-anchor">🔗</a></h3>
<p>Like most recent releases, v2.4 includes a few improvement to the End to End Encryption (E2EE) system. The goal is to make it easier to use, to make it more reliable and to support the future use case of sharing encrypted notebooks or notes.</p>
<p>One important change is the support for a master password. This single password will be responsible to encrypt various keys, including some that will be automatically generated. Thanks to this, it won't be necessary to ask to enter a new password every time a key needs to be encrypted, since the master password can be used. It will also be easier to manage since you'll only have one password to remember instead of a different one for each notebook you might have shared.</p>
<p>Finally, it's now possible to disable a master key. What it means is that it will no longer show up in the list of master keys, and will also no longer generate a warning asking you to enter the password. In some case you might have forgotten it and no longer need it key, so you can now disable it.</p>
<h3>Custom CSS<a name="custom-css" href="#custom-css" class="heading-anchor">🔗</a></h3>
<p>This version also introduces a few internal change to better support custom CSS. In particular the colours now come from a CSS file, which could potentially be overridden, and new UI elements are styled using stylesheets, which likewise could be overridden.</p>
<p>Those are just first steps, but eventually these changes will make it easier to style the UI and create new themes.</p>
<h3>Bug fixes<a name="bug-fixes" href="#bug-fixes" class="heading-anchor">🔗</a></h3>
<p>This release also includes about 30 various bug fixes and improvements.</p>
<p>A notable one is a fix for GotoAnything, which recently wasn't working on first try.</p>
<p>The plugin screen has also been improved so that search works even when GitHub is down or blocked, as it is in China in particular.</p>
]]></description><link>https://joplinapp.org/news/20210929-144036/</link><guid isPermaLink="false">20210929-144036</guid><pubDate>Wed, 29 Sep 2021 14:40:36 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
]]></description><link>https://joplinapp.org/news/20210930-163458/</link><guid isPermaLink="false">20210930-163458</guid><pubDate>Thu, 30 Sep 2021 16:34:58 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>

View File

@@ -421,7 +421,7 @@
</div>
<script
src="{{jsBaseUrl}}/bootstrap5.0.2.min.js"
src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js"
rel="preload"
as="script"
></script>

View File

@@ -85,6 +85,11 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
{{> footer}}
</div>
<script
src="{{jsBaseUrl}}/bootstrap5.0.2.bundle.min.js"
rel="preload"
as="script"
></script>
<script src="{{{assetUrls.js.script}}}"></script>
{{> analytics}}

View File

@@ -17,6 +17,21 @@
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
<a href="{{forumUrl}}" class="fw500">Forum</a>
<a href="{{baseUrl}}/cn/" class="fw500">中文</a>
<!--
<div class="dropdown language-switcher">
<button class="fw500" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
Language
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
-->
{{#showJoplinCloudLinks}}
{{> joplinCloudButton}}
{{/showJoplinCloudLinks}}

View File

@@ -134,10 +134,16 @@ else
print "The latest version is ${RELEASE_VERSION}, but you have ${CURRENT_VERSION:-no version} installed."
fi
# Check if it's an update or a new install
DOWNLOAD_TYPE="New"
if [[ -f ~/.joplin/Joplin.AppImage ]]; then
DOWNLOAD_TYPE="Update"
fi
#-----------------------------------------------------
print 'Downloading Joplin...'
TEMP_DIR=$(mktemp -d)
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://github.com/laurent22/joplin/releases/download/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage"
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE"
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
#-----------------------------------------------------

View File

@@ -1,5 +1,5 @@
<!-- DONATELINKS -->
[![Donate using PayPal](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=E8JMYD2LQ8MMA&lc=GB&item_name=Joplin+Development&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted) [![Sponsor on GitHub](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/GitHub-Badge.svg)](https://github.com/sponsors/laurent22/) [![Become a patron](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Patreon-Badge.svg)](https://www.patreon.com/joplin) [![Donate using IBAN](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-IBAN.svg)](https://joplinapp.org/donate/#donations)
[![Donate using PayPal](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=E8JMYD2LQ8MMA&no_recurring=0&item_name=I+rely+on+donations+to+maintain+and+improve+the+Joplin+open+source+project.+Thank+you+for+your+help+-+it+makes+a+difference%21&currency_code=EUR) [![Sponsor on GitHub](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/GitHub-Badge.svg)](https://github.com/sponsors/laurent22/) [![Become a patron](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Patreon-Badge.svg)](https://www.patreon.com/joplin) [![Donate using IBAN](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-IBAN.svg)](https://joplinapp.org/donate/#donations)
<!-- DONATELINKS -->
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
@@ -22,11 +22,11 @@ Three types of applications are available: for **desktop** (Windows, macOS and L
Operating System | Download
---|---
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-Setup-2.9.17.exe'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-2.9.17.dmg'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/Joplin-2.9.17.AppImage'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
Windows (32 and 64-bit) | <a href='https://objects.joplinusercontent.com/v2.10.18/Joplin-Setup-2.10.18.exe?source=JoplinWebsite&type=New'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
macOS | <a href='https://objects.joplinusercontent.com/v2.10.18/Joplin-2.10.18.dmg?source=JoplinWebsite&type=New'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
Linux | <a href='https://objects.joplinusercontent.com/v2.10.18/Joplin-2.10.18.AppImage?source=JoplinWebsite&type=New'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/JoplinPortable.exe'>Portable version</a>. 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.
**On Windows**, you may also use the <a href='https://objects.joplinusercontent.com/v2.10.18/JoplinPortable.exe?source=JoplinWebsite&type=New'>Portable version</a>. 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.
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
@@ -36,7 +36,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.9.17/J
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://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.9.8/joplin-v2.9.8-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://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://objects.joplinusercontent.com/android-v2.9.8/joplin-v2.9.8.apk?source=JoplinWebsite&type=New) [32-bit](https://objects.joplinusercontent.com/android-v2.9.8/joplin-v2.9.8-32bit.apk?source=JoplinWebsite&type=New)
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
## Terminal application
@@ -64,7 +64,7 @@ A community maintained list of these distributions can be found here: [Unofficia
# Sponsors
<!-- SPONSORS-ORG -->
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-github&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&amp;mtm_kwd=joplinapp&amp;mtm_source=joplinapp-webseite&amp;mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a> <a href="https://grundstueckspreise.info/"><img title="SP Software GmbH" width="256" src="https://joplinapp.org/images/sponsors/Grundstueckspreise.png"/></a>
<!-- SPONSORS-ORG -->
* * *
@@ -125,9 +125,11 @@ A community maintained list of these distributions can be found here: [Unofficia
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
- [Note history spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
- [Synchronisation spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync.md)
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
- [Overall Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/architecture.md)
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
- [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md)
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
@@ -528,44 +530,44 @@ Current translations:
<!-- LOCALE-TABLE-AUTO-GENERATED -->
&nbsp; | Language | Po File | Last translator | Percent done
---|---|---|---|---
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 80%
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 23%
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 58%
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 79%
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 22%
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 57%
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 45%
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 77%
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | Fejby | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 44%
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Villaverde](mailto:teko.gr@gmail.com) | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Villaverde](mailto:teko.gr@gmail.com) | 98%
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 25%
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 95%
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 29%
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 81%
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 78%
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 79%
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 80%
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 77%
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 78%
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 87%
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 55%
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 91%
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 73%
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 51%
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 90%
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Douglas Leão](mailto:djlsplays@gmail.com) | 87%
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 72%
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 50%
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 80%
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 96%
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 36%
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 78%
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 77%
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 72%
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 88%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Dmitriy Q](mailto:krotesk@mail.ru) | 99%
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 87%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Dmitriy Q](mailto:krotesk@mail.ru) | 98%
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 65%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [wh201906](mailto:wh201906@yandex.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [wh201906](mailto:wh201906@yandex.com) | 96%
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 89%

7
bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,26 +1,52 @@
const gulp = require('gulp');
const utils = require('./packages/tools/gulp/utils');
const execa = require('execa');
const { stdout } = require('process');
const execCommand = async (executableName, args, options = null) => {
options = {
showInput: true,
showStdout: true,
showStderr: true,
quiet: false,
...options,
};
if (options.quiet) {
options.showInput = false;
options.showStdout = false;
options.showStderr = false;
}
if (options.showInput) {
stdout.write(`> ${executableName} ${args.join(' ')}\n`);
}
const promise = execa(executableName, args);
if (options.showStdout && promise.stdout) promise.stdout.pipe(process.stdout);
if (options.showStderr && promise.stderr) promise.stderr.pipe(process.stderr);
const result = await promise;
return result.stdout.trim();
};
const tasks = {
updateIgnoredTypeScriptBuild: require('./packages/tools/gulp/tasks/updateIgnoredTypeScriptBuild'),
buildCommandIndex: require('./packages/tools/gulp/tasks/buildCommandIndex'),
completePublishAll: {
fn: async () => {
await utils.execCommandVerbose('git', ['add', '-A']);
await utils.execCommandVerbose('git', ['commit', '-m', 'Releasing sub-packages']);
await execCommand('git', ['add', '-A']);
await execCommand('git', ['commit', '-m', 'Releasing sub-packages']);
// Lerna does some unnecessary auth check that doesn't work with
// automation tokens, thus the --no-verify-access. Automation token
// is still used for access when publishing even with this flag
// (publishing would fail otherwise).
// https://github.com/lerna/lerna/issues/2788
await utils.execCommandVerbose('lerna', ['publish', 'from-package', '-y', '--no-verify-access']);
await execCommand('lerna', ['publish', 'from-package', '-y', '--no-verify-access']);
await utils.execCommandVerbose('yarn', ['install']);
await utils.execCommandVerbose('git', ['add', '-A']);
await utils.execCommandVerbose('git', ['commit', '-m', 'Lock file']);
await execCommand('yarn', ['install']);
await execCommand('git', ['add', '-A']);
await execCommand('git', ['commit', '-m', 'Lock file']);
await utils.execCommandVerbose('git', ['push']);
await execCommand('git', ['push']);
},
},
build: {
@@ -33,12 +59,14 @@ const tasks = {
// faster, especially when having to rebuild after adding a
// dependency.
if (process.env.BUILD_SEQUENCIAL === '1') {
await utils.execCommandVerbose('yarn', ['run', 'buildSequential']);
await execCommand('yarn', ['run', 'buildSequential']);
} else {
await utils.execCommandVerbose('yarn', ['run', 'buildParallel']);
await execCommand('yarn', ['run', 'buildParallel']);
}
},
},
};
utils.registerGulpTasks(gulp, tasks);
for (const taskName in tasks) {
gulp.task(taskName, tasks[taskName].fn);
}

View File

@@ -15,7 +15,7 @@
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn run tsc",
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn run tsc",
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
"buildCommandIndex": "gulp buildCommandIndex",
"buildCommandIndex": "node packages/tools/gulp/tasks/buildCommandIndexRun.js",
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../joplin-website/docs/api/references/plugin_api packages/lib/services/plugins/api/",
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
"updateNews": "node ./packages/tools/website/updateNews",
@@ -53,7 +53,7 @@
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
"updateIgnored": "gulp updateIgnoredTypeScriptBuild",
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
"watchWebsite": "nodemon --verbose --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
@@ -64,6 +64,7 @@
}
},
"devDependencies": {
"@joplin/utils": "~2.11",
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
"@typescript-eslint/eslint-plugin": "5.48.2",
"@typescript-eslint/parser": "5.48.2",
@@ -74,12 +75,13 @@
"eslint-plugin-jest": "27.2.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.32.0",
"fs-extra": "11.1.0",
"execa": "5.1.1",
"fs-extra": "11.1.1",
"glob": "8.1.0",
"gulp": "4.0.2",
"husky": "3.1.0",
"lerna": "3.22.1",
"lint-staged": "13.1.4",
"lint-staged": "13.2.1",
"madge": "6.0.0",
"npm-package-json-lint": "6.4.0",
"typedoc": "0.17.8",
@@ -89,10 +91,12 @@
"@types/fs-extra": "9.0.13",
"http-server": "14.1.1",
"node-gyp": "9.3.1",
"nodemon": "2.0.21"
"nodemon": "2.0.22"
},
"packageManager": "yarn@3.3.1",
"resolutions": {
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch"
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch",
"react-native-vosk@0.1.12": "patch:react-native-vosk@npm%3A0.1.12#./.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch"
}
}

View File

@@ -35,19 +35,19 @@
],
"owner": "Laurent Cozic"
},
"version": "2.10.3",
"version": "2.11.0",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
},
"dependencies": {
"@joplin/lib": "~2.10",
"@joplin/renderer": "~2.10",
"@joplin/utils": "~2.10",
"aws-sdk": "2.1290.0",
"@joplin/lib": "~2.11",
"@joplin/renderer": "~2.11",
"@joplin/utils": "~2.11",
"aws-sdk": "2.1340.0",
"chalk": "4.1.2",
"compare-version": "0.1.2",
"fs-extra": "11.1.0",
"fs-extra": "11.1.1",
"html-entities": "1.4.0",
"image-type": "3.1.0",
"keytar": "7.9.0",
@@ -57,7 +57,7 @@
"proper-lockfile": "4.1.2",
"read-chunk": "2.1.0",
"server-destroy": "1.0.1",
"sharp": "0.31.3",
"sharp": "0.32.0",
"sprintf-js": "1.1.2",
"sqlite3": "5.1.6",
"string-padding": "1.0.2",
@@ -70,7 +70,7 @@
"yargs-parser": "21.1.1"
},
"devDependencies": {
"@joplin/tools": "~2.10",
"@joplin/tools": "~2.11",
"@types/fs-extra": "9.0.13",
"@types/jest": "29.2.6",
"@types/node": "18.11.18",

View File

@@ -0,0 +1 @@
<div class="jop-noMdConv"><svg class="jop-noMdConv"><style class="jop-noMdConv">&lt;/svg>&lt;iframe srcdoc="&lt;script>top.require('child_process').execSync('calc')&lt;/script>">&lt;/iframe>&lt;/div>

View File

@@ -0,0 +1 @@
<div><svg><style></svg><iframe srcdoc="<script>top.require('child_process').execSync('calc')</script>"></iframe></div>

View File

@@ -0,0 +1 @@
<a href="#" class="jop-noMdConv">XSS</a>

View File

@@ -0,0 +1 @@
<a data-from-md="" href="javascript:top.require('child_process').execSync('open -a Calculator')">XSS</a>

View File

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

View File

@@ -126,4 +126,4 @@
"react-app"
]
}
}
}

View File

@@ -68,6 +68,10 @@ export class Bridge {
return process.argv;
}
public getLocale = () => {
return this.electronApp().electronApp().getLocale();
};
// Applies to electron-context-menu@3:
//
// For now we have to disable spell checking in non-editor text

View File

@@ -97,7 +97,8 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
}
if (found) {
downloadUrl = asset.browser_download_url;
downloadUrl = asset.browser_download_url.replace('github.com/laurent22/joplin/releases/download', 'objects.joplinusercontent.com');
downloadUrl.concat('?source=DesktopApp&type=Update');
break;
}
}

View File

@@ -21,7 +21,7 @@ import checkForUpdates from '../checkForUpdates';
const { connect } = require('react-redux');
import { reg } from '@joplin/lib/registry';
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
import PluginService from '@joplin/lib/services/plugins/PluginService';
import PluginService, { PluginSettings } from '@joplin/lib/services/plugins/PluginService';
const packageInfo = require('../packageInfo.js');
const { clipboard } = require('electron');
const Menu = bridge().Menu;
@@ -128,6 +128,7 @@ interface Props {
customCss: string;
locale: string;
profileConfig: ProfileConfig;
pluginSettings: PluginSettings;
}
const commandNames: string[] = menuCommandNames();
@@ -487,7 +488,7 @@ function useMenu(props: Props) {
}
function _showAbout() {
const v = versionInfo(packageInfo, PluginService.instance().plugins);
const v = versionInfo(packageInfo, PluginService.instance().enabledPlugins(props.pluginSettings));
const copyToClipboard = bridge().showMessageBox(v.message, {
icon: `${bridge().electronApp().buildDir()}/icons/128x128.png`,
@@ -930,6 +931,7 @@ function useMenu(props: Props) {
props['spellChecker.languages'],
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
props['spellChecker.enabled'],
props.pluginSettings,
props.customCss,
props.locale,
props.profileConfig,
@@ -985,6 +987,7 @@ const mapStateToProps = (state: AppState) => {
['folders.sortOrder.field']: state.settings['folders.sortOrder.field'],
['notes.sortOrder.reverse']: state.settings['notes.sortOrder.reverse'],
['folders.sortOrder.reverse']: state.settings['folders.sortOrder.reverse'],
pluginSettings: state.settings['plugins.states'],
showNoteCounts: state.settings.showNoteCounts,
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
showCompletedTodos: state.settings.showCompletedTodos,

View File

@@ -631,7 +631,7 @@ const mapStateToProps = (state: AppState) => {
], whenClauseContext)[0],
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
isSafeMode: state.settings.isSafeMode,
useCustomPdfViewer: state.settings.useCustomPdfViewer,
useCustomPdfViewer: false, // state.settings.useCustomPdfViewer,
};
};

View File

@@ -3,6 +3,7 @@ import { useCallback, useMemo } from 'react';
import { ResourceInfos } from './types';
import markupLanguageUtils from '../../../utils/markupLanguageUtils';
import Setting from '@joplin/lib/models/Setting';
import shim from '@joplin/lib/shim';
const { themeStyle } = require('@joplin/lib/theme');
import Note from '@joplin/lib/models/Note';
@@ -23,6 +24,7 @@ export interface MarkupToHtmlOptions {
useCustomPdfViewer?: boolean;
noteId?: string;
vendorDir?: string;
platformName?: string;
}
export default function useMarkupToHtml(deps: HookDependencies) {
@@ -40,6 +42,7 @@ export default function useMarkupToHtml(deps: HookDependencies) {
options = {
replaceResourceInternalToExternalLinks: false,
resourceInfos: {},
platformName: shim.platformName(),
...options,
};

View File

@@ -26,11 +26,15 @@ export default class PromptDialog extends React.Component<Props, any> {
private focusInput_: boolean;
private styles_: any;
private styleKey_: string;
private menuIsOpened_: boolean = false;
public constructor(props: Props) {
super(props);
this.answerInput_ = React.createRef();
this.select_menuOpen = this.select_menuOpen.bind(this);
this.select_menuClose = this.select_menuClose.bind(this);
}
public UNSAFE_componentWillMount() {
@@ -39,6 +43,7 @@ export default class PromptDialog extends React.Component<Props, any> {
answer: this.props.defaultValue ? this.props.defaultValue : '',
});
this.focusInput_ = true;
this.menuIsOpened_ = false;
}
public UNSAFE_componentWillReceiveProps(newProps: Props) {
@@ -52,6 +57,14 @@ export default class PromptDialog extends React.Component<Props, any> {
}
}
private select_menuOpen() {
this.menuIsOpened_ = true;
}
private select_menuClose() {
this.menuIsOpened_ = false;
}
public componentDidUpdate() {
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
this.focusInput_ = false;
@@ -224,16 +237,14 @@ export default class PromptDialog extends React.Component<Props, any> {
const onKeyDown = (event: any) => {
if (event.key === 'Enter') {
if (this.props.inputType === 'tags' || this.props.inputType === 'dropdown') {
// If the dropdown is open, we don't close the dialog - instead
// the currently item will be selcted. If it is closed however
// we confirm the dialog.
if ((this.props.inputType === 'tags' || this.props.inputType === 'dropdown') && this.menuIsOpened_) {
// Do nothing
} else {
onClose(true);
}
// } else if (this.answerInput_.current && !this.answerInput_.current.state.menuIsOpen) {
// // The menu will be open if the user is selecting a new item
// onClose(true);
// }
} else if (event.key === 'Escape') {
onClose(false);
}
@@ -246,9 +257,9 @@ export default class PromptDialog extends React.Component<Props, any> {
if (this.props.inputType === 'datetime') {
inputComp = <Datetime className="datetime-picker" value={this.state.answer} inputProps={{ style: styles.input }} dateFormat={time.dateFormat()} timeFormat={time.timeFormat()} onChange={(momentObject: any) => onDateTimeChange(momentObject)} />;
} else if (this.props.inputType === 'tags') {
inputComp = <CreatableSelect className="tag-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
inputComp = <CreatableSelect className="tag-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
} else if (this.props.inputType === 'dropdown') {
inputComp = <Select className="item-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
inputComp = <Select className="item-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
} else {
inputComp = <input style={styles.input} ref={this.answerInput_} value={this.state.answer} type="text" onChange={event => onChange(event)} onKeyDown={event => onKeyDown(event)} />;
}

View File

@@ -27,7 +27,7 @@ import StyleSheetContainer from './StyleSheets/StyleSheetContainer';
import ImportScreen from './ImportScreen';
const { ResourceScreen } = require('./ResourceScreen.js');
import Navigator from './Navigator';
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
import WelcomeUtils from '@joplin/lib/WelcomeUtils';
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
const bridge = require('@electron/remote').require('./bridge').default;
@@ -141,7 +141,7 @@ class RootComponent extends React.Component<Props, any> {
});
}
await WelcomeUtils.install(this.props.dispatch);
await WelcomeUtils.install(Setting.value('locale'), this.props.dispatch);
}
private renderModalMessage(props: ModalDialogProps) {

View File

@@ -48,6 +48,15 @@ const StyledFoldersHolder = styled.div`
}}
}
`;
const TagsHolder = styled.div`
// linux bug: https://github.com/laurent22/joplin/issues/8000
// solution ref: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
& a.list-item {
${shim.isLinux() && {
opacity: 1,
}}
}
`;
interface Props {
themeId: number;
@@ -738,9 +747,9 @@ const SidebarComponent = (props: Props) => {
tagItemsOrder_.current = result.order;
items.push(
<div className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
<TagsHolder className="tags" key="tag_items" style={{ display: props.tagHeaderIsExpanded ? 'block' : 'none' }}>
{tagItems}
</div>
</TagsHolder>
);
}

View File

@@ -56,6 +56,19 @@ if (typeof module !== 'undefined') {
const markJsUtils = {};
const isInsideContainer = (node, tagName) => {
if (!node) return false;
tagName = tagName.toLowerCase();
while (node) {
if (node.tagName && node.tagName.toLowerCase() === tagName) return true;
node = node.parentNode;
}
return false;
};
markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
if (typeof keyword === 'string') {
keyword = {
@@ -71,12 +84,13 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
if (isBasicSearch) accuracy = 'partially';
if (keyword.type === 'regex') {
accuracy = 'complementary';
// Remove the trailing wildcard and "accuracy = complementary" will take care of
// highlighting the relevant keywords.
// Remove the trailing wildcard and "accuracy = complementary" will take
// care of highlighting the relevant keywords.
// Known bug: it will also highlight word that contain the term as a suffix for example for "ent*", it will highlight "present"
// which is incorrect (it should only highlight what starts with "ent") but for now will do. Mark.js doesn't have an option
// to tweak this behaviour.
// Known bug: it will also highlight word that contain the term as a
// suffix for example for "ent*", it will highlight "present" which is
// incorrect (it should only highlight what starts with "ent") but for
// now will do. Mark.js doesn't have an option to tweak this behaviour.
value = keyword.value.substr(0, keyword.value.length - 1);
}
@@ -86,6 +100,18 @@ markJsUtils.markKeyword = (mark, keyword, stringUtils, extraOptions = null) => {
{},
{
accuracy: accuracy,
filter: (node, _term, _totalCounter, _counter) => {
// We exclude SVG because it creates a "<mark>" tag inside
// the document, which is not a valid SVG tag. As a result
// the content within that tag disappears.
//
// mark.js has an "exclude" parameter, but it doesn't work
// so we use "filter" instead.
//
// https://github.com/joplin/plugin-abc-sheet-music
if (isInsideContainer(node, 'SVG')) return false;
return true;
},
},
extraOptions
)

View File

@@ -1,6 +1,6 @@
{
"name": "@joplin/app-desktop",
"version": "2.10.12",
"version": "2.11.2",
"description": "Joplin for Desktop",
"main": "main.js",
"private": true,
@@ -12,7 +12,7 @@
"electronRebuild": "gulp electronRebuild",
"tsc": "tsc --project tsconfig.json",
"watch": "tsc --watch --preserveWatchOutput --project tsconfig.json",
"start": "gulp build && electron . --env dev --log-level debug --no-welcome --open-dev-tools",
"start": "gulp build && electron . --env dev --log-level debug --open-dev-tools",
"test": "jest",
"test-ci": "yarn test"
},
@@ -27,6 +27,7 @@
},
"build": {
"appId": "net.cozic.joplin-desktop",
"compression": "maximum",
"productName": "Joplin",
"npmRebuild": false,
"afterSign": "./tools/notarizeMacApp.js",
@@ -107,7 +108,7 @@
},
"homepage": "https://github.com/laurent22/joplin#readme",
"devDependencies": {
"@joplin/tools": "~2.10",
"@joplin/tools": "~2.11",
"@testing-library/react-hooks": "8.0.1",
"@types/jest": "29.2.6",
"@types/node": "18.11.18",
@@ -115,7 +116,7 @@
"@types/react-redux": "7.1.25",
"@types/styled-components": "5.1.26",
"electron": "19.1.4",
"electron-builder": "23.6.0",
"electron-builder": "22.11.7",
"electron-notarize": "1.2.2",
"electron-rebuild": "3.2.9",
"glob": "8.1.0",
@@ -136,9 +137,8 @@
"@electron/remote": "2.0.9",
"@fortawesome/fontawesome-free": "5.15.4",
"@joeattardi/emoji-button": "4.6.4",
"@joplin/lib": "~2.10",
"@joplin/pdf-viewer": "~2.10",
"@joplin/renderer": "~2.10",
"@joplin/lib": "~2.11",
"@joplin/renderer": "~2.11",
"async-mutex": "0.4.0",
"codemirror": "5.65.9",
"color": "3.2.1",
@@ -147,7 +147,7 @@
"debounce": "1.2.1",
"electron-window-state": "5.0.3",
"formatcoords": "1.1.3",
"fs-extra": "11.1.0",
"fs-extra": "11.1.1",
"highlight.js": "11.7.0",
"immer": "7.0.15",
"keytar": "7.9.0",
@@ -163,15 +163,15 @@
"react-datetime": "3.2.0",
"react-dom": "18.2.0",
"react-redux": "8.0.5",
"react-select": "5.7.0",
"react-select": "5.7.2",
"react-toggle-button": "2.2.0",
"react-tooltip": "4.5.1",
"redux": "4.2.1",
"reselect": "4.1.7",
"reselect": "4.1.8",
"roboto-fontface": "0.10.0",
"smalltalk": "2.5.1",
"sqlite3": "5.1.6",
"styled-components": "5.3.9",
"styled-components": "5.3.10",
"styled-system": "5.1.5",
"taboverride": "4.0.3",
"tinymce": "5.10.6"

View File

@@ -72,10 +72,10 @@ async function main() {
src: langSourceDir,
dest: `${buildLibDir}/tinymce/langs`,
},
{
src: resolve(__dirname, '../../pdf-viewer/dist'),
dest: `${buildLibDir}/@joplin/pdf-viewer`,
},
// {
// src: resolve(__dirname, '../../pdf-viewer/dist'),
// dest: `${buildLibDir}/@joplin/pdf-viewer`,
// },
];
const files = [
@@ -93,10 +93,10 @@ async function main() {
src: resolve(__dirname, '../../lib/services/plugins/sandboxProxy.js'),
dest: `${buildLibDir}/@joplin/lib/services/plugins/sandboxProxy.js`,
},
{
src: resolve(__dirname, '../../pdf-viewer/index.html'),
dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
},
// {
// src: resolve(__dirname, '../../pdf-viewer/index.html'),
// dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
// },
];
// First we delete all the destination directories, then we copy the files.

View File

@@ -72,3 +72,4 @@ components/NoteEditor/CodeMirror/CodeMirror.bundle.min.js
components/NoteEditor/**/*.bundle.js.md5
utils/fs-driver-android.js
android/app/build-*

View File

@@ -79,6 +79,12 @@ import org.apache.tools.ant.taskdefs.condition.Os
*/
project.ext.react = [
// 2023-05-09: This seems to be optional, but it's not. Without it, the app
// will crash on certain devices with this error:
//
// > java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libhermes.so"
//
// https://github.com/laurent22/joplin/issues/8144#issuecomment-1539629812
enableHermes: true, // clean and rebuild if changing
]
@@ -150,8 +156,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2097685
versionName "2.10.9"
versionCode 2097706
versionName "2.11.21"
// ndk {
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
// }
@@ -298,8 +304,11 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
// implementation "com.facebook.react:react-native:+" // From node_modules
implementation ("com.facebook.react:react-native") version {
strictly "0.70.6" // pass in your react-native version
}
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {

View File

@@ -0,0 +1,7 @@
French small model for Vosk
WER
%WER 23.95 [ 37203 / 155330, 5373 ins, 4427 del, 27403 sub ] exp/chain_a/tdnn/decode_test_cv/wer_12_0.0
%WER 19.30 [ 2975 / 15412, 683 ins, 672 del, 1620 sub ] exp/chain_a/tdnn/decode_test_mtedx/wer_10_0.0
%WER 27.25 [ 20208 / 74145, 2647 ins, 5852 del, 11709 sub ] exp/chain_a/tdnn/decode_test_podcast_reseg/wer_10_0.0

View File

@@ -0,0 +1,8 @@
--use-energy=false
--sample-frequency=16000
--num-mel-bins=40
--num-ceps=40
--low-freq=40
--high-freq=-200
--allow-upsample=true
--allow-downsample=true

View File

@@ -0,0 +1,10 @@
--min-active=200
--max-active=7000
--beam=13.0
--lattice-beam=4.0
--acoustic-scale=1.0
--frame-subsampling-factor=3
--endpoint.silence-phones=1:2:3:4:5:6:7:8:9:10
--endpoint.rule2.min-trailing-silence=0.5
--endpoint.rule3.min-trailing-silence=1.0
--endpoint.rule4.min-trailing-silence=2.0

View File

@@ -0,0 +1,76 @@
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440

View File

@@ -0,0 +1,154 @@
1 nonword
2 begin
3 end
4 internal
5 singleton
6 nonword
7 begin
8 end
9 internal
10 singleton
11 begin
12 end
13 internal
14 singleton
15 begin
16 end
17 internal
18 singleton
19 begin
20 end
21 internal
22 singleton
23 begin
24 end
25 internal
26 singleton
27 begin
28 end
29 internal
30 singleton
31 begin
32 end
33 internal
34 singleton
35 begin
36 end
37 internal
38 singleton
39 begin
40 end
41 internal
42 singleton
43 begin
44 end
45 internal
46 singleton
47 begin
48 end
49 internal
50 singleton
51 begin
52 end
53 internal
54 singleton
55 begin
56 end
57 internal
58 singleton
59 begin
60 end
61 internal
62 singleton
63 begin
64 end
65 internal
66 singleton
67 begin
68 end
69 internal
70 singleton
71 begin
72 end
73 internal
74 singleton
75 begin
76 end
77 internal
78 singleton
79 begin
80 end
81 internal
82 singleton
83 begin
84 end
85 internal
86 singleton
87 begin
88 end
89 internal
90 singleton
91 begin
92 end
93 internal
94 singleton
95 begin
96 end
97 internal
98 singleton
99 begin
100 end
101 internal
102 singleton
103 begin
104 end
105 internal
106 singleton
107 begin
108 end
109 internal
110 singleton
111 begin
112 end
113 internal
114 singleton
115 begin
116 end
117 internal
118 singleton
119 begin
120 end
121 internal
122 singleton
123 begin
124 end
125 internal
126 singleton
127 begin
128 end
129 internal
130 singleton
131 begin
132 end
133 internal
134 singleton
135 begin
136 end
137 internal
138 singleton
139 begin
140 end
141 internal
142 singleton
143 begin
144 end
145 internal
146 singleton
147 begin
148 end
149 internal
150 singleton
151 begin
152 end
153 internal
154 singleton

View File

@@ -0,0 +1,3 @@
[
1.022245e+11 -6.33291e+09 -2.480997e+09 8.290258e+09 -9.084483e+09 -8.092173e+09 -1.4735e+10 -7.041795e+09 -1.171205e+10 -2.976464e+08 -1.009425e+10 -6765179 -7.821326e+09 1.449499e+09 -6.413975e+09 -5.303802e+08 -4.998635e+09 9.521598e+07 -3.073041e+09 1.56756e+08 -1.287956e+09 1.738752e+08 -2.382392e+08 -2.716675e+07 4.404485e+08 -1.913359e+08 7.780919e+08 -4.006922e+08 7.895809e+08 -5.401082e+08 5.17605e+08 -6.227134e+08 6.58271e+08 -6.204593e+07 5.187754e+08 -4.497048e+08 4.219366e+07 -2.78742e+08 -1.797385e+07 -3.604475e+07 1.053647e+09
1.040194e+13 6.245521e+11 4.223293e+11 6.831219e+11 6.078478e+11 6.3425e+11 7.943839e+11 6.013323e+11 6.781652e+11 5.272091e+11 5.810814e+11 4.353831e+11 4.473305e+11 3.42063e+11 3.083377e+11 2.14257e+11 1.892057e+11 1.163827e+11 8.367058e+10 4.203224e+10 2.297476e+10 7.596307e+09 1.099877e+09 2.886651e+08 3.797438e+09 9.372847e+09 1.629059e+10 2.196351e+10 2.747149e+10 3.072878e+10 3.238528e+10 3.330232e+10 3.407238e+10 3.230687e+10 2.676914e+10 2.252055e+10 1.914305e+10 1.565974e+10 1.224627e+10 8.415393e+09 0 ]

View File

@@ -0,0 +1,2 @@
--left-context=3
--right-context=3

View File

@@ -0,0 +1 @@
1b7180e6-e500-4818-adc8-a41fe97a84ce

View File

@@ -3,8 +3,11 @@ import shim from '@joplin/lib/shim';
import Setting from '@joplin/lib/models/Setting';
const { themeStyle } = require('../../global-style.js');
import markupLanguageUtils from '@joplin/lib/markupLanguageUtils';
import Logger from '@joplin/lib/Logger';
const { assetsToHeaders } = require('@joplin/renderer');
const logger = Logger.create('NoteBodyViewer/useSource');
interface UseSourceResult {
// [html] can be null if the note is still being rendered.
html: string|null;
@@ -19,6 +22,23 @@ function usePrevious(value: any, initialValue: any = null): any {
return ref.current;
}
const onlyCheckboxHasChangedHack = (previousBody: string, newBody: string) => {
if (previousBody.length !== newBody.length) return false;
for (let i = 0; i < previousBody.length; i++) {
const c1 = previousBody.charAt(i);
const c2 = newBody.charAt(i);
if (c1 !== c2) {
if (c1 === ' ' && (c2 === 'x' || c2 === 'X')) continue;
if (c2 === ' ' && (c1 === 'x' || c1 === 'X')) continue;
return false;
}
}
return true;
};
export default function useSource(noteBody: string, noteMarkupLanguage: number, themeId: number, highlightedKeywords: string[], noteResources: any, paddingBottom: number, noteHash: string): UseSourceResult {
const [html, setHtml] = useState<string>('');
const [injectedJs, setInjectedJs] = useState<string[]>([]);
@@ -42,14 +62,20 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
// To address https://github.com/laurent22/joplin/issues/433
//
// If a checkbox in a note is ticked, the body changes, which normally
// would trigger a re-render of this component, which has the
// unfortunate side effect of making the view scroll back to the top.
// This re-rendering however is uncessary since the component is
// already visually updated via JS. So here, if the note has not
// changed, we prevent the component from updating. This fixes the
// above issue. A drawback of this is if the note is updated via sync,
// this change will not be displayed immediately.
// If a checkbox in a note is ticked, the body changes, which normally would
// trigger a re-render of this component, which has the unfortunate side
// effect of making the view scroll back to the top. This re-rendering
// however is uncessary since the component is already visually updated via
// JS. So here, if the note has not changed, we prevent the component from
// updating. This fixes the above issue. A drawback of this is if the note
// is updated via sync, this change will not be displayed immediately.
//
// 2022-05-03: However we sometimes need the HTML to be updated, even when
// only the body has changed - for example when attaching a resource, or
// when adding text via speech recognition. So the logic has been narrowed
// down so that updates are skipped only when checkbox has been changed.
// Checkboxes still work as expected, without making the note scroll, and
// other text added to the note is displayed correctly.
//
// IMPORTANT: KEEP noteBody AS THE FIRST dependency in the array as the
// below logic rely on this.
@@ -62,9 +88,13 @@ export default function useSource(noteBody: string, noteMarkupLanguage: number,
return accum;
}, {});
const onlyNoteBodyHasChanged = Object.keys(changedDeps).length === 1 && changedDeps[0];
const onlyCheckboxesHaveChanged = previousDeps[0] && changedDeps[0] && onlyCheckboxHasChangedHack(previousDeps[0], noteBody);
useEffect(() => {
if (onlyNoteBodyHasChanged) return () => {};
if (onlyNoteBodyHasChanged && onlyCheckboxesHaveChanged) {
logger.info('Only a checkbox has changed - not updating HTML');
return () => {};
}
let cancelled = false;

View File

@@ -2,6 +2,7 @@
* @jest-environment jsdom
*/
import { EditorSettings } from '../types';
import { initCodeMirror } from './CodeMirror';
import { themeStyle } from '@joplin/lib/theme';
@@ -9,6 +10,8 @@ import Setting from '@joplin/lib/models/Setting';
import { forceParsing } from '@codemirror/language';
import loadLangauges from './testUtil/loadLanguages';
import { expect, describe, it } from '@jest/globals';
const createEditorSettings = (themeId: number) => {
const themeData = themeStyle(themeId);
@@ -23,6 +26,14 @@ const createEditorSettings = (themeId: number) => {
};
describe('CodeMirror', () => {
// This checks for a regression -- occasionally, when updating packages,
// syntax highlighting in the CodeMirror editor stops working. This is usually
// fixed by
// 1. removing all `@codemirror/` and `@lezer/` dependencies from yarn.lock,
// 2. upgrading all CodeMirror packages to the latest versions in package.json, and
// 3. re-running `yarn install`.
//
// See https://github.com/laurent22/joplin/issues/7253
it('should give headings a different style', async () => {
const headerLineText = '# Testing...';
const initialText = `${headerLineText}\nThis is a test.`;

View File

@@ -1,15 +1,32 @@
const React = require('react');
const Component = React.Component;
const { connect } = require('react-redux');
const { FlatList, Text, StyleSheet, Button, View } = require('react-native');
import { Component } from 'react';
import { connect } from 'react-redux';
import { FlatList, Text, StyleSheet, Button, View } from 'react-native';
import { FolderEntity, NoteEntity } from '@joplin/lib/services/database/types';
import { AppState } from '../utils/types';
const { _ } = require('@joplin/lib/locale');
const { NoteItem } = require('./note-item.js');
const time = require('@joplin/lib/time').default;
const { themeStyle } = require('./global-style.js');
class NoteListComponent extends Component {
constructor() {
super();
interface NoteListProps {
themeId: string;
dispatch: (action: any)=> void;
notesSource: string;
items: NoteEntity[];
folders: FolderEntity[];
noteSelectionEnabled?: boolean;
selectedFolderId?: string;
}
class NoteListComponent extends Component<NoteListProps> {
private rootRef_: FlatList;
private styles_: Record<string, StyleSheet.NamedStyles<any>>;
public constructor(props: NoteListProps) {
super(props);
this.state = {
items: [],
@@ -21,7 +38,7 @@ class NoteListComponent extends Component {
this.createNotebookButton_click = this.createNotebookButton_click.bind(this);
}
styles() {
private styles() {
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
@@ -47,7 +64,7 @@ class NoteListComponent extends Component {
return this.styles_[themeId];
}
createNotebookButton_click() {
private createNotebookButton_click() {
this.props.dispatch({
type: 'NAV_GO',
routeName: 'Folder',
@@ -55,34 +72,14 @@ class NoteListComponent extends Component {
});
}
filterNotes(notes) {
const todoFilter = 'all'; // Setting.value('todoFilter');
if (todoFilter === 'all') return notes;
const now = time.unixMs();
const maxInterval = 1000 * 60 * 60 * 24;
const notRecentTime = now - maxInterval;
const output = [];
for (let i = 0; i < notes.length; i++) {
const note = notes[i];
if (note.is_todo) {
if (todoFilter === 'recent' && note.user_updated_time < notRecentTime && !!note.todo_completed) continue;
if (todoFilter === 'nonCompleted' && !!note.todo_completed) continue;
}
output.push(note);
}
return output;
}
UNSAFE_componentWillReceiveProps(newProps) {
public UNSAFE_componentWillReceiveProps(newProps: NoteListProps) {
// Make sure scroll position is reset when switching from one folder to another or to a tag list.
if (this.rootRef_ && newProps.notesSource !== this.props.notesSource) {
this.rootRef_.scrollToOffset({ offset: 0, animated: false });
}
}
render() {
public render() {
// `enableEmptySections` is to fix this warning: https://github.com/FaridSafi/react-native-gifted-listview/issues/39
if (this.props.items.length) {
@@ -109,7 +106,7 @@ class NoteListComponent extends Component {
}
}
const NoteList = connect(state => {
const NoteList = connect((state: AppState) => {
return {
items: state.notes,
folders: state.folders,
@@ -119,4 +116,4 @@ const NoteList = connect(state => {
};
})(NoteListComponent);
module.exports = { NoteList };
export default NoteList;

View File

@@ -2,9 +2,12 @@ const React = require('react');
import Setting from '@joplin/lib/models/Setting';
import { useEffect, useMemo, useState } from 'react';
import { View, Dimensions, Alert, Button } from 'react-native';
import FingerprintScanner from 'react-native-fingerprint-scanner';
import { SensorInfo } from './sensorInfo';
import { _ } from '@joplin/lib/locale';
import Logger from '@joplin/lib/Logger';
import biometricAuthenticate from './biometricAuthenticate';
const logger = Logger.create('BiometricPopup');
interface Props {
themeId: number;
@@ -18,23 +21,31 @@ export default (props: Props) => {
// doesn't work properly, we disable it. We only want the user to enable the
// feature after they've read the description in the config screen.
const [initialPromptDone, setInitialPromptDone] = useState(true); // useState(Setting.value('security.biometricsInitialPromptDone'));
const [display, setDisplay] = useState(!!props.sensorInfo.supportedSensors && (props.sensorInfo.enabled || !initialPromptDone));
const [display, setDisplay] = useState(props.sensorInfo.enabled || !initialPromptDone);
const [tryBiometricsCheck, setTryBiometricsCheck] = useState(initialPromptDone);
logger.info('Render start');
logger.info('initialPromptDone', initialPromptDone);
logger.info('display', display);
logger.info('tryBiometricsCheck', tryBiometricsCheck);
logger.info('props.sensorInfo', props.sensorInfo);
useEffect(() => {
if (!display || !tryBiometricsCheck) return;
const biometricsCheck = async () => {
logger.info('biometricsCheck: start');
try {
await FingerprintScanner.authenticate({ description: _('Verify your identity') });
setTryBiometricsCheck(false);
await biometricAuthenticate();
setDisplay(false);
} catch (error) {
Alert.alert(_('Could not verify your identify'), error.message);
setTryBiometricsCheck(false);
} finally {
FingerprintScanner.release();
Alert.alert(error.message);
}
setTryBiometricsCheck(false);
logger.info('biometricsCheck: end');
};
void biometricsCheck();
@@ -45,6 +56,9 @@ export default (props: Props) => {
if (!display) return;
const complete = (enableBiometrics: boolean) => {
logger.info('complete: start');
logger.info('complete: enableBiometrics:', enableBiometrics);
setInitialPromptDone(true);
Setting.setValue('security.biometricsInitialPromptDone', true);
Setting.setValue('security.biometricsEnabled', enableBiometrics);
@@ -59,6 +73,8 @@ export default (props: Props) => {
type: 'BIOMETRICS_DONE_SET',
value: true,
});
logger.info('complete: end');
};
Alert.alert(
@@ -77,7 +93,7 @@ export default (props: Props) => {
},
]
);
}, [initialPromptDone, props.sensorInfo.supportedSensors, display, props.dispatch]);
}, [initialPromptDone, display, props.dispatch]);
const windowSize = useMemo(() => {
return {
@@ -87,12 +103,18 @@ export default (props: Props) => {
}, []);
useEffect(() => {
logger.info('effect 1: start');
if (!display) {
logger.info('effect 1: display', display);
props.dispatch({
type: 'BIOMETRICS_DONE_SET',
value: true,
});
}
logger.info('effect 1: end');
}, [display, props.dispatch]);
const renderTryAgainButton = () => {

View File

@@ -0,0 +1,28 @@
import Logger from '@joplin/lib/Logger';
import FingerprintScanner, { Errors } from 'react-native-fingerprint-scanner';
import { _ } from '@joplin/lib/locale';
const logger = Logger.create('biometricAuthenticate');
export default async () => {
try {
logger.info('Authenticate...');
await FingerprintScanner.authenticate({ description: _('Verify your identity') });
logger.info('Authenticate done');
} catch (error) {
const errorName = (error as Errors).name;
let errorMessage = error.message;
if (errorName === 'FingerprintScannerNotEnrolled' || errorName === 'FingerprintScannerNotAvailable') {
errorMessage = _('Biometric unlock is not setup on the device. Please set it up in order to unlock Joplin. If the device is on lockout, consider switching it off and on to reset biometrics scanning.');
}
error.message = _('Could not verify your identify: %s', errorMessage);
logger.warn(error);
throw error;
} finally {
FingerprintScanner.release();
}
};

View File

@@ -1,5 +1,7 @@
import Logger from '@joplin/lib/Logger';
import Setting from '@joplin/lib/models/Setting';
import FingerprintScanner from 'react-native-fingerprint-scanner';
const logger = Logger.create('sensorInfo');
export interface SensorInfo {
enabled: boolean;
@@ -12,6 +14,9 @@ export default async (): Promise<SensorInfo> => {
// FingerprintScanner scanner calls, since it seems they can fail and freeze
// the app.
logger.info('Start');
logger.info('security.biometricsEnabled', Setting.value('security.biometricsEnabled'));
if (!Setting.value('security.biometricsEnabled')) {
return {
enabled: false,
@@ -24,7 +29,21 @@ export default async (): Promise<SensorInfo> => {
let supportedSensors = '';
try {
logger.info('Getting isSensorAvailable...');
// Note: If `isSensorAvailable()` doesn't return anything, it seems we
// could assume that biometrics are not setup on the device, and thus we
// can unlock the app. However that's not always correct - on some
// devices (eg Galaxy S22), `isSensorAvailable()` will return nothing if
// the device is on lockout - i.e. if the user gave the wrong
// fingerprint multiple times.
//
// So we definitely can't unlock the app in that case, and it means
// `isSensorAvailable()` is pretty much useless. Instead we ask for
// fingerprint when the user turns on the feature and at that point we
// know if the device supports biometrics or not.
const result = await FingerprintScanner.isSensorAvailable();
logger.info('isSensorAvailable result', result);
supportedSensors = result;
if (result) {
@@ -34,7 +53,7 @@ export default async (): Promise<SensorInfo> => {
}
}
} catch (error) {
console.warn('Could not check for biometrics sensor:', error);
logger.warn('Could not check for biometrics sensor:', error);
Setting.setValue('security.biometricsSupportedSensors', '');
}

View File

@@ -23,6 +23,7 @@ const { themeStyle } = require('../global-style.js');
const shared = require('@joplin/lib/components/shared/config-shared.js');
import SyncTargetRegistry from '@joplin/lib/SyncTargetRegistry';
import { openDocumentTree } from '@joplin/react-native-saf-x';
import biometricAuthenticate from '../biometrics/biometricAuthenticate';
class ConfigScreenComponent extends BaseScreenComponent {
public static navigationOptions(): any {
@@ -463,7 +464,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
<Text key="label" style={this.styles().switchSettingText}>
{label}
</Text>
<Switch key="control" style={this.styles().switchSettingControl} trackColor={{ false: theme.dividerColor }} value={value} onValueChange={(value: any) => updateSettingValue(key, value)} />
<Switch key="control" style={this.styles().switchSettingControl} trackColor={{ false: theme.dividerColor }} value={value} onValueChange={(value: any) => void updateSettingValue(key, value)} />
</View>
{descriptionComp}
</View>
@@ -474,13 +475,39 @@ class ConfigScreenComponent extends BaseScreenComponent {
return !hasDescription ? this.styles().settingContainer : this.styles().settingContainerNoBottomBorder;
}
private async handleSetting(key: string, value: any): Promise<boolean> {
// When the user tries to enable biometrics unlock, we ask for the
// fingerprint or Face ID, and if it's correct we save immediately. If
// it's not, we don't turn on the setting.
if (key === 'security.biometricsEnabled' && !!value) {
try {
await biometricAuthenticate();
shared.updateSettingValue(this, key, value);
await this.saveButton_press();
} catch (error) {
shared.updateSettingValue(this, key, false);
Alert.alert(error.message);
}
return true;
}
if (key === 'security.biometricsEnabled' && !value) {
shared.updateSettingValue(this, key, value);
await this.saveButton_press();
return true;
}
return false;
}
public settingToComponent(key: string, value: any) {
const themeId = this.props.themeId;
const theme = themeStyle(themeId);
const output: any = null;
const updateSettingValue = (key: string, value: any) => {
return shared.updateSettingValue(this, key, value);
const updateSettingValue = async (key: string, value: any) => {
const handled = await this.handleSetting(key, value);
if (!handled) shared.updateSettingValue(this, key, value);
};
const md = Setting.settingMetadata(key);
@@ -517,7 +544,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
fontSize: theme.fontSize,
}}
onValueChange={(itemValue: string) => {
updateSettingValue(key, itemValue);
void updateSettingValue(key, itemValue);
}}
/>
</View>
@@ -553,7 +580,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
</Text>
<View style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', flex: 1 }}>
<Text style={this.styles().sliderUnits}>{unitLabel}</Text>
<Slider key="control" style={{ flex: 1 }} step={md.step} minimumValue={minimum} maximumValue={maximum} value={value} onValueChange={value => updateSettingValue(key, value)} />
<Slider key="control" style={{ flex: 1 }} step={md.step} minimumValue={minimum} maximumValue={maximum} value={value} onValueChange={value => void updateSettingValue(key, value)} />
</View>
</View>
);
@@ -577,7 +604,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
<Text key="label" style={this.styles().settingText}>
{md.label()}
</Text>
<TextInput autoCorrect={false} autoComplete="off" selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} autoCapitalize="none" key="control" style={this.styles().settingControl} value={value} onChangeText={(value: any) => updateSettingValue(key, value)} secureTextEntry={!!md.secure} />
<TextInput autoCorrect={false} autoComplete="off" selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} autoCapitalize="none" key="control" style={this.styles().settingControl} value={value} onChangeText={(value: any) => void updateSettingValue(key, value)} secureTextEntry={!!md.secure} />
</View>
);
} else {
@@ -724,6 +751,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
</View>
);
settingComps.push(
<View key="version_info_hermes" style={this.styles().settingContainer}>
<Text style={this.styles().settingText}>{_('Hermes enabled: %d', (global as any).HermesInternal ? 1 : 0)}</Text>
</View>
);
return (
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader title={_('Configuration')} showSaveButton={true} showSearchButton={false} showSideMenuButton={false} saveButtonDisabled={!this.state.changedSettingKeys.length} onSaveButtonPress={this.saveButton_press} />

View File

@@ -29,7 +29,7 @@ import ScreenHeader from '../ScreenHeader';
const NoteTagsDialog = require('./NoteTagsDialog');
import time from '@joplin/lib/time';
const { Checkbox } = require('../checkbox.js');
const { _ } = require('@joplin/lib/locale');
import { _, currentLocale } from '@joplin/lib/locale';
import { reg } from '@joplin/lib/registry';
import ResourceFetcher from '@joplin/lib/services/ResourceFetcher';
const { BaseScreenComponent } = require('../base-screen.js');
@@ -44,13 +44,18 @@ import ShareExtension from '../../utils/ShareExtension.js';
import CameraView from '../CameraView';
import { NoteEntity } from '@joplin/lib/services/database/types';
import Logger from '@joplin/lib/Logger';
import VoiceTypingDialog from '../voiceTyping/VoiceTypingDialog';
import { voskEnabled } from '../../services/voiceTyping/vosk';
const urlUtils = require('@joplin/lib/urlUtils');
// import Vosk from 'react-native-vosk';
const emptyArray: any[] = [];
const logger = Logger.create('screens/Note');
class NoteScreenComponent extends BaseScreenComponent {
public static navigationOptions(): any {
return { header: null };
}
@@ -84,6 +89,8 @@ class NoteScreenComponent extends BaseScreenComponent {
canUndo: false,
canRedo: false,
},
voiceTypingDialogShown: false,
};
this.saveActionQueues_ = {};
@@ -238,6 +245,8 @@ class NoteScreenComponent extends BaseScreenComponent {
this.onBodyViewerCheckboxChange = this.onBodyViewerCheckboxChange.bind(this);
this.onBodyChange = this.onBodyChange.bind(this);
this.onUndoRedoDepthChange = this.onUndoRedoDepthChange.bind(this);
this.voiceTypingDialog_onText = this.voiceTypingDialog_onText.bind(this);
this.voiceTypingDialog_onDismiss = this.voiceTypingDialog_onDismiss.bind(this);
}
private useEditorBeta(): boolean {
@@ -871,6 +880,69 @@ class NoteScreenComponent extends BaseScreenComponent {
if (buttonId === 'attachPhoto') void this.attachPhoto_onPress();
}
// private vosk_:Vosk;
// private async getVosk() {
// if (this.vosk_) return this.vosk_;
// this.vosk_ = new Vosk();
// await this.vosk_.loadModel('model-fr-fr');
// return this.vosk_;
// }
// private async voiceRecording_onPress() {
// logger.info('Vosk: Getting instance...');
// const vosk = await this.getVosk();
// this.voskResult_ = [];
// const eventHandlers: any[] = [];
// eventHandlers.push(vosk.onResult(e => {
// logger.info('Vosk: result', e.data);
// this.voskResult_.push(e.data);
// }));
// eventHandlers.push(vosk.onError(e => {
// logger.warn('Vosk: error', e.data);
// }));
// eventHandlers.push(vosk.onTimeout(e => {
// logger.warn('Vosk: timeout', e.data);
// }));
// eventHandlers.push(vosk.onFinalResult(e => {
// logger.info('Vosk: final result', e.data);
// }));
// logger.info('Vosk: Starting recording...');
// void vosk.start();
// const buttonId = await dialogs.pop(this, 'Voice recording in progress...', [
// { text: 'Stop recording', id: 'stop' },
// { text: _('Cancel'), id: 'cancel' },
// ]);
// logger.info('Vosk: Stopping recording...');
// vosk.stop();
// for (const eventHandler of eventHandlers) {
// eventHandler.remove();
// }
// logger.info('Vosk: Recording stopped:', this.voskResult_);
// if (buttonId === 'cancel') return;
// const newNote: NoteEntity = { ...this.state.note };
// newNote.body = `${newNote.body} ${this.voskResult_.join(' ')}`;
// this.setState({ note: newNote });
// this.scheduleSave();
// }
public menuOptions() {
const note = this.state.note;
const isTodo = note && !!note.is_todo;
@@ -914,6 +986,18 @@ class NoteScreenComponent extends BaseScreenComponent {
void this.share_onPress();
},
});
// Voice typing is enabled only for French language and on Android for now
if (voskEnabled && shim.mobilePlatform() === 'android' && currentLocale() === 'fr_FR') {
output.push({
title: _('Voice typing...'),
onPress: () => {
// this.voiceRecording_onPress();
this.setState({ voiceTypingDialogShown: true });
},
});
}
if (isSaved) {
output.push({
title: _('Tags'),
@@ -1033,6 +1117,25 @@ class NoteScreenComponent extends BaseScreenComponent {
void this.saveOneProperty('body', newBody);
}
private voiceTypingDialog_onText(text: string) {
if (this.state.mode === 'view') {
const newNote: NoteEntity = { ...this.state.note };
newNote.body = `${newNote.body} ${text}`;
this.setState({ note: newNote });
this.scheduleSave();
} else {
if (this.useEditorBeta()) {
this.editorRef.current.insertText(text);
} else {
logger.warn('Voice typing is not supported in plaintext editor');
}
}
}
private voiceTypingDialog_onDismiss() {
this.setState({ voiceTypingDialogShown: false });
}
public render() {
if (this.state.isLoading) {
return (
@@ -1188,6 +1291,11 @@ class NoteScreenComponent extends BaseScreenComponent {
const noteTagDialog = !this.state.noteTagDialogShown ? null : <NoteTagsDialog onCloseRequested={this.noteTagDialog_closeRequested} />;
const renderVoiceTypingDialog = () => {
if (!this.state.voiceTypingDialogShown) return null;
return <VoiceTypingDialog onText={this.voiceTypingDialog_onText} onDismiss={this.voiceTypingDialog_onDismiss}/>;
};
return (
<View style={this.rootStyle(this.props.themeId).root}>
<ScreenHeader
@@ -1216,6 +1324,7 @@ class NoteScreenComponent extends BaseScreenComponent {
}}
/>
{noteTagDialog}
{renderVoiceTypingDialog()}
</View>
);
}
@@ -1238,6 +1347,10 @@ const NoteScreen = connect((state: any) => {
showSideMenu: state.showSideMenu,
provisionalNoteIds: state.provisionalNoteIds,
highlightedWords: state.highlightedWords,
// What we call "beta editor" in this component is actually the (now
// default) CodeMirror editor. That should be refactored to make it less
// confusing.
useEditorBeta: !state.settings['editor.usePlainText'],
};
})(NoteScreenComponent);

View File

@@ -2,7 +2,7 @@ const React = require('react');
import { AppState as RNAppState, View, StyleSheet, NativeEventSubscription } from 'react-native';
import { stateUtils } from '@joplin/lib/reducer';
import { connect } from 'react-redux';
const { NoteList } = require('../note-list.js');
import NoteList from '../NoteList';
import Folder from '@joplin/lib/models/Folder';
import Tag from '@joplin/lib/models/Tag';
import Note from '@joplin/lib/models/Note';
@@ -254,7 +254,7 @@ class NotesScreenComponent extends BaseScreenComponent<any> {
return (
<View style={rootStyle}>
<ScreenHeader title={iconString + title} showBackButton={false} parentComponent={thisComp} sortButton_press={this.sortButton_press} folderPickerOptions={this.folderPickerOptions()} showSearchButton={true} showSideMenuButton={true} />
<NoteList style={this.styles().noteList} />
<NoteList />
{actionButtonComp}
<DialogBox
ref={(dialogbox: any) => {

View File

@@ -0,0 +1,99 @@
import * as React from 'react';
import { useState, useEffect, useCallback } from 'react';
import { Button, Dialog, Text } from 'react-native-paper';
import { _ } from '@joplin/lib/locale';
import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect';
import { getVosk, Recorder, startRecording, Vosk } from '../../services/voiceTyping/vosk';
import { Alert } from 'react-native';
interface Props {
onDismiss: ()=> void;
onText: (text: string)=> void;
}
enum RecorderState {
Loading = 1,
Recording = 2,
Processing = 3,
}
const useVosk = (): Vosk|null => {
const [vosk, setVosk] = useState<Vosk>(null);
useAsyncEffect(async (event: AsyncEffectEvent) => {
const v = await getVosk();
if (event.cancelled) return;
setVosk(v);
}, []);
return vosk;
};
export default (props: Props) => {
const [recorder, setRecorder] = useState<Recorder>(null);
const [recorderState, setRecorderState] = useState<RecorderState>(RecorderState.Loading);
const vosk = useVosk();
useEffect(() => {
if (!vosk) return;
setRecorderState(RecorderState.Recording);
}, [vosk]);
useEffect(() => {
if (recorderState === RecorderState.Recording) {
setRecorder(startRecording(vosk));
}
}, [recorderState, vosk]);
const onDismiss = useCallback(() => {
recorder.cleanup();
props.onDismiss();
}, [recorder, props.onDismiss]);
const onStop = useCallback(async () => {
try {
setRecorderState(RecorderState.Processing);
const result = await recorder.stop();
props.onText(result);
} catch (error) {
Alert.alert(error.message);
}
onDismiss();
}, [recorder, onDismiss, props.onText]);
const renderContent = () => {
const components: Record<RecorderState, any> = {
[RecorderState.Loading]: <Text variant="bodyMedium">{_('Loading...')}</Text>,
[RecorderState.Recording]: <Text variant="bodyMedium">{_('Please record your voice...')}</Text>,
[RecorderState.Processing]: <Text variant="bodyMedium">{_('Converting speech to text...')}</Text>,
};
return components[recorderState];
};
const renderActions = () => {
const components: Record<RecorderState, any> = {
[RecorderState.Loading]: null,
[RecorderState.Recording]: (
<Dialog.Actions>
<Button onPress={onDismiss}>{_('Cancel')}</Button>
<Button onPress={onStop}>{_('Done')}</Button>
</Dialog.Actions>
),
[RecorderState.Processing]: null,
};
return components[recorderState];
};
return (
<Dialog visible={true} onDismiss={props.onDismiss}>
<Dialog.Title>{_('Voice typing')}</Dialog.Title>
<Dialog.Content>
{renderContent()}
</Dialog.Content>
{renderActions()}
</Dialog>
);
};

View File

@@ -384,14 +384,12 @@
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -422,6 +420,7 @@
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-vosk/Vosk.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
@@ -442,6 +441,7 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Vosk.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -523,7 +523,7 @@
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 12.10.5;
MARKETING_VERSION = 12.11.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -551,7 +551,7 @@
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 12.10.5;
MARKETING_VERSION = 12.11.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -598,7 +598,7 @@
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -661,7 +661,7 @@
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -705,7 +705,7 @@
INFOPLIST_FILE = ShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 12.10.5;
MARKETING_VERSION = 12.11.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
@@ -736,7 +736,7 @@
INFOPLIST_FILE = ShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 12.10.5;
MARKETING_VERSION = 12.11.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -20,10 +20,13 @@ target 'Joplin' do
use_react_native!(
:path => config[:reactNativePath],
# Hermes is now enabled by default. Disable by setting this flag to false.
# Hermes is now enabled by default. Disable by setting this flag to false.
# Upcoming versions of React Native may rely on get_default_flags(), but
# we make it explicit here to aid in the React Native upgrade process.
:hermes_enabled => true,
# 2023/05/07: Leave that to `false` for now because Hermes is rubbish at
# reporting errors, which it makes it impossible to investigate crashes.
:hermes_enabled => false,
:fabric_enabled => flags[:fabric_enabled],
# Enables Flipper.
#

View File

@@ -73,7 +73,6 @@ PODS:
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
- hermes-engine (0.70.6)
- JoplinCommonShareExtension (1.0.0)
- JoplinRNShareExtension (1.0.0):
- JoplinCommonShareExtension
@@ -91,12 +90,6 @@ PODS:
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- RCT-Folly/Futures (2021.07.22.00):
- boost
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- libevent
- RCTRequired (0.70.6)
- RCTTypeSafety (0.70.6):
- FBLazyVector (= 0.70.6)
@@ -274,17 +267,6 @@ PODS:
- React-logger (= 0.70.6)
- React-perflogger (= 0.70.6)
- React-runtimeexecutor (= 0.70.6)
- React-hermes (0.70.6):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly/Futures (= 2021.07.22.00)
- React-cxxreact (= 0.70.6)
- React-jsi (= 0.70.6)
- React-jsiexecutor (= 0.70.6)
- React-jsinspector (= 0.70.6)
- React-perflogger (= 0.70.6)
- React-jsi (0.70.6):
- boost (= 1.76.0)
- DoubleConversion
@@ -306,7 +288,7 @@ PODS:
- React-jsinspector (0.70.6)
- React-logger (0.70.6):
- glog
- react-native-alarm-notification (2.10.0):
- react-native-alarm-notification (2.11.0):
- React
- react-native-camera (4.2.1):
- React-Core
@@ -316,7 +298,7 @@ PODS:
- React-Core
- react-native-camera/RN (4.2.1):
- React-Core
- react-native-document-picker (8.1.3):
- react-native-document-picker (8.2.0):
- React-Core
- react-native-fingerprint-scanner (6.0.0):
- React
@@ -324,17 +306,17 @@ PODS:
- React-Core
- react-native-get-random-values (1.8.0):
- React-Core
- react-native-image-picker (5.1.0):
- react-native-image-picker (5.3.1):
- React-Core
- react-native-image-resizer (1.4.5):
- React-Core
- react-native-netinfo (9.3.7):
- react-native-netinfo (9.3.9):
- React-Core
- react-native-rsa-native (2.0.5):
- React
- react-native-saf-x (2.10.2):
- react-native-saf-x (2.11.0):
- React-Core
- react-native-safe-area-context (4.5.0):
- react-native-safe-area-context (4.5.1):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
@@ -346,6 +328,8 @@ PODS:
- React-Core
- react-native-version-info (1.1.1):
- React-Core
- react-native-vosk (0.1.12):
- React-Core
- react-native-webview (11.26.1):
- React-Core
- React-perflogger (0.70.6)
@@ -432,7 +416,7 @@ PODS:
- React
- RNSecureRandom (1.0.1):
- React
- RNShare (8.2.1):
- RNShare (8.2.2):
- React-Core
- RNVectorIcons (9.2.0):
- React-Core
@@ -468,10 +452,8 @@ DEPENDENCIES:
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
- JoplinCommonShareExtension (from `ShareExtension`)
- JoplinRNShareExtension (from `ShareExtension`)
- libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.1100)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
@@ -485,7 +467,6 @@ DEPENDENCIES:
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
- React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
@@ -505,6 +486,7 @@ DEPENDENCIES:
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
- react-native-version-info (from `../node_modules/react-native-version-info`)
- react-native-vosk (from `../node_modules/react-native-vosk`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
@@ -560,8 +542,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
hermes-engine:
:podspec: "../node_modules/react-native/sdks/hermes/hermes-engine.podspec"
JoplinCommonShareExtension:
:path: ShareExtension
JoplinRNShareExtension:
@@ -586,8 +566,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/CoreModules"
React-cxxreact:
:path: "../node_modules/react-native/ReactCommon/cxxreact"
React-hermes:
:path: "../node_modules/react-native/ReactCommon/hermes"
React-jsi:
:path: "../node_modules/react-native/ReactCommon/jsi"
React-jsiexecutor:
@@ -626,6 +604,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-sqlite-storage"
react-native-version-info:
:path: "../node_modules/react-native-version-info"
react-native-vosk:
:path: "../node_modules/react-native-vosk"
react-native-webview:
:path: "../node_modules/react-native-webview"
React-perflogger:
@@ -694,7 +674,6 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
@@ -709,26 +688,26 @@ SPEC CHECKSUMS:
React-Core: b587d0a624f9611b0e032505f3d6f25e8daa2bee
React-CoreModules: c6ff48b985e7aa622e82ca51c2c353c7803eb04e
React-cxxreact: ade3d9e63c599afdead3c35f8a8bd12b3da6730b
React-hermes: ed09ae33512bbb8d31b2411778f3af1a2eb681a1
React-jsi: 5a3952e0c6d57460ad9ee2c905025b4c28f71087
React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
react-native-alarm-notification: 0f58eaa37a4188480536fd7ab62db9b1dfba392f
react-native-alarm-notification: 26527410a6162d07a9dc57f4bbc62e94ff48e65d
react-native-camera: 3eae183c1d111103963f3dd913b65d01aef8110f
react-native-document-picker: 958e2bc82e128be69055be261aeac8d872c8d34c
react-native-document-picker: 495c444c0c773c6e83a5d91165890ecb1c0a399a
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
react-native-geolocation: 69f4fd37650b8e7fee91816d395e62dd16f5ab8d
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
react-native-image-picker: c33d4e79f0a14a2b66e5065e14946ae63749660b
react-native-image-picker: ec9b713e248760bfa0f879f0715391de4651a7cb
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
react-native-netinfo: 22c082970cbd99071a4e5aa7a612ac20d66b08f0
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
react-native-saf-x: db5a33862e7aec0f9f2d4cccfe7264b09b234e2e
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
react-native-saf-x: 9bd5238d3b43d76bbec64aa82c173ac20a4bce9f
react-native-safe-area-context: f5549f36508b1b7497434baa0cd97d7e470920d4
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
react-native-vosk: 33b8e82a46cc56f31bb4847a40efa2d160270e2e
react-native-webview: 9f111dfbcfc826084d6c507f569e5e03342ee1c1
React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
React-RCTActionSheet: 7316773acabb374642b926c19aef1c115df5c466
@@ -751,12 +730,12 @@ SPEC CHECKSUMS:
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
RNShare: eaee3dd5a06dad397c7d3b14762007035c5de405
RNShare: d82e10f6b7677f4b0048c23709bd04098d5aee6c
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 1f5ea1b29b693e847adf004360d019d064a024ca
PODFILE CHECKSUM: 0235ffbfa2e655de806a80d996148182dd493d8d
COCOAPODS: 1.11.3

View File

@@ -2,10 +2,10 @@
"name": "@joplin/app-mobile",
"description": "Joplin for Mobile",
"license": "AGPL-3.0-or-later",
"version": "2.10.0",
"version": "2.11.0",
"private": true,
"scripts": {
"start": "react-native start --reset-cache",
"start": "BROWSERSLIST_IGNORE_OLD_DATA=true react-native start --reset-cache",
"android": "react-native run-android",
"build": "gulp build",
"tsc": "tsc --project tsconfig.json",
@@ -18,14 +18,14 @@
"postinstall": "jetify && yarn run build"
},
"dependencies": {
"@joplin/lib": "~2.10",
"@joplin/react-native-alarm-notification": "~2.10",
"@joplin/react-native-saf-x": "~2.10",
"@joplin/renderer": "~2.10",
"@joplin/lib": "~2.11",
"@joplin/react-native-alarm-notification": "~2.11",
"@joplin/react-native-saf-x": "~2.11",
"@joplin/renderer": "~2.11",
"@react-native-community/clipboard": "1.5.1",
"@react-native-community/datetimepicker": "6.7.5",
"@react-native-community/geolocation": "2.1.0",
"@react-native-community/netinfo": "9.3.7",
"@react-native-community/netinfo": "9.3.9",
"@react-native-community/push-notification-ios": "1.10.1",
"@react-native-community/slider": "4.4.2",
"assert-browserify": "2.0.0",
@@ -44,28 +44,29 @@
"react-native-action-button": "2.8.5",
"react-native-camera": "4.2.1",
"react-native-dialogbox": "0.6.10",
"react-native-document-picker": "8.1.4",
"react-native-document-picker": "8.2.0",
"react-native-dropdownalert": "4.5.1",
"react-native-exit-app": "1.1.0",
"react-native-file-viewer": "2.1.5",
"react-native-fingerprint-scanner": "6.0.0",
"react-native-fs": "2.20.0",
"react-native-get-random-values": "1.8.0",
"react-native-image-picker": "5.1.0",
"react-native-image-picker": "5.3.1",
"react-native-image-resizer": "1.4.5",
"react-native-modal-datetime-picker": "14.0.1",
"react-native-paper": "5.2.0",
"react-native-paper": "5.6.0",
"react-native-popup-menu": "0.16.1",
"react-native-quick-actions": "0.3.13",
"react-native-rsa-native": "2.0.5",
"react-native-safe-area-context": "4.5.0",
"react-native-safe-area-context": "4.5.1",
"react-native-securerandom": "1.0.1",
"react-native-share": "8.2.1",
"react-native-share": "8.2.2",
"react-native-side-menu-updated": "1.3.2",
"react-native-sqlite-storage": "6.0.1",
"react-native-url-polyfill": "1.3.0",
"react-native-vector-icons": "9.2.0",
"react-native-version-info": "1.1.1",
"react-native-vosk": "0.1.12",
"react-native-webview": "11.26.1",
"react-redux": "7.2.9",
"redux": "4.2.1",
@@ -79,36 +80,36 @@
"devDependencies": {
"@babel/core": "7.16.0",
"@babel/runtime": "7.16.3",
"@codemirror/commands": "6.1.2",
"@codemirror/commands": "6.2.2",
"@codemirror/lang-cpp": "6.0.2",
"@codemirror/lang-html": "6.4.0",
"@codemirror/lang-html": "6.4.3",
"@codemirror/lang-java": "6.0.1",
"@codemirror/lang-javascript": "6.1.1",
"@codemirror/lang-markdown": "6.0.5",
"@codemirror/lang-javascript": "6.1.5",
"@codemirror/lang-markdown": "6.1.0",
"@codemirror/lang-php": "6.0.1",
"@codemirror/lang-rust": "6.0.1",
"@codemirror/language": "6.3.2",
"@codemirror/legacy-modes": "6.3.1",
"@codemirror/search": "6.2.3",
"@codemirror/state": "6.1.4",
"@codemirror/view": "6.7.1",
"@joplin/tools": "~2.10",
"@lezer/highlight": "1.1.3",
"@codemirror/language": "6.6.0",
"@codemirror/legacy-modes": "6.3.2",
"@codemirror/search": "6.3.0",
"@codemirror/state": "6.2.0",
"@codemirror/view": "6.9.3",
"@joplin/tools": "~2.11",
"@lezer/highlight": "1.1.4",
"@types/fs-extra": "9.0.13",
"@types/jest": "29.2.6",
"@types/react-native": "0.70.6",
"@types/react-redux": "7.1.25",
"babel-plugin-module-resolver": "4.1.0",
"execa": "4.1.0",
"fs-extra": "11.1.0",
"fs-extra": "11.1.1",
"gulp": "4.0.2",
"jest": "29.4.3",
"jest-environment-jsdom": "29.4.3",
"jetifier": "2.0.0",
"jsdom": "21.0.0",
"jsdom": "21.1.1",
"md5-file": "5.0.0",
"metro-react-native-babel-preset": "0.72.3",
"nodemon": "2.0.21",
"nodemon": "2.0.22",
"ts-jest": "29.0.5",
"ts-loader": "9.4.2",
"ts-node": "10.9.1",

View File

@@ -76,7 +76,7 @@ const { defaultState } = require('@joplin/lib/reducer');
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local');
import ResourceFetcher from '@joplin/lib/services/ResourceFetcher';
import SearchEngine from '@joplin/lib/services/searchengine/SearchEngine';
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
import WelcomeUtils from '@joplin/lib/WelcomeUtils';
const { themeStyle } = require('./components/global-style.js');
import SyncTargetRegistry from '@joplin/lib/SyncTargetRegistry';
const SyncTargetFilesystem = require('@joplin/lib/SyncTargetFilesystem.js');
@@ -142,7 +142,7 @@ const generalMiddleware = (store: any) => (next: any) => async (action: any) =>
if (action.type === 'NAV_GO') Keyboard.dismiss();
if (['NOTE_UPDATE_ONE', 'NOTE_DELETE', 'FOLDER_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
if (!await reg.syncTarget().syncStarted()) void reg.scheduleSync(5 * 1000, { syncSteps: ['update_remote', 'delete_remote'] }, true);
if (!await reg.syncTarget().syncStarted()) void reg.scheduleSync(1000, { syncSteps: ['update_remote', 'delete_remote'] }, true);
SearchEngine.instance().scheduleSyncTables();
}
@@ -501,7 +501,7 @@ async function initialize(dispatch: Function) {
if (Setting.value('env') === 'prod') {
await db.open({ name: getDatabaseName(currentProfile, isSubProfile) });
} else {
await db.open({ name: getDatabaseName(currentProfile, isSubProfile, '-1') });
await db.open({ name: getDatabaseName(currentProfile, isSubProfile, '-3') });
// await db.clearForTesting();
}
@@ -659,7 +659,7 @@ async function initialize(dispatch: Function) {
// doWifiConnectionCheck set to true so initial sync
// doesn't happen on mobile data
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
void reg.scheduleSync(1000, null, true).then(() => {
void reg.scheduleSync(100, null, true).then(() => {
// Wait for the first sync before updating the notifications, since synchronisation
// might change the notifications.
void AlarmService.updateAllNotifications();
@@ -667,7 +667,7 @@ async function initialize(dispatch: Function) {
void DecryptionWorker.instance().scheduleStart();
});
await WelcomeUtils.install(dispatch);
await WelcomeUtils.install(Setting.value('locale'), dispatch);
// Collect revisions more frequently on mobile because it doesn't auto-save
// and it cannot collect anything when the app is not active.
@@ -984,6 +984,10 @@ class AppComponent extends React.Component {
const biometricIsEnabled = !!this.state.sensorInfo && this.state.sensorInfo.enabled;
const shouldShowMainContent = !biometricIsEnabled || this.props.biometricsDone;
logger.info('root.biometrics: biometricIsEnabled', biometricIsEnabled);
logger.info('root.biometrics: shouldShowMainContent', shouldShowMainContent);
logger.info('root.biometrics: this.state.sensorInfo', this.state.sensorInfo);
const mainContent = (
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
<SideMenu

View File

@@ -0,0 +1,21 @@
type Vosk = any;
export { Vosk };
export interface Recorder {
stop: ()=> Promise<string>;
cleanup: ()=> void;
}
export const getVosk = async () => {
return {} as any;
};
export const startRecording = (_vosk: Vosk): Recorder => {
return {
stop: async () => { return ''; },
cleanup: () => {},
};
};
export const voskEnabled = false;

View File

@@ -0,0 +1,113 @@
import Logger from '@joplin/lib/Logger';
import Vosk from 'react-native-vosk';
const logger = Logger.create('voiceTyping/vosk');
enum State {
Idle = 0,
Recording,
}
let vosk_: Vosk|null = null;
let state_: State = State.Idle;
export const voskEnabled = true;
export { Vosk };
export interface Recorder {
stop: ()=> Promise<string>;
cleanup: ()=> void;
}
export const getVosk = async () => {
if (vosk_) return vosk_;
vosk_ = new Vosk();
await vosk_.loadModel('model-fr-fr');
return vosk_;
};
export const startRecording = (vosk: Vosk): Recorder => {
if (state_ !== State.Idle) throw new Error('Vosk is already recording');
state_ = State.Recording;
const result: string[] = [];
const eventHandlers: any[] = [];
let finalResultPromiseResolve: Function = null;
let finalResultPromiseReject: Function = null;
let finalResultTimeout = false;
const completeRecording = (finalResult: string, error: Error) => {
logger.info(`Complete recording. Final result: ${finalResult}. Error:`, error);
for (const eventHandler of eventHandlers) {
eventHandler.remove();
}
vosk.cleanup(),
state_ = State.Idle;
if (error) {
if (finalResultPromiseReject) finalResultPromiseReject(error);
} else {
if (finalResultPromiseResolve) finalResultPromiseResolve(finalResult);
}
};
eventHandlers.push(vosk.onResult(e => {
logger.info('Result', e.data);
result.push(e.data);
}));
eventHandlers.push(vosk.onError(e => {
logger.warn('Error', e.data);
}));
eventHandlers.push(vosk.onTimeout(e => {
logger.warn('Timeout', e.data);
}));
eventHandlers.push(vosk.onFinalResult(e => {
logger.info('Final result', e.data);
if (finalResultTimeout) {
logger.warn('Got final result - but already timed out. Not doing anything.');
return;
}
completeRecording(e.data, null);
}));
logger.info('Starting recording...');
void vosk.start();
return {
stop: (): Promise<string> => {
logger.info('Stopping recording...');
vosk.stopOnly();
logger.info('Waiting for final result...');
setTimeout(() => {
finalResultTimeout = true;
logger.warn('Timed out waiting for finalResult event');
completeRecording('', new Error('Could not process your message. Please try again.'));
}, 5000);
return new Promise((resolve: Function, reject: Function) => {
finalResultPromiseResolve = resolve;
finalResultPromiseReject = reject;
});
},
cleanup: () => {
if (state_ !== State.Idle) {
logger.info('Cancelling...');
vosk.stopOnly();
completeRecording('', null);
}
},
};
};

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 1,
"id": "<%= pluginId %>",
"app_min_version": "2.10",
"app_min_version": "2.11",
"version": "1.0.0",
"name": "<%= pluginName %>",
"description": "<%= pluginDescription %>",

View File

@@ -1,6 +1,6 @@
{
"name": "generator-joplin",
"version": "2.10.0",
"version": "2.11.0",
"description": "Scaffolds out a new Joplin plugin",
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
"author": {
@@ -24,7 +24,7 @@
},
"dependencies": {
"chalk": "2.4.2",
"slugify": "1.6.5",
"slugify": "1.6.6",
"yeoman-generator": "5.8.0",
"yosay": "2.0.2"
},

View File

@@ -1,6 +1,6 @@
{
"name": "@joplin/htmlpack",
"version": "2.10.2",
"version": "2.11.0",
"description": "Pack an HTML file and all its linked resources into a single HTML file",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -17,7 +17,7 @@
"@joplin/fork-htmlparser2": "^4.1.43",
"css": "3.0.0",
"datauri": "4.1.0",
"fs-extra": "11.1.0",
"fs-extra": "11.1.1",
"html-entities": "1.4.0"
},
"devDependencies": {

View File

@@ -840,13 +840,8 @@ export default class BaseApplication {
}
if (Setting.value('firstStart')) {
// If it's a sub-profile, the locale must come from the root
// profile.
if (!Setting.value('isSubProfile')) {
const locale = shim.detectAndSetLocale(Setting);
reg.logger().info(`First start: detected locale as ${locale}`);
}
const locale = shim.detectAndSetLocale(Setting);
reg.logger().info(`First start: detected locale as ${locale}`);
Setting.skipDefaultMigrations();
if (Setting.value('env') === 'dev') {

View File

@@ -96,12 +96,14 @@ export default class SyncTargetOneDrive extends BaseSyncTarget {
let context = Setting.value(`sync.${this.syncTargetId()}.context`);
context = context === '' ? null : JSON.parse(context);
let accountProperties = context ? context.accountProperties : null;
const api = this.api();
if (!accountProperties) {
accountProperties = await this.api_.execAccountPropertiesRequest();
accountProperties = await api.execAccountPropertiesRequest();
context ? context.accountProperties = accountProperties : context = { accountProperties: accountProperties };
Setting.setValue(`sync.${this.syncTargetId()}.context`, JSON.stringify(context));
}
this.api_.setAccountProperties(accountProperties);
api.setAccountProperties(accountProperties);
const appDir = await this.api().appDirectory();
// the appDir might contain non-ASCII characters
// /[^\u0021-\u00ff]/ is used in Node.js to detect the unescaped characters.

View File

@@ -1,80 +0,0 @@
const welcomeAssets = require('./welcomeAssets');
const Note = require('./models/Note').default;
const Setting = require('./models/Setting').default;
const Folder = require('./models/Folder').default;
const Tag = require('./models/Tag').default;
const shim = require('./shim').default;
const uuid = require('./uuid').default;
const { fileExtension, basename } = require('./path-utils');
const { pregQuote } = require('./string-utils');
class WelcomeUtils {
static async createWelcomeItems() {
const output = {
defaultFolderId: null,
};
const folderAssets = welcomeAssets.folders;
const tempDir = Setting.value('resourceDir');
for (let i = 0; i < folderAssets.length; i++) {
const folderAsset = folderAssets[i];
const folder = await Folder.save({ title: `${folderAsset.title} (${Setting.appTypeToLabel(Setting.value('appType'))})` });
if (!output.defaultFolderId) output.defaultFolderId = folder.id;
}
const noteAssets = welcomeAssets.notes;
for (let i = noteAssets.length - 1; i >= 0; i--) {
const noteAsset = noteAssets[i];
let noteBody = noteAsset.body;
for (const resourceUrl in noteAsset.resources) {
if (!noteAsset.resources.hasOwnProperty(resourceUrl)) continue;
const resourceAsset = noteAsset.resources[resourceUrl];
const ext = fileExtension(resourceUrl);
const tempFilePath = `${tempDir}/${uuid.create()}.tmp.${ext}`;
await shim.fsDriver().writeFile(tempFilePath, resourceAsset.body, 'base64');
const resource = await shim.createResourceFromPath(tempFilePath, {
title: basename(resourceUrl),
});
await shim.fsDriver().remove(tempFilePath);
const regex = new RegExp(pregQuote(`(${resourceUrl})`), 'g');
noteBody = noteBody.replace(regex, `(:/${resource.id})`);
}
const note = await Note.save({
parent_id: output.defaultFolderId,
title: noteAsset.title,
body: noteBody,
});
if (noteAsset.tags) await Tag.setNoteTagsByTitles(note.id, noteAsset.tags);
}
return output;
}
static async install(dispatch) {
if (!Setting.value('welcome.enabled')) {
Setting.setValue('welcome.wasBuilt', true);
return;
}
if (!Setting.value('welcome.wasBuilt')) {
const result = await WelcomeUtils.createWelcomeItems();
Setting.setValue('welcome.wasBuilt', true);
dispatch({
type: 'FOLDER_SELECT',
id: result.defaultFolderId,
});
Setting.setValue('activeFolderId', result.defaultFolderId);
}
}
}
module.exports = WelcomeUtils;

View File

@@ -0,0 +1,122 @@
const welcomeAssetsAny = require('./welcomeAssets');
import Note from './models/Note';
import Setting from './models/Setting';
import Folder from './models/Folder';
import shim from './shim';
import uuid from './uuid';
import { fileExtension, basename } from './path-utils';
import { _ } from './locale';
const { pregQuote } = require('./string-utils');
export interface ItemMetadatum {
id: string;
}
export type ItemMetadata = Record<string, ItemMetadatum>;
export interface CreateWelcomeItemsResult {
defaultFolderId: string;
}
export interface WelcomeAssetResource {
id: string;
body: string;
}
export interface WelcomeAssetNote {
id: string;
parent_id: string;
title: string;
body: string;
resources: Record<string, WelcomeAssetResource>;
}
export interface WelcomeAssetFolder {
id: string;
title: string;
}
export interface AssetContent {
notes: WelcomeAssetNote[];
folders: WelcomeAssetFolder[];
timestamp: number;
}
export type WelcomeAssets = Record<string, AssetContent>;
class WelcomeUtils {
public static async createWelcomeItems(locale: string): Promise<CreateWelcomeItemsResult> {
const output: CreateWelcomeItemsResult = {
defaultFolderId: null,
};
const allWelcomeAssets = welcomeAssetsAny as WelcomeAssets;
const welcomeAssets = locale in allWelcomeAssets ? allWelcomeAssets[locale] : allWelcomeAssets['en_GB'];
const enGbWelcomeAssets = allWelcomeAssets['en_GB'];
const folderAssets = welcomeAssets.folders;
const tempDir = Setting.value('resourceDir');
// Actually we don't really support mutiple folders at this point, because not needed
for (let i = 0; i < folderAssets.length; i++) {
const folder = await Folder.save({ title: _('Welcome!') });
if (!output.defaultFolderId) output.defaultFolderId = folder.id;
}
const noteAssets = welcomeAssets.notes;
for (let i = noteAssets.length - 1; i >= 0; i--) {
const noteAsset = noteAssets[i];
const enGbNoteAsset = enGbWelcomeAssets.notes[i];
let noteBody = noteAsset.body;
for (const resourceUrl in enGbNoteAsset.resources) {
if (!enGbNoteAsset.resources.hasOwnProperty(resourceUrl)) continue;
const resourceAsset = enGbNoteAsset.resources[resourceUrl];
const ext = fileExtension(resourceUrl);
const tempFilePath = `${tempDir}/${uuid.create()}.tmp.${ext}`;
await shim.fsDriver().writeFile(tempFilePath, resourceAsset.body, 'base64');
const resource = await shim.createResourceFromPath(tempFilePath, {
title: basename(resourceUrl),
});
await shim.fsDriver().remove(tempFilePath);
const regex = new RegExp(pregQuote(`(${resourceUrl})`), 'g');
noteBody = noteBody.replace(regex, `(:/${resource.id})`);
}
await Note.save({
parent_id: output.defaultFolderId,
title: noteAsset.title,
body: noteBody,
});
// if (noteAsset.tags) await Tag.setNoteTagsByTitles(note.id, noteAsset.tags);
}
return output;
}
public static async install(locale: string, dispatch: Function) {
if (!Setting.value('welcome.enabled')) {
Setting.setValue('welcome.wasBuilt', true);
return;
}
if (!Setting.value('welcome.wasBuilt')) {
const result = await WelcomeUtils.createWelcomeItems(locale);
Setting.setValue('welcome.wasBuilt', true);
dispatch({
type: 'FOLDER_SELECT',
id: result.defaultFolderId,
});
Setting.setValue('activeFolderId', result.defaultFolderId);
}
}
}
export default WelcomeUtils;

View File

@@ -0,0 +1,18 @@
import { closestSupportedLocale } from './locale';
describe('locale', () => {
it('should find the closest matching locale', () => {
const testCases: [string, string[], string][] = [
['fr', ['fr_FR', 'en_GB'], 'fr_FR'],
['pt-br', ['fr_FR', 'en_GB', 'pt_BR'], 'pt_BR'],
['ro', ['fr_FR', 'en_GB', 'pt_BR'], 'en_GB'],
];
for (const [input, locales, expected] of testCases) {
const actual = closestSupportedLocale(input, true, locales);
expect(actual).toBe(expected);
}
});
});

View File

@@ -584,14 +584,7 @@ function localesFromLanguageCode(languageCode: string, locales: string[]): strin
}
function _(s: string, ...args: any[]): string {
const strings = localeStrings(currentLocale_);
let result = strings[s];
if (result === '' || result === undefined) result = s;
try {
return sprintf(result, ...args);
} catch (error) {
return `${result} ${args.join(', ')} (Translation error: ${error.message})`;
}
return stringByLocale(currentLocale_, s, ...args);
}
function _n(singular: string, plural: string, n: number, ...args: any[]) {
@@ -599,4 +592,15 @@ function _n(singular: string, plural: string, n: number, ...args: any[]) {
return _(singular, ...args);
}
const stringByLocale = (locale: string, s: string, ...args: any[]): string => {
const strings = localeStrings(locale);
let result = strings[s];
if (result === '' || result === undefined) result = s;
try {
return sprintf(result, ...args);
} catch (error) {
return `${result} ${args.join(', ')} (Translation error: ${error.message})`;
}
};
export { _, _n, supportedLocales, currentLocale, localesFromLanguageCode, languageCodeOnly, countryDisplayName, localeStrings, setLocale, supportedLocalesToLanguages, defaultLocale, closestSupportedLocale, languageCode, countryCodeOnly };

View File

@@ -1,10 +1,15 @@
{
"\"%s\" is missing the required \"%s\" property.": "\"%s\" chybí požadovaná vlastnost \"%s\".",
"%d days": "%d dní",
"%d GB": "%d GB",
"%d GB storage space": "%d GB místa v úložišti",
"%d hour": "%d hodina",
"%d hours": "%d hodin",
"%d MB": "%d MB",
"%d MB per note or attachment": "%d MB na poznámku nebo přílohu",
"%d minutes": "%d minut",
"%d notes match this pattern. Delete them?": "%d poznámek vyhovuje zadání. Smazat všechny?",
"%s": "%s",
"%s %s (%s, %s)": "%s %s (%s, %s)",
"%s (%s) could not be uploaded: %s": "%s (%s) se nepodařilo nahrát: %s",
"%s (%s) would like to share a notebook with you.": "Uživatel %s (%s) by s vámi rád sdílel zápisník.",
@@ -27,6 +32,8 @@
"&Tools": "&Nástroje",
"&View": "&Zobrazit",
"(%s)": "(%s)",
"(In plugin: %s)": "(V pluginu: %s)",
"(None)": "(Žádné)",
"(wysiwyg: %s)": "(wysiwyg: %s)",
"- Camera: to allow taking a picture and attaching it to a note.": "- Fotoaparát: umožňuje pořízení fotografie a její připojení k poznámce.",
"- Location: to allow attaching geo-location information to a note.": "- Poloha: umožňuje k poznámce připojit informaci o zeměpisné poloze.",
@@ -41,27 +48,38 @@
"Accelerator \"%s\" is not valid.": "Akcelerátor \"%s\" není platný.",
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to unexpected behaviour.": "Akcelerátor \"%s\" se používá pro příkazy \"%s\" a \"%s\". Toto může vést k neočekávanému chování.",
"Accept": "Přijmout",
"Account": "Účet",
"Action": "Akce",
"Actions": "Akce",
"Active": "Aktivní",
"Actual Size": "Skutečná velikost",
"Add body": "Přidat tělo",
"Add new": "Přidat nový",
"Add or remove tags:": "Přidat či odebrat štítky:",
"Add recipient:": "Přidat příjemce:",
"Add title": "Přidejte nadpis",
"Add to dictionary": "Přidat do slovníku",
"Admin": "Admin",
"Admin dashboard": "Admin panel",
"Advanced options": "Ukázat pokročilé volby",
"Advanced tools": "Pokročilé volby",
"All data, including notes, notebooks and tags will be permanently deleted.": "Všechna data včetně poznámek, zápisníků a značek budou trvale odstraněna.",
"All notes": "Všechny poznámky",
"All potential ports are in use - please report the issue at %s": "Všechny dostupné porty jsou používané - nahlaste prosím tento problém na %s",
"Also displays unset and hidden config variables.": "Zobrazí i nenastavené a schované konfigurační proměnné.",
"Also publish linked notes": "Zveřejněte také propojené poznámky",
"Always": "Vždy",
"Ambiguous notebook \"%s\". Please use notebook id instead - press \"ti\" to see the short notebook id or use $b for current selected notebook": "Nejednoznačný zápisník \"%s\". Místo toho prosím použijte id zápisníku - stiskněte \"ti\" pro zobrazení krátkého id zápisníku nebo použijte $b pro aktuální vybraný zápisník.",
"Ambiguous notebook \"%s\". Please use short notebook id instead - press \"ti\" to see the short notebook id": "Nejednoznačný zápisník \"%s\". Místo toho prosím použijte zkrácené id zápisníku - stiskněte \"ti\" pro zobrazení zkráceného id zápisníku.",
"An update is available, do you want to download it now?": "Je k dispozici aktualizace, chcete ji stáhnout?",
"Appearance": "Vzhled",
"Application": "Aplikace",
"Apply": "Použít",
"Are you sure you want to renew the authorisation token?": "Opravdu chcete obnovit autorizační token?",
"Are you sure you want to return to the default layout? The current layout configuration will be lost.": "Určitě se chcete vrátit k výchozímu rozložení? Aktuální konfigurace rozložení bude ztracena.",
"Arguments:": "Argumenty:",
"Aritim Dark": "Aritim Dark",
"Attach": "Připojit",
"Attach file": "Přiložit soubor",
"Attach photo": "Přiložit obrázek",
"Attach...": "Přiložit...",
@@ -75,13 +93,17 @@
"Authentication was not completed (did not receive an authentication token).": "Autentizace nebyla dokončena (nedostali jsme autentizační token).",
"Authorisation token:": "Autorizační token:",
"Auto": "Automaticky",
"Auto-add disabled accounts for deletion": "Automatické přidání zakázaných účtů k odstranění",
"Auto-pair braces, parenthesis, quotations, etc.": "Automaticky zdvojit uvozovky, závorky, apod.",
"Automatically check for updates": "Automatická kontrola aktualizací",
"Automatically switch theme to match system theme": "Automaticky přepnout téma vzhledu podle nastavení systému",
"Back": "Zpět",
"Basic": "Základní",
"Bold": "Tučně",
"Browse all plugins": "Procházet všechna rozšíření",
"Browse...": "Procházet...",
"Bulleted List": "Seznam s odrážkami",
"Can Share": "Může se sdílet",
"Cancel": "Zrušit",
"Cancelling background synchronisation... Please wait.": "Zastavování synchronizace, počkejte prosím...",
"Cancelling...": "Zastavování...",
@@ -90,12 +112,17 @@
"Cannot change encrypted item": "Nelze editovat zašifrovanou položku",
"Cannot copy note to \"%s\" notebook": "Poznámku \"%s\" nelze zkopírovat do zápisníku",
"Cannot find \"%s\".": "Výraz \"%s\" nebyl nalezen.",
"Cannot find: \"%s\"": "Nelze najít: \"%s\"",
"Cannot initialise synchroniser.": "Nelze inicializovat synchronizátor.",
"Cannot load \"%s\" module for format \"%s\" and output \"%s\"": "Nelze načíst modul \"%s\" pro formát \"%s\" a výstup \"%s\"",
"Cannot load \"%s\" module for format \"%s\" and target \"%s\"": "Nelze načíst modul \"%s\" pro formát \"%s\" a cíl \"%s\"",
"Cannot move note to \"%s\" notebook": "Poznámku nelze přesunout do \"%s\" zápisníku",
"Cannot move notebook to this location": "Zápisník nelze přesunout na toto umístění",
"Cannot refresh token: authentication data is missing. Starting the synchronisation again may fix the problem.": "Nelze obnovit token: chybí autentizační data. Opětovné spuštění synchronizace může tento problém vyřešit.",
"Cannot save %s \"%s\" because it is larger than the allowed limit (%s)": "Nelze uložit %s \"%s\", protože je větší než povolený limit (%s).",
"Cannot save %s \"%s\" because it would go over the total allowed size (%s) for this account": "Nelze uložit %s \"%s\", protože by překročila celkovou povolenou velikost (%s) pro tento účet.",
"Cannot share encrypted notebook with recipient %s because they have not enabled end-to-end encryption. They may do so from the screen Configuration > Encryption.": "Nelze sdílet šifrovaný zápisník s příjemcem %s, protože nemá povoleno koncové šifrování. Mohou tak učinit na obrazovce Konfigurace > Šifrování.",
"Case sensitive": "Rozlišování malých a velkých písmen",
"Change application layout": "Změnit rozložení aplikace",
"Change language": "Změnit jazyk",
"Characters": "Znaky",
@@ -113,26 +140,39 @@
"Click to add tags...": "Klepněte pro přidání štítku...",
"Client ID: %s": "ID klienta: %s",
"Close": "Zavřít",
"Close dropdown": "Zavřít rozevírací seznam",
"Close Window": "Zavřít okno",
"Code": "Kód",
"Code Block": "Blok kódu",
"Code View": "Zobrazit kód",
"Collaborate on notebooks with others": "Spolupracujte na zápisnících s ostatními",
"Collapse": "Sbalit",
"Coming alarms": "Nadcházející alarmy",
"Comma-separated list of paths to directories to load the certificates from, or path to individual cert files. For example: /my/cert_dir, /other/custom.pem. Note that if you make changes to the TLS settings, you must save your changes before clicking on \"Check synchronisation configuration\".": "Čárkami oddělený seznam adresářů s certifikáty nebo cestami k jednotlivým souborům s certifikáty. Například: /my/cert_dir, /other/custom.pem. Pamatujte, že pokud provedete změny nastavení TLS, musíte změny před klepnutím na \"Zkontrolovat konfiguraci synchronizace\" uložit.",
"command": "příkaz",
"Command": "Příkaz",
"Command palette": "Nabídka příkazů",
"Command palette...": "Příkazová paleta...",
"Completed": "Dokončeno",
"Completed decryption.": "Dešifrování dokončeno.",
"Completed: %s (%s)": "Dokončeno: %s (%s)",
"Compress old changes": "Komprese starých změn",
"Configuration": "Nastavení",
"Confirm password cannot be empty": "Heslo pro potvrzení nemůže být prázdné",
"Confirm password:": "Potvrďte heslo:",
"Confirmation": "Potvrzení",
"Conflicted: %d": "Konflikt: %d",
"Conflicts": "Konflikty",
"Conflicts (attachments)": "Konflikty (přílohy)",
"Consolidated billing": "Consolidated billing",
"Content provided by %s": "Obsah poskytl %s",
"Continue": "Pokračovat",
"Convert to note": "Konvertovat na poznámku",
"Convert to todo": "Převést na úkolexpr",
"Copy": "Kopírovat",
"Copy dev mode command to clipboard": "Zkopírovat příkaz režimu pro vývojáře vývojáře do schránky",
"Copy external link": "Kopírovat externí odkaz",
"Copy image": "Kopírovat obrázek",
"Copy Link Address": "Kopírovat adresu odkazu",
"Copy Markdown link": "Vytvořit Markdown odkaz",
"Copy path to clipboard": "Kopírovat cestu do schránky",
@@ -140,15 +180,25 @@
"Copy token": "Zkopírovat token",
"Could not authorise application:\n\n%s\n\nPlease try again.": "Aplikaci se nepodařilo autorizovat:\\n\n\\n\n%s\\n\n\\n\nProsím, zkuste to znovu.",
"Could not connect to Joplin Server. Please check the Synchronisation options in the config screen. Full error was:\n\n%s": "Nelze se připojit k Joplin serveru. Zkontrolujte prosím nastavení synchronizace na konfigurační obrazovce. Celá chyba:\n\n%s",
"Could not connect to plugin repository.": "Nepodařilo se připojit k úložišti zásuvných pluginů.",
"Could not export notes: %s": "Nelze exportovat poznámky: %s",
"Could not install plugin: %s": "Rozšíření se nepodařilo nainstalovat: %s",
"Could not respond to the invitation. Please try again, or check with the notebook owner if they are still sharing it.\n\nThe error was: \"%s\"": "Na pozvánku nebylo možné reagovat. Zkuste to prosím znovu nebo se obraťte na majitele zápisníku, zda jej stále sdílí.\n\nChyba byla následující: \"%s\"",
"Could not switch profile: %s": "Nelze přepnout profil: %s",
"Could not upgrade master key: %s": "Hlavní klíč nelze upgradovat: %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Nelze ověřit stav sdílení tohoto zápisníku - přerušení. Zkuste to prosím znovu, až budete připojeni k internetu.",
"Create": "Vytvořit",
"Create a new notebook under a parent notebook.": "Vytvoření nového zápisníku pod nadřazeným zápisníkem.",
"Create a notebook": "Vytvořit nový zápisník",
"Create new profile...": "Vytvořit nový profil...",
"Create notebook": "Vytvořit zápisník",
"Create user": "Vytvořit uživatele",
"Created": "Vytvořeno",
"created date": "datum vytvoření",
"Created local items: %d.": "Položky vytvořené lokálně: %d.",
"Created locally": "Vytvořené lokálně",
"Created remote items: %d.": "Položky vytvořené na vzdáleném úložišti: %d.",
"Created: ": "Vytvořeno: ",
"Created: %d.": "Vytvořeno: %d.",
"Created: %s": "Vytvořeno: %s",
"Creates a new note.": "Vytvoří novou poznámku.",
@@ -164,9 +214,12 @@
"Custom TLS certificates": "Vlastní TLS certifikát",
"Cut": "Vyjmout",
"Dark": "Tmavý",
"Dashboard": "Panel",
"Database v%s": "Databáze v%s",
"Date": "Datum",
"Date format": "Formát data",
"days": "dní",
"Decrease indent level": "Snížení úrovně odsazení",
"Decrypted items: %d": "Dešifrované položky: %d",
"Decrypted items: %s / %s": "Dešifrované položky: %s/%s",
"Decrypting items: %d/%d": "Dešifrování položek: %d/%d",
@@ -174,6 +227,8 @@
"Default: %s": "Výchozí: %s",
"Delete": "Smazat",
"Delete attachment \"%s\"?": "Smazat přílohu \"%s\"?",
"Delete expired sessions": "Odstranění relací, jejichž platnost vypršela",
"Delete expired tokens": "Odstranění prošlých tokenů",
"Delete line": "Smazat řádek",
"Delete local data and re-download from sync target": "Smazat místní data a stáhnout je z cíle synchronizace",
"Delete note \"%s\"?": "Smazat poznámku \"%s\"?",
@@ -181,8 +236,11 @@
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "Smazat zápisník \"%s\"?\n\nBudou smazány i všechny poznámky a pod-zápisníky v tomto zápisníku.",
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "Smazat zápisník? Budou smazány i všechny poznámky a pod-zápisníky v něm obsažené.",
"Delete plugin \"%s\"?": "Smazat rozšíření \"%s\"?",
"Delete profile \"%s\"": "Odstranění profilu \"%s\"",
"Delete selected notes": "Odstranění vybraných poznámek",
"Delete these %d notes?": "Smazat tyto \"%d\" poznámky?",
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "Opravdu chcete smazat tuto pozvánku? Příjemce už nebude mít přístup k tomuto sdílenému zápisníku.",
"Delete this profile?": "Smazat tento profil?",
"Deleted local items: %d.": "Položky smazané lokálně: %d.",
"Deleted remote items: %d.": "Položky smazané na vzdáleném úložišti: %d.",
"Deletes the given notebook.": "Smaže vybraný zápisník.",
@@ -192,6 +250,7 @@
"Destination format: %s": "Cílový formát: %s",
"Directory": "Adresář",
"Directory to synchronise with (absolute path)": "Složka k synchronizaci (absolutní cesta)",
"Disable": "Vypnout",
"Disable encryption": "Vypnout šifrování",
"Disable safe mode and restart": "Vypnout nouzový režim a restartovat",
"Disable Web Clipper Service": "Služba Web clipper vypnuta",
@@ -210,6 +269,8 @@
"Displays version information": "Zobrazí informace o verzi",
"Do it now": "Provést ihned",
"Do not ask for confirmation.": "Neptat se na potvrzení.",
"Do not lose the password as, for security purposes, this will be the *only* way to decrypt the data! To enable encryption, please enter your password below.": "Heslo neztrácejte, protože z bezpečnostních důvodů je to *jediný* způsob, jak data dešifrovat! Chcete-li povolit šifrování, zadejte níže heslo.",
"Done": "Hotovo",
"Download": "Stáhnout",
"Download and install the relevant extension for your browser:": "Stáhnout a nainstalovat odpovídající rozšíření pro váš webový prohlížeč:",
"Downloaded": "Staženo",
@@ -223,18 +284,26 @@
"Dropbox Login": "Dropbox přihlášení",
"Duplicate": "Duplikovat",
"Duplicate line": "Duplikovat řádek",
"Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.": "Duplikuje poznámky vyhovující <note> do [notebook]. Pokud není notebook (zápisník) specifikován, je poznámka duplikována v tom současném.",
"Duplicate selected notes": "Duplikovat vybrané poznámky",
"Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.": "Duplikuje poznámky vyhovující <note> do [zápisník]. Pokud není zápisník (zápisník) specifikován, je poznámka duplikována v tom současném.",
"Edit": "Upravit",
"Edit in external editor": "Upravit externím editorem",
"Edit link": "Upravit odkaz",
"Edit note.": "Upravit poznámku.",
"Edit notebook": "Upravit zápisník",
"Edit profile": "Upravit profil",
"Edit profile configuration...": "Upravit konfiguraci profilu...",
"Editor": "Editor",
"Editor font": "Písmo editoru",
"Editor font family": "Rodina písma v editoru",
"Editor font size": "Velikost písma v editoru",
"Editor maximum width": "Maximální šířka editoru",
"Editor monospace font family": "Neproporcionální písmo editoru",
"Editor: %s": "Editor: %s",
"Either \"text\" or \"json\"": "Buď \"text\" nebo \"json\"",
"Emacs": "Emacs",
"Email": "E-mail",
"Emails": "E-maily",
"emphasised text": "zvýrazněný text",
"Enable": "Zapnout",
"Enable ++insert++ syntax": "Povolit syntaxi ++insert++",
@@ -242,6 +311,7 @@
"Enable ^sup^ syntax": "Povolit syntaxi ^sup^",
"Enable abbreviation syntax": "Povolit syntaxi zkratek",
"Enable audio player": "Povolit přehrávač zvuků",
"Enable biometrics authentication?": "Povolit biometrické ověřování?",
"Enable deflist syntax": "Povolit syntaxi deflist",
"Enable encryption": "Zapnout šifrování",
"Enable footnotes": "Povolit poznámky pod čarou",
@@ -254,18 +324,23 @@
"Enable note history": "Povolit historii poznámky",
"Enable PDF viewer": "Povolit zobrazení PDF",
"Enable soft breaks": "Povolit měkké zalomení",
"Enable spellcheck in the text editor": "Povolení kontroly pravopisu v textovém editoru",
"Enable table of contents extension": "Povolit rozšíření pro generování Obsahu",
"Enable typographer support": "Povolit podporu pro typographer",
"Enable video player": "Povolit přehrávač videí",
"Enable Web Clipper Service": "Povolit službu Web clipper",
"Enable ~sub~ syntax": "Povolit syntaxi ~sub~",
"Enabled": "Zapnuto",
"Enabling encryption means *all* your notes and attachments are going to be re-synchronised and sent encrypted to the sync target.": "Povolení šifrování znamená, že *všechny* vaše poznámky a přílohy budou znovu synchronizovány a odeslány do cíle synchronizace šifrovaně. Přejete si pokračovat?",
"Encrypted": "Zašifrováno",
"Encrypted items cannot be modified": "Nelze editovat zašifrovanou položku",
"Encrypted notebooks cannot be renamed": "Nelze přejmenovat zašifrovanou položku",
"Encryption": "Šifrování",
"Encryption Config": "Nastavení šifrování",
"Encryption is: %s": "Šifrování je: %s",
"Encryption keys": "Šifrovací klíče",
"Encryption:": "Šifrování:",
"End-to-end encryption": "Koncové šifrování",
"Enter code here": "Zde vložte kód",
"Enter master password:": "Zadejte hlavní heslo:",
"Enter notebook title": "Vložte název zápisníku",
@@ -278,6 +353,7 @@
"Evernote Export File (as HTML)": "Soubor exportu Evernote (jako HTML)",
"Evernote Export File (as Markdown)": "Soubor exportu Evernote (jako Markdown)",
"Exits the application.": "Ukončí aplikaci.",
"Expand": "Rozšířit",
"Export": "Exportovat",
"Export all": "Exportovat vše",
"Export debug report": "Exportovat ladicí hlášení",
@@ -291,10 +367,14 @@
"Fail-safe": "Ochrana proti ztrátě dat",
"Fail-safe: Do not wipe out local data when sync target is empty (often the result of a misconfiguration or bug)": "Zabezpečení proti selhání: Nemazat místní data, pokud je cíl synchronizace prázdný (často v důsledku nesprávné konfigurace nebo chyby)",
"Fatal error:": "Fatální chyba:",
"Feature flags": "Příznaky funkcí",
"Fetched items: %d/%d.": "Získané položky: %d/%d.",
"Fetching resources: %d/%d": "Stahování zdrojů: %d/%d",
"File": "Soubor",
"File system": "Souborový systém",
"Filter tags": "Filtrovat štítky",
"Find and replace": "Najít a nahradit",
"Find: ": "Najít: ",
"Firefox Extension": "Doplněk pro Firefox",
"Fix search index": "Opravit vyhledávací index",
"Fixing search index...": "Probíhá oprava vyhledávacího indexu...",
@@ -303,33 +383,49 @@
"Focus title": "Kurzor v názvu",
"Folders": "Složky",
"For debugging purpose only: export your profile to an external SD card.": "Pouze pro účely ladění: exportovat profil na externí SD kartu.",
"For example \"%s\"": "Například \"%s\"",
"For information on how to customise the shortcuts please visit %s": "Pro informace k úpravě klávesových zkratek prosím běžte na %s",
"For more information about End-To-End Encryption (E2EE) and advice on how to enable it please check the documentation:": "Více informací o koncovém šifrování (E2EE) a návod, jak ho povolit, najdete v dokumentaci:",
"For the list of keyboard shortcuts and config options, type `help keymap`": "Pro seznam klávesových zkratek a konfiguračních voleb zadejte `help keymap`",
"Force path style": "Vynutit styl cesty",
"Formatting": "Formátování",
"Forward": "Vpřed",
"Found: %d.": "Nalezeno: %d.",
"FTS enabled: %d": "FTS povolené: %d",
"Full changelog": "Úplný seznam změn",
"Full name": "Celé jméno",
"General": "Obecná nastavení",
"Generated": "Generováno",
"Generating link...": "Vytváření odkazu...",
"Get it now:": "Získat hned:",
"Get pre-releases when checking for updates": "Při hledání aktualizací zahrnout beta verze",
"Gets or sets a config value. If [value] is not provided, it will show the value of [name]. If neither [name] nor [value] is provided, it will list the current configuration.": "Získá nebo nastaví konfigurační hodnotu. Pokud není [hodnota] specifikována, zobrazí hodnotu položky [jméno]. Pokud není specifikována [hodnota] ani [jméno], je zobrazena současná konfigurace.",
"Go to source URL": "Jít na zdrojovou URL",
"Goto Anything...": "Přejít na...",
"Grant authorisation": "Udělení povolení",
"Header %d": "Záhlaví %d",
"Headers": "Záhlaví",
"Heading": "Nadpis",
"Help": "Nápověda",
"Hide %s": "Schovat %s",
"Hide advanced": "Skrýt pokročilé",
"Hide disabled": "Skrýt vypnuté",
"Hide disabled keys": "Skrýt vypnuté klávesy",
"Hide Joplin": "Skrýt Joplin",
"Hide keyboard": "Skrytí klávesnice",
"Hide more actions": "Skrýt další akce",
"Highlight": "Zvýraznění",
"Home": "Domů",
"Horizontal Rule": "Horizontální čára",
"HTML Directory": "HTML adresář",
"HTML File": "HTML soubor",
"Hyperlink": "Odkaz",
"Icon": "Ikona",
"ID": "ID",
"Idle": "Nečinný",
"Ignore": "Ignorovat",
"Ignore TLS certificate errors": "Ignorovat chyby TLS",
"Images": "Obrázky",
"Import": "Importovat",
"Importing from \"%s\" as \"%s\" format. Please wait...": "Probíhá import z \"%s\" ve formátu \"%s\". Počkejte prosím...",
"Importing notes...": "Probíhá import poznámky...",
@@ -342,12 +438,14 @@
"In order to use the web clipper, you need to do the following:": "Pro použití web clipper musíte udělat následující:",
"In progress": "Probíhá",
"In: %s": "V: %s",
"Increase indent level": "Zvýšení úrovně odsazení",
"Indent less": "Zmenšit odsazení",
"Indent more": "Zvětšit odsazení",
"Information": "Informace",
"Inline Code": "Vložený kód",
"Insert": "Vložit",
"Insert Hyperlink": "Vložit odkaz",
"Insert time": "Vložit datum a čas",
"Install": "Nainstalovat",
"Install from file": "Nainstalovat ze souboru",
"Installed": "Nainstalováno",
@@ -357,10 +455,14 @@
"Invalid answer: %s": "Neplatná odpověď: %s",
"Invalid command: \"%s\"": "Neplatný příkaz: \"%s\"",
"Invalid option value: \"%s\". Possible values are: %s.": "Neplatná hodnota: \"%s\". Přípustné hodnoty jsou: %s.",
"Invalid password": "Neplatné heslo",
"Italic": "Kurzíva",
"Item \"%s\" could not be downloaded: %s": "Soubor \"%s\" se nepodařilo stáhnout: %s",
"Items": "Položky",
"Items that cannot be decrypted": "Položky jež nelze dešifrovat",
"Items that cannot be synchronised": "Položky jež nelze synchronizovat",
"Join us on Twitter": "Připojte se k nám na Twitteru",
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin dokáže synchronizovat vaše poznámky pomocí různých poskytovatelů. Vyberte si některého z nich z níže uvedeného seznamu.",
"Joplin Cloud": "Joplin cloud",
"Joplin Cloud email": "E-mailová adresa Joplin cloudu",
"Joplin Cloud password": "Heslo Joplin cloudu",
@@ -374,40 +476,66 @@
"Joplin Server URL": "URL Joplin serveru",
"Joplin Web Clipper allows saving web pages and screenshots from your browser to Joplin.": "Joplin Web Clipper umožňuje ukládat webové stránky a screenshoty z vašeho prohlížeče do Joplin.",
"Joplin website": "Web Joplinu",
"Joplin's own sync service. Also gives access to Joplin-specific features such as publishing notes or collaborating on notebooks with others.": "Joplinova vlastní synchronizační služba. Umožňuje také přístup k funkcím specifickým pro Joplin, jako je publikování poznámek nebo spolupráce na zápisnících s ostatními.",
"KaTeX": "KaTeX",
"Keep note history for": "Uchovat historii poznámky",
"Keyboard Mode": "Režim klávesnice",
"Keyboard Shortcut": "Klávesová zkratka",
"Keyboard Shortcuts": "Klávesové zkratky",
"Keychain Supported: %s": "Podpora klíčenky: %s",
"Keys that need upgrading": "Klíče, které je třeba aktualizovat",
"Landscape": "Na šířku",
"Language": "Jazyk",
"Last error: %s": "Poslední chyba: %s",
"Later": "Později",
"Layout": "Rozložení",
"Layout button sequence": "Posloupnost pro tlačítko Rozložení",
"Leave notebook...": "Zanechte zápisník...",
"Legal": "Legal",
"Letter": "Dopis",
"Light": "Světlý",
"Lines": "Řádky",
"Link": "Odkaz",
"Link description": "Popis odkazu",
"Link has been copied to clipboard!": "Odkaz byl zkopírován do schránky!",
"Link text": "Text odkazu",
"Links with protocol \"%s\" are not supported": "Odkazy s protokolem \"%s\" nejsou podporovány",
"List item": "Seznam položek",
"Lists": "Seznamy",
"Loaded": "Načteno",
"Location": "Poloha",
"Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at \"%s\" and resume the operation.": "Již je držen soubor se zámkem (lock file). Pokud jste si jistí, že nyní neprobíhá synchronizace, smažte zámek v \"%s\" a pokračujte v operaci.",
"Log": "Log",
"Login": "Přihlášení",
"Login below.": "Přihlaste se níže.",
"Login with Dropbox": "Přihlášení Dropbox",
"Login with OneDrive": "Přihlásit se pomocí OneDrive",
"Logout": "Odhlásit se",
"Logs": "Logy",
"Make a donation": "Přispět",
"Manage master password": "Správa hlavního hesla",
"Manage master password...": "Správa hlavního hesla...",
"Manage multiple users": "Správa více uživatelů",
"Manage profiles": "Správa profilů",
"Manage your plugins": "Správa vašich rozšíření",
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Spravuje konfiguraci koncového šifrování. Příkazy jsou `zapnout`, `vypnout`, `dešifrovat`, `stav`, `dešifrovat soubor` a `cílový stav`.",
"Manual": "Ručně",
"Markdown": "Markdown",
"Markdown + Front Matter": "Markdown + Front Matter",
"Marks a to-do as done.": "Označí úkol jako hotový.",
"Marks a to-do as non-completed.": "Označí úkol jako nedokončený.",
"Markup": "Markup",
"Master Key %s": "Hlavní klíč %s",
"Master password": "Hlavní heslo",
"Master password:": "Hlavní heslo:",
"Max concurrent connections": "Maximální počet souběžných spojení",
"Max Item Size": "Maximální velikost položky",
"Max note or attachment size": "Maximální velikost poznámky nebo přílohy",
"Max Total Size": "Maximální celková velikost",
"Missing keys": "Chybějící klíče",
"Missing Master Keys": "Chybí hlavní klíče",
"Missing required argument: %s": "Chybí povinný parametr: %s",
"Missing required flag value: %s": "Chybí požadovaná hodnota příznaku: %s",
"Mobile data - auto-sync disabled": "Mobilní data - automatická synchronizace vypnutá",
"More info": "Více informací",
"More information": "Více informací",
@@ -416,6 +544,7 @@
"Move to notebook": "Přesunout do zápisníku",
"Move to notebook...": "Přesunout do zápisníku...",
"Move to notebook:": "Přesunout do zápisníku:",
"Moves the given <item> to [notebook]": "Přesune zadanou <item> do [notebook]",
"n": "n",
"N": "N",
"New note": "Nová poznámka",
@@ -426,6 +555,7 @@
"New tags:": "Nové štítky:",
"New to-do": "Nový úkol",
"New version: %s": "Nová verze: %s",
"Next match": "Další zápas",
"Nextcloud": "Nextcloud",
"Nextcloud password": "Nextcloud heslo",
"Nextcloud username": "Nextcloud uživatelské jméno",
@@ -445,6 +575,8 @@
"Nord": "Nord",
"Not authentified with %s. Please provide any missing credentials.": "Nepřihlášeno k %s. Prosím vyplňte chybějící přihlašovací údaje.",
"Not downloaded": "Nestaženo",
"Not generated": "Nevygenerováno",
"Not now": "Vyzkoušejte to hned",
"note": "Nová poznámka",
"Note": "Zápisníky",
"Note area growth factor": "Růstový faktor oblasti s poznámkami",
@@ -452,6 +584,7 @@
"Note attachments...": "Přílohy poznámky...",
"Note body": "Tělo poznámky",
"Note does not exist: \"%s\". Create it?": "Poznámka \"%s\" neexistuje. Chcete ji vytvořit?",
"Note editor": "Poznámka editora",
"Note has been saved.": "Poznámka uložena.",
"Note History": "Historie poznámek",
"Note is not a to-do: \"%s\"": "Poznámka není úkol: \"%s\"",
@@ -462,10 +595,12 @@
"Note&book": "&Zápisník",
"Note: Does not work in all desktop environments.": "Poznámka: Nefunguje v některých desktopových prostředích.",
"Note: When a note is shared, it will no longer be encrypted on the server.": "Poznámka: pokud je poznámka sdílena, už nebude na serveru šifrována.",
"Notebook list growth factor": "Růstový faktor seznamu notebooků",
"Notebook": "Zápisníky",
"Notebook list growth factor": "Růstový faktor seznamu zápisníků",
"Notebook: %s": "Zápisník: %s",
"Notebooks": "Zápisníky",
"Notebooks cannot be named \"%s\", which is a reserved title.": "Zápisník se nemůže jmenovat \"%s\", tento název je rezervován.",
"Notes": "Poznámky",
"Notes and settings are stored in: %s": "Poznámky a nastavení uloženo v: %s",
"Notes can only be created within a notebook.": "Poznámky mohou být vytvořeny pouze v zápisnících.",
"Numbered List": "Číslovaný seznam",
@@ -480,10 +615,15 @@
"Only one note can be printed at a time.": "Naráz lze vytisknout pouze jednu poznámku.",
"Open": "Otevřít",
"Open %s": "Otevřít %s",
"Open PDF viewer": "Otevřít prohlížeč PDF",
"Open profile directory": "Otevřít složku s profilem",
"Open Sync Wizard...": "Otevřete Průvodce synchronizací...",
"Open...": "Otevřít...",
"Operation cancelled": "Operace zrušena",
"Options": "Nastavení",
"Or create an account.": "Nebo si vytvořte účet.",
"Ordered list": "Seznam objednávek",
"Other applications...": "Další aplikace...",
"Output format: %s": "Výstupní formát: %s",
"Page orientation for PDF export": "Orientace stránky pro PDF export",
"Page size for PDF export": "Velikost stránky pro PDF export",
@@ -492,12 +632,16 @@
"Password:": "Heslo:",
"Passwords do not match!": "Hesla se neshodují!",
"Paste": "Vložit",
"Paste as text": "Vložit jako text",
"Path:": "Cesta:",
"PDF File": "PDF soubor",
"Per user. Minimum of %d users.": "Na uživatele. Minimálně %d uživatelů.",
"Permission needed": "Vyžadováno oprávnění",
"Permission to use camera": "Oprávnění použít kameru",
"Please click on \"%s\" to proceed, or set the passwords in the \"%s\" list below.": "Pro pokračování klikněte na \"%s\" nebo nastavte hesla v seznamu \"%s\" níže.",
"Please confirm that you would like to re-encrypt your complete database.": "Potvrďte prosím, že chcete znovu zašifrovat celou databázi.",
"Please enter your password in the master key list below before upgrading the key.": "Před upgradem klíče zadejte své heslo do níže uvedeného seznamu hlavních klíčů.",
"Please note that if it is a large notebook, it may take a few minutes for all the notes to show up on the recipient's device.": "Upozorňujeme, že pokud se jedná o velký zápisník, může trvat několik minut, než se všechny poznámky zobrazí v zařízení příjemce.",
"Please open the following URL in your browser to authenticate the application. The application will create a directory in \"Apps/Joplin\" and will only read and write files in this directory. It will have no access to any files outside this directory nor to any other personal data. No data will be shared with any third party.": "Otevřete prosím následující URL ve vašem prohlížeči pro autentizaci aplikace. Joplin vytvoří a bude používat výhradně složku \"Apps/Joplin\" , nebude mít přístup k souborům mimo tuto složku ani k dalším osobním informacím. Žádná data nebudou sdílena s jakoukoliv třetí stranou.",
"Please select a notebook first.": "Nejprve prosím vyberte zápisník.",
"Please select the note or notebook to be deleted first.": "Nejprve prosím vyberte poznámku či zápisník ke smazání.",
@@ -520,11 +664,28 @@
"Press the shortcut": "Stiskněte klávesovou zkratku",
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the shortcut.": "Stiskněte klávesovou zkratku a poté stiskněte ENTER. Nebo klávesovou zkratku vymažte stisknutím BACKSPACE.",
"Press to set the decryption password.": "Stiskněte pro zadání hesla k dešifrování.",
"Previous match": "Předchozí zápas",
"Previous versions of this note": "Předchozí verze poznámky",
"Print": "Tisk",
"Priority support": "Prioritní podpora",
"Privacy Policy": "Zásady ochrany osobních údajů",
"Pro": "Pro",
"Process failed payment subscriptions": "Zpracování neúspěšných platebních odběrů",
"Process oversized accounts": "Zpracování předimenzovaných účtů",
"Process user deletions": "Zpracování odstranění uživatelů",
"Profile": "Profil",
"Profile name": "Název profilu",
"Profile name:": "Jméno profilu:",
"Profile Version: %s": "Verze profilu: %s",
"Profiles": "Profily",
"Properties": "Nastavení",
"Proxy enabled": "Proxy server povolen",
"Proxy timeout (seconds)": "Proxy timeout (sekundy)",
"Proxy URL": "Proxy adresa",
"Public-private key pair:": "Párovat veřejného a soukromého klíče:",
"Publish note...": "Zveřejněte poznámku...",
"Publish Notes": "Zveřejnit poznámky",
"Publish notes to the internet": "Zveřejnění poznámek na internetu",
"Quit": "Ukončit",
"Re-encrypt data": "Znovu zašifrovat data",
"Re-encryption": "Opětovné zašifrování",
@@ -537,6 +698,7 @@
"Recipients:": "Příjemci:",
"Redo": "Provést znovu",
"Refresh": "Obnovit",
"Regular expression": "Regulární výraz",
"Reject": "Odmítnout",
"Remove": "Odstranit",
"Remove tag \"%s\" from all notes?": "Odebrat štítek \"%s\" ze všech poznámek?",
@@ -546,6 +708,12 @@
"Rename tag:": "Přejmenovat štítek:",
"Renames the given <item> (note or notebook) to <name>.": "Přejmenuje <položku> (poznámku či zápisník) na <jméno>.",
"Renew token": "Obnovit token",
"Replace": "Nahradit",
"Replace all": "Nahradit vše",
"Replace with...": "Nahradit s...",
"Replace: ": "Nahradit: ",
"Reset application layout": "Obnovit rozložení aplikace",
"Reset master password": "Obnovit hlavní heslo",
"Resources: %d.": "Zdroje: %d.",
"Restart and upgrade": "Restartovat a upgradovat",
"Restart now": "Restartovat",
@@ -558,38 +726,58 @@
"Reverses the sorting order.": "Řadit opačně.",
"Revision: %s (%s)": "Revize: %s (%s)",
"Runs the commands contained in the text file. There should be one command per line.": "Spustí příkazy z textového souboru. Každý příkaz by měl být na vlastním řádku.",
"S3": "S3",
"S3 access key": "S3 přístupový klíč",
"S3 bucket": "S3 bucket",
"S3 region": "S3 region",
"S3 secret key": "S3 tajný klíč",
"S3 URL": "S3 Adresa",
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "Aplikace je spuštěna v nouzovém režimu. Vykreslování poznámek a všechna rozšíření jsou dočasné vypnutá.",
"Save": "Uložit",
"Save alarm": "Nastavit alarm",
"Save as %s": "Uložit jako %s",
"Save as...": "Uložit jako...",
"Save changes": "Uložit změny",
"Save geo-location with notes": "Ukládat k poznámkám informace o zeměpisné poloze",
"Search": "Hledání",
"Search for plugins...": "Hledat rozšíření...",
"Search for...": "Hledat...",
"Search in all the notes": "Hledat ve všech poznámkách",
"Search in current note": "Hledat v aktuální poznámce",
"Search...": "Hledat...",
"Search:": "Hledat:",
"Searches for the given <pattern> in all the notes.": "Hledá <zadání> ve všech poznámkách.",
"See the pre-release page for more details: %s": "Pro náhled beta verzí navštivte stránku: %s",
"Select": "Vybrat",
"Select all": "Vybrat vše",
"Select emoji...": "Vybrat emoji...",
"Select file...": "Vybrat soubor...",
"Server is already running on port %d": "Server je již spuštěný na portu %d",
"Server is not running.": "Server není spuštěný.",
"Server is running on port %d": "Server je spuštěný na portu %d",
"Set alarm": "Nastavit alarm",
"Set alarm:": "Nastavit alarm:",
"Set it to 0 to make it take the complete available space. Recommended width is 600.": "Nastavte ji na 0, aby zabírala celý dostupný prostor. Doporučená šířka je 600.",
"Set the password": "Nastavit heslo",
"Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s": "Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s",
"Share": "Sdílet",
"Share and collaborate on a notebook": "Sdílení a spolupráce na zápisníku",
"Share Notebook": "Sdílet zápisník",
"Share notebook...": "Sdílet zápisník...",
"Sharing access control": "Kontrola sdílení přístupu",
"Sharing notebook...": "Sdílení zápisníku...",
"Shortcuts are not available in CLI mode.": "Klávesové zkratky nejsou v konzoli dostupné.",
"Show advanced": "Pokročilá nastavení",
"Show Advanced Settings": "Pokročilá nastavení",
"Show all": "Zobrazit vše",
"Show completed to-dos": "Zobrazit dokončené úkoly",
"Show disabled": "Zobrazit vypnuté",
"Show disabled keys": "Zobrazit vypnuté klávesy",
"Show more actions": "Zobrazit další akce",
"Show note counts": "Zobrazit počty poznámek",
"Show sort order buttons": "Zobrazit tlačítka řazení",
"Show tray icon": "Zobrazovat ikonu v panelu",
"Show/hide the sidebar": "Zobrazit/skrýt boční panel",
"Sidebar": "Postranní lišta",
"Size": "Velikost",
"Skip this version": "Přeskočit tuto verzi",
@@ -605,6 +793,7 @@
"Sort selected lines": "Seřadit vybrané řádky",
"Sorts the item by <field> (eg. title, updated_time, created_time).": "Řadit položky podle <pole> (např. title, updated_time, created_time).",
"Source format: %s": "Zdrojový formát: %s",
"Source: ": "Zdroj: ",
"Specify the port that should be used by the API server. If not set, a default will be used.": "Určete port, který by měl server API používat. Pokud není nastavena, použije se výchozí.",
"Spell checker": "Kontrola pravopisu",
"Split View": "Přepnout pohled",
@@ -624,6 +813,7 @@
"Step 2: Install the extension": "Krok 2: Nainstalovat rozšíření",
"Stop": "Zastavit",
"Stop external editing": "Ukončit externí úpravy",
"Storage space": "Úložiště",
"Strikethrough": "Přeškrtnutí",
"strong text": "tučný text",
"Submit": "Odeslat",
@@ -633,15 +823,19 @@
"Swap line down": "Prohodit s řádkem níže",
"Swap line up": "Prohodit s řádkem výše",
"Switch between note and to-do type": "Přepnout mezi poznámkou a úkolem",
"Switch profile": "Přepnout profil",
"Switch to note type": "Přepnout na poznámku",
"Switch to profile %d": "Přepnutí na profil %d",
"Switch to to-do type": "Přepnout na úkol",
"Switches to [notebook] - all further operations will happen within this notebook.": "Přepne do zápisníku [notebook]. Všechny další operace budou prováděny na tomto zápisníku.",
"Switches to [notebook] - all further operations will happen within this notebook.": "Přepne do zápisníku [zápisník]. Všechny další operace budou prováděny na tomto zápisníku.",
"Sync as many devices as you want": "Synchronizace libovolného počtu zařízení",
"Sync Status": "Stav synchronizace",
"Sync status (synced items / total items)": "Stav synchronizace (synchronizováno / celkem)",
"Sync target must be upgraded! Run `%s` to proceed.": "Je třeba upgradovat cíl synchronizace. Chcete-li pokračovat, spusťte `%s`.",
"Sync Target Upgrade": "Upgrade cíle synchronizace",
"Sync to provided target (defaults to sync.target config value)": "Synchronizovat do vybraného cíle (nebo výchozí hodnota sync.target z konfigurace)",
"Sync Version: %s": "Verze synchronizace: %s",
"Sync your notes": "Synchronizace poznámek",
"Synchronisation": "Synchronizace",
"Synchronisation interval": "Interval synchronizace",
"Synchronisation is already in progress.": "Synchronizace již probíhá.",
@@ -654,11 +848,18 @@
"Synchronising...": "Probíhá synchronizace...",
"Synchronizing...": "Probíhá synchronizace...",
"Tabloid": "Tabloid",
"tag1, tag2, ...": "štítek1, štítek2, ...",
"Tagged: %d.": "Označeno pomocí štítků: %d.",
"Tags": "Štítky",
"Take photo": "Přiložit foto",
"Task list": "Seznam úkolů",
"Tasks": "Úkoly",
"Teams": "Týmy",
"Text editor command": "Textový editor",
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Děkujeme! Váš účet Joplin Cloud je nyní nastaven a připraven k použití.",
"The active profile cannot be deleted. Switch to a different profile and try again.": "Aktivní profil nelze odstranit. Přepněte na jiný profil a zkuste to znovu.",
"The app is now going to close. Please relaunch it to complete the process.": "Aplikace se nyní vypne. Pro dokončení procesu ji znovu spusťte.",
"The application did not close properly. Would you like to start in safe mode?": "Aplikace se správně neuzavřela. Chcete ji spustit v nouzovém režimu?",
"The application has been authorised - you may now close this browser tab.": "Aplikace byla autorizována, tento tab můžete zavřít.",
"The application has been authorised!": "Aplikace byla úspěšně autorizována!",
"The application has been successfully authorised.": "Aplikace byla úspěšně autorizována.",
@@ -668,27 +869,37 @@
"The default admin password is insecure and has not been changed! [Change it now](%s)": "Výchozí heslo správce není bezpečné a ještě nebylo změněno. [Změňte ho nyní!](%s)",
"The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.": "Výchozí metoda šifrování byla změněna na bezpečnější variantu a doporučuje se použít ji na vaše data.",
"The default encryption method has been changed, you should re-encrypt your data.": "Výchozí metoda šifrování byla změněna, měli byste data znovu zašifrovat.",
"The default profile cannot be deleted": "Výchozí profil nelze odstranit",
"The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.": "Příkaz editoru (může obsahovat argumenty) ve kterém budou otevírány poznámky. Pokud není určeno, aplikace se pokusí o automatické rozpoznání výchozího editoru.",
"The factor property sets how the item will grow or shrink to fit the available space in its container with respect to the other items. Thus an item with a factor of 2 will take twice as much space as an item with a factor of 1.Restart app to see changes.": "Vlastnost faktor určuje, jak se má položka zvětšit nebo zmenšit, aby se vešla na volné místo v kontejneru vzhledem k ostatním položkám. Položka s faktorem 2 tedy zabere dvakrát tolik místa než položka s faktorem 1. Pro zobrazení změn restartujte aplikaci.",
"The following attachments are being watched for changes:": "Následující přílohy jsou sledovány, zda došlo k jejich změně:",
"The following keys use an out-dated encryption algorithm and it is recommended to upgrade them. The upgraded key will still be able to decrypt and encrypt your data as usual.": "Následující klíče používají zastaralý šifrovací algoritmus a doporučujeme je aktualizovat. Aktualizovaný klíč bude stále schopen dešifrovat a šifrovat vaše data jako obvykle.",
"The Joplin mobile app does not currently support this type of link: %s": "Mobilní aplikace Joplin aktuálně nepodporuje tento typ odkazu: %s",
"The Joplin team has vetted this plugin and it meets our standards for security and performance.": "Tým Joplin tento plugin prověřil a splňuje naše standardy zabezpečení a výkonu.",
"The keys with these IDs are used to encrypt some of your items, however the application does not currently have access to them. It is likely they will eventually be downloaded via synchronisation.": "Klíče s těmito ID se používají k šifrování některých položek, ale aplikace k nim v současné době nemá přístup. Je pravděpodobné, že budou nakonec staženy prostřednictvím synchronizace.",
"The master key has been upgraded successfully!": "Hlavní klíč byl úspěšně upgradován!",
"The master keys with these IDs are used to encrypt some of your items, however the application does not currently have access to them. It is likely they will eventually be downloaded via synchronisation.": "Hlavní klíče s těmito ID byly použity k zašifrování položek, které momentálně nejsou k dispozici. Je pravděpodobné, že tyto položky budou staženy při synchronizaci.",
"The note \"%s\" has been successfully restored to the notebook \"%s\".": "Poznámka \"%s\" byla úspěšně obnovena v zápisníku \"%s\".",
"The notebook could not be saved: %s": "Nebylo možné uložit zápisník: %s",
"The notes have been imported: %s": "Poznámky importovány: %s",
"The possible commands are:": "Dostupné příkazy:",
"The recipient could not be removed from the list. Please try again.\n\nThe error was: \"%s\"": "Příjemce nebylo možné ze seznamu odstranit. Zkuste to prosím znovu.\n\nChyba byla: \"%s\"",
"The sync target needs to be upgraded before Joplin can sync. The operation may take a few minutes to complete and the app needs to be restarted. To proceed please click on the link.": "Před synchronizací je třeba upgradovat její cíl. Dokončení operace může trvat několik minut a je třeba aplikaci restartovat. Chcete-li pokračovat, klepněte na odkaz.",
"The sync target needs to be upgraded. Press this banner to proceed.": "Cíl synchronizace je třeba aktualizovat. Stiskněte tento banner a pokračujte.",
"The tag \"%s\" already exists. Please choose a different name.": "Štítek \"%s\" už existuje. Zadejte jiný název.",
"The target to synchronise to. Each sync target may have additional parameters which are named as `sync.NUM.NAME` (all documented below).": "Cíl synchronizace. Každý cíl může mít další parametry ve formátu `sync.NUM.NAME` (dokumentace níže).",
"The Web Clipper needs your authorisation to access your data.": "Web Clipper potřebuje k přístupu k vašim údajům vaše oprávnění.",
"The web clipper service is enabled and set to auto-start.": "Služba Web clipper je povolena a nastavena pro zapnutí při spuštění.",
"The web clipper service is not enabled.": "Služba Web clipper není povolena.",
"The WebDAV implementation of %s is incompatible with Joplin, and as such is no longer supported. Please use a different sync method.": "Implementace WebDAV %s je nekompatibilní s Joplinem, a proto již není podporována. Použijte prosím jinou metodu synchronizace.",
"Theme": "Vzhled",
"There are currently no notes. Create one by clicking on the (+) button.": "Žádné poznámky. Novou vytvořte klepnutím na tlačítko (+).",
"There are unsaved changes.": "Existují neuložené změny.",
"There is currently no notebook. Create one by clicking on \"New notebook\".": "Nemáte žádný zápisník. Nový vytvoříte klepnutím na \"Nový zápisník\".",
"There is no data to export.": "Nic k exportování.",
"There was a [conflict](%s) on the attachment below.\n\n%s": "V příloze níže došlo ke [konfliktu] (%s).\n\n%s",
"There was an error downloading this attachment:": "Při stahování této přílohy došlo k chybě:",
"There was an error setting up your Joplin Cloud account. Please verify your email and password and try again. Error was:\n\n%s": "Při nastavování vašeho účtu Joplin Cloud došlo k chybě. Ověřte prosím svůj e-mail a heslo a zkuste to znovu. Chyba:\n\n%s",
"These items will remain on the device but will not be uploaded to the sync target. In order to find these items, either search for the title or the ID (which is displayed in brackets above).": "Tyto položky zůstanou na tomto zařízení, ale nebudou uploadovány na cíl synchronizace. Pro přístup k těmto souborům hledejte jejich název nebo ID (v hranatých závorkách).",
"These plugins enhance the Markdown renderer with additional features. Please note that, while these features might be useful, they are not standard Markdown and thus most of them will only work in Joplin. Additionally, some of them are *incompatible* with the WYSIWYG editor. If you open a note that uses one of these plugins in that editor, you will lose the plugin formatting. It is indicated below which plugins are compatible or not with the WYSIWYG editor.": "Tyto doplňky vylepšují vykreslovací modul Markdown o další funkce. Upozorňujeme, že i když tyto funkce mohou být užitečné, nejedná se o standardní Markdown, a proto většina z nich bude fungovat pouze v Joplinu. Některé z nich jsou navíc *nekompatibilní* s editorem WYSIWYG. Pokud v tomto editoru otevřete poznámku, která používá jeden z těchto pluginů, ztratíte formátování pluginu. Níže je uvedeno, které doplňky jsou nebo nejsou kompatibilní s editorem WYSIWYG.",
"This attachment is not downloaded or not decrypted yet": "Tato příloha ještě není stažena nebo dešifrována",
@@ -703,10 +914,12 @@
"This service allows the browser extension to communicate with Joplin. When enabling it your firewall may ask you to give permission to Joplin to listen to a particular port.": "Tato služba umožňuje rozšíření prohlížeče o komunikaci s Joplin. Pokud jej povolíte, může vás firewall požádat, abyste Joplin dali svolení naslouchat na určitém portu.",
"This will allow Joplin to run in the background. It is recommended to enable this setting so that your notes are constantly being synchronised, thus reducing the number of conflicts.": "Toto umožní Joplin běžet na pozadí. Doporučujeme toto nastavení povolit tak, aby se vaše poznámky neustále synchronizovaly, čímž se sníží počet konfliktů.",
"This will open a new screen. Save your current changes?": "Toto otevře nové okno. Chcete uložit současné změny?",
"This will remove the notebook from your collection and you will no longer have access to its content. Do you wish to continue?": "Tím sešit odstraní z vaší sbírky a vy již nebudete mít přístup k jeho obsahu. Chcete pokračovat?",
"Time format": "Formát času",
"title": "název",
"Title": "Název",
"To allow Joplin to synchronise with Dropbox, please follow the steps below:": "Pro povolení synchronizace Joplinu se službou Dropbox postupujte podle následujících kroků:",
"To continue, please enter your master password below.": "Chcete-li pokračovat, zadejte níže své hlavní heslo.",
"To delete a tag, untag the associated notes.": "Před smazáním štítku ho odeberte od přiřazených poznámek.",
"To delete: %d": "K smazání: %d",
"To enter command line mode, press \":\"": "Pro přepnutí do příkazové řádky stiskněte \":\"",
@@ -715,20 +928,26 @@
"To maximise/minimise the console, press \"tc\".": "Pro maximalizaci/minimalizaci konzole stiskněte \"tc\".",
"To move from one pane to another, press Tab or Shift+Tab.": "Pro přepínání mezi panely stiskněte Tab / Shift+Tab.",
"To retry decryption of these items. Run `e2ee decrypt --retry-failed-items`": "Pro nový pokus o dešifrování těchto položek spusťte ʻe2ee decrypt --retry-failed-items`",
"To switch the profile, the app is going to close and you will need to restart it.": "Chcete-li profil přepnout, aplikace se zavře a musíte ji znovu spustit.",
"To work correctly, the app needs the following permissions. Please enable them in your phone settings, in Apps > Joplin > Permissions": "Aby aplikace fungovala správně, potřebuje následující oprávnění. Povolte je v nastavení telefonu v aplikaci Aplikace> Joplin> Oprávnění",
"to-do": "Nový úkol",
"to-do: %s": "Úkol: %s",
"Toggle comment": "Přepnout komentář",
"Toggle development tools": "Zobrazit/skrýt nástroje pro vývojáře",
"Toggle editor layout": "Změnit rozložení editoru",
"Toggle editors": "Přepnout editory",
"Toggle external editing": "Upravit v externím textovém editoru",
"Toggle note list": "Zobrazit/skrýt seznam poznámek",
"Toggle own sort order": "Přepínání vlastního řazení",
"Toggle safe mode": "Přepnout nouzový režim",
"Toggle sidebar": "Zobrazit/skrýt postranní lištu",
"Toggle sort order field": "Přepínání pole řazení",
"Token has been copied to the clipboard!": "Token byl zkopírován do schránky!",
"Tools": "Nástroje",
"Total Size": "Celková velikost",
"Total: %d/%d": "Celkem: %d/%d",
"Try again": "Zkusit znovu",
"Try it now": "Vyzkoušejte to nyní",
"Type `help [command]` for more information about a command; or type `help all` for the complete usage information.": "Zadejte `help [příkaz]` pro více informací o příkazu; nebo `help all` pro kompletní nápovědu.",
"Type `joplin help` for usage information.": "Zadejte `joplin help` pro nápovědu.",
"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. Or type : to search for commands.": "Zadejte název poznámky, na kterou chcete přeskočit, nebo část jejího obsahu. Nebo zadejte # následovaný názvem štítku, @ následovaný názvem poznámky, nebo : pro vyhledávání příkazů.",
@@ -738,16 +957,21 @@
"Undo": "Zpět",
"Unknown flag: %s": "Neznámý flag: %s",
"Unknown item type downloaded - please upgrade Joplin to the latest version": "Stažena položka zatím neznámého typu - aktualizujte prosím Joplin na nejnovější verzi",
"Unordered list": "Neuspořádaný seznam",
"Unpublish note": "Přestat sdílet poznámku",
"Unshare": "Přestat sdílet",
"Unshare this notebook? The recipients will no longer have access to its content.": "Opravdu chcete přestat sdílet tento zápisník? Příjemci už pak nebudou mít přístup k jeho obsahu.",
"Unsupported image type: %s": "Nepodporovaný formát obrázku: %s",
"Unsupported link or message: %s": "Nepodporovaný odkaz či zpráva: %s",
"Untitled": "Bez názvu",
"Update": "Aktualizovat",
"Update profile": "Aktualizovat profil",
"Update total sizes": "Aktualizace celkových velikostí",
"Updated": "Upraveno",
"updated date": "datum aktualizace",
"Updated local items: %d.": "Položky aktualizované lokálně: %d.",
"Updated remote items: %d.": "Položky aktualizované na vzdáleném úložišti: %d.",
"Updated: ": "Upraveno: ",
"Updated: %d.": "Upraveno: %d.",
"Updated: %s": "Upraveno: %s",
"Updating...": "Probíhá aktualizace...",
@@ -755,13 +979,19 @@
"Upgrade the sync target to the latest version.": "Upgradovat cíl synchronizace na nejnovější verzi.",
"URL": "URL",
"Usage: %s": "Použití: %s",
"Use biometrics to secure access to the app": "Použití biometrických údajů pro zabezpečení přístupu k aplikaci",
"Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE": "Použít formát dlouhého seznamu. Formát je ID, NOTE_COUNT (u zápisníků), DATE, TODO_CHECKED (pro úkoly), TITLE",
"Use spell checker": "Použít kontrolu pravopisu",
"Use the arrows and page up/down to scroll the lists and text areas (including this console).": "Pro pohyb v seznamech a textových polích (včetně této konzole) používejte šipky a page up/down.",
"Use the arrows to move the layout items. Press \"Escape\" to exit.": "Pro přesun položek v rozložení použijte šipky. Pro ukončení změn stiskněte klávesu \"Escape\".",
"Use this to rebuild the search index if there is a problem with search. It may take a long time depending on the number of notes.": "Použijte toto k opětovnému vytvoření indexu vyhledávání, pokud dojde k problému s vyhledáváním. Toto může trvat dlouho, v závislosti na počtu poznámek.",
"Use your biometrics to secure access to your application. You can always set it up later in Settings.": "K zabezpečení přístupu do aplikace použijte své biometrické údaje. Vždy ji můžete nastavit později v Nastavení.",
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Používá se pro většinu textu v editoru Markdownu. Pokud nebude nalezeno, bude použito obecné proporcionální písmo s různou šířkou znaků.",
"Used where a fixed width font is needed to lay out text legibly (e.g. tables, checkboxes, code). If not found, a generic monospace (fixed width) font is used.": "Používá se, kdekoliv je potřeba znaky s jednotnou šířkou pro čitelné rozložení textu (např. tabulky, zaškrtávací tlačítka, ukázky kódu). Pokud nebude nalezeno, bude použito obecné neproporcionální písmo s jednotnou šířkou znaků.",
"User deletions": "Odstranění uživatele",
"Users": "Uživatelé",
"Valid": "Platné",
"Verify your identity": "Ověřte svou identitu",
"View": "Zobrazit",
"View on map": "Zobrazit na map+",
"View them now": "Zobrazit",
@@ -790,6 +1020,8 @@
"You may use the tool below to re-encrypt your data, for example if you know that some of your notes are encrypted with an obsolete encryption method.": "Níže uvedený nástroj můžete použít k opětovnému zašifrování dat, například pokud víte, že některé vaše poznámky jsou šifrovány zastaralou metodou šifrování.",
"Your choice: ": "Vaše volba: ",
"Your data is going to be re-encrypted and synced again.": "Vaše data budou znovu zašifrována a znovu synchronizována.",
"Your password is needed to decrypt some of your data.": "K dešifrování některých dat je potřeba heslo.",
"Your password is needed to decrypt some of your data. Type `:e2ee decrypt` to set it.": "K dešifrování některých dat je potřeba vaše heslo. Zadejte `:e2ee decrypt` pro jeho nastavení.",
"Your permission to use your camera is required.": "Je vyžadováno oprávnění použít vaši kameru.",
"Your version: %s": "Vaše verze: %s",
"Zoom In": "Přiblížit",

View File

@@ -186,7 +186,6 @@
"Could not switch profile: %s": "Kunne ikke skifte profil: %s",
"Could not upgrade master key: %s": "Kunne ikke opgradere hovednøgle: %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Kunne ikke verificere denne notesbogs status for deling - afbryder. Prøv venligst igen, når du har forbindelse til internettet.",
"Could not verify your identify": "Kunne ikke bekræfte din identitet",
"Create": "Opret",
"Create a notebook": "Opret en notesbog",
"Create new profile...": "Opret ny note...",

View File

@@ -9,6 +9,7 @@
"%d MB per note or attachment": "%d MB pro Notiz oder Anhang",
"%d minutes": "%d Minuten",
"%d notes match this pattern. Delete them?": "%d Notizen stimmen mit diesem Muster überein. Sollen sie gelöscht werden?",
"%s": "%s",
"%s %s (%s, %s)": "%s %s (%s, %s)",
"%s (%s) could not be uploaded: %s": "%s (%s) konnte nicht hochgeladen werden: %s",
"%s (%s) would like to share a notebook with you.": "%s (%s) möchte ein Notizbuch mit dir teilen.",
@@ -75,6 +76,7 @@
"Application": "Anwendung",
"Apply": "Anwenden",
"Are you sure you want to renew the authorisation token?": "Bist du sicher, dass du den Berechtigungstoken erneuern möchtest?",
"Are you sure you want to return to the default layout? The current layout configuration will be lost.": "Sicher, dass du zum Standardlayout zurückkehren möchtest? Das aktuelle Layout geht dabei verloren",
"Arguments:": "Kommandozeilenargumente:",
"Aritim Dark": "Aritim dunkel",
"Attach": "Anhängen",
@@ -110,6 +112,7 @@
"Cannot change encrypted item": "Kann verschlüsseltes Objekt nicht ändern",
"Cannot copy note to \"%s\" notebook": "Kann Notiz nicht in das Notizbuch „%s“ kopieren",
"Cannot find \"%s\".": "Kann „%s“ nicht finden.",
"Cannot find: \"%s\"": "Kann „%s“ nicht finden.",
"Cannot initialise synchroniser.": "Kann Synchronisierer nicht initialisieren.",
"Cannot load \"%s\" module for format \"%s\" and output \"%s\"": "Das Modul „%s“ für das Format „%s“ und die Ausgabe „%s“ kann nicht geladen werden",
"Cannot load \"%s\" module for format \"%s\" and target \"%s\"": "Das Modul „%s“ für das Format „%s“ und die Ausgabe „%s“ kann nicht geladen werden",
@@ -184,8 +187,8 @@
"Could not switch profile: %s": "Konnte das Profil nicht wechseln: %s",
"Could not upgrade master key: %s": "Konnte Hauptschlüssel nicht aktualisieren: %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Der Freigabestatus dieses Notizbuchs konnte nicht überprüft werden - Vorgang wird abgebrochen. Bitte versuche es erneut, wenn eine Internetverbindung besteht.",
"Could not verify your identify": "Konnte deine Identität nicht verifizieren.",
"Create": "Erstellen",
"Create a new notebook under a parent notebook.": "Erstelle ein neues Notizbuch unter einem übergeordneten Notizbuch.",
"Create a notebook": "Notizbuch erstellen",
"Create new profile...": "Neues Profil erstellen...",
"Create notebook": "Notizbuch erstellen",
@@ -321,6 +324,7 @@
"Enable note history": "Notizenverlauf aktivieren",
"Enable PDF viewer": "PDF-Betrachter aktivieren",
"Enable soft breaks": "Weiche Zeilenumbrüche aktivieren",
"Enable spellcheck in the text editor": "Aktiviere die Rechtschreibprüfung im Text-Editor",
"Enable table of contents extension": "Inhaltsverzeichnis-Erweiterung aktivieren",
"Enable typographer support": "Typographie-Unterstützung aktivieren",
"Enable video player": "Videospieler aktivieren",
@@ -457,6 +461,7 @@
"Items": "Elemente",
"Items that cannot be decrypted": "Elemente, die nicht entschlüsselt werden können",
"Items that cannot be synchronised": "Elemente, die nicht synchronisiert werden können",
"Join us on Twitter": "Folge uns auf Twitter",
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin kann deine Notizen mit verschiedenen Anbietern synchronisieren. Wähle einen aus der folgenden Liste aus.",
"Joplin Cloud": "Joplin Cloud",
"Joplin Cloud email": "Joplin Cloud E-Mail",
@@ -530,6 +535,7 @@
"Missing keys": "Fehlende Schlüssel",
"Missing Master Keys": "Fehlende Hauptschlüssel",
"Missing required argument: %s": "Fehlendes erforderliches Argument: %s",
"Missing required flag value: %s": "Fehlendes erforderliches Argument: %s",
"Mobile data - auto-sync disabled": "Mobile Daten - Auto-Synchronisierung deaktiviert",
"More info": "Weitere Information",
"More information": "Weitere Informationen",
@@ -626,6 +632,7 @@
"Password:": "Passwort:",
"Passwords do not match!": "Passwörter sind nicht identisch!",
"Paste": "Einfügen",
"Paste as text": "Einfügen als Text",
"Path:": "Pfad:",
"PDF File": "PDF-Datei",
"Per user. Minimum of %d users.": "Pro Nutzer. Minimum von %d Nutzern.",
@@ -705,6 +712,7 @@
"Replace all": "Alle ersetzen",
"Replace with...": "Ersetzen mit...",
"Replace: ": "Ersetze: ",
"Reset application layout": "Anwendungslayout zurücksetzen",
"Reset master password": "Master-Passwort zurücksetzen",
"Resources: %d.": "Anhänge: %d.",
"Restart and upgrade": "Neustarten und aktualisieren",
@@ -861,7 +869,7 @@
"The default admin password is insecure and has not been changed! [Change it now](%s)": "Das Standard-Administratorpasswort ist unsicher und wurde nicht geändert! [Jetzt ändern](%s)",
"The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.": "Die Standardverschlüsselungsmethode wurde in eine sicherere geändert und es wird empfohlen, sie auf deine Daten anzuwenden.",
"The default encryption method has been changed, you should re-encrypt your data.": "Die Standardverschlüsselungsmethode wurde geändert. Du solltest deine Daten erneut verschlüsseln.",
"The default profile cannot be deleted": "Das Standardprofil kann nicht gelöscht werden.",
"The default profile cannot be deleted": "Das Standardprofil kann nicht gelöscht werden",
"The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.": "Der Editor-Befehl (kann Kommandozeilenargumente enthalten), der zum Öffnen einer Notiz verwendet wird. Wenn keiner angegeben wird, wird versucht, den Standard-Editor automatisch zu erkennen.",
"The factor property sets how the item will grow or shrink to fit the available space in its container with respect to the other items. Thus an item with a factor of 2 will take twice as much space as an item with a factor of 1.Restart app to see changes.": "Die Faktor-Eigenschaft legt fest, wie der Artikel wächst oder schrumpft, um dem verfügbaren Platz in seinem Container in Bezug auf die anderen Artikel zu entsprechen. Ein Element mit dem Faktor 2 benötigt also doppelt so viel Platz wie ein Element mit dem Faktor 1. Starte die App neu, um Änderungen zu sehen.",
"The following attachments are being watched for changes:": "Die folgenden Anhänge werden auf Änderungen überwacht:",
@@ -883,6 +891,7 @@
"The Web Clipper needs your authorisation to access your data.": "Der Web Clipper benötigt deine Genehmigung, um auf die Daten zuzugreifen.",
"The web clipper service is enabled and set to auto-start.": "Der Web-Clipper-Dienst ist aktiviert und auf Autostart eingestellt.",
"The web clipper service is not enabled.": "Der Web-Clipper-Dienst ist nicht aktiviert.",
"The WebDAV implementation of %s is incompatible with Joplin, and as such is no longer supported. Please use a different sync method.": "Die WebDAV Implementation von %s ist nicht kompatibel mit Joplin und deshalb nicht länger unterstützt. Bitte verwende eine andere Sync-Methode.",
"Theme": "Design",
"There are currently no notes. Create one by clicking on the (+) button.": "Momentan existieren noch keine Notizen. Erstelle eine, indem du auf den (+)-Knopf drückst.",
"There are unsaved changes.": "Es gibt ungespeicherte Änderungen.",
@@ -970,7 +979,7 @@
"Upgrade the sync target to the latest version.": "Aktualisiere das Synchronisationsziel auf die neueste Version.",
"URL": "URL",
"Usage: %s": "Nutzung: %s",
"Use biometrics to secure access to the app": "Verwende Biometrie, um den Zugriff zu der App abzusichern.",
"Use biometrics to secure access to the app": "Verwende Biometrie, um den Zugriff auf die App abzusichern",
"Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE": "Verwende ausführliches Listenformat. Das Format ist ID, NOTIZEN_ANZAHL (für Notizbuch), DATUM, AUFGABE_BEARBEITET (für Aufgaben), TITEL",
"Use spell checker": "Rechtschreibprüfung verwenden",
"Use the arrows and page up/down to scroll the lists and text areas (including this console).": "Benutze die Pfeiltasten und Bild auf/ab, um durch Listen und Texte zu scrollen (inklusive dieser Konsole).",

View File

@@ -184,7 +184,6 @@
"Could not switch profile: %s": "No se pudo cambiar el perfil: %s",
"Could not upgrade master key: %s": "No se pudo actualizar la clave maestra: %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "No se ha podido verificar el estado de compartición de esta libreta - abortando. Por favor, inténtelo de nuevo cuando esté conectado a Internet.",
"Could not verify your identify": "No se pudo verificar su identidad",
"Create": "Crear",
"Create a notebook": "Crea una libreta",
"Create new profile...": "Crear nuevo perfil...",

View File

@@ -1,10 +1,15 @@
{
"\"%s\" is missing the required \"%s\" property.": "Ominaisuudesta %s puuttuu pakollinen ominaisuus %s.",
"%d days": "%d päivää",
"%d GB": "%d Gt",
"%d GB storage space": "%d Gt tallennustila",
"%d hour": "%d tunti",
"%d hours": "%d tuntia",
"%d MB": "%d Mt",
"%d MB per note or attachment": "%d Mt muistiinpanoa tai liitettä kohti",
"%d minutes": "%d minuuttia",
"%d notes match this pattern. Delete them?": "%d muistiinpanot vastaavat tätä mallia. Poistetaanko ne?",
"%s": "%s",
"%s %s (%s, %s)": "%s %s (%s, %s)",
"%s (%s) could not be uploaded: %s": "%s (%s) ei voitu ladata: %s",
"%s (%s) would like to share a notebook with you.": "%s (%s) haluaa jakaa muistikirjan kanssasi.",
@@ -58,6 +63,7 @@
"Admin dashboard": "Ylläpitäjän hallintapaneeli",
"Advanced options": "Lisäasetukset",
"Advanced tools": "Lisätyökalut",
"All data, including notes, notebooks and tags will be permanently deleted.": "Kaikki tiedot, mukaan lukien muistiinpanot, muistikirjat ja tunnisteet, poistetaan pysyvästi.",
"All notes": "Kaikki muistiinpanot",
"All potential ports are in use - please report the issue at %s": "Kaikki mahdolliset portit ovat käytössä - ilmoita ongelmasta osoitteessa %s",
"Also displays unset and hidden config variables.": "Näyttää myös merkitsemättömät ja piilotetut konfigurointimuuttujat.",
@@ -70,6 +76,7 @@
"Application": "Sovellus",
"Apply": "Käytä",
"Are you sure you want to renew the authorisation token?": "Haluatko varmasti uusia valtuutustunnuksen?",
"Are you sure you want to return to the default layout? The current layout configuration will be lost.": "Haluatko varmasti palata oletus ulkoasuun? Nykyinen ulkoasun määritys menetetään.",
"Arguments:": "Väitteet:",
"Aritim Dark": "Aritim Dark",
"Attach": "Liittää",
@@ -91,6 +98,7 @@
"Automatically check for updates": "Tarkista päivitykset automaattisesti",
"Automatically switch theme to match system theme": "Vaihda teema automaattisesti vastaamaan järjestelmän teemaa",
"Back": "Takaisin",
"Basic": "Perus",
"Bold": "Lihavoitu",
"Browse all plugins": "Selaa kaikkia laajennuksia",
"Browse...": "Selaa...",
@@ -104,6 +112,7 @@
"Cannot change encrypted item": "Salattua kohdetta ei voi muuttaa",
"Cannot copy note to \"%s\" notebook": "Muistiinpanoa ei voi kopioida \"%s\" muistikirjaan",
"Cannot find \"%s\".": "Ei löydy \"%s\".",
"Cannot find: \"%s\"": "Ei löydy: \"%s\"",
"Cannot initialise synchroniser.": "Synkronoinnin alustaminen ei onnistu.",
"Cannot load \"%s\" module for format \"%s\" and output \"%s\"": "Ei voi ladata \"%s\" moduuli muotoa varten \"%s\" ja ulostulo \"%s\"",
"Cannot load \"%s\" module for format \"%s\" and target \"%s\"": "Ei voi ladata \"%s\" moduuli muotoa varten \"%s\" ja kohde \"%s\"",
@@ -131,6 +140,7 @@
"Click to add tags...": "Klikkaa lisätäksesi tunnisteita...",
"Client ID: %s": "Asiakkaan tunnus: %s",
"Close": "Sulkea",
"Close dropdown": "Sulje pudotusvalikko",
"Close Window": "Sulje ikkuna",
"Code": "Koodi",
"Code Block": "Koodilohko",
@@ -154,7 +164,9 @@
"Conflicted: %d": "Ristiriitainen: %d",
"Conflicts": "Ristiriitoja",
"Conflicts (attachments)": "Ristiriidat (liitteet)",
"Consolidated billing": "Yhdistetty laskutus",
"Content provided by %s": "Sisällön toimittaa %s",
"Continue": "Jatkaa",
"Convert to note": "Muunna muistiinpanoksi",
"Convert to todo": "Muunna tehtäväksi",
"Copy": "Kopioi",
@@ -172,9 +184,11 @@
"Could not export notes: %s": "Muistiinpanoja ei voitu viedä: %s",
"Could not install plugin: %s": "Laajennuksen asentaminen epäonnistui: %s",
"Could not respond to the invitation. Please try again, or check with the notebook owner if they are still sharing it.\n\nThe error was: \"%s\"": "Kutsuun ei voitu vastata. Yritä uudelleen tai tarkista muistikirjan omistajalta, jakaako hän sitä edelleen.\n\nVirhe oli: \"%s\"",
"Could not switch profile: %s": "Profiilia ei voitu vaihtaa: %s",
"Could not upgrade master key: %s": "Pääavainta ei voitu päivittää: %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Tämän muistikirjan jaon tilaa ei voitu vahvistaa - keskeytetään. Yritä uudelleen, kun olet muodostanut yhteyden Internetiin.",
"Create": "Luo",
"Create a new notebook under a parent notebook.": "Luo uusi muistikirja päämuistikirjan alle.",
"Create a notebook": "Luo muistikirja",
"Create new profile...": "Luo uusi profiili...",
"Create notebook": "Luo muistikirja",
@@ -222,9 +236,11 @@
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "Poista muistikirja \"%s\"?\n\nMyös kaikki tämän muistikirjan muistiinpanot ja alimuistikirjat poistetaan.",
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "Poistetaanko muistikirja? Kaikki tämän muistikirjan muistiinpanot ja alimuistikirjat poistetaan myös.",
"Delete plugin \"%s\"?": "Poista laajennus \"%s\"?",
"Delete profile \"%s\"": "Poista profiili \"%s\"",
"Delete selected notes": "Poista valitut muistiinpanot",
"Delete these %d notes?": "Poistetaanko nämä %d muistiinpanot?",
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "Poistetaanko tämä kutsu? Vastaanottaja ei voi enää käyttää tätä jaettua muistikirjaa.",
"Delete this profile?": "Poistetaanko tämä profiili?",
"Deleted local items: %d.": "Poistetut paikalliset kohteet: %d.",
"Deleted remote items: %d.": "Poistetut etäkohteet: %d.",
"Deletes the given notebook.": "Poistaa annetun muistikirjan.",
@@ -275,6 +291,7 @@
"Edit link": "Muokkaa linkkiä",
"Edit note.": "Muokkaa muistiinpanoa.",
"Edit notebook": "Muokkaa muistikirjaa",
"Edit profile": "Muokkaa profiilia",
"Edit profile configuration...": "Muokkaa profiilin asetuksia...",
"Editor": "Editoija",
"Editor font": "Editorin fontti",
@@ -294,6 +311,7 @@
"Enable ^sup^ syntax": "Ota käyttöön ^sup^ syntax",
"Enable abbreviation syntax": "Ota lyhenteen syntaksi käyttöön",
"Enable audio player": "Ota käyttöön audiosoitin",
"Enable biometrics authentication?": "Otetaanko biometrinen todennus käyttöön?",
"Enable deflist syntax": "Ota deflist syntaksi käyttöön",
"Enable encryption": "Ota salaus käyttöön",
"Enable footnotes": "Ota alaviitteet käyttöön",
@@ -306,6 +324,7 @@
"Enable note history": "Muistiinpanohistorian ottaminen käyttöön",
"Enable PDF viewer": "Ota käyttöön PDF katseluohjelma",
"Enable soft breaks": "Ota pehmeät tauot käyttöön",
"Enable spellcheck in the text editor": "Ota oikeinkirjoituksen tarkistus käyttöön tekstieditorissa",
"Enable table of contents extension": "Ota sisällysluettelon laajennus käyttöön",
"Enable typographer support": "Ota typografiatuki käyttöön",
"Enable video player": "Ota käyttöön videosoitin",
@@ -442,6 +461,7 @@
"Items": "Kohteet",
"Items that cannot be decrypted": "Kohteet, joita ei voi purkaa",
"Items that cannot be synchronised": "Kohteet, joita ei voi synkronoida",
"Join us on Twitter": "Liity meihin Twitterissä",
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin voi synkronoida muistiinpanosi eri palveluntarjoajien avulla. Valitse yksi alla olevasta luettelosta.",
"Joplin Cloud": "Joplin Cloud",
"Joplin Cloud email": "Joplin Cloud sähköposti",
@@ -495,6 +515,8 @@
"Make a donation": "Tee lahjoitus",
"Manage master password": "Pääsalasanan hallinta",
"Manage master password...": "Pääsalasanan hallinta...",
"Manage multiple users": "Hallitse useita käyttäjiä",
"Manage profiles": "Hallitse profiileja",
"Manage your plugins": "Hallitse laajennuksia",
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Hallitse E2EE määrityksiä. Komennot ovat `enable`, `disable`, `decrypt`, `status`, `decrypt-file` ja `target-status`.",
"Manual": "Manuaalinen",
@@ -508,10 +530,12 @@
"Master password:": "Pääsalasana:",
"Max concurrent connections": "Samanaikaiset yhteydet enintään",
"Max Item Size": "Kohteen enimmäiskoko",
"Max note or attachment size": "Muistiinpanon tai liitteen enimmäiskoko",
"Max Total Size": "Suurin kokonaiskoko",
"Missing keys": "Puuttuvat avaimet",
"Missing Master Keys": "Puuttuvat pääavaimet",
"Missing required argument: %s": "Vaadittu argumentti puuttuu: %s",
"Missing required flag value: %s": "Pakollinen lipun arvo puuttuu: %s",
"Mobile data - auto-sync disabled": "Mobiilidata - automaattinen synkronointi poistettu käytöstä",
"More info": "Lisätietoja",
"More information": "Lisätietoja",
@@ -552,6 +576,7 @@
"Not authentified with %s. Please provide any missing credentials.": "Ei todennettu %s. Anna puuttuvat tunnistetiedot.",
"Not downloaded": "Ei ladattu",
"Not generated": "Ei luotu",
"Not now": "Ei nyt",
"note": "merkintä",
"Note": "Huomautus",
"Note area growth factor": "Huomautus alueen kasvutekijä",
@@ -607,8 +632,10 @@
"Password:": "Salasana:",
"Passwords do not match!": "Salasana ei täsmää!",
"Paste": "Liitä",
"Paste as text": "Liitä tekstinä",
"Path:": "Polku:",
"PDF File": "PDF tiedosto",
"Per user. Minimum of %d users.": "Käyttäjää kohti. Vähintään %d käyttäjää.",
"Permission needed": "Tarvittava lupa",
"Permission to use camera": "Lupa käyttää kameraa",
"Please click on \"%s\" to proceed, or set the passwords in the \"%s\" list below.": "Jatka napsauttamalla \"%s\" tai aseta salasana oheiseen \"%s\" luetteloon.",
@@ -640,13 +667,17 @@
"Previous match": "Edellinen vastaavuus",
"Previous versions of this note": "Tämän muistiinpanon aiemmat versiot",
"Print": "Tulosta",
"Priority support": "Ensisijainen tuki",
"Privacy Policy": "Tietosuojakäytäntö",
"Pro": "Ammattilainen",
"Process failed payment subscriptions": "Käsittele epäonnistuneet maksutilaukset",
"Process oversized accounts": "Käsittele ylisuuria tilejä",
"Process user deletions": "Käsittele käyttäjien poistot",
"Profile": "Profiili",
"Profile name": "Profiilin nimi",
"Profile name:": "Profiilin nimi:",
"Profile Version: %s": "Profiilin versio: %s",
"Profiles": "Profiilit",
"Properties": "Ominaisuudet",
"Proxy enabled": "Välityspalvelin käytössä",
"Proxy timeout (seconds)": "Välityspalvelimen aikakatkaisu (sekuntia)",
@@ -681,6 +712,7 @@
"Replace all": "Korvaa kaikki",
"Replace with...": "Korvaa...",
"Replace: ": "Vaihda: ",
"Reset application layout": "Palauta sovelluksen asettelu",
"Reset master password": "Pääsalasanan vaihtaminen",
"Resources: %d.": "Resursseja: %d.",
"Restart and upgrade": "Käynnistä uudelleen ja päivitä",
@@ -729,8 +761,10 @@
"Set the password": "Aseta salasana",
"Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s": "Asettaa ominaisuuden <name> annetusta <note> annettuun [arvoon]. Mahdolliset ominaisuudet ovat:\n\n%s",
"Share": "Jaa",
"Share and collaborate on a notebook": "Muistikirjan jakaminen ja yhteiskäyttö",
"Share Notebook": "Jaa muistikirja",
"Share notebook...": "Muistikirjan jakaminen...",
"Sharing access control": "Käyttöoikeuksien hallinnan jakaminen",
"Sharing notebook...": "Jaetaan muistikirjaa...",
"Shortcuts are not available in CLI mode.": "Pikavalinnat eivät ole käytettävissä CLI tilassa.",
"Show advanced": "Näytä edistyneet",
@@ -779,6 +813,7 @@
"Step 2: Install the extension": "Vaihe 2: Asenna laajennus",
"Stop": "Seis",
"Stop external editing": "Lopeta ulkoisen tekstieditorin muokkaus",
"Storage space": "Tallennustila",
"Strikethrough": "Yliviivaus",
"strong text": "vahva teksti",
"Submit": "Lähetä",
@@ -793,6 +828,7 @@
"Switch to profile %d": "Vaihda profiiliin %d",
"Switch to to-do type": "Vaihda tehtävätyyppiin",
"Switches to [notebook] - all further operations will happen within this notebook.": "Vaihtaa tilaan [notebook] - kaikki muut toiminnot tapahtuvat tässä muistikirjassa.",
"Sync as many devices as you want": "Synkronoi niin monta laitetta kuin haluat",
"Sync Status": "Synkronoinnin tila",
"Sync status (synced items / total items)": "Synkronoinnin tila (synkronoidut kohteet / kohteet yhteensä)",
"Sync target must be upgraded! Run `%s` to proceed.": "Synkronointikohde on päivitettävä! Suorita `%s` jatkaaksesi.",
@@ -818,8 +854,10 @@
"Take photo": "Ota valokuva",
"Task list": "Tehtävälista",
"Tasks": "Tehtävät",
"Teams": "Tiimit",
"Text editor command": "Tekstieditorin komento",
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Kiitos! Your Joplin Cloud tilisi on nyt määritetty ja käyttövalmis.",
"The active profile cannot be deleted. Switch to a different profile and try again.": "Aktiivista profiilia ei voi poistaa. Vaihda toiseen profiiliin ja yritä uudelleen.",
"The app is now going to close. Please relaunch it to complete the process.": "Sovellus suljetaan nyt. Käynnistä se uudelleen prosessin loppuun saamiseksi.",
"The application did not close properly. Would you like to start in safe mode?": "Sovellus ei sulkeutunut kunnolla. Haluatko aloittaa vikasietotilassa?",
"The application has been authorised - you may now close this browser tab.": "Sovellus on hyväksytty - voit nyt sulkea tämän välilehden.",
@@ -831,6 +869,7 @@
"The default admin password is insecure and has not been changed! [Change it now](%s)": "Järjestelmänvalvojan oletussalasana on turvaton, eikä sitä ole muutettu [Vaihda se nyt](%s)",
"The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.": "Oletussalausmenetelmä on muutettu turvallisemmaksi, ja on suositeltavaa, että käytät sitä tietoihin.",
"The default encryption method has been changed, you should re-encrypt your data.": "Oletussalausmenetelmää on muutettu, sinun on salattava tiedot uudelleen.",
"The default profile cannot be deleted": "Oletusprofiilia ei voi poistaa",
"The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.": "Editorikomento (voi sisältää argumentteja), jota käytetään muistiinpanon avaamiseen. Jos mitään ei ole annettu, se yrittää tunnistaa oletuseditorin automaattisesti.",
"The factor property sets how the item will grow or shrink to fit the available space in its container with respect to the other items. Thus an item with a factor of 2 will take twice as much space as an item with a factor of 1.Restart app to see changes.": "Kerroin ominaisuus määrittää, miten kohde kasvaa tai kutistuu niin, että se sopii säiliössä olevaan tilaan suhteessa muihin kohteisiin. Näin ollen kohde, jonka kerroin on 2, vie kaksi kertaa enemmän tilaa kuin kohde, jonka kerroin on 1.Restart sovellus muutosten näkemistä varten.",
"The following attachments are being watched for changes:": "Seuraavia liitteitä tarkkaillaan muutosten vuoksi:",
@@ -852,8 +891,10 @@
"The Web Clipper needs your authorisation to access your data.": "Web Clipper tarvitsee valtuutuksen tietojen käyttöön.",
"The web clipper service is enabled and set to auto-start.": "Web Clipper työkalu on käytössä ja asetettu käynnistymään automaattisesti.",
"The web clipper service is not enabled.": "Web Clipper työkalu ei ole käytössä.",
"The WebDAV implementation of %s is incompatible with Joplin, and as such is no longer supported. Please use a different sync method.": "%s WebDAV toteutus ei ole yhteensopiva Joplinin kanssa, joten sitä ei enää tueta. Käytä toista synkronointitapaa.",
"Theme": "Teema",
"There are currently no notes. Create one by clicking on the (+) button.": "Tällä hetkellä ei ole muistiinpanoja. Luo sellainen napsauttamalla (+) -painiketta.",
"There are unsaved changes.": "On tallentamattomia muutoksia.",
"There is currently no notebook. Create one by clicking on \"New notebook\".": "Tällä hetkellä ei ole muistikirjaa. Luo uusi napsauttamalla \"Uusi muistikirja\".",
"There is no data to export.": "Vietäviä tietoja ei ole.",
"There was a [conflict](%s) on the attachment below.\n\n%s": "Alla olevassa liitteessä oli [ristiriita](%s).\n\n%s",
@@ -887,6 +928,7 @@
"To maximise/minimise the console, press \"tc\".": "Maksimoidaksesi / minimoidaksesi konsolin, paina \"tc\".",
"To move from one pane to another, press Tab or Shift+Tab.": "Voit siirtyä ruudusta toiseen painamalla Tab tai Shift + Tab.",
"To retry decryption of these items. Run `e2ee decrypt --retry-failed-items`": "Yritä uudelleen purkaa nämä kohteet. Suorita `e2ee decrypt --retry-failed-items`",
"To switch the profile, the app is going to close and you will need to restart it.": "Jos haluat vaihtaa profiilia, sovellus suljetaan ja sinun on käynnistettävä se uudelleen.",
"To work correctly, the app needs the following permissions. Please enable them in your phone settings, in Apps > Joplin > Permissions": "Toimiakseen oikein sovellus tarvitsee seuraavat käyttöoikeudet. Ota ne käyttöön puhelimesi asetuksissa, valitsemalla Sovellukset> Joplin> Luvat (käyttöoikeudet)",
"to-do": "tehtävä",
"to-do: %s": "tehtävä: %s",
@@ -905,6 +947,7 @@
"Total Size": "Koko yhteensä",
"Total: %d/%d": "Yhteensä: %d/%d",
"Try again": "Yritä uudestaan",
"Try it now": "Kokeile nyt",
"Type `help [command]` for more information about a command; or type `help all` for the complete usage information.": "Kirjoita `help [command]` saadaksesi lisätietoja komennosta; tai kirjoita `help all` saadaksesi täydelliset käyttötiedot.",
"Type `joplin help` for usage information.": "Valitse `joplin help` saadaksesi käytöstä lisätietoja.",
"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. Or type : to search for commands.": "Kirjoita muistiinpanon otsikko, jos haluat siirtyä siihen. Voit myös kirjoittaa # ja sen jälkeen tunnisteen nimen tai @ ja sen jälkeen muistikirjan nimen. Voit myös etsiä komentoja kirjoittamalla : .",
@@ -936,16 +979,19 @@
"Upgrade the sync target to the latest version.": "Päivitä synkronointikohde uusimpaan versioon.",
"URL": "URL",
"Usage: %s": "Käyttö: %s",
"Use biometrics to secure access to the app": "Käytä biometrisiä tunnisteita suojataksesi pääsyn sovellukseen",
"Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE": "Käytä pitkää luettelomuotoa. Muoto on ID, NOTE_COUNT (muistikirjalle), DATE, TODO_CHECKED (tehtäville), TITLE",
"Use spell checker": "Käytä oikolukua",
"Use the arrows and page up/down to scroll the lists and text areas (including this console).": "Käytä nuolia ja page up/down vierittämällä luetteloita ja tekstialueita (mukaan lukien tämä konsoli).",
"Use the arrows to move the layout items. Press \"Escape\" to exit.": "Siirrä asettelukohteita nuolilla. Paina \"Esc\" poistuaksesi.",
"Use this to rebuild the search index if there is a problem with search. It may take a long time depending on the number of notes.": "Tämän avulla voit muodostaa hakuindeksin uudelleen, jos haussa on ongelma. Se voi kestää kauan muistiinpanojen määrästä riippuen.",
"Use your biometrics to secure access to your application. You can always set it up later in Settings.": "Käytä biometrisiä tunnisteita suojataksesi pääsyn sovellukseen. Voit määrittää sen myöhemmin asetuksissa.",
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Käytetään useimmissa teksteissä markdown editorissa. Jos sitä ei löydy, käytetään yleistä suhteellista fonttia (vaihtelevaa leveyttä).",
"Used where a fixed width font is needed to lay out text legibly (e.g. tables, checkboxes, code). If not found, a generic monospace (fixed width) font is used.": "Käytetään, kun tekstiin tarvitaan kiinteäleveyksinen fontti (esim. taulukot, valintaruudut, koodi). Jos sitä ei löydy, käytetään yleistä monospace fonttia (kiinteäleveyksinen).",
"User deletions": "Käyttäjien poisto",
"Users": "Käyttäjät",
"Valid": "Kelvollinen",
"Verify your identity": "Vahvista henkilöllisyytesi",
"View": "Näytä",
"View on map": "Näytä kartalla",
"View them now": "Näytä ne nyt",

View File

@@ -99,6 +99,7 @@
"Automatically switch theme to match system theme": "Changer le thème automatiquement pour correspondre au thème système",
"Back": "Retour",
"Basic": "Basique",
"Biometric unlock is not setup on the device. Please set it up in order to unlock Joplin. If the device is on lockout, consider switching it off and on to reset biometrics scanning.": "Le déverrouillage biométrique n'est pas activé sur cet appareil. Veuillez le configurer pour déverrouiller Joplin. Si l'appareil est en mode \"lockout\", éteignez-le et rallumez-le pour réinitialiser la vérification de biométrie.",
"Bold": "Gras",
"Browse all plugins": "Parcourir les plugins",
"Browse...": "Parcourir…",
@@ -112,6 +113,7 @@
"Cannot change encrypted item": "Un objet chiffré ne peut pas être modifié",
"Cannot copy note to \"%s\" notebook": "Impossible de copier la note vers le carnet \"%s\"",
"Cannot find \"%s\".": "Impossible de trouver \"%s\".",
"Cannot find: \"%s\"": "Impossible de trouver : \"%s\"",
"Cannot initialise synchroniser.": "Impossible d'initialiser la synchronisation.",
"Cannot load \"%s\" module for format \"%s\" and output \"%s\"": "Impossible de charger module \"%s\" pour le format d'entrée \"%s\" et de sortie \"%s\"",
"Cannot load \"%s\" module for format \"%s\" and target \"%s\"": "Impossible de charger module \"%s\" pour le format d'entrée \"%s\" et de sortie \"%s\"",
@@ -168,6 +170,7 @@
"Continue": "Continuer",
"Convert to note": "Convertir en note",
"Convert to todo": "Convertir en tâche",
"Converting speech to text...": "Conversion de la parole en texte...",
"Copy": "Copier",
"Copy dev mode command to clipboard": "Copier commande de développement dans presse papier",
"Copy external link": "Copier le lien externe",
@@ -186,8 +189,9 @@
"Could not switch profile: %s": "Impossible de changer de profil : %s",
"Could not upgrade master key: %s": "Impossible de mettre la clef à niveau : %s",
"Could not verify the share status of this notebook - aborting. Please try again when you are connected to the internet.": "Impossible de vérifier l'état du partage du carnet - annulation. Veuillez réessayer lorsque vous serez connecté à internet.",
"Could not verify your identify": "Impossible de vérifier votre identité",
"Could not verify your identify: %s": "Impossible de vérifier votre identité : %s",
"Create": "Créer",
"Create a new notebook under a parent notebook.": "Créer un carnet sous un carnet parent.",
"Create a notebook": "Créer un carnet",
"Create new profile...": "Créer un nouveau profil...",
"Create notebook": "Créer un carnet",
@@ -325,6 +329,7 @@
"Enable soft breaks": "Activer retours à la ligne \"doux\"",
"Enable spellcheck in the text editor": "Activer le correcteur d'orthographe de l'éditeur de texte",
"Enable table of contents extension": "Activer la table des matières",
"Enable the Markdown toolbar": "Activer la barre d'outils Markdown",
"Enable typographer support": "Activer le typographe",
"Enable video player": "Activer lecteur vidéo",
"Enable Web Clipper Service": "Activer le service du Web Clipper",
@@ -502,6 +507,7 @@
"List item": "Élément de liste",
"Lists": "Listes",
"Loaded": "Chargé",
"Loading...": "Chargement…",
"Location": "Lieu",
"Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at \"%s\" and resume the operation.": "La synchronisation est déjà en cours ou ne s'est pas interrompue correctement. Si vous savez qu'aucune autre synchronisation est en cours, vous pouvez supprimer le fichier \"%s\" pour reprendre l'opération.",
"Log": "Journal",
@@ -534,6 +540,7 @@
"Missing keys": "Clefs manquantes",
"Missing Master Keys": "Clefs maître manquantes",
"Missing required argument: %s": "Paramètre requis manquant : %s",
"Missing required flag value: %s": "Paramètre requis manquant : %s",
"Mobile data - auto-sync disabled": "Données mobiles – sync auto désactivé",
"More info": "Plus d'information",
"More information": "Plus d'information",
@@ -641,6 +648,7 @@
"Please enter your password in the master key list below before upgrading the key.": "Veuillez entrer le mot de passe de la clef maître ci‑dessous avant de mettre la clef à niveau.",
"Please note that if it is a large notebook, it may take a few minutes for all the notes to show up on the recipient's device.": "Veuillez noter que les carnets de grande taille peuvent mettre plusieurs minutes pour que toutes les notes apparaissent sur l'appareil du destinataire.",
"Please open the following URL in your browser to authenticate the application. The application will create a directory in \"Apps/Joplin\" and will only read and write files in this directory. It will have no access to any files outside this directory nor to any other personal data. No data will be shared with any third party.": "Veuillez ouvrir le lien ci‑dessous dans votre navigateur pour authentifier le logiciel. Joplin va créer un répertoire \"Apps/Joplin\" et lire/écrira des fichiers uniquement dans ce répertoire. Le logiciel n'aura pas d'accès à aucun fichier en dehors de ce répertoire, ni à d'autres données personnelles. Aucune donnée ne sera partagé avec aucun tier.",
"Please record your voice...": "Veuillez enregistrer votre voix...",
"Please select a notebook first.": "Veuillez d'abord sélectionner un carnet.",
"Please select the note or notebook to be deleted first.": "Veuillez d'abord sélectionner un carnet.",
"Please select where the sync status should be exported to": "Veuillez sélectionner un répertoire ou exporter l'état de la synchronisation",
@@ -995,6 +1003,8 @@
"View them now": "Les voir maintenant",
"Viewer": "Visionneuse",
"Vim": "Vim",
"Voice typing": "Saisie vocale",
"Voice typing...": "Saisie vocale...",
"Warning": "Avertissement",
"Warning: not all resources shown for performance reasons (limit: %s).": "Attention : tous les fichiers ne sont pas affichés pour des raisons de performance (limite : %s).",
"Web Clipper": "Web Clipper",

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