1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-27 20:29:45 +02:00

Compare commits

...

147 Commits

Author SHA1 Message Date
Laurent Cozic
8d0e562c8a Android release v1.0.181 2018-12-20 14:58:35 +01:00
Laurent Cozic
c98e67c003 /bin/bash: qa: command not found 2018-12-20 14:53:10 +01:00
Laurent Cozic
5565538b80 Android: Trying to get notifications to work in Android 8.x 2018-12-20 14:52:56 +01:00
Helmut K. C. Tessarek
958979e1d7 CLI v1.0.119 2018-12-19 11:13:18 +01:00
Laurent Cozic
685845e097 Update website 2018-12-17 23:47:35 +01:00
Laurent Cozic
3813f9e417 Clipper release v1.0.8 2018-12-17 23:42:13 +01:00
Laurent Cozic
40cf3fb4d0 Android release v1.0.179 2018-12-17 23:25:21 +01:00
Laurent Cozic
3f88b16603 iOS v10.0.27 2018-12-17 23:12:35 +01:00
Laurent Cozic
32c02275a2 Upgrade React Native 2018-12-17 23:11:53 +01:00
Laurent Cozic
c0d679b6c2 Android release v1.0.178 2018-12-16 18:41:51 +01:00
Laurent Cozic
eb789b9b9a Electron release v1.0.119 2018-12-16 18:35:37 +01:00
Laurent Cozic
b1898141c3 Mobile: Fixes #382: Implemented new search engine for mobile and highlight searched words in notes 2018-12-16 18:32:42 +01:00
Laurent Cozic
3231bfaff0 Mobile: Fixes #1045: Display notebooks as a tree in notebook dropdown 2018-12-16 17:18:24 +01:00
Laurent Cozic
6bb09c9c30 Updated FAQ with info about F-Droid and how to fix Nextcloud issues 2018-12-16 14:30:56 +01:00
Laurent Cozic
35d3fe03ab Android: Fixes #321: Changed notification library to Firebase to get more reliable notifications 2018-12-16 14:11:45 +01:00
Laurent Cozic
f05929cd17 All: Fixes #1033: Handle hard break when rendering Markdown to HTML 2018-12-16 11:41:15 +01:00
Laurent Cozic
982c9828da Desktop: Fixes #1039: Always print or export to PDF using light theme 2018-12-16 02:49:06 +01:00
Laurent Cozic
d6eacb2b33 Android release v1.0.177 2018-12-15 01:51:49 +01:00
Laurent Cozic
0abe213fc2 Merge branch 'master' of github.com:laurent22/joplin 2018-12-15 01:46:16 +01:00
Laurent Cozic
a6716d55c5 Doc: Added search engine doc 2018-12-15 01:46:06 +01:00
Laurent Cozic
fa0572de77 Mobile: Many small fixes and improvements to style and layout to make app more usable 2018-12-15 01:45:35 +01:00
Laurent Cozic
6dca4a0d6b Mobile: Optimised loading of large notes that contain many images. 2018-12-15 01:42:19 +01:00
Helmut K. C. Tessarek
eacfe1a9ac add Apache WebDAV Module to WebDAV-compatible services (#1042) 2018-12-14 22:50:50 +00:00
Laurent Cozic
c223cdf10a Electron release v1.0.118 2018-12-14 19:57:32 +01:00
Laurent Cozic
38c42b7a15 Merge branch 'full_text_search' 2018-12-14 19:56:21 +01:00
Mats Estensen
56432dc773 [Documentation] Add example editor config to FAQ (#1036)
* add external editor example config to faq

* add external editor to feature list
2018-12-14 18:04:53 +00:00
Lucas
d3b4379161 Update to make it works in Kubuntu (#1038)
The directory ~/.local/share/applications/ exists in Kubuntu 18.04 so with this change the script also work in Kubuntu.
2018-12-14 18:03:39 +00:00
Laurent Cozic
8a6fcdbcae Should be commented out by default 2018-12-14 00:00:03 +01:00
Laurent Cozic
061ce646d2 Finished search engine integration with desktop app 2018-12-13 23:57:14 +01:00
Laurent Cozic
5ec7c16e3e Fixed logic to update search engine data 2018-12-12 22:40:05 +01:00
Andros Fenollosa
5d629508c1 Fix name in Linux Desktop (#1034) 2018-12-11 21:51:47 +01:00
Laurent Cozic
0a6f8b0cfe Started integrating search engine to desktop app 2018-12-10 19:58:49 +01:00
Laurent Cozic
460f826672 Nearly finished search engine backend 2018-12-10 18:54:46 +00:00
Laurent Cozic
cb16a10121 Updated the way item changes are recorded so that info can be used by more services (including search engine) 2018-12-10 01:39:31 +01:00
Laurent Cozic
3b6131f1ca Started support for FTS search 2018-12-09 21:45:50 +01:00
Laurent Cozic
57225a36b9 Updated translations 2018-12-09 01:22:16 +01:00
Laurent Cozic
3e313399c2 Desktop: Search within current note 2018-12-09 01:18:10 +01:00
Laurent Cozic
7947e14792 Merge branch 'master' of github.com:laurent22/joplin 2018-12-08 00:42:54 +01:00
Laurent Cozic
71098102c5 Electron: Fixes #476 (maybe): Trying to fix notification flood. Added more log statements in case something goes wrong. 2018-12-08 00:42:29 +01:00
Laurent Cozic
8e601e80df All: Prevent sync infinite loop under some rare conditions 2018-12-08 00:41:39 +01:00
Caleb John
3b14cfcc54 add separate editor font size option (#1027) 2018-12-07 22:26:03 +01:00
Laurent Cozic
61a0e43092 Mobile: Fixes #999: Associate new note with default notebook when creating it from Welcome screen 2018-12-07 01:23:36 +01:00
Laurent Cozic
d08aaffe41 Mobile: Resolves #1015: (Re-)added support for selecting image from camera roll 2018-12-07 01:07:10 +01:00
Laurent Cozic
7d0def30f0 Revert "ReactNativeClient: A better NAV_BACK logic to change folder or tag. (#984)" (Was opening up side menu on first app startup)
This reverts commit fc8f53fd0e.
2018-12-07 00:45:53 +01:00
Laurent Cozic
bb45d72a56 Clipper: Fixes #1026: Handle adding tag to clipped content after content has been clipped 2018-12-06 23:50:02 +01:00
Laurent Cozic
3943192c5d All: Fixes #808 (maybe): Added fix for Nginx 404 error issue. 2018-12-06 23:09:54 +01:00
Laurent Cozic
18d76807f6 Fixing Norwegian locale 2018-12-06 22:59:08 +01:00
Laurent Cozic
01a30a7ccf Fixed renaming 'no' locale to 'nb_NO' 2018-12-05 23:30:36 +01:00
Mats Estensen
3fb35d043b Revise and complete Norwegian translation (no) and rename to correct locale: nb_NO (#1013)
* update norwegian translation and correct locale name to nb_NO

* set no to nb_NO in documentation

* Add name, email and completion to README

Norwegian translation
2018-12-05 23:21:40 +01:00
Alex Devero
9b51bd484d Fix failing Windows build (#997)
* Upgrade sqlite3 to 4.0.4

* Remove rebuild, add install-app-deps
2018-12-05 23:11:40 +01:00
Laurent Cozic
879b556845 Update website 2018-11-24 12:05:49 +00:00
Laurent Cozic
0df2a501dd Electron release v1.0.117 2018-11-24 11:44:38 +00:00
Laurent Cozic
6f64fdffcc Desktop: Fixes #995: Added flag to disable tag bar for now 2018-11-24 11:42:50 +00:00
Laurent Cozic
19252af345 Desktop: Fixes #996: Allow editing multiple notes in external editor 2018-11-21 19:50:50 +00:00
Laurent Cozic
897f53b13e All: Resolves #846: Set resource path to correct relative path so that for example images show up in Markdown viewers 2018-11-21 00:36:23 +00:00
Laurent Cozic
45cd8b7e3c Merge branch 'master' of github.com:laurent22/joplin 2018-11-20 23:19:07 +00:00
Laurent Cozic
922bbdd1b6 All: Fixes #968: Export resources specified with a title 2018-11-20 23:18:56 +00:00
rhtenhove
c24135577c Useless and error prone VERSION file removed & warn use of root (#989)
* Don't create unused VERSION file

It will throw an error if the script is run from a non-writable directory

* Warn user if running as root

This will write files as root:root

* Clearer root warning
2018-11-20 21:54:58 +00:00
Laurent Cozic
3240ff40bc Restored string to avoid invalidating all the translations. 2018-11-20 21:54:40 +00:00
Ben Fisher
58b68cab0c fix for #906, 1) windows paths like C:\a\b weren't accepted because b… (#935)
* fix for #906, 1) windows paths like C:\a\b weren't accepted because backslashes were treated as escape sequences, 2) common paths like C:\Program Files\Foo\Foo.exe weren't accepted because of the space in the path

* Using anothing approach,
a) backslashes are no longer treated as escape characters,
b) string change to remind people to add spaces

* Removing joplin.pot from the patch, it will be updated later.

* Removing unused code.
2018-11-20 21:46:18 +00:00
Helmut K. C. Tessarek
0a0afd7245 CLI v1.0.118 2018-11-20 15:38:32 -05:00
Laurent Cozic
de01606bff Update website 2018-11-20 19:09:47 +00:00
Laurent Cozic
046474b484 Android release v1.0.176 2018-11-20 00:49:27 +00:00
Laurent Cozic
277b2b9298 Electron release v1.0.116 2018-11-20 00:44:25 +00:00
Laurent Cozic
0b7296ae95 Update translations 2018-11-20 00:43:35 +00:00
Laurent Cozic
ce87dd55f0 Merge branch 'master' of github.com:laurent22/joplin 2018-11-20 00:42:33 +00:00
Laurent Cozic
07b724d65b All: Fixes #992: Allow non-ASCII chars when exporting MD and handle duplicate filenames 2018-11-20 00:42:21 +00:00
Caleb John
bc1984298f Add dark theme to note properties dialog (#991) 2018-11-19 22:48:10 +00:00
Ein Verne
9ed0bdfed2 Add more Chinese translation (#986) 2018-11-19 22:44:20 +00:00
Caleb John
57628e8986 Add missing syntax file for dark theme (#985) 2018-11-19 22:43:56 +00:00
Joybin Chen
fc8f53fd0e ReactNativeClient: A better NAV_BACK logic to change folder or tag. (#984) 2018-11-19 22:43:21 +00:00
Renato Rosa
efd7cc6a0c update-locale-pt_BR (#981)
Update missing strings and fixed flagged ones.
2018-11-19 22:40:21 +00:00
Abijeet Patro
7bfc3e1256 Fixes #979 (#980)
* Adds functionality to display tags under the open note.

Towards #469

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Ensured tags in the dialog box and under the note appear in the same order.

Few formatting tweaks.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Fixes issues raised during code review.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Refactored code to always display tags in ascending order.

This changes the order of the tags in the dialog box and below the tag title.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Added the new tag height and margin bottom to the bottomRowHeight

Fixes #979

Signed-off-by: Abijeet <abijeetpatro@gmail.com>
2018-11-17 11:21:57 +00:00
FleischKarussel
7f6ca1e527 fixed typo in Aktualsierungsdatum to Aktualisierungsdatum (#974) 2018-11-17 11:17:47 +00:00
Laurent Cozic
71d9b1d441 Electron: Fixes #933: Handle internal links from HTML and from MD 2018-11-16 18:39:11 +00:00
Laurent Cozic
a3d64d0a90 Update website 2018-11-16 16:53:37 +00:00
Laurent Cozic
e7ec2ce6cf Electron release v1.0.115 2018-11-13 23:18:08 +00:00
Laurent Cozic
61dbdd5f7c Update translations 2018-11-13 23:17:56 +00:00
Laurent Cozic
e6888c451d Fixing Katex version number 2018-11-13 22:42:06 +00:00
Laurent Cozic
899219abd2 Merge branch 'master' of github.com:laurent22/joplin 2018-11-13 22:38:32 +00:00
Joybin Chen
7a4c7a13eb Fix image fetching error. For url like http://example.com/favicon.ico?ver=1.0 will be changed to http://example.com/favicon.ico?ver=1.0?ver=1.0 (#970) 2018-11-13 22:37:39 +00:00
Laurent Cozic
e8797f49b9 Mobile: Display number of resources being fetched in side bar 2018-11-13 22:27:58 +00:00
Laurent Cozic
e17f3051f0 Display number of resources being fetched in side bar 2018-11-13 22:25:23 +00:00
Laurent Cozic
06091933e1 All: Moved resource app-specific state to different table 2018-11-13 00:45:08 +00:00
Laurent Cozic
b30c65dd89 Update CONTRIBUTING.md 2018-11-11 20:23:55 +00:00
Ben Fisher
0eb18d206d Patch to implement feature, exporting notes to JSON (#912, issues/912). (#927)
* Patch to implement feature, exporting notes to JSON (#912, issues/912).

* Revising based on feedback

* Directly calling JSON.stringify on the item
2018-11-11 20:17:43 +00:00
Laurent Cozic
3a9948e528 Build doc 2018-11-08 01:21:18 +00:00
Laurent Cozic
2bcddd38b2 Update API doc 2018-11-08 01:17:46 +00:00
Laurent Cozic
5ff8808f69 API: Allow setting the ID of newly created notes. 2018-11-08 01:14:13 +00:00
Laurent Cozic
28b1d8a324 Desktop: Fixes #953 (maybe): Improved the way internal links to notes are loaded to make it more reliable 2018-11-08 00:58:06 +00:00
Laurent Cozic
5c1dd79435 All: Fixes #952: Upgraded Katex lib to fix bug 2018-11-07 23:44:59 +00:00
Laurent Cozic
706d59a6cc Doc 2018-11-07 23:43:48 +00:00
Ben Fisher
251f1bba55 Show note title in pdf export (#890) (#937)
* Show note title in pdf export (#890)

An example of a possible approach, to temporarily change the html in the webview to show the note title. Works, but there may be a more elegant fix.

* Show title in pdf export

Revising based on feedback
Also, a couple changes to tests so that they pass in Windows.
2018-11-07 23:35:14 +00:00
Caleb John
cb1fd85ca4 Add support for custom css across all notes (#925) 2018-11-07 22:52:31 +00:00
Laurent Cozic
11ddc55911 Fixed theme handling for new tag feature 2018-11-07 22:47:34 +00:00
Caleb John
ee106105d8 Joplin desktop Dark Mode (#921)
* Added support for the dark mode on desktop

* Add dark highlighting to the code tags

* Update app/theme.js to be more clear and more easily support additional themes
Update more files to conform to theming
2018-11-07 22:37:13 +00:00
Laurent Cozic
19f5a144e5 Added comment 2018-11-07 22:22:26 +00:00
Abijeet Patro
18717bac79 Adds functionality to display tags under the open note. (#893)
* Adds functionality to display tags under the open note.

Towards #469

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Ensured tags in the dialog box and under the note appear in the same order.

Few formatting tweaks.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Fixes issues raised during code review.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Refactored code to always display tags in ascending order.

This changes the order of the tags in the dialog box and below the tag title.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>
2018-11-07 22:16:05 +00:00
Laurent Cozic
28fa83c406 Merge branch 'master' of github.com:laurent22/joplin 2018-11-02 19:56:18 +00:00
Laurent Cozic
258e514a91 Marked password cache as secure, and only display stars if the value is non-empty 2018-11-02 19:22:49 +00:00
Ben Fisher
f92546d6eb Adding some tips for building and debugging Joplin on Windows (#938) 2018-11-02 01:06:48 +00:00
sensor-freak
693456164b Minor fix for translation of 'Location' (#936) 2018-11-02 00:53:05 +00:00
Helmut K. C. Tessarek
7cd3e6b1f7 mobile: add version info (#930) 2018-11-02 00:43:42 +00:00
FoxMaSk
764e63d869 new French Translations (#923) 2018-11-02 00:24:28 +00:00
Laurent Cozic
2c6f47f277 Update README.md
Removed Hacktoberfest news
2018-11-01 17:45:05 +00:00
Laurent Cozic
e41896d6f3 All: Resolves #918: Skip properties that are on sync target but not handled by local client 2018-10-31 00:35:57 +00:00
Laurent Cozic
990591cc80 Minor improvments 2018-10-30 00:17:50 +00:00
Laurent Cozic
7b85c33213 CLI v1.0.117 2018-10-29 23:24:19 +00:00
Laurent Cozic
4b4d0e8b25 Update website 2018-10-24 21:14:38 +01:00
Laurent Cozic
4fb6af3c62 Android release v1.0.175 2018-10-24 19:59:37 +01:00
Laurent Cozic
d7ffe7e294 Electron release v1.0.114 2018-10-24 19:52:07 +01:00
Laurent Cozic
3ff139d445 Merge branch 'master' of github.com:laurent22/joplin 2018-10-24 19:51:16 +01:00
Laurent Cozic
40443e0134 Android v153 2018-10-24 19:50:26 +01:00
Laurent Cozic
1f927c1285 iOS v26 2018-10-24 19:48:09 +01:00
Andros Fenollosa
5e82e62335 Linux script install: implement previous updates (#905)
Avoid an erroneous update and prevent installation icon only on gnome.
2018-10-24 19:17:18 +01:00
Yannis Mitsos
de954827df Support FreeBSD in terminal (#896) 2018-10-24 19:16:15 +01:00
Laurent Cozic
2cb24bf198 Mobile: Fixes #902: Don't change existing note when sharing with mobile app 2018-10-24 19:10:05 +01:00
Laurent Cozic
739a6a4a9c Documentation 2018-10-24 18:47:04 +01:00
Laurent Cozic
dfcf1193dc Electron: Handle internal anchors 2018-10-17 08:01:18 +01:00
Laurent Cozic
c72f92e22f Additional info 2018-10-15 18:40:11 +01:00
Laurent Cozic
f6d01ce7e1 Android release v1.0.174 2018-10-15 00:01:36 +01:00
Laurent Cozic
fed9700587 Merge branch 'master' of github.com:laurent22/joplin 2018-10-15 00:00:13 +01:00
Laurent Cozic
12a3a9a89e android release 2018-10-14 23:59:42 +01:00
Laurent Cozic
590c62c371 Merge branch 'fixing_android_build' 2018-10-14 23:56:42 +01:00
Laurent Cozic
df41f64b3c Revert "trying to fix android build"
This reverts commit 621d0260f4.
2018-10-14 21:47:12 +01:00
Laurent Cozic
1849355245 Android: Tryinc to fix release builkd 2018-10-14 21:42:34 +01:00
Laurent Cozic
fa1b471ea4 Android: Tryinc to fix release builkd 2018-10-14 21:41:29 +01:00
Laurent Cozic
0a67f8c947 Revert "Android: Updated project to build on macOS"
This reverts commit b547f9aa13.
2018-10-14 20:44:05 +01:00
Laurent Cozic
621d0260f4 trying to fix android build 2018-10-14 19:57:30 +01:00
Laurent Cozic
f93fca7c5b Revert "Android: Updated project to build on macOS"
This reverts commit b547f9aa13.
2018-10-13 11:35:21 +01:00
Laurent Cozic
f4d830c2ef Android release v1.0.151 2018-10-13 11:09:03 +01:00
Laurent Cozic
1aa2844efa Android release v1.0.148 2018-10-13 10:39:55 +01:00
Laurent Cozic
f22b2adaad Mobile: Improved camera attachment 2018-10-13 10:32:44 +01:00
Laurent Cozic
b547f9aa13 Android: Updated project to build on macOS 2018-10-13 00:30:41 +01:00
Laurent Cozic
e4166e9da7 Electron: Fixes #312 (maybe): Removed power saving feature, which wasn\'t doing anything and added a possible fix to the UI freezing issue on Linux 2018-10-12 23:44:00 +01:00
Laurent Cozic
1634fdb421 Merge branch 'master' of github.com:laurent22/joplin 2018-10-12 23:26:11 +01:00
Laurent Cozic
7f51035f91 Mobile: Reload note when resource got downloaded. Also fixed Android build script to make it work in macOS. 2018-10-12 23:25:11 +01:00
ebayer
70e71cbc2a Mobile: Fixes #856: Add option to open source url (#872)
* Mobile: Fixes #856: Add option to open source url

* Mobile: Fixes #856: Change menu wording for opening source url
2018-10-12 19:30:00 +01:00
Laurent Cozic
ffd03bf34c Merge branch 'master' of github.com:laurent22/joplin 2018-10-11 17:53:40 +01:00
Christian Baer
f59a3dee78 Fixed some more inconsistencies in german language file. (#855)
* Fixed some typos and inconsistencies in the german language file and added missing translations.

* Fixed some more inconsistencies in german language file.
2018-10-11 17:21:12 +01:00
Timothy Cyrus
3ba3037242 Update README.md (#874) 2018-10-11 17:20:42 +01:00
Helmut K. C. Tessarek
dbb269fef6 add support for webp images (#858)
fixes #848
2018-10-11 17:18:33 +01:00
Laurent Cozic
e209189faa All: Added resource test units 2018-10-11 17:18:24 +01:00
Laurent Cozic
2d7065cde2 Android release v1.0.143 2018-10-10 20:36:42 +01:00
Laurent Cozic
59f5972c93 Electron release v1.0.113 2018-10-10 20:32:45 +01:00
Laurent Cozic
8bac5275c3 All: Fixed fetch logic - mark resource as fetched by default, unless it comes from sync 2018-10-10 18:53:09 +01:00
Helmut K. C. Tessarek
58d748e235 fix permissions for shell scripts (add executable flag) (#866) 2018-10-09 22:58:18 +01:00
214 changed files with 6345 additions and 2308 deletions

View File

@@ -58,6 +58,8 @@ If node-gyp does not works (MSBUILD: error MSB3428: Could not load the Visual C+
If `yarn dist` fails, it may need administrative rights.
The [building\_win32\_tips on this page](./readme/building_win32_tips.md) might be helpful.
# Building the Mobile application
First you need to setup React Native to build projects with native code. For this, follow the instructions on the [Get Started](https://facebook.github.io/react-native/docs/getting-started.html) tutorial, in the "Building Projects with Native Code" tab.

View File

@@ -18,9 +18,11 @@ If you want to add a new feature, consider asking about it before implementing i
Building the apps is relatively easy - please [see the build instructions](https://github.com/laurent22/joplin/blob/master/BUILD.md) for more details.
Pull requests that automatically change many files tend to be rejected (for example changes that automatically update the code styling, or to add new lines to many files, or to automatically convert images to a different format) so if you have such a pull request in mind, please discuss it first in the forum.
# Coding style
There are only two rules, but not following them means the pull request will not be accepted (it can be accepted once the issues are fixed):
- **Please use tabs, NOT spaces.**
- **Please do not add or remove optional characters, such as spaces or colons.** Please setup your editor so that it only changes what you are working on and is not making automated changes elsewhere. The reason for this is that small white space changes make diff hard to read and can cause needless conflicts.
- **Please do not add or remove optional characters, such as spaces or colons.** Please setup your editor so that it only changes what you are working on and is not making automated changes elsewhere. The reason for this is that small white space changes make diff hard to read and can cause needless conflicts.

View File

@@ -69,7 +69,8 @@ class Command extends BaseCommand {
lines.push(' }');
lines.push('}');
lines.push('```');
lines.push('');
lines.push('# Authorisation')
lines.push('');
lines.push('To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');
@@ -79,6 +80,7 @@ class Command extends BaseCommand {
lines.push('\tcurl http://localhost:41184/notes?token=ABCD123ABCD123ABCD123ABCD123ABCD123');
lines.push('');
lines.push('In the documentation below, the token will not be specified every time however you will need to include it.');
lines.push('');
lines.push('# Using the API');
lines.push('');
@@ -253,6 +255,12 @@ class Command extends BaseCommand {
lines.push('');
lines.push(' curl --data \'{ "title": "Image test", "body": "Here is Joplin icon:", "image_data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="}\' http://127.0.0.1:41184/notes');
lines.push('');
lines.push('### Creating a note with a specific ID');
lines.push('');
lines.push('When a new note is created, it is automatically assigned a new unique ID so **normally you do not need to set the ID**. However, if for some reason you want to set it, you can supply it as the `id` property. It needs to be a 32 characters long hexadecimal string. **Make sure it is unique**, for example by generating it using whatever GUID function is available in your programming language.');
lines.push('');
lines.push(' curl --data \'{ "id": "00a87474082744c1a8515da6aa5792d2", "title": "My note with custom ID"}\' http://127.0.0.1:41184/notes');
lines.push('');
}
lines.push('## PUT /' + tableName + '/:id');

View File

@@ -26,7 +26,7 @@ class Command extends BaseCommand {
const md = Setting.settingMetadata(name);
let value = Setting.value(name);
if (typeof value === 'object' || Array.isArray(value)) value = JSON.stringify(value);
if (md.secure) value = '********';
if (md.secure && value) value = '********';
if (Setting.isEnum(name)) {
return _('%s = %s (%s)', name, value, Setting.enumOptionsDoc(name));

View File

@@ -196,6 +196,7 @@ class Command extends BaseCommand {
// not going to be running in the background, so the resources need to be
// explicitely downloaded below.
if (!app().hasGui()) {
this.stdout(_('Downloading resources...'));
await ResourceFetcher.instance().fetchAll();
await ResourceFetcher.instance().waitForAllFinished();
}

View File

@@ -460,6 +460,9 @@ msgstr "No es pot inicialitzar el sincronitzador."
msgid "Starting synchronisation..."
msgstr "Està començant la sincronització..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "S'està cancel·lant... Espereu."
@@ -652,6 +655,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Cerca a totes les notes"
#, fuzzy
msgid "Search in current note"
msgstr "Cerca a totes les notes"
msgid "View"
msgstr "Visualització"
@@ -984,6 +991,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Obre..."
@@ -1000,6 +1010,9 @@ msgstr "Copia el camí al porta-retalls"
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Missatge o enllaç no suportat: %s"
@@ -1037,9 +1050,6 @@ msgstr "Estableix una alarma"
msgid "In: %s"
msgstr "A: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1117,6 +1127,14 @@ msgstr "Sincronitza"
msgid "Notebooks"
msgstr "Blocs de notes"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elements obtinguts: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccioneu on s'hauria d'exportar l'estat de la sincronització"
@@ -1161,6 +1179,9 @@ msgstr ""
"No es pot actualitzar el testimoni: manquen les dades d'autenticació. Si "
"comenceu altre cop la sincronització, potser es corregeixi el problema."
msgid "Untitled"
msgstr "Sense títol"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1208,10 +1229,6 @@ msgstr "Elements remots suprimits: %d."
msgid "Fetched items: %d/%d."
msgstr "Elements obtinguts: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estat: %s"
msgid "Cancelling..."
msgstr "S'està cancel·lant..."
@@ -1258,9 +1275,6 @@ msgstr "data d'actualització"
msgid "created date"
msgstr "data de creació"
msgid "Untitled"
msgstr "Sense títol"
msgid "This note does not have geolocation information."
msgstr "Aquesta nota no té informació de geolocalització."
@@ -1323,12 +1337,22 @@ msgstr "Mostra la icona a la safata"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: no funciona en tots els entorns d'escriptori."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Percentatge de zoom global"
#, fuzzy
msgid "Editor font size"
msgstr "Tipus de lletra de l'editor"
msgid "Editor font family"
msgstr "Tipus de lletra de l'editor"
@@ -1451,6 +1475,10 @@ msgstr "Directori d'exportació del Joplin"
msgid "Evernote Export File"
msgstr "Fitxer d'exportació de l'Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Directori d'exportació del Joplin"
msgid "Directory"
msgstr "Directori"
@@ -1525,6 +1553,12 @@ msgstr "Alarmes programades"
msgid "On %s: %s"
msgstr "A les %s.%s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Ara mateix no hi ha cap nota. Creeu-ne una fent clic en el botó (+)."
@@ -1569,10 +1603,6 @@ msgstr "Confirmació"
msgid "Cancel synchronisation"
msgstr "Cancel·la la sincronització"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elements obtinguts: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "S'està cancel·lant... Espereu."
@@ -1690,6 +1720,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipus d'imatge no admesa: %s"
#, fuzzy
msgid "Take photo"
msgstr "Adjunta una imatge"
msgid "Attach photo"
msgstr "Adjunta una imatge"
@@ -1714,6 +1748,9 @@ msgstr "Mostra les metadades"
msgid "View on map"
msgstr "Mostra-ho al mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Suprimeix el bloc de notes"
@@ -1737,5 +1774,8 @@ msgstr ""
msgid "Welcome"
msgstr "Benvingut"
#~ msgid "State: %s."
#~ msgstr "Estat: %s"
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ja existeix un bloc de notes amb aquest títol: «%s»"

View File

@@ -448,6 +448,9 @@ msgstr "Nelze zavézt synchronizátor."
msgid "Starting synchronisation..."
msgstr "Zahajuji synchronizaci..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Zastavuji, chvíli strpení."
@@ -634,6 +637,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Hledat ve všech poznámkách"
#, fuzzy
msgid "Search in current note"
msgstr "Hledat ve všech poznámkách"
msgid "View"
msgstr "Zobrazit"
@@ -955,6 +962,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Otevřít..."
@@ -971,6 +981,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodporovaný link či zpráva: %s"
@@ -1006,9 +1019,6 @@ msgstr "Nastavit alarm"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1087,6 +1097,14 @@ msgstr "Synchronizovat"
msgid "Notebooks"
msgstr "Zápisníky"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Získané položky: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Zdroje: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Prosím vyberte, kam má být stav synchronizace exportován"
@@ -1131,6 +1149,9 @@ msgstr ""
"Nelze obnovit token: chybí autentizační data. Restart synchronizace může "
"tento problém vyřešit. "
msgid "Untitled"
msgstr "Bez názvu"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1178,10 +1199,6 @@ msgstr "Položky smazané na vzdáleném úložišti: %d."
msgid "Fetched items: %d/%d."
msgstr "Získané položky: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Stav: %s."
msgid "Cancelling..."
msgstr "Zastavuji..."
@@ -1232,9 +1249,6 @@ msgstr "Upraveno: %d."
msgid "created date"
msgstr "Vytvořeno: %d."
msgid "Untitled"
msgstr "Bez názvu"
msgid "This note does not have geolocation information."
msgstr "Tato poznámka nemá informace o poloze."
@@ -1298,12 +1312,22 @@ msgstr "Zobrazovat ikonu v panelu"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Globální zoom"
#, fuzzy
msgid "Editor font size"
msgstr "Rodina písma v editoru"
msgid "Editor font family"
msgstr "Rodina písma v editoru"
@@ -1426,6 +1450,10 @@ msgstr "Složka pro export"
msgid "Evernote Export File"
msgstr "Soubor Evernote Exportu"
#, fuzzy
msgid "Json Export Directory"
msgstr "Složka pro export"
msgid "Directory"
msgstr "Adresář"
@@ -1500,6 +1528,12 @@ msgstr "Nadcházející alarmy"
msgid "On %s: %s"
msgstr "Na %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Nemáte žádné poznámky. Vytvořte jednu kliknutím na tlačítko (+)."
@@ -1545,10 +1579,6 @@ msgstr "Potvrdit"
msgid "Cancel synchronisation"
msgstr "Zrušit synchronizaci"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Získané položky: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Zastavuji, chvíli strpení."
@@ -1659,6 +1689,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodporovaný formát obrázku: %s"
#, fuzzy
msgid "Take photo"
msgstr "Přiložit obrázek"
msgid "Attach photo"
msgstr "Přiložit obrázek"
@@ -1683,6 +1717,9 @@ msgstr "Zobrazit metadata"
msgid "View on map"
msgstr "Zobrazit na map+"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Smazat zápisník"
@@ -1705,6 +1742,9 @@ msgstr "Nemáte žádný zápisník. Vytvořte jeden kliknutím na tlačítko (+
msgid "Welcome"
msgstr "Vítejte"
#~ msgid "State: %s."
#~ msgstr "Stav: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Zápisník s tímto názvem již existuje: \"%s\""

View File

@@ -452,6 +452,9 @@ msgstr "Kan ikke initialisere synkroniseringen."
msgid "Starting synchronisation..."
msgstr "Starter synkronisering."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Annullerer... Vent venligst."
@@ -639,6 +642,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Søg i alle noter"
#, fuzzy
msgid "Search in current note"
msgstr "Søg i alle noter"
msgid "View"
msgstr "Vis"
@@ -964,6 +971,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Åben..."
@@ -980,6 +990,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Ugyldigt- eller ulovligt link eller besked: %s"
@@ -1015,9 +1028,6 @@ msgstr "Indstil alarm"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1096,6 +1106,14 @@ msgstr "Synkroniser"
msgid "Notebooks"
msgstr "Notesbøger"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Hentede emner: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Ressourcer: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Vælg hvor sync status skal eksporteres til"
@@ -1140,6 +1158,9 @@ msgstr ""
"Kan ikke opdatere token: Godkendelses data mangler. Prøv at starte "
"synkronisering igen, det kan løse problemet."
msgid "Untitled"
msgstr "Samlet"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1187,10 +1208,6 @@ msgstr "Slettede fjern-emner: %d."
msgid "Fetched items: %d/%d."
msgstr "Hentede emner: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Tilstand: %s."
msgid "Cancelling..."
msgstr "Annullerer..."
@@ -1241,9 +1258,6 @@ msgstr "Opdateret %d."
msgid "created date"
msgstr "Oprettet: %d."
msgid "Untitled"
msgstr "Samlet"
msgid "This note does not have geolocation information."
msgstr "Denne note har ingen geolokations oplysninger."
@@ -1307,12 +1321,22 @@ msgstr "Vis ikon på bundbjælke"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Global zoom procent"
#, fuzzy
msgid "Editor font size"
msgstr "Rediger skrifttype"
msgid "Editor font family"
msgstr "Rediger skrifttype"
@@ -1435,6 +1459,10 @@ msgstr "Joplin eksport mappe"
msgid "Evernote Export File"
msgstr "Evernote eksport fil"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin eksport mappe"
msgid "Directory"
msgstr "Indeks"
@@ -1509,6 +1537,12 @@ msgstr "Kommende alarmer"
msgid "On %s: %s"
msgstr "På %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Der er ingen noter. Opret note ved at klikke på (+) knappen."
@@ -1554,10 +1588,6 @@ msgstr "Bekræft"
msgid "Cancel synchronisation"
msgstr "Afbryd synkronisering"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Hentede emner: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Annullerer... Vent venligst."
@@ -1668,6 +1698,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Ulovlig billedtype: %s"
#, fuzzy
msgid "Take photo"
msgstr "Vedhæft foto"
msgid "Attach photo"
msgstr "Vedhæft foto"
@@ -1692,6 +1726,9 @@ msgstr "Vis metadata"
msgid "View on map"
msgstr "Vis på kort"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Slet notesbog"
@@ -1714,6 +1751,9 @@ msgstr "Du har ingen notesbøger. Opret en ved at klikke på (+) knappen."
msgid "Welcome"
msgstr "Velkommen"
#~ msgid "State: %s."
#~ msgstr "Tilstand: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "En notesbog bruger allerede dette navn: \"%s\""

View File

@@ -197,8 +197,8 @@ msgid ""
"complete database including notebooks, notes, tags and resources."
msgstr ""
"Exportiert Joplin-Dateien in den angegebenen Pfad. Standardmäßig wird die "
"komplette Datenbank inklusive Notizbüchern, Notizen, Tags und Anhängen "
"exportiert."
"komplette Datenbank inklusive Notizbüchern, Notizen, Schlagwörtern und "
"Anhängen exportiert."
#, javascript-format
msgid "Destination format: %s"
@@ -305,7 +305,7 @@ msgstr "Anhänge: %d."
#, javascript-format
msgid "Tagged: %d."
msgstr "Getagged: %d."
msgstr "Verschlagwortet: %d."
msgid "Importing notes..."
msgstr "Importiere Notizen..."
@@ -471,6 +471,9 @@ msgstr "Kann Synchronisierer nicht initialisieren."
msgid "Starting synchronisation..."
msgstr "Starte Synchronisation..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Abbrechen… Bitte warten."
@@ -660,6 +663,10 @@ msgstr "Im externen Editor bearbeiten"
msgid "Search in all the notes"
msgstr "Alle Notizen durchsuchen"
#, fuzzy
msgid "Search in current note"
msgstr "Alle Notizen durchsuchen"
msgid "View"
msgstr "Ansicht"
@@ -918,7 +925,7 @@ msgid "Notebook title:"
msgstr "Notizbuch-Titel:"
msgid "Add or remove tags:"
msgstr "Füge hinzu oder entferne Schlagwörter:"
msgstr "Schlagwörter hinzufügen oder entfernen:"
msgid "Separate each tag by a comma."
msgstr "Trenne jedes Schlagwort mit einem Komma."
@@ -988,12 +995,16 @@ msgstr ""
"Momentan existieren noch keine Notizbücher. Erstelle eines, indem du auf "
"\"Neues Notizbuch\" drückst."
# Please note: The term 'Location' is assumed to be the geographical location where the note has been created. For this the german word 'Standort' fits better than the previously used 'Ablageort'. The latter one is used for the folder where files are stored.
msgid "Location"
msgstr "Ablageort"
msgstr "Standort"
msgid "URL"
msgstr "URL"
msgid "Note properties"
msgstr "Notiz-Eigenschaften"
msgid "Open..."
msgstr "Öffne..."
@@ -1010,6 +1021,9 @@ msgstr "Pfad in Zwischenablage kopieren"
msgid "Copy Link Address"
msgstr "Link-Adresse kopieren"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nicht unterstützter Link oder Nachricht: %s"
@@ -1047,9 +1061,6 @@ msgstr "Alarm erstellen"
msgid "In: %s"
msgstr "In: %s"
msgid "Note properties"
msgstr "Notiz-Eigenschaften"
msgid "Hyperlink"
msgstr "Weblink"
@@ -1126,6 +1137,14 @@ msgstr "Synchronisieren"
msgid "Notebooks"
msgstr "Notizbücher"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Entschlüsselte Objekte: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Anhänge: %d."
msgid "Please select where the sync status should be exported to"
msgstr ""
"Bitte wähle aus, wohin der Synchronisations-Status exportiert werden soll"
@@ -1171,6 +1190,9 @@ msgstr ""
"Kann Token nicht erneuern: Authentifikationsdaten nicht vorhanden. Ein "
"Neustart der Synchronisation könnte das Problem beheben."
msgid "Untitled"
msgstr "Unbenannt"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1218,10 +1240,6 @@ msgstr "Remote-Objekte gelöscht: %d."
msgid "Fetched items: %d/%d."
msgstr "Geladene Objekte: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Status: %s."
msgid "Cancelling..."
msgstr "Breche ab…"
@@ -1264,14 +1282,11 @@ msgid "title"
msgstr "Titel"
msgid "updated date"
msgstr "Aktualsierungsdatum"
msgstr "Aktualisierungsdatum"
msgid "created date"
msgstr "Erstelldatum"
msgid "Untitled"
msgstr "Unbenannt"
msgid "This note does not have geolocation information."
msgstr "Diese Notiz hat keine Standort-Informationen."
@@ -1334,12 +1349,22 @@ msgstr "Zeige Tray-Icon"
msgid "Note: Does not work in all desktop environments."
msgstr "Hinweis: Funktioniert nicht in allen Desktopumgebungen."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr "Starte die Anwendung minimiert im Tray"
msgid "Global zoom percentage"
msgstr "Zoomstufe der Benutzeroberfläche"
#, fuzzy
msgid "Editor font size"
msgstr "Editor Schriftenfamilie"
msgid "Editor font family"
msgstr "Editor Schriftenfamilie"
@@ -1470,6 +1495,10 @@ msgstr "Joplin Export Verzeichnis"
msgid "Evernote Export File"
msgstr "Evernote Export Datei"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin Export Verzeichnis"
msgid "Directory"
msgstr "Verzeichnis"
@@ -1545,6 +1574,12 @@ msgstr "Anstehende Alarme"
msgid "On %s: %s"
msgstr "Auf %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Momentan existieren noch keine Notizen. Erstelle eine, indem du auf den (+) "
@@ -1590,10 +1625,6 @@ msgstr "Bestätigen"
msgid "Cancel synchronisation"
msgstr "Synchronisation abbrechen"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Entschlüsselte Objekte: %d/%d"
msgid "Checking... Please wait."
msgstr "Überprüfe… Bitte warten."
@@ -1715,6 +1746,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nicht unterstütztes Fotoformat: %s"
#, fuzzy
msgid "Take photo"
msgstr "Foto anhängen"
msgid "Attach photo"
msgstr "Foto anhängen"
@@ -1739,6 +1774,9 @@ msgstr "Metadaten anzeigen"
msgid "View on map"
msgstr "Auf der Karte anzeigen"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Notizbuch löschen"
@@ -1764,6 +1802,9 @@ msgstr ""
msgid "Welcome"
msgstr "Willkommen"
#~ msgid "State: %s."
#~ msgstr "Status: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ein Notizbuch mit diesem Titel existiert bereits : \"%s\""

View File

@@ -408,6 +408,9 @@ msgstr ""
msgid "Starting synchronisation..."
msgstr ""
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr ""
@@ -570,6 +573,9 @@ msgstr ""
msgid "Search in all the notes"
msgstr ""
msgid "Search in current note"
msgstr ""
msgid "View"
msgstr ""
@@ -874,6 +880,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -890,6 +899,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr ""
@@ -925,9 +937,6 @@ msgstr ""
msgid "In: %s"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1004,6 +1013,14 @@ msgstr ""
msgid "Notebooks"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
#, javascript-format
msgid "Fetching resources: %d"
msgstr ""
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -1046,6 +1063,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr ""
msgid "Untitled"
msgstr ""
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1087,10 +1107,6 @@ msgstr ""
msgid "Fetched items: %d/%d."
msgstr ""
#, javascript-format
msgid "State: %s."
msgstr ""
msgid "Cancelling..."
msgstr ""
@@ -1137,9 +1153,6 @@ msgstr ""
msgid "created date"
msgstr ""
msgid "Untitled"
msgstr ""
msgid "This note does not have geolocation information."
msgstr ""
@@ -1202,12 +1215,21 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
msgid "Editor font size"
msgstr ""
msgid "Editor font family"
msgstr ""
@@ -1319,6 +1341,9 @@ msgstr ""
msgid "Evernote Export File"
msgstr ""
msgid "Json Export Directory"
msgstr ""
msgid "Directory"
msgstr ""
@@ -1388,6 +1413,12 @@ msgstr ""
msgid "On %s: %s"
msgstr ""
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
@@ -1431,10 +1462,6 @@ msgstr ""
msgid "Cancel synchronisation"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
msgid "Checking... Please wait."
msgstr ""
@@ -1541,6 +1568,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr ""
msgid "Take photo"
msgstr ""
msgid "Attach photo"
msgstr ""
@@ -1565,6 +1595,9 @@ msgstr ""
msgid "View on map"
msgstr ""
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr ""

View File

@@ -457,6 +457,9 @@ msgstr "No se puede inicializar sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronización..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Cancelando... Por favor espere."
@@ -648,6 +651,10 @@ msgstr "Editar con un editor externo"
msgid "Search in all the notes"
msgstr "Buscar en todas las notas"
#, fuzzy
msgid "Search in current note"
msgstr "Buscar en todas las notas"
msgid "View"
msgstr "Ver"
@@ -977,6 +984,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Abrir..."
@@ -993,6 +1003,9 @@ msgstr "Copiar la ruta en el portapapeles"
msgid "Copy Link Address"
msgstr "Copiar enlace"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Enlace o mensaje no soportado: %s"
@@ -1030,9 +1043,6 @@ msgstr "Establecer alarma"
msgid "In: %s"
msgstr "En: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Hipervínculo"
@@ -1109,6 +1119,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Libretas"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Descifrando elementos: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccione a dónde se debería exportar el estado de sincronización"
@@ -1153,6 +1171,9 @@ msgstr ""
"No se ha podido actualizar token: faltan datos de autenticación. Reiniciar "
"la sincronización podría solucionar el problema."
msgid "Untitled"
msgstr "Sin título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1200,10 +1221,6 @@ msgstr "Elementos remotos borrados: %d."
msgid "Fetched items: %d/%d."
msgstr "Elementos obtenidos: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: «%s»."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1251,9 +1268,6 @@ msgstr "fecha de actualización"
msgid "created date"
msgstr "fecha de creación"
msgid "Untitled"
msgstr "Sin título"
msgid "This note does not have geolocation information."
msgstr "Esta nota no tiene informacion de geolocalización."
@@ -1316,12 +1330,22 @@ msgstr "Mostrar icono en la bandeja"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: No funciona en todos los entornos de escritorio."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Establecer el porcentaje de aumento de la aplicación"
#, fuzzy
msgid "Editor font size"
msgstr "Fuente del editor"
msgid "Editor font family"
msgstr "Fuente del editor"
@@ -1449,6 +1473,10 @@ msgstr "Directorio para exportar de Joplin"
msgid "Evernote Export File"
msgstr "Archivo exportado de Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Directorio para exportar de Joplin"
msgid "Directory"
msgstr "Directorio"
@@ -1523,6 +1551,12 @@ msgstr "Alarmas próximas"
msgid "On %s: %s"
msgstr "En %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "No hay notas. Cree una pulsando en el botón (+)."
@@ -1567,10 +1601,6 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronización"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Descifrando elementos: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancelando... Por favor espere."
@@ -1688,6 +1718,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipo de imagen no soportado: %s"
#, fuzzy
msgid "Take photo"
msgstr "Adjuntar foto"
msgid "Attach photo"
msgstr "Adjuntar foto"
@@ -1712,6 +1746,9 @@ msgstr "Mostrar metadatos"
msgid "View on map"
msgstr "Ver en un mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Borrar libreta"
@@ -1735,6 +1772,9 @@ msgstr ""
msgid "Welcome"
msgstr "Bienvenido"
#~ msgid "State: %s."
#~ msgstr "Estado: «%s»."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ya existe una libreta con este nombre: «%s»"

View File

@@ -455,6 +455,9 @@ msgstr "Ezin has daiteke sinkronizazio prozesua."
msgid "Starting synchronisation..."
msgstr "Sinkronizazioa hasten..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Bertan behera uzten... itxaron, mesedez."
@@ -647,6 +650,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Bilatu ohar guztietan"
#, fuzzy
msgid "Search in current note"
msgstr "Bilatu ohar guztietan"
msgid "View"
msgstr ""
@@ -973,6 +980,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -990,6 +1000,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Esteka edo mezu ez dago onartua: %s"
@@ -1025,9 +1038,6 @@ msgstr "Ezarri alarma"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1109,6 +1119,14 @@ msgstr "Sinkronizatu"
msgid "Notebooks"
msgstr "Koadernoak"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Itemak eskuratuta: %d%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Baliabideak: %d."
#, fuzzy
msgid "Please select where the sync status should be exported to"
msgstr "Aukeratu nora esportatu sinkronizazioaren egoera, mesedez"
@@ -1156,6 +1174,9 @@ msgstr ""
"Tokena ezin eguneratu daiteke: egiaztatze-datuak desagertuta daude. Agian, "
"berriro sinkronizatzeak arazoa konpon lezake."
msgid "Untitled"
msgstr "Titulu gabekoa"
#, fuzzy
msgid ""
"Could not synchronize with OneDrive.\n"
@@ -1202,10 +1223,6 @@ msgstr "Urruneko itemak ezabatuta: %d."
msgid "Fetched items: %d/%d."
msgstr "Itemak eskuratuta: %d%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Egoera: \"%s\"."
msgid "Cancelling..."
msgstr "Bertan behera uzten..."
@@ -1257,9 +1274,6 @@ msgstr "Eguneratuta: %d."
msgid "created date"
msgstr "Sortuta: %d."
msgid "Untitled"
msgstr "Titulu gabekoa"
msgid "This note does not have geolocation information."
msgstr "Ohar honek ez du geokokapen informaziorik."
@@ -1327,6 +1341,12 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
@@ -1334,6 +1354,10 @@ msgstr ""
msgid "Global zoom percentage"
msgstr "Ezarri aplikazioaren zoomaren ehunekoa"
#, fuzzy
msgid "Editor font size"
msgstr "Oharra editatu."
msgid "Editor font family"
msgstr ""
@@ -1458,6 +1482,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Evernotetik esportatutako fitxategiak"
#, fuzzy
msgid "Json Export Directory"
msgstr "Evernotetik esportatutako fitxategiak"
msgid "Directory"
msgstr ""
@@ -1530,6 +1558,12 @@ msgstr "Hurrengo alarmak"
msgid "On %s: %s"
msgstr "On %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Ez dago oharrik. Sortu bat (+) botoian klik eginaz."
@@ -1575,10 +1609,6 @@ msgstr "Baieztatu"
msgid "Cancel synchronisation"
msgstr "Sinkronizazioa utzi"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Itemak eskuratuta: %d%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Bertan behera uzten... itxaron, mesedez."
@@ -1689,6 +1719,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Irudi formatua ez onartua: %s"
#, fuzzy
msgid "Take photo"
msgstr "Argazkia erantsi"
msgid "Attach photo"
msgstr "Argazkia erantsi"
@@ -1713,6 +1747,9 @@ msgstr "Erakutsi metadatuak"
msgid "View on map"
msgstr "Ikusi mapan"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Ezabatu koadernoa"
@@ -1735,6 +1772,10 @@ msgstr "Oraindik ez duzu koadernorik. Sortu bat (+) botoian sakatuta."
msgid "Welcome"
msgstr "Ongi etorri!"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Egoera: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Dagoeneko bada koaderno bat izen horrekin: \"%s\""

View File

@@ -458,6 +458,9 @@ msgstr "Impossible d'initialiser la synchronisation."
msgid "Starting synchronisation..."
msgstr "Commencement de la synchronisation..."
msgid "Downloading resources..."
msgstr "Téléchargement des ressources..."
msgid "Cancelling... Please wait."
msgstr "Annulation... Veuillez attendre."
@@ -645,6 +648,9 @@ msgstr "Ouvrir dans un éditeur externe"
msgid "Search in all the notes"
msgstr "Chercher dans toutes les notes"
msgid "Search in current note"
msgstr "Chercher dans la note en cours"
msgid "View"
msgstr "Affichage"
@@ -981,6 +987,9 @@ msgstr "Lieu"
msgid "URL"
msgstr "URL"
msgid "Note properties"
msgstr "Propriétés de la note"
msgid "Open..."
msgstr "Ouvrir..."
@@ -997,6 +1006,9 @@ msgstr "Copier le chemin"
msgid "Copy Link Address"
msgstr "Copier l'adresse du lien"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr "Cette pièce jointe n'est pas téléchargée ou pas encore déchiffrée"
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Lien ou message non géré : %s"
@@ -1034,9 +1046,6 @@ msgstr "Régler alarme"
msgid "In: %s"
msgstr "Dans : %s"
msgid "Note properties"
msgstr "Propriétés de la note"
msgid "Hyperlink"
msgstr "Lien"
@@ -1113,6 +1122,14 @@ msgstr "Synchroniser"
msgid "Notebooks"
msgstr "Carnets"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Déchiffrement des objets : %d/%d"
#, javascript-format
msgid "Fetching resources: %d"
msgstr "Tél. ressources : %d"
msgid "Please select where the sync status should be exported to"
msgstr ""
"Veuillez sélectionner un répertoire ou exporter l'état de la synchronisation"
@@ -1158,6 +1175,9 @@ msgstr ""
"Impossible de rafraîchir la connexion à OneDrive. Démarrez la "
"synchronisation à nouveau pour corriger le problème."
msgid "Untitled"
msgstr "Sans titre"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1205,10 +1225,6 @@ msgstr "Objets distants supprimés : %d."
msgid "Fetched items: %d/%d."
msgstr "Téléchargés : %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "État : %s."
msgid "Cancelling..."
msgstr "Annulation..."
@@ -1255,9 +1271,6 @@ msgstr "date de modification"
msgid "created date"
msgstr "date de création"
msgid "Untitled"
msgstr "Sans titre"
msgid "This note does not have geolocation information."
msgstr "Cette note n'a pas d'information d'emplacement."
@@ -1320,12 +1333,24 @@ msgstr "Afficher l'icône dans la zone de notifications"
msgid "Note: Does not work in all desktop environments."
msgstr "Note : Ne fonctionne pas dans tous les environnements de bureau."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
"Cela permettra à Joplin de s'exécuter en arrière-plan. Il est recommandé "
"d'activer ce réglage pour que vos notes soient constamment synchronisées, "
"donc réduire le nombre de conflits."
msgid "Start application minimised in the tray icon"
msgstr "Démarrer minimisé dans la zone de notification"
msgid "Global zoom percentage"
msgstr "Niveau de zoom"
msgid "Editor font size"
msgstr "Taille police éditeur"
msgid "Editor font family"
msgstr "Police de l'éditeur"
@@ -1455,6 +1480,9 @@ msgstr "Dossier d'export Joplin"
msgid "Evernote Export File"
msgstr "Fichiers d'export Evernote"
msgid "Json Export Directory"
msgstr "Dossier d'export JSON"
msgid "Directory"
msgstr "Dossier"
@@ -1529,6 +1557,12 @@ msgstr "Alarmes à venir"
msgid "On %s: %s"
msgstr "Le %s : %s"
msgid "Permission to use camera"
msgstr "Permission d'utiliser l'appareil photo"
msgid "Your permission to use your camera is required."
msgstr "Votre permission est requise pour utiliser l'appareil photo"
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Ce carnet ne contient aucune note. Créez-en une en appuyant sur le bouton "
@@ -1574,10 +1608,6 @@ msgstr "Confirmer"
msgid "Cancel synchronisation"
msgstr "Annuler synchronisation"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Déchiffrement des objets : %d/%d"
msgid "Checking... Please wait."
msgstr "Vérification... Veuillez attendre."
@@ -1698,6 +1728,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Type d'image non géré : %s"
msgid "Take photo"
msgstr "Prendre une photo"
msgid "Attach photo"
msgstr "Attacher une photo"
@@ -1722,6 +1755,9 @@ msgstr "Voir métadonnées"
msgid "View on map"
msgstr "Voir sur carte"
msgid "Go to source URL"
msgstr "Aller à l'URL source"
msgid "Delete notebook"
msgstr "Supprimer le carnet"
@@ -1746,6 +1782,9 @@ msgstr ""
msgid "Welcome"
msgstr "Bienvenue"
#~ msgid "State: %s."
#~ msgstr "État : %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Un carnet avec ce titre existe déjà : \"%s\""

View File

@@ -452,6 +452,9 @@ msgstr "Non é posíbel iniciar o sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronización..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Cancelando... Agarde."
@@ -639,6 +642,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Buscar en todas as notas"
#, fuzzy
msgid "Search in current note"
msgstr "Buscar en todas as notas"
msgid "View"
msgstr "Vista"
@@ -961,6 +968,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Abrir…"
@@ -977,6 +987,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Ligazón ou mensaxe incompatíbeis: %s"
@@ -1014,9 +1027,6 @@ msgstr "Estabelecer alarma"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1095,6 +1105,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Cadernos"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elementos obtidos: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccione onde exportar o estado da sincronización"
@@ -1139,6 +1157,9 @@ msgstr ""
"Non é posíbel actualizar o «token»: faltan datos da autenticación. Iniciar a "
"sincronización de novo pode arranxar o problema."
msgid "Untitled"
msgstr "Sen título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1186,10 +1207,6 @@ msgstr "Elementos remotos borrados: %d."
msgid "Fetched items: %d/%d."
msgstr "Elementos obtidos: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: %s."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1240,9 +1257,6 @@ msgstr "Actualizado: %d."
msgid "created date"
msgstr "Creado: %d."
msgid "Untitled"
msgstr "Sen título"
msgid "This note does not have geolocation information."
msgstr "Esta nota non ten información de xeolocalización."
@@ -1306,12 +1320,22 @@ msgstr "Mostrar a icona na bandexa"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Porcentaxe de ampliación"
#, fuzzy
msgid "Editor font size"
msgstr "Familia de tipos de letra do editor"
msgid "Editor font family"
msgstr "Familia de tipos de letra do editor"
@@ -1434,6 +1458,10 @@ msgstr "Cartafol de exportación do Joplin"
msgid "Evernote Export File"
msgstr "Ficheiro de exportación de Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Cartafol de exportación do Joplin"
msgid "Directory"
msgstr "Cartafol"
@@ -1508,6 +1536,12 @@ msgstr "Alarmas próximas"
msgid "On %s: %s"
msgstr "En %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Non ten notas actualmente. Cree unha premendo no botón (+)."
@@ -1553,10 +1587,6 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronización"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elementos obtidos: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancelando... Agarde."
@@ -1667,6 +1697,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipo de imaxe incompatíbel: %s"
#, fuzzy
msgid "Take photo"
msgstr "Anexar foto"
msgid "Attach photo"
msgstr "Anexar foto"
@@ -1691,6 +1725,9 @@ msgstr "Mostrar metadatos"
msgid "View on map"
msgstr "Ver no mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Eliminar caderno"
@@ -1713,5 +1750,8 @@ msgstr "Non ten cadernos actualmente. Cree un premendo no botón (+)."
msgid "Welcome"
msgstr "Benvido/a"
#~ msgid "State: %s."
#~ msgstr "Estado: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Xa existe un caderno con ese título: «%s»"

View File

@@ -455,6 +455,9 @@ msgstr "Ne mogu započeti sinkronizaciju."
msgid "Starting synchronisation..."
msgstr "Započinjem sinkronizaciju..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Prekidam... Pričekaj."
@@ -644,6 +647,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Pretraži u svim bilješkama"
#, fuzzy
msgid "Search in current note"
msgstr "Pretraži u svim bilješkama"
msgid "View"
msgstr ""
@@ -960,6 +967,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -977,6 +987,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodržana poveznica ili poruka: %s"
@@ -1012,9 +1025,6 @@ msgstr "Postavi upozorenje"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1095,6 +1105,14 @@ msgstr "Sinkroniziraj"
msgid "Notebooks"
msgstr "Bilježnice"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Stvorene lokalne stavke: %d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Resursi: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Odaberi lokaciju za izvoz statusa sinkronizacije"
@@ -1137,6 +1155,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr "Nedostaju podaci za ovjeru. Pokušaj ponovo započeti sinkronizaciju."
msgid "Untitled"
msgstr "Nenaslovljen"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1184,10 +1205,6 @@ msgstr "Obrisane udaljene stavke: %d."
msgid "Fetched items: %d/%d."
msgstr "Stvorene lokalne stavke: %d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Stanje: \"%s\"."
msgid "Cancelling..."
msgstr "Prekidam..."
@@ -1239,9 +1256,6 @@ msgstr "Ažurirano: %d."
msgid "created date"
msgstr "Stvoreno: %d."
msgid "Untitled"
msgstr "Nenaslovljen"
msgid "This note does not have geolocation information."
msgstr "Ova bilješka nema geolokacijske informacije."
@@ -1310,12 +1324,22 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
#, fuzzy
msgid "Editor font size"
msgstr "Uredi bilješku."
msgid "Editor font family"
msgstr ""
@@ -1435,6 +1459,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Evernote izvozne datoteke"
#, fuzzy
msgid "Json Export Directory"
msgstr "Evernote izvozne datoteke"
msgid "Directory"
msgstr ""
@@ -1505,6 +1533,12 @@ msgstr "Nadolazeća upozorenja"
msgid "On %s: %s"
msgstr "On %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Trenutno nema bilješki. Stvori novu klikom na (+) gumb."
@@ -1550,10 +1584,6 @@ msgstr "Potvrdi"
msgid "Cancel synchronisation"
msgstr "Prekini sinkronizaciju"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Stvorene lokalne stavke: %d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Prekidam... Pričekaj."
@@ -1665,6 +1695,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodržana vrsta slike: %s"
#, fuzzy
msgid "Take photo"
msgstr "Priloži sliku"
msgid "Attach photo"
msgstr "Priloži sliku"
@@ -1689,6 +1723,9 @@ msgstr "Prikaži metapodatke"
msgid "View on map"
msgstr "Vidi na karti"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Obriši bilježnicu"
@@ -1711,6 +1748,10 @@ msgstr "Trenutno nemaš nijednu bilježnicu. Stvori novu klikom na (+) gumb."
msgid "Welcome"
msgstr "Dobro došli"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Stanje: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Bilježnica s ovim naslovom već postoji: \"%s\""

View File

@@ -461,6 +461,9 @@ msgstr "Non è possibile inizializzare il sincronizzatore."
msgid "Starting synchronisation..."
msgstr "Inizio sincronizzazione..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Cancellazione... Attendere per favore."
@@ -645,6 +648,10 @@ msgstr "Modifica in un editor esterno"
msgid "Search in all the notes"
msgstr "Cerca in tutte le note"
#, fuzzy
msgid "Search in current note"
msgstr "Cerca in tutte le note"
msgid "View"
msgstr "Vista"
@@ -977,6 +984,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Apri ..."
@@ -993,6 +1003,9 @@ msgstr "Copia il percorso negli appunti"
msgid "Copy Link Address"
msgstr "Copia l'indirizzo del link"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Link o Messaggio non supportato: %s"
@@ -1030,9 +1043,6 @@ msgstr "Imposta Allarme"
msgid "In: %s"
msgstr "In: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Collegamento ipertestuale"
@@ -1110,6 +1120,14 @@ msgstr "Sincronizza"
msgid "Notebooks"
msgstr "Taccuini"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Decrittografia Elementi: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Risorse: %d."
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -1154,6 +1172,9 @@ msgstr ""
"Non è possibile aggiornare il token. mancano i dati di autenticazione. "
"Ricominciare la sincronizzazione da capo potrebbe risolvere il problema."
msgid "Untitled"
msgstr "Senza titolo"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1201,10 +1222,6 @@ msgstr "Elementi remoti eliminati: %d."
msgid "Fetched items: %d/%d."
msgstr "Elementi recuperati: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Stato: %s."
msgid "Cancelling..."
msgstr "Cancellazione..."
@@ -1251,9 +1268,6 @@ msgstr "Data di aggiornamento"
msgid "created date"
msgstr "Data di creazione"
msgid "Untitled"
msgstr "Senza titolo"
msgid "This note does not have geolocation information."
msgstr "Questa nota non ha informazione sulla geolocalizzazione."
@@ -1316,12 +1330,22 @@ msgstr "Visualizza tray icon"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: non funziona in tutti gli ambienti desktop."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Percentuale di zoom globale"
#, fuzzy
msgid "Editor font size"
msgstr "Editor Famiglia Caratteri"
msgid "Editor font family"
msgstr "Editor Famiglia Caratteri"
@@ -1448,6 +1472,10 @@ msgstr "Cartella di esportazione di Joplin"
msgid "Evernote Export File"
msgstr "Esporta files di Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Cartella di esportazione di Joplin"
msgid "Directory"
msgstr "Cartella"
@@ -1522,6 +1550,12 @@ msgstr "Avviso imminente"
msgid "On %s: %s"
msgstr "Su %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Al momento non ci sono note. Creane una cliccando sul bottone (+)."
@@ -1566,10 +1600,6 @@ msgstr "Conferma"
msgid "Cancel synchronisation"
msgstr "Cancella la sincronizzazione"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Decrittografia Elementi: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancellazione... Attendere per favore."
@@ -1688,6 +1718,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipo di immagine non supportata: %s"
#, fuzzy
msgid "Take photo"
msgstr "Allega foto"
msgid "Attach photo"
msgstr "Allega foto"
@@ -1712,6 +1746,9 @@ msgstr "Mostra i metadati"
msgid "View on map"
msgstr "Guarda sulla mappa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Cancella Taccuino"
@@ -1735,6 +1772,9 @@ msgstr ""
msgid "Welcome"
msgstr "Benvenuto"
#~ msgid "State: %s."
#~ msgstr "Stato: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Esiste già un Taccuino col titolo \"%s\""

View File

@@ -445,6 +445,9 @@ msgstr "同期プロセスを初期化できませんでした。"
msgid "Starting synchronisation..."
msgstr "同期を開始中..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "中止中...お待ちください。"
@@ -634,6 +637,10 @@ msgstr "外部エディターで編集"
msgid "Search in all the notes"
msgstr "すべてのノートを検索"
#, fuzzy
msgid "Search in current note"
msgstr "すべてのノートを検索"
msgid "View"
msgstr "表示"
@@ -961,6 +968,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "開く..."
@@ -977,6 +987,9 @@ msgstr "クリップボードにパスを保存"
msgid "Copy Link Address"
msgstr "リンクアドレスをコピー"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "次のリンクまたはメッセージはサポートしていません: %s"
@@ -1014,9 +1027,6 @@ msgstr "アラームをセット"
msgid "In: %s"
msgstr "内: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "ハイパーリンク"
@@ -1093,6 +1103,14 @@ msgstr "同期"
msgid "Notebooks"
msgstr "ノートブック"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "復号中のアイテム: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "リソース: %d."
msgid "Please select where the sync status should be exported to"
msgstr "同期状況の出力先を選択してください"
@@ -1137,6 +1155,9 @@ msgstr ""
"トークンの更新ができませんでした。認証データがありません。同期を再度行うこと"
"で解決することがあります。"
msgid "Untitled"
msgstr "名称未設定"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1184,10 +1205,6 @@ msgstr "リモートアイテムの削除: %d."
msgid "Fetched items: %d/%d."
msgstr "取得したアイテム: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "状態: \"%s\"."
msgid "Cancelling..."
msgstr "中止中..."
@@ -1236,9 +1253,6 @@ msgstr "アップデート日"
msgid "created date"
msgstr "作成日"
msgid "Untitled"
msgstr "名称未設定"
msgid "This note does not have geolocation information."
msgstr "このノートには位置情報がありません。"
@@ -1301,12 +1315,22 @@ msgstr "トレイアイコンの表示"
msgid "Note: Does not work in all desktop environments."
msgstr "注意: すべてのデスクトップ環境で動作するわけではありません。"
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr "アプリケーションをトレイアンコンで最小化して起動"
msgid "Global zoom percentage"
msgstr "全体ズームの割合"
#, fuzzy
msgid "Editor font size"
msgstr "エディターのフォントファミリー"
msgid "Editor font family"
msgstr "エディターのフォントファミリー"
@@ -1433,6 +1457,10 @@ msgstr "Joplin エクスポートディレクトリ"
msgid "Evernote Export File"
msgstr "Evernote エクスポートファイル"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin エクスポートディレクトリ"
msgid "Directory"
msgstr "ディレクトリ"
@@ -1507,6 +1535,12 @@ msgstr "直近のアラーム"
msgid "On %s: %s"
msgstr "日時 %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "ノートがありません。(+)ボタンを押して新しいノートを作成してください。"
@@ -1551,10 +1585,6 @@ msgstr "確認"
msgid "Cancel synchronisation"
msgstr "同期の中止"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "復号中のアイテム: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "中止中...お待ちください。"
@@ -1668,6 +1698,10 @@ msgstr "Joplinモバイルアプリは次のタイプのリンクをまだサポ
msgid "Unsupported image type: %s"
msgstr "サポートされていない画像の形式: %s"
#, fuzzy
msgid "Take photo"
msgstr "写真を添付"
msgid "Attach photo"
msgstr "写真を添付"
@@ -1692,6 +1726,9 @@ msgstr "メタデータを表示"
msgid "View on map"
msgstr "地図上に表示"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "ノートブックを削除"
@@ -1716,6 +1753,9 @@ msgstr ""
msgid "Welcome"
msgstr "ようこそ"
#~ msgid "State: %s."
#~ msgstr "状態: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "次の名前のノートブックはすでに存在しています: \"%s\""

View File

@@ -408,6 +408,9 @@ msgstr ""
msgid "Starting synchronisation..."
msgstr ""
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr ""
@@ -570,6 +573,9 @@ msgstr ""
msgid "Search in all the notes"
msgstr ""
msgid "Search in current note"
msgstr ""
msgid "View"
msgstr ""
@@ -874,6 +880,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -890,6 +899,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr ""
@@ -925,9 +937,6 @@ msgstr ""
msgid "In: %s"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1004,6 +1013,14 @@ msgstr ""
msgid "Notebooks"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
#, javascript-format
msgid "Fetching resources: %d"
msgstr ""
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -1046,6 +1063,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr ""
msgid "Untitled"
msgstr ""
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1087,10 +1107,6 @@ msgstr ""
msgid "Fetched items: %d/%d."
msgstr ""
#, javascript-format
msgid "State: %s."
msgstr ""
msgid "Cancelling..."
msgstr ""
@@ -1137,9 +1153,6 @@ msgstr ""
msgid "created date"
msgstr ""
msgid "Untitled"
msgstr ""
msgid "This note does not have geolocation information."
msgstr ""
@@ -1202,12 +1215,21 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
msgid "Editor font size"
msgstr ""
msgid "Editor font family"
msgstr ""
@@ -1319,6 +1341,9 @@ msgstr ""
msgid "Evernote Export File"
msgstr ""
msgid "Json Export Directory"
msgstr ""
msgid "Directory"
msgstr ""
@@ -1388,6 +1413,12 @@ msgstr ""
msgid "On %s: %s"
msgstr ""
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
@@ -1431,10 +1462,6 @@ msgstr ""
msgid "Cancel synchronisation"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
msgid "Checking... Please wait."
msgstr ""
@@ -1541,6 +1568,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr ""
msgid "Take photo"
msgstr ""
msgid "Attach photo"
msgstr ""
@@ -1565,6 +1595,9 @@ msgstr ""
msgid "View on map"
msgstr ""
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr ""

View File

@@ -446,6 +446,9 @@ msgstr "동기화를 시작할 수 없습니다."
msgid "Starting synchronisation..."
msgstr "동기화를 시작합니다..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "취소하는 중입니다... 잠시만 기다리세요."
@@ -631,6 +634,10 @@ msgstr "외부 편집기에서 편집하기"
msgid "Search in all the notes"
msgstr "모든 노트에서 검색"
#, fuzzy
msgid "Search in current note"
msgstr "모든 노트에서 검색"
msgid "View"
msgstr "보기"
@@ -955,6 +962,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "열기..."
@@ -971,6 +981,9 @@ msgstr "경로를 클립보드에 복사"
msgid "Copy Link Address"
msgstr "링크 주소 복사"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "지원하지 않는 링크 또는 메세지: %s"
@@ -1008,9 +1021,6 @@ msgstr "알람 설정"
msgid "In: %s"
msgstr "내부: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "하이퍼링크"
@@ -1087,6 +1097,14 @@ msgstr "동기화"
msgid "Notebooks"
msgstr "노트북"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "복호화 항목: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "리소스: %d."
msgid "Please select where the sync status should be exported to"
msgstr "동기화 상태를 내보낼 대상을 선택하세요"
@@ -1131,6 +1149,9 @@ msgstr ""
"토큰 새로고침 불가: 인증 데이터를 찾을 수 없습니다. 동기화를 다시 시도하면 문"
"제가 해결될수도 있습니다."
msgid "Untitled"
msgstr "제목 없음"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1178,10 +1199,6 @@ msgstr "원격 항목 삭제됨: %d."
msgid "Fetched items: %d/%d."
msgstr "가져온 항목: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "상태: %s."
msgid "Cancelling..."
msgstr "취소하는 중..."
@@ -1228,9 +1245,6 @@ msgstr "업데이트된 날짜"
msgid "created date"
msgstr "만들어진 날짜"
msgid "Untitled"
msgstr "제목 없음"
msgid "This note does not have geolocation information."
msgstr "이 노트는 지리적 위치 정보를 포함하고 있지 않습니다."
@@ -1293,12 +1307,22 @@ msgstr "트레이 아이콘 표시"
msgid "Note: Does not work in all desktop environments."
msgstr "참고사항: 모든 데스크탑 환경에서 작동하는 것은 아닙니다."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "전체적 확대 비율"
#, fuzzy
msgid "Editor font size"
msgstr "편집기 글꼴 집합"
msgid "Editor font family"
msgstr "편집기 글꼴 집합"
@@ -1423,6 +1447,10 @@ msgstr "조플린 내보내기 폴더"
msgid "Evernote Export File"
msgstr "에버노트 내보내기 파일"
#, fuzzy
msgid "Json Export Directory"
msgstr "조플린 내보내기 폴더"
msgid "Directory"
msgstr "폴더"
@@ -1497,6 +1525,12 @@ msgstr "다가오는 예정된 알람"
msgid "On %s: %s"
msgstr "%s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "노트가 없습니다. (+) 버튼을 선택해 새로 만드세요."
@@ -1541,10 +1575,6 @@ msgstr "확인"
msgid "Cancel synchronisation"
msgstr "동기화 취소"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "복호화 항목: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "취소하는 중입니다... 잠시만 기다리세요."
@@ -1658,6 +1688,10 @@ msgstr "조플린 모바일 앱은 현재 해당 형식의 링크를 지원하
msgid "Unsupported image type: %s"
msgstr "지원하지 않는 이미지 형식: %s"
#, fuzzy
msgid "Take photo"
msgstr "사진 첨부"
msgid "Attach photo"
msgstr "사진 첨부"
@@ -1682,6 +1716,9 @@ msgstr "메타데이터 표시"
msgid "View on map"
msgstr "지도에 표시"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "노트북 삭제"
@@ -1704,5 +1741,8 @@ msgstr "노트북이 없습니다. (+) 버튼을 눌러 새로 만드세요."
msgid "Welcome"
msgstr "환영합니다"
#~ msgid "State: %s."
#~ msgstr "상태: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "같은 제목의 노트북이 이미 있습니다: \"%s\""

File diff suppressed because it is too large Load Diff

View File

@@ -456,6 +456,9 @@ msgstr "Kan de synchronisatie niet starten."
msgid "Starting synchronisation..."
msgstr "Synchronisatie starten..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Annuleren.. Even geduld."
@@ -649,6 +652,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Zoek in alle notities"
#, fuzzy
msgid "Search in current note"
msgstr "Zoek in alle notities"
msgid "View"
msgstr ""
@@ -977,6 +984,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -994,6 +1004,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Link of bericht \"%s\" wordt niet ondersteund"
@@ -1029,9 +1042,6 @@ msgstr "Zet melding"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1112,6 +1122,14 @@ msgstr "Synchroniseer"
msgid "Notebooks"
msgstr "Notitieboeken"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Opgehaalde items: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Middelen: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Selecteer waar de synchronisatie status naar geëxporteerd moet worden"
@@ -1157,6 +1175,9 @@ msgstr ""
"Kan token niet vernieuwen: authenticatiedata ontbreekt. Herstarten van de "
"synchronisatie kan het probleem eventueel oplossen. "
msgid "Untitled"
msgstr "Untitled"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1204,10 +1225,6 @@ msgstr "Verwijderde remote items: %d."
msgid "Fetched items: %d/%d."
msgstr "Opgehaalde items: %d/%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Status: \"%s\""
msgid "Cancelling..."
msgstr "Annuleren..."
@@ -1260,9 +1277,6 @@ msgstr "Bijgewerkt: %d."
msgid "created date"
msgstr "Aangemaakt: %d."
msgid "Untitled"
msgstr "Untitled"
msgid "This note does not have geolocation information."
msgstr "Deze notitie bevat geen geo-locatie informatie."
@@ -1330,12 +1344,22 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
#, fuzzy
msgid "Editor font size"
msgstr "Bewerk notitie."
msgid "Editor font family"
msgstr ""
@@ -1458,6 +1482,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Exporteer Evernote bestanden"
#, fuzzy
msgid "Json Export Directory"
msgstr "Exporteer Evernote bestanden"
msgid "Directory"
msgstr ""
@@ -1531,6 +1559,12 @@ msgstr "Meldingen"
msgid "On %s: %s"
msgstr "Op %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Er zijn momenteel geen notities. Maak een notitie door op (+) te klikken."
@@ -1577,10 +1611,6 @@ msgstr "Bevestig"
msgid "Cancel synchronisation"
msgstr "Annuleer synchronisatie"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Opgehaalde items: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Annuleren.. Even geduld."
@@ -1691,6 +1721,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Afbeeldingstype %s wordt niet ondersteund"
#, fuzzy
msgid "Take photo"
msgstr "Voeg foto toe"
msgid "Attach photo"
msgstr "Voeg foto toe"
@@ -1715,6 +1749,9 @@ msgstr "Toon metadata"
msgid "View on map"
msgstr "Toon op de kaart"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Verwijder notitieboek"
@@ -1739,6 +1776,10 @@ msgstr ""
msgid "Welcome"
msgstr "Welkom"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Status: \"%s\""
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Er bestaat al een notitieboek met \"%s\" als titel"

View File

@@ -457,6 +457,9 @@ msgstr "De synchronisatie kan niet worden geïnitaliseerd."
msgid "Starting synchronisation..."
msgstr "Bezig met starten van synchronisatie..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Bezig met annuleren... Even geduld."
@@ -648,6 +651,10 @@ msgstr "Bewerken in externe bewerker"
msgid "Search in all the notes"
msgstr "Alle notities doorzoeken"
#, fuzzy
msgid "Search in current note"
msgstr "Alle notities doorzoeken"
msgid "View"
msgstr "Beeld"
@@ -983,6 +990,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Openen..."
@@ -999,6 +1009,9 @@ msgstr "Pad kopiëren naar klembord"
msgid "Copy Link Address"
msgstr "Linkadres kopiëren"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Niet-ondersteunde link of bericht: %s"
@@ -1036,9 +1049,6 @@ msgstr "Alarm instellen"
msgid "In: %s"
msgstr "In: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Hyperlink"
@@ -1115,6 +1125,14 @@ msgstr "Synchroniseren"
msgid "Notebooks"
msgstr "Notitieboeken"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Bezig met ontsleutelen van items: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Bronnen: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Kies waar de synchronisatiestatus naar moet worden geëxporteerd"
@@ -1159,6 +1177,9 @@ msgstr ""
"Kan toegangssleutel niet verversen: de authenticatiegegevens ontbreken. "
"Probeer om de synchronisatie opnieuw te starten."
msgid "Untitled"
msgstr "Naamloos"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1206,10 +1227,6 @@ msgstr "Externe items verwijderd: %d."
msgid "Fetched items: %d/%d."
msgstr "Items opgehaald: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Status: %s."
msgid "Cancelling..."
msgstr "Bezig met annuleren..."
@@ -1256,9 +1273,6 @@ msgstr "bijgewerkt op"
msgid "created date"
msgstr "gecreëerd op"
msgid "Untitled"
msgstr "Naamloos"
msgid "This note does not have geolocation information."
msgstr "Deze notitie bevat geen locatie-informatie."
@@ -1321,12 +1335,22 @@ msgstr "Systeemvakpictogram tonen"
msgid "Note: Does not work in all desktop environments."
msgstr "Let op: dit werkt niet in alle werkomgevingen."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Globaal zoompercentage"
#, fuzzy
msgid "Editor font size"
msgstr "Lettertype van bewerker"
msgid "Editor font family"
msgstr "Lettertype van bewerker"
@@ -1454,6 +1478,10 @@ msgstr "Joplin-exportmap"
msgid "Evernote Export File"
msgstr "Evernote-exportbestand"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin-exportmap"
msgid "Directory"
msgstr "Map"
@@ -1530,6 +1558,12 @@ msgstr "Aankomende alarmen"
msgid "On %s: %s"
msgstr "Op %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Er zijn momenteel geen notities. Creëer een notitie door te drukken op de "
@@ -1576,10 +1610,6 @@ msgstr "Bevestigen"
msgid "Cancel synchronisation"
msgstr "Synchronisatie annuleren"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Bezig met ontsleutelen van items: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Bezig met annuleren... Even geduld."
@@ -1694,6 +1724,10 @@ msgstr "De mobiele Joplin-app ondersteunt momenteel niet dit soort links: %s"
msgid "Unsupported image type: %s"
msgstr "Niet-ondersteunde afbeeldingssoort: %s"
#, fuzzy
msgid "Take photo"
msgstr "Foto bijvoegen"
msgid "Attach photo"
msgstr "Foto bijvoegen"
@@ -1718,6 +1752,9 @@ msgstr "Metagegevens tonen"
msgid "View on map"
msgstr "Tonen op kaart"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Notitieboek verwijderen"
@@ -1742,5 +1779,8 @@ msgstr ""
msgid "Welcome"
msgstr "Welkom"
#~ msgid "State: %s."
#~ msgstr "Status: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Er bestaat al een notitieboek met deze titel: \"%s\""

View File

@@ -1,7 +1,8 @@
# SOME DESCRIPTIVE TITLE.
# pt_BR locale strings - Joplin.
# Copyright (C) YEAR Laurent Cozic
# This file is distributed under the same license as the Joplin-CLI package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Updated by Renato Xavier da Silveira Rosa <renatoxsr@gmail.com>, 2018.
#
msgid ""
msgstr ""
@@ -13,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.7\n"
"X-Generator: Poedit 2.2\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "To delete a tag, untag the associated notes."
@@ -147,7 +148,7 @@ msgid "Completed decryption."
msgstr "Decriptação completada."
msgid "Enabled"
msgstr "Desabilitado"
msgstr "Habilitado"
msgid "Disabled"
msgstr "Desabilitado"
@@ -454,10 +455,12 @@ msgstr "Não é possível inicializar o sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronização..."
msgid "Downloading resources..."
msgstr "Baixando os recursos..."
msgid "Cancelling... Please wait."
msgstr "Cancelando... Aguarde."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
@@ -465,7 +468,8 @@ msgid ""
msgstr ""
"<tag-command> pode ser \"add\", \"remove\" ou \"list\" para atribuir ou "
"remover [tag] de [nota], ou para listar as notas associadas a [tag]. O "
"comando `taglist` pode ser usado para listar todas as tags."
"comando `tag list` pode ser usado para listar todas as tags (use -l para "
"opção longa)."
#, javascript-format
msgid "Invalid command: \"%s\""
@@ -625,9 +629,8 @@ msgstr "Cortar"
msgid "Paste"
msgstr "Colar"
#, fuzzy
msgid "Select all"
msgstr "Selecionar data"
msgstr "Selecionar tudo"
msgid "Bold"
msgstr "Negrito"
@@ -644,6 +647,10 @@ msgstr "Editar com editor externo"
msgid "Search in all the notes"
msgstr "Pesquisar em todas as notas"
#, fuzzy
msgid "Search in current note"
msgstr "Pesquisar em todas as notas"
msgid "View"
msgstr "Visualizar"
@@ -713,7 +720,7 @@ msgid "No"
msgstr "Não"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgstr "Token foi copiado para a \\u00e1rea de transfer\\u00eancia!"
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -725,7 +732,7 @@ msgstr "Status: Iniciado, na porta %d"
#, javascript-format
msgid "Status: %s"
msgstr "Status: \"%s\"."
msgstr "Status: %s"
msgid "Disable Web Clipper Service"
msgstr "Desabilitar serviço Web Clipper"
@@ -764,20 +771,21 @@ msgstr "Passo 2: Instalar a extensão"
msgid "Download and install the relevant extension for your browser:"
msgstr "Baixe e instale a extensão relevante para seu browser:"
#, fuzzy
msgid "Advanced options"
msgstr "Mostrar opções avançadas"
msgid "Authorisation token:"
msgstr ""
msgstr "Token de autoriza\\u00e7\\u00e3o:"
msgid "Copy token"
msgstr ""
msgstr "Copira token"
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
"Esse token de autoriza\\u00e7\\u00e3o só é necess\\u00e1rio para permitir "
"que aplicativos de terceiros acessem o Joplin."
msgid "Check synchronisation configuration"
msgstr "Verificar a configuração da sincronização"
@@ -943,13 +951,11 @@ msgstr "%s - Copiar"
msgid "Switch between note and to-do type"
msgstr "Alternar entre os tipos Nota e Tarefa"
#, fuzzy
msgid "Switch to note type"
msgstr "Alternar entre os tipos Nota e Tarefa"
msgstr "Alternar para o tipo Nota"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Alternar entre os tipos Nota e Tarefa"
msgstr "Alternar para o tipo Tarefa"
msgid "Copy Markdown link"
msgstr "Copiar link de Markdown"
@@ -968,10 +974,13 @@ msgid ""
msgstr "Atualmente, não há cadernos. Crie um, clicando em \"Novo caderno\"."
msgid "Location"
msgstr ""
msgstr "Localização"
msgid "URL"
msgstr ""
msgstr "URL"
msgid "Note properties"
msgstr "Propriedades da nota"
msgid "Open..."
msgstr "Abrir..."
@@ -989,6 +998,9 @@ msgstr "Copiar caminho para a área de transferência"
msgid "Copy Link Address"
msgstr "Copiar endereço do link"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr "O anexo ainda não foi baixado ou decriptado."
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Link ou mensagem não suportada: %s"
@@ -1026,9 +1038,6 @@ msgstr "Definir alarme"
msgid "In: %s"
msgstr "Em: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Hiperlink"
@@ -1054,7 +1063,7 @@ msgid "Click to stop external editing"
msgstr "Clique para encerrar edição externa"
msgid "Watching..."
msgstr "Verificando..."
msgstr "Observando alterações..."
msgid "to-do"
msgstr "tarefa"
@@ -1105,6 +1114,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Cadernos"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Decriptando itens: %d/%d"
#, javascript-format
msgid "Fetching resources: %d"
msgstr "Buscando recursos: %d"
msgid "Please select where the sync status should be exported to"
msgstr ""
"Favor selecionar o local para onde o status de sincronia deveria ser "
@@ -1151,6 +1168,9 @@ msgstr ""
"Não é possível atualizar token: faltam dados de autenticação. Iniciar a "
"sincronização novamente pode corrigir o problema."
msgid "Untitled"
msgstr "Sem título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1198,10 +1218,6 @@ msgstr "Itens remotos excluídos: %d."
msgid "Fetched items: %d/%d."
msgstr "Itens pesquisados: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: \"%s\"."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1249,9 +1265,6 @@ msgstr "data de ataualização"
msgid "created date"
msgstr "data de criação"
msgid "Untitled"
msgstr "Sem título"
msgid "This note does not have geolocation information."
msgstr "Esta nota não possui informações de geolocalização."
@@ -1291,7 +1304,7 @@ msgid "Sort notes by"
msgstr "Ordenar notas por"
msgid "Reverse sort order"
msgstr "Inverter ordem de classificação."
msgstr "Inverter ordem de classificação"
msgid "Save geo-location with notes"
msgstr "Salvar geolocalização com notas"
@@ -1312,14 +1325,27 @@ msgid "Show tray icon"
msgstr "Exibir tray icon"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: não funciona em todos os ambientes de desktop"
msgstr "Nota: não funciona em todos os ambientes de desktop."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
"Isso irá permitir que o Joplin continue sendo executado em segundo plano. É "
"recomendado que você habilita essa configuração para que suas notas "
"sejamconstantemente sincronizadas, de modo a reduzir as chances de conflitos."
msgid "Start application minimised in the tray icon"
msgstr ""
msgstr "Iniciar aplicativo minimizado na barra de tarefas"
msgid "Global zoom percentage"
msgstr "Porcentagem global do zoom"
#, fuzzy
msgid "Editor font size"
msgstr "Família de fontes do editor"
msgid "Editor font family"
msgstr "Família de fontes do editor"
@@ -1391,6 +1417,9 @@ msgid ""
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
"Atenção: Se você modificar esse local, tenha certeza de copiar todo o seu "
"conteúdo para lá antes de sincronizar, do contrário todos os seus arquivos "
"serão removidos! Veja o FAQ para mais detalhes: %s"
msgid "Nextcloud username"
msgstr "Usuário da Nextcloud"
@@ -1420,7 +1449,7 @@ msgstr ""
"os certificados, ou caminhos para arquivos cert. Por exemplo, /my/cert_dir, /"
"other/custom.pem. Note que se você fizer mudanças nas configurações de TLS, "
"você tem que salvar as mudanças antes de clicar em \"Verificar a "
"configuração da sincronização\""
"configuração da sincronização\"."
msgid "Ignore TLS certificate errors"
msgstr "Ignorar erros de certificados TLS"
@@ -1431,7 +1460,7 @@ msgstr "Valor da opção inválida: \"%s\". Os valores possíveis são: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgstr "A tag \"%s\" já existe. Escolha um nome diferente."
msgid "Joplin Export File"
msgstr "Arquivo de Exportação do Joplin"
@@ -1445,8 +1474,11 @@ msgstr "Diretório de Exportação do Joplin"
msgid "Evernote Export File"
msgstr "Arquivo de Exportação do Evernote"
msgid "Json Export Directory"
msgstr "Diretório de Exportação JSON"
msgid "Directory"
msgstr "DIretório"
msgstr "Diretório"
#, javascript-format
msgid "Cannot load \"%s\" module for format \"%s\""
@@ -1520,6 +1552,12 @@ msgstr "Próximos alarmes"
msgid "On %s: %s"
msgstr "Em %s: %s"
msgid "Permission to use camera"
msgstr "Permissão para utilizar sua c\\u00e2mera"
msgid "Your permission to use your camera is required."
msgstr "É necessária a sua permissão para utilizar sua c\\u00e2mera."
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Atualmente, não há notas. Crie uma, clicando no botão (+)."
@@ -1548,9 +1586,8 @@ msgstr "Mover %d notas para o caderno \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Pressione para configurar a senha de decriptação."
#, fuzzy
msgid "Clear alarm"
msgstr "Definir alarme"
msgstr "Limpar alarme"
msgid "Save alarm"
msgstr "Salvar alarme"
@@ -1564,26 +1601,22 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronização"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Decriptando itens: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancelando... Aguarde."
msgstr "Verificando... Por favor aguarde."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Verificar a configuração da sincronização"
msgstr "Sucesso! A configuração da sincronização parece estar correta."
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"Erro. Verifique se a URL, nome de usuário, senha, etc., estão corretos e "
"tenha certeza que o destino da sincronização está acessível. O erro "
"reportado foi:"
#, fuzzy
msgid "The application has been authorised!"
msgstr "O aplicativo foi autorizado com sucesso."
msgstr "O aplicativo foi autorizado!"
#, javascript-format
msgid ""
@@ -1593,10 +1626,15 @@ msgid ""
"\n"
"Please try again."
msgstr ""
"Não foi possível autorizar o aplicativo:\n"
"\n"
"%s\n"
"\n"
"Por favor tente novamente."
#, fuzzy, javascript-format
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr "Decriptando itens: %d/%d."
msgstr "Itens decriptados: %s / %s"
msgid "New tags:"
msgstr "Novas tags:"
@@ -1616,8 +1654,8 @@ msgid ""
"- Storage: to allow attaching files to notes and to enable filesystem "
"synchronisation."
msgstr ""
"- Armazenamento: para permitir anexar arquivos a notas, e para permitir a "
"sincronização do sistema de arquivos "
"- Armazenamento: para permitir anexar arquivos a notas e para permitir a "
"sincronização do sistema de arquivos."
msgid "- Camera: to allow taking a picture and attaching it to a note."
msgstr "- Câmera: para permitir tirar fotos e anexar a uma nota."
@@ -1684,6 +1722,10 @@ msgstr "O app mobile do Joplin não suporta, atualmente, esse tipo de link: %s"
msgid "Unsupported image type: %s"
msgstr "Tipo de imagem não suportada: %s"
#, fuzzy
msgid "Take photo"
msgstr "Anexar foto"
msgid "Attach photo"
msgstr "Anexar foto"
@@ -1708,6 +1750,9 @@ msgstr "Exibir metadados"
msgid "View on map"
msgstr "Ver no mapa"
msgid "Go to source URL"
msgstr "Ir para a URL de origem"
msgid "Delete notebook"
msgstr "Excluir caderno"
@@ -1730,6 +1775,9 @@ msgstr "Você não possui cadernos. Crie um clicando no botão (+)."
msgid "Welcome"
msgstr "Bem-vindo"
#~ msgid "State: %s."
#~ msgstr "Estado: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Já existe caderno com este título: \"%s\""

View File

@@ -414,6 +414,9 @@ msgstr "Nu se poate inițializa sincronizatorul."
msgid "Starting synchronisation..."
msgstr "Se începe sincronizarea..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Se anulează... Vă rugăm să așteptați."
@@ -584,6 +587,10 @@ msgstr "Editați într-un editor extern"
msgid "Search in all the notes"
msgstr "Căutați în toate notițele"
#, fuzzy
msgid "Search in current note"
msgstr "Căutați în toate notițele"
msgid "View"
msgstr "Vizualizați"
@@ -891,6 +898,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Deschideți..."
@@ -907,6 +917,9 @@ msgstr "Copiați locația în clipboard"
msgid "Copy Link Address"
msgstr "Copați adresa link-ului"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr ""
@@ -942,9 +955,6 @@ msgstr "Setați alarma"
msgid "In: %s"
msgstr "În: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Hyperlink"
@@ -1021,6 +1031,14 @@ msgstr "Sincronizați"
msgid "Notebooks"
msgstr "Caiete de notițe"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Se decriptează itemi: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Resurse: %d."
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -1063,6 +1081,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr ""
msgid "Untitled"
msgstr "Fără denumire"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1104,10 +1125,6 @@ msgstr ""
msgid "Fetched items: %d/%d."
msgstr ""
#, javascript-format
msgid "State: %s."
msgstr "Statut: %s."
msgid "Cancelling..."
msgstr "Se amână..."
@@ -1154,9 +1171,6 @@ msgstr "data actualizării"
msgid "created date"
msgstr "data creării"
msgid "Untitled"
msgstr "Fără denumire"
msgid "This note does not have geolocation information."
msgstr ""
@@ -1219,12 +1233,22 @@ msgstr "Afișați iconița coșul de gunoi"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
#, fuzzy
msgid "Editor font size"
msgstr "Editează notiță."
msgid "Editor font family"
msgstr ""
@@ -1336,6 +1360,9 @@ msgstr ""
msgid "Evernote Export File"
msgstr ""
msgid "Json Export Directory"
msgstr ""
msgid "Directory"
msgstr ""
@@ -1405,6 +1432,12 @@ msgstr "Alarmele următoare"
msgid "On %s: %s"
msgstr "Pe %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
@@ -1449,10 +1482,6 @@ msgstr "Confirmați"
msgid "Cancel synchronisation"
msgstr "Amânați sincronizarea"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Se decriptează itemi: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Se anulează... Vă rugăm să așteptați."
@@ -1560,6 +1589,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr ""
#, fuzzy
msgid "Take photo"
msgstr "Atașează imagine"
msgid "Attach photo"
msgstr "Atașează imagine"
@@ -1584,6 +1617,9 @@ msgstr "Afișați metadatele"
msgid "View on map"
msgstr "Vizualizați pe hartă"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Ștergeți caiet de notițe"
@@ -1607,5 +1643,8 @@ msgstr ""
msgid "Welcome"
msgstr "Bine ați venit"
#~ msgid "State: %s."
#~ msgstr "Statut: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Un caiet de notițe cu acest titlu există deja: \"%s\""

View File

@@ -456,6 +456,9 @@ msgstr "Не удалось инициировать синхронизацию.
msgid "Starting synchronisation..."
msgstr "Начало синхронизации..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Отмена... Пожалуйста, ожидайте."
@@ -646,6 +649,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Поиск во всех заметках"
#, fuzzy
msgid "Search in current note"
msgstr "Поиск во всех заметках"
msgid "View"
msgstr "Вид"
@@ -971,6 +978,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Открыть..."
@@ -987,6 +997,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Неподдерживаемая ссыка или сообщение: %s"
@@ -1024,9 +1037,6 @@ msgstr "Установить напоминание"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1105,6 +1115,14 @@ msgstr "Синхронизировать"
msgid "Notebooks"
msgstr "Блокноты"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Получено элементов: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Ресурсов: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Выберите, куда должен быть экспортирован статус синхронизации"
@@ -1149,6 +1167,9 @@ msgstr ""
"Не удалось обновить токен: отсутствуют данные аутентификации. Повторный "
"запуск синхронизации может решить проблему."
msgid "Untitled"
msgstr "Без имени"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1196,10 +1217,6 @@ msgstr "Удалено удалённых элементов: %d."
msgid "Fetched items: %d/%d."
msgstr "Получено элементов: %d/%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Статус: «%s»."
msgid "Cancelling..."
msgstr "Отмена..."
@@ -1250,9 +1267,6 @@ msgstr "Обновлено: %d."
msgid "created date"
msgstr "Создано: %d."
msgid "Untitled"
msgstr "Без имени"
msgid "This note does not have geolocation information."
msgstr "Эта заметка не содержит информации о геолокации."
@@ -1316,12 +1330,22 @@ msgstr "Показывать иконку в панели задач"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Глобальный масштаб в процентах"
#, fuzzy
msgid "Editor font size"
msgstr "Семейство шрифтов редактора"
msgid "Editor font family"
msgstr "Семейство шрифтов редактора"
@@ -1444,6 +1468,10 @@ msgstr "Папка экспорта Joplin"
msgid "Evernote Export File"
msgstr "Файл экспорта Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Папка экспорта Joplin"
msgid "Directory"
msgstr "Директория"
@@ -1519,6 +1547,12 @@ msgstr "Грядущие напоминания"
msgid "On %s: %s"
msgstr "В %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Сейчас здесь нет заметок. Создаёте новую, нажав кнопку (+)."
@@ -1564,10 +1598,6 @@ msgstr "Подтвердить"
msgid "Cancel synchronisation"
msgstr "Отменить синхронизацию"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Получено элементов: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "Отмена... Пожалуйста, ожидайте."
@@ -1678,6 +1708,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Неподдерживаемый формат изображения: %s"
#, fuzzy
msgid "Take photo"
msgstr "Прикрепить фото"
msgid "Attach photo"
msgstr "Прикрепить фото"
@@ -1702,6 +1736,9 @@ msgstr "Показать метаданные"
msgid "View on map"
msgstr "Посмотреть на карте"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Удалить блокнот"
@@ -1724,6 +1761,10 @@ msgstr "У вас сейчас нет блокнота. Создайте его
msgid "Welcome"
msgstr "Добро пожаловать"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Статус: «%s»."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Блокнот с таким названием уже существует: «%s»"

View File

@@ -455,6 +455,9 @@ msgstr "Ni moč zagnati sinhronizatorja."
msgid "Starting synchronisation..."
msgstr "Sinhronizacija se začenja."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "V preklicu...Prosim počakajte."
@@ -645,6 +648,10 @@ msgstr ""
msgid "Search in all the notes"
msgstr "Išči znotraj vseh zabeležk"
#, fuzzy
msgid "Search in current note"
msgstr "Išči znotraj vseh zabeležk"
msgid "View"
msgstr "Pogled"
@@ -975,6 +982,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Odpri..."
@@ -991,6 +1001,9 @@ msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodprta povezava ali sporočilo: %s"
@@ -1028,9 +1041,6 @@ msgstr "Nastavi alarm"
msgid "In: %s"
msgstr "%s: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr ""
@@ -1109,6 +1119,14 @@ msgstr "Sinhroniziraj"
msgid "Notebooks"
msgstr "Beležnice"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Preneseni predmeti: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Viri: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Prosim izberite, kam želite izvoziti sinhronizacijski status"
@@ -1153,6 +1171,9 @@ msgstr ""
"Ne gre osvežiti tokena: manjkajo podatki o avtentikaciji. Ponovno zaženite "
"sinhronizacijo, da morda popravite težavo."
msgid "Untitled"
msgstr "Neimenovano"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1200,10 +1221,6 @@ msgstr "Izbrisani oddaljeni predmeti: %d."
msgid "Fetched items: %d/%d."
msgstr "Preneseni predmeti: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Stanje: %s."
msgid "Cancelling..."
msgstr "V preklicu..."
@@ -1254,9 +1271,6 @@ msgstr "Posodobljeno: %d."
msgid "created date"
msgstr "Ustvarjeno: %d."
msgid "Untitled"
msgstr "Neimenovano"
msgid "This note does not have geolocation information."
msgstr "Ta zabeležke nima geografske lokacije."
@@ -1320,12 +1334,22 @@ msgstr "Pokaži ikono v območju za obvestila(opravilna vrstica)"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Celokupen procent povečave"
#, fuzzy
msgid "Editor font size"
msgstr "Družina urejevalnika besedilnega stila"
msgid "Editor font family"
msgstr "Družina urejevalnika besedilnega stila"
@@ -1448,6 +1472,10 @@ msgstr "Joplin izvozno mesto"
msgid "Evernote Export File"
msgstr "Evernote izvozna datoteka"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin izvozno mesto"
msgid "Directory"
msgstr "Mesto datoteke"
@@ -1522,6 +1550,12 @@ msgstr "Prihajajoči alarmi"
msgid "On %s: %s"
msgstr "Vključeno %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Trenutno ni zabeležk. Ustvarite jo s klikom na (+) gumb."
@@ -1567,10 +1601,6 @@ msgstr "Potrdi"
msgid "Cancel synchronisation"
msgstr "Prekliči sinhronizacijo"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Preneseni predmeti: %d/%d."
#, fuzzy
msgid "Checking... Please wait."
msgstr "V preklicu...Prosim počakajte."
@@ -1681,6 +1711,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodprt tip slike: %s"
#, fuzzy
msgid "Take photo"
msgstr "Pripni fotografijo"
msgid "Attach photo"
msgstr "Pripni fotografijo"
@@ -1705,6 +1739,9 @@ msgstr "Prikaži meta podatke"
msgid "View on map"
msgstr "Prikaži na zemljevidu"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Izbriši beležnico"
@@ -1727,6 +1764,9 @@ msgstr "Trenutno nimate nobene beležnice. Ustvarite jo s klikom na (+) gumb."
msgid "Welcome"
msgstr "Dobrodošli"
#~ msgid "State: %s."
#~ msgstr "Stanje: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Beležnica s tem naslovom že obstaja: \"%s\""

View File

@@ -461,6 +461,9 @@ msgstr "Kan inte initiera synkroniseraren."
msgid "Starting synchronisation..."
msgstr "Startar synkronisering..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Avbryter... vänta."
@@ -652,6 +655,10 @@ msgstr "Redigera i extern redigerare"
msgid "Search in all the notes"
msgstr "Sök i alla anteckningarna"
#, fuzzy
msgid "Search in current note"
msgstr "Sök i alla anteckningarna"
msgid "View"
msgstr "Visa"
@@ -984,6 +991,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Öppna..."
@@ -1000,6 +1010,9 @@ msgstr "Kopiera sökväg till urklipp"
msgid "Copy Link Address"
msgstr "Kopiera länkadress"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Länk eller meddelande stöds inte: %s"
@@ -1037,9 +1050,6 @@ msgstr "Sätt alarm"
msgid "In: %s"
msgstr "I: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "Hyperlänk"
@@ -1116,6 +1126,14 @@ msgstr "Synkronisera"
msgid "Notebooks"
msgstr "Anteckningsböcker"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Dekrypterar objekt: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Resurser: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Välj vart synkroniseringstillståndet ska exporteras till"
@@ -1160,6 +1178,9 @@ msgstr ""
"Kan inte uppdatera token: autentiseringsdata saknas. Om du startar "
"synkroniseringen igen kan det lösa problemet."
msgid "Untitled"
msgstr "Utan titel"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1207,10 +1228,6 @@ msgstr "Borttagna fjärrobjekt: %d."
msgid "Fetched items: %d/%d."
msgstr "Hämtade objekt: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Tillstånd: %s."
msgid "Cancelling..."
msgstr "Avbryter..."
@@ -1258,9 +1275,6 @@ msgstr "uppdaterad datum"
msgid "created date"
msgstr "Skapad datum"
msgid "Untitled"
msgstr "Utan titel"
msgid "This note does not have geolocation information."
msgstr "Denna anteckning har inte geolokaliseringsinformation."
@@ -1323,12 +1337,22 @@ msgstr "Visa fältikon"
msgid "Note: Does not work in all desktop environments."
msgstr "Obs: Fungerar inte i alla skrivbordsmiljöer."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Global zoomprocent"
#, fuzzy
msgid "Editor font size"
msgstr "Redigerarens typsnittsfamilj"
msgid "Editor font family"
msgstr "Redigerarens typsnittsfamilj"
@@ -1455,6 +1479,10 @@ msgstr "Joplin-exporteringskatalog"
msgid "Evernote Export File"
msgstr "Evernote-exporteringsfil"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin-exporteringskatalog"
msgid "Directory"
msgstr "Katalog"
@@ -1529,6 +1557,12 @@ msgstr "Kommande larm"
msgid "On %s: %s"
msgstr "På %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Det finns för närvarande inga anteckningar. Skapa en genom att klicka på (+)-"
@@ -1575,10 +1609,6 @@ msgstr "Bekräfta"
msgid "Cancel synchronisation"
msgstr "Avbryt synkronisering"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Dekrypterar objekt: %d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Avbryter... vänta."
@@ -1697,6 +1727,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Bildstorlek som inte stöds: %s"
#, fuzzy
msgid "Take photo"
msgstr "Bifoga foto"
msgid "Attach photo"
msgstr "Bifoga foto"
@@ -1721,6 +1755,9 @@ msgstr "Visa metadata"
msgid "View on map"
msgstr "Visa på karta"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Ta bort anteckningsbok"
@@ -1746,5 +1783,8 @@ msgstr ""
msgid "Welcome"
msgstr "Välkommen"
#~ msgid "State: %s."
#~ msgstr "Tillstånd: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "En anteckningsbok med denna titel finns redan: \"%s\""

View File

@@ -431,6 +431,9 @@ msgstr "无法初始化同步。"
msgid "Starting synchronisation..."
msgstr "开始同步..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "正在取消... 请稍后。"
@@ -602,7 +605,7 @@ msgid "Italic"
msgstr "斜体"
msgid "Insert Date Time"
msgstr ""
msgstr "插入时间"
#, fuzzy
msgid "Edit in external editor"
@@ -611,6 +614,10 @@ msgstr "在外部编辑器中打开"
msgid "Search in all the notes"
msgstr "在所有笔记内搜索"
#, fuzzy
msgid "Search in current note"
msgstr "在所有笔记内搜索"
msgid "View"
msgstr "显示"
@@ -680,7 +687,7 @@ msgid "No"
msgstr "否"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgstr "Token 已被复制到粘贴板"
msgid "The web clipper service is enabled and set to auto-start."
msgstr "网页剪辑服务已启用并设置为自动启动。"
@@ -732,10 +739,10 @@ msgid "Advanced options"
msgstr "显示高级选项"
msgid "Authorisation token:"
msgstr ""
msgstr "授权码:"
msgid "Copy token"
msgstr ""
msgstr "拷贝 token"
msgid ""
"This authorisation token is only needed to allow third-party applications to "
@@ -750,7 +757,7 @@ msgid "Notes and settings are stored in: %s"
msgstr "笔记与设置文件储存目录为:%s"
msgid "Apply"
msgstr ""
msgstr "应用"
msgid "Submit"
msgstr "提交"
@@ -924,11 +931,14 @@ msgid ""
msgstr "此处没有任何笔记本。点击\"新笔记本\"创建。"
msgid "Location"
msgstr ""
msgstr "位置"
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr "笔记属性"
msgid "Open..."
msgstr "打开…"
@@ -943,7 +953,10 @@ msgid "Copy path to clipboard"
msgstr "复制路径到剪切板"
msgid "Copy Link Address"
msgstr ""
msgstr "拷贝链接地址"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr "该附件没有下载或者没有解密"
#, javascript-format
msgid "Unsupported link or message: %s"
@@ -980,9 +993,6 @@ msgstr "设置提醒"
msgid "In: %s"
msgstr "在: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "超链接"
@@ -1059,6 +1069,14 @@ msgstr "同步"
msgid "Notebooks"
msgstr "笔记本"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "解密项目:%d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "资源:%d。"
msgid "Please select where the sync status should be exported to"
msgstr "请选择同步状态的导出位置"
@@ -1101,6 +1119,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr "无法刷新令牌:缺失认证数据。重新开始同步可能会修复此错误。"
msgid "Untitled"
msgstr "无标题"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1148,10 +1169,6 @@ msgstr "已删除远程项目: %d。"
msgid "Fetched items: %d/%d."
msgstr "已提取项目:%d/%d."
#, javascript-format
msgid "State: %s."
msgstr "状态:%s。"
msgid "Cancelling..."
msgstr "正在取消..."
@@ -1198,9 +1215,6 @@ msgstr "更新日期"
msgid "created date"
msgstr "创建日期"
msgid "Untitled"
msgstr "无标题"
msgid "This note does not have geolocation information."
msgstr "此笔记不包含地理定位信息。"
@@ -1263,12 +1277,24 @@ msgstr "显示托盘图标"
msgid "Note: Does not work in all desktop environments."
msgstr "注意:在所有的桌面环境中都不能工作。"
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
"该选项允许 Joplin 在后台运行,如果你的笔记时常发生变化,推荐启用该设置来减少"
"可能的冲突"
msgid "Start application minimised in the tray icon"
msgstr "启动应用程序时在托盘中最小化"
msgid "Global zoom percentage"
msgstr "全局缩放比例"
#, fuzzy
msgid "Editor font size"
msgstr "编辑器字体"
msgid "Editor font family"
msgstr "编辑器字体"
@@ -1391,6 +1417,10 @@ msgstr "Joplin 导出目录"
msgid "Evernote Export File"
msgstr "Evernote 导出文件"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin 导出目录"
msgid "Directory"
msgstr "文件目录"
@@ -1462,6 +1492,12 @@ msgstr "临近提醒"
msgid "On %s: %s"
msgstr "%s:%s"
msgid "Permission to use camera"
msgstr "使用摄像头的权限"
msgid "Your permission to use your camera is required."
msgstr "使用摄像头的权限是必须的"
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "当前没有任何笔记。点击(+)按钮创建。"
@@ -1506,10 +1542,6 @@ msgstr "确认"
msgid "Cancel synchronisation"
msgstr "取消同步"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "解密项目:%d/%d"
#, fuzzy
msgid "Checking... Please wait."
msgstr "正在取消... 请稍后。"
@@ -1522,6 +1554,8 @@ msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"发生错误。请检查 URL,用户名,密码等等是否正确并且确保同步目的地可被访问。报"
"告的错误如下:"
#, fuzzy
msgid "The application has been authorised!"
@@ -1535,6 +1569,11 @@ msgid ""
"\n"
"Please try again."
msgstr ""
"无法授权应用:\n"
"\n"
"%s\n"
"\n"
"请重新尝试"
#, fuzzy, javascript-format
msgid "Decrypted items: %s / %s"
@@ -1621,6 +1660,10 @@ msgstr "Joplin 手机应用目前不支持这种类型的链接:%s"
msgid "Unsupported image type: %s"
msgstr "不支持的图片格式:%s"
#, fuzzy
msgid "Take photo"
msgstr "附加照片"
msgid "Attach photo"
msgstr "附加照片"
@@ -1645,6 +1688,9 @@ msgstr "显示元数据"
msgid "View on map"
msgstr "查看地图"
msgid "Go to source URL"
msgstr "定位到源 URL"
msgid "Delete notebook"
msgstr "删除笔记本"
@@ -1665,6 +1711,9 @@ msgstr "您目前未有笔记本。点击(+)按钮创建。"
msgid "Welcome"
msgstr "欢迎"
#~ msgid "State: %s."
#~ msgstr "状态:%s。"
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "以此标题命名的笔记本已存在:\"%s\""

View File

@@ -431,6 +431,9 @@ msgstr "無法初始化同步器。"
msgid "Starting synchronisation..."
msgstr "正在啟動同步..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "正在取消中...請稍候。"
@@ -611,6 +614,10 @@ msgstr "使用外部編輯器編輯"
msgid "Search in all the notes"
msgstr "在所有記事中搜尋"
#, fuzzy
msgid "Search in current note"
msgstr "在所有記事中搜尋"
msgid "View"
msgstr "檢視"
@@ -929,6 +936,9 @@ msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "開啟..."
@@ -945,6 +955,9 @@ msgstr "複製路徑到剪貼板"
msgid "Copy Link Address"
msgstr "複製鏈接位址"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "不支援的鏈接或訊息: %s"
@@ -980,9 +993,6 @@ msgstr "設置提醒"
msgid "In: %s"
msgstr "在: %s"
msgid "Note properties"
msgstr ""
msgid "Hyperlink"
msgstr "超連結"
@@ -1059,6 +1069,14 @@ msgstr "進行同步"
msgid "Notebooks"
msgstr "記事本"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "正在解密項目: %d/%d 項"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "資源: %d。"
msgid "Please select where the sync status should be exported to"
msgstr "請選擇將同步狀態導出到的位置"
@@ -1101,6 +1119,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr "無法刷新 token: 缺少身份驗證資料。再次啟動同步可能會解決此問題。"
msgid "Untitled"
msgstr "未命名"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1147,10 +1168,6 @@ msgstr "已刪除的遠端項目: %d 項"
msgid "Fetched items: %d/%d."
msgstr "已擷取的本地項目: %d/%d 項"
#, javascript-format
msgid "State: %s."
msgstr "狀態: %s。"
msgid "Cancelling..."
msgstr "正在取消中..."
@@ -1197,9 +1214,6 @@ msgstr "更新日期"
msgid "created date"
msgstr "建立日期"
msgid "Untitled"
msgstr "未命名"
msgid "This note does not have geolocation information."
msgstr "此記事沒有地理位置定位資訊。"
@@ -1262,12 +1276,22 @@ msgstr "顯示系統匣圖示"
msgid "Note: Does not work in all desktop environments."
msgstr "注意: 不是在全部桌面環境中都能發揮作用。"
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "整體縮放比例 (%)"
#, fuzzy
msgid "Editor font size"
msgstr "編輯器字型系列"
msgid "Editor font family"
msgstr "編輯器字型系列"
@@ -1388,6 +1412,10 @@ msgstr "Joplin 匯出目錄"
msgid "Evernote Export File"
msgstr "Evernote 匯出檔"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin 匯出目錄"
msgid "Directory"
msgstr "目錄"
@@ -1459,6 +1487,12 @@ msgstr "將會發生的提醒事項"
msgid "On %s: %s"
msgstr "在 %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "您當前沒有任何筆記。通過按一下 (+) 鍵去新增一則筆記。"
@@ -1503,10 +1537,6 @@ msgstr "確認"
msgid "Cancel synchronisation"
msgstr "取消同步"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "正在解密項目: %d/%d 項"
#, fuzzy
msgid "Checking... Please wait."
msgstr "正在取消中...請稍候。"
@@ -1618,6 +1648,10 @@ msgstr "Joplin 移動應用程式暫時不支援此類型的連結: %s"
msgid "Unsupported image type: %s"
msgstr "不支援的圖像類型: %s"
#, fuzzy
msgid "Take photo"
msgstr "附加相片"
msgid "Attach photo"
msgstr "附加相片"
@@ -1642,6 +1676,9 @@ msgstr "顯示後設資料 (metadata)"
msgid "View on map"
msgstr "在地圖上顯示"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "刪除記事本"
@@ -1662,5 +1699,8 @@ msgstr "您當前沒有任何筆記本。通過按一下 (+) 鍵去建立一本
msgid "Welcome"
msgstr "歡迎"
#~ msgid "State: %s."
#~ msgstr "狀態: %s。"
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "同名筆記本已經存在: \"%s\""

View File

@@ -1,6 +1,6 @@
{
"name": "joplin",
"version": "1.0.116",
"version": "1.0.119",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2890,11 +2890,6 @@
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
},
"unidecode": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/unidecode/-/unidecode-0.1.8.tgz",
"integrity": "sha1-77swFTi8RSRqmsjFWdcvAVMFBT4="
},
"uniq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",

View File

@@ -19,7 +19,7 @@
],
"owner": "Laurent Cozic"
},
"version": "1.0.116",
"version": "1.0.119",
"bin": {
"joplin": "./main.js"
},
@@ -68,7 +68,6 @@
"tar": "^4.4.0",
"tcp-port-used": "^0.1.2",
"tkwidgets": "^0.5.26",
"unidecode": "^0.1.8",
"url-parse": "^1.2.0",
"uuid": "^3.0.1",
"valid-url": "^1.0.9",

View File

@@ -25,10 +25,12 @@ npm test tests-build/ArrayUtils.js
npm test tests-build/EnexToMd.js
npm test tests-build/HtmlToMd.js
npm test tests-build/markdownUtils.js
npm test tests-build/models_BaseItem.js
npm test tests-build/models_Folder.js
npm test tests-build/models_Note.js
npm test tests-build/models_Tag.js
npm test tests-build/models_Setting.js
npm test tests-build/pathUtils.js
npm test tests-build/services_InteropService.js
npm test tests-build/services_ResourceService.js
npm test tests-build/urlUtils.js

View File

@@ -1,5 +1,6 @@
require('app-module-path').addPath(__dirname);
const os = require('os');
const { time } = require('lib/time-utils.js');
const { filename } = require('lib/path-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
@@ -37,9 +38,14 @@ describe('EnexToMd', function() {
// if (htmlFilename !== 'text2.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
const expectedMd = await shim.fsDriver().readFile(mdPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
const actualMd = await enexXmlToMd('<div>' + html + '</div>', []);
let actualMd = await enexXmlToMd('<div>' + html + '</div>', []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n')
actualMd = actualMd.replace(/\r\n/g, '\n')
}
if (actualMd !== expectedMd) {
console.info('');

View File

@@ -1,5 +1,6 @@
require('app-module-path').addPath(__dirname);
const os = require('os');
const { time } = require('lib/time-utils.js');
const { filename } = require('lib/path-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
@@ -39,9 +40,14 @@ describe('HtmlToMd', function() {
// if (htmlFilename !== 'anchor_with_url_with_spaces.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
const expectedMd = await shim.fsDriver().readFile(mdPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
const actualMd = await htmlToMd.parse('<div>' + html + '</div>', []);
let actualMd = await htmlToMd.parse('<div>' + html + '</div>', []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n')
actualMd = actualMd.replace(/\r\n/g, '\n')
}
if (actualMd !== expectedMd) {
console.info('');

View File

@@ -0,0 +1,51 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseItem = require('lib/models/BaseItem.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
async function allItems() {
let folders = await Folder.all();
let notes = await Note.all();
return folders.concat(notes);
}
describe('models_BaseItem', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
// it('should be able to exclude keys when syncing', asyncTest(async () => {
// let folder1 = await Folder.save({ title: "folder1" });
// let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
// await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
// let resource1 = (await Resource.all())[0];
// console.info(await Resource.serializeForSync(resource1));
// }));
// This is to handle the case where a property is removed from a BaseItem table - in that case files in
// the sync target will still have the old property but we don't need it locally.
it('should ignore properties that are present in sync file but not in database when serialising', asyncTest(async () => {
let folder = await Folder.save({ title: "folder1" });
let serialized = await Folder.serialize(folder);
serialized += "\nignore_me: true"
let unserialized = await Folder.unserialize(serialized);
expect('ignore_me' in unserialized).toBe(false);
}));
});

View File

@@ -5,6 +5,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const ArrayUtils = require('lib/ArrayUtils.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
@@ -35,13 +36,36 @@ describe('models_Note', function() {
expect(items[0].type_).toBe(BaseModel.TYPE_NOTE);
expect(items[1].type_).toBe(BaseModel.TYPE_RESOURCE);
const resource = items[1];
note2.body += '<img alt="bla" src=":/' + resource.id + '"/>';
note2.body += '<img src=\':/' + resource.id + '\' />';
const resource2 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
const resource3 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
note2.body += '<img alt="bla" src=":/' + resource2.id + '"/>';
note2.body += '<img src=\':/' + resource3.id + '\' />';
items = await Note.linkedItems(note2.body);
expect(items.length).toBe(4);
}));
it('should find linked items', asyncTest(async () => {
const testCases = [
['[](:/06894e83b8f84d3d8cbe0f1587f9e226)', ['06894e83b8f84d3d8cbe0f1587f9e226']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226) [](:/06894e83b8f84d3d8cbe0f1587f9e226)', ['06894e83b8f84d3d8cbe0f1587f9e226']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226) [](:/06894e83b8f84d3d8cbe0f1587f9e227)', ['06894e83b8f84d3d8cbe0f1587f9e226', '06894e83b8f84d3d8cbe0f1587f9e227']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226 "some title")', ['06894e83b8f84d3d8cbe0f1587f9e226']],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const expected = t[1];
const actual = Note.linkedItemIds(input);
const contentEquals = ArrayUtils.contentEquals(actual, expected);
// console.info(contentEquals, input, expected, actual);
expect(contentEquals).toBe(true);
}
}));
it('should change the type of notes', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });

View File

@@ -0,0 +1,59 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('models_Resource', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should have a "done" fetch_status when created locally', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
let ls = await Resource.localState(resource1);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
}));
it('should have a default local state', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
let ls = await Resource.localState(resource1);
expect(!ls.id).toBe(true);
expect(ls.resource_id).toBe(resource1.id);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
}));
it('should save and delete local state', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
await Resource.setLocalState(resource1, { fetch_status: Resource.FETCH_STATUS_IDLE });
let ls = await Resource.localState(resource1);
expect(!!ls.id).toBe(true);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_IDLE);
await Resource.delete(resource1.id);
ls = await Resource.localState(resource1);
expect(!ls.id).toBe(true);
}));
});

View File

@@ -0,0 +1,39 @@
require('app-module-path').addPath(__dirname);
const { friendlySafeFilename } = require('lib/path-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('pathUtils', function() {
beforeEach(async (done) => {
done();
});
it('should create friendly safe filename', async (done) => {
const testCases = [
['生活', '生活'],
['not/good', 'not_good'],
['really/not/good', 'really_not_good'],
['con', '___'],
['no space at the end ', 'no space at the end'],
['nor dots...', 'nor dots'],
[' no space before either', 'no space before either'],
['thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong', 'thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong'],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
expect(friendlySafeFilename(t[0])).toBe(t[1]);
}
expect(!!friendlySafeFilename('')).toBe(true);
expect(!!friendlySafeFilename('...')).toBe(true);
done();
});
});

View File

@@ -310,4 +310,51 @@ describe('services_InteropService', function() {
expect(note2_2.body.indexOf(note1_2.id) >= 0).toBe(true);
}));
it('should export into json format', asyncTest(async () => {
const service = new InteropService();
let folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
const filePath = exportDir();
await service.export({ path: filePath, format: 'json' });
// verify that the json files exist and can be parsed
const items = [folder1, note1];
for (let i = 0; i < items.length; i++) {
const jsonFile = filePath + '/' + items[i].id + '.json';
let json = await fs.readFile(jsonFile, 'utf-8');
let obj = JSON.parse(json);
expect(obj.id).toBe(items[i].id);
expect(obj.type_).toBe(items[i].type_);
expect(obj.title).toBe(items[i].title);
expect(obj.body).toBe(items[i].body);
}
}));
it('should export MD with unicode filenames', asyncTest(async () => {
const service = new InteropService();
let folder1 = await Folder.save({ title: 'folder1' });
let folder2 = await Folder.save({ title: 'ジョプリン' });
let note1 = await Note.save({ title: '生活', parent_id: folder1.id });
let note2 = await Note.save({ title: '生活', parent_id: folder1.id });
let note2b = await Note.save({ title: '生活', parent_id: folder1.id });
let note3 = await Note.save({ title: '', parent_id: folder1.id });
let note4 = await Note.save({ title: '', parent_id: folder1.id });
let note5 = await Note.save({ title: 'salut, ça roule ?', parent_id: folder1.id });
let note6 = await Note.save({ title: 'ジョプリン', parent_id: folder2.id });
const outDir = exportDir();
await service.export({ path: outDir, format: 'md' });
expect(await shim.fsDriver().exists(outDir + '/folder1/生活.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (1).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (2).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled (1).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/salut, ça roule _.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/ジョプリン/ジョプリン.md')).toBe(true);
}));
});

View File

@@ -8,6 +8,7 @@ const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
const Resource = require('lib/models/Resource.js');
const ItemChange = require('lib/models/ItemChange.js');
const NoteResource = require('lib/models/NoteResource.js');
const ResourceService = require('lib/services/ResourceService.js');
const fs = require('fs-extra');
@@ -124,4 +125,25 @@ describe('services_ResourceService', function() {
expect(!!(await Resource.load(resource1.id))).toBe(true);
}));
it('should not process twice the same change', asyncTest(async () => {
const service = new ResourceService();
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
await service.indexNoteResources();
const before = (await NoteResource.all())[0];
await time.sleep(0.1);
await service.indexNoteResources();
const after = (await NoteResource.all())[0];
expect(before.last_seen_time).toBe(after.last_seen_time);
}));
});

View File

@@ -0,0 +1,188 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const SearchEngine = require('lib/services/SearchEngine');
const Note = require('lib/models/Note');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
let engine = null;
describe('services_SearchEngine', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
engine = new SearchEngine();
engine.setDb(db());
done();
});
it('should keep the content and FTS table in sync', async (done) => {
let rows, n1, n2, n3;
n1 = await Note.save({ title: "a" });
n2 = await Note.save({ title: "b" });
rows = await engine.search('a');
expect(rows.length).toBe(1);
expect(rows[0].title).toBe('a');
await Note.delete(n1.id);
rows = await engine.search('a');
expect(rows.length).toBe(0);
rows = await engine.search('b');
expect(rows[0].title).toBe('b');
await Note.save({ id: n2.id, title: 'c' });
rows = await engine.search('b');
expect(rows.length).toBe(0);
rows = await engine.search('c');
expect(rows[0].title).toBe('c');
await Note.save({ id: n2.id, encryption_applied: 1 });
rows = await engine.search('c');
expect(rows.length).toBe(0);
await Note.save({ id: n2.id, encryption_applied: 0 });
rows = await engine.search('c');
expect(rows.length).toBe(1);
done();
});
it('should order search results by relevance (1)', async (done) => {
const n1 = await Note.save({ title: "abcd efgh" }); // 3
const n2 = await Note.save({ title: "abcd aaaaa abcd abcd" }); // 1
const n3 = await Note.save({ title: "abcd aaaaa bbbb eeee abcd" }); // 2
const rows = await engine.search('abcd');
expect(rows[0].id).toBe(n2.id);
expect(rows[1].id).toBe(n3.id);
expect(rows[2].id).toBe(n1.id);
done();
});
it('should order search results by relevance (2)', async (done) => {
// 1
const n1 = await Note.save({ title: "abcd efgh", body: "XX abcd XX efgh" });
// 4
const n2 = await Note.save({ title: "abcd aaaaa bbbb eeee efgh" });
// 3
const n3 = await Note.save({ title: "abcd aaaaa efgh" });
// 2
const n4 = await Note.save({ title: "blablablabla blabla bla abcd X efgh" });
// 5
const n5 = await Note.save({ title: "occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh" });
const rows = await engine.search('abcd efgh');
expect(rows[0].id).toBe(n1.id);
expect(rows[1].id).toBe(n4.id);
expect(rows[2].id).toBe(n3.id);
expect(rows[3].id).toBe(n2.id);
expect(rows[4].id).toBe(n5.id);
done();
});
it('should supports various query types', async (done) => {
let rows;
const n1 = await Note.save({ title: "abcd efgh ijkl", body: "aaaa bbbb" });
const n2 = await Note.save({ title: "iiii efgh bbbb", body: "aaaa bbbb" });
rows = await engine.search('abcd ijkl');
expect(rows.length).toBe(1);
rows = await engine.search('"abcd ijkl"');
expect(rows.length).toBe(0);
rows = await engine.search('"abcd efgh"');
expect(rows.length).toBe(1);
rows = await engine.search('title:abcd');
expect(rows.length).toBe(1);
rows = await engine.search('title:efgh');
expect(rows.length).toBe(2);
rows = await engine.search('body:abcd');
expect(rows.length).toBe(0);
rows = await engine.search('body:bbbb');
expect(rows.length).toBe(2);
rows = await engine.search('body:bbbb iiii');
expect(rows.length).toBe(1);
done();
});
it('should parse normal query strings', async (done) => {
let rows;
const testCases = [
['abcd efgh', { _: ['abcd', 'efgh'] }],
['abcd efgh', { _: ['abcd', 'efgh'] }],
['title:abcd efgh', { _: ['efgh'], title: ['abcd'] }],
['title:abcd', { title: ['abcd'] }],
['"abcd efgh"', { _: ['abcd efgh'] }],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const expected = t[1];
const actual = engine.parseQuery(input);
expect(JSON.stringify(actual.terms._)).toBe(JSON.stringify(expected._));
expect(JSON.stringify(actual.terms.title)).toBe(JSON.stringify(expected.title));
expect(JSON.stringify(actual.terms.body)).toBe(JSON.stringify(expected.body));
}
done();
});
it('should parse query strings with wildcards', async (done) => {
let rows;
const testCases = [
['do*', ['do', 'dog', 'domino'], [] ],
// "*" is a wildcard only when used at the end (to searhc for documents with the specified prefix)
// If it's at the beginning, it's ignored, if it's in the middle, it's treated as a litteral "*".
['*an*', ['an', 'anneau'], ['piano', 'plan'] ],
['no*no', ['no*no'], ['nonono'] ],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const shouldMatch = t[1];
const shouldNotMatch = t[2];
const regex = new RegExp(engine.parseQuery(input).terms._[0].value, 'gmi');
for (let j = 0; j < shouldMatch.length; j++) {
const r = shouldMatch[j].match(regex);
expect(!!r).toBe(true, '"' + input + '" should match "' + shouldMatch[j] + '"');
}
// for (let j = 0; j < shouldNotMatch.length; j++) {
// const r = shouldNotMatch[j].match(regex);
// // console.info(input, shouldNotMatch)
// expect(!!r).toBe(false, '"' + input + '" should not match "' + shouldNotMatch[j] + '"');
// }
}
expect(engine.parseQuery('*').termCount).toBe(0);
done();
});
});

View File

@@ -156,6 +156,20 @@ describe('services_rest_Api', function() {
done();
});
it('should create notes with supplied ID', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });
response = await api.route('POST', 'notes', null, JSON.stringify({
id: '12345678123456781234567812345678',
title: 'testing',
parent_id: f.id,
}));
expect(response.id).toBe('12345678123456781234567812345678');
done();
});
it('should create notes with images', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });

View File

@@ -873,15 +873,17 @@ describe('Synchronizer', function() {
let allResources = await Resource.all();
expect(allResources.length).toBe(1);
let resource1_2 = allResources[0];
let ls = await Resource.localState(resource1_2);
expect(resource1_2.id).toBe(resource1.id);
expect(resource1_2.fetch_status).toBe(Resource.FETCH_STATUS_IDLE);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_IDLE);
const fetcher = new ResourceFetcher(() => { return synchronizer().api() });
fetcher.queueDownload(resource1_2.id);
await fetcher.waitForAllFinished();
resource1_2 = await Resource.load(resource1.id);
expect(resource1_2.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
ls = await Resource.localState(resource1_2);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
let resourcePath1_2 = Resource.fullPath(resource1_2);
expect(fileContentEqual(resourcePath1, resourcePath1_2)).toBe(true);
@@ -909,8 +911,9 @@ describe('Synchronizer', function() {
await fetcher.waitForAllFinished();
resource1 = await Resource.load(resource1.id);
expect(resource1.fetch_status).toBe(Resource.FETCH_STATUS_ERROR);
expect(resource1.fetch_error).toBe('did not work');
let ls = await Resource.localState(resource1);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_ERROR);
expect(ls.fetch_error).toBe('did not work');
}));
it('should delete resources', asyncTest(async () => {

View File

@@ -4,6 +4,7 @@ const { DatabaseDriverNode } = require('lib/database-driver-node.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const ItemChange = require('lib/models/ItemChange.js');
const Resource = require('lib/models/Resource.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
@@ -122,6 +123,8 @@ async function switchClient(id) {
async function clearDatabase(id = null) {
if (id === null) id = currentClient_;
await ItemChange.waitForAllSaved();
let queries = [
'DELETE FROM notes',
'DELETE FROM folders',

0
CliClientDemo/publish.sh Normal file → Executable file
View File

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Joplin Web Clipper [DEV]",
"version": "1.0.7",
"version": "1.0.8",
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
"homepage_url": "https://joplin.cozic.net",
"icons": {

View File

@@ -18,7 +18,10 @@ class AppComponent extends Component {
});
this.confirm_click = () => {
bridge().sendContentToJoplin(this.props.clippedContent);
const content = Object.assign({}, this.props.clippedContent);
content.tags = this.state.selectedTags.join(',');
content.parent_id = this.props.selectedFolderId;
bridge().sendContentToJoplin(content);
}
this.contentTitle_change = (event) => {
@@ -31,24 +34,18 @@ class AppComponent extends Component {
this.clipSimplified_click = () => {
bridge().sendCommandToActiveTab({
name: 'simplifiedPageHtml',
parent_id: this.props.selectedFolderId,
tags: this.state.selectedTags.join(','),
});
}
this.clipComplete_click = () => {
bridge().sendCommandToActiveTab({
name: 'completePageHtml',
parent_id: this.props.selectedFolderId,
tags: this.state.selectedTags.join(','),
});
}
this.clipSelection_click = () => {
bridge().sendCommandToActiveTab({
name: 'selectedHtml',
parent_id: this.props.selectedFolderId,
tags: this.state.selectedTags.join(','),
});
}

View File

@@ -1,20 +1,20 @@
function randomClipperPort(state, env) {
const startPorts = {
prod: 41184,
dev: 27583,
};
const startPorts = {
prod: 41184,
dev: 27583,
};
const startPort = env === 'prod' ? startPorts.prod : startPorts.dev;
const startPort = env === 'prod' ? startPorts.prod : startPorts.dev;
if (!state) {
state = { offset: 0 };
} else {
state.offset++;
}
if (!state) {
state = { offset: 0 };
} else {
state.offset++;
}
state.port = startPort + state.offset;
state.port = startPort + state.offset;
return state;
return state;
}
module.exports = randomClipperPort;

View File

@@ -23,8 +23,9 @@ const DecryptionWorker = require('lib/services/DecryptionWorker');
const InteropService = require('lib/services/InteropService');
const InteropServiceHelper = require('./InteropServiceHelper.js');
const ResourceService = require('lib/services/ResourceService');
const SearchEngine = require('lib/services/SearchEngine');
const ClipperServer = require('lib/ClipperServer');
const ExternalEditWatcher = require('lib/services/ExternalEditWatcher');
const { bridge } = require('electron').remote.require('./bridge');
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
@@ -49,7 +50,6 @@ class Application extends BaseApplication {
constructor() {
super();
this.lastMenuScreen_ = null;
this.powerSaveBlockerId_ = null;
}
hasGui() {
@@ -221,17 +221,6 @@ class Application extends BaseApplication {
Setting.setValue('sidebarVisibility', newState.sidebarVisibility);
}
if (action.type === 'SYNC_STARTED') {
if (!this.powerSaveBlockerId_) this.powerSaveBlockerId_ = bridge().powerSaveBlockerStart('prevent-app-suspension');
}
if (action.type === 'SYNC_COMPLETED') {
if (this.powerSaveBlockerId_) {
bridge().powerSaveBlockerStop(this.powerSaveBlockerId_);
this.powerSaveBlockerId_ = null;
}
}
return result;
}
@@ -471,14 +460,27 @@ class Application extends BaseApplication {
name: 'commandStartExternalEditing',
});
},
}, {
type: 'separator',
screens: ['Main'],
}, {
label: _('Search in all the notes'),
screens: ['Main'],
accelerator: 'F6',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'focus_search',
});
},
}, {
label: _('Search in current note'),
screens: ['Main'],
accelerator: 'CommandOrControl+F',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'focus_search',
name: 'showLocalSearch',
});
},
}],
@@ -688,6 +690,23 @@ class Application extends BaseApplication {
document.head.appendChild(styleTag);
}
async loadCustomCss(filePath) {
let cssString = '';
if (await fs.pathExists(filePath)) {
try {
cssString = await fs.readFile(filePath, 'utf-8');
} catch (error) {
let msg = error.message ? error.message : '';
msg = 'Could not load custom css from ' + filePath + '\n' + msg;
error.message = msg;
throw error;
}
}
return cssString;
}
async start(argv) {
const electronIsDev = require('electron-is-dev');
@@ -741,7 +760,12 @@ class Application extends BaseApplication {
ids: Setting.value('collapsedFolderIds'),
});
if (shim.isLinux()) bridge().setAllowPowerSaveBlockerToggle(true);
const cssString = await this.loadCustomCss(Setting.value('profileDir') + '/userstyle.css');
this.store().dispatch({
type: 'LOAD_CUSTOM_CSS',
css: cssString
});
// Note: Auto-update currently doesn't work in Linux: it downloads the update
// but then doesn't install it on exit.
@@ -770,6 +794,9 @@ class Application extends BaseApplication {
ResourceService.runInBackground();
SearchEngine.instance().setDb(reg.db());
SearchEngine.instance().setLogger(reg.logger());
if (Setting.value('env') === 'dev') {
AlarmService.updateAllNotifications();
} else {
@@ -792,6 +819,9 @@ class Application extends BaseApplication {
if (Setting.value('clipperServer.autoStart')) {
ClipperServer.instance().start();
}
ExternalEditWatcher.instance().setLogger(reg.logger());
ExternalEditWatcher.instance().dispatch = this.store().dispatch;
}
}

View File

@@ -1,7 +1,6 @@
const { _, setLocale } = require('lib/locale.js');
const { dirname } = require('lib/path-utils.js');
const { Logger } = require('lib/logger.js');
const { powerSaveBlocker } = require('electron');
class Bridge {
@@ -9,7 +8,6 @@ class Bridge {
this.electronWrapper_ = electronWrapper;
this.autoUpdateLogger_ = null;
this.lastSelectedPath_ = null;
this.allowPowerSaveBlockerToggle_ = false;
}
electronApp() {
@@ -24,10 +22,6 @@ class Bridge {
return this.electronWrapper_.window();
}
setAllowPowerSaveBlockerToggle(v) {
this.allowPowerSaveBlockerToggle_ = v;
}
windowContentSize() {
if (!this.window()) return { width: 0, height: 0 };
const s = this.window().getContentSize();
@@ -126,19 +120,7 @@ class Bridge {
const { checkForUpdates } = require('./checkForUpdates.js');
checkForUpdates(inBackground, window, logFilePath);
}
powerSaveBlockerStart(type) {
if (!this.allowPowerSaveBlockerToggle_) return null;
console.info('Enable powerSaveBlockerStart: ' + type);
return powerSaveBlocker.start(type);
}
powerSaveBlockerStop(id) {
if (!this.allowPowerSaveBlockerToggle_) return null;
console.info('Disable powerSaveBlocker: ' + id);
return powerSaveBlocker.stop(id);
}
}
let bridge_ = null;

View File

@@ -45,15 +45,21 @@ class ClipperConfigScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = Object.assign({}, theme.containerStyle, {
overflowY: 'scroll',
height:style.height,
});
const buttonStyle = Object.assign({}, theme.buttonStyle, { marginRight: 10 });
const stepBoxStyle = {
border: "1px solid #ccc",
padding: 15,
paddingTop: 0,
marginBottom: 15,
backgroundColor: theme.backgroundColor,
};
let webClipperStatusComps = [];
@@ -68,7 +74,7 @@ class ClipperConfigScreenComponent extends React.Component {
webClipperStatusComps.push(<button key="disable_button" onClick={this.disableClipperServer_click}>{_('Disable Web Clipper Service')}</button>)
} else {
webClipperStatusComps.push(<p key="text_4" style={theme.textStyle}>{_('The web clipper service is not enabled.')}</p>)
webClipperStatusComps.push(<button key="enable_button" onClick={this.enableClipperServer_click}>{_('Enable Web Clipper Service')}</button>)
webClipperStatusComps.push(<button key="enable_button" style={buttonStyle} onClick={this.enableClipperServer_click}>{_('Enable Web Clipper Service')}</button>)
}
const apiTokenStyle = Object.assign({}, theme.textStyle, {
@@ -81,7 +87,7 @@ class ClipperConfigScreenComponent extends React.Component {
return (
<div>
<Header style={headerStyle} />
<div style={{overflowY:'scroll', height:style.height}}>
<div style={containerStyle}>
<div style={{padding: theme.margin}}>
<p style={theme.textStyle}>{_('Joplin Web Clipper allows saving web pages and screenshots from your browser to Joplin.')}</p>
<p style={theme.textStyle}>{_('In order to use the web clipper, you need to do the following:')}</p>
@@ -106,7 +112,7 @@ class ClipperConfigScreenComponent extends React.Component {
<div style={stepBoxStyle}>
<p style={theme.h1Style}>{_('Advanced options')}</p>
<p style={theme.textStyle}>{_('Authorisation token:')}</p>
<p style={apiTokenStyle}>{this.props.apiToken} <a href="#" onClick={this.copyToken_click}>{_('Copy token')}</a></p>
<p style={apiTokenStyle}>{this.props.apiToken} <a style={theme.urlStyle} href="#" onClick={this.copyToken_click}>{_('Copy token')}</a></p>
<p style={theme.textStyle}>{_('This authorisation token is only needed to allow third-party applications to access Joplin.')}</p>
</div>
</div>
@@ -128,4 +134,4 @@ const mapStateToProps = (state) => {
const ClipperConfigScreen = connect(mapStateToProps)(ClipperConfigScreenComponent);
module.exports = { ClipperConfigScreen };
module.exports = { ClipperConfigScreen };

View File

@@ -53,10 +53,13 @@ class ConfigScreenComponent extends React.Component {
const labelStyle = Object.assign({}, theme.textStyle, {
display: 'inline-block',
marginRight: 10,
color: theme.color,
});
const controlStyle = {
display: 'inline-block',
color: theme.color,
backgroundColor: theme.backgroundColor,
};
const descriptionStyle = Object.assign({}, theme.textStyle, {
@@ -120,7 +123,10 @@ class ConfigScreenComponent extends React.Component {
updateSettingValue(key, event.target.value);
}
const inputStyle = Object.assign({}, controlStyle, { width: '50%', minWidth: '20em' });
const inputStyle = Object.assign({}, controlStyle, {
width: '50%',
minWidth: '20em',
border: '1px solid' });
const inputType = md.secure === true ? 'password' : 'text';
return (
@@ -164,21 +170,19 @@ class ConfigScreenComponent extends React.Component {
render() {
const theme = themeStyle(this.props.theme);
const style = Object.assign({}, this.props.style, { overflow: 'auto' });
const style = Object.assign({
backgroundColor: theme.backgroundColor
}, this.props.style, { overflow: 'auto' });
const settings = this.state.settings;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = {
padding: 10,
};
const containerStyle = Object.assign({}, theme.containerStyle, { padding: 10 });
const buttonStyle = {
const buttonStyle = Object.assign({}, theme.buttonStyle, {
display: this.state.changedSettingKeys.length ? 'inline-block' : 'none',
marginRight: 10,
}
});
const settingComps = shared.settingsToComponents(this, 'desktop', settings);
@@ -195,7 +199,7 @@ class ConfigScreenComponent extends React.Component {
settingComps.push(
<div key="check_sync_config_button" style={this.rowStyle_}>
<button disabled={this.state.checkSyncConfigResult === 'checking'} onClick={this.checkSyncConfig_}>{_('Check synchronisation configuration')}</button>
<button style={buttonStyle} disabled={this.state.checkSyncConfigResult === 'checking'} onClick={this.checkSyncConfig_}>{_('Check synchronisation configuration')}</button>
{ statusComp }
</div>);
}
@@ -228,4 +232,4 @@ const mapStateToProps = (state) => {
const ConfigScreen = connect(mapStateToProps)(ConfigScreenComponent);
module.exports = { ConfigScreen };
module.exports = { ConfigScreen };

View File

@@ -28,16 +28,18 @@ class DropboxLoginScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: theme.margin,
height: style.height - theme.headerHeight - theme.margin * 2,
});
const inputStyle = Object.assign({}, theme.inputStyle, { width: 500 });
return (
<div>
<Header style={headerStyle} />
<div style={{padding: theme.margin}}>
<div style={containerStyle}>
<p style={theme.textStyle}>{_('To allow Joplin to synchronise with Dropbox, please follow the steps below:')}</p>
<p style={theme.textStyle}>{_('Step 1: Open this URL in your browser to authorise the application:')}</p>
<a style={theme.textStyle} href="#" onClick={this.shared_.loginUrl_click}>{this.state.loginUrl}</a>
@@ -59,4 +61,4 @@ const mapStateToProps = (state) => {
const DropboxLoginScreen = connect(mapStateToProps)(DropboxLoginScreenComponent);
module.exports = { DropboxLoginScreen };
module.exports = { DropboxLoginScreen };

View File

@@ -50,6 +50,13 @@ class EncryptionConfigScreenComponent extends React.Component {
renderMasterKey(mk) {
const theme = themeStyle(this.props.theme);
const passwordStyle = {
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
}
const onSaveClick = () => {
return shared.onSavePasswordClick(this, mk);
}
@@ -69,7 +76,7 @@ class EncryptionConfigScreenComponent extends React.Component {
<td style={theme.textStyle}>{mk.source_application}</td>
<td style={theme.textStyle}>{time.formatMsToLocal(mk.created_time)}</td>
<td style={theme.textStyle}>{time.formatMsToLocal(mk.updated_time)}</td>
<td style={theme.textStyle}><input type="password" value={password} onChange={(event) => onPasswordChange(event)}/> <button onClick={() => onSaveClick()}>{_('Save')}</button></td>
<td style={theme.textStyle}><input type="password" style={passwordStyle} value={password} onChange={(event) => onPasswordChange(event)}/> <button style={theme.buttonStyle} onClick={() => onSaveClick()}>{_('Save')}</button></td>
<td style={theme.textStyle}>{passwordOk}</td>
</tr>
);
@@ -81,15 +88,13 @@ class EncryptionConfigScreenComponent extends React.Component {
const masterKeys = this.state.masterKeys;
const containerPadding = 10;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = {
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: containerPadding,
overflow: 'auto',
height: style.height - theme.headerHeight - containerPadding * 2,
};
});
const mkComps = [];
let nonExistingMasterKeyIds = this.props.notLoadedMasterKeys.slice();
@@ -126,7 +131,7 @@ class EncryptionConfigScreenComponent extends React.Component {
}
const decryptedItemsInfo = <p style={theme.textStyle}>{shared.decryptedStatText(this)}</p>;
const toggleButton = <button onClick={() => { onToggleButtonClick() }}>{this.props.encryptionEnabled ? _('Disable encryption') : _('Enable encryption')}</button>
const toggleButton = <button style={theme.buttonStyle} onClick={() => { onToggleButtonClick() }}>{this.props.encryptionEnabled ? _('Disable encryption') : _('Enable encryption')}</button>
let masterKeySection = null;
@@ -213,4 +218,4 @@ const mapStateToProps = (state) => {
const EncryptionConfigScreen = connect(mapStateToProps)(EncryptionConfigScreenComponent);
module.exports = { EncryptionConfigScreen };
module.exports = { EncryptionConfigScreen };

View File

@@ -108,6 +108,9 @@ class HeaderComponent extends React.Component {
color: style.color,
fontSize: style.fontSize,
fontFamily: style.fontFamily,
backgroundColor: style.searchColor,
border: '1px solid',
borderColor: style.dividerColor,
};
const searchButton = {
@@ -171,6 +174,8 @@ class HeaderComponent extends React.Component {
paddingLeft: theme.headerButtonHPadding,
paddingRight: theme.headerButtonHPadding,
color: theme.color,
searchColor: theme.backgroundColor,
dividerColor: theme.dividerColor,
textDecoration: 'none',
fontFamily: theme.fontFamily,
fontSize: theme.fontSize,
@@ -212,4 +217,4 @@ const mapStateToProps = (state) => {
const Header = connect(mapStateToProps)(HeaderComponent);
module.exports = { Header };
module.exports = { Header };

View File

@@ -35,4 +35,4 @@ class IconButton extends React.Component {
}
module.exports = { IconButton };
module.exports = { IconButton };

View File

@@ -120,7 +120,7 @@ class MainScreenComponent extends React.Component {
});
} else if (command.name === 'setTags') {
const tags = await Tag.tagsByNoteId(command.noteId);
const tagTitles = tags.map((a) => { return a.title });
const tagTitles = tags.map((a) => { return a.title }).sort();
this.setState({
promptOptions: {
@@ -158,7 +158,7 @@ class MainScreenComponent extends React.Component {
},
});
} else if (command.name === 'renameTag') {
const tag = await Tag.load(command.id);
const tag = await Tag.load(command.id);
if(!tag) return;
this.setState({
@@ -173,12 +173,12 @@ class MainScreenComponent extends React.Component {
} catch (error) {
bridge().showErrorMessageBox(error.message);
}
}
}
this.setState({promptOptions: null });
}
}
})
} else if (command.name === 'search') {
if (!this.searchId_) this.searchId_ = uuid.create();
@@ -336,14 +336,17 @@ class MainScreenComponent extends React.Component {
}
render() {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const style = Object.assign({
color: theme.color,
backgroundColor: theme.backgroundColor,
}, this.props.style);
const promptOptions = this.state.promptOptions;
const folders = this.props.folders;
const notes = this.props.notes;
const messageBoxVisible = this.props.hasDisabledSyncItems || this.props.showMissingMasterKeyMessage;
const sidebarVisibility = this.props.sidebarVisibility;
const styles = this.styles(this.props.theme, style.width, style.height, messageBoxVisible, sidebarVisibility);
const theme = themeStyle(this.props.theme);
const selectedFolderId = this.props.selectedFolderId;
const onConflictFolder = this.props.selectedFolderId === Folder.conflictFolderId();

View File

@@ -13,9 +13,16 @@ const InteropService = require('lib/services/InteropService');
const InteropServiceHelper = require('../InteropServiceHelper.js');
const Search = require('lib/models/Search');
const Mark = require('mark.js/dist/mark.min.js');
const SearchEngine = require('lib/services/SearchEngine');
class NoteListComponent extends React.Component {
constructor() {
super();
this.itemRenderer = this.itemRenderer.bind(this);
}
style() {
const theme = themeStyle(this.props.theme);
@@ -169,7 +176,10 @@ class NoteListComponent extends React.Component {
menu.popup(bridge().window());
}
itemRenderer(item, theme, width) {
itemRenderer(item) {
const theme = themeStyle(this.props.theme);
const width = this.props.style.width;
const onTitleClick = async (event, item) => {
if (event.ctrlKey) {
event.preventDefault();
@@ -225,8 +235,11 @@ class NoteListComponent extends React.Component {
let highlightedWords = [];
if (this.props.notesParentType === 'Search') {
const search = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
highlightedWords = search ? Search.keywords(search.query_pattern) : [];
const query = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
if (query) {
const parsedQuery = SearchEngine.instance().parseQuery(query.query_pattern);
highlightedWords = SearchEngine.instance().allParsedQueryTerms(parsedQuery);
}
}
let style = Object.assign({ width: width }, this.style().listItem);
@@ -257,7 +270,18 @@ class NoteListComponent extends React.Component {
exclude: ['img'],
acrossElements: true,
});
mark.mark(highlightedWords);
mark.unmark();
for (let i = 0; i < highlightedWords.length; i++) {
const w = highlightedWords[i];
if (w.type === 'regex') {
mark.markRegExp(new RegExp(w.value, 'gmi'), { acrossElements: true });
} else {
mark.mark([w]);
}
}
// Note: in this case it is safe to use dangerouslySetInnerHTML because titleElement
// is a span tag that we created and that contains data that's been inserted as plain text
@@ -269,6 +293,14 @@ class NoteListComponent extends React.Component {
titleComp = <span>{displayTitle}</span>
}
const watchedIconStyle = {
paddingRight: 4,
color: theme.color,
};
const watchedIcon = this.props.watchedNoteFiles.indexOf(item.id) < 0 ? null : (
<i style={watchedIconStyle} className={"fa fa-external-link"}></i>
);
// Need to include "todo_completed" in key so that checkbox is updated when
// item is changed via sync.
return <div key={item.id + '_' + item.todo_completed} style={style}>
@@ -283,6 +315,7 @@ class NoteListComponent extends React.Component {
onDragStart={(event) => onDragStart(event) }
data-id={item.id}
>
{watchedIcon}
{titleComp}
</a>
</div>
@@ -313,7 +346,7 @@ class NoteListComponent extends React.Component {
style={style}
className={"note-list"}
items={notes}
itemRenderer={ (item) => { return this.itemRenderer(item, theme, style.width) } }
itemRenderer={this.itemRenderer}
></ItemList>
);
}
@@ -329,6 +362,7 @@ const mapStateToProps = (state) => {
notesParentType: state.notesParentType,
searches: state.searches,
selectedSearchId: state.selectedSearchId,
watchedNoteFiles: state.watchedNoteFiles,
};
};

View File

@@ -110,12 +110,12 @@ class NotePropertiesDialog extends React.Component {
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.6)',
alignItems: 'flex-start',
justifyContent: 'center',
alignItems: 'flex-start',
justifyContent: 'center',
};
this.styles_.dialogBox = {
backgroundColor: 'white',
backgroundColor: theme.backgroundColor,
padding: 16,
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
marginTop: 20,
@@ -123,17 +123,33 @@ class NotePropertiesDialog extends React.Component {
this.styles_.controlBox = {
marginBottom: '1em',
color: 'black', //This will apply for the calendar
};
this.styles_.button = {
minWidth: theme.buttonMinWidth,
minHeight: theme.buttonMinHeight,
marginLeft: 5,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.editPropertyButton = {
color: theme.color,
textDecoration: 'none',
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.input = {
display:'inline-block',
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.dialogTitle = Object.assign({}, theme.h1Style, { marginBottom: '1.2em' });
@@ -239,7 +255,8 @@ class NotePropertiesDialog extends React.Component {
dateFormat={time.dateFormat()}
timeFormat={time.timeFormat()}
inputProps={{
onKeyDown: (event) => onKeyDown(event, key)
onKeyDown: (event) => onKeyDown(event, key),
style: styles.input
}}
onChange={(momentObject) => {this.setState({ editedValue: momentObject })}}
/>
@@ -254,7 +271,7 @@ class NotePropertiesDialog extends React.Component {
ref="editField"
onChange={(event) => {this.setState({ editedValue: event.target.value })}}
onKeyDown={(event) => onKeyDown(event)}
style={{display:'inline-block'}}
style={styles.input}
/>
}
} else {
@@ -349,7 +366,7 @@ class NotePropertiesDialog extends React.Component {
return (
<div style={modalLayerStyle}>
<div style={styles.dialogBox}>
<div style={styles.dialogTitle}>Note properties</div>
<div style={styles.dialogTitle}>{_('Note properties')}</div>
<div>{noteComps}</div>
<div style={{ textAlign: 'right', marginTop: 10 }}>
{buttonComps}
@@ -361,4 +378,4 @@ class NotePropertiesDialog extends React.Component {
}
module.exports = NotePropertiesDialog;
module.exports = NotePropertiesDialog;

View File

@@ -0,0 +1,122 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
const { _ } = require('lib/locale.js');
class NoteSearchBarComponent extends React.Component {
constructor() {
super();
this.state = {
query: '',
};
this.searchInput_change = this.searchInput_change.bind(this);
this.previousButton_click = this.previousButton_click.bind(this);
this.nextButton_click = this.nextButton_click.bind(this);
this.closeButton_click = this.closeButton_click.bind(this);
}
style() {
const theme = themeStyle(this.props.theme);
let style = {
root: Object.assign({}, theme.textStyle, {
backgroundColor: theme.backgroundColor,
color: theme.colorFaded,
}),
};
return style;
}
componentDidMount() {
this.refs.searchInput.focus();
}
buttonIconComponent(iconName, clickHandler) {
const theme = themeStyle(this.props.theme);
const searchButton = {
paddingLeft: 4,
paddingRight: 4,
paddingTop: 2,
paddingBottom: 2,
textDecoration: 'none',
marginRight: 5,
};
const iconStyle = {
display: 'flex',
fontSize: Math.round(theme.fontSize) * 1.2,
color: theme.color,
};
const icon = <i style={iconStyle} className={"fa " + iconName}></i>
return (
<a
href="#"
style={searchButton}
onClick={clickHandler}
>{icon}</a>
);
}
searchInput_change(event) {
const query = event.currentTarget.value;
this.setState({ query: query });
this.triggerOnChange(query);
}
previousButton_click(event) {
if (this.props.onPrevious) this.props.onPrevious();
}
nextButton_click(event) {
if (this.props.onNext) this.props.onNext();
}
closeButton_click(event) {
if (this.props.onClose) this.props.onClose();
}
triggerOnChange(query) {
if (this.props.onChange) this.props.onChange(query);
}
focus() {
this.refs.searchInput.focus();
}
render() {
const theme = themeStyle(this.props.theme);
const closeButton = this.buttonIconComponent('fa-times', this.closeButton_click);
const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click);
const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click);
return (
<div style={this.props.style}>
<div style={{display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
{ closeButton }
<input placeholder={_('Search...')} value={this.state.query} onChange={this.searchInput_change} ref="searchInput" type="text" style={{width: 200, marginRight: 5}}></input>
{ nextButton }
{ previousButton }
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
theme: state.settings.theme,
};
};
const NoteSearchBar = connect(mapStateToProps, null, null, { withRef: true })(NoteSearchBarComponent);
module.exports = NoteSearchBar;

View File

@@ -6,8 +6,9 @@ const Search = require('lib/models/Search.js');
const { time } = require('lib/time-utils.js');
const Setting = require('lib/models/Setting.js');
const { IconButton } = require('./IconButton.min.js');
const { urlDecode } = require('lib/string-utils');
const { urlDecode, escapeHtml } = require('lib/string-utils');
const Toolbar = require('./Toolbar.min.js');
const TagList = require('./TagList.min.js');
const { connect } = require('react-redux');
const { _ } = require('lib/locale.js');
const { reg } = require('lib/registry.js');
@@ -24,24 +25,36 @@ const fs = require('fs-extra');
const md5 = require('md5');
const mimeUtils = require('lib/mime-utils.js').mime;
const ArrayUtils = require('lib/ArrayUtils');
const ObjectUtils = require('lib/ObjectUtils');
const urlUtils = require('lib/urlUtils');
const dialogs = require('./dialogs');
const NoteSearchBar = require('./NoteSearchBar.min.js');
const markdownUtils = require('lib/markdownUtils');
const ExternalEditWatcher = require('lib/services/ExternalEditWatcher');
const ResourceFetcher = require('lib/services/ResourceFetcher');
const { toSystemSlashes, safeFilename } = require('lib/path-utils');
const { clipboard } = require('electron');
const SearchEngine = require('lib/services/SearchEngine');
require('brace/mode/markdown');
// https://ace.c9.io/build/kitchen-sink.html
// https://highlightjs.org/static/demo/
require('brace/theme/chrome');
require('brace/theme/twilight');
const NOTE_TAG_BAR_FEATURE_ENABLED = false;
class NoteTextComponent extends React.Component {
constructor() {
super();
this.localSearchDefaultState = {
query: '',
selectedIndex: 0,
resultCount: 0,
};
this.state = {
note: null,
noteMetadata: '',
@@ -53,6 +66,7 @@ class NoteTextComponent extends React.Component {
scrollHeight: null,
editorScrollTop: 0,
newNote: null,
noteTags: [],
// If the current note was just created, and the title has never been
// changed by the user, this variable contains that note ID. Used
@@ -60,6 +74,8 @@ class NoteTextComponent extends React.Component {
newAndNoTitleChangeNoteId: null,
bodyHtml: '',
lastKeys: [],
showLocalSearch: false,
localSearch: Object.assign({}, this.localSearchDefaultState),
};
this.lastLoadedNoteId_ = null;
@@ -69,8 +85,10 @@ class NoteTextComponent extends React.Component {
this.scheduleSaveTimeout_ = null;
this.restoreScrollTop_ = null;
this.lastSetHtml_ = '';
this.lastSetMarkers_ = [];
this.lastSetMarkers_ = '';
this.lastSetMarkersOptions_ = {};
this.selectionRange_ = null;
this.noteSearchBar_ = React.createRef();
// Complicated but reliable method to get editor content height
// https://github.com/ajaxorg/ace/issues/2046
@@ -209,11 +227,41 @@ class NoteTextComponent extends React.Component {
this.updateHtml(this.state.note.body);
}
}
this.noteSearchBar_change = (query) => {
this.setState({ localSearch: {
query: query,
selectedIndex: 0,
}});
}
const noteSearchBarNextPrevious = (inc) => {
const ls = Object.assign({}, this.state.localSearch);
ls.selectedIndex += inc;
if (ls.selectedIndex < 0) ls.selectedIndex = ls.resultCount - 1;
if (ls.selectedIndex >= ls.resultCount) ls.selectedIndex = 0;
this.setState({ localSearch: ls });
}
this.noteSearchBar_next = () => {
noteSearchBarNextPrevious(+1);
}
this.noteSearchBar_previous = () => {
noteSearchBarNextPrevious(-1);
}
this.noteSearchBar_close = () => {
this.setState({
showLocalSearch: false,
});
}
}
// Note:
// - What's called "cursor position" is expressed as { row: x, column: y } and is how Ace Editor get/set the cursor position
// - A "range" defines a selection with a start and end cusor position, expressed as { start: <CursorPos>, end: <CursorPos> }
// - A "range" defines a selection with a start and end cusor position, expressed as { start: <CursorPos>, end: <CursorPos> }
// - A "text offset" below is the absolute position of the cursor in the string, as would be used in the indexOf() function.
// The functions below are used to convert between the different types.
rangeToTextOffsets(range, body) {
@@ -261,7 +309,7 @@ class NoteTextComponent extends React.Component {
}
row++;
currentOffset += line.length + 1;
currentOffset += line.length + 1;
}
}
@@ -275,11 +323,12 @@ class NoteTextComponent extends React.Component {
async componentWillMount() {
let note = null;
let noteTags = [];
if (this.props.newNote) {
note = Object.assign({}, this.props.newNote);
} else if (this.props.noteId) {
note = await Note.load(this.props.noteId);
noteTags = this.props.noteTags || [];
}
const folder = note ? Folder.byId(this.props.folders, note.parent_id) : null;
@@ -289,6 +338,7 @@ class NoteTextComponent extends React.Component {
note: note,
folder: folder,
isLoading: false,
noteTags: noteTags
});
this.lastLoadedNoteId_ = note ? note.id : null;
@@ -300,6 +350,7 @@ class NoteTextComponent extends React.Component {
eventManager.on('todoToggle', this.onTodoToggle_);
ResourceFetcher.instance().on('downloadComplete', this.resourceFetcher_downloadComplete);
ExternalEditWatcher.instance().on('noteChange', this.externalEditWatcher_noteChange);
}
componentWillUnmount() {
@@ -313,8 +364,7 @@ class NoteTextComponent extends React.Component {
eventManager.removeListener('todoToggle', this.onTodoToggle_);
ResourceFetcher.instance().off('downloadComplete', this.resourceFetcher_downloadComplete);
this.destroyExternalEditWatcher();
ExternalEditWatcher.instance().off('noteChange', this.externalEditWatcher_noteChange);
}
async saveIfNeeded(saveIfNewNote = false) {
@@ -327,7 +377,7 @@ class NoteTextComponent extends React.Component {
}
await shared.saveNoteButton_press(this);
this.externalEditWatcherUpdateNoteFile(this.state.note);
ExternalEditWatcher.instance().updateNoteFile(this.state.note);
}
async saveOneProperty(name, value) {
@@ -361,14 +411,15 @@ class NoteTextComponent extends React.Component {
let note = null;
let loadingNewNote = true;
let parentFolder = null;
let noteTags = [];
if (props.newNote) {
note = Object.assign({}, props.newNote);
this.lastLoadedNoteId_ = null;
this.externalEditWatcherStopWatchingAll();
} else {
noteId = props.noteId;
loadingNewNote = stateNoteId !== noteId;
noteTags = await Tag.tagsByNoteId(noteId);
this.lastLoadedNoteId_ = noteId;
note = noteId ? await Note.load(noteId) : null;
if (noteId !== this.lastLoadedNoteId_) return; // Race condition - current note was changed while this one was loading
@@ -391,8 +442,6 @@ class NoteTextComponent extends React.Component {
// Scroll back to top when loading new note
if (loadingNewNote) {
this.externalEditWatcherStopWatchingAll();
this.editorMaxScrollTop_ = 0;
// HACK: To go around a bug in Ace editor, we first set the scroll position to 1
@@ -435,8 +484,7 @@ class NoteTextComponent extends React.Component {
}
}
if (note)
{
if (note) {
parentFolder = Folder.byId(props.folders, note.parent_id);
}
@@ -446,6 +494,7 @@ class NoteTextComponent extends React.Component {
webviewReady: webviewReady,
folder: parentFolder,
lastKeys: [],
noteTags: noteTags
};
if (!note) {
@@ -454,11 +503,33 @@ class NoteTextComponent extends React.Component {
newState.newAndNoTitleChangeNoteId = null;
}
if (!note || loadingNewNote) {
newState.showLocalSearch = false;
newState.localSearch = Object.assign({}, this.localSearchDefaultState);
}
this.lastSetHtml_ = '';
this.lastSetMarkers_ = [];
this.lastSetMarkers_ = '';
this.lastSetMarkersOptions_ = {};
this.setState(newState);
// https://github.com/laurent22/joplin/pull/893#discussion_r228025210
// @Abijeet: Had to add this check. If not, was going into an infinite loop where state was getting updated repeatedly.
// Since I'm updating the state, the componentWillReceiveProps was getting triggered again, where nextProps.newNote was still true, causing reloadNote to trigger again and again.
// Notes from Laurent: The selected note tags are part of the global Redux state because they need to be updated whenever tags are changed or deleted
// anywhere in the app. Thus it's not possible simple to load the tags here (as we won't have a way to know if they're updated afterwards).
// Perhaps a better way would be to move that code in the middleware, check for TAGS_DELETE, TAGS_UPDATE, etc. actions and update the
// selected note tags accordingly.
if (NOTE_TAG_BAR_FEATURE_ENABLED) {
if (!this.props.newNote) {
this.props.dispatch({
type: "SET_NOTE_TAGS",
items: noteTags,
});
}
}
this.updateHtml(newState.note ? newState.note.body : '');
}
@@ -467,6 +538,10 @@ class NoteTextComponent extends React.Component {
await this.reloadNote(nextProps);
} else if ('noteId' in nextProps && nextProps.noteId !== this.props.noteId) {
await this.reloadNote(nextProps);
} else if ('noteTags' in nextProps && this.areNoteTagsModified(nextProps.noteTags, this.state.noteTags)) {
this.setState({
noteTags: nextProps.noteTags
});
}
if ('syncStarted' in nextProps && !nextProps.syncStarted && !this.isModified()) {
@@ -482,6 +557,26 @@ class NoteTextComponent extends React.Component {
return shared.isModified(this);
}
areNoteTagsModified(newTags, oldTags) {
if (!NOTE_TAG_BAR_FEATURE_ENABLED) return false;
if (!oldTags) return true;
if (newTags.length !== oldTags.length) return true;
for (let i = 0; i < newTags.length; ++i) {
let currNewTag = newTags[i];
for (let j = 0; j < oldTags.length; ++j) {
let currOldTag = oldTags[j];
if (currOldTag.id === currNewTag.id && currOldTag.updated_time !== currNewTag.updated_time) {
return true;
}
}
}
return false;
}
refreshNoteMetadata(force = null) {
return shared.refreshNoteMetadata(this, force);
}
@@ -518,6 +613,10 @@ class NoteTextComponent extends React.Component {
const newBody = this.mdToHtml_.handleCheckboxClick(msg, this.state.note.body);
this.saveOneProperty('body', newBody);
} else if (msg === 'setMarkerCount') {
const ls = Object.assign({}, this.state.localSearch);
ls.resultCount = arg0;
this.setState({ localSearch: ls });
} else if (msg === 'percentScroll') {
this.ignoreNextEditorScroll_ = true;
this.setEditorPercentScroll(arg0);
@@ -567,7 +666,8 @@ class NoteTextComponent extends React.Component {
if (!item) throw new Error('No item with ID ' + itemId);
if (item.type_ === BaseModel.TYPE_RESOURCE) {
if (item.fetch_status !== Resource.FETCH_STATUS_DONE || !!item.encryption_blob_encrypted) {
const localState = await Resource.localState(item);
if (localState.fetch_status !== Resource.FETCH_STATUS_DONE || !!item.encryption_blob_encrypted) {
bridge().showErrorMessageBox(_('This attachment is not downloaded or not decrypted yet.'));
return;
}
@@ -575,16 +675,10 @@ class NoteTextComponent extends React.Component {
bridge().openItem(filePath);
} else if (item.type_ === BaseModel.TYPE_NOTE) {
this.props.dispatch({
type: "FOLDER_SELECT",
id: item.parent_id,
type: "FOLDER_AND_NOTE_SELECT",
folderId: item.parent_id,
noteId: item.id,
});
setTimeout(() => {
this.props.dispatch({
type: 'NOTE_SELECT',
id: item.id,
});
}, 10);
} else {
throw new Error('Unsupported item type: ' + item.type_);
}
@@ -595,6 +689,8 @@ class NoteTextComponent extends React.Component {
} else {
require('electron').shell.openExternal(msg);
}
} else if (msg.indexOf('#') === 0) {
// This is an internal anchor, which is handled by the WebView so skip this case
} else {
bridge().showErrorMessageBox(_('Unsupported link or message: %s', msg));
}
@@ -797,6 +893,7 @@ class NoteTextComponent extends React.Component {
let bodyToRender = body;
if (bodyToRender === null) bodyToRender = this.state.note && this.state.note.body ? this.state.note.body : '';
bodyToRender = '<style>' + this.props.customCss + '</style>\n' + bodyToRender;
let bodyHtml = '';
const visiblePanes = this.props.visiblePanes || ['editor', 'viewer'];
@@ -814,43 +911,48 @@ class NoteTextComponent extends React.Component {
async doCommand(command) {
if (!command || !this.state.note) return;
let commandProcessed = true;
let fn = null;
if (command.name === 'exportPdf' && this.webview_) {
const path = bridge().showSaveDialog({
filters: [{ name: _('PDF File'), extensions: ['pdf']}],
defaultPath: safeFilename(this.state.note.title),
});
if (path) {
this.webview_.printToPDF({}, (error, data) => {
if (error) {
bridge().showErrorMessageBox(error.message);
} else {
shim.fsDriver().writeFile(path, data, 'buffer');
}
});
}
fn = this.commandSavePdf;
} else if (command.name === 'print' && this.webview_) {
this.webview_.print();
fn = this.commandPrint;
} else if (command.name === 'textBold') {
this.commandTextBold();
fn = this.commandTextBold;
} else if (command.name === 'textItalic') {
this.commandTextItalic();
fn = this.commandTextItalic;
} else if (command.name === 'insertDateTime' ) {
this.commandDateTime();
fn = this.commandDateTime;
} else if (command.name === 'commandStartExternalEditing') {
this.commandStartExternalEditing();
} else {
commandProcessed = false;
fn = this.commandStartExternalEditing;
} else if (command.name === 'showLocalSearch') {
fn = this.commandShowLocalSearch;
}
if (commandProcessed) {
this.props.dispatch({
type: 'WINDOW_COMMAND',
name: null,
});
if (!fn) return;
this.props.dispatch({
type: 'WINDOW_COMMAND',
name: null,
});
requestAnimationFrame(() => {
fn = fn.bind(this);
fn();
});
}
commandShowLocalSearch() {
if (this.state.showLocalSearch) {
this.noteSearchBar_.current.wrappedInstance.focus();
} else {
this.setState({ showLocalSearch: true });
}
this.props.dispatch({
type: 'NOTE_VISIBLE_PANES_SET',
panes: ['editor', 'viewer'],
});
}
async commandAttachFile(filePaths = null) {
@@ -895,42 +997,66 @@ class NoteTextComponent extends React.Component {
});
}
externalEditWatcher() {
if (!this.externalEditWatcher_) {
this.externalEditWatcher_ = new ExternalEditWatcher((action) => { return this.props.dispatch(action) });
this.externalEditWatcher_.setLogger(reg.logger());
this.externalEditWatcher_.on('noteChange', this.externalEditWatcher_noteChange);
printTo_(target, options) {
const previousBody = this.state.note.body;
const tempBody = "# " + this.state.note.title + "\n\n" + previousBody;
const previousTheme = Setting.value('theme');
Setting.setValue('theme', Setting.THEME_LIGHT);
this.lastSetHtml_ = '';
this.updateHtml(tempBody);
this.forceUpdate();
const restoreSettings = () => {
Setting.setValue('theme', previousTheme);
this.lastSetHtml_ = '';
this.updateHtml(previousBody);
this.forceUpdate();
}
return this.externalEditWatcher_;
setTimeout(() => {
if (target === 'pdf') {
this.webview_.printToPDF({}, (error, data) => {
restoreSettings();
if (error) {
bridge().showErrorMessageBox(error.message);
} else {
shim.fsDriver().writeFile(options.path, data, 'buffer');
}
});
} else if (target === 'printer') {
this.webview_.print();
restoreSettings();
}
}, 100);
}
externalEditWatcherUpdateNoteFile(note) {
if (this.externalEditWatcher_) this.externalEditWatcher().updateNoteFile(note);
commandSavePdf() {
const path = bridge().showSaveDialog({
filters: [{ name: _('PDF File'), extensions: ['pdf']}],
defaultPath: safeFilename(this.state.note.title),
});
if (path) {
this.printTo_('pdf', { path: path });
}
}
externalEditWatcherStopWatchingAll() {
if (this.externalEditWatcher_) this.externalEditWatcher().stopWatchingAll();
}
destroyExternalEditWatcher() {
if (!this.externalEditWatcher_) return;
this.externalEditWatcher_.off('noteChange', this.externalEditWatcher_noteChange);
this.externalEditWatcher_.stopWatchingAll();
this.externalEditWatcher_ = null;
commandPrint() {
this.printTo_('printer');
}
async commandStartExternalEditing() {
try {
await this.externalEditWatcher().openAndWatch(this.state.note);
await ExternalEditWatcher.instance().openAndWatch(this.state.note);
} catch (error) {
bridge().showErrorMessageBox(_('Error opening note in editor: %s', error.message));
}
}
async commandStopExternalEditing() {
this.externalEditWatcherStopWatchingAll();
ExternalEditWatcher.instance().stopWatching(this.state.note.id);
}
async commandSetTags() {
@@ -1356,14 +1482,32 @@ class NoteTextComponent extends React.Component {
paddingLeft: 8,
paddingRight: 8,
marginRight: rootStyle.paddingLeft,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
const toolbarStyle = {
marginBottom: 10,
};
const bottomRowHeight = rootStyle.height - titleBarStyle.height - titleBarStyle.marginBottom - titleBarStyle.marginTop - theme.toolbarHeight - toolbarStyle.marginBottom;
const tagStyle = {
marginBottom: 10,
height: 30
};
const searchBarHeight = this.state.showLocalSearch ? 35 : 0;
let bottomRowHeight = 0;
if (NOTE_TAG_BAR_FEATURE_ENABLED) {
bottomRowHeight = rootStyle.height - titleBarStyle.height - titleBarStyle.marginBottom - titleBarStyle.marginTop - theme.toolbarHeight - tagStyle.height - tagStyle.marginBottom;
} else {
toolbarStyle.marginBottom = 10;
bottomRowHeight = rootStyle.height - titleBarStyle.height - titleBarStyle.marginBottom - titleBarStyle.marginTop - theme.toolbarHeight - toolbarStyle.marginBottom;
}
bottomRowHeight -= searchBarHeight;
const viewerStyle = {
width: Math.floor(innerWidth / 2),
height: bottomRowHeight,
@@ -1383,7 +1527,10 @@ class NoteTextComponent extends React.Component {
verticalAlign: 'top',
paddingTop: paddingTop + 'px',
lineHeight: theme.textAreaLineHeight + 'px',
fontSize: theme.fontSize + 'px',
fontSize: theme.editorFontSize + 'px',
color: theme.color,
backgroundColor: theme.backgroundColor,
editorTheme: theme.editorTheme,
};
if (visiblePanes.indexOf('viewer') < 0) {
@@ -1414,16 +1561,30 @@ class NoteTextComponent extends React.Component {
const htmlHasChanged = this.lastSetHtml_ !== html;
if (htmlHasChanged) {
this.webview_.send('setHtml', html);
let options = {codeTheme: theme.codeThemeCss};
this.webview_.send('setHtml', html, options);
this.lastSetHtml_ = html;
}
const search = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
const keywords = search ? Search.keywords(search.query_pattern) : [];
let keywords = [];
const markerOptions = {};
if (htmlHasChanged || !ArrayUtils.contentEquals(this.lastSetMarkers_, keywords)) {
this.lastSetMarkers_ = [];
this.webview_.send('setMarkers', keywords);
if (this.state.showLocalSearch) {
keywords = [this.state.localSearch.query];
markerOptions.selectedIndex = this.state.localSearch.selectedIndex;
} else {
const search = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
if (search) {
const parsedQuery = SearchEngine.instance().parseQuery(search.query_pattern);
keywords = SearchEngine.instance().allParsedQueryTerms(parsedQuery);
}
}
const keywordHash = JSON.stringify(keywords);
if (htmlHasChanged || keywordHash !== this.lastSetMarkers_ || !ObjectUtils.fieldsEqual(this.lastSetMarkersOptions_, markerOptions)) {
this.lastSetMarkers_ = keywordHash;
this.lastSetMarkersOptions_ = Object.assign({}, markerOptions);
this.webview_.send('setMarkers', keywords, markerOptions);
}
}
@@ -1443,6 +1604,11 @@ class NoteTextComponent extends React.Component {
placeholder={ this.props.newNote ? _('Creating new %s...', isTodo ? _('to-do') : _('note')) : '' }
/>
const tagList = !NOTE_TAG_BAR_FEATURE_ENABLED ? null : <TagList
style={tagStyle}
items={this.state.noteTags}
/>;
const titleBarMenuButton = <IconButton style={{
display: 'flex',
}} iconName="fa-caret-down" theme={this.props.theme} onClick={() => { this.itemContextMenu() }} />
@@ -1482,7 +1648,7 @@ class NoteTextComponent extends React.Component {
const editor = <AceEditor
value={body}
mode="markdown"
theme="chrome"
theme={editorRootStyle.editorTheme}
style={editorRootStyle}
width={editorStyle.width + 'px'}
height={editorStyle.height + 'px'}
@@ -1506,6 +1672,17 @@ class NoteTextComponent extends React.Component {
highlightActiveLine={false}
/>
const noteSearchBarComp = !this.state.showLocalSearch ? null : (
<NoteSearchBar
ref={this.noteSearchBar_}
style={{display: 'flex', height:searchBarHeight,width:innerWidth, borderTop: '1px solid ' + theme.dividerColor}}
onChange={this.noteSearchBar_change}
onNext={this.noteSearchBar_next}
onPrevious={this.noteSearchBar_previous}
onClose={this.noteSearchBar_close}
/>
);
return (
<div style={rootStyle} onDrop={this.onDrop_}>
<div style={titleBarStyle}>
@@ -1514,8 +1691,11 @@ class NoteTextComponent extends React.Component {
{ false ? titleBarMenuButton : null }
</div>
{ toolbar }
{ tagList }
{ editor }
{ viewer }
<div style={{clear:'both'}}/>
{ noteSearchBarComp }
</div>
);
}
@@ -1525,6 +1705,7 @@ class NoteTextComponent extends React.Component {
const mapStateToProps = (state) => {
return {
noteId: state.selectedNoteIds.length === 1 ? state.selectedNoteIds[0] : null,
noteTags: state.selectedNoteTags,
folderId: state.selectedFolderId,
itemType: state.selectedItemType,
folders: state.folders,
@@ -1537,9 +1718,10 @@ const mapStateToProps = (state) => {
searches: state.searches,
selectedSearchId: state.selectedSearchId,
watchedNoteFiles: state.watchedNoteFiles,
customCss: state.customCss,
};
};
const NoteText = connect(mapStateToProps)(NoteTextComponent);
module.exports = { NoteText };
module.exports = { NoteText };

View File

@@ -73,14 +73,14 @@ class OneDriveLoginScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const webviewStyle = {
width: this.props.style.width,
height: this.props.style.height - theme.headerHeight,
overflow: 'hidden',
color: theme.color,
backgroundColor: theme.backgroundColor,
};
const headerButtons = [
@@ -109,4 +109,4 @@ const mapStateToProps = (state) => {
const OneDriveLoginScreen = connect(mapStateToProps)(OneDriveLoginScreenComponent);
module.exports = { OneDriveLoginScreen };
module.exports = { OneDriveLoginScreen };

View File

@@ -59,7 +59,7 @@ class PromptDialog extends React.Component {
};
this.styles_.promptDialog = {
backgroundColor: 'white',
backgroundColor: theme.backgroundColor,
padding: 16,
display: 'inline-block',
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
@@ -69,6 +69,10 @@ class PromptDialog extends React.Component {
minWidth: theme.buttonMinWidth,
minHeight: theme.buttonMinHeight,
marginLeft: 5,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.label = {
@@ -82,6 +86,10 @@ class PromptDialog extends React.Component {
this.styles_.input = {
width: 0.5 * width,
maxWidth: 400,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.desc = Object.assign({}, theme.textStyle, {
@@ -142,6 +150,7 @@ class PromptDialog extends React.Component {
if (this.props.inputType === 'datetime') {
inputComp = <Datetime
value={this.state.answer}
inputProps={{style: styles.input}}
dateFormat={time.dateFormat()}
timeFormat={time.timeFormat()}
onChange={(momentObject) => onDateTimeChange(momentObject)}
@@ -166,7 +175,7 @@ class PromptDialog extends React.Component {
<div style={styles.modalLayer}>
<div style={styles.promptDialog}>
<label style={styles.label}>{this.props.label ? this.props.label : ''}</label>
<div style={{display: 'inline-block'}}>
<div style={{display: 'inline-block', color: 'black', backgroundColor: theme.backgroundColor}}>
{inputComp}
{descComp}
</div>
@@ -180,4 +189,4 @@ class PromptDialog extends React.Component {
}
module.exports = { PromptDialog };
module.exports = { PromptDialog };

View File

@@ -12,6 +12,7 @@ const { bridge } = require("electron").remote.require("./bridge");
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
const InteropServiceHelper = require("../InteropServiceHelper.js");
const { shim } = require('lib/shim');
class SideBarComponent extends React.Component {
@@ -178,6 +179,35 @@ class SideBarComponent extends React.Component {
return style;
}
clearForceUpdateDuringSync() {
if (this.forceUpdateDuringSyncIID_) {
clearInterval(this.forceUpdateDuringSyncIID_);
this.forceUpdateDuringSyncIID_ = null;
}
}
componentDidUpdate(prevProps) {
if (shim.isLinux()) {
// For some reason, the UI seems to sleep in some Linux distro during
// sync. Cannot find the reason for it and cannot replicate, so here
// as a test force the update at regular intervals.
// https://github.com/laurent22/joplin/issues/312#issuecomment-429472193
if (!prevProps.syncStarted && this.props.syncStarted) {
this.clearForceUpdateDuringSync();
this.forceUpdateDuringSyncIID_ = setInterval(() => {
this.forceUpdate();
}, 2000);
}
if (prevProps.syncStarted && !this.props.syncStarted) this.clearForceUpdateDuringSync();
}
}
componentWillUnmount() {
this.clearForceUpdateDuringSync();
}
itemContextMenu(event) {
const itemId = event.target.getAttribute("data-id");
if (itemId === Folder.conflictFolderId()) return;
@@ -475,7 +505,13 @@ class SideBarComponent extends React.Component {
decryptionReportText = _('Decrypting items: %d/%d', this.props.decryptionWorker.itemIndex + 1, this.props.decryptionWorker.itemCount);
}
let resourceFetcherText = '';
if (this.props.resourceFetcher && this.props.resourceFetcher.toFetchCount) {
resourceFetcherText = _('Fetching resources: %d', this.props.resourceFetcher.toFetchCount);
}
let lines = Synchronizer.reportToLines(this.props.syncReport);
if (resourceFetcherText) lines.push(resourceFetcherText);
if (decryptionReportText) lines.push(decryptionReportText);
const syncReportText = [];
for (let i = 0; i < lines.length; i++) {
@@ -517,6 +553,7 @@ const mapStateToProps = state => {
theme: state.settings.theme,
collapsedFolderIds: state.collapsedFolderIds,
decryptionWorker: state.decryptionWorker,
resourceFetcher: state.resourceFetcher,
};
};

View File

@@ -47,17 +47,14 @@ class StatusScreenComponent extends React.Component {
const theme = themeStyle(this.props.theme);
const style = this.props.style;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerPadding = 10;
const containerStyle = {
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: containerPadding,
overflowY: 'auto',
height: style.height - theme.headerHeight - containerPadding * 2,
};
});
function renderSectionTitleHtml(key, title) {
return <h2 key={'section_' + key} style={theme.h2Style}>{title}</h2>
@@ -134,4 +131,4 @@ const mapStateToProps = (state) => {
const StatusScreen = connect(mapStateToProps)(StatusScreenComponent);
module.exports = { StatusScreen };
module.exports = { StatusScreen };

View File

@@ -0,0 +1,21 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
class TagItemComponent extends React.Component {
render() {
const theme = themeStyle(this.props.theme);
const style = Object.assign({}, theme.tagStyle);
const title = this.props.title;
return <span style={style}>{title}</span>;
}
}
const mapStateToProps = (state) => {
return { theme: state.settings.theme };
};
const TagItem = connect(mapStateToProps)(TagItemComponent);
module.exports = TagItem;

View File

@@ -0,0 +1,50 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
const TagItem = require('./TagItem.min.js');
class TagListComponent extends React.Component {
render() {
const style = Object.assign({}, this.props.style);
const theme = themeStyle(this.props.theme);
const tags = this.props.items;
style.display = 'flex';
style.flexDirection = 'row';
style.borderBottom = '1px solid ' + theme.dividerColor;
style.boxSizing = 'border-box';
style.fontSize = theme.fontSize;
const tagItems = [];
if (tags || tags.length > 0) {
// Sort by id for now, but probably needs to be changed in the future.
tags.sort((a, b) => { return a.title < b.title ? -1 : +1; });
for (let i = 0; i < tags.length; i++) {
const props = {
title: tags[i].title,
key: tags[i].id
};
tagItems.push(<TagItem {...props} />);
}
}
if (tagItems.length === 0) {
style.visibility = 'hidden';
}
return (
<div className="tag-list" style={style}>
{ tagItems }
</div>
)
}
}
const mapStateToProps = (state) => {
return { theme: state.settings.theme };
};
const TagList = connect(mapStateToProps)(TagListComponent);
module.exports = TagList;

View File

@@ -30,4 +30,4 @@ class Dialogs {
const dialogs = new Dialogs();
module.exports = dialogs;
module.exports = dialogs;

View File

@@ -0,0 +1,77 @@
/*
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
line-height: 1.3em;
color: #abb2bf;
background: #282c34;
border-radius: 5px;
}
.hljs-keyword, .hljs-operator {
color: #F92672;
}
.hljs-pattern-match {
color: #F92672;
}
.hljs-pattern-match .hljs-constructor {
color: #61aeee;
}
.hljs-function {
color: #61aeee;
}
.hljs-function .hljs-params {
color: #A6E22E;
}
.hljs-function .hljs-params .hljs-typing {
color: #FD971F;
}
.hljs-module-access .hljs-module {
color: #7e57c2;
}
.hljs-constructor {
color: #e2b93d;
}
.hljs-constructor .hljs-string {
color: #9CCC65;
}
.hljs-comment, .hljs-quote {
color: #b18eb1;
font-style: italic;
}
.hljs-doctag, .hljs-formula {
color: #c678dd;
}
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
color: #98c379;
}
.hljs-built_in, .hljs-class .hljs-title {
color: #e6c07b;
}
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
color: #d19a66;
}
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

View File

@@ -16,6 +16,11 @@
}
mark {
background: #F3B717;
color: black;
}
.mark-selected {
background: #CF3F00;
color: white;
}
@@ -59,7 +64,7 @@
let hljsScriptAdded = false;
let hljsLoaded = false;
function loadHljs(callback) {
function loadHljs(options) {
hljsScriptAdded = true;
const script = document.createElement('script');
@@ -74,16 +79,16 @@
link.rel = 'stylesheet';
// https://ace.c9.io/build/kitchen-sink.html
// https://highlightjs.org/static/demo/
link.href = 'highlight/styles/atom-one-light.css';
link.href = 'highlight/styles/' + options.codeTheme;
document.getElementById('hlScriptContainer').appendChild(link);
}
function loadAndApplyHljs() {
function loadAndApplyHljs(options) {
var codeElements = document.getElementsByClassName('code');
if (!codeElements.length) return;
if (!hljsScriptAdded) {
this.loadHljs();
this.loadHljs(options);
return;
}
@@ -138,11 +143,13 @@
ipc.setHtml = (event) => {
const html = event.html;
markJsHackMarkerInserted_ = false;
updateBodyHeight();
contentElement.innerHTML = html;
loadAndApplyHljs();
loadAndApplyHljs(event.options);
// Remove the bullet from "ul" for checkbox lists and extra padding
// const checkboxes = document.getElementsByClassName('checkbox');
@@ -191,8 +198,34 @@
setPercentScroll(percent);
}
// HACK for Mark.js bug - https://github.com/julmot/mark.js/issues/127
let markJsHackMarkerInserted_ = false;
function addMarkJsSpaceHack(document) {
if (markJsHackMarkerInserted_) return;
const prepareElementsForMarkJs = (elements, type) => {
// const markJsHackMarker_ = '&#8203; &#8203;'
const markJsHackMarker_ = ' ';
for (let i = 0; i < elements.length; i++) {
if (!type) {
elements[i].innerHTML = elements[i].innerHTML + markJsHackMarker_;
} else if (type === 'insertBefore') {
elements[i].insertAdjacentHTML('beforeBegin', markJsHackMarker_);
}
}
}
prepareElementsForMarkJs(document.getElementsByTagName('p'));
prepareElementsForMarkJs(document.getElementsByTagName('div'));
prepareElementsForMarkJs(document.getElementsByTagName('br'), 'insertBefore');
markJsHackMarkerInserted_ = true;
}
let mark_ = null;
function setMarkers(keywords) {
let markSelectedElement_ = null;
function setMarkers(keywords, options = null) {
if (!options) options = {};
if (!mark_) {
mark_ = new Mark(document.getElementById('content'), {
exclude: ['img'],
@@ -200,26 +233,66 @@
});
}
mark_.mark(keywords);
addMarkJsSpaceHack(document);
mark_.unmark()
if (markSelectedElement_) markSelectedElement_.classList.remove('mark-selected');
let selectedElement = null;
let elementIndex = 0;
const onEachElement = (element) => {
if (!('selectedIndex' in options)) return;
if (('selectedIndex' in options) && elementIndex === options.selectedIndex) {
markSelectedElement_ = element;
element.classList.add('mark-selected');
selectedElement = element;
}
elementIndex++;
}
for (let i = 0; i < keywords.length; i++) {
const keyword = keywords[i];
if (keyword.type === 'regex') {
mark_.markRegExp(new RegExp(keyword.value, 'gmi'), {
each: onEachElement,
acrossElements: true,
});
} else {
mark_.mark([keyword], {
each: onEachElement,
accuracy: 'exactly',
});
}
}
ipcProxySendToHost('setMarkerCount', elementIndex);
if (selectedElement) selectedElement.scrollIntoView();
}
let markLoaded_ = false;
ipc.setMarkers = (event) => {
const keywords = event.keywords;
const options = event.options;
if (!keywords.length && !markLoaded_) return;
if (!markLoaded_) {
const script = document.createElement('script');
script.onload = function() {
setMarkers(keywords);
setMarkers(keywords, options);
};
script.src = '../../node_modules/mark.js/dist/mark.min.js';
document.getElementById('markScriptContainer').appendChild(script);
markLoaded_ = true;
} else {
setMarkers(keywords);
setMarkers(keywords, options);
}
}
@@ -276,12 +349,32 @@
}
});
// Prevent URLs added via <a> tags from being opened within the application itself
function handleInternalLink(event, anchorNode) {
const href = anchorNode.getAttribute('href');
if (href.indexOf('#') === 0) {
event.preventDefault();
location.hash = href;
return true;
}
return false;
}
document.addEventListener('click', function(event) {
const t = event.target;
// Prevent URLs added via <a> tags from being opened within the application itself
// otherwise it would open the whole website within the WebView.
if (t && t.nodeName === 'A' && !t.hasAttribute('data-from-md')) {
if (handleInternalLink(event, t)) return;
event.preventDefault();
ipcProxySendToHost(t.getAttribute('href'));
return;
}
// If this is an internal link, jump to the anchor directly
if (t && t.nodeName === 'A' && t.hasAttribute('data-from-md')) {
if (handleInternalLink(event, t)) return;
}
});
@@ -307,4 +400,4 @@
</script>
</body>
</html>
</html>

View File

@@ -5,16 +5,16 @@
const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('setHtml', (event, html) => {
window.postMessage({ target: 'webview', name: 'setHtml', data: { html: html } }, '*');
ipcRenderer.on('setHtml', (event, html, options) => {
window.postMessage({ target: 'webview', name: 'setHtml', data: { html: html, options: options } }, '*');
});
ipcRenderer.on('setPercentScroll', (event, percent) => {
window.postMessage({ target: 'webview', name: 'setPercentScroll', data: { percent: percent } }, '*');
});
ipcRenderer.on('setMarkers', (event, keywords) => {
window.postMessage({ target: 'webview', name: 'setMarkers', data: { keywords: keywords } }, '*');
ipcRenderer.on('setMarkers', (event, keywords, options) => {
window.postMessage({ target: 'webview', name: 'setMarkers', data: { keywords: keywords, options: options } }, '*');
});
window.addEventListener('message', (event) => {
@@ -33,4 +33,4 @@ window.addEventListener('message', (event) => {
} else {
throw new Error('Unsupported number of args');
}
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -12,9 +12,9 @@ locales['hr_HR'] = require('./hr_HR.json');
locales['it_IT'] = require('./it_IT.json');
locales['ja_JP'] = require('./ja_JP.json');
locales['ko'] = require('./ko.json');
locales['nb_NO'] = require('./nb_NO.json');
locales['nl_BE'] = require('./nl_BE.json');
locales['nl_NL'] = require('./nl_NL.json');
locales['no'] = require('./no.json');
locales['pt_BR'] = require('./pt_BR.json');
locales['ro'] = require('./ro.json');
locales['ru_RU'] = require('./ru_RU.json');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "Joplin",
"version": "1.0.112",
"version": "1.0.119",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4057,17 +4057,17 @@
"integrity": "sha1-FHshJTaQNcpLL30hDcU58Amz3po="
},
"katex": {
"version": "0.10.0-rc.1",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.10.0-rc.1.tgz",
"integrity": "sha512-JmnreLp0lWPA1z1krzO5drN1qBrkhqzMg5qv0l5y+Fr97sqgOuh37k9ky7VD1k/Ec+yvOe2BptiYSR9OoShkFg==",
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.10.0.tgz",
"integrity": "sha512-/WRvx+L1eVBrLwX7QzKU1dQuaGnE7E8hDvx3VWfZh9HbMiCfsKWJNnYZ0S8ZMDAfAyDSofdyXIrH/hujF1fYXg==",
"requires": {
"commander": "^2.16.0"
},
"dependencies": {
"commander": {
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
}
}
},
@@ -6981,11 +6981,6 @@
"random-bytes": "~1.0.0"
}
},
"unidecode": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/unidecode/-/unidecode-0.1.8.tgz",
"integrity": "sha1-77swFTi8RSRqmsjFWdcvAVMFBT4="
},
"union-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "Joplin",
"version": "1.0.112",
"version": "1.0.119",
"description": "Joplin for Desktop",
"main": "main.js",
"scripts": {
@@ -8,7 +8,7 @@
"pack": "node_modules/.bin/electron-builder --dir",
"dist": "node_modules/.bin/electron-builder",
"publish": "build -p always",
"postinstall": "node compile-jsx.js && node compile-package-info.js && node ../../Tools/copycss.js --copy-fonts",
"postinstall": "node compile-jsx.js && node compile-package-info.js && node ../../Tools/copycss.js --copy-fonts && install-app-deps",
"compile": "node compile-jsx.js && node compile-package-info.js && node ../../Tools/copycss.js --copy-fonts"
},
"repository": {
@@ -71,8 +71,8 @@
"electron-builder": "20.14.7"
},
"optionalDependencies": {
"7zip-bin-mac": "^1.0.1",
"7zip-bin-linux": "^1.0.1",
"7zip-bin-mac": "^1.0.1",
"7zip-bin-win": "^2.1.1"
},
"dependencies": {
@@ -95,7 +95,7 @@
"joplin-turndown": "^4.0.9",
"joplin-turndown-plugin-gfm": "^1.0.7",
"jssha": "^2.3.1",
"katex": "^0.10.0-rc.1",
"katex": "^0.10.0",
"levenshtein": "^1.0.5",
"lodash": "^4.17.10",
"mark.js": "^8.11.1",
@@ -121,13 +121,12 @@
"server-destroy": "^1.0.1",
"smalltalk": "^2.5.1",
"sprintf-js": "^1.1.1",
"sqlite3": "^3.1.13",
"sqlite3": "^4.0.4",
"string-padding": "^1.0.2",
"string-to-stream": "^1.1.1",
"syswide-cas": "^5.1.0",
"tar": "^4.4.4",
"tcp-port-used": "^0.1.2",
"unidecode": "^0.1.8",
"url-parse": "^1.4.1",
"uuid": "^3.2.1",
"valid-url": "^1.0.9",

View File

@@ -81,4 +81,4 @@ table td, table th {
.note-property-box .rdt {
display: inline-block;
}
}

View File

@@ -1,53 +1,32 @@
const Setting = require('lib/models/Setting.js');
const zoomRatio = Setting.value('style.zoom') / 100;
const editorFontSize = Setting.value('style.editor.fontSize');
// globalStyle should be used for properties that do not change across themes
// i.e. should not be used for colors
const globalStyle = {
fontSize: Math.round(12 * zoomRatio),
fontFamily: 'sans-serif',
margin: 15, // No text and no interactive component should be within this margin
itemMarginTop: 10,
itemMarginBottom: 10,
backgroundColor: "#ffffff",
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: "#dddddd",
color: "#222222", // For regular text
colorError: "red",
colorWarn: "#9A5B00",
colorFaded: "#777777", // For less important text
fontSizeSmaller: 14,
dividerColor: "#dddddd",
selectedColor: '#e5e5e5',
disabledOpacity: 0.3,
buttonMinWidth: 50,
buttonMinHeight: 30,
textAreaLineHeight: 17,
//backgroundColor2: "#2B2634",
backgroundColor2: "#162B3D",
color2: "#ffffff",
//selectedColor2: "#5A4D70",
selectedColor2: "#0269C2",
colorError2: "#ff6c6c",
warningBackgroundColor: "#FFD08D",
editorFontSize: editorFontSize,
textAreaLineHeight: Math.round(17 * editorFontSize / 12),
headerHeight: 35,
headerButtonHPadding: 6,
toolbarHeight: 35,
raisedBackgroundColor: "#0080EF",
raisedColor: "#003363",
raisedHighlightedColor: "#ffffff",
tagItemPadding: 3,
};
// For WebView - must correspond to the properties above
globalStyle.htmlFontSize = globalStyle.fontSize + 'px';
globalStyle.htmlColor ='black'; // Note: CSS in WebView component only supports named colors or rgb() notation
globalStyle.htmlBackgroundColor ='white';
globalStyle.htmlDividerColor = 'rgb(150,150,150)';
globalStyle.htmlLinkColor ='blue';
globalStyle.htmlLineHeight = Math.round(20 * zoomRatio) + 'px';
globalStyle.marginRight = globalStyle.margin;
@@ -57,28 +36,22 @@ globalStyle.marginBottom = globalStyle.margin;
globalStyle.htmlMarginLeft = ((globalStyle.marginLeft / 10) * 0.6).toFixed(2) + 'em';
globalStyle.icon = {
color: globalStyle.color,
fontSize: 30,
};
globalStyle.lineInput = {
color: globalStyle.color,
backgroundColor: globalStyle.backgroundColor,
fontFamily: globalStyle.fontFamily,
};
globalStyle.textStyle = {
color: globalStyle.color,
fontFamily: globalStyle.fontFamily,
fontSize: globalStyle.fontSize,
lineHeight: '1.6em',
};
globalStyle.textStyle2 = Object.assign({}, globalStyle.textStyle, {
color: globalStyle.color2,
});
globalStyle.textStyle2 = Object.assign({}, globalStyle.textStyle, {});
globalStyle.urlStyle = Object.assign({}, globalStyle.textStyle, { color: "#155BDA", textDecoration: 'underline' });
globalStyle.urlStyle = Object.assign({}, globalStyle.textStyle, { textDecoration: 'underline' });
globalStyle.h1Style = Object.assign({}, globalStyle.textStyle);
globalStyle.h1Style.fontSize *= 1.5;
@@ -95,7 +68,6 @@ globalStyle.toolbarStyle = {
alignItems: 'center',
paddingLeft: globalStyle.headerButtonHPadding,
paddingRight: globalStyle.headerButtonHPadding,
color: globalStyle.color,
textDecoration: 'none',
fontFamily: globalStyle.fontFamily,
fontSize: globalStyle.fontSize,
@@ -104,31 +76,213 @@ globalStyle.toolbarStyle = {
justifyContent: 'center',
};
globalStyle.headerStyle = {};
globalStyle.inputStyle = {
border: '1px solid',
};
globalStyle.containerStyle = {
overflow: 'auto',
overflowY: 'auto',
};
globalStyle.buttonStyle = {
marginRight: 10,
border: '1px solid',
};
const lightStyle = {
backgroundColor: "#ffffff",
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: "#dddddd",
color: "#222222", // For regular text
colorError: "red",
colorWarn: "#9A5B00",
colorFaded: "#777777", // For less important text
dividerColor: "#dddddd",
selectedColor: '#e5e5e5',
urlColor: '#155BDA',
backgroundColor2: "#162B3D",
color2: "#ffffff",
selectedColor2: "#0269C2",
colorError2: "#ff6c6c",
raisedBackgroundColor: "#e5e5e5",
raisedColor: "#222222",
warningBackgroundColor: "#FFD08D",
codeColor: "#EFF0F1",
codeBorderColor: '#CBCBCB',
htmlColor:'black', // Note: CSS in WebView component only supports named colors or rgb() notation
htmlBackgroundColor: 'white',
htmlDividerColor: 'rgb(150,150,150)',
htmlLinkColor: 'blue',
htmlCodeColor: 'rgb(239, 240, 241)',
htmlCodeBorderColor: 'rgb(203, 203, 203)',
editorTheme: "chrome",
codeThemeCss: "atom-one-light.css",
};
const darkStyle = {
backgroundColor: '#1D2024',
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
oddBackgroundColor: "#dddddd",
color: '#dddddd',
colorFaded: '#777777',
colorError: "red",
colorWarn: "#9A5B00",
colorFaded: "#777777", // For less important text
dividerColor: '#555555',
selectedColor: '#333333',
urlColor: '#4E87EE',
backgroundColor2: "#162B3D",
color2: "#ffffff",
selectedColor2: "#0269C2",
colorError2: "#ff6c6c",
raisedBackgroundColor: "#474747",
raisedColor: "#ffffff",
warningBackgroundColor: "#CC6600",
codeColor: "#2F3031",
codeBorderColor: '#464646',
htmlColor: 'rgb(220,220,220)', // Note: CSS in WebView component only supports named colors or rgb() notation
htmlBackgroundColor: 'rgb(29,32,36)',
htmlDividerColor: 'rgb(150,150,150)',
htmlLinkColor: 'rgb(166,166,255)',
htmlCodeColor: 'rgb(47, 48, 49)',
htmlCodeBorderColor: 'rgb(70, 70, 70)',
editorTheme: 'twilight',
codeThemeCss: "atom-one-dark-reasonable.css",
};
function addExtraStyles(style) {
style.tagStyle = {
fontSize: style.fontSize,
fontFamily: style.fontFamily,
marginTop: style.itemMarginTop * 0.4,
marginBottom: style.itemMarginBottom * 0.4,
marginRight: style.margin * 0.3,
paddingTop: style.tagItemPadding,
paddingBottom: style.tagItemPadding,
paddingRight: style.tagItemPadding * 2,
paddingLeft: style.tagItemPadding * 2,
backgroundColor: style.raisedBackgroundColor,
color: style.raisedColor,
};
return style;
}
let themeCache_ = {};
function themeStyle(theme) {
if (!theme) throw new Error('Theme must be specified');
if (themeCache_[theme]) return themeCache_[theme];
let output = Object.assign({}, globalStyle);
if (theme == Setting.THEME_LIGHT) return output;
let output = {};
if (theme == Setting.THEME_LIGHT) {
output = Object.assign({}, globalStyle, lightStyle);
}
else if (theme == Setting.THEME_DARK) {
output = Object.assign({}, globalStyle, darkStyle);
}
output.backgroundColor = '#1D2024';
output.color = '#dddddd';
output.colorFaded = '#777777';
output.dividerColor = '#555555';
output.selectedColor = '#333333';
// TODO: All the theme specific things should go in addExtraStyles
// so that their definition is not split between here and the
// beginning of the file. At least new styles should go in
// addExtraStyles.
output.raisedBackgroundColor = "#0F2051";
output.raisedColor = "#788BC3";
output.raisedHighlightedColor = "#ffffff";
output.textStyle = Object.assign({},
output.textStyle,
{ color: output.color }
);
output.htmlColor = 'rgb(220,220,220)';
output.htmlBackgroundColor = 'rgb(29,32,36)';
output.htmlLinkColor = 'rgb(166,166,255)';
output.icon = Object.assign({},
output.icon,
{ color: output.color }
);
output.lineInput = Object.assign({},
output.lineInput,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.textStyle2 = Object.assign({},
output.textStyle2,
{ color: output.color2, }
);
output.urlStyle = Object.assign({},
output.urlStyle,
{ color: output.urlColor }
);
output.h1Style = Object.assign({},
output.h1Style,
{ color: output.color }
);
output.h2Style = Object.assign({},
output.h2Style,
{ color: output.color }
);
output.toolbarStyle = Object.assign({},
output.toolbarStyle,
{ color: output.color }
);
output.headerStyle = Object.assign({},
output.headerStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.inputStyle = Object.assign({},
output.inputStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
borderColor: output.dividerColor,
}
);
output.containerStyle = Object.assign({},
output.containerStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
}
);
output.buttonStyle = Object.assign({},
output.buttonStyle,
{
color: output.color,
backgroundColor: output.backgroundColor,
borderColor: output.dividerColor,
}
);
output = addExtraStyles(output);
themeCache_[theme] = output;
return themeCache_[theme];
}
module.exports = { themeStyle };
module.exports = { themeStyle };

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