Compare commits

..
Author SHA1 Message Date
palerdot c7299cf679 fix(desktop): linux folder display bug fix 2023-03-10 12:36:40 +05:30
Laurent Cozic ad0f0414c4 iOS 12.10.5 2023-03-06 15:48:23 +00:00
Laurent Cozic 405c528ef0 Android 2.10.8 2023-02-28 18:19:09 +00:00
Laurent Cozic a176216374 Update translations 2023-02-28 18:02:09 +00:00
renovate[bot] 8d0b090f66 Update dependency madge to v6 (#7853) 2023-02-28 15:06:57 +00:00
Joplin Bot 337c5ed61c Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-28 00:45:05 +00:00
Joplin Bot b32d39860b Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-27 18:19:06 +00:00
renovate[bot] a091608f72 Update dependency react-native-share to v8.2.0 (#7845) 2023-02-27 12:22:55 +00:00
renovate[bot] 9686ee7833 Update dependency react-native-paper to v5.2.0 (#7844) 2023-02-27 12:22:38 +00:00
renovate[bot] 3b55dcac65 Update dependency sass to v1.58.2 (#7846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-27 06:00:02 +00:00
Joplin Bot d524d11d8a Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-26 18:16:41 +00:00
Tao Klerks 9c080ec631 Desktop: Fixes #7776: Drag-dropping notes to top or bottom, in custom sort, is finicky (#7777) 2023-02-26 15:40:13 +00:00
Laurent Cozic da11476fd7 CLI v2.10.3 2023-02-26 13:04:03 +00:00
Laurent Cozic d157b9cfc7 Cli: Fixed "sync" command when calling it in non-interactive mode 2023-02-26 13:02:50 +00:00
Laurent Cozic bc8c61748a CLI v2.10.2 2023-02-26 12:41:43 +00:00
Laurent Cozic 3ad727889b Lock file 2023-02-26 12:40:57 +00:00
Laurent Cozic 8df128bb7a Releasing sub-packages 2023-02-26 12:37:29 +00:00
Laurent Cozic 5a4568f4db CI: Fixed publishall 2023-02-26 12:33:59 +00:00
Laurent Cozic 170295919a CI: Fixed publishall 2023-02-26 12:17:17 +00:00
Laurent Cozic 2262cbfdfd Desktop release v2.10.8 2023-02-26 12:15:07 +00:00
Andrej Lifinzew 43e40bcf5a CLI: Resolves #1728: Create subnotebooks (#6722) 2023-02-26 12:13:45 +00:00
Helmut K. C. Tessarek e60595f0de All: Translation: Update da_DK.po (thanks ERYpTION) 2023-02-25 16:54:55 -05:00
renovate[bot] 527a7c115d Update jest monorepo to v29.4.3 (#7841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-25 20:42:10 +00:00
Laurent Cozic c22f910500 Merge branch 'release-2.10' into dev 2023-02-25 16:50:09 +00:00
Laurent Cozic 667b7969ff CLI v2.10.1 2023-02-25 16:49:54 +00:00
Laurent Cozic 1bbf065142 Releasing sub-packages 2023-02-25 16:47:37 +00:00
renovate[bot] 606cad3c3a Update dependency react-native-image-picker to v5.0.2 (#7829)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-25 07:42:17 +00:00
renovate[bot] c9612dc8b8 Update dependency lint-staged to v13.1.2 (#7832)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-25 04:15:09 +00:00
renovate[bot] 6ee30e22a6 Update dependency @react-native-community/datetimepicker to v6.7.5 (#7835)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-25 02:11:33 +00:00
Laurent Cozic a6536e1ef9 Chore: Improve logging on api/notes 2023-02-24 18:50:04 +00:00
Laurent Cozic 92cf5abd08 Desktop: Fixed clipping certain pages that contain images within links 2023-02-24 18:49:27 +00:00
Laurent Cozic d1e545ac2c Desktop: Note background does not change when theme automatically updated via system 2023-02-24 18:00:14 +00:00
Laurent Cozic ec6567c68d Update translations 2023-02-24 15:30:26 +00:00
Joplin Bot 3b236307f7 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-24 12:23:01 +00:00
Laurent Cozic 14ac54bf3d Update translations 2023-02-24 12:07:30 +00:00
Laurent Cozic e53b796523 iOS 12.10.4 2023-02-24 11:50:40 +00:00
Laurent Cozic 9d189b2b34 iOS 12.10.4 2023-02-24 11:50:16 +00:00
renovate[bot] 84545cf26d Update dependency sass to v1.58.1 (#7818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-24 10:39:20 +00:00
Joplin Bot c427a6d0a5 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-24 06:18:07 +00:00
Laurent Cozic 42dc6e1ea6 Desktop release v2.10.7 2023-02-23 13:52:29 +00:00
Laurent Cozic 431b95ff7b Android 2.10.7 2023-02-23 13:51:39 +00:00
Laurent Cozic 041fb731a6 lock file 2023-02-23 13:36:59 +00:00
pedr 5289f80394 Chore: Mobile: Fixes #7822: Spellcheck was hidden because of deprecated logic (#7830) 2023-02-23 13:31:08 +00:00
Laurent Cozic 6c12ce0e04 Chore: Set type of main BrowserWindow, and fixed popup calls 2023-02-22 18:16:28 +00:00
Teko-uy 46982c7d64 Completed spanish translation (#7817) 2023-02-22 14:36:53 +00:00
Julien 359448eb69 Chore: Regression: Revert changes made to the note list' height (#7823) 2023-02-22 13:13:39 +00:00
Julien 32bb256cca All: Resolves #7661: Stop synchronization with unsupported WebDAV providers (#7819) 2023-02-22 13:12:53 +00:00
github-actions[bot] 219585bbcf @adidevs has signed the CLA from Pull Request #7824 2023-02-22 10:33:39 +00:00
renovate[bot] 1a9dbcbd1d Update dependency yeoman-generator to v5.7.1 (#7821)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-22 04:34:29 +00:00
pedr 6a9848ebe7 Desktop: Fixes #7782: Markdown + Front Matter export fails when tag(s) lost (#7820) 2023-02-21 17:57:04 +00:00
Laurent Cozic 9e73d3590b Tools: Add eslint rule "no-unneeded-ternary" 2023-02-21 17:19:19 +00:00
Laurent Cozic 08c9a25182 Chore: Desktop: Do not wait for updating geolocation (regression) 2023-02-21 17:19:19 +00:00
renovate[bot] 5b9a45dc1d Update dependency sass to v1.58.0 (#7813) 2023-02-21 15:38:04 +00:00
Laurent Cozic 9dd2fb9674 Fixed regression 2023-02-21 15:28:00 +00:00
github-actions[bot] 234b5c8363 @Teko-uy has signed the CLA from Pull Request #7817 2023-02-21 13:37:05 +00:00
github-actions[bot] 1dc7ec3701 @rddunphy has signed the CLA from Pull Request #7815 2023-02-21 11:22:29 +00:00
Polaris66 72773caf58 Desktop: Resolves #7692: Added "Move Line Up" and "Move Line Down" shortcuts (#7755) 2023-02-21 10:55:17 +00:00
Joplin Bot 094249d074 Doc: Auto-update documentation
Auto-updated using release-website.sh
2023-02-20 18:17:07 +00:00
Laurent Cozic c324f17453 Tools: Fixed Android build error with JDK 19 2023-02-20 16:09:34 +00:00
Laurent Cozic 25a31b0689 Android: Fixes #7791: Fixed issue where app would close after sharing a file 2023-02-20 16:09:33 +00:00
pedr f2995dd196 Tools: Add prefer-arrow-callbacks to ESlint rules (#7810) 2023-02-20 15:02:29 +00:00
Tao Klerks ca575162f7 Desktop: Fixes #7731: Make note sort update logic use correct prior sort and drop-grouping (#7737) 2023-02-20 13:23:26 +00:00
pedr f0ade02435 Mobile: Fixes #7762: Hide main content while biometric is enabled and not authenticated (#7781) 2023-02-20 12:55:40 +00:00
pedr b13c02017a Desktop: Add a link to twitter inside the help menu (#7796) 2023-02-20 12:45:23 +00:00
326 changed files with 21133 additions and 17742 deletions

No files matched your search

+5
View File
@@ -79,6 +79,8 @@ packages/app-cli/app/LinkSelector.js
packages/app-cli/app/base-command.js
packages/app-cli/app/command-done.test.js
packages/app-cli/app/command-e2ee.js
packages/app-cli/app/command-mkbook.js
packages/app-cli/app/command-mkbook.test.js
packages/app-cli/app/command-settingschema.js
packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
@@ -513,6 +515,7 @@ packages/lib/markdownUtils.js
packages/lib/markdownUtils.test.js
packages/lib/markdownUtils2.test.js
packages/lib/markupLanguageUtils.js
packages/lib/migrations/42.js
packages/lib/models/Alarm.js
packages/lib/models/BaseItem.js
packages/lib/models/Folder.js
@@ -759,6 +762,8 @@ packages/lib/themes/type.js
packages/lib/time.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/webDAVUtils.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/uuid.js
packages/lib/versionInfo.js
packages/lib/versionInfo.test.js
+2
View File
@@ -92,6 +92,7 @@ module.exports = {
// "react-hooks/exhaustive-deps": "warn",
'promise/prefer-await-to-then': 'error',
'no-unneeded-ternary': 'error',
// -------------------------------
// Formatting
@@ -143,6 +144,7 @@ module.exports = {
// - notebook: In code, it should always be "folder" (not "notebook").
// In user-facing text, it should be "notebook".
'id-denylist': ['error', 'err', 'notebook', 'notebooks'],
'prefer-arrow-callback': ['error'],
},
'plugins': [
'react',
+5
View File
@@ -67,6 +67,8 @@ packages/app-cli/app/LinkSelector.js
packages/app-cli/app/base-command.js
packages/app-cli/app/command-done.test.js
packages/app-cli/app/command-e2ee.js
packages/app-cli/app/command-mkbook.js
packages/app-cli/app/command-mkbook.test.js
packages/app-cli/app/command-settingschema.js
packages/app-cli/app/command-sync.js
packages/app-cli/app/command-testing.js
@@ -501,6 +503,7 @@ packages/lib/markdownUtils.js
packages/lib/markdownUtils.test.js
packages/lib/markdownUtils2.test.js
packages/lib/markupLanguageUtils.js
packages/lib/migrations/42.js
packages/lib/models/Alarm.js
packages/lib/models/BaseItem.js
packages/lib/models/Folder.js
@@ -747,6 +750,8 @@ packages/lib/themes/type.js
packages/lib/time.js
packages/lib/utils/credentialFiles.js
packages/lib/utils/joplinCloud.js
packages/lib/utils/webDAVUtils.js
packages/lib/utils/webDAVUtils.test.js
packages/lib/uuid.js
packages/lib/versionInfo.js
packages/lib/versionInfo.test.js
+30 -30
View File
@@ -530,47 +530,47 @@ Current translations:
<!-- LOCALE-TABLE-AUTO-GENERATED -->
&nbsp; | Language | Po File | Last translator | Percent done
---|---|---|---|---
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 81%
<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/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) | 90%
<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) | 90%
<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) | 78%
<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 | 97%
<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) | 98%
<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) | | 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/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 Mora](mailto:francisco.m.collao@gmail.com) | 89%
<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 | 26%
<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 | 96%
<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/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/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/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) | 90%
<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/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) | 89%
<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) | 89%
<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) | 56%
<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) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 89%
<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/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/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) | 81%
<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) | 97%
<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) | | 37%
<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) | | 79%
<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) | 90%
<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) | 73%
<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) | 89%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 81%
<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) | | 66%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [KaneGreen](mailto:737445366KG@Gmail.com) | 95%
<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) | 90%
<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) | 90%
<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) | 90%
<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/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/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/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/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%
<!-- LOCALE-TABLE-AUTO-GENERATED -->
# Contributors
+4 -1
View File
@@ -6,7 +6,6 @@ const tasks = {
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']);
@@ -17,6 +16,10 @@ const tasks = {
// https://github.com/lerna/lerna/issues/2788
await utils.execCommandVerbose('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 utils.execCommandVerbose('git', ['push']);
},
},
+2 -2
View File
@@ -78,8 +78,8 @@
"gulp": "4.0.2",
"husky": "3.1.0",
"lerna": "3.22.1",
"lint-staged": "13.1.1",
"madge": "5.0.2",
"lint-staged": "13.1.2",
"madge": "6.0.0",
"npm-package-json-lint": "6.4.0",
"typedoc": "0.17.8",
"typescript": "4.9.4"
+2 -2
View File
@@ -125,14 +125,14 @@ async function handleAutocompletionPromise(line) {
}
function handleAutocompletion(str, callback) {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
handleAutocompletionPromise(str).then(function(res) {
handleAutocompletionPromise(str).then((res) => {
callback(undefined, res);
});
}
function toCommandLine(args) {
if (Array.isArray(args)) {
return args
.map(function(a) {
.map((a) => {
if (a.indexOf('"') !== -1 || a.indexOf(' ') !== -1) {
return `'${a}'`;
} else if (a.indexOf('\'') !== -1) {
-97
View File
@@ -1,97 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const locale_1 = require("@joplin/lib/locale");
const registry_js_1 = require("@joplin/lib/registry.js");
class BaseCommand {
constructor() {
this.stdout_ = null;
this.prompt_ = null;
}
usage() {
throw new Error('Usage not defined');
}
encryptionCheck(item) {
if (item && item.encryption_applied)
throw new Error((0, locale_1._)('Cannot change encrypted item'));
}
description() {
throw new Error('Description not defined');
}
action(_args) {
return __awaiter(this, void 0, void 0, function* () {
throw new Error('Action not defined');
});
}
compatibleUis() {
return ['cli', 'gui'];
}
supportsUi(ui) {
return this.compatibleUis().indexOf(ui) >= 0;
}
options() {
return [];
}
hidden() {
return false;
}
enabled() {
return true;
}
cancellable() {
return false;
}
cancel() {
return __awaiter(this, void 0, void 0, function* () { });
}
name() {
const r = this.usage().split(' ');
return r[0];
}
setDispatcher(fn) {
this.dispatcher_ = fn;
}
dispatch(action) {
if (!this.dispatcher_)
throw new Error('Dispatcher not defined');
return this.dispatcher_(action);
}
setStdout(fn) {
this.stdout_ = fn;
}
stdout(text) {
if (this.stdout_)
this.stdout_(text);
}
setPrompt(fn) {
this.prompt_ = fn;
}
prompt(message, options = null) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.prompt_)
throw new Error('Prompt is undefined');
return yield this.prompt_(message, options);
});
}
metadata() {
return {
name: this.name(),
usage: this.usage(),
options: this.options(),
hidden: this.hidden(),
};
}
logger() {
return registry_js_1.reg.logger();
}
}
exports.default = BaseCommand;
//# sourceMappingURL=base-command.js.map
-21
View File
@@ -1,21 +0,0 @@
const BaseCommand = require('./base-command').default;
const { app } = require('./app.js');
const { _ } = require('@joplin/lib/locale');
const Folder = require('@joplin/lib/models/Folder').default;
class Command extends BaseCommand {
usage() {
return 'mkbook <new-notebook>';
}
description() {
return _('Creates a new notebook.');
}
async action(args) {
const folder = await Folder.save({ title: args['new-notebook'] }, { userSideValidation: true });
app().switchCurrentFolder(folder);
}
}
module.exports = Command;
@@ -0,0 +1,50 @@
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
import Folder from '@joplin/lib/models/Folder';
const Command = require('./command-mkbook');
describe('command-mkbook', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
await setupApplication();
});
it('should create a subfolder in first folder', async () => {
const command = setupCommandForTesting(Command);
await command.action({ 'new-notebook': 'folder1', options: {} });
await command.action({ 'new-notebook': 'folder1_1', options: { parent: 'folder1' } });
const folder1 = await Folder.loadByTitle('folder1');
const folder1_1 = await Folder.loadByTitle('folder1_1');
expect(folder1.title).toBe('folder1');
expect(folder1_1.parent_id).toBe(folder1.id);
});
it('should not be possible to create a subfolder without an argument.', async () => {
const command = setupCommandForTesting(Command);
await command.action({ 'new-notebook': 'folder2', options: {} });
await expect(command.action({ 'new-notebook': 'folder2_1', options: { parent: true } })).rejects.toThrowError();
});
it('should not be possible to create subfolder in ambiguous destination folder', async () => {
const command = setupCommandForTesting(Command);
await command.action({ 'new-notebook': 'folder3', options: {} });
await command.action({ 'new-notebook': 'folder3', options: {} }); // ambiguous folder
await expect(command.action({ 'new-notebook': 'folder3_1', options: { parent: 'folder3' } })).rejects.toThrowError();
// check if duplicate entries have been created.
const folderAll = await Folder.all();
const folders3 = folderAll.filter(x => x.title === 'folder3');
expect(folders3.length).toBe(2);
// check if something has been created in one of the duplicate entries.
expect(await Folder.childrenIds(folders3[0].id)).toEqual([]);
expect(await Folder.childrenIds(folders3[1].id)).toEqual([]);
});
});
+65
View File
@@ -0,0 +1,65 @@
const BaseCommand = require('./base-command').default;
const { app } = require('./app.js');
import { _ } from '@joplin/lib/locale';
import BaseModel from '@joplin/lib/BaseModel';
import Folder from '@joplin/lib/models/Folder';
import { FolderEntity } from '@joplin/lib/services/database/types';
class Command extends BaseCommand {
usage() {
return 'mkbook <new-notebook>';
}
description() {
return _('Creates a new notebook.');
}
options() {
return [
['-p, --parent <parent-notebook>', _('Create a new notebook under a parent notebook.')],
];
}
// validDestinationFolder check for presents and ambiguous folders
async validDestinationFolder(targetFolder: string) {
const destinationFolder = await app().loadItem(BaseModel.TYPE_FOLDER, targetFolder);
if (!destinationFolder) {
throw new Error(_('Cannot find: "%s"', targetFolder));
}
const destinationDups = await Folder.search({ titlePattern: targetFolder, limit: 2 });
if (destinationDups.length > 1) {
throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id', targetFolder));
}
return destinationFolder;
}
async saveAndSwitchFolder(newFolder: FolderEntity) {
const folder = await Folder.save(newFolder, { userSideValidation: true });
app().switchCurrentFolder(folder);
}
async action(args: any) {
const targetFolder = args.options.parent;
const newFolder: FolderEntity = {
title: args['new-notebook'],
};
if (targetFolder) {
const destinationFolder = await this.validDestinationFolder(targetFolder);
newFolder.parent_id = destinationFolder.id;
await this.saveAndSwitchFolder(newFolder);
} else {
await this.saveAndSwitchFolder(newFolder);
}
}
}
module.exports = Command;
+7 -16
View File
@@ -9,11 +9,11 @@ import { appTypeToLockType } from '@joplin/lib/services/synchronizer/LockHandler
const BaseCommand = require('./base-command').default;
const { app } = require('./app.js');
const { OneDriveApiNodeUtils } = require('@joplin/lib/onedrive-api-node-utils.js');
const { reg } = require('@joplin/lib/registry.js');
import { reg } from '@joplin/lib/registry';
const { cliUtils } = require('./cli-utils.js');
const md5 = require('md5');
const locker = require('proper-lockfile');
const fs = require('fs-extra');
import * as locker from 'proper-lockfile';
import { pathExists, writeFile } from 'fs-extra';
class Command extends BaseCommand {
@@ -37,21 +37,12 @@ class Command extends BaseCommand {
];
}
static async lockFile(filePath: string): Promise<Function> {
private static async lockFile(filePath: string) {
return locker.lock(filePath, { stale: 1000 * 60 * 5 });
}
static isLocked(filePath: string) {
return new Promise((resolve, reject) => {
locker.check(filePath, (error: any, isLocked: boolean) => {
if (error) {
reject(error);
return;
}
resolve(isLocked);
});
});
private static async isLocked(filePath: string) {
return locker.check(filePath);
}
async doAuth() {
@@ -114,7 +105,7 @@ class Command extends BaseCommand {
// Lock is unique per profile/database
const lockFilePath = `${require('os').tmpdir()}/synclock_${md5(escape(Setting.value('profileDir')))}`; // https://github.com/pvorb/node-md5/issues/41
if (!(await fs.pathExists(lockFilePath))) await fs.writeFile(lockFilePath, 'synclock');
if (!(await pathExists(lockFilePath))) await writeFile(lockFilePath, 'synclock');
const useLock = args.options.useLock !== 0;
+2 -2
View File
@@ -75,12 +75,12 @@ if (process.platform === 'win32') {
output: process.stdout,
});
rl.on('SIGINT', function() {
rl.on('SIGINT', () => {
process.emit('SIGINT');
});
}
process.stdout.on('error', function(error) {
process.stdout.on('error', (error) => {
// https://stackoverflow.com/questions/12329816/error-write-epipe-when-piping-node-output-to-head#15884508
if (error.code === 'EPIPE') {
process.exit(0);
+3 -2
View File
@@ -34,7 +34,7 @@
],
"owner": "Laurent Cozic"
},
"version": "2.10.0",
"version": "2.10.3",
"bin": "./main.js",
"engines": {
"node": ">=10.0.0"
@@ -72,8 +72,9 @@
"@types/fs-extra": "9.0.13",
"@types/jest": "29.2.6",
"@types/node": "18.11.18",
"@types/proper-lockfile": "^4.1.2",
"gulp": "4.0.2",
"jest": "29.4.2",
"jest": "29.4.3",
"temp": "0.9.4",
"typescript": "4.9.4"
}
+1 -1
View File
@@ -12,7 +12,7 @@ const shim = require('@joplin/lib/shim').default;
const HtmlToHtml = require('@joplin/renderer/HtmlToHtml').default;
const { enexXmlToMd } = require('@joplin/lib/import-enex-md-gen.js');
describe('HtmlToHtml', function() {
describe('HtmlToHtml', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
+1 -1
View File
@@ -3,7 +3,7 @@ const os = require('os');
const { filename } = require('@joplin/lib/path-utils');
import HtmlToMd from '@joplin/lib/HtmlToMd';
describe('HtmlToMd', function() {
describe('HtmlToMd', () => {
it('should convert from Html to Markdown', (async () => {
const basePath = `${__dirname}/html_to_md`;
+1 -1
View File
@@ -1,7 +1,7 @@
const MarkupToHtml = require('@joplin/renderer/MarkupToHtml').default;
describe('MarkupToHtml', function() {
describe('MarkupToHtml', () => {
it('should strip markup', (async () => {
const service = new MarkupToHtml();
+1 -1
View File
@@ -16,7 +16,7 @@ function newTestMdToHtml(options: any = null) {
return new MdToHtml(options);
}
describe('MdToHtml', function() {
describe('MdToHtml', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
@@ -22,7 +22,7 @@ const goToNote = (testApp, note) => {
testApp.dispatch({ type: 'NOTE_SELECT', id: note.id });
};
describe('feature_NoteHistory', function() {
describe('feature_NoteHistory', () => {
beforeEach(async () => {
testApp = new TestApp();
await testApp.start(['--no-welcome']);
+1 -1
View File
@@ -8,7 +8,7 @@ const time = require('@joplin/lib/time').default;
let testApp = null;
describe('integration_NoteList', function() {
describe('integration_NoteList', () => {
beforeEach(async () => {
testApp = new TestApp();
@@ -22,7 +22,7 @@ const { ALL_NOTES_FILTER_ID } = require('@joplin/lib/reserved-ids.js');
let testApp = null;
describe('integration_ShowAllNotes', function() {
describe('integration_ShowAllNotes', () => {
beforeEach(async () => {
testApp = new TestApp();
+1 -1
View File
@@ -8,7 +8,7 @@ const time = require('@joplin/lib/time').default;
let testApp = null;
describe('integration_TagList', function() {
describe('integration_TagList', () => {
beforeEach(async () => {
testApp = new TestApp();
@@ -11,7 +11,7 @@ function describeIfCompatible(name: string, fn: any, elseFn: any) {
}
}
describeIfCompatible('services_KeychainService', function() {
describeIfCompatible('services_KeychainService', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1, { keychainEnabled: true });
@@ -29,7 +29,7 @@ function newPluginService(appVersion: string = '1.4') {
return service;
}
describe('services_PluginService', function() {
describe('services_PluginService', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
@@ -8,7 +8,7 @@ async function newRepoApi(): Promise<RepositoryApi> {
return repo;
}
describe('services_plugins_RepositoryApi', function() {
describe('services_plugins_RepositoryApi', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
@@ -24,7 +24,7 @@ function newPluginService(appVersion: string = '1.4') {
return service;
}
describe('defaultPluginsUtils', function() {
describe('defaultPluginsUtils', () => {
const pluginsId = ['joplin.plugin.ambrt.backlinksToNote', 'org.joplinapp.plugins.ToggleSidebars'];
@@ -1,7 +1,7 @@
const sandboxProxy = require('@joplin/lib/services/plugins/sandboxProxy');
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
describe('services_plugins_sandboxProxy', function() {
describe('services_plugins_sandboxProxy', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
+2 -2
View File
@@ -50,7 +50,7 @@ async function browserGetZoom(tabId) {
});
}
browser_.runtime.onInstalled.addListener(function() {
browser_.runtime.onInstalled.addListener(() => {
if (window.joplinEnv() === 'dev') {
browser_.browserAction.setIcon({
path: 'icons/32-dev.png',
@@ -165,7 +165,7 @@ async function sendClipMessage(clipType) {
}
}
browser_.commands.onCommand.addListener(function(command) {
browser_.commands.onCommand.addListener((command) => {
// We could enumerate these twice, but since we're in here first,
// why not save ourselves the trouble with this convention
if (command.startsWith('clip')) {
+2 -2
View File
@@ -130,8 +130,8 @@ checkBrowsers(paths.appPath, isInteractive)
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function(sig) {
process.on(sig, function() {
['SIGINT', 'SIGTERM'].forEach((sig) => {
process.on(sig, () => {
devServer.close();
process.exit();
});
+3 -3
View File
@@ -3,7 +3,7 @@ import { PluginMessage } from './services/plugins/PluginRunner';
import shim from '@joplin/lib/shim';
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';
const { BrowserWindow, Tray, screen } = require('electron');
import { BrowserWindow, Tray, screen } from 'electron';
const url = require('url');
const path = require('path');
const { dirname } = require('@joplin/lib/path-utils');
@@ -25,7 +25,7 @@ export default class ElectronAppWrapper {
private env_: string;
private isDebugMode_: boolean;
private profilePath_: string;
private win_: any = null;
private win_: BrowserWindow = null;
private willQuitApp_: boolean = false;
private tray_: any = null;
private buildDir_: string = null;
@@ -117,7 +117,7 @@ export default class ElectronAppWrapper {
this.win_.setPosition(primaryDisplayWidth / 2 - windowWidth, primaryDisplayHeight / 2 - windowHeight);
}
this.win_.loadURL(url.format({
void this.win_.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true,
+1 -1
View File
@@ -1,7 +1,7 @@
import { AppState } from './app.reducer';
import appReducer, { createAppDefaultState } from './app.reducer';
describe('app.reducer', function() {
describe('app.reducer', () => {
it('DIALOG_OPEN', async () => {
const state: AppState = createAppDefaultState({}, {});
@@ -225,7 +225,7 @@ export default function(props: Props) {
];
const menu = bridge().Menu.buildFromTemplate(template);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}, [onInstall, onBrowsePlugins]);
const onSearchQueryChange = useCallback((event: OnChangeEvent) => {
+7 -1
View File
@@ -8,6 +8,7 @@ interface Props {
onKeyDown?: Function;
itemRenderer: Function;
className?: string;
onNoteDrop?: Function;
}
interface State {
@@ -29,6 +30,7 @@ class ItemList extends React.Component<Props, State> {
this.onScroll = this.onScroll.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.onDrop = this.onDrop.bind(this);
}
visibleItemCount(props: Props = undefined) {
@@ -76,6 +78,10 @@ class ItemList extends React.Component<Props, State> {
if (this.props.onKeyDown) this.props.onKeyDown(event);
}
onDrop(event: any) {
if (this.props.onNoteDrop) this.props.onNoteDrop(event);
}
makeItemIndexVisible(itemIndex: number) {
const top = Math.min(this.props.items.length - 1, this.state.topItemIndex);
const bottom = Math.max(0, this.state.bottomItemIndex);
@@ -141,7 +147,7 @@ class ItemList extends React.Component<Props, State> {
if (this.props.className) classes.push(this.props.className);
return (
<div ref={this.listRef} className={classes.join(' ')} style={style} onScroll={this.onScroll} onKeyDown={this.onKeyDown}>
<div ref={this.listRef} className={classes.join(' ')} style={style} onScroll={this.onScroll} onKeyDown={this.onKeyDown} onDrop={this.onDrop}>
{itemComps}
</div>
);
@@ -20,7 +20,7 @@ export const runtime = (): CommandRuntime => {
const menuItems = SpellCheckerService.instance().spellCheckerConfigMenuItems(selectedLanguages, useSpellChecker);
const menu = Menu.buildFromTemplate(menuItems as any);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
},
mapStateToTitle(state: AppState): string {
+15 -12
View File
@@ -512,14 +512,14 @@ function useMenu(props: Props) {
// Issue: https://github.com/laurent22/joplin/issues/934
submenu: [{
label: _('About Joplin'),
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
click: () => _showAbout(),
}, {
type: 'separator',
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
}, {
label: _('Preferences...'),
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
accelerator: shim.isMac() && keymapService.getAccelerator('config'),
click: () => {
props.dispatch({
@@ -529,11 +529,11 @@ function useMenu(props: Props) {
},
}, {
label: _('Check for updates...'),
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
click: () => _checkForUpdates(),
}, {
type: 'separator',
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
},
shim.isMac() ? noItem : newNoteItem,
shim.isMac() ? noItem : newTodoItem,
@@ -541,14 +541,14 @@ function useMenu(props: Props) {
shim.isMac() ? noItem : newSubFolderItem,
{
type: 'separator',
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
}, {
label: _('Import'),
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
submenu: importItems,
}, {
label: _('Export all'),
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
submenu: exportItems,
}, {
type: 'separator',
@@ -586,7 +586,7 @@ function useMenu(props: Props) {
const rootMenuFileMacOs = {
label: _('&File'),
visible: shim.isMac() ? true : false,
visible: !!shim.isMac(),
submenu: [
newNoteItem,
newTodoItem,
@@ -788,12 +788,15 @@ function useMenu(props: Props) {
}, {
label: _('Joplin Forum'),
click() { void bridge().openExternal('https://discourse.joplinapp.org'); },
}, {
label: _('Join us on Twitter'),
click() { void bridge().openExternal('https://twitter.com/joplinapp'); },
}, {
label: _('Make a donation'),
click() { void bridge().openExternal('https://joplinapp.org/donate/'); },
}, {
label: _('Check for updates...'),
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
click: () => _checkForUpdates(),
},
separator(),
@@ -815,10 +818,10 @@ function useMenu(props: Props) {
{
type: 'separator',
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
}, {
label: _('About Joplin'),
visible: shim.isMac() ? false : true,
visible: !shim.isMac(),
click: () => _showAbout(),
}],
},
@@ -42,7 +42,7 @@ export default function MultiNoteActions(props: MultiNoteActionsProps) {
const multiNotesButton_click = (item: any) => {
if (item.submenu) {
item.submenu.popup(bridge().window());
item.submenu.popup({ window: bridge().window() });
} else {
item.click();
}
@@ -1,7 +1,7 @@
// Helper commands added to the the CodeMirror instance
export default function useJoplinCommands(CodeMirror: any) {
CodeMirror.defineExtension('commandExists', function(name: string) {
CodeMirror.defineExtension('commandExists', (name: string) => {
return !!CodeMirror.commands[name];
});
}
@@ -93,7 +93,7 @@ export default function useKeymap(CodeMirror: any) {
}
CodeMirror.defineExtension('supportsCommand', function(cmd: EditorCommand) {
CodeMirror.defineExtension('supportsCommand', (cmd: EditorCommand) => {
return isEditorCommand(cmd.name) && editorCommandToCodeMirror(cmd.name) in CodeMirror.commands;
});
@@ -674,7 +674,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
props_onDrop.current(event);
});
editor.on('ObjectResized', function(event: any) {
editor.on('ObjectResized', (event: any) => {
if (event.target.nodeName === 'IMG') {
editor.fire(TinyMceEditorEvents.JoplinChange);
dispatchDidUpdate(editor);
@@ -51,7 +51,7 @@ export default function(editor: any) {
editor.execCommand('mceToggleFormat', false, def.name);
},
onSetup: function(api: any) {
editor.formatter.formatChanged(def.name, function(state: boolean) {
editor.formatter.formatChanged(def.name, (state: boolean) => {
api.setActive(state);
});
},
@@ -107,7 +107,7 @@ export default function(editor: any, plugins: PluginStates, dispatch: Function)
template = template.concat(menuUtils.pluginContextMenuItems(plugins, MenuItemLocation.EditorContextMenu));
const menu = bridge().Menu.buildFromTemplate(template);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}
bridge().window().webContents.on('context-menu', onContextMenu);
@@ -9,7 +9,7 @@ export default function(dependencies: HookDependencies) {
const { folderId } = dependencies;
const [folder, setFolder] = useState(null);
useEffect(function() {
useEffect(() => {
let cancelled = false;
async function loadFolder() {
@@ -192,7 +192,7 @@ export default function useFormNote(dependencies: HookDependencies) {
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
}, [noteId, isProvisional, formNote]);
const onResourceChange = useCallback(async function(event: any = null) {
const onResourceChange = useCallback(async (event: any = null) => {
const resourceIds = await Note.linkedResourceIds(formNote.body);
if (!event || resourceIds.indexOf(event.id) >= 0) {
clearResourceCache();
@@ -45,7 +45,7 @@ export default function useMessageHandler(scrollWhenReady: any, setScrollWhenRea
fireEditorEvent: () => { console.warn('fireEditorEvent() not implemented'); },
}, dispatch);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
} else if (msg.indexOf('#') === 0) {
// This is an internal anchor, which is handled by the WebView so skip this case
} else if (msg === 'contentScriptExecuteCommand') {
+37 -9
View File
@@ -123,7 +123,7 @@ const NoteListComponent = (props: Props) => {
customCss: props.customCss,
});
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}, [props.selectedNoteIds, props.notes, props.dispatch, props.watchedNoteFiles, props.plugins, props.selectedFolderId, props.customCss]);
const onGlobalDrop_ = () => {
@@ -160,21 +160,27 @@ const NoteListComponent = (props: Props) => {
}
};
const noteItem_noteDrop = async (event: any) => {
if (props.notesParentType !== 'Folder') return;
const canManuallySortNotes = async () => {
if (props.notesParentType !== 'Folder') return false;
if (props.noteSortOrder !== 'order') {
const doIt = await bridge().showConfirmMessageBox(_('To manually sort the notes, the sort order must be changed to "%s" in the menu "%s" > "%s"', _('Custom order'), _('View'), _('Sort notes by')), {
buttons: [_('Do it now'), _('Cancel')],
});
if (!doIt) return;
if (!doIt) return false;
Setting.setValue('notes.sortOrder.field', 'order');
return;
return false;
}
return true;
};
const noteItem_noteDrop = async (event: any) => {
// TODO: check that parent type is folder
if (!canManuallySortNotes()) {
return;
}
const dt = event.dataTransfer;
unregisterGlobalDragEndEvent_();
setDragOverTargetNoteIndex(null);
@@ -182,7 +188,7 @@ const NoteListComponent = (props: Props) => {
const targetNoteIndex = dragTargetNoteIndex_(event);
const noteIds = JSON.parse(dt.getData('text/x-jop-note-ids'));
void Note.insertNotesAt(props.selectedFolderId, noteIds, targetNoteIndex);
void Note.insertNotesAt(props.selectedFolderId, noteIds, targetNoteIndex, props.uncompletedTodosOnTop, props.showCompletedTodos);
};
@@ -269,7 +275,6 @@ const NoteListComponent = (props: Props) => {
onCheckboxClick={noteItem_checkboxClick}
onDragStart={noteItem_dragStart}
onNoteDragOver={noteItem_noteDragOver}
onNoteDrop={noteItem_noteDrop}
onTitleClick={noteItem_titleClick}
onContextMenu={itemContextMenu}
/>;
@@ -340,11 +345,31 @@ const NoteListComponent = (props: Props) => {
return noteIndex;
};
const noteItem_noteMove = async (direction: number) => {
if (!canManuallySortNotes()) {
return;
}
const noteIds = props.selectedNoteIds;
const noteId = noteIds[0];
let targetNoteIndex = BaseModel.modelIndexById(props.notes, noteId);
if ((direction === 1)) {
targetNoteIndex += 2;
}
if ((direction === -1)) {
targetNoteIndex -= 1;
}
void Note.insertNotesAt(props.selectedFolderId, noteIds, targetNoteIndex, props.uncompletedTodosOnTop, props.showCompletedTodos);
};
const onKeyDown = async (event: any) => {
const keyCode = event.keyCode;
const noteIds = props.selectedNoteIds;
if (noteIds.length > 0 && (keyCode === 40 || keyCode === 38 || keyCode === 33 || keyCode === 34 || keyCode === 35 || keyCode === 36)) {
if ((keyCode === 40 || keyCode === 38) && event.altKey) {
// (DOWN / UP) & ALT
await noteItem_noteMove(keyCode === 40 ? 1 : -1);
event.preventDefault();
} else if (noteIds.length > 0 && (keyCode === 40 || keyCode === 38 || keyCode === 33 || keyCode === 34 || keyCode === 35 || keyCode === 36)) {
// DOWN / UP / PAGEDOWN / PAGEUP / END / HOME
const noteId = noteIds[0];
let noteIndex = BaseModel.modelIndexById(props.notes, noteId);
@@ -500,6 +525,7 @@ const NoteListComponent = (props: Props) => {
style={props.size}
itemRenderer={renderItem}
onKeyDown={onKeyDown}
onNoteDrop={noteItem_noteDrop}
/>
);
};
@@ -528,6 +554,8 @@ const mapStateToProps = (state: AppState) => {
provisionalNoteIds: state.provisionalNoteIds,
isInsertingNotes: state.isInsertingNotes,
noteSortOrder: state.settings['notes.sortOrder.field'],
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
showCompletedTodos: state.settings.showCompletedTodos,
highlightedWords: state.highlightedWords,
plugins: state.pluginService.plugins,
customCss: state.customCss,
@@ -12,6 +12,8 @@ export interface Props {
customCss: string;
notesParentType: string;
noteSortOrder: string;
uncompletedTodosOnTop: boolean;
showCompletedTodos: boolean;
resizableLayoutEventEmitter: any;
isInsertingNotes: boolean;
folders: FolderEntity[];
@@ -17,12 +17,13 @@ interface Props {
sortOrderField: string;
sortOrderReverse: boolean;
notesParentType: string;
height: number;
}
const StyledRoot = styled.div`
box-sizing: border-box;
height: ${(props: any) => props.height}px;
display: flex;
height: auto;
flex-direction: column;
padding: ${(props: any) => props.theme.mainPadding}px;
background-color: ${(props: any) => props.theme.backgroundColor3};
@@ -69,7 +70,7 @@ const SortOrderButtonsContainer = styled.div`
function NoteListControls(props: Props) {
const searchBarRef = useRef(null);
useEffect(function() {
useEffect(() => {
CommandService.instance().registerRuntime('focusSearch', focusSearchRuntime(searchBarRef));
return function() {
@@ -56,7 +56,6 @@ interface NoteListItemProps {
onCheckboxClick: any;
onDragStart: any;
onNoteDragOver: any;
onNoteDrop: any;
onTitleClick: any;
onContextMenu(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>): void;
}
@@ -175,7 +174,6 @@ function NoteListItem(props: NoteListItemProps, ref: any) {
<StyledRoot
className={classNames}
onDragOver={props.onNoteDragOver}
onDrop={props.onNoteDrop}
width={props.width}
height={props.height}
isProvisional={props.isProvisional}
@@ -1,3 +1,4 @@
import { themeStyle } from '@joplin/lib/theme';
import * as React from 'react';
import { useMemo } from 'react';
import NoteList from '../NoteList/NoteList';
@@ -20,16 +21,19 @@ const StyledRoot = styled.div`
`;
export default function NoteListWrapper(props: Props) {
const theme = themeStyle(props.themeId);
const controlHeight = theme.topRowHeight;
const noteListSize = useMemo(() => {
return {
width: props.size.width,
height: props.size.height,
height: props.size.height - controlHeight,
};
}, [props.size]);
}, [props.size, controlHeight]);
return (
<StyledRoot>
<NoteListControls />
<NoteListControls height={controlHeight}/>
<NoteList resizableLayoutEventEmitter={props.resizableLayoutEventEmitter} size={noteListSize} visible={props.visible}/>
</StyledRoot>
);
+1 -1
View File
@@ -62,7 +62,7 @@ export default function PdfViewer(props: Props) {
fireEditorEvent: () => { console.warn('fireEditorEvent() not implemented'); },
} as ContextMenuOptions, props.dispatch);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}, [props.dispatch]);
const onMessage_ = useCallback(async (event: any) => {
+1 -1
View File
@@ -98,7 +98,7 @@ const GlobalStyle = createGlobalStyle`
let wcsTimeoutId_: any = null;
async function initialize() {
bridge().window().on('resize', function() {
bridge().window().on('resize', () => {
if (wcsTimeoutId_) shim.clearTimeout(wcsTimeoutId_);
wcsTimeoutId_ = shim.setTimeout(() => {
@@ -8,7 +8,7 @@ import Setting from '@joplin/lib/models/Setting';
import restart from '../services/restart';
function useAppCloseHandler(upgradeResult: SyncTargetUpgradeResult) {
useEffect(function() {
useEffect(() => {
async function onAppClose() {
let canClose = true;
@@ -38,7 +38,7 @@ function useAppCloseHandler(upgradeResult: SyncTargetUpgradeResult) {
}
function useStyle() {
useEffect(function() {
useEffect(() => {
const element = document.createElement('style');
element.appendChild(document.createTextNode(`
body {
@@ -62,7 +62,7 @@ function useStyle() {
}
function useRestartOnDone(upgradeResult: SyncTargetUpgradeResult) {
useEffect(function() {
useEffect(() => {
if (upgradeResult.done && !upgradeResult.error) {
void restart();
}
+15 -4
View File
@@ -1,5 +1,7 @@
import * as React from 'react';
import { useEffect, useRef, useCallback, useMemo } from 'react';
import styled from 'styled-components';
import shim from '@joplin/lib/shim';
import { StyledRoot, StyledAddButton, StyledShareIcon, StyledHeader, StyledHeaderIcon, StyledAllNotesIcon, StyledHeaderLabel, StyledListItem, StyledListItemAnchor, StyledExpandLink, StyledNoteCount, StyledSyncReportText, StyledSyncReport, StyledSynchronizeButton } from './styles';
import { ButtonLevel } from '../Button/Button';
import CommandService from '@joplin/lib/services/CommandService';
@@ -38,6 +40,15 @@ const { clipboard } = require('electron');
const logger = Logger.create('Sidebar');
const StyledFoldersHolder = styled.div`
// linux bug: https://github.com/laurent22/joplin/issues/7506#issuecomment-1447101057
& a.list-item {
${shim.isLinux() && {
opacity: 1,
}}
}
`;
interface Props {
themeId: number;
dispatch: Function;
@@ -271,7 +282,7 @@ const SidebarComponent = (props: Props) => {
new MenuItem(menuUtils.commandToStatefulMenuItem('newFolder'))
);
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}, []);
const itemContextMenu = useCallback(async (event: any) => {
@@ -423,7 +434,7 @@ const SidebarComponent = (props: Props) => {
}
}
menu.popup(bridge().window());
menu.popup({ window: bridge().window() });
}, [props.folders, props.dispatch, pluginsRef]);
const folderItem_click = useCallback((folderId: string) => {
@@ -705,13 +716,13 @@ const SidebarComponent = (props: Props) => {
const folderItems = [renderAllNotesItem(theme, allNotesSelected)].concat(result.items);
folderItemsOrder_.current = result.order;
items.push(
<div
<StyledFoldersHolder
className={`folders ${props.folderHeaderIsExpanded ? 'expanded' : ''}`}
key="folder_items"
style={foldersStyle}
>
{folderItems}
</div>
</StyledFoldersHolder>
);
}
+43 -11
View File
@@ -154,34 +154,66 @@
setPercentScroll(percentScroll_);
}
// Note that this function keeps track of what's been added so as not to add the same CSS files multiple times
// It also means that once an asset has been added it is never removed from the view, which in many case is
// desirable, but still something to keep in mind.
// Note that this function keeps track of what's been added so as not to
// add the same CSS files multiple times.
function addPluginAssets(assets) {
if (!assets) return;
const pluginAssetsContainer = document.getElementById('joplin-container-pluginAssetsContainer');
const processedAssetIds = [];
for (let i = 0; i < assets.length; i++) {
const asset = assets[i];
// # and ? can be used in valid paths and shouldn't be treated as the start of a query or fragment
const encodedPath = asset.path
.replaceAll('#','%23')
.replaceAll('?','%3F')
const assetId = asset.name ? asset.name : encodedPath;
processedAssetIds.push(assetId);
if (pluginAssetsAdded_[assetId]) continue;
pluginAssetsAdded_[assetId] = true;
let element = null;
if (asset.mime === 'application/javascript') {
const script = document.createElement('script');
script.src = encodedPath;
pluginAssetsContainer.appendChild(script);
element = document.createElement('script');
element.src = encodedPath;
pluginAssetsContainer.appendChild(element);
} else if (asset.mime === 'text/css') {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = encodedPath
pluginAssetsContainer.appendChild(link);
element = document.createElement('link');
element.rel = 'stylesheet';
element.href = encodedPath
pluginAssetsContainer.appendChild(element);
}
pluginAssetsAdded_[assetId] = {
element,
}
}
// Once we have added the relevant assets, we also remove those that
// are no longer needed. It's necessary in particular for the CSS
// generated by noteStyle - if we don't remove it, we might end up
// with two or more stylesheet and that will create conflicts.
//
// It was happening for example when automatically switching from
// light to dark theme, and then back to light theme - in that case
// the viewer would remain dark because it would use the dark
// stylesheet that would still be in the DOM.
for (const [assetId, asset] of Object.entries(pluginAssetsAdded_)) {
if (!processedAssetIds.includes(assetId)) {
try {
asset.element.remove();
} catch (error) {
// We don't throw an exception but we log it since
// it shouldn't happen
console.warn('Tried to remove an asset but got an error', error);
}
pluginAssetsAdded_[assetId] = null;
}
}
}
+1 -1
View File
@@ -188,7 +188,7 @@ webviewLib.initialize = function(options) {
webviewLib.options_ = options;
};
document.addEventListener('click', function(event) {
document.addEventListener('click', (event) => {
const anchor = webviewLib.getParentAnchorElement(event.target);
if (!anchor) return;
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@joplin/app-desktop",
"version": "2.10.6",
"version": "2.10.8",
"description": "Joplin for Desktop",
"main": "main.js",
"private": true,
@@ -120,8 +120,8 @@
"electron-rebuild": "3.2.9",
"glob": "8.1.0",
"gulp": "4.0.2",
"jest": "29.4.2",
"jest-environment-jsdom": "29.4.2",
"jest": "29.4.3",
"jest-environment-jsdom": "29.4.3",
"js-sha512": "0.8.0",
"nan": "2.17.0",
"react-test-renderer": "18.2.0",
@@ -233,7 +233,7 @@ const create = (win, options) => {
// When this is being called from a web view, we can't use `win` as this
// would refer to the web view which is not allowed to render a popup menu.
//
menu.popup(electronRemote ? electronRemote.getCurrentWindow() : win);
menu.popup({ window: electronRemote ? electronRemote.getCurrentWindow() : win });
}
});
};
+2 -2
View File
@@ -150,8 +150,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2097682
versionName "2.10.6"
versionCode 2097684
versionName "2.10.8"
// ndk {
// abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
// }
@@ -78,10 +78,13 @@ public class SharePackage implements ReactPackage {
@ReactMethod
public void close() {
Activity currentActivity = getCurrentActivity();
if (currentActivity != null) {
currentActivity.finish();
}
// We disable this, because otherwise it would close the whole application
// https://github.com/laurent22/joplin/issues/7791#issuecomment-1436078948
// Activity currentActivity = getCurrentActivity();
// if (currentActivity != null) {
// currentActivity.finish();
// }
}
@ReactMethod
@@ -10,7 +10,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# 2023-02-20: Removed option "-XX:MaxPermSize=2048m" because no longer exist in JDK 19
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
@@ -517,13 +517,13 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 89;
DEVELOPMENT_TEAM = A9BXAFS6CT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 12.10.2;
MARKETING_VERSION = 12.10.5;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -546,12 +546,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Joplin/Joplin.entitlements;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 89;
DEVELOPMENT_TEAM = A9BXAFS6CT;
INFOPLIST_FILE = Joplin/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 12.10.2;
MARKETING_VERSION = 12.10.5;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -614,9 +614,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
@@ -672,9 +670,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n",
);
HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS\n\n";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
@@ -702,14 +698,14 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 89;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = A9BXAFS6CT;
GCC_C_LANGUAGE_STANDARD = gnu11;
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.2;
MARKETING_VERSION = 12.10.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
@@ -733,14 +729,14 @@
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 86;
CURRENT_PROJECT_VERSION = 89;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = A9BXAFS6CT;
GCC_C_LANGUAGE_STANDARD = gnu11;
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.2;
MARKETING_VERSION = 12.10.5;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = net.cozic.joplin.ShareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
+6 -6
View File
@@ -324,7 +324,7 @@ PODS:
- React-Core
- react-native-get-random-values (1.8.0):
- React-Core
- react-native-image-picker (5.0.1):
- react-native-image-picker (5.0.2):
- React-Core
- react-native-image-resizer (1.4.5):
- React-Core
@@ -332,7 +332,7 @@ PODS:
- React-Core
- react-native-rsa-native (2.0.5):
- React
- react-native-saf-x (2.10.0):
- react-native-saf-x (2.10.2):
- React-Core
- react-native-safe-area-context (4.5.0):
- RCT-Folly
@@ -420,7 +420,7 @@ PODS:
- React-Core
- RNCPushNotificationIOS (1.10.1):
- React-Core
- RNDateTimePicker (6.7.4):
- RNDateTimePicker (6.7.5):
- React-Core
- RNExitApp (1.1.0):
- React
@@ -720,11 +720,11 @@ SPEC CHECKSUMS:
react-native-fingerprint-scanner: ac6656f18c8e45a7459302b84da41a44ad96dbbe
react-native-geolocation: 69f4fd37650b8e7fee91816d395e62dd16f5ab8d
react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a
react-native-image-picker: 8cb4280e2c1efc3daeb2d9d597f9429a60472e40
react-native-image-picker: a5dddebb4d2955ac4712a4ed66b00a85f62a63ac
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
react-native-saf-x: 22bcd49188a04d6d6df254ca33085f26e28879c9
react-native-saf-x: db5a33862e7aec0f9f2d4cccfe7264b09b234e2e
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
@@ -745,7 +745,7 @@ SPEC CHECKSUMS:
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45
RNDateTimePicker: 2cc0a68b714aba89b4bc017796cd8c8825e0c3a7
RNDateTimePicker: 65e1d202799460b286ff5e741d8baf54695e8abd
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
+6 -6
View File
@@ -23,7 +23,7 @@
"@joplin/react-native-saf-x": "~2.10",
"@joplin/renderer": "~2.10",
"@react-native-community/clipboard": "1.5.1",
"@react-native-community/datetimepicker": "6.7.4",
"@react-native-community/datetimepicker": "6.7.5",
"@react-native-community/geolocation": "2.1.0",
"@react-native-community/netinfo": "9.3.7",
"@react-native-community/push-notification-ios": "1.10.1",
@@ -51,16 +51,16 @@
"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.0.1",
"react-native-image-picker": "5.0.2",
"react-native-image-resizer": "1.4.5",
"react-native-modal-datetime-picker": "14.0.1",
"react-native-paper": "5.1.4",
"react-native-paper": "5.2.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-securerandom": "1.0.1",
"react-native-share": "8.1.0",
"react-native-share": "8.2.0",
"react-native-side-menu-updated": "1.3.2",
"react-native-sqlite-storage": "6.0.1",
"react-native-url-polyfill": "1.3.0",
@@ -102,8 +102,8 @@
"execa": "4.1.0",
"fs-extra": "11.1.0",
"gulp": "4.0.2",
"jest": "29.4.2",
"jest-environment-jsdom": "29.4.2",
"jest": "29.4.3",
"jest-environment-jsdom": "29.4.3",
"jetifier": "2.0.0",
"jsdom": "21.0.0",
"md5-file": "5.0.0",
+6 -3
View File
@@ -729,7 +729,7 @@ class AppComponent extends React.Component {
};
this.handleOpenURL_ = (event: any) => {
logger.info('Sharing: handleOpenURL_: start');
// logger.info('Sharing: handleOpenURL_: start');
// If this is called while biometrics haven't been done yet, we can
// ignore the call, because handleShareData() will be called once
@@ -741,7 +741,7 @@ class AppComponent extends React.Component {
};
this.handleNewShare_ = () => {
logger.info('Sharing: handleNewShare_: start');
// logger.info('Sharing: handleNewShare_: start');
// look at this.handleOpenURL_ comment
if (this.props.biometricsDone) {
@@ -981,6 +981,9 @@ class AppComponent extends React.Component {
// const statusBarStyle = theme.appearance === 'light-content';
const statusBarStyle = 'light-content';
const biometricIsEnabled = !!this.state.sensorInfo && this.state.sensorInfo.enabled;
const shouldShowMainContent = !biometricIsEnabled || this.props.biometricsDone;
const mainContent = (
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
<SideMenu
@@ -1001,7 +1004,7 @@ class AppComponent extends React.Component {
<SafeAreaView style={{ flex: 0, backgroundColor: theme.backgroundColor2 }}/>
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
<AppNav screens={appNavInit} dispatch={this.props.dispatch} />
{ shouldShowMainContent && <AppNav screens={appNavInit} dispatch={this.props.dispatch} /> }
</View>
<DropdownAlert ref={(ref: any) => this.dropdownAlert_ = ref} tapToCloseEnabled={true} />
<Animated.View pointerEvents='none' style={{ position: 'absolute', backgroundColor: 'black', opacity: this.state.sideMenuContentOpacity, width: '100%', height: '120%' }}/>
+1 -1
View File
@@ -8,7 +8,7 @@ const outputDir = `${rootDir}/pluginAssets`;
const walk = function(dir) {
let results = [];
const list = fs.readdirSync(dir);
list.forEach(function(file) {
list.forEach((file) => {
file = `${dir}/${file}`;
const stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
+2 -2
View File
@@ -215,8 +215,8 @@ function shimInit() {
};
shim.waitForFrame = () => {
return new Promise(function(resolve) {
requestAnimationFrame(function() {
return new Promise((resolve) => {
requestAnimationFrame(() => {
resolve();
});
});
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@joplin/fork-htmlparser2",
"description": "Fast & forgiving HTML/XML/RSS parser",
"version": "4.1.41",
"version": "4.1.43",
"author": "Felix Boehm <me@feedic.com>",
"publishConfig": {
"access": "public"
@@ -52,7 +52,7 @@
"coveralls": "3.1.1",
"eslint": "8.31.0",
"eslint-config-prettier": "8.6.0",
"jest": "29.4.2",
"jest": "29.4.3",
"prettier": "2.8.3",
"ts-jest": "29.0.5",
"typescript": "4.9.4"
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "@joplin/fork-sax",
"description": "An evented streaming XML parser in JavaScript",
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"version": "1.2.45",
"version": "1.2.47",
"main": "lib/sax.js",
"publishConfig": {
"access": "public"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@joplin/fork-uslug",
"version": "1.0.6",
"version": "1.0.8",
"description": "A permissive slug generator that works with unicode.",
"author": "Jeremy Selier <jerem.selier@gmail.com>",
"publishConfig": {
@@ -43,7 +43,7 @@ function mergePackageKey(parentKey, source, dest) {
function mergeIgnoreFile(source, dest) {
const output = dest.trim().split(/\r?\n/).concat(source.trim().split(/\r?\n/));
return `${output.filter(function(item, pos) {
return `${output.filter((item, pos) => {
if (!item) return true; // Leave blank lines
return output.indexOf(item) === pos;
}).join('\n').trim()}\n`;
+2 -2
View File
@@ -25,11 +25,11 @@
"dependencies": {
"chalk": "2.4.2",
"slugify": "1.6.5",
"yeoman-generator": "5.7.0",
"yeoman-generator": "5.7.1",
"yosay": "2.0.2"
},
"devDependencies": {
"jest": "29.4.2"
"jest": "29.4.3"
},
"repository": "https://github.com/laurent22/generator-joplin",
"license": "AGPL-3.0-or-later",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@joplin/htmlpack",
"version": "2.10.0",
"version": "2.10.2",
"description": "Pack an HTML file and all its linked resources into a single HTML file",
"main": "dist/index.js",
"types": "src/index.ts",
@@ -14,7 +14,7 @@
"author": "Laurent Cozic",
"license": "MIT",
"dependencies": {
"@joplin/fork-htmlparser2": "^4.1.41",
"@joplin/fork-htmlparser2": "^4.1.43",
"css": "3.0.0",
"datauri": "4.1.0",
"fs-extra": "11.1.0",
+1 -1
View File
@@ -1,6 +1,6 @@
const ArrayUtils = require('./ArrayUtils');
describe('ArrayUtils', function() {
describe('ArrayUtils', () => {
+1 -1
View File
@@ -1,5 +1,5 @@
export const unique = function(array: any[]) {
return array.filter(function(elem, index, self) {
return array.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
};
+1 -1
View File
@@ -198,7 +198,7 @@ export default class ClipperServer {
if (contentType.indexOf('multipart/form-data') === 0) {
const form = new multiparty.Form();
form.parse(request, function(error: any, fields: any, files: any) {
form.parse(request, (error: any, fields: any, files: any) => {
if (error) {
writeResponse(error.httpCode ? error.httpCode : 500, error.message);
return;
+1 -1
View File
@@ -1,7 +1,7 @@
import InMemoryCache from './InMemoryCache';
import time from './time';
describe('InMemoryCache', function() {
describe('InMemoryCache', () => {
it('should get and set values', () => {
const cache = new InMemoryCache();
+5 -1
View File
@@ -354,7 +354,7 @@ export default class JoplinDatabase extends Database {
// must be set in the synchronizer too.
// Note: v16 and v17 don't do anything. They were used to debug an issue.
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41];
const existingDatabaseVersions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42];
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
@@ -913,6 +913,10 @@ export default class JoplinDatabase extends Database {
queries.push('ALTER TABLE `folders` ADD COLUMN icon TEXT NOT NULL DEFAULT ""');
}
if (targetVersion === 42) {
queries.push(this.addMigrationFile(42));
}
const updateVersionQuery = { sql: 'UPDATE version SET version = ?', params: [targetVersion] };
queries.push(updateVersionQuery);
+19 -1
View File
@@ -81,7 +81,25 @@ class Logger {
}
public static get globalLogger(): Logger {
if (!this.globalLogger_) throw new Error('Global logger has not been initialized!!');
if (!this.globalLogger_) {
// The global logger normally is initialized early, so we shouldn't
// end up here. However due to early event handlers, it might happen
// and in this case we want to know about it. So we print this
// warning, and also flag the log statements using `[UNINITIALIZED
// GLOBAL LOGGER]` so that we know from where the incorrect log
// statement comes from.
console.warn('Logger: Trying to access globalLogger, but it has not been initialized. Make sure that initializeGlobalLogger() has been called before logging. Will use the console as fallback.');
const output: any = {
log: (level: LogLevel, prefix: string, ...object: any[]) => {
// eslint-disable-next-line no-console
console.info(`[UNINITIALIZED GLOBAL LOGGER] ${this.levelIdToString(level)}: ${prefix}:`, object);
},
};
return output;
// throw new Error('Global logger has not been initialized!!');
}
return this.globalLogger_;
}
+1 -1
View File
@@ -8,7 +8,7 @@ export function sortByValue(object: any) {
});
}
temp.sort(function(a, b) {
temp.sort((a, b) => {
let v1 = a.value;
let v2 = b.value;
if (typeof v1 === 'string') v1 = v1.toLowerCase();
+1 -1
View File
@@ -3,7 +3,7 @@
const { splitCommandBatch } = require('./string-utils');
const StringUtils = require('./string-utils');
describe('StringUtils', function() {
describe('StringUtils', () => {
+2
View File
@@ -5,6 +5,7 @@ const { FileApi } = require('./file-api.js');
const Synchronizer = require('./Synchronizer').default;
const WebDavApi = require('./WebDavApi');
const { FileApiDriverWebDav } = require('./file-api-driver-webdav');
const checkProviderIsSupported = require('./utils/webDAVUtils').default;
class SyncTargetWebDAV extends BaseSyncTarget {
static id() {
@@ -56,6 +57,7 @@ class SyncTargetWebDAV extends BaseSyncTarget {
};
try {
checkProviderIsSupported(options.path());
const result = await fileApi.stat('');
if (!result) throw new Error(`WebDAV directory not found: ${options.path()}`);
output.ok = true;
+1 -1
View File
@@ -1,7 +1,7 @@
const { setupDatabaseAndSynchronizer, sleep, switchClient } = require('./testing/test-utils.js');
const TaskQueue = require('./TaskQueue').default;
describe('TaskQueue', function() {
describe('TaskQueue', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
+1 -1
View File
@@ -10,7 +10,7 @@ export function shuffle<T>(array: T[]): T[] {
}
export function unique<T>(array: T[]): T[] {
return array.filter(function(elem, index, self) {
return array.filter((elem, index, self) => {
return index === self.indexOf(elem);
});
}
+1 -1
View File
@@ -1,6 +1,6 @@
import * as callbackUrlUtils from './callbackUrlUtils';
describe('callbackUrlUtils', function() {
describe('callbackUrlUtils', () => {
it('should identify valid callback urls', () => {
const url = 'joplin://x-callback-url/123?a=b';
@@ -120,27 +120,30 @@ shared.saveNoteButton_press = async function(comp: any, folderId: string = null,
comp.setState(newState);
if (isProvisionalNote) {
const geoNote: any = await Note.updateGeolocation(note.id);
const updateGeoloc = async () => {
const geoNote: NoteEntity = await Note.updateGeolocation(note.id);
// TODO: CHECK - this code has never worked??
const stateNote = comp.state.note;
if (!stateNote || !geoNote) return;
if (stateNote.id !== geoNote.id) return; // Another note has been loaded while geoloc was being retrieved
const stateNote = comp.state.note;
if (!stateNote || !geoNote) return;
if (stateNote.id !== geoNote.id) return; // Another note has been loaded while geoloc was being retrieved
// Geo-location for this note has been saved to the database however the properties
// are is not in the state so set them now.
// Geo-location for this note has been saved to the database however the properties
// are is not in the state so set them now.
const geoInfo = {
longitude: geoNote.longitude,
latitude: geoNote.latitude,
altitude: geoNote.altitude,
};
const geoInfo = {
longitude: geoNote.longitude,
latitude: geoNote.latitude,
altitude: geoNote.altitude,
const modNote = Object.assign({}, stateNote, geoInfo);
const modLastSavedNote = Object.assign({}, comp.state.lastSavedNote, geoInfo);
comp.setState({ note: modNote, lastSavedNote: modLastSavedNote });
};
const modNote = Object.assign({}, stateNote, geoInfo);
const modLastSavedNote = Object.assign({}, comp.state.lastSavedNote, geoInfo);
comp.setState({ note: modNote, lastSavedNote: modLastSavedNote });
// We don't wait because it can be done in the background
void updateGeoloc();
}
releaseMutex();
@@ -233,7 +236,7 @@ shared.initState = async function(comp: any) {
mode: mode,
folder: folder,
isLoading: false,
fromShare: comp.props.sharedData ? true : false,
fromShare: !!comp.props.sharedData,
noteResources: await shared.attachedResources(note ? note.body : ''),
});
+1 -1
View File
@@ -1,7 +1,7 @@
const { setupDatabaseAndSynchronizer, switchClient } = require('./testing/test-utils.js');
const BaseModel = require('./BaseModel').default;
describe('database', function() {
describe('database', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
+1 -1
View File
@@ -4,7 +4,7 @@
const { checkThrow } = require('./testing/test-utils.js');
const eventManager = require('./eventManager').default;
describe('eventManager', function() {
describe('eventManager', () => {
beforeEach(async () => {
eventManager.reset();
+6
View File
@@ -1,6 +1,8 @@
const { basicDelta } = require('./file-api');
const { rtrimSlashes, ltrimSlashes } = require('./path-utils');
const JoplinError = require('./JoplinError').default;
const Setting = require('./models/Setting').default;
const checkProviderIsSupported = require('./utils/webDAVUtils').default;
class FileApiDriverWebDav {
constructor(api) {
@@ -224,6 +226,10 @@ class FileApiDriverWebDav {
await this.delete('');
await this.mkdir('');
}
initialize() {
checkProviderIsSupported(Setting.value('sync.6.path'));
}
}
module.exports = { FileApiDriverWebDav };
+1 -1
View File
@@ -1,6 +1,6 @@
import { afterAllCleanUp, setupDatabaseAndSynchronizer, switchClient, fileApi } from './testing/test-utils';
describe('file-api-driver', function() {
describe('file-api-driver', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
+1 -1
View File
@@ -422,7 +422,7 @@ async function basicDelta(path: string, getDirStatFn: Function, options: any) {
// Stats are cached until all items have been processed (until hasMore is false)
if (newContext.statsCache === null) {
newContext.statsCache = await getDirStatFn(path);
newContext.statsCache.sort(function(a: any, b: any) {
newContext.statsCache.sort((a: any, b: any) => {
return a.updated_time - b.updated_time;
});
newContext.statIdsCache = newContext.statsCache.filter((item: any) => BaseItem.isSystemPath(item.path)).map((item: any) => BaseItem.pathToId(item.path));
+1 -1
View File
@@ -12,7 +12,7 @@ function platformPath(path: string) {
}
}
describe('fsDriver', function() {
describe('fsDriver', () => {
it('should resolveRelativePathWithinDir', async () => {
const fsDriver = new FsDriverNode();
+1 -1
View File
@@ -1,6 +1,6 @@
import htmlUtils from './htmlUtils';
describe('htmlUtils', function() {
describe('htmlUtils', () => {
+5 -5
View File
@@ -69,12 +69,12 @@ function enexXmlToHtml_(stream, resources) {
parent: null,
};
saxStream.on('error', function(e) {
saxStream.on('error', (e) => {
console.warn(e);
});
saxStream.on('text', function(text) {
saxStream.on('text', (text) => {
section.lines.push(htmlentities(text));
});
@@ -135,14 +135,14 @@ function enexXmlToHtml_(stream, resources) {
}
});
saxStream.on('closetag', function(node) {
saxStream.on('closetag', (node) => {
const tagName = node ? node.toLowerCase() : node;
if (!htmlUtils.isSelfClosingTag(tagName)) section.lines.push(`</${tagName}>`);
});
saxStream.on('attribute', function() {});
saxStream.on('attribute', () => {});
saxStream.on('end', function() {
saxStream.on('end', () => {
resolve({
content: section,
resources: remainingResources,
+1 -1
View File
@@ -58,7 +58,7 @@ const compareOutputToExpected = (options) => {
}));
};
describe('EnexToHtml', function() {
describe('EnexToHtml', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
+1 -1
View File
@@ -13,7 +13,7 @@ import Resource from './models/Resource';
const enexSampleBaseDir = `${supportDir}/../enex_to_md`;
describe('import-enex-md-gen', function() {
describe('import-enex-md-gen', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
+5 -5
View File
@@ -587,7 +587,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
parent: null,
};
saxStream.on('error', function(e: any) {
saxStream.on('error', (e: any) => {
console.warn(e);
});
@@ -615,7 +615,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
return output;
};
saxStream.on('text', function(text: string) {
saxStream.on('text', (text: string) => {
if (['table', 'tr', 'tbody'].indexOf(section.type) >= 0) return;
text = !state.inPre ? unwrapInnerText(text) : text;
@@ -923,7 +923,7 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
}
});
saxStream.on('closetag', function(n: string) {
saxStream.on('closetag', (n: string) => {
n = n ? n.toLowerCase() : n;
const poppedTag = state.tags.pop();
@@ -1121,9 +1121,9 @@ function enexXmlToMdArray(stream: any, resources: ResourceEntity[]): Promise<Ene
}
});
saxStream.on('attribute', function() {});
saxStream.on('attribute', () => {});
saxStream.on('end', function() {
saxStream.on('end', () => {
resolve({
content: section,
resources: remainingResources,
+4 -4
View File
@@ -53,7 +53,7 @@ async function decodeBase64File(sourceFilePath: string, destFilePath: string) {
// would be ignored. I don't think it's happening anymore, but something to keep in mind
// anyway.
return new Promise(function(resolve, reject) {
return new Promise((resolve, reject) => {
// Note: we manually handle closing the file so that we can
// force flusing it before close. This is needed because
// "end" might be called before the file has been flushed
@@ -528,7 +528,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
}
}));
saxStream.on('opentag', handleSaxStreamEvent(function(node: Node) {
saxStream.on('opentag', handleSaxStreamEvent((node: Node) => {
const n = node.name.toLowerCase();
nodes.push(node);
@@ -551,7 +551,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
}
}));
saxStream.on('cdata', handleSaxStreamEvent(function(data: any) {
saxStream.on('cdata', handleSaxStreamEvent((data: any) => {
const n = currentNodeName();
if (noteResourceRecognition) {
@@ -633,7 +633,7 @@ export default async function importEnex(parentFolderId: string, filePath: strin
}
}));
saxStream.on('end', handleSaxStreamEvent(function() {
saxStream.on('end', handleSaxStreamEvent(() => {
// Wait till there is no more notes to process.
const iid = shim.setInterval(() => {
// eslint-disable-next-line promise/prefer-await-to-then -- Old code before rule was applied
+29
View File
@@ -9,6 +9,7 @@
"%d MB per note or attachment": "%d MB pr. note eller vedhæftning",
"%d minutes": "%d minutter",
"%d notes match this pattern. Delete them?": "%d noter der matcher dette mønster. Slet dem?",
"%s": "%s",
"%s %s (%s, %s)": "%s %s (%s, %s)",
"%s (%s) could not be uploaded: %s": "%s (%s) kunne ikke uploades: %s",
"%s (%s) would like to share a notebook with you.": "%s (%s) vil gerne dele en notesbog med dig.",
@@ -62,6 +63,7 @@
"Admin dashboard": "Kontrolpanel til administration",
"Advanced options": "Avancerede indstillinger",
"Advanced tools": "Avancerede værktøjer",
"All data, including notes, notebooks and tags will be permanently deleted.": "Alle data, herunder noter, notesbøger og etiketter, bliver slettet permanent.",
"All notes": "Alle noter",
"All potential ports are in use - please report the issue at %s": "Alle mulige porte er i brug - rapportér venligst problemet på %s",
"Also displays unset and hidden config variables.": "Viser også tomme eller skjulte konfigurations variabler.",
@@ -74,6 +76,7 @@
"Application": "Program",
"Apply": "Anvend",
"Are you sure you want to renew the authorisation token?": "Er du sikker på, at du vil forny autorisationstoken?",
"Are you sure you want to return to the default layout? The current layout configuration will be lost.": "Er du sikker på, at du vil vende tilbage til standardlayoutet? Den aktuelle layoutkonfiguration vil gå tabt.",
"Arguments:": "Argumenter:",
"Aritim Dark": "Aritim Mørk",
"Attach": "Vedhæft",
@@ -136,6 +139,7 @@
"Click to add tags...": "Klik for at tilføje etiketter...",
"Client ID: %s": "Klient-ID: %s",
"Close": "Luk",
"Close dropdown": "Luk rullelisten",
"Close Window": "Luk vindue",
"Code": "Kode",
"Code Block": "Kode blok",
@@ -161,6 +165,7 @@
"Conflicts (attachments)": "Konflikter (vedhæftninger)",
"Consolidated billing": "Konsolideret fakturering",
"Content provided by %s": "Indhold leveret af %s",
"Continue": "Fortsæt",
"Convert to note": "Konverter til note",
"Convert to todo": "Konverter til opgave",
"Copy": "Kopier",
@@ -178,8 +183,10 @@
"Could not export notes: %s": "Kunne ikke eksportere noterne: %s",
"Could not install plugin: %s": "Kunne ikke installere plugin: %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\"": "Kunne ikke svare på invitationen. Prøv venligst igen, eller kontakt ejeren af notesbogen, hvis de stadig deler den\n\nFejlen var: \"%s\"",
"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...",
@@ -228,9 +235,11 @@
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "Slet notesbogen \"%s\"?\n\nAlle noter og undernotesbøger i denne notesbog bliver også slettet.",
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "Slet notesbog? Alle noter og undernotesbøger i denne notesbog bliver også slettet.",
"Delete plugin \"%s\"?": "Slet udvidelse \"%s\"?",
"Delete profile \"%s\"": "Slet profilen \"%s\"",
"Delete selected notes": "Slet valgte noter",
"Delete these %d notes?": "Slet disse %d noter?",
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "Vil du slette denne invitation? Modtageren vil ikke længere have adgang til denne delte notesbog.",
"Delete this profile?": "Slet denne profil?",
"Deleted local items: %d.": "Slettede lokale emner: %d.",
"Deleted remote items: %d.": "Slettede fjern-emner: %d.",
"Deletes the given notebook.": "Sletter aktuelle notesbog.",
@@ -281,6 +290,7 @@
"Edit link": "Rediger link",
"Edit note.": "Rediger note.",
"Edit notebook": "Rediger notesbog",
"Edit profile": "Rediger profil",
"Edit profile configuration...": "Rediger profilkonfiguration...",
"Editor": "Editor",
"Editor font": "Tekstredigeringsskrifttype",
@@ -300,6 +310,7 @@
"Enable ^sup^ syntax": "Aktivér ^sup^ syntaks",
"Enable abbreviation syntax": "Aktivér forkortelsessyntaks",
"Enable audio player": "Aktivér lydafspiller",
"Enable biometrics authentication?": "Aktivér biometrisk autentificering?",
"Enable deflist syntax": "Aktivér deflist syntaks",
"Enable encryption": "Aktivér kryptering",
"Enable footnotes": "Aktivér fodnoter",
@@ -312,6 +323,7 @@
"Enable note history": "Slå note-historie til",
"Enable PDF viewer": "Aktivér PDF-viser",
"Enable soft breaks": "Slå bløde ombrydninger til",
"Enable spellcheck in the text editor": "Aktiver stavekontrol i teksteditoren",
"Enable table of contents extension": "Aktivér indholdsfortegnelsesudvidelsen",
"Enable typographer support": "Slå typografunderstøttelse til",
"Enable video player": "Aktivér videoafspiller",
@@ -448,6 +460,7 @@
"Items": "Emner",
"Items that cannot be decrypted": "Emner der ikke kan dekrypteres",
"Items that cannot be synchronised": "Emner kan ikke synkroniseres",
"Join us on Twitter": "Følg os på Twitter",
"Joplin can synchronise your notes using various providers. Select one from the list below.": "Joplin kan synkronisere dine noter ved hjælp af forskellige tjenesteudbydere. Vælg en fra listen nedenfor.",
"Joplin Cloud": "Joplin Cloud",
"Joplin Cloud email": "Joplin Cloud e-mail",
@@ -502,6 +515,7 @@
"Manage master password": "Administrer hovedadgangskode",
"Manage master password...": "Administrer hovedadgangskode...",
"Manage multiple users": "Administrer flere brugere",
"Manage profiles": "Administrer profiler",
"Manage your plugins": "Administrer dine udvidelser",
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Administrer E2EE-konfiguration. Kommandoer er `enable`(aktiver), `disable`(sluk), `decrypt`(dekrypter), `status`, `decrypt-file`(dekrypter fil) og `target-status` (modtager-status).",
"Manual": "Manuel",
@@ -520,6 +534,7 @@
"Missing keys": "Manglende nøgler",
"Missing Master Keys": "Manglende hovednøgler",
"Missing required argument: %s": "Mangler krævet argument: %s",
"Missing required flag value: %s": "Mangler krævet flag-værdi: %s",
"Mobile data - auto-sync disabled": "Mobildata - auto-synk deaktiveret",
"More info": "Mere information",
"More information": "Mere information",
@@ -560,6 +575,7 @@
"Not authentified with %s. Please provide any missing credentials.": "Ikke godkendt med %s. Angiv venligst eventuelle manglende legitimationsoplysninger.",
"Not downloaded": "Ikke downloadet",
"Not generated": "Ikke oprettet",
"Not now": "Ikke nu",
"note": "note",
"Note": "Note",
"Note area growth factor": "Noteområde-vækstfaktor",
@@ -615,6 +631,7 @@
"Password:": "Adgangskode:",
"Passwords do not match!": "Adgangskoder stemmer ikke overens!",
"Paste": "Indsæt",
"Paste as text": "Indsæt som tekst",
"Path:": "Sti:",
"PDF File": "PDF-fil",
"Per user. Minimum of %d users.": "Pr. bruger. Minimum %d brugere.",
@@ -656,8 +673,10 @@
"Process oversized accounts": "Behandl for store konti",
"Process user deletions": "Behandl brugersletninger",
"Profile": "Profil",
"Profile name": "Profilnavn",
"Profile name:": "Profilnavn:",
"Profile Version: %s": "Profil-version: %s",
"Profiles": "Profiler",
"Properties": "Egenskaber",
"Proxy enabled": "Proxy aktiveret",
"Proxy timeout (seconds)": "Proxy timeout (sekunder)",
@@ -692,6 +711,7 @@
"Replace all": "Erstat alt",
"Replace with...": "Erstat med...",
"Replace: ": "Erstat: ",
"Reset application layout": "Nulstil applikationslayout",
"Reset master password": "Nulstil hovedadgangskode",
"Resources: %d.": "Ressourcer: %d.",
"Restart and upgrade": "Genstart og upgradér",
@@ -792,6 +812,7 @@
"Step 2: Install the extension": "Trin 2: Installér udvidelsen",
"Stop": "Stop",
"Stop external editing": "Stop ekstern redigering",
"Storage space": "Lagerplads",
"Strikethrough": "Gennemstregning",
"strong text": "fed (strong) tekst",
"Submit": "Gem",
@@ -835,6 +856,7 @@
"Teams": "Teams",
"Text editor command": "Tekstredigeringskomando",
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Mange tak! Din Joplin Cloud-konto er nu indstillet og klar til brug.",
"The active profile cannot be deleted. Switch to a different profile and try again.": "Den aktive profil kan ikke slettes. Skift til en anden profil, og prøv igen.",
"The app is now going to close. Please relaunch it to complete the process.": "Appen lukker nu. Genstart den for at fuldføre processen.",
"The application did not close properly. Would you like to start in safe mode?": "Programmet blev ikke lukket korrekt. Ønsker du at starte i fejlsikret tilstand?",
"The application has been authorised - you may now close this browser tab.": "App'en er blevet godkendt - du kan nu lukke dette faneblad.",
@@ -846,6 +868,7 @@
"The default admin password is insecure and has not been changed! [Change it now](%s)": "Standard-administratoradgangskoden er svag og er ikke blevet ændret! [Ændr det nu](%s)",
"The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.": "Standard krypteringsmetoden er blevet ændret til en mere sikker metode og det anbefales, at du anvender den på dine data.",
"The default encryption method has been changed, you should re-encrypt your data.": "Standard-krypteringsmetoden er blevet ændret, du bør genkryptere dine data.",
"The default profile cannot be deleted": "Standardprofilen kan ikke slettes",
"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.": "Editorkommandoen (kan inkludere argumenter) der bruges til at åbne noter. Hvis der ikke er angivet nogen, vil den prøve at autodetektere standardeditoren.",
"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.": "Faktoren vil bestemme om elementet vil vokse eller skrumpe for at tilpasse den tilgængelig plads i dens beholder med hensyn til andre elementer. Således vil et element med en faktor 2 optage dobbelt så meget plads som et element med en faktor 1. Genstart app'en for at se ændringer.",
"The following attachments are being watched for changes:": "Følgende vedhæftninger overvåges for ændringer:",
@@ -867,8 +890,10 @@
"The Web Clipper needs your authorisation to access your data.": "Web Clipper har brug for din tilladelse til at få adgang til dine data.",
"The web clipper service is enabled and set to auto-start.": "Web-clipper tjenesten er slået til og sat til at starte automatisk.",
"The web clipper service is not enabled.": "Web-Clipper tjenesten er ikke slået til.",
"The WebDAV implementation of %s is incompatible with Joplin, and as such is no longer supported. Please use a different sync method.": "WebDAV-implementeringen af %s er ikke kompatibel med Joplin og understøttes derfor ikke længere. Brug venligst en anden synkroniseringsmetode.",
"Theme": "Tema",
"There are currently no notes. Create one by clicking on the (+) button.": "Der er ingen noter. Opret note ved at klikke på (+) knappen.",
"There are unsaved changes.": "Der er ikke-gemte ændringer.",
"There is currently no notebook. Create one by clicking on \"New notebook\".": "Der er ingen notesbog. Opret en ved at klikke på \"Ny Notesbog\".",
"There is no data to export.": "Der er ingen data at eksportere.",
"There was a [conflict](%s) on the attachment below.\n\n%s": "Der var en [conflict](%s) på vedhæftningen nedenfor.\n\n%s",
@@ -902,6 +927,7 @@
"To maximise/minimise the console, press \"tc\".": "For at maksimere/minimere konsollen, tryk \"tc\".",
"To move from one pane to another, press Tab or Shift+Tab.": "For flytte fra et panel til et andet, tryk Tab eller Skift+Tab.",
"To retry decryption of these items. Run `e2ee decrypt --retry-failed-items`": "For at prøve at dekryptere dem igen. Kør `e2ee decrypt --retry-failed-items`",
"To switch the profile, the app is going to close and you will need to restart it.": "Hvis du vil skifte profil, lukkes appen, og du skal genstarte den.",
"To work correctly, the app needs the following permissions. Please enable them in your phone settings, in Apps > Joplin > Permissions": "For at virke korrekt skal app'en bruge følgende tilladelser. Slå dem til i din telefons indstillinger, i Apps > Joplin > Tilladelser",
"to-do": "opgave",
"to-do: %s": "opgave: %s",
@@ -952,16 +978,19 @@
"Upgrade the sync target to the latest version.": "Opgrader synkmålet til den seneste version.",
"URL": "URL",
"Usage: %s": "Forbrug: %s",
"Use biometrics to secure access to the app": "Brug biometri til at sikre adgangen til appen",
"Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE": "Brug langt liste format. Formatet er ID,NOTE_TÆLLER (for notesbøger), DATO, MARKEREDE_OPGAVER (for opgaver), TITEL",
"Use spell checker": "Brug stavekontrol",
"Use the arrows and page up/down to scroll the lists and text areas (including this console).": "Brug pilene og PageUp/PageDown for at rulle lister og tekst-områder (inkl. denne konsol)",
"Use the arrows to move the layout items. Press \"Escape\" to exit.": "Brug pilene for at flytte layout-elementerne. Tryk på \"Escape\" for at afslutte.",
"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.": "Brug denne funktion til at genopbygge søgeindekset, hvis der er problemer med søgning. Det kan tage lang tid afhængig af antallet af noter.",
"Use your biometrics to secure access to your application. You can always set it up later in Settings.": "Brug dine biometriske data til at sikre adgangen til din applikation. Du kan altid konfigurere det senere i Indstillinger.",
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Bruges til det meste tekst i markdown-editoren. Hvis ikke fundet, bruges en proportional (variabel bredde) font.",
"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.": "Bruges hvor en font med fast bredde er nødvendig for at vise læsbar tekst (f.eks. tabeller, afkrydsningsfelter, kode). Hvis ikke fundet, bruges en generisk monospatieret (fast bredde) font.",
"User deletions": "Brugersletninger",
"Users": "Brugere",
"Valid": "Gyldig",
"Verify your identity": "Bekræft din identitet",
"View": "Vis",
"View on map": "Vis på kort",
"View them now": "Se dem nu",
+20
View File
@@ -62,6 +62,7 @@
"Admin dashboard": "Admin-Übersichtsseite",
"Advanced options": "Erweiterte Optionen",
"Advanced tools": "Erweiterte Optionen",
"All data, including notes, notebooks and tags will be permanently deleted.": "Alle Daten, inklusive Notizen, Notizbücher und Schlagwörter werden permanent gelöscht.",
"All notes": "Alle Notizen",
"All potential ports are in use - please report the issue at %s": "Alle potentielle Port-Nummern sind in Verwendung - bitte melde dieses Problem auf %s",
"Also displays unset and hidden config variables.": "Zeigt auch nicht gesetzte und versteckte Konfigurationsvariablen an.",
@@ -136,6 +137,7 @@
"Click to add tags...": "Zum Hinzufügen von Schlagwörtern klicken ...",
"Client ID: %s": "Client-ID: %s",
"Close": "Schließen",
"Close dropdown": "Auswahlliste schließen",
"Close Window": "Fenster schließen",
"Code": "Code",
"Code Block": "Code-Block",
@@ -161,6 +163,7 @@
"Conflicts (attachments)": "Konflikte (Anhänge)",
"Consolidated billing": "Konsolidierte Rechnung",
"Content provided by %s": "Von %s bereitgestellte Inhalte",
"Continue": "Fortfahren",
"Convert to note": "In eine Notiz umwandeln",
"Convert to todo": "In eine Aufgabe umwandeln",
"Copy": "Kopieren",
@@ -178,8 +181,10 @@
"Could not export notes: %s": "Konnte Notizen nicht exportieren: %s",
"Could not install plugin: %s": "Erweiterung konnte nicht installiert werden: %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\"": "Die Einladung konnte nicht beantwortet werden. Bitte versuche es erneut, oder prüfe, ob der Notizbuch-Besitzer dieses noch freigibt.\n\nDer Fehler war: „%s“",
"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 notebook": "Notizbuch erstellen",
"Create new profile...": "Neues Profil erstellen...",
@@ -228,9 +233,11 @@
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "Notizbuch „%s“ löschen?\n\nAlle Notizen und Unter-Notizbücher in diesem Notizbuch werden ebenfalls gelöscht.",
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "Notizbuch löschen? Alle Notizen und Unter-Notizbücher in diesem Notizbuch werden ebenfalls gelöscht.",
"Delete plugin \"%s\"?": "Erweiterung „%s“ löschen?",
"Delete profile \"%s\"": "Lösche Profil \"%s\"",
"Delete selected notes": "Ausgewählte Notizen löschen",
"Delete these %d notes?": "Sollen diese %d Notizen gelöscht werden?",
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "Einladung löschen? Der Empfänger hat dann keinen Zugriff mehr auf dieses freigegebene Notizbuch.",
"Delete this profile?": "Dieses Profil löschen?",
"Deleted local items: %d.": "Lokale Elemente gelöscht: %d.",
"Deleted remote items: %d.": "Remote-Elemente gelöscht: %d.",
"Deletes the given notebook.": "Löscht das ausgewählte Notizbuch.",
@@ -281,6 +288,7 @@
"Edit link": "Link bearbeiten",
"Edit note.": "Notiz bearbeiten.",
"Edit notebook": "Notizbuch bearbeiten",
"Edit profile": "Profil bearbeiten",
"Edit profile configuration...": "Profilkonfiguration bearbeiten...",
"Editor": "Editor",
"Editor font": "Schriftart im Editor",
@@ -300,6 +308,7 @@
"Enable ^sup^ syntax": "Syntax ^sup^ aktivieren",
"Enable abbreviation syntax": "Abkürzungssyntax aktivieren",
"Enable audio player": "Audiospieler aktivieren",
"Enable biometrics authentication?": "Biometrische Authentifizierung aktivieren?",
"Enable deflist syntax": "Syntax deflist aktivieren",
"Enable encryption": "Verschlüsselung aktivieren",
"Enable footnotes": "Fußnoten aktivieren",
@@ -502,6 +511,7 @@
"Manage master password": "Master-Passwort verwalten",
"Manage master password...": "Master-Passwort verwalten...",
"Manage multiple users": "Verwalte mehrere Nutzer",
"Manage profiles": "Profile verwalten",
"Manage your plugins": "Erweiterungen verwalten",
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Verwaltet die E2EE-Konfiguration. Die Befehle lauten `enable`, `disable`, `decrypt`, `status`, `decrypt-file` und `target-status`.",
"Manual": "Manuell",
@@ -560,6 +570,7 @@
"Not authentified with %s. Please provide any missing credentials.": "Keine Authentifizierung mit %s. Gib bitte alle fehlenden Zugangsdaten an.",
"Not downloaded": "Nicht heruntergeladen",
"Not generated": "Nicht erzeugt",
"Not now": "Nicht jetzt",
"note": "Notiz",
"Note": "Notiz",
"Note area growth factor": "Notiz-Flächenwachstumsfaktor",
@@ -656,8 +667,10 @@
"Process oversized accounts": "Verarbeite zu große Konten",
"Process user deletions": "Verarbeite Benutzerlöschungen",
"Profile": "Profil",
"Profile name": "Profilname",
"Profile name:": "Profilname:",
"Profile Version: %s": "Profil-Version: %s",
"Profiles": "Profile",
"Properties": "Eigenschaften",
"Proxy enabled": "Proxy aktiviert",
"Proxy timeout (seconds)": "Proxy Zeitüberschreitung (Sekunden)",
@@ -836,6 +849,7 @@
"Teams": "Teams",
"Text editor command": "Texteditor-Befehl",
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Vielen Dank! Das Joplin Cloud-Konto ist nun eingerichtet und einsatzbereit.",
"The active profile cannot be deleted. Switch to a different profile and try again.": "Das aktive Profil kann nicht gelöscht werden. Bitte wechsle in ein anderes Profil und versuche es erneut.",
"The app is now going to close. Please relaunch it to complete the process.": "Die App wird nun geschlossen. Bitte starte sie erneut, um den Vorgang abzuschließen.",
"The application did not close properly. Would you like to start in safe mode?": "Die Anwendung wurde nicht ordnungsgemäß geschlossen. Im abgesicherten Modus starten?",
"The application has been authorised - you may now close this browser tab.": "Die Anwendung wurde autorisiert - du kannst diesen Browsertab nun schließen.",
@@ -847,6 +861,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 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:",
@@ -870,6 +885,7 @@
"The web clipper service is not enabled.": "Der Web-Clipper-Dienst ist nicht aktiviert.",
"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.",
"There is currently no notebook. Create one by clicking on \"New notebook\".": "Momentan existieren noch keine Notizbücher. Erstelle eines, indem du auf „Neues Notizbuch“ klickst.",
"There is no data to export.": "Keine Daten für den Export vorhanden.",
"There was a [conflict](%s) on the attachment below.\n\n%s": "Es gab einen [Konflikt](%s) beim Anhang unten.\n\n%s",
@@ -903,6 +919,7 @@
"To maximise/minimise the console, press \"tc\".": "Um die Konsole zu maximieren/minimieren, drücke „tc“.",
"To move from one pane to another, press Tab or Shift+Tab.": "Um von einem Bereich zu einem anderen zu wechseln, drücke Tab oder Umschalt+Tab.",
"To retry decryption of these items. Run `e2ee decrypt --retry-failed-items`": "Um die Entschlüsselung dieser Objekte nochmal zu versuchen, führe `e2ee decrypt --retry-failed-items` aus",
"To switch the profile, the app is going to close and you will need to restart it.": "Um das Profil zu wechseln, wird die App beendet und muss von dir neu gestartet werden.",
"To work correctly, the app needs the following permissions. Please enable them in your phone settings, in Apps > Joplin > Permissions": "Um korrekt arbeiten zu können, benötigt die App die folgenden Berechtigungen. Bitte aktiviere diese in deinen Telefoneinstellungen, unter Apps > Joplin > Berechtigungen",
"to-do": "Aufgabe",
"to-do: %s": "To-Do: %s",
@@ -953,16 +970,19 @@
"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 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).",
"Use the arrows to move the layout items. Press \"Escape\" to exit.": "Verwende die Pfeile, um die Layoutelemente zu verschieben. Drücke zum Beenden „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.": "Verwende dies, um den Suchindex neu aufzubauen, wenn es ein Problem mit der Suche gibt. Dies kann je nach Anzahl der Notizen eine lange Zeit dauern.",
"Use your biometrics to secure access to your application. You can always set it up later in Settings.": "Verwende Biometrie, um den Zugriff zu deiner Anwendung abzusichern. Du kannst sie jederzeit in den Einstellungen einrichten.",
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Hauptsächlich für Text im Markdown-Editor verwendet. Falls nicht vorhanden wird eine generische Proportional-Schriftart (mit variabler Breite) verwendet.",
"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.": "Verwendete Schriftart mit fester Breite, um Text lesbar zu machen (z.B. in Tabellen, Kontrollkästchen, Code). Falls nicht vorhanden wird eine Monotype-Scrhiftart (mit fester Breite) verwendet.",
"User deletions": "Benutzer-Löschungen",
"Users": "Benutzer",
"Valid": "Gültig",
"Verify your identity": "Verifiziere deine Identität",
"View": "Ansicht",
"View on map": "Auf der Karte anzeigen",
"View them now": "Zeige sie jetzt an",
+109
View File
@@ -1,8 +1,12 @@
{
"\"%s\" is missing the required \"%s\" property.": "A «%s» le falta la propiedad requerida de «%s».",
"%d days": "%d días",
"%d GB": "%d GB",
"%d GB storage space": "%d GB de almacenamiento",
"%d hour": "%d hora",
"%d hours": "%d horas",
"%d MB": "%d MB",
"%d MB per note or attachment": "%d MB por nota o adjunto",
"%d minutes": "%d minutos",
"%d notes match this pattern. Delete them?": "%d notas coinciden con el patrón. ¿Eliminarlas?",
"%s %s (%s, %s)": "%s %s (%s, %s)",
@@ -27,6 +31,7 @@
"&Tools": "&Herramientas",
"&View": "&Ver",
"(%s)": "(%s)",
"(In plugin: %s)": "(En plugin: %s)",
"(None)": "(Ninguno)",
"(wysiwyg: %s)": "(wysiwyg: %s)",
"- Camera: to allow taking a picture and attaching it to a note.": "- Cámara: Permite tomar fotografías y adjuntarlas a una nota.",
@@ -42,11 +47,13 @@
"Accelerator \"%s\" is not valid.": "El acelerador «%s» no es válido.",
"Accelerator \"%s\" is used for \"%s\" and \"%s\" commands. This may lead to unexpected behaviour.": "El acelerador «%s» se usa para los comandos «%s» y «%s». Esto puede llevar a un comportamiento inesperado.",
"Accept": "Aceptar",
"Account": "Cuenta",
"Action": "Acción",
"Actions": "Acciones",
"Active": "Activa",
"Actual Size": "Tamaño Original",
"Add body": "Añadir cuerpo",
"Add new": "Añadir nuevo",
"Add or remove tags:": "Agregar o eliminar etiquetas:",
"Add recipient:": "Agregar destinatario:",
"Add title": "Añadir título",
@@ -55,10 +62,14 @@
"Admin dashboard": "Tablero de Mandos de Administrador",
"Advanced options": "Opciones avanzadas",
"Advanced tools": "Herramientas avanzadas",
"All data, including notes, notebooks and tags will be permanently deleted.": "Todos los datos, incluyendo notas, libretas y etiquetas, serán borrados.",
"All notes": "Todas las notas",
"All potential ports are in use - please report the issue at %s": "Todos los puertos potenciales están en uso - por favor informe del problema en %s",
"Also displays unset and hidden config variables.": "También muestra variables no configuradas u ocultas.",
"Also publish linked notes": "También publicar notas enlazadas",
"Always": "Siempre",
"Ambiguous notebook \"%s\". Please use notebook id instead - press \"ti\" to see the short notebook id or use $b for current selected notebook": "Libreta \"%s\" es ambigua. Utilice el id de la libreta - presione \"ti\" para ver el id abreviado o utilice $b para la libreta seleccionada",
"Ambiguous notebook \"%s\". Please use short notebook id instead - press \"ti\" to see the short notebook id": "Libreta \"%s\" es ambigua. Utilice el id abreviado - presione \"ti\" para ver el id abreviado de la libreta",
"An update is available, do you want to download it now?": "Está disponible una actualización. ¿Quiere descargarla ahora?",
"Appearance": "Apariencia",
"Application": "Aplicación",
@@ -66,6 +77,7 @@
"Are you sure you want to renew the authorisation token?": "¿Está seguro de que desea renovar el token de autorización?",
"Arguments:": "Argumentos:",
"Aritim Dark": "Aritim Oscuro",
"Attach": "Adjuntar",
"Attach file": "Adjuntar archivo",
"Attach photo": "Adjuntar foto",
"Attach...": "Adjuntar...",
@@ -84,10 +96,12 @@
"Automatically check for updates": "Comprobar actualizaciones",
"Automatically switch theme to match system theme": "Cambiar automáticamente el tema para que coincida con el tema del sistema",
"Back": "Retroceder",
"Basic": "Básico",
"Bold": "Negrita",
"Browse all plugins": "Explorar todos los plugins",
"Browse...": "Explorar...",
"Bulleted List": "Lista con Viñetas",
"Can Share": "Puede compartir",
"Cancel": "Cancelar",
"Cancelling background synchronisation... Please wait.": "Cancelando sincronización en segundo plano... Por favor espere.",
"Cancelling...": "Cancelando...",
@@ -105,6 +119,7 @@
"Cannot save %s \"%s\" because it is larger than the allowed limit (%s)": "No se puede guardar %s \"%s\" porque es más pesado que el límite permitido (%s)",
"Cannot save %s \"%s\" because it would go over the total allowed size (%s) for this account": "No se puede guardar %s \"%s\" porque es más pesado que el límite permitido (%s)",
"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.": "No se puede compartir la libreta cifrada con el destinatario %s porque este no ha habilitado el cifrado de extremo a extremo. Puede hacerlo desde la pantalla Configuración > Cifrado.",
"Case sensitive": "Distingue mayúsculas",
"Change application layout": "Cambiar el diseño de la aplicación",
"Change language": "Cambiar idioma",
"Characters": "Caracteres",
@@ -122,11 +137,13 @@
"Click to add tags...": "Haga clic aquí para agregar etiquetas...",
"Client ID: %s": "ID del Cliente: %s",
"Close": "Cerrar",
"Close dropdown": "Cerrar menú",
"Close Window": "Cerrar Ventana",
"Code": "Código",
"Code Block": "Bloque de Código",
"Code View": "Código",
"Collaborate on notebooks with others": "Colaborar en los cuadernos con otros",
"Collapse": "Colapsar",
"Coming alarms": "Alarmas próximas",
"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\".": "Lista de rutas de directorios separados por comas de dónde cargar los certificados, o ruta a certificados individuales. Por ejemplo: /mi/cert_dir, /otro/personalizado.pem. Tenga en cuenta que si realiza cambios en la configuración de los certificados TLS, debe guardar los cambios antes de hacer clic en «Comprobar la configuración de sincronización».",
"command": "comando",
@@ -144,7 +161,9 @@
"Conflicted: %d": "Conflictos: %d",
"Conflicts": "Conflictos",
"Conflicts (attachments)": "Conflictos (adjuntos)",
"Consolidated billing": "Facturación consolidada",
"Content provided by %s": "Contenido provisto por %s",
"Continue": "Continuar",
"Convert to note": "Convertir en nota",
"Convert to todo": "Convertir a tarea",
"Copy": "Copiar",
@@ -162,9 +181,13 @@
"Could not export notes: %s": "No se pudo exportar las notas: %s",
"Could not install plugin: %s": "No se pudo instalar el plugin: %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\"": "No se ha podido responder a la invitación. Por favor, inténtelo de nuevo, o compruebe con el propietario de la libreta si todavía la está compartiendo.\n\nEl error fue: \"%s\"",
"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...",
"Create notebook": "Crea libreta",
"Create user": "Crear usuario",
"Created": "Creada",
@@ -193,6 +216,7 @@
"Date": "Fecha",
"Date format": "Formato de fecha",
"days": "días",
"Decrease indent level": "Reducir un nivel de sangría",
"Decrypted items: %d": "Elementos descifrados: %d",
"Decrypted items: %s / %s": "Elementos descifrados: %s / %s",
"Decrypting items: %d/%d": "Descifrando elementos: %d/%d",
@@ -209,8 +233,11 @@
"Delete notebook \"%s\"?\n\nAll notes and sub-notebooks within this notebook will also be deleted.": "¿Borrar libreta «%s»?\n\nTodas las notas y sublibretas de esta libreta serán borradas.",
"Delete notebook? All notes and sub-notebooks within this notebook will also be deleted.": "¿Borrar libreta? Todas las notas y sublibretas dentro de esta libreta también serán eliminadas.",
"Delete plugin \"%s\"?": "¿Borrar plugin «%s»?",
"Delete profile \"%s\"": "¿Borrar perfil \"%s\"?",
"Delete selected notes": "Borrar notas seleccionadas",
"Delete these %d notes?": "¿Borrar estas %d notas?",
"Delete this invitation? The recipient will no longer have access to this shared notebook.": "¿Eliminar esta invitación? El destinatario ya no tendrá acceso a esta libreta compartida.",
"Delete this profile?": "¿Borrar este perfil?",
"Deleted local items: %d.": "Elementos locales borrados: %d.",
"Deleted remote items: %d.": "Elementos remotos borrados: %d.",
"Deletes the given notebook.": "Elimina la libreta dada.",
@@ -240,6 +267,7 @@
"Do it now": "Hacerlo ahora",
"Do not ask for confirmation.": "No pedir confirmación.",
"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.": "No pierda la contraseña, pues, por cuestiones de seguridad, ¡es la *única* forma de descifrar los datos! Para habilitar el cifrado, por favor introduzca su contraseña a continuación.",
"Done": "Listo",
"Download": "Descargar",
"Download and install the relevant extension for your browser:": "Descargue e instale la extensión apropiada para su navegador:",
"Downloaded": "Descargado",
@@ -253,17 +281,22 @@
"Dropbox Login": "Inicio de sesión de Dropbox",
"Duplicate": "Duplicar",
"Duplicate line": "Duplicar línea",
"Duplicate selected notes": "Duplicar notas seleccionadas",
"Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.": "Duplica las notas que coincidan con <nota> a [libreta]. Si no se especifica una libreta la nota se duplica en la libreta actual.",
"Edit": "Editar",
"Edit in external editor": "Editar con un editor externo",
"Edit link": "Editar enlace",
"Edit note.": "Editar nota.",
"Edit notebook": "Editar libreta",
"Edit profile": "Editar perfil",
"Edit profile configuration...": "Editar configuración de perfil...",
"Editor": "Editor",
"Editor font": "Fuente del editor",
"Editor font family": "Familia de fuente del editor",
"Editor font size": "Tamaño de fuente del editor",
"Editor maximum width": "Ancho máximo del editor",
"Editor monospace font family": "Familia de fuente monoespaciada del editor",
"Editor: %s": "Editor: %s",
"Either \"text\" or \"json\"": "Puede ser «text» o «json»",
"Emacs": "Emacs",
"Email": "Email",
@@ -275,6 +308,7 @@
"Enable ^sup^ syntax": "Activar sintaxis ^sup^",
"Enable abbreviation syntax": "Activar sintaxis de abreviaturas",
"Enable audio player": "Activar reproductor de audio",
"Enable biometrics authentication?": "¿Activar autenticación biométrica?",
"Enable deflist syntax": "Activar sintaxis Deflist",
"Enable encryption": "Habilitar cifrado",
"Enable footnotes": "Activar notas al pie",
@@ -315,6 +349,7 @@
"Evernote Export File (as HTML)": "Exportar como Archivo de Ever(como HTML)",
"Evernote Export File (as Markdown)": "Exportar como Archivo de Ever(como Markdown)",
"Exits the application.": "Sale de la aplicación.",
"Expand": "Expandir",
"Export": "Exportar",
"Export all": "Exportar todo",
"Export debug report": "Exportar Informe de depuración",
@@ -333,6 +368,9 @@
"Fetching resources: %d/%d": "Obteniendo recursos: %d/%d",
"File": "Archivo",
"File system": "Sistema de archivos",
"Filter tags": "Filtrar etiquetas",
"Find and replace": "Buscar y reemplazar",
"Find: ": "Buscar: ",
"Firefox Extension": "Extensión de Firefox",
"Fix search index": "Reparar índice de búsqueda",
"Fixing search index...": "Reparando índice de búsqueda...",
@@ -341,14 +379,17 @@
"Focus title": "Enfocar título",
"Folders": "Carpetas",
"For debugging purpose only: export your profile to an external SD card.": "Solo para fines de depuración: exporte su perfil a una tarjeta SD externa.",
"For example \"%s\"": "Por ejemplo \"%s\"",
"For information on how to customise the shortcuts please visit %s": "Para información de cómo personalizar los atajos, por favor visite %s",
"For more information about End-To-End Encryption (E2EE) and advice on how to enable it please check the documentation:": "Para más información acerca del Cifrado de Extremo a Extremo (E2EE) y recomendaciones acerca de como habilitarlo por favor revise la documentación:",
"For the list of keyboard shortcuts and config options, type `help keymap`": "Para la lista de los atajos de teclado disponibles, escriba `help keymap`",
"Force path style": "Forzar estilo de ruta",
"Formatting": "Formatear",
"Forward": "Avanzar",
"Found: %d.": "Encontrado: %d.",
"FTS enabled: %d": "FTS activado: %d",
"Full changelog": "Registro de cambios completo",
"Full name": "Nombre completo",
"General": "General",
"Generated": "Generado",
"Generating link...": "Creando enlace...",
@@ -358,11 +399,17 @@
"Go to source URL": "Ir a URL de origen",
"Goto Anything...": "Ir a...",
"Grant authorisation": "Conceder la autorización",
"Header %d": "Encabezado %d",
"Headers": "Encabezados",
"Heading": "Título",
"Help": "Ayuda",
"Hide %s": "Ocultar %s",
"Hide advanced": "Ocultar avanzadas",
"Hide disabled": "Ocultar desactivadas",
"Hide disabled keys": "Ocultar las claves desactivadas",
"Hide Joplin": "Ocultar Joplin",
"Hide keyboard": "Ocultar teclado",
"Hide more actions": "Ocultar más acciones",
"Highlight": "Resaltado",
"Home": "Inicio",
"Horizontal Rule": "Regla Horizontal",
@@ -387,12 +434,14 @@
"In order to use the web clipper, you need to do the following:": "Para utilizar el Web Clipper, necesita hacer lo siguiente:",
"In progress": "En progreso",
"In: %s": "En: %s",
"Increase indent level": "Aumentar un nivel de sangría",
"Indent less": "Disminuir sangría",
"Indent more": "Aumentar sangría",
"Information": "Información",
"Inline Code": "Código Integrado",
"Insert": "Insertar",
"Insert Hyperlink": "Insertar Hipervínculo",
"Insert time": "Insertar hora",
"Install": "Instalar",
"Install from file": "Instalar desde archivo",
"Installed": "Instalado",
@@ -423,6 +472,7 @@
"Joplin Web Clipper allows saving web pages and screenshots from your browser to Joplin.": "El Web Clipper de Joplin le permite guardar páginas web y capturas de pantalla desde su navegador a la aplicación.",
"Joplin website": "Sitio web de Joplin",
"Joplin's own sync service. Also gives access to Joplin-specific features such as publishing notes or collaborating on notebooks with others.": "El servicio de sincronización propio de Joplin. También da acceso a funciones específicas de Joplin, como la publicación de notas o la colaboración en cuadernos con otras personas.",
"KaTeX": "KaTeX",
"Keep note history for": "Mantener historial de la nota durante",
"Keyboard Mode": "Modo de Teclado",
"Keyboard Shortcut": "Atajo de Teclado",
@@ -440,9 +490,13 @@
"Letter": "Carta",
"Light": "Claro",
"Lines": "Líneas",
"Link": "Enlace",
"Link description": "Descripción de enlace",
"Link has been copied to clipboard!": "¡El enlace ha sido copiado al portapapeles!",
"Link text": "Texto de enlace",
"Links with protocol \"%s\" are not supported": "Enlaces con el protocolo «%s» no están soportados",
"List item": "Listar elemento",
"Lists": "Listas",
"Loaded": "Cargado",
"Location": "Localización",
"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.": "Ya hay un archivo de bloqueo. Si está seguro de que no hay ninguna sincronización en curso, puede eliminar el archivo de bloqueo en «%s» y reanudar la operación.",
@@ -456,6 +510,8 @@
"Make a donation": "Hacer una donación",
"Manage master password": "Administrar contraseña maestra",
"Manage master password...": "Administrar contraseña maestra...",
"Manage multiple users": "Administrar múltiples usuarios",
"Manage profiles": "Administrar perfiles",
"Manage your plugins": "Administre sus plugins",
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, `status`, `decrypt-file`, and `target-status`.": "Administra la configuración E2EE. Los comandos son `enable`, `disable`, `decrypt`, `status`, `decrypt-file` y `target-status`.",
"Manual": "Manual",
@@ -468,6 +524,9 @@
"Master password": "Contraseña maestra",
"Master password:": "Contraseña maestra:",
"Max concurrent connections": "Conexiones simultáneas máximas",
"Max Item Size": "Tamaño máximo de item",
"Max note or attachment size": "Tamaño máximo de notas o adjuntos",
"Max Total Size": "Tamaño original",
"Missing keys": "Claves faltantes",
"Missing Master Keys": "Claves Maestras Faltantes",
"Missing required argument: %s": "Falta un argumento requerido: %s",
@@ -479,6 +538,7 @@
"Move to notebook": "Mover a la libreta",
"Move to notebook...": "Mover a la libreta...",
"Move to notebook:": "Mover a la libreta:",
"Moves the given <item> to [notebook]": "Mueve la nota <nota> a [libreta]",
"n": "n",
"N": "N",
"New note": "Nueva nota",
@@ -489,6 +549,7 @@
"New tags:": "Nuevas etiquetas:",
"New to-do": "Nueva tarea",
"New version: %s": "Nueva versión: %s",
"Next match": "Siguiente coincidencia",
"Nextcloud": "Nextcloud",
"Nextcloud password": "Contraseña de Nextcloud",
"Nextcloud username": "Usuario de Nextcloud",
@@ -509,6 +570,7 @@
"Not authentified with %s. Please provide any missing credentials.": "No autenticado con %s. Por favor provea las credenciales faltantes.",
"Not downloaded": "No descargado",
"Not generated": "No generado",
"Not now": "Ahora no",
"note": "nota",
"Note": "Nota",
"Note area growth factor": "Factor de crecimiento del área de la nota",
@@ -516,6 +578,7 @@
"Note attachments...": "Adjuntos de las notas...",
"Note body": "Cuerpo de la nota",
"Note does not exist: \"%s\". Create it?": "La nota no existe: «%s». ¿Crearla?",
"Note editor": "Editor de notas",
"Note has been saved.": "La nota ha sido guardada.",
"Note History": "Historial",
"Note is not a to-do: \"%s\"": "La nota no es una tarea: «%s»",
@@ -546,12 +609,14 @@
"Only one note can be printed at a time.": "Solo una nota puede ser impresa a la vez.",
"Open": "Abrir",
"Open %s": "Abrir %s",
"Open PDF viewer": "Abrir visor de PDF",
"Open profile directory": "Abrir directorio de perfiles",
"Open Sync Wizard...": "Abrir el asistente de sincronización...",
"Open...": "Abrir...",
"Operation cancelled": "Operación cancelada",
"Options": "Opciones",
"Or create an account.": "Crea una nueva nota.O crea una cuenta.",
"Ordered list": "Lista ordenada",
"Other applications...": "Otras aplicaciones...",
"Output format: %s": "Formato de destino: %s",
"Page orientation for PDF export": "Orientación de la página al exportar como PDF",
@@ -563,8 +628,10 @@
"Paste": "Pegar",
"Path:": "Ruta:",
"PDF File": "Archivo PDF",
"Per user. Minimum of %d users.": "Por usuario. Mínimo %d usuarios.",
"Permission needed": "Se necesita permiso",
"Permission to use camera": "Permiso para usar la cámara",
"Please click on \"%s\" to proceed, or set the passwords in the \"%s\" list below.": "Haga click en \"%s\" para proceder, o indique las contraseñas en la lista \"%s\" debajo.",
"Please confirm that you would like to re-encrypt your complete database.": "Por favor, confirme que desea volver a cifrar su base de datos completa.",
"Please enter your password in the master key list below before upgrading the key.": "Por favor, ingrese su contraseña en la lista de claves maestras a continuación antes de actualizar la clave.",
"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.": "Tenga en cuenta de que si se trata de una libreta grande, puede tardar unos minutos para que todas las notas aparezcan en el dispositivo del destinatario.",
@@ -590,15 +657,24 @@
"Press the shortcut": "Pulse el atajo",
"Press the shortcut and then press ENTER. Or, press BACKSPACE to clear the shortcut.": "Pulse el atajo; y luego, ENTER. O bien, pulse RETROCESO para borrar el atajo.",
"Press to set the decryption password.": "Pulse para establecer la contraseña de descifrado.",
"Previous match": "Anterior coincidencia",
"Previous versions of this note": "Versiones anteriores de esta nota",
"Print": "Imprimir",
"Priority support": "Soporte prioritario",
"Privacy Policy": "Política de Privacidad",
"Pro": "Pro",
"Process failed payment subscriptions": "Procesar las suscripciones de pago fallidas",
"Process oversized accounts": "Procesar cuentas de gran tamaño",
"Process user deletions": "Procesar eliminaciones de usuarios",
"Profile": "Perfil",
"Profile name": "Nombre de perfil",
"Profile name:": "Nombre de perfil:",
"Profile Version: %s": "Versión del Perfil: %s",
"Profiles": "Perfiles",
"Properties": "Propiedades",
"Proxy enabled": "Proxy habilitado",
"Proxy timeout (seconds)": "Proxy timeout (segundos)",
"Proxy URL": "URL de Proxy",
"Public-private key pair:": "Par de claves públicas y privadas:",
"Publish note...": "Publicar nota...",
"Publish Notes": "Publicar notas",
@@ -615,6 +691,7 @@
"Recipients:": "Destinatarios:",
"Redo": "Rehacer",
"Refresh": "Recargar",
"Regular expression": "Expresión regular",
"Reject": "Rechazar",
"Remove": "Eliminar",
"Remove tag \"%s\" from all notes?": "¿Desea eliminar la etiqueta «%s» de todas las notas?",
@@ -624,6 +701,10 @@
"Rename tag:": "Renombrar etiqueta:",
"Renames the given <item> (note or notebook) to <name>.": "Renombra el <elemento> dado (nota o libreta) a <nombre>.",
"Renew token": "Renovar token",
"Replace": "Reemplazar",
"Replace all": "Reemplazar todo",
"Replace with...": "Reemplazar con...",
"Replace: ": "Reemplazar: ",
"Reset master password": "Restablecer contraseña maestra",
"Resources: %d.": "Recursos: %d.",
"Restart and upgrade": "Reiniciar y actualizar",
@@ -646,11 +727,13 @@
"Safe mode is currently active. Note rendering and all plugins are temporarily disabled.": "El modo seguro está actualmente activo. El renderizado de notas y todos los plugins están temporalmente deshabilitados.",
"Save": "Guardar",
"Save alarm": "Establecer alarma",
"Save as %s": "Guardar como %s",
"Save as...": "Guardar como...",
"Save changes": "Guardar cambios",
"Save geo-location with notes": "Guardar geolocalización en las notas",
"Search": "Buscar",
"Search for plugins...": "Buscar plugins...",
"Search for...": "Buscar...",
"Search in all the notes": "Buscar en todas las notas",
"Search in current note": "Buscar en la nota actual",
"Search...": "Buscar...",
@@ -670,17 +753,23 @@
"Set the password": "Establecer la contraseña",
"Sets the property <name> of the given <note> to the given [value]. Possible properties are:\n\n%s": "Asigna la propiedad <nombre> de la <nota> dada al [valor] dado. Propiedades posibles son:\n\n%s",
"Share": "Compartir",
"Share and collaborate on a notebook": "Compartir y colaborar en una libreta",
"Share Notebook": "Compartir Libreta",
"Share notebook...": "Compartir libreta...",
"Sharing access control": "Compartiendo control de acceso",
"Sharing notebook...": "Compartiendo libreta...",
"Shortcuts are not available in CLI mode.": "Los atajos no están disponibles en el modo CLI.",
"Show advanced": "Mostrar opciones avanzadas",
"Show Advanced Settings": "Mostrar Opciones Avanzadas",
"Show all": "Mostrar todo",
"Show completed to-dos": "Mostrar tareas completadas",
"Show disabled": "Mostrar opciones desactivadas",
"Show disabled keys": "Mostrar claves desactivadas",
"Show more actions": "Mostrar más acciones",
"Show note counts": "Mostrar número de notas",
"Show sort order buttons": "Mostrar botones de ordenación",
"Show tray icon": "Mostrar icono en la bandeja",
"Show/hide the sidebar": "Mostrar/ocultar barra lateral",
"Sidebar": "Barra lateral",
"Size": "Tamaño",
"Skip this version": "Omitir esta versión",
@@ -716,6 +805,7 @@
"Step 2: Install the extension": "Paso 2: Instale la extensión",
"Stop": "Detener",
"Stop external editing": "Detener la edición externa",
"Storage space": "Espacio de almacenamiento",
"Strikethrough": "Tachado",
"strong text": "texto en negrita",
"Submit": "Enviar",
@@ -725,9 +815,12 @@
"Swap line down": "Mover línea hacia abajo",
"Swap line up": "Mover línea hacia arriba",
"Switch between note and to-do type": "Alternar entre nota y tarea",
"Switch profile": "Cambiar perfil",
"Switch to note type": "Cambiar a nota",
"Switch to profile %d": "Cambiar al perfil %d",
"Switch to to-do type": "Cambiar a tarea",
"Switches to [notebook] - all further operations will happen within this notebook.": "Cambia a [libreta] - todas las demás operaciones se realizarán en esta libreta.",
"Sync as many devices as you want": "Sincronice todos los dispositivos que desee",
"Sync Status": "Estado de la sincronización",
"Sync status (synced items / total items)": "Estado de la sincronización (elementos sincronizados / elementos totales)",
"Sync target must be upgraded! Run `%s` to proceed.": "¡El objetivo de sincronización debe ser actualizado! Ejecute `%s` para proceder.",
@@ -747,13 +840,18 @@
"Synchronising...": "Sincronizando...",
"Synchronizing...": "Sincronizando...",
"Tabloid": "Tabloide",
"tag1, tag2, ...": "etiqueta1, etiqueta2, ...",
"Tagged: %d.": "Etiquetado: %d.",
"Tags": "Etiquetas",
"Take photo": "Tomar una foto",
"Task list": "Lista de tareas",
"Tasks": "Tareas",
"Teams": "Equipos",
"Text editor command": "Comando de editor de texto",
"Thank you! Your Joplin Cloud account is now setup and ready to use.": "Gracias. Su cuenta de Joplin Cloud ya está configurada y lista para ser utilizada.",
"The active profile cannot be deleted. Switch to a different profile and try again.": "El perfil activo no puede eliminarse. Cambie de perfil e intente de nuevo.",
"The app is now going to close. Please relaunch it to complete the process.": "La aplicación se va a cerrar. Por favor, vuelva a iniciarla para completar el proceso.",
"The application did not close properly. Would you like to start in safe mode?": "La aplicación no cerró correctamente. ¿Quiere iniciarla en modo seguro?",
"The application has been authorised - you may now close this browser tab.": "La aplicación ha sido autorizada - ahora puede cerrar la pestaña de su navegador.",
"The application has been authorised!": "¡La aplicación ha sido autorizada!",
"The application has been successfully authorised.": "La aplicación ha sido autorizada exitosamente.",
@@ -763,6 +861,7 @@
"The default admin password is insecure and has not been changed! [Change it now](%s)": "La contraseña de administrador por defecto es insegura y no ha sido cambiada! [Cambiarla ahora](%s)",
"The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.": "El método de cifrado predeterminado ha sido cambiado por uno más seguro y se recomienda que lo aplique a sus datos.",
"The default encryption method has been changed, you should re-encrypt your data.": "El método de cifrado predeterminado ha sido cambiado, se recomienda recifrar los datos.",
"The default profile cannot be deleted": "El perfil por defecto no puede eliminarse",
"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.": "El comando del editor (puede incluir argumentos) que se utilizará para abrir una nota. Si no se provee ninguno se intentará autodetectar el editor por defecto.",
"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.": "La propiedad factor establece cómo el elemento crecerá o se reducirá para adaptarse al espacio disponible en su contenedor con respecto a los otros elementos. Por lo tanto, un elemento con un factor de 2 ocupará el doble de espacio que un elemento con un factor de 1. Reinicie la aplicación para ver los cambios.",
"The following attachments are being watched for changes:": "Los adjuntos siguientes están siendo vigilados en busca de cambios:",
@@ -786,6 +885,7 @@
"The web clipper service is not enabled.": "El servicio de Web Clipper no está habilitado.",
"Theme": "Tema",
"There are currently no notes. Create one by clicking on the (+) button.": "Actualmente, no hay notas. Cree una pulsando en el botón (+).",
"There are unsaved changes.": "Hay cambios sin guardar.",
"There is currently no notebook. Create one by clicking on \"New notebook\".": "No hay ninguna libreta. Cree una haciendo clic en «Libreta nueva».",
"There is no data to export.": "No hay datos para exportar.",
"There was a [conflict](%s) on the attachment below.\n\n%s": "Ha habido un [conflicto](%s) en el adjunto siguiente:.\n\n%s",
@@ -819,8 +919,10 @@
"To maximise/minimise the console, press \"tc\".": "Para maximizar/minimizar la consola, pulse «tc».",
"To move from one pane to another, press Tab or Shift+Tab.": "Para trasladarse desde un panel a otro, pulse Tab o Mayús+Tab.",
"To retry decryption of these items. Run `e2ee decrypt --retry-failed-items`": "Para reintentar el descifrado de estos elementos ejecute 'e2ee decrypt --retry-failed-items'",
"To switch the profile, the app is going to close and you will need to restart it.": "Para cambiar el perfil, la aplicación se cerrará y deberás reiniciarla.",
"To work correctly, the app needs the following permissions. Please enable them in your phone settings, in Apps > Joplin > Permissions": "Para funcionar correctamente, la aplicación necesita los siguientes permisos. Por favor habilítelos en la configuración de su teléfono, en Aplicaciones > Joplin > Permisos",
"to-do": "tarea",
"to-do: %s": "tarea: %s",
"Toggle comment": "Alternar comentario",
"Toggle development tools": "Alternar herramientas de desarrollo",
"Toggle editor layout": "Alternar el diseño del editor",
@@ -833,8 +935,10 @@
"Toggle sort order field": "Alternar el campo de orden",
"Token has been copied to the clipboard!": "¡El token ha sido copiado al portapapeles!",
"Tools": "Herramientas",
"Total Size": "Tamaño total",
"Total: %d/%d": "Total: %d/%d",
"Try again": "Vuelva a intentarlo",
"Try it now": "Intentar ahora",
"Type `help [command]` for more information about a command; or type `help all` for the complete usage information.": "Escriba `help [comando]` para obtener más información sobre el comando o escriba `help all` para obtener toda la información acerca del uso del programa.",
"Type `joplin help` for usage information.": "Escriba `joplin help` para mostrar información de uso.",
"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.": "Escriba el título de una nota o parte de su contenido para abrirla. O escriba # seguido del nombre de una etiqueta, o @ seguido del nombre de una libreta. O escriba : para buscar comandos.",
@@ -844,6 +948,7 @@
"Undo": "Deshacer",
"Unknown flag: %s": "Flag desconocida: %s",
"Unknown item type downloaded - please upgrade Joplin to the latest version": "Se ha descargado un elemento de tipo desconocido - por favor actualice Joplin a la última versión",
"Unordered list": "Lista",
"Unpublish note": "Despublicar nota",
"Unshare": "Dejar de compartir",
"Unshare this notebook? The recipients will no longer have access to its content.": "¿Dejar de compartir esta libreta? Los destinatarios ya no tendrán acceso a su contenido.",
@@ -865,16 +970,19 @@
"Upgrade the sync target to the latest version.": "Actualizar el objetivo de sincronización a la última versión.",
"URL": "URL",
"Usage: %s": "Uso: %s",
"Use biometrics to secure access to the app": "Usar biométricas para asegurar el acceso a la aplicación",
"Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE": "Usar formato de lista larga. El formato es ID, NOTE_COUNT (para libretas), DATE,TODO_CHECKED (para tareas), TITLE",
"Use spell checker": "Utilizar el corrector ortográfico",
"Use the arrows and page up/down to scroll the lists and text areas (including this console).": "Utilice las flechas y re/avpág para desplazar las listas y áreas de textos (incluyendo esta consola).",
"Use the arrows to move the layout items. Press \"Escape\" to exit.": "Use las flechas para mover los elementos del diseño. Pulse «Escape» para salir.",
"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.": "Use esto para reparar el índice de búsqueda si hay un problema con la búsqueda. Puede tomar un largo tiempo dependiendo del número de notas.",
"Use your biometrics to secure access to your application. You can always set it up later in Settings.": "Usa tus biométricas para asegurar el acceso a la aplicación. Siempre puedes configurarlo luego en Ajustes.",
"Used for most text in the markdown editor. If not found, a generic proportional (variable width) font is used.": "Se utiliza para la mayor parte del texto en el editor markdown. Si no se encuentra, se utiliza una fuente genérica proporcional (ancho variable).",
"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.": "Se utiliza donde se necesita una fuente de ancho fijo para presentar el texto de manera legible (por ejemplo, tablas, casillas de verificación, código). Si no se encuentra, se utiliza una fuente genérica monoespaciada (ancho fijo).",
"User deletions": "Eliminaciones de usuarios",
"Users": "Usuarios",
"Valid": "Válido",
"Verify your identity": "Verifica tu identidad",
"View": "Ver",
"View on map": "Ver en mapa",
"View them now": "Verlos ahora",
@@ -903,6 +1011,7 @@
"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.": "Puede utilizar la siguiente herramienta para volver a cifrar sus datos, por ejemplo, si sabe que algunas de sus notas están cifradas con un método de cifrado obsoleto.",
"Your choice: ": "Su elección: ",
"Your data is going to be re-encrypted and synced again.": "Sus datos van a ser cifrados y sincronizados nuevamente.",
"Your password is needed to decrypt some of your data.": "Su contraseña es necesaria para descifrar algunos de sus datos.",
"Your password is needed to decrypt some of your data. Type `:e2ee decrypt` to set it.": "Su contraseña es necesaria para descrifrar algunos de sus datos. Escriba `:e2ee decrypt` para establecerla.",
"Your permission to use your camera is required.": "Su permiso para usar su cámara es necesario.",
"Your version: %s": "Su versión: %s",
Loaded 100 of 326 files, more files were not shown because too many files have changed in this diff. Show more