You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-27 20:29:45 +02:00
Compare commits
227 Commits
cli-v1.0.1
...
list
Author | SHA1 | Date | |
---|---|---|---|
|
5e82e62335 | ||
|
de954827df | ||
|
2cb24bf198 | ||
|
739a6a4a9c | ||
|
dfcf1193dc | ||
|
c72f92e22f | ||
|
f6d01ce7e1 | ||
|
fed9700587 | ||
|
12a3a9a89e | ||
|
590c62c371 | ||
|
df41f64b3c | ||
|
1849355245 | ||
|
fa1b471ea4 | ||
|
0a67f8c947 | ||
|
621d0260f4 | ||
|
f4d830c2ef | ||
|
1aa2844efa | ||
|
f22b2adaad | ||
|
b547f9aa13 | ||
|
e4166e9da7 | ||
|
1634fdb421 | ||
|
7f51035f91 | ||
|
70e71cbc2a | ||
|
ffd03bf34c | ||
|
f59a3dee78 | ||
|
3ba3037242 | ||
|
dbb269fef6 | ||
|
e209189faa | ||
|
2d7065cde2 | ||
|
59f5972c93 | ||
|
8bac5275c3 | ||
|
58d748e235 | ||
|
e69ac3e62a | ||
|
7fc8ac4c0f | ||
|
069dce69cd | ||
|
3bdf621026 | ||
|
2f62897fb6 | ||
|
dbdd602f50 | ||
|
d66fa87b2b | ||
|
124a959c8d | ||
|
127dce1cd6 | ||
|
44986a35a4 | ||
|
ea516301fd | ||
|
90b684457a | ||
|
8517e2aa42 | ||
|
b880be8b7c | ||
|
57fd1a7588 | ||
|
5ed458f634 | ||
|
ac12143d00 | ||
|
b6c36d1961 | ||
|
3c2de70baa | ||
|
f6c5620682 | ||
|
79b6f64bd0 | ||
|
ed89f55bff | ||
|
8841a92142 | ||
|
0bd19c97eb | ||
|
2fd026d107 | ||
|
5e7eb37ca7 | ||
|
6b10d5d821 | ||
|
0f4dbfbcbf | ||
|
99493174ec | ||
|
333253fd4f | ||
|
01470e8d3b | ||
|
bda2fe6717 | ||
|
d1f4c5be18 | ||
|
377adea51d | ||
|
cda3d20834 | ||
|
d11870b1eb | ||
|
53bda3eea7 | ||
|
30165e8d6a | ||
|
2202eb6570 | ||
|
720927f488 | ||
|
2858c0fce0 | ||
|
36c3521f40 | ||
|
98a3b99d17 | ||
|
95a06c4531 | ||
|
6ea77b36ce | ||
|
0cd7ebf9d3 | ||
|
a816498fc6 | ||
|
549c1a6767 | ||
|
f87d1f11b0 | ||
|
fb913bc33c | ||
|
53d7a51cb0 | ||
|
12da48c756 | ||
|
a0a6bdb684 | ||
|
eb4aa2c026 | ||
|
a9e789f845 | ||
|
89b76918bd | ||
|
e98575643c | ||
|
7c9e7743f1 | ||
|
435aa4845b | ||
|
9841488ce4 | ||
|
9c907989a5 | ||
|
f684d8e59a | ||
|
a1ad6c9712 | ||
|
b6ca3090df | ||
|
ff2d793fbb | ||
|
fcfb7f1111 | ||
|
6125cde223 | ||
|
c83391e624 | ||
|
a3a818ea74 | ||
|
54a4965503 | ||
|
2233d88c01 | ||
|
9680ab74a3 | ||
|
ef711af5b5 | ||
|
8a619e4b8b | ||
|
bc09d2c640 | ||
|
f82dfde6f4 | ||
|
312c7f2d27 | ||
|
953cc327c6 | ||
|
14cff96713 | ||
|
34b9af2ce0 | ||
|
6a6ee280c3 | ||
|
861387707a | ||
|
830e665366 | ||
|
f14ae68ea0 | ||
|
c7084bf27e | ||
|
fc8ffcbe46 | ||
|
77f089654e | ||
|
e7a12bb0dd | ||
|
22fe3a4e44 | ||
|
afb8b92528 | ||
|
5178f99100 | ||
|
72af564382 | ||
|
0a2b83998c | ||
|
73e79213dc | ||
|
e31ffc9474 | ||
|
fdb8706a5f | ||
|
4c0262bd82 | ||
|
3b2dcb37a6 | ||
|
46a3b020a6 | ||
|
8373392e99 | ||
|
695c2623c2 | ||
|
979e7f2486 | ||
|
e7a9f630ec | ||
|
4e8372174b | ||
|
1b8912d7e9 | ||
|
8c3669588b | ||
|
1b784fe3b0 | ||
|
5ab1d8dfd6 | ||
|
cda8b95bfa | ||
|
9664842b1a | ||
|
09836e1d34 | ||
|
8974e20c7f | ||
|
761a49803e | ||
|
a40028f0c0 | ||
|
d4fca7e313 | ||
|
6748d4d825 | ||
|
0a5ad1d628 | ||
|
4080958e10 | ||
|
95c4a717e3 | ||
|
c5b9353105 | ||
|
17595f7ceb | ||
|
dcf78e8a06 | ||
|
de0c54c3c3 | ||
|
38970e9a52 | ||
|
563f43168b | ||
|
6e235605ed | ||
|
0749e0b675 | ||
|
756f3e627c | ||
|
4b39ed42b1 | ||
|
abe85ca4bd | ||
|
a559565ace | ||
|
d35e3163ca | ||
|
f22ad85681 | ||
|
727bdaeea4 | ||
|
42f7764eed | ||
|
1fbc1073ca | ||
|
66b683e5e7 | ||
|
7d1f61e47b | ||
|
643e5a6a2a | ||
|
a1e7e29279 | ||
|
abf6c3f3f1 | ||
|
32c81ad8c2 | ||
|
0f461c4caa | ||
|
57ed718993 | ||
|
ef1ae63233 | ||
|
81ac200cc0 | ||
|
3a2d62f6c7 | ||
|
7f80f67fd6 | ||
|
cebd8de77a | ||
|
417218fc34 | ||
|
29586437c2 | ||
|
f51d0ad914 | ||
|
35294b5f97 | ||
|
758562cff9 | ||
|
da0678c6fe | ||
|
afe4fd70cc | ||
|
4cef383fe7 | ||
|
b58c30889e | ||
|
1561c0e4d7 | ||
|
32b11c15a4 | ||
|
5e06efc1b9 | ||
|
43bd88703c | ||
|
cdd70230af | ||
|
eaf3eef2d3 | ||
|
81ec8eaf83 | ||
|
23f7e350c6 | ||
|
cea368cd3f | ||
|
50c8f2ae61 | ||
|
ed0ecababb | ||
|
72aa4c40a5 | ||
|
4f6784e2e5 | ||
|
01f015a54f | ||
|
806acad22a | ||
|
1d322d8a39 | ||
|
aef94e6950 | ||
|
456fcec334 | ||
|
3b6937c2f0 | ||
|
7cdd1d41c1 | ||
|
1fc535a740 | ||
|
033b37077a | ||
|
07f6a4a08b | ||
|
8c1b592a51 | ||
|
9460f7a17a | ||
|
106260ed69 | ||
|
123162e946 | ||
|
54e81966e5 | ||
|
9bf6ab60bb | ||
|
4f0ff3cdfc | ||
|
47cfaaa5ab | ||
|
1f49788f21 | ||
|
7e4cf9aeda | ||
|
4b6964b683 | ||
|
3caf398021 | ||
|
8840631266 | ||
|
c4411bb895 |
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
6
BUILD.md
6
BUILD.md
@@ -9,8 +9,6 @@
|
||||
echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.bash_profile
|
||||
source ~/.bash_profile
|
||||
|
||||
If you get a node-gyp related error you might need to manually install it: `npm install -g node-gyp`
|
||||
|
||||
## Linux and Windows (WSL) dependencies
|
||||
|
||||
- Install yarn - https://yarnpkg.com/lang/en/docs/install/
|
||||
@@ -37,6 +35,10 @@ yarn dist
|
||||
|
||||
If there's an error `while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory`, run `sudo apt-get install libgconf-2-4`
|
||||
|
||||
If you get a node-gyp related error you might need to manually install it: `npm install -g node-gyp`.
|
||||
|
||||
If you get the error `libtool: unrecognized option '-static'`, follow the instructions [in this post](https://stackoverflow.com/a/38552393/561309) to use the correct libtool version.
|
||||
|
||||
That will create the executable file in the `dist` directory.
|
||||
|
||||
From `/ElectronClient` you can also run `run.sh` to run the app for testing.
|
||||
|
@@ -17,3 +17,10 @@ Again, please check that it has not already been requested. If it has, simply **
|
||||
If you want to add a new feature, consider asking about it before implementing it or checking existing discussions to make sure it is within the scope of the project. Of course you are free to create the pull request directly but it is not guaranteed it is going to be accepted.
|
||||
|
||||
Building the apps is relatively easy - please [see the build instructions](https://github.com/laurent22/joplin/blob/master/BUILD.md) for more details.
|
||||
|
||||
# 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.
|
1
CliClient/.gitignore
vendored
1
CliClient/.gitignore
vendored
@@ -13,6 +13,7 @@ tests/fuzzing.*
|
||||
tests/fuzzing -*
|
||||
tests/logs/*
|
||||
tests/cli-integration/
|
||||
tests/tmp/
|
||||
*.mo
|
||||
*.*~
|
||||
tests/sync
|
||||
|
@@ -21,7 +21,6 @@ const { _, setLocale, defaultLocale, closestSupportedLocale } = require('lib/loc
|
||||
const os = require('os');
|
||||
const fs = require('fs-extra');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const EventEmitter = require('events');
|
||||
const Cache = require('lib/Cache');
|
||||
|
||||
class Application extends BaseApplication {
|
||||
|
281
CliClient/app/command-apidoc.js
Normal file
281
CliClient/app/command-apidoc.js
Normal file
@@ -0,0 +1,281 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const EncryptionService = require('lib/services/EncryptionService');
|
||||
const DecryptionWorker = require('lib/services/DecryptionWorker');
|
||||
const MasterKey = require('lib/models/MasterKey');
|
||||
const BaseItem = require('lib/models/BaseItem');
|
||||
const BaseModel = require('lib/BaseModel');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { toTitleCase } = require('lib/string-utils.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const markdownUtils = require('lib/markdownUtils');
|
||||
const { Database } = require('lib/database.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'apidoc';
|
||||
}
|
||||
|
||||
description() {
|
||||
return 'Build the API doc';
|
||||
}
|
||||
|
||||
createPropertiesTable(tableFields) {
|
||||
const headers = [
|
||||
{ name: 'name', label: 'Name' },
|
||||
{ name: 'type', label: 'Type', filter: (value) => {
|
||||
return Database.enumName('fieldType', value);
|
||||
}},
|
||||
{ name: 'description', label: 'Description' },
|
||||
];
|
||||
|
||||
return markdownUtils.createMarkdownTable(headers, tableFields);
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
const models = [
|
||||
{
|
||||
type: BaseModel.TYPE_NOTE,
|
||||
},
|
||||
{
|
||||
type: BaseModel.TYPE_FOLDER,
|
||||
},
|
||||
{
|
||||
type: BaseModel.TYPE_RESOURCE,
|
||||
},
|
||||
{
|
||||
type: BaseModel.TYPE_TAG,
|
||||
},
|
||||
];
|
||||
|
||||
const lines = [];
|
||||
|
||||
lines.push('# Joplin API');
|
||||
lines.push('');
|
||||
|
||||
lines.push('When the Web Clipper service is enabled, Joplin exposes a [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer) which allows third-party applications to access Joplin\'s data and to create, modify or delete notes, notebooks, resources or tags.');
|
||||
lines.push('');
|
||||
lines.push('In order to use it, you\'ll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port **41184**. If you want to find it programmatically, you may follow this kind of algorithm:');
|
||||
lines.push('');
|
||||
lines.push('```javascript');
|
||||
lines.push('let port = null;');
|
||||
lines.push('for (let portToTest = 41184; portToTest <= 41194; portToTest++) {');
|
||||
lines.push(' const result = pingPort(portToTest); // Call GET /ping');
|
||||
lines.push(' if (result == \'JoplinClipperServer\') {');
|
||||
lines.push(' port = portToTest; // Found the port');
|
||||
lines.push(' break;');
|
||||
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.');
|
||||
lines.push('');
|
||||
lines.push('This would be an example of valid cURL call using a token:');
|
||||
lines.push('');
|
||||
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('# Using the API');
|
||||
lines.push('');
|
||||
lines.push('All the calls, unless noted otherwise, receives and send **JSON data**. For example to create a new note:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://localhost:41184/notes');
|
||||
lines.push('');
|
||||
lines.push('In the documentation below, the calls may include special parameters such as :id or :note_id. You would replace this with the item ID or note ID.');
|
||||
lines.push('');
|
||||
lines.push('For example, for the endpoint `DELETE /tags/:id/notes/:note_id`, to remove the tag with ID "ABCD1234" from the note with ID "EFGH789", you would run for example:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl -X DELETE http://localhost:41184/tags/ABCD1234/notes/EFGH789');
|
||||
lines.push('');
|
||||
lines.push('The four verbs supported by the API are the following ones:');
|
||||
lines.push('');
|
||||
lines.push('* **GET**: To retrieve items (notes, notebooks, etc.).');
|
||||
lines.push('* **POST**: To create new items. In general most item properties are optional. If you omit any, a default value will be used.');
|
||||
lines.push('* **PUT**: To update an item. Note in a REST API, traditionally PUT is used to completely replace an item, however in this API it will only replace the properties that are provided. For example if you PUT {"title": "my new title"}, only the "title" property will be changed. The other properties will be left untouched (they won\'t be cleared nor changed).');
|
||||
lines.push('* **DELETE**: To delete items.');
|
||||
lines.push('');
|
||||
|
||||
lines.push('# Filtering data');
|
||||
lines.push('');
|
||||
lines.push('You can change the fields that will be returned by the API using the `fields=` query parameter, which takes a list of comma separated fields. For example, to get the longitude and latitude of a note, use this:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl http://localhost:41184/notes/ABCD123?fields=longitude,latitude');
|
||||
lines.push('');
|
||||
lines.push('To get the IDs only of all the tags:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl http://localhost:41184/tags?fields=id');
|
||||
lines.push('');
|
||||
|
||||
lines.push('# About the property types');
|
||||
lines.push('');
|
||||
lines.push('* Text is UTF-8.');
|
||||
lines.push('* All date/time are Unix timestamps in milliseconds.');
|
||||
lines.push('* Booleans are integer values 0 or 1.');
|
||||
lines.push('');
|
||||
|
||||
lines.push('# Testing if the service is available');
|
||||
lines.push('');
|
||||
lines.push('Call **GET /ping** to check if the service is available. It should return "JoplinClipperServer" if it works.');
|
||||
lines.push('');
|
||||
|
||||
for (let i = 0; i < models.length; i++) {
|
||||
const model = models[i];
|
||||
const ModelClass = BaseItem.getClassByItemType(model.type);
|
||||
const tableName = ModelClass.tableName();
|
||||
let tableFields = reg.db().tableFields(tableName, { includeDescription: true });
|
||||
const singular = tableName.substr(0, tableName.length - 1);
|
||||
|
||||
if (model.type === BaseModel.TYPE_NOTE) {
|
||||
tableFields = tableFields.slice();
|
||||
tableFields.push({
|
||||
name: 'body_html',
|
||||
type: Database.enumId('fieldType', 'text'),
|
||||
description: 'Note body, in HTML format',
|
||||
});
|
||||
tableFields.push({
|
||||
name: 'base_url',
|
||||
type: Database.enumId('fieldType', 'text'),
|
||||
description: 'If `body_html` is provided and contains relative URLs, provide the `base_url` parameter too so that all the URLs can be converted to absolute ones. The base URL is basically where the HTML was fetched from, minus the query (everything after the \'?\'). For example if the original page was `https://stackoverflow.com/search?q=%5Bjava%5D+test`, the base URL is `https://stackoverflow.com/search`.',
|
||||
});
|
||||
tableFields.push({
|
||||
name: 'image_data_url',
|
||||
type: Database.enumId('fieldType', 'text'),
|
||||
description: 'An image to attach to the note, in [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.',
|
||||
});
|
||||
tableFields.push({
|
||||
name: 'crop_rect',
|
||||
type: Database.enumId('fieldType', 'text'),
|
||||
description: 'If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format `{ x: x, y: y, width: width, height: height }`',
|
||||
});
|
||||
tableFields.push({
|
||||
name: 'tags',
|
||||
type: Database.enumId('fieldType', 'text'),
|
||||
description: 'Comma-separated list of tags. eg. `tag1,tag2`.',
|
||||
});
|
||||
}
|
||||
|
||||
lines.push('# ' + toTitleCase(tableName));
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_FOLDER) {
|
||||
lines.push('This is actually a notebook. Internally notebooks are called "folders".');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## Properties');
|
||||
lines.push('');
|
||||
lines.push(this.createPropertiesTable(tableFields));
|
||||
lines.push('');
|
||||
|
||||
lines.push('## GET /' + tableName);
|
||||
lines.push('');
|
||||
lines.push('Gets all ' + tableName);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_FOLDER) {
|
||||
lines.push('The folders are returned as a tree. The sub-notebooks of a notebook, if any, are under the `children` key.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## GET /' + tableName + '/:id');
|
||||
lines.push('');
|
||||
lines.push('Gets ' + singular + ' with ID :id');
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_TAG) {
|
||||
lines.push('## GET /tags/:id/notes');
|
||||
lines.push('');
|
||||
lines.push('Gets all the notes with this tag.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
if (model.type === BaseModel.TYPE_NOTE) {
|
||||
lines.push('## GET /notes/:id/tags');
|
||||
lines.push('');
|
||||
lines.push('Gets all the tags attached to this note.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
if (model.type === BaseModel.TYPE_FOLDER) {
|
||||
lines.push('## GET /folders/:id/notes');
|
||||
lines.push('');
|
||||
lines.push('Gets all the notes inside this folder.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
if (model.type === BaseModel.TYPE_RESOURCE) {
|
||||
lines.push('## GET /resources/:id/file');
|
||||
lines.push('');
|
||||
lines.push('Gets the actual file associated with this resource.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push('## POST /' + tableName);
|
||||
lines.push('');
|
||||
lines.push('Creates a new ' + singular);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_RESOURCE) {
|
||||
lines.push('Creating a new resource is special because you also need to upload the file. Unlike other API calls, this one must have the "multipart/form-data" Content-Type. The file data must be passed to the "data" form field, and the other properties to the "props" form field. An example of a valid call with cURL would be:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl -F \'data=@/path/to/file.jpg\' -F \'props={"title":"my resource title"}\' http://localhost:41184/resources');
|
||||
lines.push('');
|
||||
lines.push('The "data" field is required, while the "props" one is not. If not specified, default values will be used.');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
if (model.type === BaseModel.TYPE_TAG) {
|
||||
lines.push('## POST /tags/:id/notes');
|
||||
lines.push('');
|
||||
lines.push('Post a note to this endpoint to add the tag to the note. The note data must at least contain an ID property (all other properties will be ignored).');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
if (model.type === BaseModel.TYPE_NOTE) {
|
||||
lines.push('You can either specify the note body as Markdown by setting the `body` parameter, or in HTML by setting the `body_html`.');
|
||||
lines.push('');
|
||||
lines.push('Examples:');
|
||||
lines.push('');
|
||||
lines.push('* Create a note from some Markdown text');
|
||||
lines.push('');
|
||||
lines.push(' curl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://127.0.0.1:41184/notes');
|
||||
lines.push('');
|
||||
lines.push('* Create a note from some HTML');
|
||||
lines.push('');
|
||||
lines.push(' curl --data \'{ "title": "My note", "body_html": "Some note in <b>HTML</b>"}\' http://127.0.0.1:41184/notes');
|
||||
lines.push('');
|
||||
lines.push('* Create a note and attach an image to it:');
|
||||
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('## PUT /' + tableName + '/:id');
|
||||
lines.push('');
|
||||
lines.push('Sets the properties of the ' + singular + ' with ID :id');
|
||||
lines.push('');
|
||||
|
||||
lines.push('## DELETE /' + tableName + '/:id');
|
||||
lines.push('');
|
||||
lines.push('Deletes the ' + singular + ' with ID :id');
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_TAG) {
|
||||
lines.push('## DELETE /tags/:id/notes/:note_id');
|
||||
lines.push('');
|
||||
lines.push('Remove the tag from the note.');
|
||||
lines.push('');
|
||||
}
|
||||
}
|
||||
|
||||
this.stdout(lines.join('\n'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
@@ -47,34 +47,63 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
if (args.command === 'decrypt') {
|
||||
if (args.path) {
|
||||
const plainText = await EncryptionService.instance().decryptString(args.path);
|
||||
this.stdout(plainText);
|
||||
} else {
|
||||
this.stdout(_('Starting decryption... Please wait as it may take several minutes depending on how much there is to decrypt.'));
|
||||
while (true) {
|
||||
try {
|
||||
if (args.path) {
|
||||
const plainText = await EncryptionService.instance().decryptString(args.path);
|
||||
this.stdout(plainText);
|
||||
return;
|
||||
} else {
|
||||
if (process.stdin.isTTY) {
|
||||
this.stdout(_('Starting decryption... Please wait as it may take several minutes depending on how much there is to decrypt.'));
|
||||
await DecryptionWorker.instance().start();
|
||||
this.stdout(_('Completed decryption.'));
|
||||
return;
|
||||
} else {
|
||||
// var repl = require("repl");
|
||||
// var r = repl.start("node> ");
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
await DecryptionWorker.instance().start();
|
||||
break;
|
||||
} catch (error) {
|
||||
if (error.code === 'masterKeyNotLoaded') {
|
||||
const masterKeyId = error.masterKeyId;
|
||||
const password = await this.prompt(_('Enter master password:'), { type: 'string', secure: true });
|
||||
if (!password) {
|
||||
this.stdout(_('Operation cancelled'));
|
||||
return;
|
||||
const text = await new Promise((accept, reject) => {
|
||||
var buffer = '';
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function(chunk) {
|
||||
buffer += chunk;
|
||||
// process.stdout.write(chunk);
|
||||
});
|
||||
process.stdin.on('end', function() {
|
||||
accept(buffer.trim());
|
||||
});
|
||||
});
|
||||
|
||||
if (text.length > 0) {
|
||||
var cipherText = text;
|
||||
try {
|
||||
var item = await BaseItem.unserialize(text);
|
||||
cipherText = item.encryption_cipher_text;
|
||||
} catch (error) {
|
||||
// we already got the pure cipher text
|
||||
}
|
||||
const plainText = await EncryptionService.instance().decryptString(cipherText);
|
||||
this.stdout(plainText);
|
||||
}
|
||||
Setting.setObjectKey('encryption.passwordCache', masterKeyId, password);
|
||||
await EncryptionService.instance().loadMasterKeysFromSettings();
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code === 'masterKeyNotLoaded') {
|
||||
const masterKeyId = error.masterKeyId;
|
||||
const password = await this.prompt(_('Enter master password:'), { type: 'string', secure: true });
|
||||
if (!password) {
|
||||
this.stdout(_('Operation cancelled'));
|
||||
return;
|
||||
}
|
||||
Setting.setObjectKey('encryption.passwordCache', masterKeyId, password);
|
||||
await EncryptionService.instance().loadMasterKeysFromSettings();
|
||||
continue;
|
||||
}
|
||||
|
||||
this.stdout(_('Completed decryption.'));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -186,4 +215,4 @@ class Command extends BaseCommand {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
||||
module.exports = Command;
|
||||
|
@@ -22,7 +22,7 @@ class Command extends BaseCommand {
|
||||
enabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
options() {
|
||||
return [
|
||||
['-n, --limit <num>', _('Displays only the first top <num> notes.')],
|
||||
@@ -93,7 +93,7 @@ class Command extends BaseCommand {
|
||||
row.push(await Folder.noteCount(item.id));
|
||||
}
|
||||
|
||||
row.push(time.unixMsToLocalDateTime(item.user_updated_time));
|
||||
row.push(time.formatMsToLocal(item.user_updated_time));
|
||||
}
|
||||
|
||||
let title = item.title;
|
||||
@@ -123,4 +123,4 @@ class Command extends BaseCommand {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
||||
module.exports = Command;
|
||||
|
@@ -4,6 +4,7 @@ const { _ } = require('lib/locale.js');
|
||||
const { OneDriveApiNodeUtils } = require('./onedrive-api-node-utils.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||
const { Synchronizer } = require('lib/synchronizer.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
@@ -191,6 +192,14 @@ class Command extends BaseCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// When using the tool in command line mode, the ResourceFetcher service is
|
||||
// not going to be running in the background, so the resources need to be
|
||||
// explicitely downloaded below.
|
||||
if (!app().hasGui()) {
|
||||
await ResourceFetcher.instance().fetchAll();
|
||||
await ResourceFetcher.instance().waitForAllFinished();
|
||||
}
|
||||
|
||||
await app().refreshCurrentFolder();
|
||||
} catch (error) {
|
||||
cleanUp();
|
||||
|
@@ -3,6 +3,7 @@ const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
@@ -11,11 +12,19 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('<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 `tag list` can be used to list all the tags.');
|
||||
return _('<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 `tag list` can be used to list all the tags (use -l for long option).');
|
||||
}
|
||||
|
||||
|
||||
options() {
|
||||
return [
|
||||
['-l, --long', _('Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE')],
|
||||
];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let tag = null;
|
||||
let options = args.options;
|
||||
|
||||
if (args.tag) tag = await app().loadItem(BaseModel.TYPE_TAG, args.tag);
|
||||
let notes = [];
|
||||
if (args.note) {
|
||||
@@ -41,7 +50,28 @@ class Command extends BaseCommand {
|
||||
} else if (command == 'list') {
|
||||
if (tag) {
|
||||
let notes = await Tag.notes(tag.id);
|
||||
notes.map((note) => { this.stdout(note.title); });
|
||||
notes.map((note) => {
|
||||
let line = '';
|
||||
if (options.long) {
|
||||
line += BaseModel.shortId(note.id);
|
||||
line += ' ';
|
||||
line += time.formatMsToLocal(note.user_updated_time);
|
||||
line += ' ';
|
||||
}
|
||||
if (note.is_todo) {
|
||||
line += '[';
|
||||
if (note.todo_completed) {
|
||||
line += 'X';
|
||||
} else {
|
||||
line += ' ';
|
||||
}
|
||||
line += '] ';
|
||||
} else {
|
||||
line += ' ';
|
||||
}
|
||||
line += note.title;
|
||||
this.stdout(line);
|
||||
});
|
||||
} else {
|
||||
let tags = await Tag.all();
|
||||
tags.map((tag) => { this.stdout(tag.title); });
|
||||
|
@@ -32,8 +32,6 @@ class FolderListWidget extends ListWidget {
|
||||
output.push(_('Search:'));
|
||||
output.push(item.title);
|
||||
}
|
||||
|
||||
// if (item && item.id) output.push(item.id.substr(0, 5));
|
||||
|
||||
return output.join(' ');
|
||||
};
|
||||
@@ -85,7 +83,6 @@ class FolderListWidget extends ListWidget {
|
||||
}
|
||||
|
||||
set notesParentType(v) {
|
||||
//if (this.notesParentType_ === v) return;
|
||||
this.notesParentType_ = v;
|
||||
this.updateIndexFromSelectedItemId()
|
||||
this.invalidate();
|
||||
@@ -123,6 +120,14 @@ class FolderListWidget extends ListWidget {
|
||||
this.updateIndexFromSelectedItemId()
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
folderHasChildren_(folders, folderId) {
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
let folder = folders[i];
|
||||
if (folder.parent_id === folderId) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.updateItems_) {
|
||||
@@ -130,7 +135,18 @@ class FolderListWidget extends ListWidget {
|
||||
const wasSelectedItemId = this.selectedJoplinItemId;
|
||||
const previousParentType = this.notesParentType;
|
||||
|
||||
let newItems = this.folders.slice();
|
||||
let newItems = [];
|
||||
const orderFolders = (parentId) => {
|
||||
for (let i = 0; i < this.folders.length; i++) {
|
||||
const f = this.folders[i];
|
||||
if (f.parent_id === parentId) {
|
||||
newItems.push(f);
|
||||
if (this.folderHasChildren_(this.folders, f.id)) orderFolders(f.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
orderFolders('');
|
||||
|
||||
if (this.tags.length) {
|
||||
if (newItems.length) newItems.push('-');
|
||||
|
@@ -463,10 +463,11 @@ msgstr "Està començant la sincronització..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "S'està cancel·lant... Espereu."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command>pot ser «add», «remove» o «list» per a assignar o suprimir "
|
||||
"[tag] de la [nota], o per a llistar les notes associades amb [tag]. L'ordre "
|
||||
@@ -632,6 +633,10 @@ msgstr "Retalla"
|
||||
msgid "Paste"
|
||||
msgstr "Enganxa"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Seleccioneu una data"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -715,6 +720,9 @@ msgstr "Sí"
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
"El servei de desa-retalls de webs és actiu i configurat per a iniciar-se "
|
||||
@@ -765,6 +773,21 @@ msgstr "Pas 2: Instal·leu l'extensió"
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr "Baixeu i instal·leu l'extensió adient per al vostre navegador:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Mostra les opcions avançades"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Comprova la configuració de la sincronització"
|
||||
|
||||
@@ -929,6 +952,14 @@ msgstr "Copia"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Alterna entre el tipus nota i tasques pendents"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Alterna entre el tipus nota i tasques pendents"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Alterna entre el tipus nota i tasques pendents"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Copia l'enllaç Markdown"
|
||||
|
||||
@@ -947,6 +978,12 @@ msgstr ""
|
||||
"Ara mateix no hi ha cap bloc de notes. Creeu-ne un fent clic a «Bloc de "
|
||||
"notes nou»."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Obre..."
|
||||
|
||||
@@ -1000,6 +1037,9 @@ msgstr "Estableix una alarma"
|
||||
msgid "In: %s"
|
||||
msgstr "A: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1205,10 +1245,6 @@ msgstr "Conflictes"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "No es pot moure el bloc de notes a aquesta ubicació"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Ja existeix un bloc de notes amb aquest títol: «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Els blocs de notes no poden tenir el nom «%s», és un títol reservat."
|
||||
@@ -1287,6 +1323,9 @@ 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 "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Percentatge de zoom global"
|
||||
|
||||
@@ -1357,6 +1396,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "URL del Nextcloud WebDAV"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nom d'usuari del Nextcloud"
|
||||
|
||||
@@ -1389,6 +1435,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "El valor de l'opció no és vàlid: «%s». Els valors possibles són: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Fitxer d'exportació del Joplin"
|
||||
|
||||
@@ -1503,6 +1553,10 @@ msgstr "Voleu moure %d notes al bloc de notes «%s»?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Premeu per a establir la contrasenya de desxifratge."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Estableix una alarma"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Desa l'alarma"
|
||||
|
||||
@@ -1519,6 +1573,36 @@ msgstr "Cancel·la la sincronització"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Elements obtinguts: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "S'està cancel·lant... Espereu."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Comprova la configuració de la sincronització"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "L'aplicació s'ha autoritzat correctament."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Elements obtinguts: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Etiquetes noves:"
|
||||
|
||||
@@ -1652,3 +1736,6 @@ msgstr ""
|
||||
|
||||
msgid "Welcome"
|
||||
msgstr "Benvingut"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Ja existeix un bloc de notes amb aquest títol: «%s»"
|
||||
|
@@ -451,10 +451,11 @@ msgstr "Zahajuji synchronizaci..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Zastavuji, chvíli strpení."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> může být \"add\", \"remove\" nebo \"list\" - přidat (add) či "
|
||||
"odebrat (remove) [tag] k [poznámce], nebo vypsat (list) seznam poznámek "
|
||||
@@ -614,6 +615,10 @@ msgstr "Vyjmout"
|
||||
msgid "Paste"
|
||||
msgstr "Vložit"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Vybrat datum"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -697,6 +702,9 @@ msgstr "Ano"
|
||||
msgid "No"
|
||||
msgstr "Ne"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -740,6 +748,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Ukázat pokročilé volby"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Zkontrolujte nastavení synchronizace"
|
||||
|
||||
@@ -901,6 +924,14 @@ msgstr "Kopírovat"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Přepnout mezi poznámkou a to-do"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Přepnout mezi poznámkou a to-do"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Přepnout mezi poznámkou a to-do"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown"
|
||||
@@ -918,6 +949,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Nemáte žádný zápisník. Vytvořte jeden kliknutím na \"Nový zápisník\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Otevřít..."
|
||||
|
||||
@@ -969,6 +1006,9 @@ msgstr "Nastavit alarm"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1176,10 +1216,6 @@ msgstr "Konflikty"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Poznámku nelze přesunout do zápisníku \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Zápisník s tímto názvem již existuje: \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Zápisník se nemůže jmenovat \"%s\", tento název je rezervován."
|
||||
@@ -1262,6 +1298,9 @@ msgstr "Zobrazovat ikonu v panelu"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Globální zoom"
|
||||
|
||||
@@ -1332,6 +1371,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud uživatelské jméno"
|
||||
|
||||
@@ -1364,6 +1410,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Neplatná hodnota: \"%s\". Přípustné hodnoty jsou: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Soubor Joplin Export"
|
||||
|
||||
@@ -1478,6 +1528,10 @@ msgstr "Přesunout poznámky %d do zápisníku \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Stiskněte pro zadání hesla k dešifrování."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Nastavit alarm"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Nastavit alarm"
|
||||
@@ -1495,6 +1549,36 @@ msgstr "Zrušit synchronizaci"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Získané položky: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Zastavuji, chvíli strpení."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Zkontrolujte nastavení synchronizace"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Aplikace byla úspěšně autorizována."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Získané položky: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Nové tagy:"
|
||||
|
||||
@@ -1621,5 +1705,8 @@ msgstr "Nemáte žádný zápisník. Vytvořte jeden kliknutím na tlačítko (+
|
||||
msgid "Welcome"
|
||||
msgstr "Vítejte"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Zápisník s tímto názvem již existuje: \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Hledané výrazy"
|
||||
|
@@ -455,10 +455,11 @@ msgstr "Starter synkronisering."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Annullerer... Vent venligst."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> (mærke-kommando) kan enten være \"add\" (tilføj), \"remove"
|
||||
"\" (slet) eller \"list\" (liste) for at tilføje eller fjerne mærke [tag] fra "
|
||||
@@ -619,6 +620,10 @@ msgstr "Klip"
|
||||
msgid "Paste"
|
||||
msgstr "Indsæt"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Vælg dato"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -702,6 +707,9 @@ msgstr "Ja"
|
||||
msgid "No"
|
||||
msgstr "Nej"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -745,6 +753,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Vis avancerede indstillinger"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Check synkroniserings Indstillinger"
|
||||
|
||||
@@ -910,6 +933,14 @@ msgstr "Kopier"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Skift mellem note- og opgave type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Skift mellem note- og opgave type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Skift mellem note- og opgave type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown"
|
||||
@@ -927,6 +958,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Der er ingen notesbog. Opret en ved at klikke på \"Ny Notesbog\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Åben..."
|
||||
|
||||
@@ -978,6 +1015,9 @@ msgstr "Indstil alarm"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1185,10 +1225,6 @@ msgstr "Konflikter"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Kan ikke flytte note til \"%s\" notesbog"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "En notesbog bruger allerede dette navn: \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Notesbøger kan ikke få navnet \"%s\", da det er en beskyttet titel."
|
||||
@@ -1271,6 +1307,9 @@ msgstr "Vis ikon på bundbjælke"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Global zoom procent"
|
||||
|
||||
@@ -1341,6 +1380,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud brugernavn"
|
||||
|
||||
@@ -1373,6 +1419,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ulovlig værdi: \"%s\". Mulige valg er: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Joplin eksport fil"
|
||||
|
||||
@@ -1487,6 +1537,10 @@ msgstr "Flyt %d noter til notesbogen \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Klik for at gemme dekrypterings kodeord."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Indstil alarm"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Indstil alarm"
|
||||
@@ -1504,6 +1558,36 @@ msgstr "Afbryd synkronisering"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Hentede emner: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Annullerer... Vent venligst."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Check synkroniserings Indstillinger"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Denne app er succesfuldt godkendt."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Hentede emner: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Nye tags:"
|
||||
|
||||
@@ -1630,6 +1714,9 @@ msgstr "Du har ingen notesbøger. Opret en ved at klikke på (+) knappen."
|
||||
msgid "Welcome"
|
||||
msgstr "Velkommen"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "En notesbog bruger allerede dette navn: \"%s\""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
|
||||
#~ "how to enable it please check the documentation"
|
||||
|
@@ -13,13 +13,14 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.8\n"
|
||||
"X-Generator: Poedit 2.1.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr ""
|
||||
"Um ein Schlagwort zu löschen, entferne es bei allen damit verbundenen "
|
||||
"Notizen."
|
||||
"Um ein Tag zu löschen, entferne es bei allen damit verbundenen Notizen."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr ""
|
||||
@@ -197,8 +198,8 @@ msgid ""
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"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, Markierungen und "
|
||||
"Exportiert Joplin-Dateien in den angegebenen Pfad. Standardmäßig wird die "
|
||||
"komplette Datenbank inklusive Notizbüchern, Notizen, Schlagwörtern und "
|
||||
"Anhängen exportiert."
|
||||
|
||||
#, javascript-format
|
||||
@@ -306,7 +307,7 @@ msgstr "Anhänge: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Tagged: %d."
|
||||
msgstr "Markiert: %d."
|
||||
msgstr "Verschlagwortet: %d."
|
||||
|
||||
msgid "Importing notes..."
|
||||
msgstr "Importiere Notizen..."
|
||||
@@ -478,12 +479,12 @@ msgstr "Abbrechen… Bitte warten."
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> kann \"add\", \"remove\" or \"list\" sein, um ein [Schlagwort] "
|
||||
"zu [Notiz] zuzuweisen oder zu entfernen, oder um mit [Schlagwort] markierte "
|
||||
"Notizen anzuzeigen. Mit dem Befehl `tag list` können alle Schlagwörter "
|
||||
"angezeigt werden."
|
||||
"<tag-command> kann „add“, „remove“ oder „list“ sein um [tag] zu [note] "
|
||||
"hinzuzufügen oder zu entfernen, oder um die Notizen aufzulisten die [tag] "
|
||||
"zugeordnet sind. Der Befehl `tag list` kann benutzt werden, um alle "
|
||||
"Schlagwörter anzuzeigen (nutze -l für die lange Option)."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid command: \"%s\""
|
||||
@@ -643,6 +644,9 @@ msgstr "Ausschneiden"
|
||||
msgid "Paste"
|
||||
msgstr "Einfügen"
|
||||
|
||||
msgid "Select all"
|
||||
msgstr "Alle auswählen"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr "Fett"
|
||||
|
||||
@@ -665,7 +669,7 @@ msgid "Toggle sidebar"
|
||||
msgstr "Seitenleiste ein/aus"
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr "Editor Layout umschalten"
|
||||
msgstr "Editor-Layout umschalten"
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Werkzeuge"
|
||||
@@ -674,7 +678,7 @@ msgid "Synchronisation status"
|
||||
msgstr "Status der Synchronisation"
|
||||
|
||||
msgid "Web clipper options"
|
||||
msgstr "Web Clipper Optionen"
|
||||
msgstr "Web-Clipper Optionen"
|
||||
|
||||
msgid "Encryption options"
|
||||
msgstr "Verschlüsselungsoptionen"
|
||||
@@ -718,7 +722,7 @@ msgid "Current version is up-to-date."
|
||||
msgstr "Die aktuelle Version ist up-to-date."
|
||||
|
||||
msgid "An update is available, do you want to download it now?"
|
||||
msgstr "Es ist ein Update verfügbar! Soll es jetzt heruntergeladen werden?"
|
||||
msgstr "Es ist ein Update verfügbar. Soll es jetzt heruntergeladen werden?"
|
||||
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
@@ -726,9 +730,12 @@ msgstr "Ja"
|
||||
msgid "No"
|
||||
msgstr "Nein"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr "Token wurde in die Zwischenablage kopiert."
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
"Der Webclipperservice ist bereits aktiviert und auf Autostart eingestellt."
|
||||
"Der Web-Clipper-Service ist bereits aktiviert und auf Autostart eingestellt."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Status: Started on port %d"
|
||||
@@ -739,26 +746,26 @@ msgid "Status: %s"
|
||||
msgstr "Status: %s"
|
||||
|
||||
msgid "Disable Web Clipper Service"
|
||||
msgstr "Web Clipper Service deaktivieren"
|
||||
msgstr "Web-Clipper-Service deaktivieren"
|
||||
|
||||
msgid "The web clipper service is not enabled."
|
||||
msgstr "Der Web Clipper Service ist nicht aktiviert."
|
||||
msgstr "Der Web-Clipper-Service ist nicht aktiviert."
|
||||
|
||||
msgid "Enable Web Clipper Service"
|
||||
msgstr "Web Clipper Service aktivieren"
|
||||
msgstr "Web-Clipper-Service aktivieren"
|
||||
|
||||
msgid ""
|
||||
"Joplin Web Clipper allows saving web pages and screenshots from your browser "
|
||||
"to Joplin."
|
||||
msgstr ""
|
||||
"Joplin Web Clipper erlaubt im Browser das Speichern von Webseiten und "
|
||||
"Joplin Web-Clipper erlaubt im Browser das Speichern von Webseiten und "
|
||||
"Screenshots nach Joplin."
|
||||
|
||||
msgid "In order to use the web clipper, you need to do the following:"
|
||||
msgstr "Um den Web Clipper zu benutzen, musst du folgendes machen:"
|
||||
msgstr "Um den Web-Clipper zu benutzen, musst du folgendes machen:"
|
||||
|
||||
msgid "Step 1: Enable the clipper service"
|
||||
msgstr "Schritt 1: Clipper Service aktivieren"
|
||||
msgstr "Schritt 1: Clipper-Service aktivieren"
|
||||
|
||||
msgid ""
|
||||
"This service allows the browser extension to communicate with Joplin. When "
|
||||
@@ -767,7 +774,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Dieser Service erlaubt es der Browser-Erweiterung mit Joplin zu "
|
||||
"kommunizieren. Beim Aktivieren kann deine Firewall dich nach der Erlaubnis "
|
||||
"bitten, dass Joplin auf einen bestimmten Port mithört."
|
||||
"bitten, dass Joplin auf einen bestimmten Port mithören darf."
|
||||
|
||||
msgid "Step 2: Install the extension"
|
||||
msgstr "Schritt 2: Erweiterung installieren"
|
||||
@@ -777,6 +784,22 @@ msgstr ""
|
||||
"Lade die entsprechende Erweiterung für deinen Browser herunter und "
|
||||
"installiere sie:"
|
||||
|
||||
msgid "Advanced options"
|
||||
msgstr "Erweiterte Optionen"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr "Autorisierung-Token:"
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr "Token kopieren"
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
"Dieses Autorisierung-Token wird nur benötigt, um Drittanbieter-Anwendungen "
|
||||
"Zugriff auf Joplin zu gewähren."
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Überprüfen der Synchronisationseinstellungen"
|
||||
|
||||
@@ -855,13 +878,14 @@ msgstr ""
|
||||
"Notizbücher ursprünglich verschlüsselt wurden."
|
||||
|
||||
msgid "Missing Master Keys"
|
||||
msgstr "Fehlender Master-Key"
|
||||
msgstr "Fehlender Hauptschlüssel"
|
||||
|
||||
msgid ""
|
||||
"The master keys with these IDs are used to encrypt some of your items, "
|
||||
"however the application does not currently have access to them. It is likely "
|
||||
"they will eventually be downloaded via synchronisation."
|
||||
msgstr "Die Master-Keas dieser IDs werden für die Verschlüsselung einiger ..."
|
||||
msgstr ""
|
||||
"Die Hauptschlüssel dieser IDs werden für die Verschlüsselung einiger ..."
|
||||
|
||||
msgid ""
|
||||
"For more information about End-To-End Encryption (E2EE) and advices on how "
|
||||
@@ -893,10 +917,10 @@ msgid "Please create a notebook first"
|
||||
msgstr "Bitte erstelle zuerst ein Notizbuch"
|
||||
|
||||
msgid "Notebook title:"
|
||||
msgstr "Notizbuch Titel:"
|
||||
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."
|
||||
@@ -941,6 +965,12 @@ msgstr "%s kopieren"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Zwischen Notiz und To-Do Typ wechseln"
|
||||
|
||||
msgid "Switch to note type"
|
||||
msgstr "Zu Notiz-Typ wechseln"
|
||||
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Zu To-Do-Typ wechseln"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown-Link kopieren"
|
||||
|
||||
@@ -952,8 +982,7 @@ msgstr "Notizen löschen?"
|
||||
|
||||
msgid "No notes in here. Create one by clicking on \"New note\"."
|
||||
msgstr ""
|
||||
"Hier sind noch keine Notizen. Erstelle eine, indem du auf \"Neue Notiz\" "
|
||||
"drückst."
|
||||
"Keine Notizen vorhanden. Erstelle eine, indem du auf \"Neue Notiz\" drückst."
|
||||
|
||||
msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
@@ -961,6 +990,12 @@ msgstr ""
|
||||
"Momentan existieren noch keine Notizbücher. Erstelle eines, indem du auf "
|
||||
"\"Neues Notizbuch\" drückst."
|
||||
|
||||
msgid "Location"
|
||||
msgstr "Ablageort"
|
||||
|
||||
msgid "URL"
|
||||
msgstr "URL"
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Öffne..."
|
||||
|
||||
@@ -969,7 +1004,7 @@ msgid "This file could not be opened: %s"
|
||||
msgstr "Dieses Notizbuch konnte nicht geöffnet werden: %s"
|
||||
|
||||
msgid "Save as..."
|
||||
msgstr "Sichern unter..."
|
||||
msgstr "Speichern unter..."
|
||||
|
||||
msgid "Copy path to clipboard"
|
||||
msgstr "Pfad in Zwischenablage kopieren"
|
||||
@@ -1005,7 +1040,7 @@ msgid "Attach file"
|
||||
msgstr "Datei anhängen"
|
||||
|
||||
msgid "Tags"
|
||||
msgstr "Markierungen"
|
||||
msgstr "Schlagwörter"
|
||||
|
||||
msgid "Set alarm"
|
||||
msgstr "Alarm erstellen"
|
||||
@@ -1014,6 +1049,9 @@ msgstr "Alarm erstellen"
|
||||
msgid "In: %s"
|
||||
msgstr "In: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr "Notiz-Eigenschaften"
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr "Weblink"
|
||||
|
||||
@@ -1038,9 +1076,8 @@ msgstr "Horizontale Linie"
|
||||
msgid "Click to stop external editing"
|
||||
msgstr "Klicken Sie hier, um die externe Bearbeitung anzuhalten"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Watching..."
|
||||
msgstr "Ansehen…"
|
||||
msgstr "Zuschauend…"
|
||||
|
||||
msgid "to-do"
|
||||
msgstr "To-Do"
|
||||
@@ -1059,22 +1096,22 @@ msgid "Clear"
|
||||
msgstr "Leeren"
|
||||
|
||||
msgid "OneDrive Login"
|
||||
msgstr "OneDrive Anmeldung"
|
||||
msgstr "OneDrive-Anmeldung"
|
||||
|
||||
msgid "Dropbox Login"
|
||||
msgstr "Dropbox Anmeldung"
|
||||
msgstr "Dropbox-Anmeldung"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Optionen"
|
||||
|
||||
msgid "Synchronisation Status"
|
||||
msgstr "Synchronisations Status"
|
||||
msgstr "Synchronisations-Status"
|
||||
|
||||
msgid "Encryption Options"
|
||||
msgstr "Verschlüsselungsoptionen"
|
||||
|
||||
msgid "Clipper Options"
|
||||
msgstr "Clipper Einstellungen"
|
||||
msgstr "Clipper-Einstellungen"
|
||||
|
||||
msgid "Remove this tag from all the notes?"
|
||||
msgstr "Dieses Schlagwort von allen Notizen entfernen?"
|
||||
@@ -1093,7 +1130,7 @@ msgstr "Notizbücher"
|
||||
|
||||
msgid "Please select where the sync status should be exported to"
|
||||
msgstr ""
|
||||
"Bitte wähle aus, wohin der Synchronisations Status exportiert werden soll"
|
||||
"Bitte wähle aus, wohin der Synchronisations-Status exportiert werden soll"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Usage: %s"
|
||||
@@ -1123,11 +1160,11 @@ msgstr "WebDAV"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown log level: %s"
|
||||
msgstr "Unbekanntes Log Level: %s"
|
||||
msgstr "Unbekanntes Log-Level: %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown level ID: %s"
|
||||
msgstr "Unbekannte Level ID: %s"
|
||||
msgstr "Unbekannte Level-ID: %s"
|
||||
|
||||
msgid ""
|
||||
"Cannot refresh token: authentication data is missing. Starting the "
|
||||
@@ -1149,7 +1186,7 @@ msgstr ""
|
||||
"Dieser Fehler kommt oft vor, wenn OneDrive Business benutzt wird, das leider "
|
||||
"nicht unterstützt wird.\n"
|
||||
"\n"
|
||||
"Bitte benutze stattdessen einen normalen OneDrive Account."
|
||||
"Bitte benutze stattdessen einen normalen OneDrive-Account."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot access %s"
|
||||
@@ -1165,11 +1202,11 @@ msgstr "Lokale Objekte aktualisiert: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Created remote items: %d."
|
||||
msgstr "Remote Objekte erstellt: %d."
|
||||
msgstr "Remote-Objekte erstellt: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Updated remote items: %d."
|
||||
msgstr "Remote Objekte aktualisiert: %d."
|
||||
msgstr "Remote-Objekte aktualisiert: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Deleted local items: %d."
|
||||
@@ -1177,7 +1214,7 @@ msgstr "Lokale Objekte gelöscht: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Deleted remote items: %d."
|
||||
msgstr "Remote Objekte gelöscht: %d."
|
||||
msgstr "Remote-Objekte gelöscht: %d."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Fetched items: %d/%d."
|
||||
@@ -1188,7 +1225,7 @@ msgid "State: %s."
|
||||
msgstr "Status: %s."
|
||||
|
||||
msgid "Cancelling..."
|
||||
msgstr "Abbrechen…"
|
||||
msgstr "Breche ab…"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Completed: %s"
|
||||
@@ -1220,14 +1257,10 @@ msgstr "Konflikte"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Kann Notizbuch nicht an diesen Ort verschieben"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Ein Notizbuch mit diesem Titel existiert bereits : \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
"Notizbuch kann nicht \"%s\" genannt werden. Dies ist ein reservierter Titel."
|
||||
"Notizbuch kann nicht \"%s\" genannt werden. Dieser Name ist reserviert.."
|
||||
|
||||
msgid "title"
|
||||
msgstr "Titel"
|
||||
@@ -1274,7 +1307,7 @@ msgid "Uncompleted to-dos on top"
|
||||
msgstr "Zeige unvollständige To-Dos an oberster Stelle"
|
||||
|
||||
msgid "Show completed to-dos"
|
||||
msgstr "Abgeschlossene ToDos anzeigen"
|
||||
msgstr "Abgeschlossene To-Dos anzeigen"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr "Sortiere Notizen nach"
|
||||
@@ -1298,11 +1331,14 @@ msgid "When creating a new note:"
|
||||
msgstr "Wenn eine neue Notiz erstellt wird:"
|
||||
|
||||
msgid "Show tray icon"
|
||||
msgstr "Zeige Tray Icon"
|
||||
msgstr "Zeige Tray-Icon"
|
||||
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr "Hinweis: Funktioniert nicht in allen Desktopumgebungen."
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr "Starte die Anwendung minimiert im Tray"
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Zoomstufe der Benutzeroberfläche"
|
||||
|
||||
@@ -1360,7 +1396,7 @@ msgstr ""
|
||||
"dokumentiert) bezeichnet werden."
|
||||
|
||||
msgid "Directory to synchronise with (absolute path)"
|
||||
msgstr "Verzeichnis zum synchronisieren (absoluter Pfad)"
|
||||
msgstr "Verzeichnis mit dem synchronisiert werden soll (absoluter Pfad)"
|
||||
|
||||
msgid ""
|
||||
"The path to synchronise with when file system synchronisation is enabled. "
|
||||
@@ -1370,22 +1406,32 @@ msgstr ""
|
||||
"Synchronisation aktiviert ist. Siehe `sync.target`."
|
||||
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV-URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
"Achtung: Stelle sicher, dass Du vor der Synchronisation alle Inhalte an den "
|
||||
"neuen Ablageort kopiert hast, sonst werden alle Dateien gelöscht! Lies auch "
|
||||
"die FAQs hierzu: %s"
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud Benutzername"
|
||||
msgstr "Nextcloud-Benutzername"
|
||||
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Nextcloud Passwort"
|
||||
msgstr "Nextcloud-Passwort"
|
||||
|
||||
msgid "WebDAV URL"
|
||||
msgstr "WebDAV URL"
|
||||
msgstr "WebDAV-URL"
|
||||
|
||||
msgid "WebDAV username"
|
||||
msgstr "WebDAV Benutzername"
|
||||
msgstr "WebDAV-Benutzername"
|
||||
|
||||
msgid "WebDAV password"
|
||||
msgstr "WebDAV Passwort"
|
||||
msgstr "WebDAV-Passwort"
|
||||
|
||||
msgid "Custom TLS certificates"
|
||||
msgstr "Benutzerdefinierte TLS-Zertifikate"
|
||||
@@ -1397,9 +1443,9 @@ msgid ""
|
||||
"changes before clicking on \"Check synchronisation configuration\"."
|
||||
msgstr ""
|
||||
"Kommagetrennte Liste von Pfaden zu Verzeichnissen, aus denen die Zertifikate "
|
||||
"geladen werden, oder Pfad zu einzelnen Zertifikatsdateien. Zum Beispiel: / "
|
||||
"my / cert_dir, /other/custom.pem. Wenn Sie Änderungen an den TLS-"
|
||||
"Einstellungen vornehmen, müssen Sie Ihre Änderungen speichern, bevor Sie auf "
|
||||
"geladen werden, oder Pfad zu einzelnen Zertifikatsdateien. Zum Beispiel: /my/"
|
||||
"cert_dir, /other/custom.pem. Wenn Sie Änderungen an den TLS-Einstellungen "
|
||||
"vornehmen, müssen Sie Ihre Änderungen speichern, bevor Sie auf "
|
||||
"\"Synchronisierungskonfiguration prüfen\" klicken."
|
||||
|
||||
msgid "Ignore TLS certificate errors"
|
||||
@@ -1409,6 +1455,11 @@ msgstr "Ignoriere TLS-Zertifikatfehler"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ungültiger Optionswert: \"%s\". Mögliche Werte sind: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
"Das Schlagwort \"%s\" existiert bereits. Bitte wähle einen anderen Namen."
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Joplin Export Datei"
|
||||
|
||||
@@ -1526,6 +1577,9 @@ msgstr "%d Notizen in das Notizbuch \"%s\" verschieben?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Tippe hier, um das Entschlüsselungspasswort festzulegen."
|
||||
|
||||
msgid "Clear alarm"
|
||||
msgstr "Alarm löschen"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Alarm speichern"
|
||||
|
||||
@@ -1542,6 +1596,41 @@ msgstr "Synchronisation abbrechen"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Entschlüsselte Objekte: %d/%d"
|
||||
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Überprüfe… Bitte warten."
|
||||
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr ""
|
||||
"Erfolgreich. Die Synchronisation-Konfiguration scheint korrekt zu sein."
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
"Fehler. Bitte überprüfe, ob die URL, der Benutzername, das Passwort. usw. "
|
||||
"korrekt sind und das das Synchronisierungsziel erreichbar ist. Fehlermeldung:"
|
||||
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Das Programm wurde erfolgreich autorisiert."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
"Konnte Applikation nicht autorisieren:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Bitte versuche es erneut."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Entschlüsselte Objekte: %s / %s"
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Neue Schlagwörter:"
|
||||
|
||||
@@ -1671,12 +1760,15 @@ msgstr ""
|
||||
|
||||
msgid "You currently have no notebook. Create one by clicking on (+) button."
|
||||
msgstr ""
|
||||
"Du hast noch kein Notizbuch. Erstelle eines, indem du auf den (+) Knopf "
|
||||
"drückst."
|
||||
"Du hast noch kein Notizbuch angelegt. Erstelle eines, indem du auf den (+) "
|
||||
"Knopf drückst."
|
||||
|
||||
msgid "Welcome"
|
||||
msgstr "Willkommen"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Ein Notizbuch mit diesem Titel existiert bereits : \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Suchen"
|
||||
|
||||
|
@@ -414,7 +414,7 @@ msgstr ""
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -552,6 +552,9 @@ msgstr ""
|
||||
msgid "Paste"
|
||||
msgstr ""
|
||||
|
||||
msgid "Select all"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -635,6 +638,9 @@ msgstr ""
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -678,6 +684,20 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr ""
|
||||
|
||||
@@ -826,6 +846,12 @@ msgstr ""
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch to note type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch to to-do type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr ""
|
||||
|
||||
@@ -842,6 +868,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr ""
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr ""
|
||||
|
||||
@@ -893,6 +925,9 @@ msgstr ""
|
||||
msgid "In: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1089,10 +1124,6 @@ msgstr ""
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
@@ -1171,6 +1202,9 @@ msgstr ""
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
@@ -1230,6 +1264,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
@@ -1262,6 +1303,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr ""
|
||||
|
||||
@@ -1371,6 +1416,9 @@ msgstr ""
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clear alarm"
|
||||
msgstr ""
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr ""
|
||||
|
||||
@@ -1387,6 +1435,33 @@ msgstr ""
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checking... Please wait."
|
||||
msgstr ""
|
||||
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
msgid "The application has been authorised!"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
|
@@ -460,10 +460,11 @@ msgstr "Iniciando sincronización..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Cancelando... Por favor espere."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> puede ser \"add\", \"remove\" o \"list\" para asignar o "
|
||||
"eliminar [tag] de [note], o para listar las notas asociadas con [tag]. El "
|
||||
@@ -628,17 +629,21 @@ msgstr "Cortar"
|
||||
msgid "Paste"
|
||||
msgstr "Pegar"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Seleccione fecha"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
msgstr "Negrita"
|
||||
|
||||
msgid "Italic"
|
||||
msgstr ""
|
||||
msgstr "Cursiva"
|
||||
|
||||
msgid "Insert Date Time"
|
||||
msgstr ""
|
||||
msgstr "Introduce fecha"
|
||||
|
||||
msgid "Edit in external editor"
|
||||
msgstr ""
|
||||
msgstr "Editar con un editor externo"
|
||||
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Buscar en todas las notas"
|
||||
@@ -711,11 +716,13 @@ msgstr "Sí"
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
"El servicio de recorte web está habilitado y configurado para inicie "
|
||||
"automaticamente"
|
||||
"El servicio de recorte web está habilitado y configurado para que inicie "
|
||||
"automáticamente."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Status: Started on port %d"
|
||||
@@ -762,6 +769,21 @@ msgstr "Paso 2: Instalar la extensión"
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr "Descargar e instalar para su navegador:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Mostrar opciones avanzadas"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Comprobar sincronización"
|
||||
|
||||
@@ -770,7 +792,7 @@ msgid "Notes and settings are stored in: %s"
|
||||
msgstr "Las notas y los ajustes se guardan en: %s"
|
||||
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
msgstr "Aplicar"
|
||||
|
||||
msgid "Submit"
|
||||
msgstr "Aceptar"
|
||||
@@ -916,15 +938,23 @@ msgid "Add or remove tags"
|
||||
msgstr "Añadir o borrar etiquetas"
|
||||
|
||||
msgid "Duplicate"
|
||||
msgstr ""
|
||||
msgstr "Duplicado"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "%s - Copy"
|
||||
msgstr "Copiar"
|
||||
msgstr "%s - Copiar"
|
||||
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Cambiar entre nota y lista de tareas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Cambiar entre nota y lista de tareas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Cambiar entre nota y lista de tareas"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Copiar el enlace de Markdown"
|
||||
|
||||
@@ -941,12 +971,18 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "No hay ninguna libreta. Cree una pulsando en «Libreta nueva»."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Abrir..."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "This file could not be opened: %s"
|
||||
msgstr "No se ha podido guardar esta libreta: %s"
|
||||
msgstr "No se ha podido abrir este archivo: %s"
|
||||
|
||||
msgid "Save as..."
|
||||
msgstr "Guardar como..."
|
||||
@@ -955,7 +991,7 @@ msgid "Copy path to clipboard"
|
||||
msgstr "Copiar la ruta en el portapapeles"
|
||||
|
||||
msgid "Copy Link Address"
|
||||
msgstr ""
|
||||
msgstr "Copiar enlace"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unsupported link or message: %s"
|
||||
@@ -970,16 +1006,16 @@ msgstr ""
|
||||
"editar la nota."
|
||||
|
||||
msgid "strong text"
|
||||
msgstr ""
|
||||
msgstr "texto destacado"
|
||||
|
||||
msgid "emphasized text"
|
||||
msgstr ""
|
||||
msgstr "texto resaltado"
|
||||
|
||||
msgid "List item"
|
||||
msgstr ""
|
||||
msgstr "Listar elementos"
|
||||
|
||||
msgid "Insert Hyperlink"
|
||||
msgstr ""
|
||||
msgstr "Insertar hipervínculo"
|
||||
|
||||
msgid "Attach file"
|
||||
msgstr "Adjuntar archivo"
|
||||
@@ -990,37 +1026,39 @@ msgstr "Etiquetas"
|
||||
msgid "Set alarm"
|
||||
msgstr "Establecer alarma"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
msgstr "En: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
msgstr "Hipervínculo"
|
||||
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
msgstr "Código"
|
||||
|
||||
msgid "Numbered List"
|
||||
msgstr ""
|
||||
msgstr "Lista numerada"
|
||||
|
||||
msgid "Bulleted List"
|
||||
msgstr ""
|
||||
msgstr "Lista con viñetas"
|
||||
|
||||
msgid "Checkbox"
|
||||
msgstr ""
|
||||
msgstr "Casilla"
|
||||
|
||||
msgid "Heading"
|
||||
msgstr ""
|
||||
msgstr "Título"
|
||||
|
||||
msgid "Horizontal Rule"
|
||||
msgstr ""
|
||||
msgstr "Regla horizontal"
|
||||
|
||||
msgid "Click to stop external editing"
|
||||
msgstr ""
|
||||
msgstr "Pulsa para detener la edición externa"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Watching..."
|
||||
msgstr "Cancelando..."
|
||||
msgstr "Mirando..."
|
||||
|
||||
msgid "to-do"
|
||||
msgstr "lista de tareas"
|
||||
@@ -1199,26 +1237,19 @@ msgstr "Conflictos"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "No se puede mover la libreta a este lugar"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Ya existe una libreta con este nombre: «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
"No se puede usar el nombre «%s» para una libreta; es un título reservado."
|
||||
|
||||
#, fuzzy
|
||||
msgid "title"
|
||||
msgstr "Sin título"
|
||||
msgstr "título"
|
||||
|
||||
#, fuzzy
|
||||
msgid "updated date"
|
||||
msgstr "Actualizado: %d."
|
||||
msgstr "fecha de actualización"
|
||||
|
||||
#, fuzzy
|
||||
msgid "created date"
|
||||
msgstr "Creado: %d."
|
||||
msgstr "fecha de creación"
|
||||
|
||||
msgid "Untitled"
|
||||
msgstr "Sin título"
|
||||
@@ -1285,6 +1316,9 @@ 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 "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Establecer el porcentaje de aumento de la aplicación"
|
||||
|
||||
@@ -1317,17 +1351,16 @@ msgstr "%d hora"
|
||||
msgid "%d hours"
|
||||
msgstr "%d horas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Text editor command"
|
||||
msgstr "Editor de texto"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The editor command (may include arguments) that will be used to open a note. "
|
||||
"If none is provided it will try to auto-detect the default editor."
|
||||
msgstr ""
|
||||
"El editor que se usará para abrir una nota. Se intentará auto-detectar el "
|
||||
"editor predeterminado si no se proporciona ninguno."
|
||||
"El comando del editor (puede incluir argumentos) que se utilizará para abrir "
|
||||
"una nota. Si no se provee ninguno se intentará auto detectar el editor por "
|
||||
"defecto."
|
||||
|
||||
msgid "Show advanced options"
|
||||
msgstr "Mostrar opciones avanzadas"
|
||||
@@ -1356,6 +1389,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Servidor WebDAV de Nextcloud"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Usuario de Nextcloud"
|
||||
|
||||
@@ -1372,7 +1412,7 @@ msgid "WebDAV password"
|
||||
msgstr "Contraseña de WebDAV"
|
||||
|
||||
msgid "Custom TLS certificates"
|
||||
msgstr ""
|
||||
msgstr "Certificados TLS personalizados"
|
||||
|
||||
msgid ""
|
||||
"Comma-separated list of paths to directories to load the certificates from, "
|
||||
@@ -1380,14 +1420,23 @@ msgid ""
|
||||
"pem. Note that if you make changes to the TLS settings, you must save your "
|
||||
"changes before clicking on \"Check synchronisation configuration\"."
|
||||
msgstr ""
|
||||
"Lista de rutas de los directorios de dónde cargar los certificados separados "
|
||||
"por comas, o la ruta individual de los certificados. Por ejemplo: /mi/"
|
||||
"cert_dir, /otro/personalizado.pem. Tenga en cuenta que si realiza cambios en "
|
||||
"la configuración de los certificados debe guardar los cambios antes de "
|
||||
"pulsar en \"Comprobar la configuración de sincronización\"."
|
||||
|
||||
msgid "Ignore TLS certificate errors"
|
||||
msgstr ""
|
||||
msgstr "Ignorar errores en certificados TLS"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Opción inválida: «%s». Los valores posibles son: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Archivo de exportación de Joplin"
|
||||
|
||||
@@ -1503,6 +1552,9 @@ msgid "Press to set the decryption password."
|
||||
msgstr "Presione para establecer la contraseña de descifrado."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Establecer alarma"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Establecer alarma"
|
||||
|
||||
@@ -1515,9 +1567,39 @@ msgstr "Confirmar"
|
||||
msgid "Cancel synchronisation"
|
||||
msgstr "Cancelar sincronización"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Elementos obtenidos: %d/%d."
|
||||
msgstr "Descifrando elementos: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Cancelando... Por favor espere."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Comprobar sincronización"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "La aplicacion ha sido autorizada éxitosamente."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Descifrando elementos: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Nuevas etiquetas:"
|
||||
@@ -1653,6 +1735,9 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Bienvenido"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Ya existe una libreta con este nombre: «%s»"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
|
||||
#~ "how to enable it please check the documentation"
|
||||
|
@@ -458,10 +458,11 @@ msgstr "Sinkronizazioa hasten..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Bertan behera uzten... itxaron, mesedez."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> izan daiteke \"add\", \"remove\" edo \"list\" [oharra]tik "
|
||||
"[etiketa] esleitu edo kentzeko, edo [etiketa]rekin elkartutako oharrak "
|
||||
@@ -627,6 +628,10 @@ msgstr "Moztu"
|
||||
msgid "Paste"
|
||||
msgstr "Itsatsi"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Data aukeratu"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -712,6 +717,9 @@ msgstr ""
|
||||
msgid "No"
|
||||
msgstr "E"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -755,6 +763,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Erakutsi aukera aurreratuak"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Sinkronizazioa utzi"
|
||||
@@ -920,6 +943,14 @@ msgstr "Kopiatu"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Aldatu oharra eta zeregin eren artean."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Aldatu oharra eta zeregin eren artean."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Aldatu oharra eta zeregin eren artean."
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr ""
|
||||
|
||||
@@ -936,6 +967,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Momentuz ez dago koadernorik. Sortu bat \"Koaderno berria\" sakatuta."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr ""
|
||||
|
||||
@@ -988,6 +1025,9 @@ msgstr "Ezarri alarma"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1200,10 +1240,6 @@ msgstr "Gatazkak"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Ezin eraman daiteke oharra \"%s\" koadernora"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Dagoeneko bada koaderno bat izen horrekin: \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
@@ -1291,6 +1327,9 @@ msgstr ""
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Ezarri aplikazioaren zoomaren ehunekoa"
|
||||
@@ -1359,6 +1398,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud erabiltzaile-izena"
|
||||
|
||||
@@ -1394,6 +1440,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Balio aukera baliogabea: \"%s\". Litezkeen balioak: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernotetik esportatutako fitxategiak"
|
||||
@@ -1508,6 +1558,10 @@ msgstr "Mugitu %d oharrak \"%s\" koadernora?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Sakatu deszifratze pasahitza ezartzeko."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Ezarri alarma"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Ezarri alarma"
|
||||
@@ -1525,6 +1579,36 @@ msgstr "Sinkronizazioa utzi"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Itemak eskuratuta: %d%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Bertan behera uzten... itxaron, mesedez."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Sinkronizazioa utzi"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Aplikazioak baimena hartu du."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Itemak eskuratuta: %d%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
@@ -1651,6 +1735,9 @@ msgstr "Oraindik ez duzu koadernorik. Sortu bat (+) botoian sakatuta."
|
||||
msgid "Welcome"
|
||||
msgstr "Ongi etorri!"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Dagoeneko bada koaderno bat izen horrekin: \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Bilaketak"
|
||||
|
||||
|
@@ -59,7 +59,7 @@ msgstr ""
|
||||
"La commande \"%s\" est disponible uniquement en mode d'interface graphique"
|
||||
|
||||
msgid "Cannot change encrypted item"
|
||||
msgstr "Un objet crypté ne peut pas être modifié"
|
||||
msgstr "Un objet chiffré ne peut pas être modifié"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Missing required argument: %s"
|
||||
@@ -127,7 +127,7 @@ msgid ""
|
||||
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, "
|
||||
"`status` and `target-status`."
|
||||
msgstr ""
|
||||
"Gérer la configuration E2EE (Cryptage de bout à bout). Les commandes sont "
|
||||
"Gérer la configuration E2EE (Chiffrement de bout à bout). Les commandes sont "
|
||||
"`enable`, `disable`, `decrypt` et `status` et `target-status`."
|
||||
|
||||
msgid "Enter master password:"
|
||||
@@ -140,11 +140,11 @@ msgid ""
|
||||
"Starting decryption... Please wait as it may take several minutes depending "
|
||||
"on how much there is to decrypt."
|
||||
msgstr ""
|
||||
"Démarrage du décryptage... Veuillez patienter car cela pourrait prendre "
|
||||
"plusieurs minutes selon le nombre d'objets à décrypter."
|
||||
"Démarrage du déchiffrement... Veuillez patienter car cela pourrait prendre "
|
||||
"plusieurs minutes selon le nombre d'objets à déchiffrer."
|
||||
|
||||
msgid "Completed decryption."
|
||||
msgstr "Décryptage complété."
|
||||
msgstr "Déchiffrement complété."
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Activé"
|
||||
@@ -154,7 +154,7 @@ msgstr "Désactivé"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Encryption is: %s"
|
||||
msgstr "Le cryptage est : %s"
|
||||
msgstr "Le chiffrement est : %s"
|
||||
|
||||
msgid "Edit note."
|
||||
msgstr "Éditer la note."
|
||||
@@ -464,12 +464,12 @@ msgstr "Annulation... Veuillez attendre."
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> peut être \"add\", \"remove\" ou \"list\" pour assigner ou "
|
||||
"enlever l'étiquette [tag] de la [note], our pour lister les notes associées "
|
||||
"avec l'étiquette [tag]. La commande `tag list` peut être utilisée pour "
|
||||
"lister les étiquettes."
|
||||
"lister les étiquettes (utilisez l'option -l pour les options complètes)."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid command: \"%s\""
|
||||
@@ -571,10 +571,10 @@ msgid ""
|
||||
"supplied the password, the encrypted items are being decrypted in the "
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
"Au moins un objet est actuellement crypté et il se peut que vous deviez "
|
||||
"Au moins un objet est actuellement chiffré et il se peut que vous deviez "
|
||||
"fournir votre mot de passe maître. Pour se faire, veuillez taper `e2ee "
|
||||
"decrypt`. Si vous avez déjà fourni ce mot de passe, les objets cryptés vont "
|
||||
"être décrypté en tâche de fond et seront disponible prochainement."
|
||||
"decrypt`. Si vous avez déjà fourni ce mot de passe, les objets chiffrés vont "
|
||||
"être déchiffré en tâche de fond et seront disponible prochainement."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
@@ -627,6 +627,9 @@ msgstr "Couper"
|
||||
msgid "Paste"
|
||||
msgstr "Coller"
|
||||
|
||||
msgid "Select all"
|
||||
msgstr "Sélectionner tout"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr "Gras"
|
||||
|
||||
@@ -661,7 +664,7 @@ msgid "Web clipper options"
|
||||
msgstr "Options du Web Clipper"
|
||||
|
||||
msgid "Encryption options"
|
||||
msgstr "Options de cryptage"
|
||||
msgstr "Options de chiffrement"
|
||||
|
||||
msgid "General Options"
|
||||
msgstr "Options générales"
|
||||
@@ -711,6 +714,9 @@ msgstr "Oui"
|
||||
msgid "No"
|
||||
msgstr "Non"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr "Le code d'authentification a été copié dans le presse-papiers !"
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr "Le service du Web Clipper est activé et démarrera automatiquement."
|
||||
|
||||
@@ -761,6 +767,22 @@ msgstr ""
|
||||
"Téléchargez et installez le module complémentaire correspondant à votre "
|
||||
"navigateur :"
|
||||
|
||||
msgid "Advanced options"
|
||||
msgstr "Options avancées"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr "Code d'authentification :"
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr "Copier le code"
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
"Ce code d'authentification est nécessaire uniquement pour permettre aux "
|
||||
"logiciels tiers d'accéder aux données de Joplin."
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Vérifier config synchronisation"
|
||||
|
||||
@@ -782,9 +804,9 @@ msgid ""
|
||||
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
|
||||
"continue?"
|
||||
msgstr ""
|
||||
"Désactiver le cryptage signifie que *toutes* les notes et fichiers vont être "
|
||||
"re-synchronisés et envoyés décryptés sur la cible de la synchronisation. "
|
||||
"Souhaitez vous continuer ?"
|
||||
"Désactiver le chiffrement signifie que *toutes* les notes et fichiers vont "
|
||||
"être re-synchronisés et envoyés déchiffrés sur la cible de la "
|
||||
"synchronisation. Souhaitez vous continuer ?"
|
||||
|
||||
msgid ""
|
||||
"Enabling encryption means *all* your notes and attachments are going to be "
|
||||
@@ -792,17 +814,17 @@ msgid ""
|
||||
"password as, for security purposes, this will be the *only* way to decrypt "
|
||||
"the data! To enable encryption, please enter your password below."
|
||||
msgstr ""
|
||||
"Activer le cryptage signifie que *toutes* les notes et fichiers vont être re-"
|
||||
"synchronisés et envoyés cryptés vers la cible de la synchronisation. Ne "
|
||||
"Activer le chiffrement signifie que *toutes* les notes et fichiers vont être "
|
||||
"re-synchronisés et envoyés chiffrés vers la cible de la synchronisation. Ne "
|
||||
"perdez pas votre mot de passe car, pour des raisons de sécurité, ce sera la "
|
||||
"*seule* façon de décrypter les données ! Pour activer le cryptage, veuillez "
|
||||
"entrer votre mot de passe ci-dessous."
|
||||
"*seule* façon de déchiffrer les données ! Pour activer le chiffrement, "
|
||||
"veuillez entrer votre mot de passe ci-dessous."
|
||||
|
||||
msgid "Disable encryption"
|
||||
msgstr "Désactiver le cryptage"
|
||||
msgstr "Désactiver le chiffrement"
|
||||
|
||||
msgid "Enable encryption"
|
||||
msgstr "Activer le cryptage"
|
||||
msgstr "Activer le chiffrement"
|
||||
|
||||
msgid "Master Keys"
|
||||
msgstr "Clefs maître"
|
||||
@@ -833,10 +855,10 @@ msgid ""
|
||||
"as \"active\"). Any of the keys might be used for decryption, depending on "
|
||||
"how the notes or notebooks were originally encrypted."
|
||||
msgstr ""
|
||||
"Note : seule une clef maître va être utilisée pour le cryptage (celle "
|
||||
"Note : seule une clef maître va être utilisée pour le chiffrement (celle "
|
||||
"marquée comme \"actif\" ci-dessus). N'importe quelle clef peut être utilisée "
|
||||
"pour le décryptage, selon la façon dont les notes ou carnets étaient cryptés "
|
||||
"à l'origine."
|
||||
"pour le déchiffrement, selon la façon dont les notes ou carnets étaient "
|
||||
"chiffrés à l'origine."
|
||||
|
||||
msgid "Missing Master Keys"
|
||||
msgstr "Clefs maître manquantes"
|
||||
@@ -846,7 +868,7 @@ msgid ""
|
||||
"however the application does not currently have access to them. It is likely "
|
||||
"they will eventually be downloaded via synchronisation."
|
||||
msgstr ""
|
||||
"Les clefs maître avec ces identifiants sont utilisées pour crypter certains "
|
||||
"Les clefs maître avec ces identifiants sont utilisées pour chiffrer certains "
|
||||
"de vos objets, cependant le logiciel n'y a pour l'instant pas accès. Il est "
|
||||
"probable qu'elle vont être prochainement disponible via la synchronisation."
|
||||
|
||||
@@ -854,14 +876,14 @@ msgid ""
|
||||
"For more information about End-To-End Encryption (E2EE) and advices on how "
|
||||
"to enable it please check the documentation:"
|
||||
msgstr ""
|
||||
"Pour plus d'informations sur l'encryption de bout en bout, ainsi que des "
|
||||
"Pour plus d'informations sur le chiffrement de bout en bout, ainsi que des "
|
||||
"conseils pour l'activer, veuillez consulter la documentation :"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "État"
|
||||
|
||||
msgid "Encryption is:"
|
||||
msgstr "Le cryptage est :"
|
||||
msgstr "Le chiffrement est :"
|
||||
|
||||
msgid "Back"
|
||||
msgstr "Retour"
|
||||
@@ -910,7 +932,7 @@ msgid "View them now"
|
||||
msgstr "Les voir maintenant"
|
||||
|
||||
msgid "Some items cannot be decrypted."
|
||||
msgstr "Certains objets ne peuvent être décryptés."
|
||||
msgstr "Certains objets ne peuvent être déchiffrés."
|
||||
|
||||
msgid "Set the password"
|
||||
msgstr "Définir le mot de passe"
|
||||
@@ -928,6 +950,12 @@ msgstr "%s - Copie"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Alterner entre note et tâche"
|
||||
|
||||
msgid "Switch to note type"
|
||||
msgstr "Convertir en note"
|
||||
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Convertir en tâche"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Copier lien Markdown"
|
||||
|
||||
@@ -947,6 +975,12 @@ msgstr ""
|
||||
"Il n'y a pour l'instant aucun carnet. Créez-en un en cliquant sur \"Nouveau "
|
||||
"carnet\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr "Lieu"
|
||||
|
||||
msgid "URL"
|
||||
msgstr "URL"
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Ouvrir..."
|
||||
|
||||
@@ -1000,6 +1034,9 @@ msgstr "Régler alarme"
|
||||
msgid "In: %s"
|
||||
msgstr "Dans : %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr "Propriétés de la note"
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr "Lien"
|
||||
|
||||
@@ -1056,7 +1093,7 @@ msgid "Synchronisation Status"
|
||||
msgstr "État de la synchronisation"
|
||||
|
||||
msgid "Encryption Options"
|
||||
msgstr "Options de cryptage"
|
||||
msgstr "Options de chiffrement"
|
||||
|
||||
msgid "Clipper Options"
|
||||
msgstr "Options du Web Clipper"
|
||||
@@ -1194,10 +1231,10 @@ msgid "Synchronisation is already in progress. State: %s"
|
||||
msgstr "La synchronisation est déjà en cours. État : %s"
|
||||
|
||||
msgid "Encrypted"
|
||||
msgstr "Crypté"
|
||||
msgstr "Chiffré"
|
||||
|
||||
msgid "Encrypted items cannot be modified"
|
||||
msgstr "Les objets cryptés ne peuvent être modifiés"
|
||||
msgstr "Les objets chiffrés ne peuvent être modifiés"
|
||||
|
||||
msgid "Conflicts"
|
||||
msgstr "Conflits"
|
||||
@@ -1205,10 +1242,6 @@ msgstr "Conflits"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Impossible de déplacer le carnet à cet endroit"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Un carnet avec ce titre existe déjà : \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Les carnets ne peuvent être nommés \"%s\" car c'est un nom réservé."
|
||||
@@ -1287,6 +1320,9 @@ 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 "Start application minimised in the tray icon"
|
||||
msgstr "Démarrer minimisé dans la zone de notification"
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Niveau de zoom"
|
||||
|
||||
@@ -1356,6 +1392,16 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud : URL WebDAV"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
"Attention : si vous changez cet emplacement, copiez-y tout le contenu avant "
|
||||
"de synchroniser, sinon tous les fichiers seront supprimés ! Consulter la FAQ "
|
||||
"pour plus de détails : %s"
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud : Nom utilisateur"
|
||||
|
||||
@@ -1393,6 +1439,10 @@ msgstr "Ignorer les erreurs de certificats TLS"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Option invalide: \"%s\". Les valeurs possibles sont : %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr "L'étiquette \"%s\" existe déjà. Veuillez choisir un autre nom."
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Fichier d'export Joplin"
|
||||
|
||||
@@ -1421,7 +1471,7 @@ msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
"Cet objet est crypté : %s \"%s\". Veuillez attendre que tout soit décrypté "
|
||||
"Cet objet est chiffré : %s \"%s\". Veuillez attendre que tout soit déchiffré "
|
||||
"et réessayez."
|
||||
|
||||
msgid "There is no data to export."
|
||||
@@ -1494,7 +1544,7 @@ msgid "Export Debug Report"
|
||||
msgstr "Exporter rapport de débogage"
|
||||
|
||||
msgid "Encryption Config"
|
||||
msgstr "Config cryptage"
|
||||
msgstr "Config chiffrement"
|
||||
|
||||
msgid "Configuration"
|
||||
msgstr "Configuration"
|
||||
@@ -1509,6 +1559,9 @@ msgstr "Déplacer %d notes vers carnet \"%s\" ?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Définir mot de passe de synchronisation."
|
||||
|
||||
msgid "Clear alarm"
|
||||
msgstr "Enlever l'alarme"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Enregistrer alarme"
|
||||
|
||||
@@ -1523,7 +1576,41 @@ msgstr "Annuler synchronisation"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Décryptage des objets : %d/%d"
|
||||
msgstr "Déchiffrement des objets : %d/%d"
|
||||
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Vérification... Veuillez attendre."
|
||||
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "La configuration de la synchronisation semble correcte."
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
"Erreur. Veuillez vérifier que l'URL, le nom, le mot de passe, etc. sont "
|
||||
"corrects et que la destination est accessible. L'erreur reportée est :"
|
||||
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Le logiciel a été autorisé !"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
"Impossible d'autoriser le logiciel :\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Veuillez réessayer."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Déchiffrement : %s / %s"
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Nouvelles étiquettes :"
|
||||
@@ -1659,12 +1746,15 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Bienvenue"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Un carnet avec ce titre existe déjà : \"%s\""
|
||||
|
||||
#~ msgid ""
|
||||
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
|
||||
#~ "how to enable it please check the documentation"
|
||||
#~ msgstr ""
|
||||
#~ "Pour plus d'informations sur l'encryption de bout en bout, ainsi que des "
|
||||
#~ "conseils pour l'activer, veuillez consulter la documentation"
|
||||
#~ "Pour plus d'informations sur le chiffrement de bout en bout, ainsi que "
|
||||
#~ "des conseils pour l'activer, veuillez consulter la documentation"
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Recherches"
|
||||
|
@@ -455,10 +455,11 @@ msgstr "Iniciando sincronización..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Cancelando... Agarde."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> pode ser «add», «remove» ou «list» para asignar ou eliminar "
|
||||
"[tag] da [note] ou para listar as notas asociadas con [tag]. A orde «list» "
|
||||
@@ -619,6 +620,10 @@ msgstr "Cortar"
|
||||
msgid "Paste"
|
||||
msgstr "Pegar"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Seleccionar data"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -702,6 +707,9 @@ msgstr "Si"
|
||||
msgid "No"
|
||||
msgstr "Non"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -745,6 +753,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Mostrar opcións avanzadas"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Comprobar a configuración da sincronización"
|
||||
|
||||
@@ -907,6 +930,14 @@ msgstr "Copiar"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Cambiar entre notas e tarefas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Cambiar entre notas e tarefas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Cambiar entre notas e tarefas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown"
|
||||
@@ -924,6 +955,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Este no é un caderno. Cree un, premendo en «Novo caderno»."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Abrir…"
|
||||
|
||||
@@ -977,6 +1014,9 @@ msgstr "Estabelecer alarma"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1184,10 +1224,6 @@ msgstr "Conflitos"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Non é posíbel mover a nota ao caderno «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Xa existe un caderno con ese título: «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Os cadernos non poden levar o nome «%s» porque é un título reservado."
|
||||
@@ -1270,6 +1306,9 @@ msgstr "Mostrar a icona na bandexa"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Porcentaxe de ampliación"
|
||||
|
||||
@@ -1340,6 +1379,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "URL de Nextcloud WebDAV"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Usuario de Nextcloud"
|
||||
|
||||
@@ -1372,6 +1418,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Valor incorrecto de opción: «%s». Os valores posíbeis son: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Ficheiro de exportación do Joplin"
|
||||
|
||||
@@ -1486,6 +1536,10 @@ msgstr "Mover %d notas para o caderno \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Prema para estabelecer o contrasinal de descifrado."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Estabelecer alarma"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Estabelecer alarma"
|
||||
@@ -1503,6 +1557,36 @@ msgstr "Cancelar sincronización"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Elementos obtidos: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Cancelando... Agarde."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Comprobar a configuración da sincronización"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "O aplicativo foi autorizado correctamente."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Elementos obtidos: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Etiquetas novas:"
|
||||
|
||||
@@ -1628,3 +1712,6 @@ msgstr "Non ten cadernos actualmente. Cree un premendo no botón (+)."
|
||||
|
||||
msgid "Welcome"
|
||||
msgstr "Benvido/a"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Xa existe un caderno con ese título: «%s»"
|
||||
|
@@ -462,7 +462,7 @@ msgstr "Prekidam... Pričekaj."
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<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 "
|
||||
@@ -625,6 +625,10 @@ msgstr "Izreži"
|
||||
msgid "Paste"
|
||||
msgstr "Zalijepi"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Odaberi datum"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -711,6 +715,9 @@ msgstr ""
|
||||
msgid "No"
|
||||
msgstr "N"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -754,6 +761,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Prikaži napredne opcije"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Prekini sinkronizaciju"
|
||||
@@ -908,6 +930,14 @@ msgstr "Kopiraj"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Zamijeni bilješku i zadatak"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Zamijeni bilješku i zadatak"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Zamijeni bilješku i zadatak"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr ""
|
||||
|
||||
@@ -924,6 +954,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Ovdje nema bilježnica. Stvori novu pritiskom na \"Nova bilježnica\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr ""
|
||||
|
||||
@@ -976,6 +1012,9 @@ msgstr "Postavi upozorenje"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1184,10 +1223,6 @@ msgstr "Sukobi"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Ne mogu premjestiti bilješku u bilježnicu %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Bilježnica s ovim naslovom već postoji: \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Naslov \"%s\" je rezerviran i ne može se koristiti."
|
||||
@@ -1275,6 +1310,9 @@ msgstr ""
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
@@ -1340,6 +1378,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
@@ -1372,6 +1417,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Nevažeća vrijednost: \"%s\". Moguće vrijednosti su: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernote izvozne datoteke"
|
||||
@@ -1484,6 +1533,10 @@ msgstr "Premjesti %d bilješke u bilježnicu \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Postavi upozorenje"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Postavi upozorenje"
|
||||
@@ -1501,6 +1554,36 @@ msgstr "Prekini sinkronizaciju"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Stvorene lokalne stavke: %d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Prekidam... Pričekaj."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Prekini sinkronizaciju"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Aplikacija je uspješno autorizirana."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Stvorene lokalne stavke: %d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
@@ -1628,6 +1711,9 @@ msgstr "Trenutno nemaš nijednu bilježnicu. Stvori novu klikom na (+) gumb."
|
||||
msgid "Welcome"
|
||||
msgstr "Dobro došli"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Bilježnica s ovim naslovom već postoji: \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Pretraživanja"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -414,7 +414,7 @@ msgstr ""
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -552,6 +552,9 @@ msgstr ""
|
||||
msgid "Paste"
|
||||
msgstr ""
|
||||
|
||||
msgid "Select all"
|
||||
msgstr ""
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -635,6 +638,9 @@ msgstr ""
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -678,6 +684,20 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Advanced options"
|
||||
msgstr ""
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr ""
|
||||
|
||||
@@ -826,6 +846,12 @@ msgstr ""
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch to note type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch to to-do type"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr ""
|
||||
|
||||
@@ -842,6 +868,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr ""
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr ""
|
||||
|
||||
@@ -893,6 +925,9 @@ msgstr ""
|
||||
msgid "In: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1089,10 +1124,6 @@ msgstr ""
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
@@ -1171,6 +1202,9 @@ msgstr ""
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
@@ -1230,6 +1264,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
@@ -1262,6 +1303,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr ""
|
||||
|
||||
@@ -1371,6 +1416,9 @@ msgstr ""
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr ""
|
||||
|
||||
msgid "Clear alarm"
|
||||
msgstr ""
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr ""
|
||||
|
||||
@@ -1387,6 +1435,33 @@ msgstr ""
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr ""
|
||||
|
||||
msgid "Checking... Please wait."
|
||||
msgstr ""
|
||||
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
msgid "The application has been authorised!"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
|
1708
CliClient/locales/ko.po
Normal file
1708
CliClient/locales/ko.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -459,10 +459,11 @@ msgstr "Synchronisatie starten..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Annuleren.. Even geduld."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> kan \"add\", \"remove\" of \"list\" zijn om een [tag] toe te "
|
||||
"voegen aan een [note] of te verwijderen, of om alle notities geassocieerd "
|
||||
@@ -629,6 +630,10 @@ msgstr "Knip"
|
||||
msgid "Paste"
|
||||
msgstr "Plak"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Selecteer datum"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -714,6 +719,9 @@ msgstr ""
|
||||
msgid "No"
|
||||
msgstr "N"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -757,6 +765,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Toon geavanceerde opties"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Annuleer synchronisatie"
|
||||
@@ -922,6 +945,14 @@ msgstr "Kopieer"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Wissel tussen notitie en to-do type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Wissel tussen notitie en to-do type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Wissel tussen notitie en to-do type"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr ""
|
||||
|
||||
@@ -940,6 +971,12 @@ msgstr ""
|
||||
"U heeft momenteel geen notitieboek. Maak een notitieboek door op \"Nieuw "
|
||||
"notitieboek\" te klikken."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr ""
|
||||
|
||||
@@ -992,6 +1029,9 @@ msgstr "Zet melding"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1202,10 +1242,6 @@ msgstr "Conflicten"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Kan notitie niet naar notitieboek \"%s\" verplaatsen."
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Er bestaat al een notitieboek met \"%s\" als titel"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
@@ -1294,6 +1330,9 @@ msgstr ""
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
@@ -1360,6 +1399,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
@@ -1394,6 +1440,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ongeldige optie: \"%s\". Geldige waarden zijn: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Exporteer Evernote bestanden"
|
||||
@@ -1510,6 +1560,10 @@ msgstr "Verplaats %d notities naar notitieboek \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Klik om het decryptie wachtwoord in te stellen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Zet melding"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Zet melding"
|
||||
@@ -1527,6 +1581,36 @@ msgstr "Annuleer synchronisatie"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Opgehaalde items: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Annuleren.. Even geduld."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Annuleer synchronisatie"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "De applicatie is succesvol geauthenticeerd."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Opgehaalde items: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
@@ -1655,6 +1739,9 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Welkom"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Er bestaat al een notitieboek met \"%s\" als titel"
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Zoekopdrachten"
|
||||
|
||||
|
1746
CliClient/locales/nl_NL.po
Normal file
1746
CliClient/locales/nl_NL.po
Normal file
File diff suppressed because it is too large
Load Diff
1726
CliClient/locales/no.po
Normal file
1726
CliClient/locales/no.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -246,9 +246,8 @@ msgstr ""
|
||||
"Use as setas e a Page Up/Page Down para rolar as listas e áreas de texto "
|
||||
"(incluindo este console)."
|
||||
|
||||
#, fuzzy
|
||||
msgid "To maximise/minimise the console, press \"tc\"."
|
||||
msgstr "Para maximizar / minimizar o console, pressione \"TC\"."
|
||||
msgstr "Para maximizar / minimizar o console, pressione \"tc\"."
|
||||
|
||||
msgid "To enter command line mode, press \":\""
|
||||
msgstr "Para entrar no modo de linha de comando, pressione \":\""
|
||||
@@ -363,12 +362,11 @@ msgstr "Exclui o caderno informado."
|
||||
msgid "Deletes the notebook without asking for confirmation."
|
||||
msgstr "Exclui o caderno sem pedir confirmação."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Delete notebook? All notes and sub-notebooks within this notebook will also "
|
||||
"be deleted."
|
||||
msgstr ""
|
||||
"Excluir o caderno? Todas as notas deste caderno notebook também serão "
|
||||
"Excluir o caderno? Todas as notas e sub-cadernos dentro deste também serão "
|
||||
"excluídas."
|
||||
|
||||
msgid "Deletes the notes matching <note-pattern>."
|
||||
@@ -459,10 +457,11 @@ msgstr "Iniciando sincronização..."
|
||||
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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
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 "
|
||||
@@ -626,17 +625,21 @@ msgstr "Cortar"
|
||||
msgid "Paste"
|
||||
msgstr "Colar"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Selecionar data"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
msgstr "Negrito"
|
||||
|
||||
msgid "Italic"
|
||||
msgstr ""
|
||||
msgstr "Itálico"
|
||||
|
||||
msgid "Insert Date Time"
|
||||
msgstr ""
|
||||
msgstr "Inserir Data e Hora"
|
||||
|
||||
msgid "Edit in external editor"
|
||||
msgstr ""
|
||||
msgstr "Editar com editor externo"
|
||||
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Pesquisar em todas as notas"
|
||||
@@ -645,7 +648,7 @@ msgid "View"
|
||||
msgstr "Visualizar"
|
||||
|
||||
msgid "Toggle sidebar"
|
||||
msgstr ""
|
||||
msgstr "Alternar barra lateral"
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr "Alternar layout do editor"
|
||||
@@ -657,7 +660,7 @@ msgid "Synchronisation status"
|
||||
msgstr "Status de sincronização"
|
||||
|
||||
msgid "Web clipper options"
|
||||
msgstr ""
|
||||
msgstr "Opções do Web clipper"
|
||||
|
||||
msgid "Encryption options"
|
||||
msgstr "Opções de Encriptação"
|
||||
@@ -709,47 +712,71 @@ msgstr "Sim"
|
||||
msgid "No"
|
||||
msgstr "Não"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
"O serviço de web clipper está habilitado e configurado para auto-start."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Status: Started on port %d"
|
||||
msgstr ""
|
||||
msgstr "Status: Iniciado, na porta %d"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Status: %s"
|
||||
msgstr "Estado: \"%s\"."
|
||||
msgstr "Status: \"%s\"."
|
||||
|
||||
msgid "Disable Web Clipper Service"
|
||||
msgstr ""
|
||||
msgstr "Desabilitar serviço Web Clipper"
|
||||
|
||||
msgid "The web clipper service is not enabled."
|
||||
msgstr ""
|
||||
msgstr "O serviço de web clipper não está habilitado."
|
||||
|
||||
msgid "Enable Web Clipper Service"
|
||||
msgstr ""
|
||||
msgstr "Habilitar serviço Web Clipper"
|
||||
|
||||
msgid ""
|
||||
"Joplin Web Clipper allows saving web pages and screenshots from your browser "
|
||||
"to Joplin."
|
||||
msgstr ""
|
||||
"O serviço de Web Clipper do Joplin permite salvar páginas da web e "
|
||||
"screenshots do seu browser, no Joplin."
|
||||
|
||||
msgid "In order to use the web clipper, you need to do the following:"
|
||||
msgstr ""
|
||||
msgstr "Para usar o web clipper, você precisa fazer o seguinte:"
|
||||
|
||||
msgid "Step 1: Enable the clipper service"
|
||||
msgstr ""
|
||||
msgstr "Passo 1: Habilitar o serviço do clipper"
|
||||
|
||||
msgid ""
|
||||
"This service allows the browser extension to communicate with Joplin. When "
|
||||
"enabling it your firewall may ask you to give permission to Joplin to listen "
|
||||
"to a particular port."
|
||||
msgstr ""
|
||||
"Este serviço permite a extensão do browser se comunicat com o Joplin. Quando "
|
||||
"habilitar, talvez seu firewall peça que você conceda permissão ao Joplin "
|
||||
"para escutar determinada porta."
|
||||
|
||||
msgid "Step 2: Install the extension"
|
||||
msgstr ""
|
||||
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 ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
@@ -760,7 +787,7 @@ msgid "Notes and settings are stored in: %s"
|
||||
msgstr "Notas e configurações estão armazenadas em: %s"
|
||||
|
||||
msgid "Apply"
|
||||
msgstr ""
|
||||
msgstr "Aplicar"
|
||||
|
||||
msgid "Submit"
|
||||
msgstr "Enviar"
|
||||
@@ -879,9 +906,8 @@ msgstr "Separe cada tag por vírgula."
|
||||
msgid "Rename notebook:"
|
||||
msgstr "Renomear caderno:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Rename tag:"
|
||||
msgstr "Renomear"
|
||||
msgstr "Renomear tag:"
|
||||
|
||||
msgid "Set alarm:"
|
||||
msgstr "Definir alarme:"
|
||||
@@ -908,18 +934,25 @@ msgid "Add or remove tags"
|
||||
msgstr "Adicionar ou remover tags"
|
||||
|
||||
msgid "Duplicate"
|
||||
msgstr ""
|
||||
msgstr "Duplicar"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "%s - Copy"
|
||||
msgstr "Copiar"
|
||||
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"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Alternar entre os tipos Nota e Tarefa"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown"
|
||||
msgstr "Copiar link de Markdown"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Excluir"
|
||||
@@ -934,21 +967,27 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Atualmente, não há cadernos. Crie um, clicando em \"Novo caderno\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Abrir..."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "This file could not be opened: %s"
|
||||
msgstr "O caderno não pôde ser salvo: %s"
|
||||
msgstr "Este arquivo não pôde ser aberto: %s"
|
||||
|
||||
msgid "Save as..."
|
||||
msgstr "Salvar como..."
|
||||
|
||||
msgid "Copy path to clipboard"
|
||||
msgstr ""
|
||||
msgstr "Copiar caminho para a área de transferência"
|
||||
|
||||
msgid "Copy Link Address"
|
||||
msgstr ""
|
||||
msgstr "Copiar endereço do link"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unsupported link or message: %s"
|
||||
@@ -963,16 +1002,16 @@ msgstr ""
|
||||
"e edite a nota."
|
||||
|
||||
msgid "strong text"
|
||||
msgstr ""
|
||||
msgstr "texto forte"
|
||||
|
||||
msgid "emphasized text"
|
||||
msgstr ""
|
||||
msgstr "texto enfatizado"
|
||||
|
||||
msgid "List item"
|
||||
msgstr ""
|
||||
msgstr "Listar item"
|
||||
|
||||
msgid "Insert Hyperlink"
|
||||
msgstr ""
|
||||
msgstr "Inserir Hiperlink"
|
||||
|
||||
msgid "Attach file"
|
||||
msgstr "Anexar arquivo"
|
||||
@@ -983,37 +1022,39 @@ msgstr "Tags"
|
||||
msgid "Set alarm"
|
||||
msgstr "Definir alarme"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
msgstr "Em: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
msgstr "Hiperlink"
|
||||
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
msgstr "Código"
|
||||
|
||||
msgid "Numbered List"
|
||||
msgstr ""
|
||||
msgstr "Lista numerada"
|
||||
|
||||
msgid "Bulleted List"
|
||||
msgstr ""
|
||||
msgstr "Lista com bullets"
|
||||
|
||||
msgid "Checkbox"
|
||||
msgstr ""
|
||||
msgstr "Checkbox"
|
||||
|
||||
msgid "Heading"
|
||||
msgstr ""
|
||||
msgstr "Cabeçalho"
|
||||
|
||||
msgid "Horizontal Rule"
|
||||
msgstr ""
|
||||
msgstr "Régua horizontal"
|
||||
|
||||
msgid "Click to stop external editing"
|
||||
msgstr ""
|
||||
msgstr "Clique para encerrar edição externa"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Watching..."
|
||||
msgstr "Cancelando..."
|
||||
msgstr "Verificando..."
|
||||
|
||||
msgid "to-do"
|
||||
msgstr "tarefa"
|
||||
@@ -1046,9 +1087,8 @@ msgstr "Status de sincronização"
|
||||
msgid "Encryption Options"
|
||||
msgstr "Opções de Encriptação"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clipper Options"
|
||||
msgstr "Opções Gerais"
|
||||
msgstr "Opções do clipper"
|
||||
|
||||
msgid "Remove this tag from all the notes?"
|
||||
msgstr "Remover esta tag de todas as notas?"
|
||||
@@ -1192,30 +1232,22 @@ msgstr "Itens encriptados não podem ser modificados"
|
||||
msgid "Conflicts"
|
||||
msgstr "Conflitos"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Não é possível mover a nota para o caderno \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Já existe caderno com este título: \"%s\""
|
||||
msgstr "Não é possível mover a nota para este local"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr ""
|
||||
"Os cadernos não podem ser nomeados como\"%s\", que é um título reservado."
|
||||
|
||||
#, fuzzy
|
||||
msgid "title"
|
||||
msgstr "Sem título"
|
||||
msgstr "título"
|
||||
|
||||
#, fuzzy
|
||||
msgid "updated date"
|
||||
msgstr "Atualizado: %d."
|
||||
msgstr "data de ataualização"
|
||||
|
||||
#, fuzzy
|
||||
msgid "created date"
|
||||
msgstr "Criado: %d."
|
||||
msgstr "data de criação"
|
||||
|
||||
msgid "Untitled"
|
||||
msgstr "Sem título"
|
||||
@@ -1252,9 +1284,8 @@ msgstr "Dark"
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Mostrar tarefas incompletas no topo"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Show completed to-dos"
|
||||
msgstr "Mostrar tarefas incompletas no topo"
|
||||
msgstr "Mostrar tarefas completas"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr "Ordenar notas por"
|
||||
@@ -1281,6 +1312,9 @@ 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"
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
@@ -1289,13 +1323,12 @@ msgstr "Porcentagem global do zoom"
|
||||
msgid "Editor font family"
|
||||
msgstr "Família de fontes do editor"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"This must be *monospace* font or it will not work properly. If the font is "
|
||||
"incorrect or empty, it will default to a generic monospace font."
|
||||
msgstr ""
|
||||
"O nomes da fonte não será verificado. Se estiver incorreto ou vazio, será "
|
||||
"usado por default uma fonte genérica monospace."
|
||||
"Deve ser uma fonte *monospace\" ou não vai funcionar direito. Se a fonte "
|
||||
"estiver incorreta ou vazia, será usada uma fonte genérica monospace default."
|
||||
|
||||
msgid "Automatically update the application"
|
||||
msgstr "Atualizar automaticamente o aplicativo"
|
||||
@@ -1315,17 +1348,16 @@ msgstr "%d hora"
|
||||
msgid "%d hours"
|
||||
msgstr "%d horas"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Text editor command"
|
||||
msgstr "Editor de texto"
|
||||
msgstr "Comando do editor de texto"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The editor command (may include arguments) that will be used to open a note. "
|
||||
"If none is provided it will try to auto-detect the default editor."
|
||||
msgstr ""
|
||||
"O editor que será usado para abrir uma nota. Se nenhum for indicado, ele "
|
||||
"tentará detectar automaticamente o editor padrão."
|
||||
"O comando do editor (pode incluir argumentos) que será usado para abrir uma "
|
||||
"nota. Se nenhum for indicado, ele tentará detectar automaticamente o editor "
|
||||
"padrão."
|
||||
|
||||
msgid "Show advanced options"
|
||||
msgstr "Mostrar opções avançadas"
|
||||
@@ -1353,6 +1385,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Usuário da Nextcloud"
|
||||
|
||||
@@ -1369,7 +1408,7 @@ msgid "WebDAV password"
|
||||
msgstr "Senha do WebDAV"
|
||||
|
||||
msgid "Custom TLS certificates"
|
||||
msgstr ""
|
||||
msgstr "Certificados TLS customizados"
|
||||
|
||||
msgid ""
|
||||
"Comma-separated list of paths to directories to load the certificates from, "
|
||||
@@ -1377,14 +1416,23 @@ msgid ""
|
||||
"pem. Note that if you make changes to the TLS settings, you must save your "
|
||||
"changes before clicking on \"Check synchronisation configuration\"."
|
||||
msgstr ""
|
||||
"Lista de caminhos para diretórios, separados por vírgula, de onde carregar "
|
||||
"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\""
|
||||
|
||||
msgid "Ignore TLS certificate errors"
|
||||
msgstr ""
|
||||
msgstr "Ignorar erros de certificados TLS"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
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 ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Arquivo de Exportação do Joplin"
|
||||
|
||||
@@ -1501,9 +1549,12 @@ msgid "Press to set the decryption password."
|
||||
msgstr "Pressione para configurar a senha de decriptação."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgid "Clear alarm"
|
||||
msgstr "Definir alarme"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Salvar alarme"
|
||||
|
||||
msgid "Select date"
|
||||
msgstr "Selecionar data"
|
||||
|
||||
@@ -1513,9 +1564,39 @@ msgstr "Confirmar"
|
||||
msgid "Cancel synchronisation"
|
||||
msgstr "Cancelar sincronização"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Itens pesquisados: %d/%d."
|
||||
msgstr "Decriptando itens: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Cancelando... Aguarde."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Verificar a configuração da sincronização"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "O aplicativo foi autorizado com sucesso."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Decriptando itens: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Novas tags:"
|
||||
@@ -1527,17 +1608,24 @@ msgid ""
|
||||
"To work correctly, the app needs the following permissions. Please enable "
|
||||
"them in your phone settings, in Apps > Joplin > Permissions"
|
||||
msgstr ""
|
||||
"Para funcionar corretamente, o app precisa das seguintes permissões. Por "
|
||||
"favor, habilite-as nas configurações do seu telefone, em Apps >Joplin > "
|
||||
"Permissões"
|
||||
|
||||
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 "
|
||||
|
||||
msgid "- Camera: to allow taking a picture and attaching it to a note."
|
||||
msgstr ""
|
||||
msgstr "- Câmera: para permitir tirar fotos e anexar a uma nota."
|
||||
|
||||
msgid "- Location: to allow attaching geo-location information to a note."
|
||||
msgstr ""
|
||||
"- Localização: para permitir anexar informações de geo-localização a uma "
|
||||
"nota."
|
||||
|
||||
msgid "Joplin website"
|
||||
msgstr "Site do Joplin"
|
||||
@@ -1586,11 +1674,11 @@ msgstr "Descartar alterações"
|
||||
|
||||
#, javascript-format
|
||||
msgid "No item with ID %s"
|
||||
msgstr ""
|
||||
msgstr "Nenhum item com ID %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "The Joplin mobile app does not currently support this type of link: %s"
|
||||
msgstr ""
|
||||
msgstr "O app mobile do Joplin não suporta, atualmente, esse tipo de link: %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unsupported image type: %s"
|
||||
@@ -1603,7 +1691,7 @@ msgid "Attach any file"
|
||||
msgstr "Anexar qualquer arquivo"
|
||||
|
||||
msgid "Share"
|
||||
msgstr ""
|
||||
msgstr "Compartilhar"
|
||||
|
||||
msgid "Convert to note"
|
||||
msgstr "Converter para nota"
|
||||
@@ -1642,6 +1730,9 @@ msgstr "Você não possui cadernos. Crie um clicando no botão (+)."
|
||||
msgid "Welcome"
|
||||
msgstr "Bem-vindo"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Já existe caderno com este título: \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Pesquisas"
|
||||
|
||||
|
1611
CliClient/locales/ro.po
Normal file
1611
CliClient/locales/ro.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -459,10 +459,11 @@ msgstr "Начало синхронизации..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Отмена... Пожалуйста, ожидайте."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> может быть «add», «remove» или «list», чтобы назначить или "
|
||||
"убрать [tag] с [note], или чтобы вывести список заметок, ассоциированых с "
|
||||
@@ -626,6 +627,10 @@ msgstr "Вырезать"
|
||||
msgid "Paste"
|
||||
msgstr "Вставить"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Выбрать дату"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -709,6 +714,9 @@ msgstr "Да"
|
||||
msgid "No"
|
||||
msgstr "Нет"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -752,6 +760,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Показывать расширенные настройки"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Проверить настройки синхронизации"
|
||||
|
||||
@@ -917,6 +940,14 @@ msgstr "Копировать"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Переключить тип между заметкой и задачей"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Переключить тип между заметкой и задачей"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Переключить тип между заметкой и задачей"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdown"
|
||||
@@ -934,6 +965,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "Сейчас здесь нет блокнотов. Создайте новый нажав «Новый блокнот»."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Открыть..."
|
||||
|
||||
@@ -987,6 +1024,9 @@ msgstr "Установить напоминание"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1194,10 +1234,6 @@ msgstr "Конфликты"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Не удалось переместить заметку в блокнот «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Блокнот с таким названием уже существует: «%s»"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Блокнот не может быть назван «%s», это зарезервированное название."
|
||||
@@ -1280,6 +1316,9 @@ msgstr "Показывать иконку в панели задач"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Глобальный масштаб в процентах"
|
||||
|
||||
@@ -1350,6 +1389,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Имя пользователя Nextcloud"
|
||||
|
||||
@@ -1382,6 +1428,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Неверное значение параметра: «%s». Доступные значения: %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Файл экспорта Joplin"
|
||||
|
||||
@@ -1497,6 +1547,10 @@ msgstr "Переместить %d заметок в блокнот «%s»?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Нажмите, чтобы установить пароль для расшифровки."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Установить напоминание"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Установить напоминание"
|
||||
@@ -1514,6 +1568,36 @@ msgstr "Отменить синхронизацию"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Получено элементов: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Отмена... Пожалуйста, ожидайте."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Проверить настройки синхронизации"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Приложение успешно авторизовано."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Получено элементов: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
@@ -1640,6 +1724,9 @@ msgstr "У вас сейчас нет блокнота. Создайте его
|
||||
msgid "Welcome"
|
||||
msgstr "Добро пожаловать"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Блокнот с таким названием уже существует: «%s»"
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Запросы"
|
||||
|
||||
|
@@ -458,10 +458,11 @@ msgstr "Sinhronizacija se začenja."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "V preklicu...Prosim počakajte."
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> je lahko \"dodaj\", \"odstrani\" ali \"naštej\", da dodeliš "
|
||||
"ali odstraniš [tag] from [note] ali našteje zabeležke povezane z oznako "
|
||||
@@ -625,6 +626,10 @@ msgstr "Izreži"
|
||||
msgid "Paste"
|
||||
msgstr "Prilepi"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Izberi datum"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr ""
|
||||
|
||||
@@ -708,6 +713,9 @@ msgstr "Da"
|
||||
msgid "No"
|
||||
msgstr "Ne"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr ""
|
||||
|
||||
@@ -751,6 +759,21 @@ msgstr ""
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Pokaži napredne možnosti"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "Preveri nastavitve sinhronizacije"
|
||||
|
||||
@@ -917,6 +940,14 @@ msgstr "Kopiraj"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Menjaj med zabeležko in seznamom opravil"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Menjaj med zabeležko in seznamom opravil"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Menjaj med zabeležko in seznamom opravil"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Sistem označevanja"
|
||||
@@ -938,6 +969,12 @@ msgstr ""
|
||||
"Trenutno ni tukaj nobene beležnice. Ustvarite jo z klikom na \"Nova beležnica"
|
||||
"\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Odpri..."
|
||||
|
||||
@@ -991,6 +1028,9 @@ msgstr "Nastavi alarm"
|
||||
msgid "In: %s"
|
||||
msgstr "%s: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr ""
|
||||
|
||||
@@ -1198,10 +1238,6 @@ msgstr "Konfikti"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "Ni moč premakniti zabeležke v \"%s\" beležnico"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "Beležnica s tem naslovom že obstaja: \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "Beležnica ne more biti imenovana \"%s\", ker je to rezerviran naslov."
|
||||
@@ -1284,6 +1320,9 @@ msgstr "Pokaži ikono v območju za obvestila(opravilna vrstica)"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Celokupen procent povečave"
|
||||
|
||||
@@ -1354,6 +1393,13 @@ msgstr ""
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud uporabniško ime"
|
||||
|
||||
@@ -1386,6 +1432,10 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Neveljavna vrednost: \"%s\". Možne vrednosti so : %s."
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Joplin izvozna datoteka"
|
||||
|
||||
@@ -1500,6 +1550,10 @@ msgstr "Premakni %d zabeležk v beležnico \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Klikni za nastavitev dekripcijskega gesla."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Nastavi alarm"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Save alarm"
|
||||
msgstr "Nastavi alarm"
|
||||
@@ -1517,6 +1571,36 @@ msgstr "Prekliči sinhronizacijo"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Preneseni predmeti: %d/%d."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "V preklicu...Prosim počakajte."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Preveri nastavitve sinhronizacije"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "Aplikacija je bila uspešno avtorizirana."
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Preneseni predmeti: %d/%d."
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr ""
|
||||
|
||||
@@ -1643,5 +1727,8 @@ msgstr "Trenutno nimate nobene beležnice. Ustvarite jo s klikom na (+) gumb."
|
||||
msgid "Welcome"
|
||||
msgstr "Dobrodošli"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "Beležnica s tem naslovom že obstaja: \"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "Iskalni niz"
|
||||
|
1750
CliClient/locales/sv.po
Normal file
1750
CliClient/locales/sv.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,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.8\n"
|
||||
"X-Generator: Poedit 2.1.1\n"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "移除相关笔记的标签后才可删除此标签。"
|
||||
@@ -247,7 +247,7 @@ msgstr "按 ESC 键退出命令行模式"
|
||||
|
||||
msgid ""
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr "输入 `help keymap` 来获取完整的键盘快捷键列表。"
|
||||
msgstr "输入 `help keymap` 来获取完整的键盘快捷键列表"
|
||||
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr "导入数据至 Jolin。"
|
||||
@@ -434,10 +434,11 @@ msgstr "开始同步..."
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "正在取消... 请稍后。"
|
||||
|
||||
#, 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 "
|
||||
"`tag list` can be used to list all the tags."
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> 可以是 \"add\", \"remove\" 或者 \"list\" 从 [note] 中分配或删"
|
||||
"除 [tag],或者列出与 [tag] 相关的笔记。`tag list` 命令将列出所有的标签。"
|
||||
@@ -465,7 +466,7 @@ msgid ""
|
||||
msgstr "切换至 [notebook] - 所有进一步处理将在此笔记本中进行。"
|
||||
|
||||
msgid "Displays version information"
|
||||
msgstr "显示版本信息。"
|
||||
msgstr "显示版本信息"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%s %s (%s)"
|
||||
@@ -590,6 +591,10 @@ msgstr "剪切"
|
||||
msgid "Paste"
|
||||
msgstr "粘贴"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "选择日期"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr "粗体"
|
||||
|
||||
@@ -674,6 +679,9 @@ msgstr "是"
|
||||
msgid "No"
|
||||
msgstr "否"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr "网页剪辑服务已启用并设置为自动启动。"
|
||||
|
||||
@@ -683,7 +691,7 @@ msgstr "状态:从端口 %d 开始"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Status: %s"
|
||||
msgstr "状态:\"%s\"。"
|
||||
msgstr "状态:%s"
|
||||
|
||||
msgid "Disable Web Clipper Service"
|
||||
msgstr "禁用网页剪辑服务"
|
||||
@@ -719,6 +727,21 @@ msgstr "步骤二:安装扩展"
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr "为您的浏览器下载并安装相关的扩展:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "显示高级选项"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
|
||||
msgid "Check synchronisation configuration"
|
||||
msgstr "检查同步配置"
|
||||
|
||||
@@ -778,7 +801,7 @@ msgid "Updated"
|
||||
msgstr "更新日期"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码:"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Password OK"
|
||||
msgstr "密码可用"
|
||||
@@ -840,7 +863,7 @@ msgid "Rename notebook:"
|
||||
msgstr "重命名笔记本:"
|
||||
|
||||
msgid "Rename tag:"
|
||||
msgstr "重命名标签"
|
||||
msgstr "重命名标签:"
|
||||
|
||||
msgid "Set alarm:"
|
||||
msgstr "设置提醒:"
|
||||
@@ -867,15 +890,23 @@ msgid "Add or remove tags"
|
||||
msgstr "添加或删除标签"
|
||||
|
||||
msgid "Duplicate"
|
||||
msgstr ""
|
||||
msgstr "重复的"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "%s - Copy"
|
||||
msgstr "复制"
|
||||
msgstr "%s - 副本"
|
||||
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "在笔记和待办事项类型之间切换"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "在笔记和待办事项类型之间切换"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "在笔记和待办事项类型之间切换"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "复制 Markdown 链接"
|
||||
|
||||
@@ -892,6 +923,12 @@ msgid ""
|
||||
"There is currently no notebook. Create one by clicking on \"New notebook\"."
|
||||
msgstr "此处没有任何笔记本。点击\"新笔记本\"创建。"
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "打开…"
|
||||
|
||||
@@ -925,7 +962,7 @@ msgid "emphasized text"
|
||||
msgstr "强调文本"
|
||||
|
||||
msgid "List item"
|
||||
msgstr ""
|
||||
msgstr "项目列表"
|
||||
|
||||
msgid "Insert Hyperlink"
|
||||
msgstr "插入超链接"
|
||||
@@ -941,7 +978,10 @@ msgstr "设置提醒"
|
||||
|
||||
#, javascript-format
|
||||
msgid "In: %s"
|
||||
msgstr "In: %s"
|
||||
msgstr "在: %s"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
|
||||
msgid "Hyperlink"
|
||||
msgstr "超链接"
|
||||
@@ -965,11 +1005,10 @@ msgid "Horizontal Rule"
|
||||
msgstr "水平线"
|
||||
|
||||
msgid "Click to stop external editing"
|
||||
msgstr ""
|
||||
msgstr "点击以停止外部编辑"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Watching..."
|
||||
msgstr "正在取消..."
|
||||
msgstr "正在监控变化..."
|
||||
|
||||
msgid "to-do"
|
||||
msgstr "待办事项"
|
||||
@@ -988,10 +1027,10 @@ msgid "Clear"
|
||||
msgstr "清除"
|
||||
|
||||
msgid "OneDrive Login"
|
||||
msgstr "登陆 OneDrive"
|
||||
msgstr "登录 OneDrive"
|
||||
|
||||
msgid "Dropbox Login"
|
||||
msgstr "登陆 Dropbox"
|
||||
msgstr "登录 Dropbox"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "选项"
|
||||
@@ -1055,7 +1094,7 @@ msgstr "未知日志级别:%s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown level ID: %s"
|
||||
msgstr "未知 level ID:%s"
|
||||
msgstr "未知的级别 ID:%s"
|
||||
|
||||
msgid ""
|
||||
"Cannot refresh token: authentication data is missing. Starting the "
|
||||
@@ -1132,13 +1171,13 @@ msgstr "正在进行"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Synchronisation is already in progress. State: %s"
|
||||
msgstr "同步正在进行中。状态:\"%s\""
|
||||
msgstr "同步正在进行中。状态:%s"
|
||||
|
||||
msgid "Encrypted"
|
||||
msgstr "已加密"
|
||||
|
||||
msgid "Encrypted items cannot be modified"
|
||||
msgstr "无法修改加密项目。"
|
||||
msgstr "无法修改已加密项目"
|
||||
|
||||
msgid "Conflicts"
|
||||
msgstr "冲突文件"
|
||||
@@ -1146,10 +1185,6 @@ msgstr "冲突文件"
|
||||
msgid "Cannot move notebook to this location"
|
||||
msgstr "无法移动笔记本到该位置"
|
||||
|
||||
#, javascript-format
|
||||
msgid "A notebook with this title already exists: \"%s\""
|
||||
msgstr "以此标题命名的笔记本已存在:\"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
|
||||
msgstr "笔记本无法被命名为 \"%s\",此标题为保留标题。"
|
||||
@@ -1205,7 +1240,7 @@ msgid "Sort notes by"
|
||||
msgstr "排序笔记"
|
||||
|
||||
msgid "Reverse sort order"
|
||||
msgstr "反转排序顺序。"
|
||||
msgstr "反转排序顺序"
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "保存笔记时同时保存地理定位信息"
|
||||
@@ -1228,6 +1263,9 @@ msgstr "显示托盘图标"
|
||||
msgid "Note: Does not work in all desktop environments."
|
||||
msgstr "注意:在所有的桌面环境中都不能工作。"
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr "启动应用程序时在托盘中最小化"
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "全局缩放比例"
|
||||
|
||||
@@ -1249,25 +1287,25 @@ msgstr "同步间隔"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%d minutes"
|
||||
msgstr "%d分"
|
||||
msgstr "%d 分钟"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%d hour"
|
||||
msgstr "%d小时"
|
||||
msgstr "%d 小时"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%d hours"
|
||||
msgstr "%d小时"
|
||||
msgstr "%d 小时"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Text editor command"
|
||||
msgstr "文本编辑器"
|
||||
msgstr "文本编辑器命令"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The editor command (may include arguments) that will be used to open a note. "
|
||||
"If none is provided it will try to auto-detect the default editor."
|
||||
msgstr "此编辑器将会被用于打开笔记。若未提供将自动检测默认编辑器。"
|
||||
msgstr ""
|
||||
"此文本编辑器命令(可能包括参数)将会被用于打开笔记。若未提供将尝试自动检测默"
|
||||
"认编辑器。"
|
||||
|
||||
msgid "Show advanced options"
|
||||
msgstr "显示高级选项"
|
||||
@@ -1291,7 +1329,16 @@ msgid ""
|
||||
msgstr "文件系统同步启用时的同步目录。见 `sync.target`。"
|
||||
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV 链接"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Attention: If you change this location, make sure you copy all your content "
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
"注意:如果您更改此位置,请确保在同步之前将所有内容复制到该位置,否则将删除所"
|
||||
"有文件! 有关详细信息,请参阅常见问题解答(FAQ):%s"
|
||||
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud 用户名"
|
||||
@@ -1300,7 +1347,7 @@ msgid "Nextcloud password"
|
||||
msgstr "Nextcloud 密码"
|
||||
|
||||
msgid "WebDAV URL"
|
||||
msgstr "WebDAV URL"
|
||||
msgstr "WebDAV 链接"
|
||||
|
||||
msgid "WebDAV username"
|
||||
msgstr "WebDAV 用户名"
|
||||
@@ -1309,7 +1356,7 @@ msgid "WebDAV password"
|
||||
msgstr "WebDAV 密码"
|
||||
|
||||
msgid "Custom TLS certificates"
|
||||
msgstr ""
|
||||
msgstr "自定义 TLS 证书"
|
||||
|
||||
msgid ""
|
||||
"Comma-separated list of paths to directories to load the certificates from, "
|
||||
@@ -1317,22 +1364,29 @@ msgid ""
|
||||
"pem. Note that if you make changes to the TLS settings, you must save your "
|
||||
"changes before clicking on \"Check synchronisation configuration\"."
|
||||
msgstr ""
|
||||
"以逗号分隔的路径列表,可以是包含证书的目录,也可以是单独的证书路径。 例如:/"
|
||||
"my/cert_dir,/other/custom.pem。 请注意,如果更改 TLS 设置,则必须先保存更改,"
|
||||
"然后再点击『检查同步配置』。"
|
||||
|
||||
msgid "Ignore TLS certificate errors"
|
||||
msgstr ""
|
||||
msgstr "忽略 TLS 证书的错误"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "无效设置数值:\"%s\"。可用值为:%s。"
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr "标签“%s”已经存在。请选择一个不一样的名字。"
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Joplin 输出文件"
|
||||
msgstr "Joplin 导出文件"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr "Markdown"
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr "Joplin 输出文件目录"
|
||||
msgstr "Joplin 导出目录"
|
||||
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote 导出文件"
|
||||
@@ -1342,7 +1396,7 @@ msgstr "文件目录"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr "无法加载 \"%s\" 模块读取 \"%s\" 格式"
|
||||
msgstr "无法加载 \"%s\" 模块以读取 \"%s\" 格式"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
@@ -1361,7 +1415,7 @@ msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "请指定导入笔记的目标笔记本。"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "项目无法被同步。"
|
||||
msgstr "无法同步项目"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%s (%s): %s"
|
||||
@@ -1436,9 +1490,13 @@ msgstr "移动%d条笔记至笔记本\"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "按键将设置解密密码。"
|
||||
|
||||
msgid "Save alarm"
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "设置提醒"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "保存提醒"
|
||||
|
||||
msgid "Select date"
|
||||
msgstr "选择日期"
|
||||
|
||||
@@ -1452,6 +1510,36 @@ msgstr "取消同步"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "解密项目:%d/%d"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "正在取消... 请稍后。"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "检查同步配置"
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "此程序已被成功授权。"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Could not authorise application:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "解密项目:%d/%d"
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "新标签:"
|
||||
|
||||
@@ -1462,8 +1550,8 @@ msgid ""
|
||||
"To work correctly, the app needs the following permissions. Please enable "
|
||||
"them in your phone settings, in Apps > Joplin > Permissions"
|
||||
msgstr ""
|
||||
"为了正确地工作,应用需要以下权限。请在你的手机设置(应用 > Joplin > 权限)中"
|
||||
"启用它们。"
|
||||
"为了正常的使用,应用需要以下权限。请在你的手机设置(应用 > Joplin > 权限)中"
|
||||
"启用它们"
|
||||
|
||||
msgid ""
|
||||
"- Storage: to allow attaching files to notes and to enable filesystem "
|
||||
@@ -1480,7 +1568,7 @@ msgid "Joplin website"
|
||||
msgstr "Joplin 官网"
|
||||
|
||||
msgid "Login with Dropbox"
|
||||
msgstr "通过 Dropbox 登陆"
|
||||
msgstr "通过 Dropbox 登录"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Master Key %s"
|
||||
@@ -1561,7 +1649,7 @@ msgid "Delete notebook"
|
||||
msgstr "删除笔记本"
|
||||
|
||||
msgid "Login with OneDrive"
|
||||
msgstr "通过 OneDrive 登陆"
|
||||
msgstr "通过 OneDrive 登录"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "搜索"
|
||||
@@ -1577,5 +1665,8 @@ msgstr "您目前未有笔记本。点击(+)按钮创建。"
|
||||
msgid "Welcome"
|
||||
msgstr "欢迎"
|
||||
|
||||
#~ msgid "A notebook with this title already exists: \"%s\""
|
||||
#~ msgstr "以此标题命名的笔记本已存在:\"%s\""
|
||||
|
||||
#~ msgid "Searches"
|
||||
#~ msgstr "搜索历史"
|
||||
|
File diff suppressed because it is too large
Load Diff
1203
CliClient/package-lock.json
generated
1203
CliClient/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "1.0.112",
|
||||
"version": "1.0.116",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
@@ -37,12 +37,14 @@
|
||||
"fs-extra": "^5.0.0",
|
||||
"html-entities": "^1.2.1",
|
||||
"html-minifier": "^3.5.15",
|
||||
"image-data-uri": "^2.0.0",
|
||||
"image-type": "^3.0.0",
|
||||
"joplin-turndown": "^4.0.8",
|
||||
"joplin-turndown": "^4.0.9",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.7",
|
||||
"jssha": "^2.3.0",
|
||||
"levenshtein": "^1.0.5",
|
||||
"lodash": "^4.17.4",
|
||||
"markdown-it": "^8.4.2",
|
||||
"md5": "^2.2.1",
|
||||
"mime": "^2.0.3",
|
||||
"moment": "^2.18.1",
|
||||
@@ -56,7 +58,7 @@
|
||||
"redux": "^3.7.2",
|
||||
"sax": "^1.2.2",
|
||||
"server-destroy": "^1.0.1",
|
||||
"sharp": "^0.18.4",
|
||||
"sharp": "^0.20.8",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"sqlite3": "^4.0.1",
|
||||
"string-padding": "^1.0.2",
|
||||
@@ -66,6 +68,7 @@
|
||||
"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",
|
||||
|
@@ -22,14 +22,16 @@ trap finish EXIT
|
||||
|
||||
cd "$ROOT_DIR"
|
||||
npm test tests-build/ArrayUtils.js
|
||||
npm test tests-build/encryption.js
|
||||
npm test tests-build/EnexToMd.js
|
||||
npm test tests-build/HtmlToMd.js
|
||||
npm test tests-build/markdownUtils.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/services_InteropService.js
|
||||
npm test tests-build/services_ResourceService.js
|
||||
npm test tests-build/synchronizer.js
|
||||
npm test tests-build/urlUtils.js
|
||||
npm test tests-build/urlUtils.js
|
||||
npm test tests-build/encryption.js
|
||||
npm test tests-build/services_rest_Api.js
|
||||
npm test tests-build/synchronizer.js
|
@@ -36,7 +36,7 @@ describe('HtmlToMd', function() {
|
||||
const htmlPath = basePath + '/' + htmlFilename;
|
||||
const mdPath = basePath + '/' + filename(htmlFilename) + '.md';
|
||||
|
||||
// if (htmlFilename !== 'code_1.html') continue;
|
||||
// if (htmlFilename !== 'anchor_with_url_with_spaces.html') continue;
|
||||
|
||||
const html = await shim.fsDriver().readFile(htmlPath);
|
||||
const expectedMd = await shim.fsDriver().readFile(mdPath);
|
||||
|
5
CliClient/tests/enex_to_md/list4.html
Normal file
5
CliClient/tests/enex_to_md/list4.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<ul>
|
||||
<li><div>This note has an unordered list</div></li>
|
||||
<li><div>List item</div></li>
|
||||
<li><div>List item</div></li>
|
||||
</ul>
|
3
CliClient/tests/enex_to_md/list4.md
Normal file
3
CliClient/tests/enex_to_md/list4.md
Normal file
@@ -0,0 +1,3 @@
|
||||
- This note has an unordered list
|
||||
- List item
|
||||
- List item
|
@@ -0,0 +1 @@
|
||||
<a href="http://example.com/That is not right"/>Testing</a>
|
@@ -0,0 +1 @@
|
||||
[Testing](http://example.com/That%20is%20not%20right)
|
29
CliClient/tests/html_to_md/picture_with_no_img.html
Normal file
29
CliClient/tests/html_to_md/picture_with_no_img.html
Normal file
@@ -0,0 +1,29 @@
|
||||
Some pictures:
|
||||
|
||||
<picture>
|
||||
<!--[if IE 9]><video style="display: none;"><![endif]-->
|
||||
<source media="(min-width: 768px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w">
|
||||
<source media="(min-width: 768px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w">
|
||||
<source media="(min-width: 481px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w">
|
||||
<source media="(min-width: 481px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w">
|
||||
<source media="(min-width: 321px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop&dpr=1.5 675w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop&dpr=1.5 675w">
|
||||
<source media="(min-width: 321px)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop 450w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop 450w">
|
||||
<source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop&dpr=1.5 480w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop&dpr=1.5 480w">
|
||||
<source media="(min-width: 0px)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop 320w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop 320w">
|
||||
<!--[if IE 9]></video><![endif]-->
|
||||
<img class=" lazyloaded" title="" alt="" id="img-id-0">
|
||||
</picture>
|
||||
|
||||
<picture>
|
||||
<!--[if IE 9]><video style="display: none;"><![endif]-->
|
||||
<source media="(min-width: 768px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w">
|
||||
<source media="(min-width: 768px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w">
|
||||
<source media="(min-width: 481px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5 882w">
|
||||
<source media="(min-width: 481px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop 588w">
|
||||
<source media="(min-width: 321px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop&dpr=1.5 675w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop&dpr=1.5 675w">
|
||||
<source media="(min-width: 321px)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop 450w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=450&h=688&fit=crop 450w">
|
||||
<source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop&dpr=1.5 480w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop&dpr=1.5 480w">
|
||||
<source media="(min-width: 0px)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop 320w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=320&h=489&fit=crop 320w">
|
||||
<!--[if IE 9]></video><![endif]-->
|
||||
<img class=" lazyloaded" title="" alt="" id="img-id-0" src="http://example.com/test.gif">
|
||||
</picture>
|
1
CliClient/tests/html_to_md/picture_with_no_img.md
Normal file
1
CliClient/tests/html_to_md/picture_with_no_img.md
Normal file
@@ -0,0 +1 @@
|
||||
Some pictures:  
|
@@ -39,6 +39,7 @@ describe('markdownUtils', function() {
|
||||
['', ['http://test.com/img.png']],
|
||||
[' ', ['http://test.com/img.png', 'http://test.com/img2.png']],
|
||||
['', ['http://test.com/img.png']],
|
||||
['.png)', ['https://test.com/ohoh_(123).png']],
|
||||
];
|
||||
|
||||
for (let i = 0; i < testCases.length; i++) {
|
||||
|
@@ -34,6 +34,33 @@ describe('models_Note', function() {
|
||||
expect(items.length).toBe(2);
|
||||
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 + '\' />';
|
||||
items = await Note.linkedItems(note2.body);
|
||||
expect(items.length).toBe(4);
|
||||
}));
|
||||
|
||||
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 });
|
||||
note1 = await Note.load(note1.id);
|
||||
|
||||
let changedNote = Note.changeNoteType(note1, 'todo');
|
||||
expect(changedNote === note1).toBe(false);
|
||||
expect(!!changedNote.is_todo).toBe(true);
|
||||
await Note.save(changedNote);
|
||||
|
||||
note1 = await Note.load(note1.id);
|
||||
changedNote = Note.changeNoteType(note1, 'todo');
|
||||
expect(changedNote === note1).toBe(true);
|
||||
expect(!!changedNote.is_todo).toBe(true);
|
||||
|
||||
note1 = await Note.load(note1.id);
|
||||
changedNote = Note.changeNoteType(note1, 'note');
|
||||
expect(changedNote === note1).toBe(false);
|
||||
expect(!!changedNote.is_todo).toBe(false);
|
||||
}));
|
||||
|
||||
});
|
31
CliClient/tests/models_Resource.js
Normal file
31
CliClient/tests/models_Resource.js
Normal file
@@ -0,0 +1,31 @@
|
||||
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];
|
||||
console.info(resource1);
|
||||
}));
|
||||
|
||||
});
|
45
CliClient/tests/models_Tag.js
Normal file
45
CliClient/tests/models_Tag.js
Normal file
@@ -0,0 +1,45 @@
|
||||
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 Tag = require('lib/models/Tag.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_Tag', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should add tags by title', asyncTest(async () => {
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
await Tag.setNoteTagsByTitles(note1.id, ['un', 'deux']);
|
||||
|
||||
const noteTags = await Tag.tagsByNoteId(note1.id);
|
||||
expect(noteTags.length).toBe(2);
|
||||
}));
|
||||
|
||||
it('should not allow renaming tag to existing tag names', asyncTest(async () => {
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
await Tag.setNoteTagsByTitles(note1.id, ['un', 'deux']);
|
||||
|
||||
const tagUn = await Tag.loadByTitle('un');
|
||||
const hasThrown = await checkThrowAsync(async () => await Tag.save({ id: tagUn.id, title: 'deux' }, { userSideValidation: true }));
|
||||
|
||||
expect(hasThrown).toBe(true);
|
||||
}));
|
||||
|
||||
});
|
@@ -79,7 +79,6 @@ describe('services_ResourceService', function() {
|
||||
let note2 = await Note.save({ title: 'ma deuxième note', parent_id: folder1.id });
|
||||
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
|
||||
let resource1 = (await Resource.all())[0];
|
||||
const resourcePath = Resource.fullPath(resource1);
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
@@ -106,4 +105,23 @@ describe('services_ResourceService', function() {
|
||||
expect((await Resource.all()).length).toBe(1);
|
||||
}));
|
||||
|
||||
it('should not delete resource if it is used in an IMG tag', 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();
|
||||
|
||||
await Note.save({ id: note1.id, body: 'This is HTML: <img src=":/' + resource1.id + '"/>' });
|
||||
|
||||
await service.indexNoteResources();
|
||||
|
||||
await service.deleteOrphanResources(0);
|
||||
|
||||
expect(!!(await Resource.load(resource1.id))).toBe(true);
|
||||
}));
|
||||
|
||||
});
|
275
CliClient/tests/services_rest_Api.js
Normal file
275
CliClient/tests/services_rest_Api.js
Normal file
@@ -0,0 +1,275 @@
|
||||
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 markdownUtils = require('lib/markdownUtils.js');
|
||||
const Api = require('lib/services/rest/Api');
|
||||
const Folder = require('lib/models/Folder');
|
||||
const Note = require('lib/models/Note');
|
||||
const Tag = require('lib/models/Tag');
|
||||
const Resource = require('lib/models/Resource');
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
let api = null;
|
||||
|
||||
describe('services_rest_Api', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
api = new Api();
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should ping', async (done) => {
|
||||
const response = await api.route('GET', 'ping');
|
||||
expect(response).toBe('JoplinClipperServer');
|
||||
done();
|
||||
});
|
||||
|
||||
it('should handle Not Found errors', async (done) => {
|
||||
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'pong'));
|
||||
expect(hasThrown).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should get folders', async (done) => {
|
||||
let f1 = await Folder.save({ title: "mon carnet" });
|
||||
const response = await api.route('GET', 'folders');
|
||||
expect(response.length).toBe(1);
|
||||
expect(response[0].title).toBe('mon carnet');
|
||||
done();
|
||||
});
|
||||
|
||||
it('should update folders', async (done) => {
|
||||
let f1 = await Folder.save({ title: "mon carnet" });
|
||||
const response = await api.route('PUT', 'folders/' + f1.id, null, JSON.stringify({
|
||||
title: 'modifié',
|
||||
}));
|
||||
|
||||
let f1b = await Folder.load(f1.id);
|
||||
expect(f1b.title).toBe('modifié');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should delete folders', async (done) => {
|
||||
let f1 = await Folder.save({ title: "mon carnet" });
|
||||
await api.route('DELETE', 'folders/' + f1.id);
|
||||
|
||||
let f1b = await Folder.load(f1.id);
|
||||
expect(!f1b).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create folders', async (done) => {
|
||||
const response = await api.route('POST', 'folders', null, JSON.stringify({
|
||||
title: 'from api',
|
||||
}));
|
||||
|
||||
expect(!!response.id).toBe(true);
|
||||
|
||||
let f = await Folder.all();
|
||||
expect(f.length).toBe(1);
|
||||
expect(f[0].title).toBe('from api');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should get one folder', async (done) => {
|
||||
let f1 = await Folder.save({ title: "mon carnet" });
|
||||
const response = await api.route('GET', 'folders/' + f1.id);
|
||||
expect(response.id).toBe(f1.id);
|
||||
|
||||
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'folders/doesntexist'));
|
||||
expect(hasThrown).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should get the folder notes', async (done) => {
|
||||
let f1 = await Folder.save({ title: "mon carnet" });
|
||||
const response2 = await api.route('GET', 'folders/' + f1.id + '/notes');
|
||||
expect(response2.length).toBe(0);
|
||||
|
||||
const n1 = await Note.save({ title: 'un', parent_id: f1.id });
|
||||
const n2 = await Note.save({ title: 'deux', parent_id: f1.id });
|
||||
const response = await api.route('GET', 'folders/' + f1.id + '/notes');
|
||||
expect(response.length).toBe(2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should fail on invalid paths', async (done) => {
|
||||
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'schtroumpf'));
|
||||
expect(hasThrown).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should get notes', async (done) => {
|
||||
let response = null;
|
||||
const f1 = await Folder.save({ title: "mon carnet" });
|
||||
const f2 = await Folder.save({ title: "mon deuxième carnet" });
|
||||
const n1 = await Note.save({ title: 'un', parent_id: f1.id });
|
||||
const n2 = await Note.save({ title: 'deux', parent_id: f1.id });
|
||||
const n3 = await Note.save({ title: 'trois', parent_id: f2.id });
|
||||
|
||||
response = await api.route('GET', 'notes');
|
||||
expect(response.length).toBe(3);
|
||||
|
||||
response = await api.route('GET', 'notes/' + n1.id);
|
||||
expect(response.id).toBe(n1.id);
|
||||
|
||||
response = await api.route('GET', 'notes/' + n3.id, { fields: 'id,title' });
|
||||
expect(Object.getOwnPropertyNames(response).length).toBe(3);
|
||||
expect(response.id).toBe(n3.id);
|
||||
expect(response.title).toBe('trois');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create notes', async (done) => {
|
||||
let response = null;
|
||||
const f = await Folder.save({ title: "mon carnet" });
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing',
|
||||
parent_id: f.id,
|
||||
}));
|
||||
expect(response.title).toBe('testing');
|
||||
expect(!!response.id).toBe(true);
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing',
|
||||
parent_id: f.id,
|
||||
}));
|
||||
expect(response.title).toBe('testing');
|
||||
expect(!!response.id).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create notes with images', async (done) => {
|
||||
let response = null;
|
||||
const f = await Folder.save({ title: "mon carnet" });
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing image',
|
||||
parent_id: f.id,
|
||||
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="
|
||||
}));
|
||||
|
||||
const resources = await Resource.all();
|
||||
expect(resources.length).toBe(1);
|
||||
|
||||
const resource = resources[0];
|
||||
expect(response.body.indexOf(resource.id) >= 0).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create notes from HTML', async (done) => {
|
||||
let response = null;
|
||||
const f = await Folder.save({ title: "mon carnet" });
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing HTML',
|
||||
parent_id: f.id,
|
||||
body_html: '<b>Bold text</b>',
|
||||
}));
|
||||
|
||||
expect(response.body).toBe('**Bold text**');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should filter fields', async (done) => {
|
||||
let f = api.fields_({ query: { fields: 'one,two' } }, []);
|
||||
expect(f.length).toBe(2);
|
||||
expect(f[0]).toBe('one');
|
||||
expect(f[1]).toBe('two');
|
||||
|
||||
f = api.fields_({ query: { fields: 'one ,, two ' } }, []);
|
||||
expect(f.length).toBe(2);
|
||||
expect(f[0]).toBe('one');
|
||||
expect(f[1]).toBe('two');
|
||||
|
||||
f = api.fields_({ query: { fields: ' ' } }, ['def']);
|
||||
expect(f.length).toBe(1);
|
||||
expect(f[0]).toBe('def');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should handle tokens', async (done) => {
|
||||
api = new Api('mytoken');
|
||||
|
||||
let hasThrown = await checkThrowAsync(async () => await api.route('GET', 'notes'));
|
||||
expect(hasThrown).toBe(true);
|
||||
|
||||
const response = await api.route('GET', 'notes', { token: 'mytoken' })
|
||||
expect(response.length).toBe(0);
|
||||
|
||||
hasThrown = await checkThrowAsync(async () => await api.route('POST', 'notes', null, JSON.stringify({title:'testing'})));
|
||||
expect(hasThrown).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should add tags to notes', async (done) => {
|
||||
const tag = await Tag.save({ title: "mon étiquette" });
|
||||
const note = await Note.save({ title: "ma note" });
|
||||
|
||||
const response = await api.route('POST', 'tags/' + tag.id + '/notes', null, JSON.stringify({
|
||||
id: note.id,
|
||||
}));
|
||||
|
||||
const noteIds = await Tag.noteIds(tag.id);
|
||||
expect(noteIds[0]).toBe(note.id);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should remove tags from notes', async (done) => {
|
||||
const tag = await Tag.save({ title: "mon étiquette" });
|
||||
const note = await Note.save({ title: "ma note" });
|
||||
await Tag.addNote(tag.id, note.id);
|
||||
|
||||
const response = await api.route('DELETE', 'tags/' + tag.id + '/notes/' + note.id);
|
||||
|
||||
const noteIds = await Tag.noteIds(tag.id);
|
||||
expect(noteIds.length).toBe(0);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should list all tag notes', async (done) => {
|
||||
const tag = await Tag.save({ title: "mon étiquette" });
|
||||
const tag2 = await Tag.save({ title: "mon étiquette 2" });
|
||||
const note1 = await Note.save({ title: "ma note un" });
|
||||
const note2 = await Note.save({ title: "ma note deux" });
|
||||
await Tag.addNote(tag.id, note1.id);
|
||||
await Tag.addNote(tag.id, note2.id);
|
||||
|
||||
const response = await api.route('GET', 'tags/' + tag.id + '/notes');
|
||||
expect(response.length).toBe(2);
|
||||
expect('id' in response[0]).toBe(true);
|
||||
expect('title' in response[0]).toBe(true);
|
||||
|
||||
const response2 = await api.route('GET', 'notes/' + note1.id + '/tags');
|
||||
expect(response2.length).toBe(1);
|
||||
await Tag.addNote(tag2.id, note1.id);
|
||||
const response3 = await api.route('GET', 'notes/' + note1.id + '/tags');
|
||||
expect(response3.length).toBe(2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
@@ -7,6 +7,7 @@ const fs = require('fs-extra');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const { Database } = require('lib/database.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
@@ -872,12 +873,46 @@ describe('Synchronizer', function() {
|
||||
let allResources = await Resource.all();
|
||||
expect(allResources.length).toBe(1);
|
||||
let resource1_2 = allResources[0];
|
||||
let resourcePath1_2 = Resource.fullPath(resource1_2);
|
||||
|
||||
expect(resource1_2.id).toBe(resource1.id);
|
||||
expect(resource1_2.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);
|
||||
|
||||
let resourcePath1_2 = Resource.fullPath(resource1_2);
|
||||
expect(fileContentEqual(resourcePath1, resourcePath1_2)).toBe(true);
|
||||
}));
|
||||
|
||||
it('should handle resource download errors', asyncTest(async () => {
|
||||
while (insideBeforeEach) await time.msleep(500);
|
||||
|
||||
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 resourcePath1 = Resource.fullPath(resource1);
|
||||
await synchronizer().start();
|
||||
|
||||
await switchClient(2);
|
||||
|
||||
await synchronizer().start();
|
||||
|
||||
const fetcher = new ResourceFetcher(() => { return {
|
||||
// Simulate a failed download
|
||||
get: () => { return new Promise((resolve, reject) => { reject(new Error('did not work')) }); }
|
||||
} });
|
||||
fetcher.queueDownload(resource1.id);
|
||||
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');
|
||||
}));
|
||||
|
||||
it('should delete resources', asyncTest(async () => {
|
||||
while (insideBeforeEach) await time.msleep(500);
|
||||
|
||||
@@ -926,6 +961,10 @@ describe('Synchronizer', function() {
|
||||
Setting.setObjectKey('encryption.passwordCache', masterKey.id, '123456');
|
||||
await encryptionService().loadMasterKeysFromSettings();
|
||||
|
||||
const fetcher = new ResourceFetcher(() => { return synchronizer().api() });
|
||||
fetcher.queueDownload(resource1.id);
|
||||
await fetcher.waitForAllFinished();
|
||||
|
||||
let resource1_2 = (await Resource.all())[0];
|
||||
resource1_2 = await Resource.decrypt(resource1_2);
|
||||
let resourcePath1_2 = Resource.fullPath(resource1_2);
|
||||
|
@@ -48,7 +48,9 @@ EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
|
||||
const logDir = __dirname + '/../tests/logs';
|
||||
const tempDir = __dirname + '/../tests/tmp';
|
||||
fs.mkdirpSync(logDir, 0o755);
|
||||
fs.mkdirpSync(tempDir, 0o755);
|
||||
|
||||
SyncTargetRegistry.addClass(SyncTargetMemory);
|
||||
SyncTargetRegistry.addClass(SyncTargetFilesystem);
|
||||
@@ -80,6 +82,7 @@ BaseItem.loadClass('MasterKey', MasterKey);
|
||||
|
||||
Setting.setConstant('appId', 'net.cozic.joplin-cli');
|
||||
Setting.setConstant('appType', 'cli');
|
||||
Setting.setConstant('tempDir', tempDir);
|
||||
|
||||
BaseService.logger_ = logger;
|
||||
|
||||
|
0
CliClientDemo/publish.sh
Normal file → Executable file
0
CliClientDemo/publish.sh
Normal file → Executable file
@@ -80,8 +80,9 @@
|
||||
title: title,
|
||||
html: html,
|
||||
base_url: baseUrl(),
|
||||
url: location.origin + location.pathname,
|
||||
url: location.origin + location.pathname + location.search,
|
||||
parent_id: command.parent_id,
|
||||
tags: command.tags || '',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -137,6 +138,7 @@
|
||||
messageComp.style.maxWidth = messageCompWidth + 'px'
|
||||
messageComp.style.border = '1px solid black'
|
||||
messageComp.style.background = 'white'
|
||||
messageComp.style.color = 'black';
|
||||
messageComp.style.top = '10px'
|
||||
messageComp.style.textAlign = 'center';
|
||||
messageComp.style.padding = '10px'
|
||||
@@ -214,6 +216,7 @@
|
||||
crop_rect: selectionArea,
|
||||
url: location.origin + location.pathname,
|
||||
parent_id: command.parent_id,
|
||||
tags: command.tags,
|
||||
};
|
||||
|
||||
browser_.runtime.sendMessage({
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Joplin Web Clipper [DEV]",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.7",
|
||||
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
||||
"homepage_url": "https://joplin.cozic.net",
|
||||
"icons": {
|
||||
|
@@ -1,5 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!-- NOTE: I think this is not used at all -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
@@ -100,21 +100,34 @@
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.App .Folders {
|
||||
.App .Folders,
|
||||
.App .Tags {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
align-items: top;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.App .Folders label {
|
||||
.App .Folders label,
|
||||
.App .Tags label {
|
||||
flex: 0;
|
||||
white-space: nowrap;
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
.App .Folders select {
|
||||
flex: 1;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.App .Tags input {
|
||||
display: inline-block;
|
||||
flex: 1;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.App .ClearTagButton {
|
||||
margin-left: .5em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.App .StatusBar {
|
||||
|
@@ -14,6 +14,7 @@ class AppComponent extends Component {
|
||||
|
||||
this.state = ({
|
||||
contentScriptLoaded: false,
|
||||
selectedTags: [],
|
||||
});
|
||||
|
||||
this.confirm_click = () => {
|
||||
@@ -31,6 +32,7 @@ class AppComponent extends Component {
|
||||
bridge().sendCommandToActiveTab({
|
||||
name: 'simplifiedPageHtml',
|
||||
parent_id: this.props.selectedFolderId,
|
||||
tags: this.state.selectedTags.join(','),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,6 +40,7 @@ class AppComponent extends Component {
|
||||
bridge().sendCommandToActiveTab({
|
||||
name: 'completePageHtml',
|
||||
parent_id: this.props.selectedFolderId,
|
||||
tags: this.state.selectedTags.join(','),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,6 +48,7 @@ class AppComponent extends Component {
|
||||
bridge().sendCommandToActiveTab({
|
||||
name: 'selectedHtml',
|
||||
parent_id: this.props.selectedFolderId,
|
||||
tags: this.state.selectedTags.join(','),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,6 +60,7 @@ class AppComponent extends Component {
|
||||
name: 'screenshot',
|
||||
api_base_url: baseUrl,
|
||||
parent_id: this.props.selectedFolderId,
|
||||
tags: this.state.selectedTags.join(','),
|
||||
});
|
||||
|
||||
window.close();
|
||||
@@ -74,6 +79,41 @@ class AppComponent extends Component {
|
||||
id: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
this.tagCompChanged = this.tagCompChanged.bind(this);
|
||||
this.onAddTagClick = this.onAddTagClick.bind(this);
|
||||
this.onClearTagButtonClick = this.onClearTagButtonClick.bind(this);
|
||||
}
|
||||
|
||||
onAddTagClick(event) {
|
||||
const newTags = this.state.selectedTags.slice();
|
||||
newTags.push('');
|
||||
this.setState({ selectedTags: newTags });
|
||||
this.focusNewTagInput_ = true;
|
||||
}
|
||||
|
||||
onClearTagButtonClick(event) {
|
||||
const index = event.target.getAttribute('data-index');
|
||||
const newTags = this.state.selectedTags.slice();
|
||||
newTags.splice(index, 1);
|
||||
this.setState({ selectedTags: newTags });
|
||||
}
|
||||
|
||||
tagCompChanged(event) {
|
||||
const index = Number(event.target.getAttribute('data-index'));
|
||||
const value = event.target.value;
|
||||
|
||||
if (this.state.selectedTags.length <= index) {
|
||||
const newTags = this.state.selectedTags.slice();
|
||||
newTags.push(value);
|
||||
this.setState({ selectedTags: newTags });
|
||||
} else {
|
||||
if (this.state.selectedTags[index] !== value) {
|
||||
const newTags = this.state.selectedTags.slice();
|
||||
newTags[index] = value;
|
||||
this.setState({ selectedTags: newTags });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async loadContentScripts() {
|
||||
@@ -87,6 +127,39 @@ class AppComponent extends Component {
|
||||
this.setState({
|
||||
contentScriptLoaded: true,
|
||||
});
|
||||
|
||||
let foundSelectedFolderId = false;
|
||||
|
||||
const searchSelectedFolder = (folders) => {
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
const folder = folders[i];
|
||||
if (folder.id === this.props.selectedFolderId) foundSelectedFolderId = true;
|
||||
if (folder.children) searchSelectedFolder(folder.children);
|
||||
}
|
||||
}
|
||||
|
||||
searchSelectedFolder(this.props.folders);
|
||||
|
||||
if (!foundSelectedFolderId) {
|
||||
const newFolderId = this.props.folders.length ? this.props.folders[0].id : null;
|
||||
this.props.dispatch({
|
||||
type: 'SELECTED_FOLDER_SET',
|
||||
id: newFolderId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.focusNewTagInput_) {
|
||||
this.focusNewTagInput_ = false;
|
||||
let lastRef = null;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const ref = this.refs['tagSelector' + i];
|
||||
if (!ref) break;
|
||||
lastRef = ref;
|
||||
}
|
||||
if (lastRef) lastRef.focus();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -119,24 +192,17 @@ class AppComponent extends Component {
|
||||
<p className="Info">{ msg }</p>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if (hasContent) {
|
||||
previewComponent = (
|
||||
<div className="Preview">
|
||||
<input className={"Title"} value={content.title} onChange={this.contentTitle_change}/>
|
||||
<div className={"BodyWrapper"}>
|
||||
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.body_html}}></div>
|
||||
</div>
|
||||
<a className={"Confirm Button"} onClick={this.confirm_click}>Confirm</a>
|
||||
} else if (hasContent) {
|
||||
previewComponent = (
|
||||
<div className="Preview">
|
||||
<h2>Preview:</h2>
|
||||
<input className={"Title"} value={content.title} onChange={this.contentTitle_change}/>
|
||||
<div className={"BodyWrapper"}>
|
||||
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.body_html}}></div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
previewComponent = (
|
||||
<div className="Preview">
|
||||
<p className="Info">(No preview yet)</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<a className={"Confirm Button"} onClick={this.confirm_click}>Confirm</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const clipperStatusComp = () => {
|
||||
@@ -166,8 +232,6 @@ class AppComponent extends Component {
|
||||
return <div className="StatusBar"><img alt={foundState} className="Led" src={led}/><span className="ServerStatus">{ msg }{ helpLink }</span></div>
|
||||
}
|
||||
|
||||
console.info(this.props.selectedFolderId);
|
||||
|
||||
const foldersComp = () => {
|
||||
const optionComps = [];
|
||||
|
||||
@@ -196,6 +260,37 @@ class AppComponent extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
const tagsComp = () => {
|
||||
const comps = [];
|
||||
for (let i = 0; i < this.state.selectedTags.length; i++) {
|
||||
comps.push(<div>
|
||||
<input
|
||||
ref={'tagSelector' + i}
|
||||
data-index={i}
|
||||
key={i}
|
||||
type="text"
|
||||
list="tags"
|
||||
value={this.state.selectedTags[i]}
|
||||
onChange={this.tagCompChanged}
|
||||
onInput={this.tagCompChanged}
|
||||
/>
|
||||
<a data-index={i} href="#" className="ClearTagButton" onClick={this.onClearTagButtonClick}>[x]</a>
|
||||
</div>);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{comps}
|
||||
<a className="AddTagButton" href="#" onClick={this.onAddTagClick}>Add tag</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const tagDataListOptions = [];
|
||||
for (let i = 0; i < this.props.tags.length; i++) {
|
||||
const tag = this.props.tags[i];
|
||||
tagDataListOptions.push(<option key={tag.id}>{tag.title}</option>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="Controls">
|
||||
@@ -207,8 +302,14 @@ class AppComponent extends Component {
|
||||
</ul>
|
||||
</div>
|
||||
{ foldersComp() }
|
||||
<div className="Tags">
|
||||
<label>Tags:</label>
|
||||
{tagsComp()}
|
||||
<datalist id="tags">
|
||||
{tagDataListOptions}
|
||||
</datalist>
|
||||
</div>
|
||||
{ warningComponent }
|
||||
<h2>Preview:</h2>
|
||||
{ previewComponent }
|
||||
{ clipperStatusComp() }
|
||||
</div>
|
||||
@@ -224,6 +325,7 @@ const mapStateToProps = (state) => {
|
||||
contentUploadOperation: state.contentUploadOperation,
|
||||
clipperServer: state.clipperServer,
|
||||
folders: state.folders,
|
||||
tags: state.tags,
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
};
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@ const randomClipperPort = require('./randomClipperPort');
|
||||
|
||||
class Bridge {
|
||||
|
||||
init(browser, browserSupportsPromises, dispatch) {
|
||||
async init(browser, browserSupportsPromises, dispatch) {
|
||||
console.info('Popup: Init bridge');
|
||||
|
||||
this.browser_ = browser;
|
||||
@@ -28,6 +28,7 @@ class Bridge {
|
||||
base_url: command.base_url,
|
||||
source_url: command.url,
|
||||
parent_id: command.parent_id,
|
||||
tags: command.tags || '',
|
||||
};
|
||||
|
||||
this.dispatch({ type: 'CLIPPED_CONTENT_SET', content: content });
|
||||
@@ -36,7 +37,7 @@ class Bridge {
|
||||
|
||||
this.browser_.runtime.onMessage.addListener(this.browser_notify);
|
||||
|
||||
const backgroundPage = this.browser_.extension.getBackgroundPage();
|
||||
const backgroundPage = await this.backgroundPage(this.browser_);
|
||||
|
||||
// Not sure why the getBackgroundPage() sometimes returns null, so
|
||||
// in that case default to "prod" environment, which means the live
|
||||
@@ -53,6 +54,17 @@ class Bridge {
|
||||
this.findClipperServerPort();
|
||||
}
|
||||
|
||||
async backgroundPage(browser) {
|
||||
const bgp = browser.extension.getBackgroundPage();
|
||||
if (bgp) return bgp;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
browser.runtime.getBackgroundPage((bgp) => {
|
||||
resolve(bgp);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
env() {
|
||||
return this.env_;
|
||||
}
|
||||
@@ -111,6 +123,11 @@ class Bridge {
|
||||
|
||||
const folders = await this.folderTree();
|
||||
this.dispatch({ type: 'FOLDERS_SET', folders: folders });
|
||||
|
||||
const tags = await this.clipperApiExec('GET', 'tags');
|
||||
this.dispatch({ type: 'TAGS_SET', tags: tags });
|
||||
|
||||
bridge().restoreState();
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
|
@@ -16,6 +16,7 @@ const defaultState = {
|
||||
port: null,
|
||||
},
|
||||
folders: [],
|
||||
tags: [],
|
||||
selectedFolderId: null,
|
||||
env: 'prod',
|
||||
};
|
||||
@@ -65,6 +66,11 @@ function reducer(state = defaultState, action) {
|
||||
newState.selectedFolderId = action.folders[0].id;
|
||||
}
|
||||
|
||||
} else if (action.type === 'TAGS_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.tags = action.tags;
|
||||
|
||||
} else if (action.type === 'SELECTED_FOLDER_SET') {
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
@@ -88,11 +94,18 @@ function reducer(state = defaultState, action) {
|
||||
return newState;
|
||||
}
|
||||
|
||||
const store = createStore(reducer, applyMiddleware(reduxMiddleware));
|
||||
async function main() {
|
||||
const store = createStore(reducer, applyMiddleware(reduxMiddleware));
|
||||
|
||||
bridge().init(window.browser ? window.browser : window.chrome, !!window.browser, store.dispatch);
|
||||
bridge().restoreState();
|
||||
console.info('Popup: Init bridge and restore state...');
|
||||
|
||||
console.info('Popup: Creating React app...');
|
||||
await bridge().init(window.browser ? window.browser : window.chrome, !!window.browser, store.dispatch);
|
||||
|
||||
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
|
||||
console.info('Popup: Creating React app...');
|
||||
|
||||
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Fatal error on initialisation:', error);
|
||||
});
|
@@ -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;
|
@@ -62,7 +62,9 @@ class ElectronAppWrapper {
|
||||
|
||||
require('electron-context-menu')({
|
||||
shouldShowMenu: (event, params) => {
|
||||
return params.isEditable;
|
||||
// params.inputFieldType === 'none' when right-clicking the text editor. This is a bit of a hack to detect it because in this
|
||||
// case we don't want to use the built-in context menu but a custom one.
|
||||
return params.isEditable && params.inputFieldType !== 'none';
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -11,7 +11,7 @@ class InteropServiceHelper {
|
||||
|
||||
if (module.target === 'file') {
|
||||
path = bridge().showSaveDialog({
|
||||
filters: [{ name: module.description, extensions: module.fileExtension}]
|
||||
filters: [{ name: module.description, extensions: module.fileExtensions}]
|
||||
});
|
||||
} else {
|
||||
path = bridge().showOpenDialog({
|
||||
|
@@ -49,7 +49,6 @@ class Application extends BaseApplication {
|
||||
constructor() {
|
||||
super();
|
||||
this.lastMenuScreen_ = null;
|
||||
this.powerSaveBlockerId_ = null;
|
||||
}
|
||||
|
||||
hasGui() {
|
||||
@@ -166,8 +165,10 @@ class Application extends BaseApplication {
|
||||
|
||||
case 'NOTE_FILE_WATCHER_CLEAR':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.watchedNoteFiles = [];
|
||||
if (state.watchedNoteFiles.length) {
|
||||
newState = Object.assign({}, state);
|
||||
newState.watchedNoteFiles = [];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -219,17 +220,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;
|
||||
}
|
||||
|
||||
@@ -418,6 +408,10 @@ class Application extends BaseApplication {
|
||||
label: _('Paste'),
|
||||
role: 'paste',
|
||||
accelerator: 'CommandOrControl+V',
|
||||
}, {
|
||||
label: _('Select all'),
|
||||
role: 'selectall',
|
||||
accelerator: 'CommandOrControl+A',
|
||||
}, {
|
||||
type: 'separator',
|
||||
screens: ['Main'],
|
||||
@@ -735,8 +729,6 @@ class Application extends BaseApplication {
|
||||
ids: Setting.value('collapsedFolderIds'),
|
||||
});
|
||||
|
||||
if (shim.isLinux()) bridge().setAllowPowerSaveBlockerToggle(true);
|
||||
|
||||
// Note: Auto-update currently doesn't work in Linux: it downloads the update
|
||||
// but then doesn't install it on exit.
|
||||
if (shim.isWindows() || shim.isMac()) {
|
||||
@@ -758,6 +750,10 @@ class Application extends BaseApplication {
|
||||
AlarmService.garbageCollect();
|
||||
}, 1000 * 60 * 60);
|
||||
|
||||
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
|
||||
bridge().window().hide();
|
||||
}
|
||||
|
||||
ResourceService.runInBackground();
|
||||
|
||||
if (Setting.value('env') === 'dev') {
|
||||
|
@@ -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;
|
||||
|
File diff suppressed because one or more lines are too long
@@ -35,6 +35,7 @@ class HeaderComponent extends React.Component {
|
||||
this.search_onClear = (event) => {
|
||||
this.setState({ searchQuery: '' });
|
||||
triggerOnQuery('');
|
||||
if (this.searchElement_) this.searchElement_.focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ const { SideBar } = require('./SideBar.min.js');
|
||||
const { NoteList } = require('./NoteList.min.js');
|
||||
const { NoteText } = require('./NoteText.min.js');
|
||||
const { PromptDialog } = require('./PromptDialog.min.js');
|
||||
const NotePropertiesDialog = require('./NotePropertiesDialog.min.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
@@ -19,13 +20,24 @@ const eventManager = require('../eventManager');
|
||||
|
||||
class MainScreenComponent extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.notePropertiesDialog_close = this.notePropertiesDialog_close.bind(this);
|
||||
}
|
||||
|
||||
notePropertiesDialog_close() {
|
||||
this.setState({ notePropertiesDialogOptions: {} });
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({
|
||||
promptOptions: null,
|
||||
modalLayer: {
|
||||
visible: false,
|
||||
message: '',
|
||||
}
|
||||
},
|
||||
notePropertiesDialogOptions: {},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -189,6 +201,13 @@ class MainScreenComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
} else if (command.name === 'commandNoteProperties') {
|
||||
this.setState({
|
||||
notePropertiesDialogOptions: {
|
||||
noteId: command.noteId,
|
||||
visible: true,
|
||||
},
|
||||
});
|
||||
} else if (command.name === 'toggleVisiblePanes') {
|
||||
this.toggleVisiblePanes();
|
||||
} else if (command.name === 'toggleSidebar') {
|
||||
@@ -412,10 +431,19 @@ class MainScreenComponent extends React.Component {
|
||||
|
||||
const modalLayerStyle = Object.assign({}, styles.modalLayer, { display: this.state.modalLayer.visible ? 'block' : 'none' });
|
||||
|
||||
const notePropertiesDialogOptions = this.state.notePropertiesDialogOptions;
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<div style={modalLayerStyle}>{this.state.modalLayer.message}</div>
|
||||
|
||||
<NotePropertiesDialog
|
||||
theme={this.props.theme}
|
||||
noteId={notePropertiesDialogOptions.noteId}
|
||||
visible={!!notePropertiesDialogOptions.visible}
|
||||
onClose={this.notePropertiesDialog_close}
|
||||
/>
|
||||
|
||||
<PromptDialog
|
||||
autocomplete={promptOptions && ('autocomplete' in promptOptions) ? promptOptions.autocomplete : null}
|
||||
defaultValue={promptOptions && promptOptions.value ? promptOptions.value : ''}
|
||||
@@ -427,6 +455,7 @@ class MainScreenComponent extends React.Component {
|
||||
visible={!!this.state.promptOptions}
|
||||
buttons={promptOptions && ('buttons' in promptOptions) ? promptOptions.buttons : null}
|
||||
inputType={promptOptions && ('inputType' in promptOptions) ? promptOptions.inputType : null} />
|
||||
|
||||
<Header style={styles.header} showBackButton={false} items={headerItems} />
|
||||
{messageComp}
|
||||
<SideBar style={styles.sideBar} />
|
||||
|
@@ -97,13 +97,33 @@ class NoteListComponent extends React.Component {
|
||||
}
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({label: _('Switch between note and to-do type'), click: async () => {
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
const note = await Note.load(noteIds[i]);
|
||||
await Note.save(Note.toggleIsTodo(note), { userSideValidation: true });
|
||||
eventManager.emit('noteTypeToggle', { noteId: note.id });
|
||||
if (noteIds.length <= 1) {
|
||||
menu.append(new MenuItem({label: _('Switch between note and to-do type'), click: async () => {
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
const note = await Note.load(noteIds[i]);
|
||||
await Note.save(Note.toggleIsTodo(note), { userSideValidation: true });
|
||||
eventManager.emit('noteTypeToggle', { noteId: note.id });
|
||||
}
|
||||
}}));
|
||||
} else {
|
||||
const switchNoteType = async (noteIds, type) => {
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
const note = await Note.load(noteIds[i]);
|
||||
const newNote = Note.changeNoteType(note, type);
|
||||
if (newNote === note) continue;
|
||||
await Note.save(newNote, { userSideValidation: true });
|
||||
eventManager.emit('noteTypeToggle', { noteId: note.id });
|
||||
}
|
||||
}
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({label: _('Switch to note type'), click: async () => {
|
||||
await switchNoteType(noteIds, 'note');
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({label: _('Switch to to-do type'), click: async () => {
|
||||
await switchNoteType(noteIds, 'todo');
|
||||
}}));
|
||||
}
|
||||
|
||||
menu.append(new MenuItem({label: _('Copy Markdown link'), click: async () => {
|
||||
const { clipboard } = require('electron');
|
||||
|
364
ElectronClient/app/gui/NotePropertiesDialog.jsx
Normal file
364
ElectronClient/app/gui/NotePropertiesDialog.jsx
Normal file
@@ -0,0 +1,364 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const moment = require('moment');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const Datetime = require('react-datetime');
|
||||
const Note = require('lib/models/Note');
|
||||
const formatcoords = require('formatcoords');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
|
||||
class NotePropertiesDialog extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.okButton_click = this.okButton_click.bind(this);
|
||||
this.cancelButton_click = this.cancelButton_click.bind(this);
|
||||
|
||||
this.state = {
|
||||
formNote: null,
|
||||
editedKey: null,
|
||||
editedValue: null,
|
||||
visible: false,
|
||||
};
|
||||
|
||||
this.keyToLabel_ = {
|
||||
id: _('ID'),
|
||||
user_created_time: _('Created'),
|
||||
user_updated_time: _('Updated'),
|
||||
location: _('Location'),
|
||||
source_url: _('URL'),
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if ('visible' in newProps && newProps.visible !== this.state.visible) {
|
||||
this.setState({ visible: newProps.visible });
|
||||
}
|
||||
|
||||
if ('noteId' in newProps) {
|
||||
this.loadNote(newProps.noteId);
|
||||
}
|
||||
}
|
||||
|
||||
async loadNote(noteId) {
|
||||
if (!noteId) {
|
||||
this.setState({ formNote: null });
|
||||
} else {
|
||||
const note = await Note.load(noteId);
|
||||
const formNote = this.noteToFormNote(note);
|
||||
this.setState({ formNote: formNote });
|
||||
}
|
||||
}
|
||||
|
||||
latLongFromLocation(location) {
|
||||
const o = {};
|
||||
const l = location.split(',');
|
||||
if (l.length == 2) {
|
||||
o.latitude = l[0].trim();
|
||||
o.longitude = l[1].trim();
|
||||
} else {
|
||||
o.latitude = '';
|
||||
o.longitude = '';
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
noteToFormNote(note) {
|
||||
const formNote = {};
|
||||
|
||||
formNote.user_updated_time = time.formatMsToLocal(note.user_updated_time);
|
||||
formNote.user_created_time = time.formatMsToLocal(note.user_created_time);
|
||||
formNote.source_url = note.source_url;
|
||||
|
||||
formNote.location = '';
|
||||
if (Number(note.latitude) || Number(note.longitude)) {
|
||||
formNote.location = note.latitude + ', ' + note.longitude;
|
||||
}
|
||||
|
||||
formNote.id = note.id;
|
||||
|
||||
return formNote;
|
||||
}
|
||||
|
||||
formNoteToNote(formNote) {
|
||||
const note = Object.assign({ id: formNote.id }, this.latLongFromLocation(formNote.location));
|
||||
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
|
||||
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
|
||||
note.source_url = formNote.source_url;
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
styles(themeId) {
|
||||
const styleKey = themeId;
|
||||
if (styleKey === this.styleKey_) return this.styles_;
|
||||
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
this.styles_ = {};
|
||||
this.styleKey_ = styleKey;
|
||||
|
||||
this.styles_.modalLayer = {
|
||||
zIndex: 9999,
|
||||
display: 'flex',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: 'rgba(0,0,0,0.6)',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'center',
|
||||
};
|
||||
|
||||
this.styles_.dialogBox = {
|
||||
backgroundColor: 'white',
|
||||
padding: 16,
|
||||
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
|
||||
marginTop: 20,
|
||||
}
|
||||
|
||||
this.styles_.controlBox = {
|
||||
marginBottom: '1em',
|
||||
};
|
||||
|
||||
this.styles_.button = {
|
||||
minWidth: theme.buttonMinWidth,
|
||||
minHeight: theme.buttonMinHeight,
|
||||
marginLeft: 5,
|
||||
};
|
||||
|
||||
this.styles_.editPropertyButton = {
|
||||
color: theme.color,
|
||||
textDecoration: 'none',
|
||||
};
|
||||
|
||||
this.styles_.dialogTitle = Object.assign({}, theme.h1Style, { marginBottom: '1.2em' });
|
||||
|
||||
return this.styles_;
|
||||
}
|
||||
|
||||
async closeDialog(applyChanges) {
|
||||
if (applyChanges) {
|
||||
await this.saveProperty();
|
||||
const note = this.formNoteToNote(this.state.formNote);
|
||||
note.updated_time = Date.now();
|
||||
await Note.save(note, { autoTimestamp: false });
|
||||
} else {
|
||||
await this.cancelProperty();
|
||||
}
|
||||
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
|
||||
if (this.props.onClose) {
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
okButton_click() {
|
||||
this.closeDialog(true);
|
||||
}
|
||||
|
||||
cancelButton_click() {
|
||||
this.closeDialog(false);
|
||||
}
|
||||
|
||||
editPropertyButtonClick(key, initialValue) {
|
||||
this.setState({
|
||||
editedKey: key,
|
||||
editedValue: initialValue,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
if (this.refs.editField.openCalendar) {
|
||||
this.refs.editField.openCalendar();
|
||||
} else {
|
||||
this.refs.editField.focus();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
async saveProperty() {
|
||||
if (!this.state.editedKey) return;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const newFormNote = Object.assign({}, this.state.formNote);
|
||||
|
||||
if (this.state.editedKey.indexOf('_time') >= 0) {
|
||||
const dt = time.anythingToDateTime(this.state.editedValue, new Date());
|
||||
newFormNote[this.state.editedKey] = time.formatMsToLocal(dt.getTime());
|
||||
} else {
|
||||
newFormNote[this.state.editedKey] = this.state.editedValue;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
formNote: newFormNote,
|
||||
editedKey: null,
|
||||
editedValue: null
|
||||
}, () => { resolve() });
|
||||
});
|
||||
}
|
||||
|
||||
async cancelProperty() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.setState({
|
||||
editedKey: null,
|
||||
editedValue: null
|
||||
}, () => { resolve() });
|
||||
});
|
||||
}
|
||||
|
||||
createNoteField(key, value) {
|
||||
const styles = this.styles(this.props.theme);
|
||||
const theme = themeStyle(this.props.theme);
|
||||
const labelComp = <label style={Object.assign({}, theme.textStyle, {marginRight: '1em', width: '6em', display:'inline-block', fontWeight: 'bold'})}>{this.formatLabel(key)}</label>;
|
||||
let controlComp = null;
|
||||
let editComp = null;
|
||||
let editCompHandler = null;
|
||||
let editCompIcon = null;
|
||||
|
||||
const onKeyDown = (event) => {
|
||||
if (event.keyCode === 13) {
|
||||
this.saveProperty();
|
||||
} else if (event.keyCode === 27) {
|
||||
this.cancelProperty();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state.editedKey === key) {
|
||||
if (key.indexOf('_time') >= 0) {
|
||||
|
||||
controlComp = <Datetime
|
||||
ref="editField"
|
||||
defaultValue={value}
|
||||
dateFormat={time.dateFormat()}
|
||||
timeFormat={time.timeFormat()}
|
||||
inputProps={{
|
||||
onKeyDown: (event) => onKeyDown(event, key)
|
||||
}}
|
||||
onChange={(momentObject) => {this.setState({ editedValue: momentObject })}}
|
||||
/>
|
||||
|
||||
editCompHandler = () => {this.saveProperty()};
|
||||
editCompIcon = 'fa-save';
|
||||
} else {
|
||||
|
||||
controlComp = <input
|
||||
defaultValue={value}
|
||||
type="text"
|
||||
ref="editField"
|
||||
onChange={(event) => {this.setState({ editedValue: event.target.value })}}
|
||||
onKeyDown={(event) => onKeyDown(event)}
|
||||
style={{display:'inline-block'}}
|
||||
/>
|
||||
}
|
||||
} else {
|
||||
let displayedValue = value;
|
||||
|
||||
if (key === 'location') {
|
||||
try {
|
||||
const dms = formatcoords(value);
|
||||
displayedValue = dms.format('DDMMss', { decimalPlaces: 0 });
|
||||
} catch (error) {
|
||||
displayedValue = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (['source_url', 'location'].indexOf(key) >= 0) {
|
||||
let url = '';
|
||||
if (key === 'source_url') url = value;
|
||||
if (key === 'location') {
|
||||
const ll = this.latLongFromLocation(value);
|
||||
url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude);
|
||||
}
|
||||
controlComp = <a href="#" onClick={() => bridge().openExternal(url)} style={theme.urlStyle}>{displayedValue}</a>
|
||||
} else {
|
||||
controlComp = <div style={Object.assign({}, theme.textStyle, {display: 'inline-block'})}>{displayedValue}</div>
|
||||
}
|
||||
|
||||
if (key !== 'id') {
|
||||
editCompHandler = () => {this.editPropertyButtonClick(key, value)};
|
||||
editCompIcon = 'fa-edit';
|
||||
}
|
||||
}
|
||||
|
||||
if (editCompHandler) {
|
||||
editComp = (
|
||||
<a href="#" onClick={editCompHandler} style={styles.editPropertyButton}>
|
||||
<i className={'fa ' + editCompIcon} aria-hidden="true" style={{ marginLeft: '.5em'}}></i>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={key} style={this.styles_.controlBox} className="note-property-box">
|
||||
{ labelComp }
|
||||
{ controlComp }
|
||||
{ editComp }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
formatLabel(key) {
|
||||
if (this.keyToLabel_[key]) return this.keyToLabel_[key];
|
||||
return key;
|
||||
}
|
||||
|
||||
formatValue(key, note) {
|
||||
if (key === 'location') {
|
||||
if (!Number(note.latitude) && !Number(note.longitude)) return null;
|
||||
const dms = formatcoords(Number(note.latitude), Number(note.longitude))
|
||||
return dms.format('DDMMss', { decimalPlaces: 0 });
|
||||
}
|
||||
|
||||
if (['user_updated_time', 'user_created_time'].indexOf(key) >= 0) {
|
||||
return time.formatMsToLocal(note[key]);
|
||||
}
|
||||
|
||||
return note[key];
|
||||
}
|
||||
|
||||
render() {
|
||||
const style = this.props.style;
|
||||
const theme = themeStyle(this.props.theme);
|
||||
const styles = this.styles(this.props.theme);
|
||||
const formNote = this.state.formNote;
|
||||
|
||||
const buttonComps = [];
|
||||
buttonComps.push(<button key="ok" style={styles.button} onClick={this.okButton_click}>{_('Apply')}</button>);
|
||||
buttonComps.push(<button key="cancel" style={styles.button} onClick={this.cancelButton_click}>{_('Cancel')}</button>);
|
||||
|
||||
const noteComps = [];
|
||||
|
||||
const modalLayerStyle = Object.assign({}, styles.modalLayer);
|
||||
if (!this.state.visible) modalLayerStyle.display = 'none';
|
||||
|
||||
if (formNote) {
|
||||
for (let key in formNote) {
|
||||
if (!formNote.hasOwnProperty(key)) continue;
|
||||
const comp = this.createNoteField(key, formNote[key]);
|
||||
noteComps.push(comp);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={modalLayerStyle}>
|
||||
<div style={styles.dialogBox}>
|
||||
<div style={styles.dialogTitle}>Note properties</div>
|
||||
<div>{noteComps}</div>
|
||||
<div style={{ textAlign: 'right', marginTop: 10 }}>
|
||||
{buttonComps}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = NotePropertiesDialog;
|
@@ -6,6 +6,7 @@ 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 Toolbar = require('./Toolbar.min.js');
|
||||
const { connect } = require('react-redux');
|
||||
const { _ } = require('lib/locale.js');
|
||||
@@ -27,6 +28,7 @@ const urlUtils = require('lib/urlUtils');
|
||||
const dialogs = require('./dialogs');
|
||||
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');
|
||||
|
||||
@@ -87,13 +89,14 @@ class NoteTextComponent extends React.Component {
|
||||
this.onNoteTypeToggle_ = (event) => { if (event.noteId === this.props.noteId) this.reloadNote(this.props); }
|
||||
this.onTodoToggle_ = (event) => { if (event.noteId === this.props.noteId) this.reloadNote(this.props); }
|
||||
|
||||
this.onEditorPaste_ = async (event) => {
|
||||
this.onEditorPaste_ = async (event = null) => {
|
||||
const formats = clipboard.availableFormats();
|
||||
for (let i = 0; i < formats.length; i++) {
|
||||
const format = formats[i].toLowerCase();
|
||||
const formatType = format.split('/')[0]
|
||||
|
||||
if (formatType === 'image') {
|
||||
event.preventDefault();
|
||||
if (event) event.preventDefault();
|
||||
|
||||
const image = clipboard.readImage();
|
||||
|
||||
@@ -114,8 +117,47 @@ class NoteTextComponent extends React.Component {
|
||||
this.setState({ lastKeys: lastKeys });
|
||||
}
|
||||
|
||||
this.onEditorContextMenu_ = (event) => {
|
||||
const menu = new Menu();
|
||||
|
||||
const selectedText = this.selectedText();
|
||||
const clipboardText = clipboard.readText();
|
||||
|
||||
menu.append(new MenuItem({label: _('Cut'), enabled: !!selectedText, click: async () => {
|
||||
this.editorCutText();
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({label: _('Copy'), enabled: !!selectedText, click: async () => {
|
||||
this.editorCopyText();
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({label: _('Paste'), enabled: true, click: async () => {
|
||||
if (clipboardText) {
|
||||
this.editorPasteText();
|
||||
} else {
|
||||
// To handle pasting images
|
||||
this.onEditorPaste_();
|
||||
}
|
||||
}}));
|
||||
|
||||
menu.popup(bridge().window());
|
||||
}
|
||||
|
||||
this.onDrop_ = async (event) => {
|
||||
const files = event.dataTransfer.files;
|
||||
const dt = event.dataTransfer;
|
||||
|
||||
if (dt.types.indexOf("text/x-jop-note-ids") >= 0) {
|
||||
const noteIds = JSON.parse(dt.getData("text/x-jop-note-ids"));
|
||||
const linkText = [];
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
const note = await Note.load(noteIds[i]);
|
||||
linkText.push(Note.markdownTag(note));
|
||||
}
|
||||
|
||||
this.wrapSelectionWithStrings("", "", '', linkText.join('\n'));
|
||||
}
|
||||
|
||||
const files = dt.files;
|
||||
if (!files || !files.length) return;
|
||||
|
||||
const filesToAttach = [];
|
||||
@@ -130,6 +172,10 @@ class NoteTextComponent extends React.Component {
|
||||
}
|
||||
|
||||
const updateSelectionRange = () => {
|
||||
if (!this.rawEditor()) {
|
||||
this.selectionRange_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const ranges = this.rawEditor().getSelection().getAllRanges();
|
||||
if (!ranges || !ranges.length || !this.state.note) {
|
||||
@@ -153,6 +199,16 @@ class NoteTextComponent extends React.Component {
|
||||
this.reloadNote(this.props);
|
||||
}
|
||||
}
|
||||
|
||||
this.resourceFetcher_downloadComplete = async (resource) => {
|
||||
if (!this.state.note || !this.state.note.body) return;
|
||||
const resourceIds = await Note.linkedResourceIds(this.state.note.body);
|
||||
if (resourceIds.indexOf(resource.id) >= 0) {
|
||||
this.mdToHtml().clearCache();
|
||||
this.lastSetHtml_ = '';
|
||||
this.updateHtml(this.state.note.body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note:
|
||||
@@ -242,6 +298,8 @@ class NoteTextComponent extends React.Component {
|
||||
eventManager.on('alarmChange', this.onAlarmChange_);
|
||||
eventManager.on('noteTypeToggle', this.onNoteTypeToggle_);
|
||||
eventManager.on('todoToggle', this.onTodoToggle_);
|
||||
|
||||
ResourceFetcher.instance().on('downloadComplete', this.resourceFetcher_downloadComplete);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -254,6 +312,8 @@ class NoteTextComponent extends React.Component {
|
||||
eventManager.removeListener('noteTypeToggle', this.onNoteTypeToggle_);
|
||||
eventManager.removeListener('todoToggle', this.onTodoToggle_);
|
||||
|
||||
ResourceFetcher.instance().off('downloadComplete', this.resourceFetcher_downloadComplete);
|
||||
|
||||
this.destroyExternalEditWatcher();
|
||||
}
|
||||
|
||||
@@ -342,9 +402,8 @@ class NoteTextComponent extends React.Component {
|
||||
this.editorSetScrollTop(1);
|
||||
this.restoreScrollTop_ = 0;
|
||||
|
||||
// If a search is in progress we don't focus any field otherwise it will
|
||||
// take the focus out of the search box.
|
||||
if (note && this.props.notesParentType !== 'Search') {
|
||||
// Only force focus on notes when creating a new note/todo
|
||||
if (this.props.newNote) {
|
||||
const focusSettingName = !!note.is_todo ? 'newTodoFocus' : 'newNoteFocus';
|
||||
|
||||
if (Setting.value(focusSettingName) === 'title') {
|
||||
@@ -467,8 +526,6 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
const menu = new Menu()
|
||||
|
||||
console.info(itemType);
|
||||
|
||||
if (itemType === "image" || itemType === "resource") {
|
||||
const resource = await Resource.load(arg0.resourceId);
|
||||
const resourcePath = Resource.fullPath(resource);
|
||||
@@ -510,6 +567,10 @@ 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) {
|
||||
bridge().showErrorMessageBox(_('This attachment is not downloaded or not decrypted yet.'));
|
||||
return;
|
||||
}
|
||||
const filePath = Resource.fullPath(item);
|
||||
bridge().openItem(filePath);
|
||||
} else if (item.type_ === BaseModel.TYPE_NOTE) {
|
||||
@@ -528,7 +589,14 @@ class NoteTextComponent extends React.Component {
|
||||
throw new Error('Unsupported item type: ' + item.type_);
|
||||
}
|
||||
} else if (urlUtils.urlProtocol(msg)) {
|
||||
require('electron').shell.openExternal(msg);
|
||||
if (msg.indexOf('file://') === 0) {
|
||||
// When using the file:// protocol, openExternal doesn't work (does nothing) with URL-encoded paths
|
||||
require('electron').shell.openExternal(urlDecode(msg));
|
||||
} 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));
|
||||
}
|
||||
@@ -595,6 +663,7 @@ class NoteTextComponent extends React.Component {
|
||||
this.editor_.editor.renderer.off('afterRender', this.onAfterEditorRender_);
|
||||
document.querySelector('#note-editor').removeEventListener('paste', this.onEditorPaste_, true);
|
||||
document.querySelector('#note-editor').removeEventListener('keydown', this.onEditorKeyDown_);
|
||||
document.querySelector('#note-editor').removeEventListener('contextmenu', this.onEditorContextMenu_);
|
||||
}
|
||||
|
||||
this.editor_ = element;
|
||||
@@ -623,6 +692,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
document.querySelector('#note-editor').addEventListener('paste', this.onEditorPaste_, true);
|
||||
document.querySelector('#note-editor').addEventListener('keydown', this.onEditorKeyDown_);
|
||||
document.querySelector('#note-editor').addEventListener('contextmenu', this.onEditorContextMenu_);
|
||||
|
||||
const lineLeftSpaces = function(line) {
|
||||
let output = '';
|
||||
@@ -722,7 +792,7 @@ class NoteTextComponent extends React.Component {
|
||||
this.forceUpdate();
|
||||
}, 100);
|
||||
},
|
||||
postMessageSyntax: 'ipcRenderer.sendToHost',
|
||||
postMessageSyntax: 'ipcProxySendToHost',
|
||||
};
|
||||
|
||||
const theme = themeStyle(this.props.theme);
|
||||
@@ -895,6 +965,49 @@ class NoteTextComponent extends React.Component {
|
||||
return lines[row];
|
||||
}
|
||||
|
||||
selectedText() {
|
||||
if (!this.state.note || !this.state.note.body) return '';
|
||||
|
||||
const selection = this.textOffsetSelection();
|
||||
if (!selection || selection.start === selection.end) return '';
|
||||
|
||||
return this.state.note.body.substr(selection.start, selection.end - selection.start);
|
||||
}
|
||||
|
||||
editorCopyText() {
|
||||
clipboard.writeText(this.selectedText());
|
||||
}
|
||||
|
||||
editorCutText() {
|
||||
const selectedText = this.selectedText();
|
||||
if (!selectedText) return;
|
||||
|
||||
clipboard.writeText(selectedText);
|
||||
|
||||
const s = this.textOffsetSelection();
|
||||
if (!s || s.start === s.end) return '';
|
||||
|
||||
const s1 = this.state.note.body.substr(0, s.start);
|
||||
const s2 = this.state.note.body.substr(s.end);
|
||||
|
||||
shared.noteComponent_change(this, 'body', s1 + s2);
|
||||
|
||||
this.updateEditorWithDelay((editor) => {
|
||||
const range = this.selectionRange_;
|
||||
range.setStart(range.start.row, range.start.column);
|
||||
range.setEnd(range.start.row, range.start.column);
|
||||
editor.getSession().getSelection().setSelectionRange(range, false);
|
||||
editor.focus();
|
||||
}, 10);
|
||||
}
|
||||
|
||||
editorPasteText() {
|
||||
const s = this.textOffsetSelection();
|
||||
const s1 = this.state.note.body.substr(0, s.start);
|
||||
const s2 = this.state.note.body.substr(s.end);
|
||||
this.wrapSelectionWithStrings("", "", '', clipboard.readText());
|
||||
}
|
||||
|
||||
selectionRangePreviousLine() {
|
||||
if (!this.selectionRange_) return '';
|
||||
const row = this.selectionRange_.start.row;
|
||||
@@ -907,16 +1020,20 @@ class NoteTextComponent extends React.Component {
|
||||
return this.lineAtRow(row);
|
||||
}
|
||||
|
||||
wrapSelectionWithStrings(string1, string2 = '', defaultText = '') {
|
||||
textOffsetSelection() {
|
||||
return this.selectionRange_ ? this.rangeToTextOffsets(this.selectionRange_, this.state.note.body) : null;
|
||||
}
|
||||
|
||||
wrapSelectionWithStrings(string1, string2 = '', defaultText = '', replacementText = '') {
|
||||
if (!this.rawEditor() || !this.state.note) return;
|
||||
|
||||
const selection = this.selectionRange_ ? this.rangeToTextOffsets(this.selectionRange_, this.state.note.body) : null;
|
||||
const selection = this.textOffsetSelection();
|
||||
|
||||
let newBody = this.state.note.body;
|
||||
|
||||
if (selection && selection.start !== selection.end) {
|
||||
const s1 = this.state.note.body.substr(0, selection.start);
|
||||
const s2 = this.state.note.body.substr(selection.start, selection.end - selection.start);
|
||||
const s2 = replacementText ? replacementText : this.state.note.body.substr(selection.start, selection.end - selection.start);
|
||||
const s3 = this.state.note.body.substr(selection.end);
|
||||
newBody = s1 + string1 + s2 + string2 + s3;
|
||||
|
||||
@@ -927,6 +1044,11 @@ class NoteTextComponent extends React.Component {
|
||||
end: { row: r.end.row, column: r.end.column + string1.length},
|
||||
};
|
||||
|
||||
if (replacementText) {
|
||||
const diff = replacementText.length - (selection.end - selection.start);
|
||||
newRange.end.column += diff;
|
||||
}
|
||||
|
||||
this.updateEditorWithDelay((editor) => {
|
||||
const range = this.selectionRange_;
|
||||
range.setStart(newRange.start.row, newRange.start.column);
|
||||
@@ -935,19 +1057,23 @@ class NoteTextComponent extends React.Component {
|
||||
editor.focus();
|
||||
});
|
||||
} else {
|
||||
let middleText = replacementText ? replacementText : defaultText;
|
||||
const textOffset = this.currentTextOffset();
|
||||
const s1 = this.state.note.body.substr(0, textOffset);
|
||||
const s2 = this.state.note.body.substr(textOffset);
|
||||
newBody = s1 + string1 + defaultText + string2 + s2;
|
||||
newBody = s1 + string1 + middleText + string2 + s2;
|
||||
|
||||
const p = this.textOffsetToCursorPosition(textOffset + string1.length, newBody);
|
||||
const newRange = {
|
||||
start: { row: p.row, column: p.column },
|
||||
end: { row: p.row, column: p.column + defaultText.length },
|
||||
end: { row: p.row, column: p.column + middleText.length },
|
||||
};
|
||||
|
||||
// BUG!! If replacementText contains newline characters, the logic
|
||||
// to select the new text will not work.
|
||||
|
||||
this.updateEditorWithDelay((editor) => {
|
||||
if (defaultText && newRange) {
|
||||
if (middleText && newRange) {
|
||||
const range = this.selectionRange_;
|
||||
range.setStart(newRange.start.row, newRange.start.column);
|
||||
range.setEnd(newRange.end.row, newRange.end.column);
|
||||
@@ -1066,6 +1192,25 @@ class NoteTextComponent extends React.Component {
|
||||
type: 'separator',
|
||||
});
|
||||
|
||||
toolbarItems.push({
|
||||
tooltip: _('Note properties'),
|
||||
iconName: 'fa-info-circle',
|
||||
onClick: () => {
|
||||
const n = this.state.note;
|
||||
if (!n || !n.id) return;
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'commandNoteProperties',
|
||||
noteId: n.id,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
toolbarItems.push({
|
||||
type: 'separator',
|
||||
});
|
||||
|
||||
toolbarItems.push({
|
||||
tooltip: _('Hyperlink'),
|
||||
iconName: 'fa-link',
|
||||
@@ -1252,7 +1397,11 @@ class NoteTextComponent extends React.Component {
|
||||
}
|
||||
|
||||
if (visiblePanes.indexOf('editor') < 0) {
|
||||
editorStyle.display = 'none';
|
||||
// Note: Ideally we'd set the display to "none" to take the editor out
|
||||
// of the DOM but if we do that, certain things won't work, in particular
|
||||
// things related to scroll, which are based on the editor. See
|
||||
// editorScrollTop_, restoreScrollTop_, etc.
|
||||
editorStyle.width = 0;
|
||||
viewerStyle.width = innerWidth;
|
||||
}
|
||||
|
||||
@@ -1306,6 +1455,7 @@ class NoteTextComponent extends React.Component {
|
||||
style={viewerStyle}
|
||||
preload="gui/note-viewer/preload.js"
|
||||
src="gui/note-viewer/index.html"
|
||||
webpreferences="contextIsolation"
|
||||
ref={(elem) => { this.webview_ref(elem); } }
|
||||
/>
|
||||
|
||||
|
@@ -102,7 +102,8 @@ class PromptDialog extends React.Component {
|
||||
if (this.props.onClose) {
|
||||
let outputAnswer = this.state.answer;
|
||||
if (this.props.inputType === 'datetime') {
|
||||
outputAnswer = anythingToDate(outputAnswer);
|
||||
// outputAnswer = anythingToDate(outputAnswer);
|
||||
outputAnswer = time.anythingToDateTime(outputAnswer);
|
||||
}
|
||||
this.props.onClose(accept ? outputAnswer : null, buttonType);
|
||||
}
|
||||
@@ -113,14 +114,14 @@ class PromptDialog extends React.Component {
|
||||
this.setState({ answer: event.target.value });
|
||||
}
|
||||
|
||||
const anythingToDate = (o) => {
|
||||
if (o && o.toDate) return o.toDate();
|
||||
if (!o) return null;
|
||||
let m = moment(o, time.dateTimeFormat());
|
||||
if (m.isValid()) return m.toDate();
|
||||
m = moment(o, time.dateFormat());
|
||||
return m.isValid() ? m.toDate() : null;
|
||||
}
|
||||
// const anythingToDate = (o) => {
|
||||
// if (o && o.toDate) return o.toDate();
|
||||
// if (!o) return null;
|
||||
// let m = moment(o, time.dateTimeFormat());
|
||||
// if (m.isValid()) return m.toDate();
|
||||
// m = moment(o, time.dateFormat());
|
||||
// return m.isValid() ? m.toDate() : null;
|
||||
// }
|
||||
|
||||
const onDateTimeChange = (momentObject) => {
|
||||
this.setState({ answer: momentObject });
|
||||
|
@@ -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 {
|
||||
|
||||
@@ -55,6 +56,21 @@ class SideBarComponent extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
this.onTagDrop_ = async (event) => {
|
||||
const tagId = event.currentTarget.getAttribute('tagid');
|
||||
const dt = event.dataTransfer;
|
||||
if (!dt) return;
|
||||
|
||||
if (dt.types.indexOf("text/x-jop-note-ids") >= 0) {
|
||||
event.preventDefault();
|
||||
|
||||
const noteIds = JSON.parse(dt.getData("text/x-jop-note-ids"));
|
||||
for (let i = 0; i < noteIds.length; i++) {
|
||||
await Tag.addNote(tagId, noteIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.onFolderToggleClick_ = async (event) => {
|
||||
const folderId = event.currentTarget.getAttribute('folderid');
|
||||
|
||||
@@ -163,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;
|
||||
@@ -238,14 +283,22 @@ class SideBarComponent extends React.Component {
|
||||
|
||||
const InteropService = require("lib/services/InteropService.js");
|
||||
|
||||
const exportMenu = new Menu();
|
||||
const ioService = new InteropService();
|
||||
const ioModules = ioService.modules();
|
||||
for (let i = 0; i < ioModules.length; i++) {
|
||||
const module = ioModules[i];
|
||||
if (module.type !== 'exporter') continue;
|
||||
|
||||
exportMenu.append(new MenuItem({ label: module.fullLabel() , click: async () => {
|
||||
await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] });
|
||||
}}));
|
||||
}
|
||||
|
||||
menu.append(
|
||||
new MenuItem({
|
||||
label: _("Export"),
|
||||
click: async () => {
|
||||
const ioService = new InteropService();
|
||||
const module = ioService.moduleByFormat_("exporter", "jex");
|
||||
await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] });
|
||||
},
|
||||
submenu: exportMenu,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -346,8 +399,10 @@ class SideBarComponent extends React.Component {
|
||||
data-id={tag.id}
|
||||
data-type={BaseModel.TYPE_TAG}
|
||||
onContextMenu={event => this.itemContextMenu(event)}
|
||||
tagid={tag.id}
|
||||
key={tag.id}
|
||||
style={style}
|
||||
onDrop={this.onTagDrop_}
|
||||
onClick={() => {
|
||||
this.tagItem_click(tag);
|
||||
}}
|
||||
@@ -445,7 +500,13 @@ class SideBarComponent extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let decryptionReportText = '';
|
||||
if (this.props.decryptionWorker && this.props.decryptionWorker.state !== 'idle' && this.props.decryptionWorker.itemCount) {
|
||||
decryptionReportText = _('Decrypting items: %d/%d', this.props.decryptionWorker.itemIndex + 1, this.props.decryptionWorker.itemCount);
|
||||
}
|
||||
|
||||
let lines = Synchronizer.reportToLines(this.props.syncReport);
|
||||
if (decryptionReportText) lines.push(decryptionReportText);
|
||||
const syncReportText = [];
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
syncReportText.push(
|
||||
@@ -485,6 +546,7 @@ const mapStateToProps = state => {
|
||||
locale: state.settings.locale,
|
||||
theme: state.settings.theme,
|
||||
collapsedFolderIds: state.collapsedFolderIds,
|
||||
decryptionWorker: state.decryptionWorker,
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -36,6 +36,22 @@
|
||||
<script>
|
||||
const contentElement = document.getElementById('content');
|
||||
|
||||
const ipc = {};
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
// Here we only deal with messages that are sent from the main Electro process to the webview.
|
||||
if (!event.data || event.data.target !== 'webview') return;
|
||||
|
||||
const callName = event.data.name;
|
||||
const callData = event.data.data;
|
||||
|
||||
if (!ipc[callName]) {
|
||||
console.warn('Missing IPC function:', event.data);
|
||||
} else {
|
||||
ipc[callName](callData);
|
||||
}
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Handle dynamically loading HLJS when a code element is present
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -119,7 +135,9 @@
|
||||
setPercentScroll(percentScroll_);
|
||||
}
|
||||
|
||||
ipcRenderer.on('setHtml', (event, html) => {
|
||||
ipc.setHtml = (event) => {
|
||||
const html = event.html;
|
||||
|
||||
updateBodyHeight();
|
||||
|
||||
contentElement.innerHTML = html;
|
||||
@@ -158,10 +176,12 @@
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let ignoreNextScrollEvent = false;
|
||||
ipcRenderer.on('setPercentScroll', (event, percent) => {
|
||||
ipc.setPercentScroll = (event) => {
|
||||
const percent = event.percent;
|
||||
|
||||
if (checkScrollIID_) {
|
||||
clearInterval(checkScrollIID_);
|
||||
checkScrollIID_ = null;
|
||||
@@ -169,7 +189,7 @@
|
||||
|
||||
ignoreNextScrollEvent = true;
|
||||
setPercentScroll(percent);
|
||||
});
|
||||
}
|
||||
|
||||
let mark_ = null;
|
||||
function setMarkers(keywords) {
|
||||
@@ -184,7 +204,9 @@
|
||||
}
|
||||
|
||||
let markLoaded_ = false;
|
||||
ipcRenderer.on('setMarkers', (event, keywords) => {
|
||||
ipc.setMarkers = (event) => {
|
||||
const keywords = event.keywords;
|
||||
|
||||
if (!keywords.length && !markLoaded_) return;
|
||||
|
||||
if (!markLoaded_) {
|
||||
@@ -199,7 +221,7 @@
|
||||
} else {
|
||||
setMarkers(keywords);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function maxScrollTop() {
|
||||
return Math.max(0, contentElement.scrollHeight - contentElement.clientHeight);
|
||||
@@ -210,6 +232,10 @@
|
||||
document.getElementById('body').style.height = window.innerHeight + 'px';
|
||||
}
|
||||
|
||||
const ipcProxySendToHost = (methodName, arg) => {
|
||||
window.postMessage({ target: 'main', name: methodName, args: [ arg ] }, '*');
|
||||
}
|
||||
|
||||
contentElement.addEventListener('scroll', function(e) {
|
||||
if (ignoreNextScrollEvent) {
|
||||
ignoreNextScrollEvent = false;
|
||||
@@ -218,7 +244,8 @@
|
||||
const m = maxScrollTop();
|
||||
const percent = m ? contentElement.scrollTop / m : 0;
|
||||
setPercentScroll(percent);
|
||||
ipcRenderer.sendToHost('percentScroll', percent);
|
||||
|
||||
ipcProxySendToHost('percentScroll', percent);
|
||||
});
|
||||
|
||||
document.addEventListener('contextmenu', function(event) {
|
||||
@@ -228,7 +255,7 @@
|
||||
if (element && !element.getAttribute('data-resource-id')) element = element.parentElement;
|
||||
|
||||
if (element && element.getAttribute('data-resource-id')) {
|
||||
ipcRenderer.sendToHost('contextMenu', {
|
||||
ipcProxySendToHost('contextMenu', {
|
||||
type: element.getAttribute('src') ? 'image' : 'resource',
|
||||
resourceId: element.getAttribute('data-resource-id'),
|
||||
});
|
||||
@@ -236,12 +263,12 @@
|
||||
const selectedText = window.getSelection().toString();
|
||||
|
||||
if (selectedText) {
|
||||
ipcRenderer.sendToHost('contextMenu', {
|
||||
ipcProxySendToHost('contextMenu', {
|
||||
type: 'text',
|
||||
textToCopy: selectedText,
|
||||
});
|
||||
} else if (event.target.getAttribute('href')) {
|
||||
ipcRenderer.sendToHost('contextMenu', {
|
||||
ipcProxySendToHost('contextMenu', {
|
||||
type: 'link',
|
||||
textToCopy: event.target.getAttribute('href'),
|
||||
});
|
||||
@@ -249,6 +276,27 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', function(event) {
|
||||
const t = event.target;
|
||||
|
||||
// Prevent URLs added via <a> tags from being opened within the application itself
|
||||
if (t && t.nodeName === 'A' && !t.hasAttribute('data-from-md')) {
|
||||
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')) {
|
||||
const href = t.getAttribute('href');
|
||||
if (href.indexOf('#') === 0) {
|
||||
event.preventDefault();
|
||||
location.hash = href;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Disable drag and drop otherwise it's possible to drop a URL
|
||||
// on it and it will open in the view as a website.
|
||||
document.addEventListener('drop', function(e) {
|
||||
|
@@ -1,4 +1,36 @@
|
||||
// Define here Electron objects that need to be accessed from the WebView
|
||||
// https://github.com/electron/electron/blob/master/docs/tutorial/security.md#2-disable-nodejs-integration-for-remote-content
|
||||
// In order to give access to the webview to certain functions of the main process, we need
|
||||
// this bridge which listens from the main process and sends to the webview and the other
|
||||
// way around. This is necessary after having enabled the "contextIsolation" option, which
|
||||
// prevents the webview from accessing low-level methods in the main process.
|
||||
|
||||
window.ipcRenderer = require('electron').ipcRenderer;
|
||||
const ipcRenderer = require('electron').ipcRenderer;
|
||||
|
||||
ipcRenderer.on('setHtml', (event, html) => {
|
||||
window.postMessage({ target: 'webview', name: 'setHtml', data: { html: html } }, '*');
|
||||
});
|
||||
|
||||
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 } }, '*');
|
||||
});
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
// Here we only deal with messages that are sent from the webview to the main Electron process
|
||||
if (!event.data || event.data.target !== 'main') return;
|
||||
|
||||
const callName = event.data.name;
|
||||
const args = event.data.args;
|
||||
|
||||
if (args.length === 0) {
|
||||
ipcRenderer.sendToHost(callName);
|
||||
} else if (args.length === 1) {
|
||||
ipcRenderer.sendToHost(callName, args[0]);
|
||||
} else if (args.length === 2) {
|
||||
ipcRenderer.sendToHost(callName, args[1]);
|
||||
} 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
@@ -11,10 +11,15 @@ locales['gl_ES'] = require('./gl_ES.json');
|
||||
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['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');
|
||||
locales['sl_SI'] = require('./sl_SI.json');
|
||||
locales['sv'] = require('./sv.json');
|
||||
locales['zh_CN'] = require('./zh_CN.json');
|
||||
locales['zh_TW'] = require('./zh_TW.json');
|
||||
module.exports = { locales: locales };
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
ElectronClient/app/locales/ko.json
Normal file
1
ElectronClient/app/locales/ko.json
Normal file
File diff suppressed because one or more lines are too long
1
ElectronClient/app/locales/nb.json
Normal file
1
ElectronClient/app/locales/nb.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
ElectronClient/app/locales/nl_NL.json
Normal file
1
ElectronClient/app/locales/nl_NL.json
Normal file
File diff suppressed because one or more lines are too long
1
ElectronClient/app/locales/no.json
Normal file
1
ElectronClient/app/locales/no.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
ElectronClient/app/locales/ro.json
Normal file
1
ElectronClient/app/locales/ro.json
Normal file
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
1
ElectronClient/app/locales/sv.json
Normal file
1
ElectronClient/app/locales/sv.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user