Compare commits
539 Commits
server-v2.
...
note_link_
Author | SHA1 | Date | |
---|---|---|---|
|
29426814e4 | ||
|
a5e18200e8 | ||
|
ab5313e37f | ||
|
54cc7063ad | ||
|
12a510c464 | ||
|
21d5800923 | ||
|
1d5e8e65d9 | ||
|
d2a6d24846 | ||
|
fb372723a4 | ||
|
b32a341700 | ||
|
caef5449dc | ||
|
864a3a7efe | ||
|
ce02d4c94f | ||
|
052d9f03d6 | ||
|
8a8def39f0 | ||
|
f0831f1d60 | ||
|
0e532fbaf0 | ||
|
11a1e1cb6b | ||
|
37b89b5644 | ||
|
2c464e89e6 | ||
|
68764bd82e | ||
|
520d9746c5 | ||
|
c3df191a95 | ||
|
06d5feaa63 | ||
|
0b3c4edb92 | ||
|
58045f87d8 | ||
|
28e66e2619 | ||
|
c3179a39a4 | ||
|
eb71260674 | ||
|
ed4a013cfc | ||
|
5ffe90c4b0 | ||
|
8a836ea4f9 | ||
|
1f2930f037 | ||
|
ef3afb2a01 | ||
|
5d873a3264 | ||
|
effba83a0e | ||
|
55d98346ee | ||
|
d848865b0d | ||
|
879702dadf | ||
|
8bb5b4a557 | ||
|
2c4cf9fbdb | ||
|
3b35ab6581 | ||
|
6744dc3a8a | ||
|
97c6684154 | ||
|
e797ebb864 | ||
|
f99b8dfde8 | ||
|
c21b28e6e6 | ||
|
c58e9fe346 | ||
|
c58ce8e2da | ||
|
f64d046c62 | ||
|
c7e3245008 | ||
|
8f3fd0bf8b | ||
|
d293474402 | ||
|
aaa610d5f4 | ||
|
20a7cd2323 | ||
|
d7af060564 | ||
|
d7663212cf | ||
|
429a49b07e | ||
|
124ce342d8 | ||
|
19f4139470 | ||
|
21b6564301 | ||
|
c8b6122a65 | ||
|
c0bc4c38c3 | ||
|
0c50a5ab9b | ||
|
ce6797d842 | ||
|
29a1cc022c | ||
|
af665f247c | ||
|
8ea32201e7 | ||
|
4c88376449 | ||
|
0618e9ec90 | ||
|
176c9e0bcf | ||
|
c7697b65ca | ||
|
3bb00956fe | ||
|
e3695c6a80 | ||
|
40bc63e7ea | ||
|
c320d2364e | ||
|
fb9e78d6c1 | ||
|
27ef917350 | ||
|
2dedede5c3 | ||
|
443e049022 | ||
|
b4c3ba249d | ||
|
46f146309d | ||
|
541203f919 | ||
|
8495045ada | ||
|
64c3784a8b | ||
|
ff897236f7 | ||
|
53206d5488 | ||
|
1eeefb942d | ||
|
87296a616a | ||
|
6c0f3c3578 | ||
|
c1fb9fb3f5 | ||
|
466a534fcd | ||
|
9375fe1323 | ||
|
19b8191712 | ||
|
7111d31813 | ||
|
d97064979f | ||
|
232e0a3a72 | ||
|
40d9ccf183 | ||
|
f75a9d4a64 | ||
|
7168e0dc90 | ||
|
91df23e959 | ||
|
63b3115d3b | ||
|
8f0763ed45 | ||
|
94ac82d7d9 | ||
|
7c2bb02f9e | ||
|
832d1a560a | ||
|
020fd4ad9a | ||
|
e4b150a4cd | ||
|
9ac3b353e7 | ||
|
84d7f0fd60 | ||
|
d4c209e638 | ||
|
2cbe7be16e | ||
|
d2bb2e9df4 | ||
|
c2a6a13eb4 | ||
|
6ba5a896e8 | ||
|
6937066c60 | ||
|
64ef5ebde4 | ||
|
7ec3a7be9f | ||
|
81ea66f4ad | ||
|
075c4053a8 | ||
|
17256873dc | ||
|
6f1a806e5c | ||
|
41e95e81de | ||
|
f406d112bd | ||
|
2151a626cd | ||
|
0fc65acfa2 | ||
|
2eddd40667 | ||
|
a8723ea512 | ||
|
a6c3fbb0ed | ||
|
5e0c171099 | ||
|
b8aa7d0735 | ||
|
91d786ddbe | ||
|
1fc0fb39d3 | ||
|
afdc7ef141 | ||
|
adf317e16c | ||
|
191c49c0cd | ||
|
27118c2d00 | ||
|
766d7ebb65 | ||
|
d99312e06c | ||
|
b28f069f70 | ||
|
876a67d9b0 | ||
|
814a5a0cd8 | ||
|
5adee9085c | ||
|
c86e7f5eed | ||
|
c7444e563b | ||
|
2486c787a4 | ||
|
e518d45719 | ||
|
47c3ee0f2c | ||
|
f7b5ed9871 | ||
|
015562c86a | ||
|
7f3e8c5455 | ||
|
cef3eac372 | ||
|
d97a7bc7ab | ||
|
9806e3319a | ||
|
22ae50c126 | ||
|
0d4cb5c16a | ||
|
0d8c69123b | ||
|
ae5b810bed | ||
|
c95367fbbb | ||
|
22c83214be | ||
|
86179bd74c | ||
|
8abdbfe2bd | ||
|
790c98ca40 | ||
|
774c20772b | ||
|
d9a4a9cb30 | ||
|
bd917ae09c | ||
|
a7c0e926cf | ||
|
8a65bb5818 | ||
|
aa503aee3e | ||
|
373cd805dc | ||
|
fc095986b0 | ||
|
8e5d862c36 | ||
|
2399ca6321 | ||
|
889aecc8d4 | ||
|
36e75310bf | ||
|
d3d944d52b | ||
|
89a498b886 | ||
|
b7167552ec | ||
|
627b16728d | ||
|
18a7b1a69f | ||
|
1b1e060226 | ||
|
ebbb1d6d37 | ||
|
dabd0e1d3b | ||
|
64377cd3c9 | ||
|
be8001857e | ||
|
5d9b43ee31 | ||
|
1797e847aa | ||
|
fd9fe5c931 | ||
|
b4a6e17090 | ||
|
0cdef66816 | ||
|
a111531810 | ||
|
510df43d8d | ||
|
845ac19f0d | ||
|
01ee178566 | ||
|
3f4e7ff74e | ||
|
65ad6543a2 | ||
|
f27d15a5a7 | ||
|
7c619df2ce | ||
|
546447b09b | ||
|
7ef9d87e76 | ||
|
8019306247 | ||
|
818ad62fbe | ||
|
671077e1bb | ||
|
1b043d856d | ||
|
7e1ee40333 | ||
|
343b81ad09 | ||
|
7b7e53f3b2 | ||
|
95d5866955 | ||
|
39efc88059 | ||
|
558e55090f | ||
|
ff066baa26 | ||
|
e5313a9719 | ||
|
376019b540 | ||
|
c28979e620 | ||
|
7e9c7a5954 | ||
|
55db877f85 | ||
|
f24750f7b4 | ||
|
cfd5416b73 | ||
|
ea2418d018 | ||
|
e8d704f13a | ||
|
c94a98b841 | ||
|
4fd19d6970 | ||
|
6f249c3008 | ||
|
0374505212 | ||
|
21706fa00a | ||
|
74273cd570 | ||
|
6458ad0540 | ||
|
58bf93a112 | ||
|
5962b0813e | ||
|
cffea3ea1e | ||
|
f6e21e0180 | ||
|
e02422070e | ||
|
727d64b646 | ||
|
23e54a60d9 | ||
|
0d4978223e | ||
|
0b32a29cce | ||
|
a0d77d10ba | ||
|
bdd9c6cf35 | ||
|
f2bfa30e04 | ||
|
8077117e65 | ||
|
7e8927398a | ||
|
09dcee876c | ||
|
23b56f4f70 | ||
|
b3d09ce776 | ||
|
84d40b805e | ||
|
c097a82b7b | ||
|
dfa22b560e | ||
|
7d31a3fe90 | ||
|
79aabc2d06 | ||
|
70e82ca64f | ||
|
a0662412b2 | ||
|
220b48ef02 | ||
|
cb637e817b | ||
|
27198a16a4 | ||
|
1a5bff3bf4 | ||
|
571147acbb | ||
|
9d9420a35c | ||
|
a79bc69604 | ||
|
3153d3a1b6 | ||
|
df8c265ee4 | ||
|
3725b14e04 | ||
|
a73d822998 | ||
|
a62e1fba96 | ||
|
37d51c3b58 | ||
|
d5dfecc19f | ||
|
8f8cc12d79 | ||
|
8e1802409f | ||
|
42b2f2146c | ||
|
2ba1563d92 | ||
|
a679b21119 | ||
|
dd10b6ac65 | ||
|
32600df7ce | ||
|
8a1cfabfc6 | ||
|
1b2046f2fa | ||
|
a1d5168918 | ||
|
047c1fb1a5 | ||
|
e83d662555 | ||
|
5c3b2671bf | ||
|
02a2dce605 | ||
|
c4e158d0fb | ||
|
fa8a1c2122 | ||
|
3f732939d0 | ||
|
fb8886db4b | ||
|
eb86e9c896 | ||
|
85e3a44276 | ||
|
8352e23bdf | ||
|
96137d74f0 | ||
|
addcfb0129 | ||
|
f4ec73ab0e | ||
|
19ba939f0f | ||
|
780b58ada4 | ||
|
b3aed81bea | ||
|
74dd2d1194 | ||
|
3c11445db0 | ||
|
50890a7b2b | ||
|
dc60da219a | ||
|
bef93e1375 | ||
|
45e02a6b3f | ||
|
0c5f64207f | ||
|
8e88686bb1 | ||
|
9594508c73 | ||
|
de7d3b6b8a | ||
|
f5b6398d07 | ||
|
62a5cf520a | ||
|
90bfffed0f | ||
|
a5b0d594c3 | ||
|
1547256af4 | ||
|
c3e7fcb471 | ||
|
261302d5c4 | ||
|
38e65253ad | ||
|
eb8d0daa3d | ||
|
5a6c03fbac | ||
|
21f9dab908 | ||
|
6dba4730b0 | ||
|
9599d4ef7e | ||
|
252f08e828 | ||
|
94dc216add | ||
|
32de63fad3 | ||
|
299a14755a | ||
|
053dbabf74 | ||
|
07f128ae95 | ||
|
98f9ed641c | ||
|
d814fd6965 | ||
|
d44aade075 | ||
|
4884c9ef87 | ||
|
3e518ff2c7 | ||
|
195c84ff59 | ||
|
6881259501 | ||
|
6d7f6e29bd | ||
|
dc991d4c0f | ||
|
75cc9d7f9b | ||
|
693e52a1fd | ||
|
88ac664e37 | ||
|
20784b0e99 | ||
|
a325bf6dc6 | ||
|
ff79745d28 | ||
|
82109a3132 | ||
|
4e901436cc | ||
|
f0113c0673 | ||
|
0a1947a712 | ||
|
39aee65eee | ||
|
d37b820bd3 | ||
|
5b5165dbcd | ||
|
06b95bb718 | ||
|
8e87e64dea | ||
|
422a5bfa91 | ||
|
bfe5ee8ba3 | ||
|
00e0f6b97c | ||
|
46490113a2 | ||
|
cc69cabf9b | ||
|
da88ddb6bd | ||
|
554fd73054 | ||
|
c48a0c6e79 | ||
|
f8b7db40c7 | ||
|
051eac09ec | ||
|
7584b203fc | ||
|
440618ef71 | ||
|
166d8da81b | ||
|
6b7fd24f9e | ||
|
41dd93bc24 | ||
|
4906087649 | ||
|
fe95926fa2 | ||
|
a0fcd240b0 | ||
|
ae3a4a3027 | ||
|
5252fdc8ce | ||
|
fe787d1257 | ||
|
a70f9b1a13 | ||
|
ed20604ad2 | ||
|
105a61c1ee | ||
|
38fbaa9acf | ||
|
0d0231e82c | ||
|
b79270990b | ||
|
064891d097 | ||
|
9036bc4fd1 | ||
|
0f41a2d00a | ||
|
3ee0c7f440 | ||
|
89ada6432b | ||
|
445d691103 | ||
|
de757026d4 | ||
|
5e8ed8bc24 | ||
|
0a739e099d | ||
|
f3b1f07a75 | ||
|
1b91646d92 | ||
|
885f0e1557 | ||
|
2933b7eb2a | ||
|
9f252ea673 | ||
|
db497ee0a5 | ||
|
31fcd0ed1d | ||
|
5d7d597147 | ||
|
6ebec0cbf8 | ||
|
f4b39633ea | ||
|
4c8e2fba7d | ||
|
288ae1b463 | ||
|
e3c9bcbec6 | ||
|
49180fbf88 | ||
|
486ac6db7b | ||
|
b3fc8fbc93 | ||
|
980190ec09 | ||
|
cebf043284 | ||
|
4c11bbf0da | ||
|
69170dd362 | ||
|
1afcb27601 | ||
|
68469bc1a5 | ||
|
a4e279270b | ||
|
2f7ab7e92e | ||
|
46202beb9b | ||
|
dd705680f1 | ||
|
00163f58d0 | ||
|
df9c460363 | ||
|
603c8338c0 | ||
|
fca5875c21 | ||
|
2941ee0590 | ||
|
5d71787835 | ||
|
2b2070aabe | ||
|
bb464d8a59 | ||
|
00a3014131 | ||
|
f51b0c6d06 | ||
|
01825e6d3e | ||
|
b7bb5acd41 | ||
|
638905e1b8 | ||
|
e05c89aa11 | ||
|
f5f7981dba | ||
|
23d9ba7bf1 | ||
|
095db5d0d2 | ||
|
5718001a33 | ||
|
91907aa5dd | ||
|
d70dca3139 | ||
|
630584c80e | ||
|
b152879086 | ||
|
2238ef5fd0 | ||
|
6bb0318c2f | ||
|
c668bb0370 | ||
|
360293949c | ||
|
8289ce3749 | ||
|
1bb4c38699 | ||
|
bc977bf43f | ||
|
c98edf89fa | ||
|
c6b67126fb | ||
|
c1aa57a72c | ||
|
fdba6c076e | ||
|
f8d0bb472e | ||
|
3a18da49f3 | ||
|
5143a81749 | ||
|
f283970186 | ||
|
abf50565cb | ||
|
287057fea6 | ||
|
8ac6017c02 | ||
|
8cdb73bd65 | ||
|
35e6aaceb7 | ||
|
52287c30bf | ||
|
a9daa4f772 | ||
|
316e31f937 | ||
|
94f4ba3053 | ||
|
8825133675 | ||
|
2fd724911d | ||
|
12704bfb4d | ||
|
070fd0434b | ||
|
a105306dc7 | ||
|
70035f49d1 | ||
|
066dcbc6e4 | ||
|
597454d39d | ||
|
6bc70ed8dc | ||
|
cfce397df8 | ||
|
0274fd1790 | ||
|
47da47e12d | ||
|
7088be01c8 | ||
|
6a1f3ace67 | ||
|
4ae3bec7e4 | ||
|
970c1fb423 | ||
|
810018b41f | ||
|
e0bfa0dbe6 | ||
|
ca7e68ba4b | ||
|
3fcdeb08d9 | ||
|
ebaddfa4a8 | ||
|
2ab049305e | ||
|
98bfb65ead | ||
|
09cbe3cb7c | ||
|
fd322edaab | ||
|
09ed92bc26 | ||
|
fb6069de6d | ||
|
39056ae1aa | ||
|
d031a04a2c | ||
|
ed0f0fae01 | ||
|
c185f00006 | ||
|
3117133be2 | ||
|
b92c650f5d | ||
|
9dbf5e02eb | ||
|
e1016b8af4 | ||
|
3ba4a1de72 | ||
|
a683f12622 | ||
|
89184a3f9f | ||
|
24dbede6c1 | ||
|
70e623e741 | ||
|
5c77317735 | ||
|
9684b38f7e | ||
|
3dfe43204d | ||
|
16148b2255 | ||
|
df14ffdee2 | ||
|
f6ed5eb064 | ||
|
a14115bfd7 | ||
|
dd68d6cf2c | ||
|
7d3555d62c | ||
|
af472528a2 | ||
|
5c8b0ec1cb | ||
|
5e20e890d8 | ||
|
50dc656f65 | ||
|
b36cf46a06 | ||
|
1781334374 | ||
|
71140a638f | ||
|
6ba0fce237 | ||
|
c033a343c1 | ||
|
898c96a566 | ||
|
b83fa133b2 | ||
|
ec7fec8b59 | ||
|
b2fb4f2ea2 | ||
|
c74e51a58e | ||
|
7cba4be498 | ||
|
19b396f2ec | ||
|
4ed7c340a0 | ||
|
fe770917fd | ||
|
f2168d3bca | ||
|
5d4ebc6e14 | ||
|
3cf0841775 | ||
|
e5b6ecc50b | ||
|
f451633a51 | ||
|
e813d15ef2 | ||
|
b5b02d8d7b | ||
|
2660ff3af6 | ||
|
59cdcaf8d1 | ||
|
d6f4ebfff5 | ||
|
e03655bc4d | ||
|
9426a2170c | ||
|
b47a541976 | ||
|
4df5ad5c7a | ||
|
b214c8e42a | ||
|
360ac40f50 | ||
|
7c00bc5d0e | ||
|
6f0f3d586e | ||
|
863d894af1 |
@@ -1,12 +1,19 @@
|
||||
_mydocs/
|
||||
_releases/
|
||||
.git/
|
||||
.yarn/cache/
|
||||
**/.DS_Store
|
||||
**/node_modules
|
||||
Assets/
|
||||
.git/
|
||||
_releases/
|
||||
packages/app-desktop
|
||||
packages/app-cli
|
||||
packages/app-mobile
|
||||
packages/app-clipper
|
||||
packages/generator-joplin
|
||||
packages/plugin-repo-cli
|
||||
docs/
|
||||
lerna-debug.log
|
||||
packages/app-cli/
|
||||
packages/app-clipper/
|
||||
packages/app-desktop/
|
||||
packages/app-mobile/
|
||||
packages/generator-joplin/
|
||||
packages/plugin-repo-cli/
|
||||
packages/server/db-*.sqlite
|
||||
packages/server/temp
|
||||
packages/server/dist/
|
||||
packages/server/logs/
|
||||
packages/server/temp/
|
||||
|
149
.eslintignore
@@ -46,7 +46,7 @@ packages/app-desktop/packageInfo.js
|
||||
packages/app-desktop/services/electron-context-menu.js
|
||||
packages/app-desktop/vendor/lib/
|
||||
packages/app-mobile/android
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.bundle.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.bundle.js
|
||||
packages/app-mobile/ios
|
||||
packages/app-mobile/lib/rnInjectedJs/
|
||||
packages/app-mobile/locales
|
||||
@@ -148,6 +148,9 @@ packages/app-desktop/checkForUpdates.js.map
|
||||
packages/app-desktop/commands/copyDevCommand.d.ts
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyDevCommand.js.map
|
||||
packages/app-desktop/commands/editProfileConfig.d.ts
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
packages/app-desktop/commands/editProfileConfig.js.map
|
||||
packages/app-desktop/commands/exportFolders.d.ts
|
||||
packages/app-desktop/commands/exportFolders.js
|
||||
packages/app-desktop/commands/exportFolders.js.map
|
||||
@@ -175,6 +178,18 @@ packages/app-desktop/commands/startExternalEditing.js.map
|
||||
packages/app-desktop/commands/stopExternalEditing.d.ts
|
||||
packages/app-desktop/commands/stopExternalEditing.js
|
||||
packages/app-desktop/commands/stopExternalEditing.js.map
|
||||
packages/app-desktop/commands/switchProfile.d.ts
|
||||
packages/app-desktop/commands/switchProfile.js
|
||||
packages/app-desktop/commands/switchProfile.js.map
|
||||
packages/app-desktop/commands/switchProfile1.d.ts
|
||||
packages/app-desktop/commands/switchProfile1.js
|
||||
packages/app-desktop/commands/switchProfile1.js.map
|
||||
packages/app-desktop/commands/switchProfile2.d.ts
|
||||
packages/app-desktop/commands/switchProfile2.js
|
||||
packages/app-desktop/commands/switchProfile2.js.map
|
||||
packages/app-desktop/commands/switchProfile3.d.ts
|
||||
packages/app-desktop/commands/switchProfile3.js
|
||||
packages/app-desktop/commands/switchProfile3.js.map
|
||||
packages/app-desktop/commands/toggleExternalEditing.d.ts
|
||||
packages/app-desktop/commands/toggleExternalEditing.js
|
||||
packages/app-desktop/commands/toggleExternalEditing.js.map
|
||||
@@ -217,6 +232,9 @@ packages/app-desktop/gui/Dialog.js.map
|
||||
packages/app-desktop/gui/DialogButtonRow.d.ts
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js.map
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.d.ts
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js.map
|
||||
packages/app-desktop/gui/DialogTitle.d.ts
|
||||
packages/app-desktop/gui/DialogTitle.js
|
||||
packages/app-desktop/gui/DialogTitle.js.map
|
||||
@@ -235,6 +253,9 @@ packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
|
||||
packages/app-desktop/gui/ErrorBoundary.d.ts
|
||||
packages/app-desktop/gui/ErrorBoundary.js
|
||||
packages/app-desktop/gui/ErrorBoundary.js.map
|
||||
packages/app-desktop/gui/FolderIconBox.d.ts
|
||||
packages/app-desktop/gui/FolderIconBox.js
|
||||
packages/app-desktop/gui/FolderIconBox.js.map
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.d.ts
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js.map
|
||||
@@ -256,6 +277,9 @@ packages/app-desktop/gui/KeymapConfig/utils/useKeymap.js.map
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.d.ts
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.js
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.js.map
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.d.ts
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.js
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.js.map
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.d.ts
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.js
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.js.map
|
||||
@@ -487,6 +511,12 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js.map
|
||||
@@ -532,6 +562,9 @@ packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js.map
|
||||
packages/app-desktop/gui/NoteList/commands/index.d.ts
|
||||
packages/app-desktop/gui/NoteList/commands/index.js
|
||||
packages/app-desktop/gui/NoteList/commands/index.js.map
|
||||
packages/app-desktop/gui/NoteList/types.d.ts
|
||||
packages/app-desktop/gui/NoteList/types.js
|
||||
packages/app-desktop/gui/NoteList/types.js.map
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.d.ts
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js.map
|
||||
@@ -721,6 +754,9 @@ packages/app-desktop/gui/utils/convertToScreenCoordinates.js.map
|
||||
packages/app-desktop/gui/utils/loadScript.d.ts
|
||||
packages/app-desktop/gui/utils/loadScript.js
|
||||
packages/app-desktop/gui/utils/loadScript.js.map
|
||||
packages/app-desktop/loadResources.testEnv.d.ts
|
||||
packages/app-desktop/loadResources.testEnv.js
|
||||
packages/app-desktop/loadResources.testEnv.js.map
|
||||
packages/app-desktop/plugins/GotoAnything.d.ts
|
||||
packages/app-desktop/plugins/GotoAnything.js
|
||||
packages/app-desktop/plugins/GotoAnything.js.map
|
||||
@@ -772,6 +808,9 @@ packages/app-desktop/services/plugins/hooks/useViewIsReady.js.map
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.d.ts
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
|
||||
packages/app-desktop/services/restart.d.ts
|
||||
packages/app-desktop/services/restart.js
|
||||
packages/app-desktop/services/restart.js.map
|
||||
packages/app-desktop/services/share/invitationRespond.d.ts
|
||||
packages/app-desktop/services/share/invitationRespond.js
|
||||
packages/app-desktop/services/share/invitationRespond.js.map
|
||||
@@ -814,9 +853,24 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js.ma
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.d.ts
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.d.ts
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js.map
|
||||
@@ -835,6 +889,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/gulpfile.d.ts
|
||||
packages/app-mobile/gulpfile.js
|
||||
packages/app-mobile/gulpfile.js.map
|
||||
packages/app-mobile/root.d.ts
|
||||
packages/app-mobile/root.js
|
||||
packages/app-mobile/root.js.map
|
||||
@@ -850,6 +907,9 @@ packages/app-mobile/services/e2ee/RSA.react-native.js.map
|
||||
packages/app-mobile/setupQuickActions.d.ts
|
||||
packages/app-mobile/setupQuickActions.js
|
||||
packages/app-mobile/setupQuickActions.js.map
|
||||
packages/app-mobile/tools/buildInjectedJs.d.ts
|
||||
packages/app-mobile/tools/buildInjectedJs.js
|
||||
packages/app-mobile/tools/buildInjectedJs.js.map
|
||||
packages/app-mobile/utils/ShareExtension.d.ts
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
packages/app-mobile/utils/ShareExtension.js.map
|
||||
@@ -928,6 +988,9 @@ packages/generator-joplin/generators/app/templates/src/index.js.map
|
||||
packages/htmlpack/src/index.d.ts
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/src/index.js.map
|
||||
packages/lib/ArrayUtils.d.ts
|
||||
packages/lib/ArrayUtils.js
|
||||
packages/lib/ArrayUtils.js.map
|
||||
packages/lib/AsyncActionQueue.d.ts
|
||||
packages/lib/AsyncActionQueue.js
|
||||
packages/lib/AsyncActionQueue.js.map
|
||||
@@ -946,6 +1009,12 @@ packages/lib/ClipperServer.js.map
|
||||
packages/lib/CssUtils.d.ts
|
||||
packages/lib/CssUtils.js
|
||||
packages/lib/CssUtils.js.map
|
||||
packages/lib/EventDispatcher.d.ts
|
||||
packages/lib/EventDispatcher.js
|
||||
packages/lib/EventDispatcher.js.map
|
||||
packages/lib/EventDispatcher.test.d.ts
|
||||
packages/lib/EventDispatcher.test.js
|
||||
packages/lib/EventDispatcher.test.js.map
|
||||
packages/lib/HtmlToMd.d.ts
|
||||
packages/lib/HtmlToMd.js
|
||||
packages/lib/HtmlToMd.js.map
|
||||
@@ -1030,6 +1099,9 @@ packages/lib/database.js.map
|
||||
packages/lib/debug/DebugService.d.ts
|
||||
packages/lib/debug/DebugService.js
|
||||
packages/lib/debug/DebugService.js.map
|
||||
packages/lib/dom.d.ts
|
||||
packages/lib/dom.js
|
||||
packages/lib/dom.js.map
|
||||
packages/lib/dummy.test.d.ts
|
||||
packages/lib/dummy.test.js
|
||||
packages/lib/dummy.test.js.map
|
||||
@@ -1060,6 +1132,9 @@ packages/lib/fs-driver-node.js.map
|
||||
packages/lib/fsDriver.test.d.ts
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/fsDriver.test.js.map
|
||||
packages/lib/geolocation-node.d.ts
|
||||
packages/lib/geolocation-node.js
|
||||
packages/lib/geolocation-node.js.map
|
||||
packages/lib/hooks/useAsyncEffect.d.ts
|
||||
packages/lib/hooks/useAsyncEffect.js
|
||||
packages/lib/hooks/useAsyncEffect.js.map
|
||||
@@ -1147,6 +1222,9 @@ packages/lib/models/NoteTag.js.map
|
||||
packages/lib/models/Resource.d.ts
|
||||
packages/lib/models/Resource.js
|
||||
packages/lib/models/Resource.js.map
|
||||
packages/lib/models/Resource.test.d.ts
|
||||
packages/lib/models/Resource.test.js
|
||||
packages/lib/models/Resource.test.js.map
|
||||
packages/lib/models/ResourceLocalState.d.ts
|
||||
packages/lib/models/ResourceLocalState.js
|
||||
packages/lib/models/ResourceLocalState.js.map
|
||||
@@ -1231,6 +1309,9 @@ packages/lib/services/DecryptionWorker.js.map
|
||||
packages/lib/services/ExternalEditWatcher.d.ts
|
||||
packages/lib/services/ExternalEditWatcher.js
|
||||
packages/lib/services/ExternalEditWatcher.js.map
|
||||
packages/lib/services/ExternalEditWatcher/utils.d.ts
|
||||
packages/lib/services/ExternalEditWatcher/utils.js
|
||||
packages/lib/services/ExternalEditWatcher/utils.js.map
|
||||
packages/lib/services/ItemChangeUtils.d.ts
|
||||
packages/lib/services/ItemChangeUtils.js
|
||||
packages/lib/services/ItemChangeUtils.js.map
|
||||
@@ -1435,6 +1516,9 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js.map
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.d.ts
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.js
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.js.map
|
||||
packages/lib/services/plugins/BasePlatformImplementation.d.ts
|
||||
packages/lib/services/plugins/BasePlatformImplementation.js
|
||||
packages/lib/services/plugins/BasePlatformImplementation.js.map
|
||||
packages/lib/services/plugins/BasePluginRunner.d.ts
|
||||
packages/lib/services/plugins/BasePluginRunner.js
|
||||
packages/lib/services/plugins/BasePluginRunner.js.map
|
||||
@@ -1555,6 +1639,24 @@ packages/lib/services/plugins/utils/validatePluginVersion.js.map
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.d.ts
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.js
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.js.map
|
||||
packages/lib/services/profileConfig/index.d.ts
|
||||
packages/lib/services/profileConfig/index.js
|
||||
packages/lib/services/profileConfig/index.js.map
|
||||
packages/lib/services/profileConfig/index.test.d.ts
|
||||
packages/lib/services/profileConfig/index.test.js
|
||||
packages/lib/services/profileConfig/index.test.js.map
|
||||
packages/lib/services/profileConfig/initProfile.d.ts
|
||||
packages/lib/services/profileConfig/initProfile.js
|
||||
packages/lib/services/profileConfig/initProfile.js.map
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.d.ts
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js.map
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.d.ts
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js.map
|
||||
packages/lib/services/profileConfig/types.d.ts
|
||||
packages/lib/services/profileConfig/types.js
|
||||
packages/lib/services/profileConfig/types.js.map
|
||||
packages/lib/services/rest/Api.d.ts
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.js.map
|
||||
@@ -1633,6 +1735,9 @@ packages/lib/services/searchengine/SearchEngineUtils.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js.map
|
||||
packages/lib/services/searchengine/SearchFilter.test.d.ts
|
||||
packages/lib/services/searchengine/SearchFilter.test.js
|
||||
packages/lib/services/searchengine/SearchFilter.test.js.map
|
||||
packages/lib/services/searchengine/filterParser.d.ts
|
||||
packages/lib/services/searchengine/filterParser.js
|
||||
packages/lib/services/searchengine/filterParser.js.map
|
||||
@@ -1855,6 +1960,9 @@ packages/plugins/ToggleSidebars/api/types.js.map
|
||||
packages/plugins/ToggleSidebars/src/index.d.ts
|
||||
packages/plugins/ToggleSidebars/src/index.js
|
||||
packages/plugins/ToggleSidebars/src/index.js.map
|
||||
packages/react-native-saf-x/src/index.d.ts
|
||||
packages/react-native-saf-x/src/index.js
|
||||
packages/react-native-saf-x/src/index.js.map
|
||||
packages/renderer/HtmlToHtml.d.ts
|
||||
packages/renderer/HtmlToHtml.js
|
||||
packages/renderer/HtmlToHtml.js.map
|
||||
@@ -1924,9 +2032,15 @@ packages/renderer/MdToHtml/validateLinks.js.map
|
||||
packages/renderer/headerAnchor.d.ts
|
||||
packages/renderer/headerAnchor.js
|
||||
packages/renderer/headerAnchor.js.map
|
||||
packages/renderer/highlight.d.ts
|
||||
packages/renderer/highlight.js
|
||||
packages/renderer/highlight.js.map
|
||||
packages/renderer/htmlUtils.d.ts
|
||||
packages/renderer/htmlUtils.js
|
||||
packages/renderer/htmlUtils.js.map
|
||||
packages/renderer/htmlUtils.test.d.ts
|
||||
packages/renderer/htmlUtils.test.js
|
||||
packages/renderer/htmlUtils.test.js.map
|
||||
packages/renderer/index.d.ts
|
||||
packages/renderer/index.js
|
||||
packages/renderer/index.js.map
|
||||
@@ -1945,6 +2059,12 @@ packages/tools/buildServerDocker.js.map
|
||||
packages/tools/buildServerDocker.test.d.ts
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/buildServerDocker.test.js.map
|
||||
packages/tools/checkLibPaths.d.ts
|
||||
packages/tools/checkLibPaths.js
|
||||
packages/tools/checkLibPaths.js.map
|
||||
packages/tools/checkLibPaths.test.d.ts
|
||||
packages/tools/checkLibPaths.test.js
|
||||
packages/tools/checkLibPaths.test.js.map
|
||||
packages/tools/convertThemesToCss.d.ts
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/convertThemesToCss.js.map
|
||||
@@ -1957,6 +2077,9 @@ packages/tools/generate-images.js.map
|
||||
packages/tools/git-changelog.d.ts
|
||||
packages/tools/git-changelog.js
|
||||
packages/tools/git-changelog.js.map
|
||||
packages/tools/licenseChecker.d.ts
|
||||
packages/tools/licenseChecker.js
|
||||
packages/tools/licenseChecker.js.map
|
||||
packages/tools/release-android.d.ts
|
||||
packages/tools/release-android.js
|
||||
packages/tools/release-android.js.map
|
||||
@@ -1978,6 +2101,9 @@ packages/tools/release-server.js.map
|
||||
packages/tools/setupNewRelease.d.ts
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/setupNewRelease.js.map
|
||||
packages/tools/spellcheck.d.ts
|
||||
packages/tools/spellcheck.js
|
||||
packages/tools/spellcheck.js.map
|
||||
packages/tools/tagServerLatest.d.ts
|
||||
packages/tools/tagServerLatest.js
|
||||
packages/tools/tagServerLatest.js.map
|
||||
@@ -1999,9 +2125,24 @@ packages/tools/website/build.js.map
|
||||
packages/tools/website/updateDownloadPage.d.ts
|
||||
packages/tools/website/updateDownloadPage.js
|
||||
packages/tools/website/updateDownloadPage.js.map
|
||||
packages/tools/website/updateNews.d.ts
|
||||
packages/tools/website/updateNews.js
|
||||
packages/tools/website/updateNews.js.map
|
||||
packages/tools/website/utils/frontMatter.d.ts
|
||||
packages/tools/website/utils/frontMatter.js
|
||||
packages/tools/website/utils/frontMatter.js.map
|
||||
packages/tools/website/utils/news.d.ts
|
||||
packages/tools/website/utils/news.js
|
||||
packages/tools/website/utils/news.js.map
|
||||
packages/tools/website/utils/openGraph.d.ts
|
||||
packages/tools/website/utils/openGraph.js
|
||||
packages/tools/website/utils/openGraph.js.map
|
||||
packages/tools/website/utils/openGraph.test.d.ts
|
||||
packages/tools/website/utils/openGraph.test.js
|
||||
packages/tools/website/utils/openGraph.test.js.map
|
||||
packages/tools/website/utils/parser.d.ts
|
||||
packages/tools/website/utils/parser.js
|
||||
packages/tools/website/utils/parser.js.map
|
||||
packages/tools/website/utils/pressCarousel.d.ts
|
||||
packages/tools/website/utils/pressCarousel.js
|
||||
packages/tools/website/utils/pressCarousel.js.map
|
||||
|
@@ -76,6 +76,7 @@ module.exports = {
|
||||
|
||||
'no-array-constructor': ['error'],
|
||||
'radix': ['error'],
|
||||
'eqeqeq': ['error', 'always'],
|
||||
|
||||
// Warn only for now because fixing everything would take too much
|
||||
// refactoring, but new code should try to stick to it.
|
||||
|
7
.github/scripts/run_ci.sh
vendored
@@ -37,6 +37,9 @@ echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
|
||||
echo "GITHUB_REF=$GITHUB_REF"
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||
echo "BUILD_SEQUENCIAL=$BUILD_SEQUENCIAL"
|
||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
||||
|
||||
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
||||
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
||||
@@ -168,10 +171,10 @@ cd "$ROOT_DIR/packages/app-desktop"
|
||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||
echo "Step: Building and publishing desktop application..."
|
||||
USE_HARD_LINKS=false yarn run dist
|
||||
elif [[ $GIT_TAG_NAME = server-v* ]] && [[ $IS_LINUX = 1 ]]; then
|
||||
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
||||
echo "Step: Building Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images
|
||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
else
|
||||
echo "Step: Building but *not* publishing desktop application..."
|
||||
USE_HARD_LINKS=false yarn run dist --publish=never
|
||||
|
25
.github/stale.yml
vendored
@@ -1,25 +0,0 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "good first issue"
|
||||
- "upstream"
|
||||
- "backlog"
|
||||
- "high"
|
||||
- "medium"
|
||||
- "spec"
|
||||
- "cannot reproduce"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
|
||||
You may comment on the issue and I will leave it open.
|
||||
Thank you for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
|
||||
only: issues
|
23
.github/workflows/close-stale-issues.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: 'Close stale issues'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 16 * * *'
|
||||
permissions:
|
||||
issues: write
|
||||
jobs:
|
||||
ProcessStaleIssues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
# Use this to do a dry run from a pull request
|
||||
# debug-only: true
|
||||
stale-issue-message: "Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? If you require support or are requesting an enhancement or feature then please create a topic on the [Joplin forum](https://discourse.joplinapp.org/). This issue may be closed if no further activity occurs. You may comment on the issue and I will leave it open. Thank you for your contributions."
|
||||
days-before-stale: 30
|
||||
days-before-close: 7
|
||||
operations-per-run: 1000
|
||||
exempt-issue-labels: 'good first issue,upstream,backlog,high,medium,spec,cannot reproduce,enhancement'
|
||||
stale-issue-label: 'stale'
|
||||
close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, feel free to create a new issue with up-to-date information.'
|
||||
# Don't process pull requests at all
|
||||
days-before-pr-stale: -1
|
27
.github/workflows/github-actions-main.yml
vendored
@@ -5,7 +5,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-2016]
|
||||
# Removed windows-2016 for now - discontinued by GitHub
|
||||
os: [macos-latest, ubuntu-latest, windows-2019]
|
||||
steps:
|
||||
|
||||
# Silence apt-get update errors (for example when a module doesn't
|
||||
@@ -74,6 +75,7 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
run: |
|
||||
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
|
||||
|
||||
@@ -84,10 +86,23 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
# To ensure that the operations stop on failure, all commands
|
||||
# should be on one line with "&&" in between.
|
||||
run: |
|
||||
yarn install
|
||||
cd packages/app-desktop
|
||||
yarn run dist
|
||||
yarn install && cd packages/app-desktop && yarn run dist
|
||||
|
||||
# Build and package the Windows app, without publishing it, just to
|
||||
# verify that the build process hasn't been broken.
|
||||
- name: Build Windows app (no publishing)
|
||||
if: runner.os == 'Windows' && !startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
IS_CONTINUOUS_INTEGRATION: 1
|
||||
BUILD_SEQUENCIAL: 1
|
||||
SERVER_REPOSITORY: joplin/server
|
||||
SERVER_TAG_PREFIX: server
|
||||
run: |
|
||||
yarn install && cd packages/app-desktop && yarn run dist --publish=never
|
||||
|
||||
ServerDockerImage:
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -122,7 +137,9 @@ jobs:
|
||||
corepack enable
|
||||
|
||||
- name: Build Docker Image
|
||||
env:
|
||||
BUILD_SEQUENCIAL: 1
|
||||
run: |
|
||||
yarn install
|
||||
yarn run buildServerDocker --tag-name server-v0.0.0
|
||||
yarn run buildServerDocker --tag-name server-v0.0.0 --repository joplin/server
|
||||
|
147
.gitignore
vendored
@@ -138,6 +138,9 @@ packages/app-desktop/checkForUpdates.js.map
|
||||
packages/app-desktop/commands/copyDevCommand.d.ts
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyDevCommand.js.map
|
||||
packages/app-desktop/commands/editProfileConfig.d.ts
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
packages/app-desktop/commands/editProfileConfig.js.map
|
||||
packages/app-desktop/commands/exportFolders.d.ts
|
||||
packages/app-desktop/commands/exportFolders.js
|
||||
packages/app-desktop/commands/exportFolders.js.map
|
||||
@@ -165,6 +168,18 @@ packages/app-desktop/commands/startExternalEditing.js.map
|
||||
packages/app-desktop/commands/stopExternalEditing.d.ts
|
||||
packages/app-desktop/commands/stopExternalEditing.js
|
||||
packages/app-desktop/commands/stopExternalEditing.js.map
|
||||
packages/app-desktop/commands/switchProfile.d.ts
|
||||
packages/app-desktop/commands/switchProfile.js
|
||||
packages/app-desktop/commands/switchProfile.js.map
|
||||
packages/app-desktop/commands/switchProfile1.d.ts
|
||||
packages/app-desktop/commands/switchProfile1.js
|
||||
packages/app-desktop/commands/switchProfile1.js.map
|
||||
packages/app-desktop/commands/switchProfile2.d.ts
|
||||
packages/app-desktop/commands/switchProfile2.js
|
||||
packages/app-desktop/commands/switchProfile2.js.map
|
||||
packages/app-desktop/commands/switchProfile3.d.ts
|
||||
packages/app-desktop/commands/switchProfile3.js
|
||||
packages/app-desktop/commands/switchProfile3.js.map
|
||||
packages/app-desktop/commands/toggleExternalEditing.d.ts
|
||||
packages/app-desktop/commands/toggleExternalEditing.js
|
||||
packages/app-desktop/commands/toggleExternalEditing.js.map
|
||||
@@ -207,6 +222,9 @@ packages/app-desktop/gui/Dialog.js.map
|
||||
packages/app-desktop/gui/DialogButtonRow.d.ts
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js.map
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.d.ts
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js.map
|
||||
packages/app-desktop/gui/DialogTitle.d.ts
|
||||
packages/app-desktop/gui/DialogTitle.js
|
||||
packages/app-desktop/gui/DialogTitle.js.map
|
||||
@@ -225,6 +243,9 @@ packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js.map
|
||||
packages/app-desktop/gui/ErrorBoundary.d.ts
|
||||
packages/app-desktop/gui/ErrorBoundary.js
|
||||
packages/app-desktop/gui/ErrorBoundary.js.map
|
||||
packages/app-desktop/gui/FolderIconBox.d.ts
|
||||
packages/app-desktop/gui/FolderIconBox.js
|
||||
packages/app-desktop/gui/FolderIconBox.js.map
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.d.ts
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js.map
|
||||
@@ -246,6 +267,9 @@ packages/app-desktop/gui/KeymapConfig/utils/useKeymap.js.map
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.d.ts
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.js
|
||||
packages/app-desktop/gui/MainScreen/MainScreen.js.map
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.d.ts
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.js
|
||||
packages/app-desktop/gui/MainScreen/commands/addProfile.js.map
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.d.ts
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.js
|
||||
packages/app-desktop/gui/MainScreen/commands/commandPalette.js.map
|
||||
@@ -477,6 +501,12 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.test.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js.map
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.d.ts
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js.map
|
||||
@@ -522,6 +552,9 @@ packages/app-desktop/gui/NoteList/commands/focusElementNoteList.js.map
|
||||
packages/app-desktop/gui/NoteList/commands/index.d.ts
|
||||
packages/app-desktop/gui/NoteList/commands/index.js
|
||||
packages/app-desktop/gui/NoteList/commands/index.js.map
|
||||
packages/app-desktop/gui/NoteList/types.d.ts
|
||||
packages/app-desktop/gui/NoteList/types.js
|
||||
packages/app-desktop/gui/NoteList/types.js.map
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.d.ts
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js
|
||||
packages/app-desktop/gui/NoteListControls/NoteListControls.js.map
|
||||
@@ -711,6 +744,9 @@ packages/app-desktop/gui/utils/convertToScreenCoordinates.js.map
|
||||
packages/app-desktop/gui/utils/loadScript.d.ts
|
||||
packages/app-desktop/gui/utils/loadScript.js
|
||||
packages/app-desktop/gui/utils/loadScript.js.map
|
||||
packages/app-desktop/loadResources.testEnv.d.ts
|
||||
packages/app-desktop/loadResources.testEnv.js
|
||||
packages/app-desktop/loadResources.testEnv.js.map
|
||||
packages/app-desktop/plugins/GotoAnything.d.ts
|
||||
packages/app-desktop/plugins/GotoAnything.js
|
||||
packages/app-desktop/plugins/GotoAnything.js.map
|
||||
@@ -762,6 +798,9 @@ packages/app-desktop/services/plugins/hooks/useViewIsReady.js.map
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.d.ts
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js.map
|
||||
packages/app-desktop/services/restart.d.ts
|
||||
packages/app-desktop/services/restart.js
|
||||
packages/app-desktop/services/restart.js.map
|
||||
packages/app-desktop/services/share/invitationRespond.d.ts
|
||||
packages/app-desktop/services/share/invitationRespond.js
|
||||
packages/app-desktop/services/share/invitationRespond.js.map
|
||||
@@ -804,9 +843,24 @@ packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js.ma
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.d.ts
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/decoratorExtension.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/markdownMathParser.test.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/syntaxHighlightingLanguages.js.map
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.d.ts
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/theme.js.map
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.d.ts
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js.map
|
||||
@@ -825,6 +879,9 @@ packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js.map
|
||||
packages/app-mobile/components/screens/encryption-config.d.ts
|
||||
packages/app-mobile/components/screens/encryption-config.js
|
||||
packages/app-mobile/components/screens/encryption-config.js.map
|
||||
packages/app-mobile/gulpfile.d.ts
|
||||
packages/app-mobile/gulpfile.js
|
||||
packages/app-mobile/gulpfile.js.map
|
||||
packages/app-mobile/root.d.ts
|
||||
packages/app-mobile/root.js
|
||||
packages/app-mobile/root.js.map
|
||||
@@ -840,6 +897,9 @@ packages/app-mobile/services/e2ee/RSA.react-native.js.map
|
||||
packages/app-mobile/setupQuickActions.d.ts
|
||||
packages/app-mobile/setupQuickActions.js
|
||||
packages/app-mobile/setupQuickActions.js.map
|
||||
packages/app-mobile/tools/buildInjectedJs.d.ts
|
||||
packages/app-mobile/tools/buildInjectedJs.js
|
||||
packages/app-mobile/tools/buildInjectedJs.js.map
|
||||
packages/app-mobile/utils/ShareExtension.d.ts
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
packages/app-mobile/utils/ShareExtension.js.map
|
||||
@@ -918,6 +978,9 @@ packages/generator-joplin/generators/app/templates/src/index.js.map
|
||||
packages/htmlpack/src/index.d.ts
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/src/index.js.map
|
||||
packages/lib/ArrayUtils.d.ts
|
||||
packages/lib/ArrayUtils.js
|
||||
packages/lib/ArrayUtils.js.map
|
||||
packages/lib/AsyncActionQueue.d.ts
|
||||
packages/lib/AsyncActionQueue.js
|
||||
packages/lib/AsyncActionQueue.js.map
|
||||
@@ -936,6 +999,12 @@ packages/lib/ClipperServer.js.map
|
||||
packages/lib/CssUtils.d.ts
|
||||
packages/lib/CssUtils.js
|
||||
packages/lib/CssUtils.js.map
|
||||
packages/lib/EventDispatcher.d.ts
|
||||
packages/lib/EventDispatcher.js
|
||||
packages/lib/EventDispatcher.js.map
|
||||
packages/lib/EventDispatcher.test.d.ts
|
||||
packages/lib/EventDispatcher.test.js
|
||||
packages/lib/EventDispatcher.test.js.map
|
||||
packages/lib/HtmlToMd.d.ts
|
||||
packages/lib/HtmlToMd.js
|
||||
packages/lib/HtmlToMd.js.map
|
||||
@@ -1020,6 +1089,9 @@ packages/lib/database.js.map
|
||||
packages/lib/debug/DebugService.d.ts
|
||||
packages/lib/debug/DebugService.js
|
||||
packages/lib/debug/DebugService.js.map
|
||||
packages/lib/dom.d.ts
|
||||
packages/lib/dom.js
|
||||
packages/lib/dom.js.map
|
||||
packages/lib/dummy.test.d.ts
|
||||
packages/lib/dummy.test.js
|
||||
packages/lib/dummy.test.js.map
|
||||
@@ -1050,6 +1122,9 @@ packages/lib/fs-driver-node.js.map
|
||||
packages/lib/fsDriver.test.d.ts
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/fsDriver.test.js.map
|
||||
packages/lib/geolocation-node.d.ts
|
||||
packages/lib/geolocation-node.js
|
||||
packages/lib/geolocation-node.js.map
|
||||
packages/lib/hooks/useAsyncEffect.d.ts
|
||||
packages/lib/hooks/useAsyncEffect.js
|
||||
packages/lib/hooks/useAsyncEffect.js.map
|
||||
@@ -1137,6 +1212,9 @@ packages/lib/models/NoteTag.js.map
|
||||
packages/lib/models/Resource.d.ts
|
||||
packages/lib/models/Resource.js
|
||||
packages/lib/models/Resource.js.map
|
||||
packages/lib/models/Resource.test.d.ts
|
||||
packages/lib/models/Resource.test.js
|
||||
packages/lib/models/Resource.test.js.map
|
||||
packages/lib/models/ResourceLocalState.d.ts
|
||||
packages/lib/models/ResourceLocalState.js
|
||||
packages/lib/models/ResourceLocalState.js.map
|
||||
@@ -1221,6 +1299,9 @@ packages/lib/services/DecryptionWorker.js.map
|
||||
packages/lib/services/ExternalEditWatcher.d.ts
|
||||
packages/lib/services/ExternalEditWatcher.js
|
||||
packages/lib/services/ExternalEditWatcher.js.map
|
||||
packages/lib/services/ExternalEditWatcher/utils.d.ts
|
||||
packages/lib/services/ExternalEditWatcher/utils.js
|
||||
packages/lib/services/ExternalEditWatcher/utils.js.map
|
||||
packages/lib/services/ItemChangeUtils.d.ts
|
||||
packages/lib/services/ItemChangeUtils.js
|
||||
packages/lib/services/ItemChangeUtils.js.map
|
||||
@@ -1425,6 +1506,9 @@ packages/lib/services/keychain/KeychainServiceDriver.node.js.map
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.d.ts
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.js
|
||||
packages/lib/services/keychain/KeychainServiceDriverBase.js.map
|
||||
packages/lib/services/plugins/BasePlatformImplementation.d.ts
|
||||
packages/lib/services/plugins/BasePlatformImplementation.js
|
||||
packages/lib/services/plugins/BasePlatformImplementation.js.map
|
||||
packages/lib/services/plugins/BasePluginRunner.d.ts
|
||||
packages/lib/services/plugins/BasePluginRunner.js
|
||||
packages/lib/services/plugins/BasePluginRunner.js.map
|
||||
@@ -1545,6 +1629,24 @@ packages/lib/services/plugins/utils/validatePluginVersion.js.map
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.d.ts
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.js
|
||||
packages/lib/services/plugins/utils/validatePluginVersion.test.js.map
|
||||
packages/lib/services/profileConfig/index.d.ts
|
||||
packages/lib/services/profileConfig/index.js
|
||||
packages/lib/services/profileConfig/index.js.map
|
||||
packages/lib/services/profileConfig/index.test.d.ts
|
||||
packages/lib/services/profileConfig/index.test.js
|
||||
packages/lib/services/profileConfig/index.test.js.map
|
||||
packages/lib/services/profileConfig/initProfile.d.ts
|
||||
packages/lib/services/profileConfig/initProfile.js
|
||||
packages/lib/services/profileConfig/initProfile.js.map
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.d.ts
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/mergeGlobalAndLocalSettings.js.map
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.d.ts
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js
|
||||
packages/lib/services/profileConfig/splitGlobalAndLocalSettings.js.map
|
||||
packages/lib/services/profileConfig/types.d.ts
|
||||
packages/lib/services/profileConfig/types.js
|
||||
packages/lib/services/profileConfig/types.js.map
|
||||
packages/lib/services/rest/Api.d.ts
|
||||
packages/lib/services/rest/Api.js
|
||||
packages/lib/services/rest/Api.js.map
|
||||
@@ -1623,6 +1725,9 @@ packages/lib/services/searchengine/SearchEngineUtils.js.map
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.d.ts
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js
|
||||
packages/lib/services/searchengine/SearchEngineUtils.test.js.map
|
||||
packages/lib/services/searchengine/SearchFilter.test.d.ts
|
||||
packages/lib/services/searchengine/SearchFilter.test.js
|
||||
packages/lib/services/searchengine/SearchFilter.test.js.map
|
||||
packages/lib/services/searchengine/filterParser.d.ts
|
||||
packages/lib/services/searchengine/filterParser.js
|
||||
packages/lib/services/searchengine/filterParser.js.map
|
||||
@@ -1845,6 +1950,9 @@ packages/plugins/ToggleSidebars/api/types.js.map
|
||||
packages/plugins/ToggleSidebars/src/index.d.ts
|
||||
packages/plugins/ToggleSidebars/src/index.js
|
||||
packages/plugins/ToggleSidebars/src/index.js.map
|
||||
packages/react-native-saf-x/src/index.d.ts
|
||||
packages/react-native-saf-x/src/index.js
|
||||
packages/react-native-saf-x/src/index.js.map
|
||||
packages/renderer/HtmlToHtml.d.ts
|
||||
packages/renderer/HtmlToHtml.js
|
||||
packages/renderer/HtmlToHtml.js.map
|
||||
@@ -1914,9 +2022,15 @@ packages/renderer/MdToHtml/validateLinks.js.map
|
||||
packages/renderer/headerAnchor.d.ts
|
||||
packages/renderer/headerAnchor.js
|
||||
packages/renderer/headerAnchor.js.map
|
||||
packages/renderer/highlight.d.ts
|
||||
packages/renderer/highlight.js
|
||||
packages/renderer/highlight.js.map
|
||||
packages/renderer/htmlUtils.d.ts
|
||||
packages/renderer/htmlUtils.js
|
||||
packages/renderer/htmlUtils.js.map
|
||||
packages/renderer/htmlUtils.test.d.ts
|
||||
packages/renderer/htmlUtils.test.js
|
||||
packages/renderer/htmlUtils.test.js.map
|
||||
packages/renderer/index.d.ts
|
||||
packages/renderer/index.js
|
||||
packages/renderer/index.js.map
|
||||
@@ -1935,6 +2049,12 @@ packages/tools/buildServerDocker.js.map
|
||||
packages/tools/buildServerDocker.test.d.ts
|
||||
packages/tools/buildServerDocker.test.js
|
||||
packages/tools/buildServerDocker.test.js.map
|
||||
packages/tools/checkLibPaths.d.ts
|
||||
packages/tools/checkLibPaths.js
|
||||
packages/tools/checkLibPaths.js.map
|
||||
packages/tools/checkLibPaths.test.d.ts
|
||||
packages/tools/checkLibPaths.test.js
|
||||
packages/tools/checkLibPaths.test.js.map
|
||||
packages/tools/convertThemesToCss.d.ts
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/convertThemesToCss.js.map
|
||||
@@ -1947,6 +2067,9 @@ packages/tools/generate-images.js.map
|
||||
packages/tools/git-changelog.d.ts
|
||||
packages/tools/git-changelog.js
|
||||
packages/tools/git-changelog.js.map
|
||||
packages/tools/licenseChecker.d.ts
|
||||
packages/tools/licenseChecker.js
|
||||
packages/tools/licenseChecker.js.map
|
||||
packages/tools/release-android.d.ts
|
||||
packages/tools/release-android.js
|
||||
packages/tools/release-android.js.map
|
||||
@@ -1968,6 +2091,9 @@ packages/tools/release-server.js.map
|
||||
packages/tools/setupNewRelease.d.ts
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/setupNewRelease.js.map
|
||||
packages/tools/spellcheck.d.ts
|
||||
packages/tools/spellcheck.js
|
||||
packages/tools/spellcheck.js.map
|
||||
packages/tools/tagServerLatest.d.ts
|
||||
packages/tools/tagServerLatest.js
|
||||
packages/tools/tagServerLatest.js.map
|
||||
@@ -1989,9 +2115,24 @@ packages/tools/website/build.js.map
|
||||
packages/tools/website/updateDownloadPage.d.ts
|
||||
packages/tools/website/updateDownloadPage.js
|
||||
packages/tools/website/updateDownloadPage.js.map
|
||||
packages/tools/website/updateNews.d.ts
|
||||
packages/tools/website/updateNews.js
|
||||
packages/tools/website/updateNews.js.map
|
||||
packages/tools/website/utils/frontMatter.d.ts
|
||||
packages/tools/website/utils/frontMatter.js
|
||||
packages/tools/website/utils/frontMatter.js.map
|
||||
packages/tools/website/utils/news.d.ts
|
||||
packages/tools/website/utils/news.js
|
||||
packages/tools/website/utils/news.js.map
|
||||
packages/tools/website/utils/openGraph.d.ts
|
||||
packages/tools/website/utils/openGraph.js
|
||||
packages/tools/website/utils/openGraph.js.map
|
||||
packages/tools/website/utils/openGraph.test.d.ts
|
||||
packages/tools/website/utils/openGraph.test.js
|
||||
packages/tools/website/utils/openGraph.test.js.map
|
||||
packages/tools/website/utils/parser.d.ts
|
||||
packages/tools/website/utils/parser.js
|
||||
packages/tools/website/utils/parser.js.map
|
||||
packages/tools/website/utils/pressCarousel.d.ts
|
||||
packages/tools/website/utils/pressCarousel.js
|
||||
packages/tools/website/utils/pressCarousel.js.map
|
||||
|
@@ -9,11 +9,13 @@ import PluginManager from 'tinymce/core/api/PluginManager';
|
||||
import * as Api from './api/Api';
|
||||
import * as Commands from './api/Commands';
|
||||
import * as Keyboard from './core/Keyboard';
|
||||
import * as Mouse from './core/Mouse'
|
||||
import * as Buttons from './ui/Buttons';
|
||||
|
||||
export default function () {
|
||||
PluginManager.add('joplinLists', function (editor) {
|
||||
Keyboard.setup(editor);
|
||||
Mouse.setup(editor);
|
||||
Buttons.register(editor);
|
||||
Commands.register(editor);
|
||||
|
||||
|
26
Assets/TinyMCE/JoplinLists/src/main/ts/core/Mouse.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { isJoplinChecklistItem } from '../listModel/JoplinListUtil';
|
||||
|
||||
|
||||
const setup = function (editor) {
|
||||
const editorClickHandler = (event) => {
|
||||
if (!isJoplinChecklistItem(event.target)) return;
|
||||
|
||||
// We only process the click if it's within the checkbox itself (and not the label).
|
||||
// That checkbox, based on
|
||||
// the current styling is in the negative margin, so offsetX is negative when clicking
|
||||
// on the checkbox itself, and positive when clicking on the label. This is strongly
|
||||
// dependent on how the checkbox is styled, so if the style is changed, this might need
|
||||
// to be updated too.
|
||||
// For the styling, see:
|
||||
// packages/renderer/MdToHtml/rules/checkbox.ts
|
||||
//
|
||||
// The previous solution was to use "pointer-event: none", which mostly work, however
|
||||
// it means that links are no longer clickable when they are within the checkbox label.
|
||||
if (event.offsetX >= 0) return;
|
||||
|
||||
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
|
||||
}
|
||||
editor.on('click', editorClickHandler);
|
||||
};
|
||||
|
||||
export { setup };
|
@@ -10,7 +10,7 @@ import * as Settings from '../api/Settings';
|
||||
import * as NodeType from '../core/NodeType';
|
||||
import Editor from 'tinymce/core/api/Editor';
|
||||
import { isCustomList } from '../core/Util';
|
||||
import { findContainerListTypeFromEvent, isJoplinChecklistItem } from '../listModel/JoplinListUtil';
|
||||
import { findContainerListTypeFromEvent } from '../listModel/JoplinListUtil';
|
||||
|
||||
const findIndex = function (list, predicate) {
|
||||
for (let index = 0; index < list.length; index++) {
|
||||
@@ -38,37 +38,11 @@ const listState = function (editor: Editor, listName, options:any = {}) {
|
||||
buttonApi.setActive(listType === options.listType && lists.length > 0 && lists[0].nodeName === listName && !isCustomList(lists[0]));
|
||||
};
|
||||
|
||||
const editorClickHandler = (event) => {
|
||||
if (!isJoplinChecklistItem(event.target)) return;
|
||||
|
||||
// We only process the click if it's within the checkbox itself (and not the label).
|
||||
// That checkbox, based on
|
||||
// the current styling is in the negative margin, so offsetX is negative when clicking
|
||||
// on the checkbox itself, and positive when clicking on the label. This is strongly
|
||||
// dependent on how the checkbox is styled, so if the style is changed, this might need
|
||||
// to be updated too.
|
||||
// For the styling, see:
|
||||
// packages/renderer/MdToHtml/rules/checkbox.ts
|
||||
//
|
||||
// The previous solution was to use "pointer-event: none", which mostly work, however
|
||||
// it means that links are no longer clickable when they are within the checkbox label.
|
||||
if (event.offsetX >= 0) return;
|
||||
|
||||
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
|
||||
}
|
||||
|
||||
if (options.listType === 'joplinChecklist') {
|
||||
editor.on('click', editorClickHandler);
|
||||
}
|
||||
|
||||
editor.on('NodeChange', nodeChangeHandler);
|
||||
|
||||
return () => {
|
||||
if (options.listType === 'joplinChecklist') {
|
||||
editor.off('click', editorClickHandler);
|
||||
}
|
||||
editor.off('NodeChange', nodeChangeHandler);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -307,7 +307,7 @@ p,
|
||||
div.navbar-mobile-content a.sponsor-button {
|
||||
padding: 4px 12px;
|
||||
font-size: 0.9em;
|
||||
margin-right: 1em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
#nav-section.white-bg a {
|
||||
@@ -670,9 +670,9 @@ footer .bottom-links-row p {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.news-page img,
|
||||
.news-item-page img {
|
||||
max-width: 650px;
|
||||
.news-page .main-content img,
|
||||
.news-item-page .main-content img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
@@ -728,6 +728,23 @@ footer .bottom-links-row p {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
MEDIUM VIEW
|
||||
- Make menu bar elements smaller and closer to each others
|
||||
so that everything fit.
|
||||
*****************************************************************/
|
||||
|
||||
@media (max-width: 990px) {
|
||||
#nav-section > .container {
|
||||
max-width: 960px;
|
||||
}
|
||||
|
||||
#nav-section .button-link {
|
||||
padding: 4px 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
NARROW VIEW
|
||||
- Top right menu is displayed
|
||||
@@ -740,6 +757,23 @@ footer .bottom-links-row p {
|
||||
padding-bottom: 130px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links a {
|
||||
margin-left: 15px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#menu-mobile .social-links .social-link-mastodon,
|
||||
#menu-mobile .social-links .social-link-reddit,
|
||||
#menu-mobile .social-links .social-link-patreon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.front-page h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
@@ -857,7 +891,7 @@ footer .bottom-links-row p {
|
||||
}
|
||||
|
||||
#menu-mobile .button-link {
|
||||
padding: 10px 15px;
|
||||
padding: 4px 12px;
|
||||
font-size: 16px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
@@ -903,6 +937,25 @@ footer .bottom-links-row p {
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
VERY NARROW VIEW
|
||||
eg for Galaxy Fold
|
||||
*****************************************************************/
|
||||
|
||||
@media (max-width: 350px) {
|
||||
|
||||
#nav-section .navbar-mobile-content a.sponsor-button {
|
||||
background-color: transparent;
|
||||
color: #0557ba !important;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#nav-section .navbar-mobile-content a.sponsor-button .sponsor-button-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
PLANS PAGE
|
||||
*****************************************************************/
|
||||
@@ -1020,6 +1073,10 @@ footer .bottom-links-row p {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.joplin-cloud-feature-list table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-row .plan-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
BIN
Assets/WebsiteAssets/images/e2ee/e2ee-setup.png
Normal file
After Width: | Height: | Size: 292 KiB |
BIN
Assets/WebsiteAssets/images/e2ee/e2ee-share.png
Normal file
After Width: | Height: | Size: 382 KiB |
BIN
Assets/WebsiteAssets/images/e2ee/e2ee-sync.png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
Assets/WebsiteAssets/images/news/20220224-edit-dialog.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
Assets/WebsiteAssets/images/news/20220224-edit-notebook.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
Assets/WebsiteAssets/images/news/20220224-notebook-icon.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Assets/WebsiteAssets/images/news/20220308-gsoc-banner.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
Assets/WebsiteAssets/images/news/20220606-mermaid-as-png.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
Assets/WebsiteAssets/images/news/20220606-publish-website.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/ResidenceGreece.jpg
Normal file
After Width: | Height: | Size: 6.5 KiB |
261
Assets/WebsiteAssets/rss.xml
Normal file
@@ -0,0 +1,261 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Joplin]]></title><description><![CDATA[Joplin, the open source note-taking application]]></description><link>https://joplinapp.org</link><generator>RSS for Node</generator><lastBuildDate>Mon, 06 Jun 2022 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 06 Jun 2022 00:00:00 GMT</pubDate><item><title><![CDATA[Joplin 2.8 is available!]]></title><description><![CDATA[<p>As always a lot of changes and new features in this new version available on both desktop and mobile.</p>
|
||||
<h1>Multiple profile support<a name="multiple-profile-support" href="#multiple-profile-support" class="heading-anchor">🔗</a></h1>
|
||||
<p>Perhaps the most visible change in this version is the support for multiple profiles. You can now create as many application profile as you wish, each with their own settings, and easily switch from one to another. The main use case is to support for example a "work" profile and a "personal" profile, to allow you to keep things independent, and each profile can sync with a different sync target.</p>
|
||||
<p>To create a new profile, open <strong>File > Switch profile</strong> and select <strong>Create new profile</strong>, enter the profile name and press OK. The app will automatically switch to this new profile, which you can now configure.</p>
|
||||
<p>To switch back to the previous profile, again open <strong>File > Switch profile</strong> and select <strong>Default</strong>.</p>
|
||||
<p>Note that profiles all share certain settings, such as language, font size, theme, etc. This is done so that you don't have reconfigure every details when switching profiles. Other settings such as sync configuration is per profile.</p>
|
||||
<p>The feature is available on desktop only for now, and should be ported to mobile relatively soon.</p>
|
||||
<h1>Save Mermaid graph as PNG/SVG<a name="save-mermaid-graph-as-png-svg" href="#save-mermaid-graph-as-png-svg" class="heading-anchor">🔗</a></h1>
|
||||
<p>This convenient feature allows exporting a Mermaid graph as a PNG or SVG image, or allows copying the image as a DataUrl, which can then be pasted in any compatible text editor. Thanks Asrient for implementing this!</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220606-mermaid-as-png.png" alt=""></p>
|
||||
<h1>Publish a mini-website using Joplin Cloud<a name="publish-a-mini-website-using-joplin-cloud" href="#publish-a-mini-website-using-joplin-cloud" class="heading-anchor">🔗</a></h1>
|
||||
<p>Joplin Cloud now supports publishing a note "recursively", which means the notes and all the notes it is linked to. This allows easily publishing a simple website made of multiples and images.</p>
|
||||
<p>To make use of this feature, simply select <strong>Also publish linked notes</strong> when publishing a note.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220606-publish-website.png" alt=""></p>
|
||||
<h1>And more!<a name="and-more" href="#and-more" class="heading-anchor">🔗</a></h1>
|
||||
<p>In total there are 38 changes to improve the app reliability, security and usability. Full changelog is at <a href="https://joplinapp.org/changelog/">https://joplinapp.org/changelog/</a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20220606-release-2-8/</link><guid isPermaLink="false">20220606-release-2-8</guid><pubDate>Mon, 06 Jun 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin received 6 Contributor Projects for GSoC 2022!]]></title><description><![CDATA[<p>We are glad to announce that Google allocated us six projects this year for Google Summer of Code! So this is six contributors who will be working on various parts of the apps, both desktop and mobile, over the summer.</p>
|
||||
<p>Over the next few weeks, till 13 June, will be the Community Bonding Period during which GSoC contributors get to know mentors, read documentation, and get up to speed to begin working on their projects.</p>
|
||||
<p>Here's the full list of projects, contributors and mentors.</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Project Title</th>
|
||||
<th>Contributor</th>
|
||||
<th>Assigned Mentor(s)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Improve PDF previewer of Joplin</td>
|
||||
<td>asrient</td>
|
||||
<td>Roman, JackGruber</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Implement default plugins on desktop application</td>
|
||||
<td>mak2002</td>
|
||||
<td>CalebJohn, Laurent</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mobile — Easier Editing</td>
|
||||
<td>Henry H</td>
|
||||
<td>Daeraxa, CalebJohn</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Improve plugin search and discoverability</td>
|
||||
<td>Retr0ve</td>
|
||||
<td>JackGruber, Stefan</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tablet Layout Project</td>
|
||||
<td>Tolu-Mals</td>
|
||||
<td>Laurent, Daeraxa</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Email Plugin</td>
|
||||
<td>Bishoy Magdy Adeeb</td>
|
||||
<td>Stefan, Roman</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
]]></description><link>https://joplinapp.org/news/20220522-gsoc-contributors/</link><guid isPermaLink="false">20220522-gsoc-contributors</guid><pubDate>Sun, 22 May 2022 00:00:00 GMT</pubDate><twitter-text>Joplin received 6 Contributor Projects for GSoC 2022! Welcome to our new contributors who will be working on these projects over summer! #GSoC2022</twitter-text></item><item><title><![CDATA[GSoC "Contributor Proposals" phase is starting now!]]></title><description><![CDATA[<p>The "Contributor Proposals" phase of GSoC 2022 is starting today! If you would like to be a contributor, now is the time to choose your project idea, write your proposal, and upload it to <a href="https://summerofcode.withgoogle.com/">https://summerofcode.withgoogle.com/</a></p>
|
||||
<p>When it's done, please also let us know by posting an update on your forum introduction post.</p>
|
||||
<p>If you haven't created a pull request yet, it's still time to create one. Doing so will greatly increase your chances of being selected!</p>
|
||||
]]></description><link>https://joplinapp.org/news/20220405-gsoc-contributor-proposals/</link><guid isPermaLink="false">20220405-gsoc-contributor-proposals</guid><pubDate>Tue, 05 Apr 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin participates in Google Summer of Code 2022!]]></title><description><![CDATA[<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220308-gsoc-banner.png" alt=""></p>
|
||||
<p>For the third year, Joplin has been selected as a <strong>Google Summer of Code</strong> mentor organisation! We look forward to start working with the contributors on some great new projects. This year's main themes are:</p>
|
||||
<ul>
|
||||
<li><strong>Mobile and tablet development</strong> - we want to improve the mobile/tablet application on iOS and Android.</li>
|
||||
<li><strong>Plugin and external apps</strong> - leverage the Joplin API to create plugins and external apps.</li>
|
||||
<li>And of course contributors are welcome to suggest their own ideas.</li>
|
||||
</ul>
|
||||
<p>Our full idea list is available here: <a href="https://joplinapp.org/gsoc2022/ideas/">GSoC 2022 idea list</a></p>
|
||||
<p>In the coming month (<strong>March 7 - April 3</strong>), contributors will start getting involved in the forum and start discussing project ideas with the mentors and community. It's also a good time to start looking at Joplin's source code, perhaps work on fixing bugs or implement small features to get familiar with the source code, and to show us your skills.</p>
|
||||
<p>One difference with previous years is that anyone, not just students, are allowed to participate.</p>
|
||||
<p>Additionally, last year Google only allowed smaller projects, while this year they allow again small and large projects, so we've indicated this in the idea list - the small ones are <strong>175 hours</strong>, and the large ones <strong>350 hours</strong>.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20220308-gsoc2022-start/</link><guid isPermaLink="false">20220308-gsoc2022-start</guid><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.7 is available!]]></title><description><![CDATA[<p>This new release is largely focused on bug fixing and optimising various parts of the apps. There's about 26 improvements and 25 bugs and security fixes included - as always many of these apply to both the mobile and desktop app (see the <a href="https://joplinapp.org/changelog/">desktop changelog</a> and <a href="https://joplinapp.org/changelog_android/">mobile changelog</a>).</p>
|
||||
<p>Many thanks to all the contributors who helped create this release!</p>
|
||||
<p>Below are some of the more noticeable changes:</p>
|
||||
<h1>Notebook custom icons<a name="notebook-custom-icons" href="#notebook-custom-icons" class="heading-anchor">🔗</a></h1>
|
||||
<p>Since version 2.6 it was possible to assign an emoji icon to a notebook, and with this new version it's now possible to assign any custom icon. The icon may be a PNG or JPG file of any size. The app will then import the file and resize it to the correct size. To use a custom icon, follow these steps:</p>
|
||||
<p>Right-click on a notebook, and select "Edit":</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220224-edit-notebook.png" alt=""></p>
|
||||
<p>In the "Edit notebook" dialog, click "Select file..." and browse to your icon image:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220224-edit-dialog.png" alt=""></p>
|
||||
<p>Click "OK" and the icon will now appear next to the notebook:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220224-notebook-icon.png" alt=""></p>
|
||||
<p>The icon can be changed only from the desktop application at the moment, but it will sync and be displayed correctly on the mobile app too.</p>
|
||||
<h1>Plugin API improvements<a name="plugin-api-improvements" href="#plugin-api-improvements" class="heading-anchor">🔗</a></h1>
|
||||
<p>This version also includes a number of improvements to the plugin API, in particular it is now easier to customise the editor context menu from a plugin and dynamically add items to it depending on the context. For example, with the Rich Markdown plugin it will be possible to right-click on an image and open it, or copy it to the clipboard.</p>
|
||||
<p>A few additional functions have also been added to make plugin development simpler - in particular a command to open any item, whether it's a notebook, note, tag or attachement; and functions to work with attachements, in particular to reveal an attachement in the system file explorer, and to track changes to an attachement.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20220224-release-2-7/</link><guid isPermaLink="false">20220224-release-2-7</guid><pubDate>Thu, 24 Feb 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Automatic deletion of disabled accounts on Joplin Cloud]]></title><description><![CDATA[<p>As of 15 Feb 2022, disabled accounts on Joplin Cloud will be automatically deleted after 90 days. A disabled account is one where the Stripe subscription has been cancelled either by the user or automatically (eg for unpaid invoices).</p>
|
||||
<p>Although it is an automated system, I will manually verify each account that's queued for deletion over the next few days for additional safety (for now everything's working as expected).</p>
|
||||
<p>When an account is queued for deletion, all notes, notebooks, tags, etc are removed from the system within 2 days, and permanently deleted within 7 days. User information, in particular email and full name will be removed from the system within 2 days, but archived for an additional 90 days for legal reasons, after which they will be deleted too.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20220215-142000/</link><guid isPermaLink="false">20220215-142000</guid><pubDate>Tue, 15 Feb 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.6 is available!]]></title><description><![CDATA[<p>Many changes in this new release, available on mobile, desktop and CLI:</p>
|
||||
<p><strong>Per-notebook sort order and sort buttons</strong></p>
|
||||
<p>This new feature adds a number of changes to the way notes are sorted. The most visible one is the addition of a sort button above the note list - it allows sorting by modification date, creation date, title or by custom order, in either ascending or descending order:</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211217-120324_0.png" alt=""></p>
|
||||
<p>By default, this sort order is going to apply to all notebooks, however you can now also assign a per-notebook sort order. In this case, any sort order will be apply to that notebook only. To enable this behaviour, simply right-click on a notebook and select "Toggle own sort order":</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211217-120324_1.png" alt=""></p>
|
||||
<p>Thanks to Kenichi Kobayashi for developing this feature!</p>
|
||||
<p><strong>Support for notebook icons</strong></p>
|
||||
<p>It is now possible to associate icons with notebooks no both the desktop and mobile applications. To do so, right-click on a notebook and selected "Edit".</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211217-120324_2.png" alt=""></p>
|
||||
<p>This will open the new notebook dialog from which can change the title and assign an icon. For now the icons are emojis but perhaps custom icons could be supported later on.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211217-120324_3.png" alt=""></p>
|
||||
<p><strong>Allow collaborating on encrypted notebooks using Joplin Cloud</strong></p>
|
||||
<p>Thanks to the encryption improvements in the previous Joplin versions it is now possible to share and collaborated on encrypted notebooks, when synchronising with Joplin Cloud (or Joplin Server).</p>
|
||||
<p>To get this working, you and the recipient will need to have Joplin 2.6 and the person who shares will need to have encryption enabled. After that most of the process is handled automatically by the apps - in particular it will automatically generate and share the required encryption keys for each users.</p>
|
||||
<p><strong>Improved synchronisation startup speed</strong></p>
|
||||
<p>Synchronisation is also a bit faster in this release due to an optimisation on the startup process. When syncing, the app needs to acquire a lock, which may be time consuming since it requires making multiple requests. This has now been optimised so that less requests are necessary and also each request consumes less resources. This will have a postive impact on Joplin Cloud in particular, but you should also see improvements with Joplin Server and smaller improvements with the other sync targets.</p>
|
||||
<p><strong>Improved Markdown editor split view scrolling</strong></p>
|
||||
<p>Kenichi Kobayashi made some great improvements to the Markdown editor scrolling in this release. The issue before was that the editor on the left and the viewer on the right would often not be in sync, in particular if the note contains several images and other media.</p>
|
||||
<p>With Kenichi's change the editor and viewer stay nicely in sync, regardless of the note content. In fact it looks a bit like magic when you scroll through large notes - notice in particular how each side appear to wait for the other or speed up in order to make sure both sides are aligned as well possible. Kenichi provides a nice technical documentation about the feature <a href="https://github.com/laurent22/joplin/pull/5512#issuecomment-931277022">here</a>.</p>
|
||||
<p><a href="https://www.youtube.com/watch?v=Wbs5XZR0oeU">https://www.youtube.com/watch?v=Wbs5XZR0oeU</a></p>
|
||||
<p><strong>Improved and optimised S3 synchronisation</strong></p>
|
||||
<p>Thanks to the efforts of Lee Matos, synchronisation with S3 is now more reliable and errors are also better handled. The underlying S3 SDK has also been upgraded from v2 to v3 which results in a smaller executable size (about 3-5 MB depending on the operating system)</p>
|
||||
<p><strong>Export notes as self-contained HTML files</strong></p>
|
||||
<p>Exporting a single note as HTML is now more user friendly as all images, scripts, styles and other attachments are all packed into a single HTML file (Previously it would create multiples files and directories). This makes it easier to share the complete note with someone who doesn't have Joplin.</p>
|
||||
<p><strong>Other changes and bug fixes</strong></p>
|
||||
<p>This release includes a total of 19 new features and improvements and 16 bug fixes. See the 2.6.x changelogs for more details:</p>
|
||||
<p><a href="https://joplinapp.org/changelog/">https://joplinapp.org/changelog/</a></p>
|
||||
<p><a href="https://joplinapp.org/changelog_android/">https://joplinapp.org/changelog_android/</a></p>
|
||||
<p><a href="https://joplinapp.org/changelog_ios/">https://joplinapp.org/changelog_ios/</a></p>
|
||||
<p><a href="https://joplinapp.org/changelog_cli/">https://joplinapp.org/changelog_cli/</a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20211217-120324/</link><guid isPermaLink="false">20211217-120324</guid><pubDate>Fri, 17 Dec 2021 12:03:24 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Potential breaking change in next Joplin Server update (2.5.10)]]></title><description><![CDATA[<p>Just a head up that the next Joplin Server update could potentially include a breaking change, depending on your data.</p>
|
||||
<p>One of the database migration is going to add an "owner_id" column to the "items" table (where all notes, notebooks, etc. are stored), and automatically populate it. Normally that shouldn't take too long but you might want to make sure you won't need the server right away when you process this.</p>
|
||||
<p>The second database migration will add a unique constraint on items.name and items.owner_id and that's where the breaking change might be. Normally this data is already unique because that's enforced by the application but in some rare cases, due a race condition, there could be duplicate data in there. If that happens the migration will fail and the server will not start.</p>
|
||||
<p>If that happens, you'll need to decide what to do with the data, as it's not possible to automatically decide. You can find all duplicates using this query:</p>
|
||||
<p><code><strong>select</strong> count(<em>), name, owner_id<br>
|
||||
<strong>from</strong> items <strong>group</strong> <strong>by</strong> name, owner_id<br>
|
||||
<strong>having</strong> count(</em>) > 1;</code></p>
|
||||
<p>Once you have the list of IDs you have a few options:</p>
|
||||
<ul>
|
||||
<li>Find the corresponding item in Joplin (it can unfortunately be anything - a note, resource, folder, etc.), then delete it and sync.</li>
|
||||
<li>Or, just delete the data directly in the database. You'll want to delete the corresponding item_id from the user_items table too.</li>
|
||||
</ul>
|
||||
<p>But really in most cases you should be fine. Especially if you don't have that many notes it's unlikely you have duplicates.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20211102-150403/</link><guid isPermaLink="false">20211102-150403</guid><pubDate>Tue, 02 Nov 2021 15:04:03 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin v2.5 is available for desktop and mobile!]]></title><description><![CDATA[<p><a href="https://joplinapp.org/download/">Joplin v2.5</a> is now available for desktop, mobile and CLI! Here's an overview of the changes:</p>
|
||||
<h3>Support for Markdown + Front Matter<a name="support-for-markdown-front-matter" href="#support-for-markdown-front-matter" class="heading-anchor">🔗</a></h3>
|
||||
<p>Markdown + Front Matter is a format that allows attaching metadata, such as tags, creation date, or geolocation to a Markdown file. This is done by adding a block of YAML code (a "front matter") at the top of the file.</p>
|
||||
<p>Thansk to Caleb John's efforts the Joplin desktop and CLI applications now support importing and exporting these files. When exporting, we try to preserve as much metadata as possible, while still keeping it the formatting user friendly.</p>
|
||||
<p>Here's an example, with the Front Matter at the top, delimited by "---", and the text below.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211031-115215_0.png" alt=""></p>
|
||||
<p>Markdown + Front Matter is an excellent way to share notes with someone who doesn't have Joplin, to backup notes in a durable format (since no third-party application is needed to read it), and also to export notes to other applications, or to import them.</p>
|
||||
<p>As with the regular Markdown exporter, the images and attachments are also exported.</p>
|
||||
<h3>Add support for callback URLs<a name="add-support-for-callback-urls" href="#add-support-for-callback-urls" class="heading-anchor">🔗</a></h3>
|
||||
<p>Callback URLs is a semi-standard that defines how certain resources in an application can be accessed via URLs. Either to view the resource, or to perform certain actions, such as deletion, creation, etc.</p>
|
||||
<p>Joplin now support callback URLs to open notes, notebooks and folders. To do so, right click on a note and select "Copy external link":</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20211031-115215_1.png" alt=""></p>
|
||||
<p>That would give you a URL such as this:</p>
|
||||
<blockquote>
|
||||
<p>joplin://x-callback-url/openNote?id=b7a7b93281f54d928612eea550f33a7f</p>
|
||||
</blockquote>
|
||||
<p>Then if you click it from outside the app, the app will open and select this particular note. In practice such a feature allows third-party application to interact with Joplin by creating links that can be opened from outside. For example, you may use a different application for project planning, then link to the individual notes for more details about each task.</p>
|
||||
<p>Many thanks to Roman Musin for adding the feature!</p>
|
||||
<h3>Improved end-to-end encryption support<a name="improved-end-to-end-encryption-support" href="#improved-end-to-end-encryption-support" class="heading-anchor">🔗</a></h3>
|
||||
<p>The series of quiet but major changes to the end-to-end encryption support continue in this new verison. One goal is still to allow sharing notebooks while encryption is enabled.</p>
|
||||
<p>To that end, v2.5 includes support for RSA public-private key pairs. If you have encryption enabled, they will be automatically generated when you synchronise by the mobile, desktop or CLI applications. Later on, these keys will be used to allow sharing encrypted notebooks.</p>
|
||||
<p>The second goal of these E2EE changes is to simplify the system enough that it can be enabled by default. To that end, the master password dialog and encryption screen have been improved. An option to reset the master password is now also available.</p>
|
||||
<h3>Various other improvements and bug fixes<a name="various-other-improvements-and-bug-fixes" href="#various-other-improvements-and-bug-fixes" class="heading-anchor">🔗</a></h3>
|
||||
<p>In total this release includes about 11 other bug fixes and improvements. There was in particular several improvements to the share features. It is now also possible for a share recipient to leave the shared notebook.</p>
|
||||
<h3>Mobile app update<a name="mobile-app-update" href="#mobile-app-update" class="heading-anchor">🔗</a></h3>
|
||||
<p>As always the mobile apps (to be released soon) benefit from several of the above changes since they share the same codebase as the desktop app.</p>
|
||||
<p>Specific to the mobile version 2.5 are some improvements to the beta editor - in particular the layout has been cleaned up, and the first word of sentences is now automatically capitalised, which makes typing notes easier. If you haven't tried the beta editor yet, you can enable it from the Configuration screen.</p>
|
||||
<p>The full changelog is available there: <a href="https://joplinapp.org/changelog/">https://joplinapp.org/changelog/</a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20211031-115215/</link><guid isPermaLink="false">20211031-115215</guid><pubDate>Sun, 31 Oct 2021 11:52:15 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA["Certificate has expired" error with Joplin Cloud, and workaround]]></title><description><![CDATA[<p>Some of you might be experiencing an error "Certificate has expired" when synchronising with Joplin Cloud (and possibly other services) when using the desktop application.</p>
|
||||
<p>This is due to Let's Encrypt root certificate that expired on 30 September, and the new method they are using is not compatible with the Joplin desktop application.</p>
|
||||
<p>This actually affects thousands of applications, not just Joplin, so various solutions are being considered right now and hopefully a fix will be available relatively soon.</p>
|
||||
<p>For now, as a workaround, you can simply check "<strong>Ignore TLS certificate errors</strong>" in <strong>Configuration > Synchronisation > Advanced Options</strong></p>
|
||||
<p>I will let you know as soon as a fix is available so that you can clear that option.</p>
|
||||
<p>More info:</p>
|
||||
<p>- <a href="https://community.letsencrypt.org/t/issues-with-electron-and-expired-root/160991">Issue with Electron and expired root</a> on Let's Encrypt</p>
|
||||
<p>- <a href="https://github.com/electron/electron/issues/31212">Let's Encrypt root CA isn't working properly</a> on Electron GitHub repository</p>
|
||||
<p><strong>Update:</strong> I have implemented a temporary fix on Joplin Cloud which should solve the issue for now. If you're still having some issues please let me know. An updated desktop app will be available later on with a more permanent fix.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210930-163458/</link><guid isPermaLink="false">20210930-163458</guid><pubDate>Thu, 30 Sep 2021 16:34:58 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.4 is available!]]></title><description><![CDATA[<p>Joplin 2.4 is now available on desktop, mobile and CLI. Here's what's new in this release:</p>
|
||||
<h3>Sync Wizard Dialog<a name="sync-wizard-dialog" href="#sync-wizard-dialog" class="heading-anchor">🔗</a></h3>
|
||||
<p>A new Sync Wizard Dialog has been added to simplify setting up sync on new clients.</p>
|
||||
<p>The dialog shows the main sync targets, their differences, and makes it easy to choose one and start synchronising. This is mostly aimed at new users or those perhaps less technical. Those who are self hosting or using complex setups will still easily find what they need from a link on that dialog (or in Config > Synchronisation like before).</p>
|
||||
<p>Sync setup on mobile has been slightly improved too - now on a new client, instead of asking you to sync with Dropbox directly (which may not be what you want), it jumps to the Config > Synchronisation section where you can select the sync target</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_0.png" alt=""></p>
|
||||
<h3>Disable synchronisation<a name="disable-synchronisation" href="#disable-synchronisation" class="heading-anchor">🔗</a></h3>
|
||||
<p>It's a small change but something that's been asked many time - it's now possible to disable synchronisation entirely by selecting "None" as a sync target. Previously that could be done in a hacky way, by selecting a non-configured sync target. Now it's clearer and easier to do.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_1.png" alt=""></p>
|
||||
<h3>Add back support for deprecated plugins<a name="add-back-support-for-deprecated-plugins" href="#add-back-support-for-deprecated-plugins" class="heading-anchor">🔗</a></h3>
|
||||
<p>Recently some plugins stopped working because deprecated plugin APIs had been removed. It had been planned for a long time but I suspect the warnings weren't visible enough so plugin developers didn't act on them, and as a result many plugins stopped working.</p>
|
||||
<p>This is now fixed in the latest version. A selected number of plugins will have access to these old deprecated APIs, which means they will start working again. This was mainly affecting ambrt's plugins such as "Convert Text To New Note" or the popular "Embed Search" plugin.</p>
|
||||
<h3>Add support for recommended plugins<a name="add-support-for-recommended-plugins" href="#add-support-for-recommended-plugins" class="heading-anchor">🔗</a></h3>
|
||||
<p>As mentioned in an earlier post, we now support <a href="https://www.patreon.com/posts/introducing-in-55618802">recommended plugins</a>. These recommended plugins appear on top when searching and are identified by a small crown.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210929-144036_2.png" alt=""></p>
|
||||
<h3>End to End Encryption improvements<a name="end-to-end-encryption-improvements" href="#end-to-end-encryption-improvements" class="heading-anchor">🔗</a></h3>
|
||||
<p>Like most recent releases, v2.4 includes a few improvement to the End to End Encryption (E2EE) system. The goal is to make it easier to use, to make it more reliable and to support the future use case of sharing encrypted notebooks or notes.</p>
|
||||
<p>One important change is the support for a master password. This single password will be responsible to encrypt various keys, including some that will be automatically generated. Thanks to this, it won't be necessary to ask to enter a new password every time a key needs to be encrypted, since the master password can be used. It will also be easier to manage since you'll only have one password to remember instead of a different one for each notebook you might have shared.</p>
|
||||
<p>Finally, it's now possible to disable a master key. What it means is that it will no longer show up in the list of master keys, and will also no longer generate a warning asking you to enter the password. In some case you might have forgotten it and no longer need it key, so you can now disable it.</p>
|
||||
<h3>Custom CSS<a name="custom-css" href="#custom-css" class="heading-anchor">🔗</a></h3>
|
||||
<p>This version also introduces a few internal change to better support custom CSS. In particular the colours now come from a CSS file, which could potentially be overridden, and new UI elements are styled using stylesheets, which likewise could be overridden.</p>
|
||||
<p>Those are just first steps, but eventually these changes will make it easier to style the UI and create new themes.</p>
|
||||
<h3>Bug fixes<a name="bug-fixes" href="#bug-fixes" class="heading-anchor">🔗</a></h3>
|
||||
<p>This release also includes about 30 various bug fixes and improvements.</p>
|
||||
<p>A notable one is a fix for GotoAnything, which recently wasn't working on first try.</p>
|
||||
<p>The plugin screen has also been improved so that search works even when GitHub is down or blocked, as it is in China in particular.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210929-144036/</link><guid isPermaLink="false">20210929-144036</guid><pubDate>Wed, 29 Sep 2021 14:40:36 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Introducing recommended plugins in the next Joplin version]]></title><description><![CDATA[<p>A common request from new users is how to know which plugin is safe to install or not. In fact probably all of them are safe but as a new user that's not necessarily easy to know. So to help with this, the next version of Joplin will support recommended plugins - those will be plugins that meet our standards of quality and performance, and they will be indicated by a small crown tag inside the plugin box. Recommended plugins will also appear on top when searching.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210901-113415_0.png" alt=""></p>
|
||||
<p>For now, since we don't have a review process, the recommended plugins are those developed by the Joplin team and frequent contributors, because we know those are safe to use.</p>
|
||||
<p>Later we might have a review process and add more recommended plugins. That being said, in the meantime even if a plugin is not marked as recommended, there's a good chance it is still safe and have good performance too. Often you can search for it on the forum and if it's active with many users commenting, you're most likely good to go.</p>
|
||||
<p>But if there's any doubt, the recommended tag is a good way to be sure.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210901-113415/</link><guid isPermaLink="false">20210901-113415</guid><pubDate>Wed, 01 Sep 2021 11:34:15 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin Cloud is officially production ready!]]></title><description><![CDATA[<p><a href="https://joplinapp.org/plans/">Joplin Cloud</a> has been out of beta for a few weeks now and since then it has been quietly running without any troubles. There is no known bugs and the service is running smoothly so it's now safe to say that it is production ready!</p>
|
||||
<p>As a reminder, Joplin Cloud is meant to provide a more seamless Joplin experience - if you want to quickly get started, it's as easy as downloading the app and getting a Joplin Cloud account. Besides improved sync performance, that will give you the ability to collaborate on notebooks with others, as well as publishing and sharing notes.</p>
|
||||
<p>Of course Joplin still supports other sync options such as Nextcloud, Dropbox and OneDrive or AWS S3. You can also self host using Joplin Server. The advantage of Joplin Cloud being that you don't need to maintain a server yourself - for a small fee you'll get that taken care of.</p>
|
||||
<p>Additionally, subscribing to Joplin Cloud is a great way to support the project as a whole, including the open source applications. Such support is needed in the long term to provide bug and security fixes, add new features, and provide support.</p>
|
||||
<p>At some level it is also an experiment, to see if such a service is financially viable and can allow me to work full time on the project. This is certainly something I would like, and perhaps Joplin Cloud combined with your donations will allow that.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210831-154354/</link><guid isPermaLink="false">20210831-154354</guid><pubDate>Tue, 31 Aug 2021 15:43:54 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[How to start your subscription if you have a free Joplin Cloud Beta account]]></title><description><![CDATA[<p>For anyone with a beta account, if you would like to keep using it after the end of the trial period, there is now a button to do this from the Joplin Cloud home page:</p>
|
||||
<img height="222" src="https://aws1.discourse-cdn.com/standard14/uploads/cozic/optimized/2X/e/e2b54352d0e401e692a75817f6faa0432322c405_2_517x222.png" width="517">
|
||||
<p>If you click on it you will be sent to the Plans page via a special link. Then once you click on "Buy now" you will be sent to the Stripe page where you can start the subscription.</p>
|
||||
<p>As mentioned in the message, the process takes into account your remaining beta trial days. So for example, if your beta account expires in 60 days, the subscription will have a free 60 days trial period. This is so you don't lose any of the beta trial days no matter when you start the subscription.</p>
|
||||
<p>If you have any question about it, please let me know.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210804-085003/</link><guid isPermaLink="false">20210804-085003</guid><pubDate>Wed, 04 Aug 2021 08:50:03 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[New beta editor for the mobile app]]></title><description><![CDATA[<p>The <a href="https://github.com/laurent22/joplin-android/releases">latest Android pre-release 24</a> features an improved beta editor, which I hope could become a replacement for the very basic editor we have at the moment.</p>
|
||||
<p>It's still experimental because it's based on the equally experimental CodeMirror 6, however for simple editing tasks it seems to work fine. At the moment the improvements are:</p>
|
||||
<p>- Syntax highlighting for various tags such as bold, italic and headings.</p>
|
||||
<p>- List continuation for ordered and unordered lists (I didn't try checklists but I assume it doesn't work)</p>
|
||||
<p>- Improved undo/redo</p>
|
||||
<p>- Maybe better handling of large documents? CodeMirror 6 has a demo that loads a document with millions of lines, so maybe that will solve the performance issues that some users were having</p>
|
||||
<p>If everything works well, later on we should be able to add things like a toolbar, spellchecking and other features that are impossible with the current editor.</p>
|
||||
<p>If you find any bug, feel free to report here. Also make sure you backup your notes regularly in case there's an issue!</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210729-103234/</link><guid isPermaLink="false">20210729-103234</guid><pubDate>Thu, 29 Jul 2021 10:32:34 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[The Jopin Cloud beta is now closed]]></title><description><![CDATA[<p>The beta program helped narrow down a few issues and should make Joplin Cloud (and Joplin Server) more reliable. More precisely:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>About 7 bugs have been fixed, including two major ones regarding sharing, and one security issue.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>About a dozen improvements, new features and optimisations have been added following your feedback.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>As promised if you have a beta account you can keep using it and it will remain free for the three months after the account was created. After that, you will receive a link to start the Stripe subscription if you wish to keep using the account.</p>
|
||||
<p>If you have sent me an email before the end of the beta and I didn't reply yet, I will do so soon, and will send you the confirmation email.</p>
|
||||
<p>Thanks everyone for participating!</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210718-103538/</link><guid isPermaLink="false">20210718-103538</guid><pubDate>Sun, 18 Jul 2021 10:35:38 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[New website is ready!]]></title><description><![CDATA[<p>The new website is finally ready at <a href="https://joplinapp.org">https://joplinapp.org</a></p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20210711-095626_0.png" alt=""></p>
|
||||
<p>The previous website had been built organically over the past few years. It had a lot of useful content but finding your way was tricky and, for new users, it wasn't clear what Joplin was about. Finding out how to install the app wasn't obvious since the download buttons were lost in the clutter of information.</p>
|
||||
<p>So the new website includes a front page with clear goals:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Allows people to easily download the app - for that there's a large Download button at the top and bottom of the page. It redirects to a page that automatically picks the version based on your operating system.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Showcase the application key features. The <a href="https://discourse.joplinapp.org/t/what-are-the-key-features-of-joplin/5837">key features post</a> on the forum helped narrow down what Joplin is about, so there are sections about the web clipper, the open source nature of the app, encryption, synchronisation, customisation and the ability to create multimedia notes.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The top screenshots have also been updated (the previous one was showing a dev version from 2016, before the app was even released). As a nod to Scott Joplin, the screenshot shows an imaginary plan to open a vintage piano store, with various tasks, tables, documents and images attached, to showcase Joplin features.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Finally there's a Press section, which includes extracts from some cool articles that have been written about the app.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Also many thanks to everyone who voted and contributed to the tagline discussion! It helped narrow down what the tagline should be, along with the equally important description below. If you have any question or notice any issue with the website let me know!</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210711-095626/</link><guid isPermaLink="false">20210711-095626</guid><pubDate>Sun, 11 Jul 2021 09:56:26 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Poll: What should Joplin tagline be?]]></title><description><![CDATA[<p>Thanks everyone for your tagline suggestions - there were lots of good ideas in there. I've compiled a few of them and create a poll in the forum, so please cast your vote! And if you have any other suggestions on what would make a good tagline, feel free to post over there or here.</p>
|
||||
<p><a href="https://discourse.joplinapp.org/t/poll-what-should-joplin-tagline-be/18487">https://discourse.joplinapp.org/t/poll-what-should-joplin-tagline-be/18487</a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20210706-140228/</link><guid isPermaLink="false">20210706-140228</guid><pubDate>Tue, 06 Jul 2021 14:02:28 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Any ideas for a Joplin tagline?]]></title><description><![CDATA[<p>I'm going to update the website front page to better showcase the application. I have most of the sections right, but the part I'm still not sure about is the top tagline, so I'm wondering if anyone had any suggestion about it?</p>
|
||||
<p>From what I can see on Google Keep or Evernote for example it should be something like "Use our app to get X or Y benefit", it should be a sentence that directly speaks to the user essentially.</p>
|
||||
<p>So far I have "Your notes, anywhere you are" but I'm not certain that's particularly inspiring. Any other idea about what tagline could be used?</p>
|
||||
]]></description><link>https://joplinapp.org/news/20210705-094247/</link><guid isPermaLink="false">20210705-094247</guid><pubDate>Mon, 05 Jul 2021 09:42:47 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Poll: What's the size of your note collection?]]></title><description><![CDATA[<p>Poll is on the forum:</p>
|
||||
<p><a href="https://discourse.joplinapp.org/t/poll-whats-the-size-of-your-note-collection/18191">https://discourse.joplinapp.org/t/poll-whats-the-size-of-your-note-collection/18191</a></p>
|
||||
]]></description><link>https://joplinapp.org/news/20210624-171844/</link><guid isPermaLink="false">20210624-171844</guid><pubDate>Thu, 24 Jun 2021 17:18:44 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>
|
@@ -1,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{{> gtmHead}}
|
||||
{{> gaOptimize}}
|
||||
<meta
|
||||
charset="utf-8"
|
||||
@@ -10,8 +11,9 @@
|
||||
<link rel="icon" href="{{imageBaseUrl}}/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Joplin, the open source note-taking application" />
|
||||
<link rel="stylesheet" href="{{{assetUrls.css.fontawesome}}}">
|
||||
{{> openGraphTags}}
|
||||
{{> rssFeedLink}}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{cssBaseUrl}}/bootstrap5.0.2.min.css"
|
||||
@@ -33,6 +35,8 @@
|
||||
<title>Joplin</title>
|
||||
</head>
|
||||
<body class="front-page website-env-{{env}}">
|
||||
{{> gtmBody}}
|
||||
|
||||
<div class="container-fluid" id="main-container">
|
||||
|
||||
{{#navbar}}
|
||||
|
@@ -14,6 +14,7 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
||||
-->
|
||||
|
||||
<head>
|
||||
{{> gtmHead}}
|
||||
{{> gaOptimize}}
|
||||
<meta
|
||||
charset="utf-8"
|
||||
@@ -23,7 +24,8 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
||||
<link rel="icon" href="{{imageBaseUrl}}/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Joplin, the open source note-taking application" />
|
||||
{{> openGraphTags}}
|
||||
{{> rssFeedLink}}
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{cssBaseUrl}}/bootstrap5.0.2.min.css"
|
||||
@@ -47,6 +49,8 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
||||
></script>
|
||||
</head>
|
||||
<body class="website-env-{{env}}">
|
||||
{{> gtmBody}}
|
||||
|
||||
<div class="container-fluid generic-template {{pageName}}-page" id="main-container">
|
||||
|
||||
{{#navbar}}
|
||||
@@ -65,11 +69,6 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
|
||||
{{{contentHtml}}}
|
||||
{{#showBottomLinks}}
|
||||
<div class="bottom-links">
|
||||
{{#discussOnForumLink}}
|
||||
<a class="bottom-link" href="{{{discussOnForumLink}}}">
|
||||
<i class="fab fa-discourse"></i></i> Discuss on the forum
|
||||
</a>
|
||||
{{/discussOnForumLink}}
|
||||
{{#showImproveThisDoc}}
|
||||
<a class="bottom-link" href="https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}">
|
||||
<i class="fab fa-github"></i> Improve this doc
|
||||
|
@@ -1,15 +1,6 @@
|
||||
<footer class="darkblue-bg">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-12 social-links">
|
||||
<a href="https://twitter.com/joplinapp" title="Joplin Twitter feed"><i class="fab fa-twitter"></i></a>
|
||||
<a href="https://mastodon.social/@joplinapp" title="Joplin Mastodon feed"><i class="fab fa-mastodon"></i></a>
|
||||
<a href="https://www.patreon.com/joplin" title="Joplin Patreon"><i class="fab fa-patreon"></i></a>
|
||||
<a href="https://discord.gg/VSj7AFHvpq" title="Joplin Discord chat"><i class="fab fa-discord"></i></a>
|
||||
<a href="https://www.reddit.com/r/joplinapp/" title="Joplin Subreddit"><i class="fab fa-reddit"></i></a>
|
||||
<a href="https://github.com/laurent22/joplin/" title="Joplin GitHub repository"><i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{{> socialFeeds}}
|
||||
|
||||
<div class="row bottom-links-row">
|
||||
<div class="col-12 col-md-6">
|
||||
|
@@ -1,5 +1,9 @@
|
||||
<!-- Donate button A/B testing -->
|
||||
<!-- Monthly/Yearly plan A/B testing -->
|
||||
<!--
|
||||
<script src="https://www.googleoptimize.com/optimize.js?id=OPT-PW3ZPK3"></script>
|
||||
-->
|
||||
|
||||
<!-- Donate button A/B testing -->
|
||||
<!--
|
||||
<script async src="https://www.googleoptimize.com/optimize.js?id=OPT-PW3ZPK3"></script>
|
||||
-->
|
4
Assets/WebsiteAssets/templates/partials/gtmBody.mustache
Normal file
@@ -0,0 +1,4 @@
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-579DTGX"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
7
Assets/WebsiteAssets/templates/partials/gtmHead.mustache
Normal file
@@ -0,0 +1,7 @@
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-579DTGX');</script>
|
||||
<!-- End Google Tag Manager -->
|
@@ -12,7 +12,8 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-9 text-right d-none d-md-block">
|
||||
<a href="{{baseUrl}}/news/" class="fw500">What's New</a>
|
||||
{{> twitterLink}}
|
||||
<a href="{{baseUrl}}/news/" class="fw500">News</a>
|
||||
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
|
||||
<a href="{{forumUrl}}" class="fw500">Forum</a>
|
||||
{{#showJoplinCloudLinks}}
|
||||
@@ -21,6 +22,7 @@
|
||||
{{> supportButton}}
|
||||
</div>
|
||||
<div class="col-9 text-right d-block d-md-none navbar-mobile-content">
|
||||
{{> twitterLink}}
|
||||
{{> supportButton}}
|
||||
|
||||
<span class="pointer"
|
||||
@@ -43,7 +45,7 @@
|
||||
</div>
|
||||
|
||||
<div class="text-center menu-mobile-top">
|
||||
<a href="{{baseUrl}}/news/" class="fw500 mobile-menu-link">What's New</a>
|
||||
<a href="{{baseUrl}}/news/" class="fw500 mobile-menu-link">News</a>
|
||||
<a href="{{baseUrl}}/help/" class="fw500 mobile-menu-link">Help</a>
|
||||
<a href="{{forumUrl}}" class="fw500 mobile-menu-link">Forum</a>
|
||||
</div>
|
||||
@@ -59,6 +61,8 @@
|
||||
{{#showToc}}
|
||||
<div id="toc-mobile">{{{tocHtml}}}</div>
|
||||
{{/showToc}}
|
||||
|
||||
{{> socialFeeds}}
|
||||
|
||||
<div>
|
||||
<p class="light-blue mobile-menu-link-bottom text-center">
|
||||
|
@@ -0,0 +1,14 @@
|
||||
{{#openGraph}}
|
||||
<meta name="description" content="{{openGraph.description}}" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@joplinapp" />
|
||||
<meta property="og:url" content="{{{openGraph.url}}}" />
|
||||
<meta property="og:title" content="{{openGraph.title}}" />
|
||||
<meta property="twitter:title" content="{{openGraph.title}}" />
|
||||
<meta property="og:description" content="{{openGraph.description}}" />
|
||||
<meta property="twitter:description" content="{{openGraph.description}}" />
|
||||
{{#openGraph.image}}
|
||||
<meta property="og:image" content="{{{openGraph.image}}}" />
|
||||
<meta property="twitter:image" content="{{{openGraph.image}}}" />
|
||||
{{/openGraph.image}}
|
||||
{{/openGraph}}
|
@@ -6,11 +6,11 @@
|
||||
</div>
|
||||
|
||||
<div class="plan-price plan-price-monthly">
|
||||
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month"> /month</sub>
|
||||
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month"> /month{{#footnote}} (*){{/footnote}}</sub>
|
||||
</div>
|
||||
|
||||
<div class="plan-price plan-price-yearly">
|
||||
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month"> /month</sub>
|
||||
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month"> /month{{#footnote}} (*){{/footnote}}</sub>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,17 +20,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#featuresOn}}
|
||||
{{#featureLabelsOn}}
|
||||
<p><i class="fas fa-check feature feature-on"></i>{{.}}</p>
|
||||
{{/featuresOn}}
|
||||
{{/featureLabelsOn}}
|
||||
|
||||
{{#featuresOff}}
|
||||
{{#featureLabelsOff}}
|
||||
<p class="unchecked-text"><i class="fas fa-times feature feature-off"></i>{{.}}</p>
|
||||
{{/featuresOff}}
|
||||
{{/featureLabelsOff}}
|
||||
|
||||
<p class="text-center subscribe-wrapper">
|
||||
<a id="subscribeButton-{{name}}" href="{{cfaUrl}}" class="button-link btn-white subscribeButton">{{cfaLabel}}</a>
|
||||
</p>
|
||||
|
||||
{{#footnote}}<sub>(*) {{.}}</sub>{{/footnote}}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
@@ -0,0 +1 @@
|
||||
<link rel="alternate" type="application/rss+xml" title="Joplin RSS feed" href="https://joplinapp.org/rss.xml" />
|
10
Assets/WebsiteAssets/templates/partials/socialFeeds.mustache
Normal file
@@ -0,0 +1,10 @@
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-12 social-links">
|
||||
<a class="social-link-twitter" href="https://twitter.com/joplinapp" title="Joplin Twitter feed"><i class="fab fa-twitter"></i></a>
|
||||
<a class="social-link-mastodon" href="https://mastodon.social/@joplinapp" title="Joplin Mastodon feed"><i class="fab fa-mastodon"></i></a>
|
||||
<a class="social-link-patreon" href="https://www.patreon.com/joplin" title="Joplin Patreon"><i class="fab fa-patreon"></i></a>
|
||||
<a class="social-link-discord" href="https://discord.gg/VSj7AFHvpq" title="Joplin Discord chat"><i class="fab fa-discord"></i></a>
|
||||
<a class="social-link-reddit" href="https://www.reddit.com/r/joplinapp/" title="Joplin Subreddit"><i class="fab fa-reddit"></i></a>
|
||||
<a class="social-link-github" href="https://github.com/laurent22/joplin/" title="Joplin GitHub repository"><i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
@@ -1,3 +1,3 @@
|
||||
<a class="button-link btn-blue sponsor-button" href="{{baseUrl}}/donate">
|
||||
<i class="fas fa-heart heart-full"></i><i class="far fa-heart heart-line"></i> Support us
|
||||
<i class="fas fa-heart heart-full"></i><i class="far fa-heart heart-line"></i><span class="sponsor-button-label"> Support us</span>
|
||||
</a>
|
@@ -0,0 +1 @@
|
||||
<a href="https://twitter.com/joplinapp" title="Joplin Twitter feed" class="fw500"><i class="fab fa-twitter"></i></a>
|
@@ -42,13 +42,23 @@
|
||||
{{> plan}}
|
||||
{{/plans.pro}}
|
||||
|
||||
{{#plans.business}}
|
||||
{{#plans.teams}}
|
||||
{{> plan}}
|
||||
{{/plans.business}}
|
||||
{{/plans.teams}}
|
||||
|
||||
<p class="joplin-cloud-login-info">Already have a Joplin Cloud account? <a href="https://joplincloud.com">Login now</a></p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
<h1>Feature comparison</h1>
|
||||
<div class="joplin-cloud-feature-list">
|
||||
{{{featureListHtml}}}
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
{{{faqHtml}}}
|
||||
</div>
|
||||
|
11
BUILD.md
@@ -18,14 +18,15 @@ There are also a few forks of existing packages under the "fork-*" name.
|
||||
|
||||
## Required dependencies
|
||||
|
||||
- Install node 16+ - https://nodejs.org/en/
|
||||
- [Enable yarn](https://yarnpkg.com/getting-started/install): `corepack enable`
|
||||
- macOS: Install Cocoapods - `brew install cocoapods`
|
||||
- Windows: Install Windows Build Tools - `yarn install -g windows-build-tools --vs2015`
|
||||
- Install Node 16+. On Windows, also install the build tools - https://nodejs.org/en/
|
||||
- [Enable Yarn](https://yarnpkg.com/getting-started/install): `corepack enable`
|
||||
- macOS: Install Cocoapods - `brew install cocoapods`. Apple Silicon [may require libvips](https://github.com/laurent22/joplin/pull/5966#issuecomment-1007158597) - `brew install vips`.
|
||||
- Linux: Install dependencies - `sudo apt install build-essential libnss3 libsecret-1-dev python rsync`
|
||||
|
||||
## Building
|
||||
|
||||
Make sure the path to the project directory does not contain spaces or the build may fail.
|
||||
|
||||
Before doing anything else, from the root of the project, run:
|
||||
|
||||
yarn install
|
||||
@@ -60,7 +61,7 @@ Normally the **bundler** should start automatically with the application. If it
|
||||
## Building the clipper
|
||||
|
||||
cd packages/app-clipper/popup
|
||||
yarn run watch # To watch for changes
|
||||
npm run watch # To watch for changes
|
||||
|
||||
To test the extension please refer to the relevant pages for each browser: [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#Trying_it_out) / [Chrome](https://developer.chrome.com/docs/extensions/mv3/getstarted/). Please note that the extension in dev mode will only connect to a dev instance of the desktop app (and vice-versa).
|
||||
|
||||
|
@@ -31,58 +31,79 @@ Joplin is available in multiple languages thanks to the help of its users. You c
|
||||
|
||||
If you want to start contributing to the project's code, please follow these guidelines before creating a pull request:
|
||||
|
||||
- Explain WHY you want to add this change. Explain it inside the pull request and you may link to an issue for additional information, but the PR should gives a clear overview of why you want to add this.
|
||||
- Explain WHY you want to add this change. Explain it inside the pull request and you may link to an issue for additional information, but the PR should give a clear overview of why you want to add this.
|
||||
- Bug fixes are always welcome. Start by reviewing the [list of bugs](https://github.com/laurent22/joplin/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
|
||||
- A good way to easily start contributing is to pick and work on a [good first issue](https://github.com/laurent22/joplin/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). We try to make these issues as clear as possible and provide basic info on how the code should be changed, and if something is unclear feel free to ask for more information on the issue.
|
||||
- Before adding a new feature, ask about it in the [Github Issue Tracker](https://github.com/laurent22/joplin/issues?utf8=%E2%9C%93&q=is%3Aissue) or the [Joplin Forum](https://discourse.joplinapp.org/), or check if existing discussions exist to make sure the new functionality is desired.
|
||||
- **Changes that will consist in more than 50 lines of code should be discussed the [Joplin Forum](https://discourse.joplinapp.org/)**, so that you don't spend too much time implementing something that might not be accepted.
|
||||
- All the applications share the same backend (database, synchronisation, settings, models, business logic, etc.) so if you change something in the backend in one app, makes sure it still work in the other apps. Usually it does, but keep this in mind.
|
||||
- **Changes that will consist of more than 50 lines of code should be discussed on the [Joplin Forum](https://discourse.joplinapp.org/)**, so that you don't spend too much time implementing something that might not be accepted.
|
||||
- All the applications share the same backend (database, synchronisation, settings, models, business logic, etc.) so if you change something in the backend in one app, make sure it still works in the other apps. Usually it does, but keep this in mind.
|
||||
- Pull requests that make many changes using an automated tool, like for spell fixing, styling, etc. will not be accepted. An exception would be if the changes have been discussed in the forum and someone has agreed to review **and test** the pull request.
|
||||
- Pull requests that make address multiple issues will most likely stall and eventually be closed. This is because we might be fine with one of the changes but not with others and untangling that kind of pull request is too much hassle both for maintainers and the person who submitted it. So most of the time someone gives up and the PR gets closed. So please keep the pull request focused on one issue.
|
||||
- Pull requests that address multiple issues will most likely stall and eventually be closed. This is because we might be fine with one of the changes but not with others and untangling that kind of pull request is too much hassle both for maintainers and the person who submitted it. So most of the time someone gives up and the PR gets closed. So please keep the pull request focused on one issue.
|
||||
- **Do not mark your reviewer's comments as "resolved"**. If you do that, the comments will be hidden and the reviewer will not know what are the pending issues in the pull request. Only the reviewer should resolve the comments.
|
||||
|
||||
Building the apps is relatively easy - please [see the build instructions](https://github.com/laurent22/joplin/blob/dev/BUILD.md) for more details.
|
||||
|
||||
## Coding style
|
||||
|
||||
Coding style is enforced by a pre-commit hook that runs eslint. This hook is installed whenever running `yarn install` on any of the application directory. If for some reason the pre-commit hook didn't get installed, you can manually install it by running `yarn install` at the root of the repository.
|
||||
Please see [readme/coding_style.md](readme/coding_style.md).
|
||||
|
||||
For new React components, please use [React Hooks](https://reactjs.org/docs/hooks-intro.html). For new code in general, please use TypeScript. Even if you are modifying a file that was originally in JavaScript you should ideally convert it first to TypeScript before modifying it. Doing so is relatively easy and it helps maintain code quality.
|
||||
## GUI style
|
||||
|
||||
For changes made to the Desktop client that affect the user interface, refer to `packages/app-desktop/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
|
||||
For changes made to the Desktop and mobile clients that affect the user interface, refer to `packages/lib/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
|
||||
|
||||
## Automated tests
|
||||
|
||||
When submitting a pull request for a new feature or a bug fix, please add automated tests for your code whenever possible. Tests in Joplin are divided into **unit tests** and **feature tests**.
|
||||
When submitting a pull request for a new feature or a bug fix, please add automated tests. We use [Jest](https://jestjs.io/) as a testing framework so you will need to be familiar with it or go through their documentation.
|
||||
|
||||
* **Unit tests** are used to test models, services or utility classes - they are relatively low level. Unit tests should be prefixed with the type of class that is being tested - for example "models_Folder" or "services_SearchEngine".
|
||||
### Running the tests
|
||||
|
||||
* **Feature tests** on the other hand are to test higher level functionalities such as interactions with the GUI and how they affect the underlying model. Often these tests would dispatch Redux actions, and inspect how the application state has been changed. The feature tests should be prefixed with "feature_", for example "feature_TagList". There's a good explanation on what qualifies as a feature test in [this post](https://github.com/laurent22/joplin/pull/2819#issuecomment-603502230).
|
||||
|
||||
The tests are under packages/app-cli/tests. To get them running, you first need to build the CLI app:
|
||||
|
||||
```sh
|
||||
yarn install
|
||||
cd packages/app-cli
|
||||
```
|
||||
|
||||
To run all the test units:
|
||||
To run all the test units, run from the root:
|
||||
|
||||
```sh
|
||||
yarn test
|
||||
```
|
||||
|
||||
Or you can go inside a package folder, and run the tests from there. For example to run all the library tests, go in `packages/lib` and run `yarn test`
|
||||
|
||||
To run just one particular file:
|
||||
|
||||
```sh
|
||||
yarn test --filter=markdownUtils # Don't add the .js extension
|
||||
# Run all the tests in markdownUtils.test.ts
|
||||
yarn test markdownUtils
|
||||
```
|
||||
|
||||
To filter tests. For example, to run all the test units that contain "should handle conflict" in their description:
|
||||
To run only a particular test in a file:
|
||||
|
||||
```sh
|
||||
yarn test --filter="should handle conflict"
|
||||
# Run only the test described as "should handle conflict"
|
||||
# inside markdownUtils.test.ts:
|
||||
yarn test markdownUtils --filter="should handle conflict"
|
||||
```
|
||||
|
||||
### Adding a new test file
|
||||
|
||||
To add a test, simply create a new file with an extension `.test.ts` in the same directory. For example if you are working on the file `example.ts`, create a file `example.test.ts` for the unit tests. If this file already exist, simply add your tests directly to it.
|
||||
|
||||
### Setting the testing environment
|
||||
|
||||
Many utility functions are available under the package `@joplin/lib/testing/test-utils`. Have a look for example at [Note.test.ts](https://github.com/laurent22/joplin/blob/dev/packages/lib/models/Note.test.ts) to see how to setup test units with database support and synchroniser support. Note that this is not needed for all tests - if you just have a simple functions to test you won't need that extra setup.
|
||||
|
||||
### Testing React Hooks
|
||||
|
||||
To test React Hooks please use the package `@testing-library/react-hooks`. See [useLayoutItemSizes.test.ts](https://github.com/laurent22/joplin/blob/dev/packages/app-desktop/gui/ResizableLayout/utils/useLayoutItemSizes.test.ts) for an example.
|
||||
|
||||
### If it is not possible to add tests
|
||||
|
||||
More often than not, it is actually possible to add tests - just go back to your code and see if it can be refactored and certain functionalities moved to simple functions (with no dependencies). Once you have a simple function, you can easily add unit tests for it.
|
||||
|
||||
Additionally, if the unit tests are not sufficient, please provide a **manual testing plan**, which should include detailed steps on:
|
||||
|
||||
- How to test that your feature is working. Include at least 5 tests. Try to think of the possible inputs - if it's a list, how does it work with 0 elements, or 1, or 10, or 100,000. If it's a text input, how does it work with an empty string, or a very large string, etc. Basically don't just put one test that check the best case scenario.
|
||||
|
||||
- How to verify that related parts of the applications are not broken. For example if you changed the note loading logic, check that the toolbar is still working as expected (and not modifying the previously loaded note for example), check that switching from one note to another still works. Look at the note list and verify that the note title is updated there too, etc.
|
||||
|
||||
A reviewer should be able to run the app with your changes, then do the above steps to verify that everything's working as expected.
|
||||
|
||||
## About abandoned pull requests
|
||||
|
||||
It happens that a pull request is started but not finished and despite our attempts to contact the contributor, we don't hear from them again.
|
||||
|
@@ -1,88 +1,75 @@
|
||||
FROM node:16-bullseye
|
||||
# =============================================================================
|
||||
# Build stage
|
||||
# =============================================================================
|
||||
|
||||
FROM node:16-bullseye AS builder
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
python \
|
||||
python tini \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enables Yarn
|
||||
RUN corepack enable
|
||||
|
||||
RUN echo "Node: $(node --version)"
|
||||
RUN echo "Npm: $(npm --version)"
|
||||
RUN echo "Yarn: $(yarn --version)"
|
||||
WORKDIR /build
|
||||
|
||||
COPY .yarn/plugins ./.yarn/plugins
|
||||
COPY .yarn/releases ./.yarn/releases
|
||||
COPY package.json .
|
||||
COPY .yarnrc.yml .
|
||||
COPY yarn.lock .
|
||||
COPY gulpfile.js .
|
||||
COPY tsconfig.json .
|
||||
COPY packages/turndown ./packages/turndown
|
||||
COPY packages/turndown-plugin-gfm ./packages/turndown-plugin-gfm
|
||||
COPY packages/fork-htmlparser2 ./packages/fork-htmlparser2
|
||||
COPY packages/server/package*.json ./packages/server/
|
||||
COPY packages/fork-sax ./packages/fork-sax
|
||||
COPY packages/fork-uslug ./packages/fork-uslug
|
||||
COPY packages/htmlpack ./packages/htmlpack
|
||||
COPY packages/renderer ./packages/renderer
|
||||
COPY packages/tools ./packages/tools
|
||||
COPY packages/lib ./packages/lib
|
||||
COPY packages/server ./packages/server
|
||||
|
||||
# For some reason there's both a .yarn/cache and .yarn/berry/cache that are
|
||||
# being generated, and both have the same content. Not clear why it does this
|
||||
# but we can delete it anyway. We can delete the cache because we use
|
||||
# `nodeLinker: node-modules`. If we ever implement Zero Install, we'll need to
|
||||
# keep the cache.
|
||||
#
|
||||
# Note that `yarn install` ignores `NODE_ENV=production` and will install dev
|
||||
# dependencies too, but this is fine because we need them to build the app.
|
||||
|
||||
RUN BUILD_SEQUENCIAL=1 yarn install --inline-builds \
|
||||
&& yarn cache clean \
|
||||
&& rm -rf .yarn/berry
|
||||
|
||||
# =============================================================================
|
||||
# Final stage - we copy only the relevant files from the build stage and start
|
||||
# from a smaller base image.
|
||||
# =============================================================================
|
||||
|
||||
FROM node:16-bullseye-slim
|
||||
|
||||
ARG user=joplin
|
||||
|
||||
RUN useradd --create-home --shell /bin/bash $user
|
||||
|
||||
USER $user
|
||||
|
||||
ENV NODE_ENV development
|
||||
|
||||
WORKDIR /home/$user
|
||||
|
||||
RUN mkdir /home/$user/logs
|
||||
|
||||
# Install the root scripts but don't run postinstall (which would bootstrap
|
||||
# and build TypeScript files, but we don't have the TypeScript files at
|
||||
# this point)
|
||||
|
||||
COPY --chown=$user:$user package*.json ./
|
||||
COPY --chown=$user:$user .yarn ./.yarn
|
||||
COPY --chown=$user:$user .yarnrc.yml .
|
||||
COPY --chown=$user:$user yarn.lock .
|
||||
|
||||
RUN yarn install --inline-builds --mode=skip-build
|
||||
|
||||
# To take advantage of the Docker cache, we first copy all the package.json
|
||||
# and package-lock.json files, as they rarely change, and then bootstrap
|
||||
# all the packages.
|
||||
#
|
||||
# Note that bootstrapping the packages will run all the postinstall
|
||||
# scripts, which means that for packages that have such scripts, we need to
|
||||
# copy all the files.
|
||||
#
|
||||
# We can't run boostrap with "--ignore-scripts" because that would
|
||||
# prevent certain sub-packages, such as sqlite3, from being built
|
||||
|
||||
COPY --chown=$user:$user packages/fork-sax/package*.json ./packages/fork-sax/
|
||||
COPY --chown=$user:$user packages/fork-uslug/package*.json ./packages/fork-uslug/
|
||||
COPY --chown=$user:$user packages/htmlpack/package*.json ./packages/htmlpack/
|
||||
COPY --chown=$user:$user packages/renderer/package*.json ./packages/renderer/
|
||||
COPY --chown=$user:$user packages/tools/package*.json ./packages/tools/
|
||||
COPY --chown=$user:$user packages/lib/package*.json ./packages/lib/
|
||||
COPY --chown=$user:$user tsconfig.json .
|
||||
|
||||
# The following have postinstall scripts so we need to copy all the files.
|
||||
# Since they should rarely change this is not an issue
|
||||
|
||||
COPY --chown=$user:$user packages/turndown ./packages/turndown
|
||||
COPY --chown=$user:$user packages/turndown-plugin-gfm ./packages/turndown-plugin-gfm
|
||||
COPY --chown=$user:$user packages/fork-htmlparser2 ./packages/fork-htmlparser2
|
||||
COPY --chown=$user:$user packages/server/package*.json ./packages/server/
|
||||
|
||||
# Then bootstrap only, without compiling the TypeScript files
|
||||
|
||||
RUN yarn install --inline-builds --mode=skip-build
|
||||
|
||||
# Now copy the source files. Put lib and server last as they are more likely to change.
|
||||
|
||||
COPY --chown=$user:$user packages/fork-sax ./packages/fork-sax
|
||||
COPY --chown=$user:$user packages/fork-uslug ./packages/fork-uslug
|
||||
COPY --chown=$user:$user packages/htmlpack ./packages/htmlpack
|
||||
COPY --chown=$user:$user packages/renderer ./packages/renderer
|
||||
COPY --chown=$user:$user packages/tools ./packages/tools
|
||||
COPY --chown=$user:$user packages/lib ./packages/lib
|
||||
COPY --chown=$user:$user packages/server ./packages/server
|
||||
|
||||
# Finally build everything, in particular the TypeScript files.
|
||||
|
||||
RUN yarn run build
|
||||
COPY --chown=$user:$user --from=builder /build/packages /home/$user/packages
|
||||
COPY --chown=$user:$user --from=builder /usr/bin/tini /usr/local/bin/tini
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV RUNNING_IN_DOCKER=1
|
||||
EXPOSE ${APP_PORT}
|
||||
|
||||
CMD [ "yarn", "--prefix", "packages/server", "start" ]
|
||||
# Use Tini to start Joplin Server:
|
||||
# https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals
|
||||
WORKDIR /home/$user/packages/server
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
CMD ["node", "dist/app.js"]
|
||||
|
||||
# Build-time metadata
|
||||
# https://github.com/opencontainers/image-spec/blob/master/annotations.md
|
||||
|
@@ -219,6 +219,8 @@ then
|
||||
Type=Application
|
||||
Categories=Office;
|
||||
MimeType=x-scheme-handler/joplin;
|
||||
X-GNOME-SingleWindow=true // should be removed eventually as it was upstream to be an XDG specification
|
||||
SingleMainWindow=true
|
||||
EOF
|
||||
|
||||
# Update application icons
|
||||
|
15
LICENSE
@@ -1,15 +1,20 @@
|
||||
All code in this repository is licensed under the MIT License **unless a
|
||||
directory contains a LICENSE file**, in which case that LICENSE file applies to
|
||||
the code in that sub-directory.
|
||||
directory contains a LICENSE or LICENSE.md file**, in which case that file
|
||||
applies to the code in that sub-directory.
|
||||
|
||||
For example, packages/fork-sax contains a ISC LICENSE file, thus all code under
|
||||
the packages/fork-sax directory is licensed under ISC.
|
||||
For example, packages/server contains a LICENSE.md file, thus all code under the
|
||||
packages/server directory is licensed under that license.
|
||||
|
||||
For example, packages/app-cli does NOT contain a LICENSE file, thus all code
|
||||
under that directory is licensed under the default license, which is MIT.
|
||||
|
||||
* * *
|
||||
|
||||
Joplin® is a trademark of Cozic Ltd registered in the European Union, with
|
||||
filing number 018544315.
|
||||
|
||||
* * *
|
||||
|
||||
Logo and Icon License
|
||||
|
||||
The Joplin logos and icons are copyright (c) Laurent Cozic, all rights reserved,
|
||||
@@ -20,7 +25,7 @@ icons please contact the author in order to get a permission.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2021 Laurent Cozic
|
||||
Copyright (c) 2016-2022 Laurent Cozic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
171
README.md
@@ -4,13 +4,19 @@
|
||||
|
||||
* * *
|
||||
|
||||
🌞 Joplin participates in **Google Summer of Code 2022**! More info on [the announcement post](https://github.com/laurent22/joplin/blob/dev/readme/news/20220308-gsoc2022-start.md). 🌞
|
||||
|
||||
* * *
|
||||
|
||||
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
|
||||
|
||||
Notes exported from Evernote via .enex files [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
Notes exported from Evernote [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
|
||||
The notes can be [synchronised](#synchronisation) with various cloud services including [Nextcloud](https://nextcloud.com/), Dropbox, OneDrive, WebDAV or the file system (for example with a network directory). When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.
|
||||
The notes can be securely [synchronised](#synchronisation) using [end-to-end encryption](#encryption) with various cloud services including Nextcloud, Dropbox, OneDrive and [Joplin Cloud](https://joplinapp.org/plans/).
|
||||
|
||||
The application is available for Windows, Linux, macOS, Android and iOS (the terminal app also works on FreeBSD). A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
|
||||
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
|
||||
|
||||
The application is available for Windows, Linux, macOS, Android and iOS. A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
|
||||
|
||||
<div class="top-screenshot"><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/home-top-img.png" style="max-width: 100%; max-height: 35em;"></div>
|
||||
|
||||
@@ -22,11 +28,11 @@ Three types of applications are available: for **desktop** (Windows, macOS and L
|
||||
|
||||
Operating System | Download
|
||||
---|---
|
||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v2.6.10/Joplin-Setup-2.6.10.exe'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v2.6.10/Joplin-2.6.10.dmg'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.6.10/Joplin-2.6.10.AppImage'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
|
||||
Windows (32 and 64-bit) | <a href='https://github.com/laurent22/joplin/releases/download/v2.8.8/Joplin-Setup-2.8.8.exe'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v2.8.8/Joplin-2.8.8.dmg'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.8.8/Joplin-2.8.8.AppImage'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
|
||||
|
||||
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.6.10/JoplinPortable.exe'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||
**On Windows**, you may also use the <a href='https://github.com/laurent22/joplin/releases/download/v2.8.8/JoplinPortable.exe'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
|
||||
|
||||
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
|
||||
|
||||
@@ -36,7 +42,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/v2.6.10/J
|
||||
|
||||
Operating System | Download | Alt. Download
|
||||
---|---|---
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.6.9/joplin-v2.6.9.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.6.9/joplin-v2.6.9-32bit.apk)
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.8.1/joplin-v2.8.1.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.8.1/joplin-v2.8.1-32bit.apk)
|
||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
|
||||
|
||||
## Terminal application
|
||||
@@ -49,23 +55,22 @@ To start it, type `joplin`.
|
||||
|
||||
For usage information, please refer to the full [Joplin Terminal Application Documentation](https://joplinapp.org/terminal/).
|
||||
|
||||
### Unsupported methods
|
||||
|
||||
There are other ways to install the terminal application. However, they are not supported and problems must be reported to the upstream projects.
|
||||
|
||||
Operating system | Method
|
||||
-----------------|----------------
|
||||
Arch Linux | An Arch Linux package is available [here](https://aur.archlinux.org/packages/joplin/). To install it, use an AUR wrapper such as yay: `yay -S joplin`. Both the CLI tool (type `joplin`) and desktop app (type `joplin-desktop`) are packaged. You can also install a compiled version with the [chaotic-aur](https://wiki.archlinux.org/index.php/Unofficial_user_repositories#chaotic-aur) repository. For support, please go to the [GitHub repo](https://github.com/masterkorp/joplin-pkgbuild). If you are interested in [pre-release](https://joplinapp.org/prereleases/) you have [joplin-beta](https://aur.archlinux.org/packages/joplin-beta).
|
||||
Flatpak | A Flatpak is available on [Flathub](https://flathub.org/apps/details/net.cozic.joplin_desktop). To install it, run `flatpak install net.cozic.joplin_desktop` after [setting up Flathub](https://flatpak.org/setup/). GUI software managers on most distros support Flatpak installation.
|
||||
|
||||
## Web Clipper
|
||||
|
||||
The Web Clipper is a browser extension that allows you to save web pages and screenshots from your browser. For more information on how to install and use it, see the [Web Clipper Help Page](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md).
|
||||
|
||||
## Unofficial Alternative Distributions
|
||||
|
||||
There are a number of unofficial alternative Joplin distributions. If you do not want to or cannot use appimages or any of the other officially supported releases then you may wish to consider these.
|
||||
|
||||
However these come with a caveat in that they are not officially supported so certain issues may not be supportable by the main project. Rather support requests, bug reports and general advice would need to go to the maintainers of these distributions.
|
||||
|
||||
A community maintained list of these distributions can be found here: [Unofficial Joplin distributions](https://discourse.joplinapp.org/t/unofficial-alternative-joplin-distributions/23703)
|
||||
|
||||
# Sponsors
|
||||
|
||||
<!-- SPONSORS-ORG -->
|
||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a>
|
||||
<a href="https://seirei.ne.jp"><img title="Serei Network" width="256" src="https://joplinapp.org/images/sponsors/SeireiNetwork.png"/></a> <a href="https://usrigging.com/"><img title="U.S. Ringing Supply" width="256" src="https://joplinapp.org/images/sponsors/RingingSupply.svg"/></a> <a href="https://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-github&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://residence-greece.com/"><img title="Greece Golden Visa" width="256" src="https://joplinapp.org/images/sponsors/ResidenceGreece.jpg"/></a>
|
||||
<!-- SPONSORS-ORG -->
|
||||
|
||||
* * *
|
||||
@@ -75,9 +80,10 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/215668?s=96&v=4"/></br>[avanderberg](https://github.com/avanderberg) | <img width="50" src="https://avatars2.githubusercontent.com/u/3061769?s=96&v=4"/></br>[c-nagy](https://github.com/c-nagy) | <img width="50" src="https://avatars2.githubusercontent.com/u/70780798?s=96&v=4"/></br>[cabottech](https://github.com/cabottech) | <img width="50" src="https://avatars2.githubusercontent.com/u/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/4862947?s=96&v=4"/></br>[chrootlogin](https://github.com/chrootlogin) | <img width="50" src="https://avatars2.githubusercontent.com/u/82579431?s=96&v=4"/></br>[clmntsl](https://github.com/clmntsl) | <img width="50" src="https://avatars2.githubusercontent.com/u/808091?s=96&v=4"/></br>[cuongtransc](https://github.com/cuongtransc) | <img width="50" src="https://avatars2.githubusercontent.com/u/1307332?s=96&v=4"/></br>[dbrandonjohnson](https://github.com/dbrandonjohnson) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[fbloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/38898566?s=96&v=4"/></br>[h4sh5](https://github.com/h4sh5) | <img width="50" src="https://avatars2.githubusercontent.com/u/3266447?s=96&v=4"/></br>[iamwillbar](https://github.com/iamwillbar) | <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) | <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) | <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1439535?s=96&v=4"/></br>[fbloise](https://github.com/fbloise) | <img width="50" src="https://avatars2.githubusercontent.com/u/49439044?s=96&v=4"/></br>[fourstepper](https://github.com/fourstepper) | <img width="50" src="https://avatars2.githubusercontent.com/u/38898566?s=96&v=4"/></br>[h4sh5](https://github.com/h4sh5) | <img width="50" src="https://avatars2.githubusercontent.com/u/3266447?s=96&v=4"/></br>[iamwillbar](https://github.com/iamwillbar) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/37297218?s=96&v=4"/></br>[Jesssullivan](https://github.com/Jesssullivan) | <img width="50" src="https://avatars2.githubusercontent.com/u/1248504?s=96&v=4"/></br>[joesfer](https://github.com/joesfer) | <img width="50" src="https://avatars2.githubusercontent.com/u/5588131?s=96&v=4"/></br>[kianenigma](https://github.com/kianenigma) | <img width="50" src="https://avatars2.githubusercontent.com/u/24908652?s=96&v=4"/></br>[konishi-t](https://github.com/konishi-t) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/42319182?s=96&v=4"/></br>[marcdw1289](https://github.com/marcdw1289) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/29300939?s=96&v=4"/></br>[mcejp](https://github.com/mcejp) | <img width="50" src="https://avatars2.githubusercontent.com/u/1168659?s=96&v=4"/></br>[nicholashead](https://github.com/nicholashead) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/5782817?s=96&v=4"/></br>[piccobit](https://github.com/piccobit) | <img width="50" src="https://avatars2.githubusercontent.com/u/77214738?s=96&v=4"/></br>[Polymathic-Company](https://github.com/Polymathic-Company) | <img width="50" src="https://avatars2.githubusercontent.com/u/47742?s=96&v=4"/></br>[ravenscroftj](https://github.com/ravenscroftj) | <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/73081837?s=96&v=4"/></br>[thismarty](https://github.com/thismarty) | <img width="50" src="https://avatars2.githubusercontent.com/u/15859362?s=96&v=4"/></br>[thomasbroussard](https://github.com/thomasbroussard) | | |
|
||||
<!-- SPONSORS-GITHUB -->
|
||||
|
||||
@@ -125,25 +131,30 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
- Development
|
||||
|
||||
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
|
||||
- [End-to-end encryption spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
||||
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
|
||||
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
|
||||
- [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
|
||||
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
|
||||
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
|
||||
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
|
||||
- [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md)
|
||||
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
|
||||
- [E2EE: Workflow](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee/workflow.md)
|
||||
- [Server: File URL Format](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_file_url_format.md)
|
||||
- [Server: Delta Sync](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_delta_sync.md)
|
||||
- [Server: Sharing](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_sharing.md)
|
||||
|
||||
- Google Summer of Code 2021
|
||||
- Google Summer of Code 2022
|
||||
|
||||
- [Google Summer of Code 2021](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/index.md)
|
||||
- [How to submit a GSoC pull request](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/pull_request_guidelines.md)
|
||||
- [Project Ideas](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2021/ideas.md)
|
||||
- [Google Summer of Code 2022](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/index.md)
|
||||
- [How to submit a GSoC pull request](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/pull_request_guidelines.md)
|
||||
- [Project Ideas](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/ideas.md)
|
||||
|
||||
- About
|
||||
|
||||
- [Changelog (Desktop App)](https://github.com/laurent22/joplin/blob/dev/readme/changelog.md)
|
||||
- [Changelog (Android)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md)
|
||||
- [Changelog (iOS)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_ios.md)
|
||||
- [Changelog (CLI App)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_cli.md)
|
||||
- [Changelog (Server)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_server.md)
|
||||
- [Stats](https://github.com/laurent22/joplin/blob/dev/readme/stats.md)
|
||||
@@ -176,6 +187,7 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
|
||||
- Custom CSS support for customisation of both the rendered markdown and overall user interface.
|
||||
- Customisable layout allows toggling, movement and sizing of various elements.
|
||||
- Keyboard shortcuts are editable and allow binding of most Joplin commands with export/import functionality.
|
||||
- Multiple profile support.
|
||||
|
||||
# Importing
|
||||
|
||||
@@ -300,10 +312,10 @@ To add a **Bucket Policy** from the AWS S3 Web Console, navigate to the **Permis
|
||||
{
|
||||
"Sid": "VisualEditor0",
|
||||
"Effect": "Allow",
|
||||
"Principal": "*",
|
||||
"Action": [
|
||||
"s3:ListBucket",
|
||||
"s3:GetBucketLocation",
|
||||
"s3:GetObject",
|
||||
"s3:DeleteObject",
|
||||
"s3:DeleteObjectVersion",
|
||||
"s3:PutObject"
|
||||
@@ -408,9 +420,10 @@ Important: userstyle.css and userchrome.css are provided for your convenience, b
|
||||
|
||||
# Plugins
|
||||
|
||||
The **desktop app** has the ability to extend beyond its standard functionality by the way of plugins. These plugins adhere to the Joplin plugin API and can be installed & configured within the application via the `Plugins` page in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md). This menu allows the manual installation of the plugin using the single 'Joplin Plugin Archive' (*.jpl) file. Once the application is reloaded the plugins will appear within the plugins menu where they can be toggled on/off or removed entirely.
|
||||
The **desktop app** has the ability to extend beyond its standard functionality by the way of plugins. These plugins adhere to the Joplin [plugin API](https://joplinapp.org/api/references/plugin_api/classes/joplin.html) and can be installed & configured within the application via the `Plugins` page of the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md).
|
||||
|
||||
Plugins are currently maintained by the community in the [Joplin Discourse 'plugins' category](https://discourse.joplinapp.org/c/plugins/18).
|
||||
From this menu you can search for plugins uploaded to the [Joplin plugins](https://github.com/joplin/plugins) repository as well as manual installation of plugins using a 'Joplin Plugin Archive' (*.jpl) file.
|
||||
Once the application is reloaded the plugins will appear within the plugins menu where they can be toggled on/off or removed entirely.
|
||||
|
||||
For more information see [Plugins](https://github.com/laurent22/joplin/blob/dev/readme/plugins.md)
|
||||
|
||||
@@ -440,7 +453,7 @@ You can also use search filters to further restrict the search.
|
||||
|
||||
| Operator | Description | Example |
|
||||
| --- | --- | --- |
|
||||
|**-**|If placed before a text term, it excludes the notes that contain that term. You can also place it before a filter to negate it. |`-spam` searches for all notes without the word `spam`.<br>`office -trash` searches for all notes with the word`office` and without the word `trash`.|
|
||||
|**-**|If placed before a text term, it excludes the notes that contain that term. You can also place it before a filter to negate it. |`-spam` searches for all notes without the word `spam`.<br>`office -trash` searches for all notes with the word `office` and without the word `trash`.|
|
||||
|**any:**|Return notes that satisfy any/all of the required conditions. `any:0` is the default, which means all conditions must be satisfied.|`any:1 cat dog` will return notes that have the word `cat` or `dog`.<br>`any:0 cat dog` will return notes with both the words `cat` and `dog`. |
|
||||
| **title:** <br> **body:**|Restrict your search to just the title or the body field.|`title:"hello world"` searches for notes whose title contains `hello` and `world`.<br>`title:hello -body:world` searches for notes whose title contains `hello` and body does not contain `world`.
|
||||
| **tag:** |Restrict the search to the notes with the specified tags.|`tag:office` searches for all notes having tag office.<br>`tag:office tag:important` searches for all notes having both office and important tags.<br>`tag:office -tag:spam` searches for notes having tag `office` which do not have tag `spam`.<br>`any:1 tag:office tag:spam` searches for notes having tag `office` or tag `spam`.<br>`tag:be*ful` does a search with wildcards.<br>`tag:*` returns all notes with tags.<br>`-tag:*` returns all notes without tags.|
|
||||
@@ -472,24 +485,16 @@ Notes are sorted by "relevance". Currently it means the notes that contain the r
|
||||
|
||||
In the desktop application, press <kbd>Ctrl+P</kbd> or <kbd>Cmd+P</kbd> and type a note title or part of its content to jump to it. Or type <kbd>#</kbd> followed by a tag name, or <kbd>@</kbd> followed by a notebook name.
|
||||
|
||||
# Privacy
|
||||
# Multiple profile support
|
||||
|
||||
To create a new profile, open File > Switch profile and select Create new profile, enter the profile name and press OK. The app will automatically switch to this new profile, which you can now configure.
|
||||
|
||||
Joplin values your privacy and security by giving you complete control over your information and digital footprint.
|
||||
To switch back to the previous profile, again open File > Switch profile and select Default.
|
||||
|
||||
Joplin applications do not send any data to any service without your authorisation. Any data that Joplin saves, such as notes or images, are saved to your own device and you are free to delete this data at any time.
|
||||
|
||||
Joplin has many modern features, some of which use third-party services. You can disable any or all of these features in the application settings. These features are:
|
||||
|
||||
|Feature | Description | Default|
|
||||
|--------|-------------|--------|
|
||||
|Auto-update|Joplin periodically connects to GitHub to check for new releases.|Enabled|
|
||||
|Geo-location|Joplin saves geo-location information in note properties when you create a note.|Enabled|
|
||||
|Synchronisation|Joplin supports synchronisation of your notes across multiple devices. If you choose to synchronise with a third-party, such as OneDrive, the notes will be sent to your OneDrive account, in which case the third-party privacy policy applies.|Disabled|
|
||||
|
||||
Joplin is developed as an open-source application and the source code is freely available online to inspect.
|
||||
|
||||
For any question about Joplin privacy, please leave a message on the [Joplin Forum](https://discourse.joplinapp.org/).
|
||||
Note that profiles all share certain settings, such as language, font size, theme, etc. This is done so that you don't have reconfigure every details when switching profiles. Other settings such as sync configuration is per profile.
|
||||
|
||||
The feature is available on desktop only for now, and should be ported to mobile relatively soon.
|
||||
|
||||
# Donations
|
||||
|
||||
Donations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.
|
||||
@@ -530,47 +535,47 @@ Current translations:
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
| Language | Po File | Last translator | Percent done
|
||||
---|---|---|---|---
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 27%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 67%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 53%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:s.robin@tutanota.de) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 51%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 25%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 64%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 50%
|
||||
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | [Michal Stanke](mailto:michal@stanke.cz) | 86%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [MrKanister](mailto:pueblos_spatulas@aleeas.com) | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 49%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 99%
|
||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 30%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Mora](mailto:francisco.m.collao@gmail.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 28%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 34%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 92%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 78%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MetBril](mailto:metbril@users.noreply.github.com) | 85%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | Alexander Dawson | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 64%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 84%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Felipe Viggiano](mailto:felipeviggiano@gmail.com) | 94%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 84%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 59%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 43%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vi.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 83%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 93%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 76%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [南宫小骏](mailto:jackytsu@vip.qq.com) | 97%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [SiderealArt](mailto:nelson22768384@gmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 32%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [eresytter](mailto:42007357+eresytter@users.noreply.github.com) | 88%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Albano Battistella](mailto:albano_battistella@hotmail.com) | 86%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 86%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 88%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 62%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [konhi](mailto:hello.konhi@gmail.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Renato Nunes Bastos](mailto:rnbastos@gmail.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 81%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 57%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 90%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 41%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 96%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 80%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Sergey Segeda](mailto:thesermanarm@gmail.com) | 89%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 72%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [horaceyoung](mailto:paventyang@gmail.com) | 98%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [SiderealArt](mailto:nelson22768384@gmail.com) | 87%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 100%
|
||||
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 86%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Contributors
|
||||
|
954
cspell.json
Normal file
@@ -0,0 +1,954 @@
|
||||
{
|
||||
"version": "0.2",
|
||||
"language": "en_GB",
|
||||
"ignorePaths": [
|
||||
"**/*.min.*",
|
||||
"**/*.svg",
|
||||
"/_mydocs",
|
||||
"/_releases",
|
||||
"/.git",
|
||||
"/.yarn",
|
||||
"/Assets",
|
||||
"/packages/app-cli/app/fuzzing.js",
|
||||
"/packages/app-cli/build",
|
||||
"/packages/app-cli/tests/support",
|
||||
"/packages/app-cli/tests/test data",
|
||||
"/packages/app-cli/tests/tmp",
|
||||
"/packages/app-clipper/content_scripts/JSDOMParser.js",
|
||||
"/packages/app-clipper/content_scripts/Readability-readerable.js",
|
||||
"/packages/app-clipper/content_scripts/Readability.js",
|
||||
"/packages/app-clipper/popup/build/js/0.chunk.js",
|
||||
"/packages/app-clipper/popup/build/js/bundle.js",
|
||||
"/packages/app-clipper/popup/build/js/main.chunk.js",
|
||||
"/packages/app-clipper/popup/build/js/main.chunk.js",
|
||||
"/packages/app-clipper/popup/config",
|
||||
"/packages/app-desktop/vendor/",
|
||||
"/packages/app-mobile/pluginAssets",
|
||||
"/packages/fork-sax/examples",
|
||||
"/packages/fork-sax/lib/sax.js",
|
||||
"/packages/fork-sax/test",
|
||||
"/packages/fork-uslug",
|
||||
"/packages/lib/locales",
|
||||
"/packages/lib/mime-utils-types.js",
|
||||
"/packages/lib/parameters.js",
|
||||
"/packages/lib/plugin_types",
|
||||
"/packages/lib/resourceUtils.js",
|
||||
"/packages/lib/services/joplinServer/personalizedUserContentBaseUrl.ts",
|
||||
"/packages/lib/vendor",
|
||||
"/packages/lib/welcomeAssets.js",
|
||||
"/packages/turndown-plugin-gfm/config",
|
||||
"/packages/turndown/config",
|
||||
"node_modules"
|
||||
],
|
||||
"words": [
|
||||
"aàáâãäåāą",
|
||||
"AÀÁÂÃÄÅĀĄ",
|
||||
"abbrev",
|
||||
"ABCDEFGHIJ",
|
||||
"Abhishek",
|
||||
"Abkhazian",
|
||||
"accel",
|
||||
"accum",
|
||||
"actualkeyword",
|
||||
"adata",
|
||||
"advlist",
|
||||
"AGSFE",
|
||||
"Aland",
|
||||
"Åland",
|
||||
"alertbanner",
|
||||
"Allaire",
|
||||
"alse",
|
||||
"altool",
|
||||
"aman",
|
||||
"ambrt",
|
||||
"Amharic",
|
||||
"amothc",
|
||||
"andrejilderda",
|
||||
"anki",
|
||||
"Antarctique",
|
||||
"antarctiques",
|
||||
"Antártico",
|
||||
"anymore",
|
||||
"apidoc",
|
||||
"appiconset",
|
||||
"applewebkit",
|
||||
"approot",
|
||||
"arableague",
|
||||
"Aragonés",
|
||||
"ARITIM",
|
||||
"armeabi",
|
||||
"asterix",
|
||||
"atest",
|
||||
"atestb",
|
||||
"attribname",
|
||||
"attribvalue",
|
||||
"authcode",
|
||||
"autocompleteitem",
|
||||
"autocompleter",
|
||||
"Autocompleter",
|
||||
"AUTOEXEC",
|
||||
"autohide",
|
||||
"Avenir",
|
||||
"Ayiti",
|
||||
"azamah",
|
||||
"Azərbaycan",
|
||||
"backoff",
|
||||
"Bangla",
|
||||
"Bêafrîka",
|
||||
"beforeinput",
|
||||
"België",
|
||||
"Belgien",
|
||||
"Belgique",
|
||||
"Bénin",
|
||||
"Bhutani",
|
||||
"bibtex",
|
||||
"Bihari",
|
||||
"Bislama",
|
||||
"blabla",
|
||||
"blablablabla",
|
||||
"boohay",
|
||||
"Bosna",
|
||||
"Bouvet",
|
||||
"Bouvetøya",
|
||||
"browserslist",
|
||||
"bthqu",
|
||||
"btns",
|
||||
"Bulibiya",
|
||||
"bullist",
|
||||
"bulma",
|
||||
"Byelorussian",
|
||||
"calebjohn",
|
||||
"Calédonie",
|
||||
"Caligraphic",
|
||||
"callsites",
|
||||
"Cameroun",
|
||||
"cantdothat",
|
||||
"Capslock",
|
||||
"cardcontainer",
|
||||
"cardimage",
|
||||
"cardmenuitem",
|
||||
"cardtext",
|
||||
"Caribisch",
|
||||
"CAUTOEXEC",
|
||||
"cçćč",
|
||||
"CÇĆČ",
|
||||
"cdataend",
|
||||
"cdatastart",
|
||||
"cdot",
|
||||
"ceaf",
|
||||
"centrafricaine",
|
||||
"Centrafrican",
|
||||
"Česká",
|
||||
"changedtitle",
|
||||
"charcodes",
|
||||
"checkboxclick",
|
||||
"checkmark",
|
||||
"chemfive",
|
||||
"choiceitem",
|
||||
"chromedriver",
|
||||
"chromeframe",
|
||||
"chromeos",
|
||||
"Città",
|
||||
"Cmds",
|
||||
"codepoint",
|
||||
"colorinput",
|
||||
"colorpicker",
|
||||
"colorswatch",
|
||||
"colspan",
|
||||
"committerdate",
|
||||
"commmmmand",
|
||||
"commonmark",
|
||||
"COMMONMARK",
|
||||
"Comores",
|
||||
"compositionend",
|
||||
"compositionstart",
|
||||
"compositionupdate",
|
||||
"conflicter",
|
||||
"contenteditable",
|
||||
"contextform",
|
||||
"contextformbutton",
|
||||
"contextformtogglebutton",
|
||||
"contextkey",
|
||||
"contexttoolbar",
|
||||
"continuelist",
|
||||
"Contrl",
|
||||
"Conv",
|
||||
"convo",
|
||||
"copytags",
|
||||
"cozic",
|
||||
"Cozic",
|
||||
"createdb",
|
||||
"Creds",
|
||||
"Crna",
|
||||
"cronspec",
|
||||
"cros",
|
||||
"crypted",
|
||||
"Curaçao",
|
||||
"curso",
|
||||
"customeditor",
|
||||
"customkeymap",
|
||||
"cyingfan",
|
||||
"d'Ivoire",
|
||||
"Danmark",
|
||||
"Dansk",
|
||||
"dataimg",
|
||||
"datauri",
|
||||
"Datauri",
|
||||
"datetime",
|
||||
"Datetime",
|
||||
"davris",
|
||||
"dbuuid",
|
||||
"DDTHH",
|
||||
"deflist",
|
||||
"deinit",
|
||||
"Démocratique",
|
||||
"deselector",
|
||||
"deuxième",
|
||||
"dflt",
|
||||
"dialogbox",
|
||||
"dialogs",
|
||||
"Dialogs",
|
||||
"DIALOGS",
|
||||
"Distill",
|
||||
"dists",
|
||||
"docid",
|
||||
"docsize",
|
||||
"doctypes",
|
||||
"doesnotwork",
|
||||
"doesntexist",
|
||||
"doesntlookright",
|
||||
"domelementtype",
|
||||
"domhandler",
|
||||
"Dominicana",
|
||||
"domutils",
|
||||
"DONATELINKS",
|
||||
"downarrow",
|
||||
"dragdrop",
|
||||
"draggesture",
|
||||
"dünn",
|
||||
"dylib",
|
||||
"dynamiclib",
|
||||
"ecuatorial",
|
||||
"eèéêëěēę",
|
||||
"EÈÉÊËĚĒĘ",
|
||||
"Eesti",
|
||||
"effet",
|
||||
"efgh",
|
||||
"égalité",
|
||||
"Éire",
|
||||
"elem",
|
||||
"elementpath",
|
||||
"elems",
|
||||
"ellipsize",
|
||||
"ELOCKED",
|
||||
"encryptable",
|
||||
"endregion",
|
||||
"enex",
|
||||
"Enex",
|
||||
"ENEX",
|
||||
"enumber",
|
||||
"eqeqeq",
|
||||
"équatoriale",
|
||||
"Erro",
|
||||
"errorish",
|
||||
"escapeplus",
|
||||
"eslintignore",
|
||||
"España",
|
||||
"étiquette",
|
||||
"EUNSPECIFIED",
|
||||
"eventname",
|
||||
"evermeet",
|
||||
"evernote",
|
||||
"Evernote",
|
||||
"execa",
|
||||
"expando",
|
||||
"expirable",
|
||||
"Expirable",
|
||||
"expval",
|
||||
"Færøerne",
|
||||
"Fahrräder",
|
||||
"FAILSAFE",
|
||||
"fallbacks",
|
||||
"fancymenuitem",
|
||||
"fancytype",
|
||||
"favorites",
|
||||
"Fiber",
|
||||
"filepicker",
|
||||
"folderid",
|
||||
"foldl",
|
||||
"fontawesome",
|
||||
"fontface",
|
||||
"forall",
|
||||
"forcewake",
|
||||
"Føroyar",
|
||||
"fortawesome",
|
||||
"française",
|
||||
"françaises",
|
||||
"Gabuutih",
|
||||
"gedit",
|
||||
"geoip",
|
||||
"Geoip",
|
||||
"geoloc",
|
||||
"geoplugin",
|
||||
"getlastmodified",
|
||||
"gettext",
|
||||
"githubusercontent",
|
||||
"Gora",
|
||||
"gotchas",
|
||||
"gradlew",
|
||||
"Grønland",
|
||||
"grouptoolbarbutton",
|
||||
"Gruber",
|
||||
"gsoc",
|
||||
"gttest",
|
||||
"Guåhån",
|
||||
"guarentee",
|
||||
"guarentees",
|
||||
"Guiena",
|
||||
"Guiné",
|
||||
"Guinée",
|
||||
"gulpfile",
|
||||
"Guyane",
|
||||
"gvim",
|
||||
"Haïti",
|
||||
"hanlder",
|
||||
"Hausa",
|
||||
"headerless",
|
||||
"Heisenbug",
|
||||
"Hercegovina",
|
||||
"hift",
|
||||
"highjack",
|
||||
"highlited",
|
||||
"historyhas",
|
||||
"HMRKG",
|
||||
"hoge",
|
||||
"homenote",
|
||||
"hotfolder",
|
||||
"Howver",
|
||||
"hpagent",
|
||||
"Hrvatska",
|
||||
"htmlentities",
|
||||
"htmlfile",
|
||||
"htmlpack",
|
||||
"htmlpanel",
|
||||
"ʻĀirani",
|
||||
"icns",
|
||||
"iconset",
|
||||
"iconutil",
|
||||
"Iforgot",
|
||||
"iframes",
|
||||
"ihack",
|
||||
"iife",
|
||||
"iìíîïī",
|
||||
"IÌÍÎÏĪ",
|
||||
"ijkl",
|
||||
"imagelink",
|
||||
"imagetools",
|
||||
"immer",
|
||||
"iname",
|
||||
"Incl",
|
||||
"infint",
|
||||
"inflim",
|
||||
"infty",
|
||||
"inputi",
|
||||
"inserttable",
|
||||
"Interlingue",
|
||||
"Interp",
|
||||
"interupting",
|
||||
"Inteval",
|
||||
"Inuktitut",
|
||||
"Inupiak",
|
||||
"Invididual",
|
||||
"IOERR",
|
||||
"Ionicons",
|
||||
"IPHONEOS",
|
||||
"ipify",
|
||||
"ipwhois",
|
||||
"iscompleted",
|
||||
"Ísland",
|
||||
"Italiano",
|
||||
"Itoophiyaa",
|
||||
"itsgone",
|
||||
"itunes",
|
||||
"Jabuuti",
|
||||
"jackgruber",
|
||||
"joeattardi",
|
||||
"jopext",
|
||||
"joplinapp",
|
||||
"JOPLINAPP",
|
||||
"joplincloud",
|
||||
"joplindev",
|
||||
"JOPLINMOD",
|
||||
"joplintest",
|
||||
"jsbundles",
|
||||
"justtesting",
|
||||
"Kalaallit",
|
||||
"kalba",
|
||||
"kanban",
|
||||
"Kashmiri",
|
||||
"katex",
|
||||
"keychain",
|
||||
"keycodes",
|
||||
"keymaps",
|
||||
"keytar",
|
||||
"Kibris",
|
||||
"Kinyarwanda",
|
||||
"Kirundi",
|
||||
"Ködörösêse",
|
||||
"Komori",
|
||||
"Kpck",
|
||||
"Kūki",
|
||||
"Laothian",
|
||||
"lastmod",
|
||||
"Latvija",
|
||||
"lcov",
|
||||
"leaft",
|
||||
"leftarrow",
|
||||
"leftequilibrium",
|
||||
"leftrightarrow",
|
||||
"Lettish",
|
||||
"Lëtzebuerg",
|
||||
"Levithan",
|
||||
"Liban",
|
||||
"libz",
|
||||
"Lietuva",
|
||||
"Lietuvių",
|
||||
"lineheight",
|
||||
"Lingala",
|
||||
"linkg",
|
||||
"linkurl",
|
||||
"listbox",
|
||||
"listfile",
|
||||
"listpreview",
|
||||
"loglevel",
|
||||
"longclick",
|
||||
"longpress",
|
||||
"longpresscancel",
|
||||
"looooooong",
|
||||
"ltrim",
|
||||
"Luxemburg",
|
||||
"Maarten",
|
||||
"Madagasikara",
|
||||
"Magyarország",
|
||||
"majax",
|
||||
"Mardown",
|
||||
"markdowncalc",
|
||||
"Maroc",
|
||||
"MASTERKEY",
|
||||
"matchinfo",
|
||||
"mathchoice",
|
||||
"mathjax",
|
||||
"Mathjax",
|
||||
"MATHJAX",
|
||||
"mathllap",
|
||||
"mathml",
|
||||
"mathrlap",
|
||||
"mathrm",
|
||||
"Mauritanie",
|
||||
"Maxiumm",
|
||||
"Mayen",
|
||||
"mchem",
|
||||
"mechanim",
|
||||
"mediumtext",
|
||||
"menubutton",
|
||||
"mergeff",
|
||||
"Metadatas",
|
||||
"México",
|
||||
"mhchem",
|
||||
"middlewares",
|
||||
"migth",
|
||||
"mkbook",
|
||||
"MKCOL",
|
||||
"mkdirp",
|
||||
"mknote",
|
||||
"mktodo",
|
||||
"MMYY",
|
||||
"modifié",
|
||||
"monokai",
|
||||
"MONOSPACE",
|
||||
"msgctxt",
|
||||
"msgfmt",
|
||||
"msgmerge",
|
||||
"msgstr",
|
||||
"msleep",
|
||||
"mtext",
|
||||
"mult",
|
||||
"multicursor",
|
||||
"multimarkdown",
|
||||
"multimd",
|
||||
"multistatus",
|
||||
"multitable",
|
||||
"mybucket",
|
||||
"mydir",
|
||||
"myfile",
|
||||
"mynote",
|
||||
"myplugin",
|
||||
"mytag",
|
||||
"mytaga",
|
||||
"mytagb",
|
||||
"mytagc",
|
||||
"mytagd",
|
||||
"mytest",
|
||||
"mytoken",
|
||||
"myvalue",
|
||||
"nanoid",
|
||||
"Neaus",
|
||||
"Nederlands",
|
||||
"nestedmenuitem",
|
||||
"newone",
|
||||
"Nextcloud",
|
||||
"njstrace",
|
||||
"nñňń",
|
||||
"NÑŇŃ",
|
||||
"NOCASE",
|
||||
"nodechange",
|
||||
"nodir",
|
||||
"noexpand",
|
||||
"nojs",
|
||||
"nolongershared",
|
||||
"nonlatin",
|
||||
"NONLATIN",
|
||||
"Noreg",
|
||||
"Norge",
|
||||
"nospecialcharacters",
|
||||
"notanumber",
|
||||
"notarization",
|
||||
"notetags",
|
||||
"Notif",
|
||||
"notindexed",
|
||||
"notthere",
|
||||
"nounce",
|
||||
"Nounce",
|
||||
"Nounces",
|
||||
"npmignore",
|
||||
"numadd",
|
||||
"numbersareok",
|
||||
"numdec",
|
||||
"numdiv",
|
||||
"numlist",
|
||||
"Numlock",
|
||||
"nummult",
|
||||
"numsub",
|
||||
"Nunaat",
|
||||
"obelix",
|
||||
"odata",
|
||||
"ohno",
|
||||
"OHNO",
|
||||
"oldppk",
|
||||
"onattribdata",
|
||||
"onattribend",
|
||||
"onattribname",
|
||||
"onattribute",
|
||||
"oncdata",
|
||||
"oncdataend",
|
||||
"oncdatastart",
|
||||
"onclosetag",
|
||||
"oncomment",
|
||||
"oncommentend",
|
||||
"ondeclaration",
|
||||
"onedrive",
|
||||
"onelink",
|
||||
"onformat",
|
||||
"onmatch",
|
||||
"onopentag",
|
||||
"onopentagend",
|
||||
"onopentagname",
|
||||
"onparserinit",
|
||||
"onprocessinginstruction",
|
||||
"onselfclosingtag",
|
||||
"ontext",
|
||||
"oòóôõöøō",
|
||||
"OÒÓÔÕÖØŌ",
|
||||
"opentag",
|
||||
"opentagname",
|
||||
"Opptionn",
|
||||
"orignal",
|
||||
"Oromo",
|
||||
"Österreich",
|
||||
"otherpackage",
|
||||
"outdented",
|
||||
"overidding",
|
||||
"overriden",
|
||||
"padd",
|
||||
"pandoc",
|
||||
"paperclip",
|
||||
"passthrough",
|
||||
"Päth",
|
||||
"Pbuild",
|
||||
"pbxproj",
|
||||
"pcmag",
|
||||
"pcnalx",
|
||||
"pddv",
|
||||
"Pehr",
|
||||
"Percents",
|
||||
"père",
|
||||
"Perú",
|
||||
"pfff",
|
||||
"PGPASSWORD",
|
||||
"pidfile",
|
||||
"PLUGINLEGACY",
|
||||
"pocount",
|
||||
"Polska",
|
||||
"Polski",
|
||||
"Polynésie",
|
||||
"Português",
|
||||
"Potoczny's",
|
||||
"powerpoint",
|
||||
"Prakash",
|
||||
"precommit",
|
||||
"pred",
|
||||
"preg",
|
||||
"prerelease",
|
||||
"Prerelease",
|
||||
"presigner",
|
||||
"prettycron",
|
||||
"pricetag",
|
||||
"Príncipe",
|
||||
"privkey",
|
||||
"processinginstruction",
|
||||
"programatically",
|
||||
"propfind",
|
||||
"PROPFIND",
|
||||
"propname",
|
||||
"propstat",
|
||||
"protcol",
|
||||
"pseudoclass",
|
||||
"pseudos",
|
||||
"Pushto",
|
||||
"quot",
|
||||
"qwer",
|
||||
"raisebox",
|
||||
"rbga",
|
||||
"readerable",
|
||||
"Readerable",
|
||||
"READERABLE",
|
||||
"Redownload",
|
||||
"reencrypt",
|
||||
"reencrypted",
|
||||
"Reencrypting",
|
||||
"reencrypts",
|
||||
"regexes",
|
||||
"Regexs",
|
||||
"Relavent",
|
||||
"relayouted",
|
||||
"rels",
|
||||
"renamings",
|
||||
"renderered",
|
||||
"Renderered",
|
||||
"República",
|
||||
"republika",
|
||||
"République",
|
||||
"requestheaders",
|
||||
"resourcetype",
|
||||
"resynced",
|
||||
"Rhaeto",
|
||||
"rightarrow",
|
||||
"rightequilibrium",
|
||||
"rightleftarrows",
|
||||
"rightleftharpoons",
|
||||
"rmbook",
|
||||
"rmnote",
|
||||
"rmusin",
|
||||
"rnfs",
|
||||
"RNFS",
|
||||
"robocopy",
|
||||
"Roboto",
|
||||
"România",
|
||||
"roule",
|
||||
"rowid",
|
||||
"ROWID",
|
||||
"ROWIDs",
|
||||
"rowspan",
|
||||
"rseidelsohn",
|
||||
"rtrim",
|
||||
"safeext",
|
||||
"salut",
|
||||
"Sangho",
|
||||
"sasss",
|
||||
"SAVEPOINT",
|
||||
"schtroumpf",
|
||||
"Schweiz",
|
||||
"Scrolllock",
|
||||
"scrollmap",
|
||||
"seafdav",
|
||||
"Seafile",
|
||||
"searchengine",
|
||||
"searchlimit",
|
||||
"SEARCHOVERLAY",
|
||||
"securerandom",
|
||||
"segdir",
|
||||
"selectbox",
|
||||
"Sénégal",
|
||||
"Serializers",
|
||||
"setext",
|
||||
"settingschema",
|
||||
"shantanugoel",
|
||||
"sharee",
|
||||
"Shiftt",
|
||||
"Shoft",
|
||||
"shouldntendwithit",
|
||||
"shouldstartwiththis",
|
||||
"Shqip",
|
||||
"Shqipëria",
|
||||
"Sicen",
|
||||
"simplemath",
|
||||
"Siswati",
|
||||
"sizeinput",
|
||||
"SJCL",
|
||||
"Slovenčina",
|
||||
"Slovenija",
|
||||
"Slovensko",
|
||||
"softbreaks",
|
||||
"Solarised",
|
||||
"SOLARIZED",
|
||||
"someid",
|
||||
"somewhereelse",
|
||||
"sourceurl",
|
||||
"SPACEBAR",
|
||||
"spaceno",
|
||||
"Spacify",
|
||||
"spdfgh",
|
||||
"spellfix",
|
||||
"sphemy",
|
||||
"splitbutton",
|
||||
"sprintf",
|
||||
"sqlts",
|
||||
"srcfolder",
|
||||
"SSSZ",
|
||||
"starttls",
|
||||
"Starttls",
|
||||
"stepsize",
|
||||
"stevenlevithan",
|
||||
"stex",
|
||||
"stilltryingtohack",
|
||||
"strack",
|
||||
"Stringifiable",
|
||||
"subdir",
|
||||
"subl",
|
||||
"Suomi",
|
||||
"Sūriyya",
|
||||
"Svenska",
|
||||
"Sverige",
|
||||
"svgs",
|
||||
"Svizra",
|
||||
"Svizzera",
|
||||
"synclock",
|
||||
"synclog",
|
||||
"syswide",
|
||||
"syswidecas",
|
||||
"taboverride",
|
||||
"tabpanel",
|
||||
"taga",
|
||||
"tagb",
|
||||
"tagc",
|
||||
"Tajik",
|
||||
"takesover",
|
||||
"targetfolder",
|
||||
"Tchad",
|
||||
"Teardown",
|
||||
"termi",
|
||||
"termutils",
|
||||
"Terres",
|
||||
"Tessarek",
|
||||
"tessus",
|
||||
"Testb",
|
||||
"testcreate",
|
||||
"testexportfolder",
|
||||
"testingconnection",
|
||||
"testingkeychain",
|
||||
"testunit",
|
||||
"texify",
|
||||
"Texify",
|
||||
"textareas",
|
||||
"textexportnote",
|
||||
"textstyle",
|
||||
"thaaaaaaan",
|
||||
"thatsok",
|
||||
"thatsreallylongthatsreallylongthatsreallylongthats",
|
||||
"thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong",
|
||||
"Thevenard",
|
||||
"thisisfine",
|
||||
"Thmmss",
|
||||
"Tiếng",
|
||||
"Tigrinya",
|
||||
"tiiitlllle",
|
||||
"tinymce",
|
||||
"titi",
|
||||
"titletitle",
|
||||
"tkwidget",
|
||||
"tkwidgets",
|
||||
"Todos",
|
||||
"togglebutton",
|
||||
"togglemenuitem",
|
||||
"toolip",
|
||||
"tooshort",
|
||||
"treymo",
|
||||
"tripledash",
|
||||
"tsmerge",
|
||||
"Tsonga",
|
||||
"tttest",
|
||||
"Tunisie",
|
||||
"Türkçe",
|
||||
"Türkiye",
|
||||
"Türkmenistan",
|
||||
"turndown",
|
||||
"Turndown",
|
||||
"TWCO",
|
||||
"typeahead",
|
||||
"Typora",
|
||||
"tzip",
|
||||
"uastring",
|
||||
"uglifycss",
|
||||
"uglifyjs",
|
||||
"Uighur",
|
||||
"unconflicted",
|
||||
"underbrace",
|
||||
"Undos",
|
||||
"unescaping",
|
||||
"unhighlighted",
|
||||
"unixlike",
|
||||
"unmocked",
|
||||
"unserialize",
|
||||
"unserialized",
|
||||
"unserializes",
|
||||
"unserializing",
|
||||
"unshares",
|
||||
"unsharing",
|
||||
"unusued",
|
||||
"uparrow",
|
||||
"uphy",
|
||||
"urlconverter",
|
||||
"urlinput",
|
||||
"userchrome",
|
||||
"usercontent",
|
||||
"userstyle",
|
||||
"uslug",
|
||||
"Ustd",
|
||||
"utems",
|
||||
"uuidgen",
|
||||
"uuidv",
|
||||
"uùúûüůū",
|
||||
"UÙÚÛÜŮŪ",
|
||||
"valign",
|
||||
"Valign",
|
||||
"vars",
|
||||
"Vars",
|
||||
"Vaticano",
|
||||
"vers",
|
||||
"verylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongidverylongid",
|
||||
"veryverylongclientidveryverylongclientidveryverylongclientidveryverylongclientid",
|
||||
"veryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitleveryverylongtitle",
|
||||
"Việt",
|
||||
"viewbox",
|
||||
"Volapuk",
|
||||
"Volívia",
|
||||
"votearrow",
|
||||
"webclipper",
|
||||
"webdav",
|
||||
"webfonts",
|
||||
"whitespaces",
|
||||
"widder",
|
||||
"Wifi",
|
||||
"Withflags",
|
||||
"Wolof",
|
||||
"WONTFIX",
|
||||
"wrongclienttype",
|
||||
"wrongpassword",
|
||||
"wrongtype",
|
||||
"Wuliwya",
|
||||
"wxyz",
|
||||
"xcallbackurl",
|
||||
"xcassets",
|
||||
"xcodeproj",
|
||||
"xcrun",
|
||||
"xgettext",
|
||||
"xlink",
|
||||
"xzvf",
|
||||
"yarg",
|
||||
"yosay",
|
||||
"yufzkns",
|
||||
"YYYYMMDDTHH",
|
||||
"zxcvbn",
|
||||
"zžżź",
|
||||
"ZŽŻŹ",
|
||||
"Ελλάδα",
|
||||
"Ελληνικά",
|
||||
"Κύπρος",
|
||||
"Агентство",
|
||||
"Антарктике",
|
||||
"Беларусь",
|
||||
"България",
|
||||
"Гора",
|
||||
"језик",
|
||||
"Казахстан",
|
||||
"Киргизия",
|
||||
"Книги",
|
||||
"Кыргызстан",
|
||||
"Қазақстан",
|
||||
"Македонија",
|
||||
"Молдавия",
|
||||
"Монгол",
|
||||
"номер",
|
||||
"рейтер",
|
||||
"Рейтер",
|
||||
"Россия",
|
||||
"Русский",
|
||||
"Северна",
|
||||
"сообщило",
|
||||
"СООБЩИЛО",
|
||||
"Србија",
|
||||
"српски",
|
||||
"Україна",
|
||||
"Црна",
|
||||
"საქართველო",
|
||||
"Հայաստան",
|
||||
"ישראל",
|
||||
"עיברית",
|
||||
"إرتريا",
|
||||
"اسلامي",
|
||||
"اسلامی",
|
||||
"افغانستان",
|
||||
"الأُرْدُن",
|
||||
"الإمارات",
|
||||
"البحرين",
|
||||
"الجزائر",
|
||||
"السعودية",
|
||||
"السودان",
|
||||
"الصومال",
|
||||
"العراق",
|
||||
"العربيّة",
|
||||
"ﺍﻟﻘﻤﺮي",
|
||||
"الكويت",
|
||||
"المتّحدة",
|
||||
"المغرب",
|
||||
"اليَمَن",
|
||||
"ایران",
|
||||
"پاکستان",
|
||||
"تشاد",
|
||||
"تونس",
|
||||
"جمهوری",
|
||||
"جيبوتي",
|
||||
"دولة",
|
||||
"دولتدولت",
|
||||
"سلطنة",
|
||||
"سوريا",
|
||||
"عُمان",
|
||||
"لبنان",
|
||||
"ليبيا",
|
||||
"موريتانيا",
|
||||
"ⵍⵎⵖⵔⵉⴱ",
|
||||
"ኢትዮጵያ",
|
||||
"ኤርትራ",
|
||||
"भारत",
|
||||
"গণপ্রজাতন্ত্রী",
|
||||
"লাদেশ",
|
||||
"இலங்கை",
|
||||
"ලංකා",
|
||||
"คือค",
|
||||
"คือคนไทย",
|
||||
"ประเทศไทย",
|
||||
"ປະຊາຊົນລາວ",
|
||||
"မြန်မာ",
|
||||
"កម្ពុជា"
|
||||
]
|
||||
}
|
@@ -1,8 +1,19 @@
|
||||
# This is a sample docker-compose file that can be used to run Joplin Server
|
||||
# along with a PostgreSQL server.
|
||||
#
|
||||
# All environment variables are optional. If you don't set them, you will get a
|
||||
# warning from docker-compose, however the app should use working defaults.
|
||||
# Update the following fields in the stanza below:
|
||||
#
|
||||
# POSTGRES_USER
|
||||
# POSTGRES_PASSWORD
|
||||
# APP_BASE_URL
|
||||
#
|
||||
# APP_BASE_URL: This is the base public URL where the service will be running.
|
||||
# - If Joplin Server needs to be accessible over the internet, configure APP_BASE_URL as follows: https://example.com/joplin.
|
||||
# - If Joplin Server does not need to be accessible over the internet, set the the APP_BASE_URL to your server's hostname.
|
||||
# For Example: http://[hostname]:22300. The base URL can include the port.
|
||||
# APP_PORT: The local port on which the Docker container will listen.
|
||||
# - This would typically be mapped to port to 443 (TLS) with a reverse proxy.
|
||||
# - If Joplin Server does not need to be accessible over the internet, the port can be mapped to 22300.
|
||||
|
||||
version: '3'
|
||||
|
||||
|
1
fastlane/metadata/android/de/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
eine Notiz- und Aufgaben-App mit Sync zwischen Linux, macOS, Windows
|
9
fastlane/metadata/android/en-US/full_description.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
<strong>Joplin</strong> is a note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in <a href="#markdown">Markdown format</a>.
|
||||
|
||||
Notes exported from Evernote and other applications <a href="https://joplinapp.org/help/#importing">can be imported</a> into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
|
||||
The notes can be securely <a href="https://joplinapp.org/help/#synchronisation">synchronised</a> using <a href="https://joplinapp.org/help/#encryption">end-to-end encryption</a> with various cloud services including Nextcloud, Dropbox, OneDrive and <a href="https://joplinapp.org/plans/">Joplin Cloud</a>.
|
||||
|
||||
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
|
||||
|
||||
The application is available for Windows, Linux, macOS, Android and iOS. A <a href="https://joplinapp.org/clipper/">Web Clipper</a>, to save web pages and screenshots from your browser, is also available for <a href="https://addons.mozilla.org/firefox/addon/joplin-web-clipper/">Firefox</a> and <a href="https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB">Chrome</a>.
|
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/01.png
Normal file
After Width: | Height: | Size: 281 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/02.png
Normal file
After Width: | Height: | Size: 69 KiB |
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
a note taking and to-do app with sync between Linux, macOS, Windows, and mobile
|
16
gulpfile.js
@@ -20,6 +20,22 @@ const tasks = {
|
||||
await utils.execCommandVerbose('git', ['push']);
|
||||
},
|
||||
},
|
||||
build: {
|
||||
fn: async () => {
|
||||
// Building everything in parallel seems to be unreliable on CI as
|
||||
// certain scripts randomly fail with missing files or folder, or
|
||||
// cannot delete certain directories (eg. copyPluginAssets or
|
||||
// copyApplicationAssets). Because of this, on CI, we run the build
|
||||
// sequencially. Locally we run it in parallel, which is much
|
||||
// faster, especially when having to rebuild after adding a
|
||||
// dependency.
|
||||
if (process.env.BUILD_SEQUENCIAL === '1') {
|
||||
await utils.execCommandVerbose('yarn', ['run', 'buildSequential']);
|
||||
} else {
|
||||
await utils.execCommandVerbose('yarn', ['run', 'buildParallel']);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
utils.registerGulpTasks(gulp, tasks);
|
||||
|
@@ -12,6 +12,8 @@ module.exports = {
|
||||
// '**/*.ts?(x)': () => 'npm run tsc',
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'yarn run linter-precommit',
|
||||
'yarn run checkLibPaths',
|
||||
// 'yarn run spellcheck',
|
||||
'git add',
|
||||
],
|
||||
};
|
||||
|
14
package.json
@@ -12,14 +12,17 @@
|
||||
"node": ">=16"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn workspaces foreach --verbose --interlaced --parallel run build && yarn run tsc",
|
||||
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 run build && yarn run tsc",
|
||||
"buildSequential": "yarn workspaces foreach --verbose --interlaced run build && yarn run tsc",
|
||||
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
|
||||
"buildCommandIndex": "gulp buildCommandIndex",
|
||||
"buildPluginDoc": "typedoc --name 'Joplin Plugin API Documentation' --mode file -theme './Assets/PluginDocTheme/' --readme './Assets/PluginDocTheme/index.md' --excludeNotExported --excludeExternals --excludePrivate --excludeProtected --out ../joplin-website/docs/api/references/plugin_api packages/lib/services/plugins/api/",
|
||||
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
||||
"updateNews": "node ./packages/tools/website/updateNews",
|
||||
"buildSettingJsonSchema": "yarn workspace joplin start settingschema ../../../joplin-website/docs/schema/settings.json",
|
||||
"buildTranslations": "node packages/tools/build-translation.js",
|
||||
"buildWebsite": "node ./packages/tools/website/build.js && yarn run buildPluginDoc && yarn run buildSettingJsonSchema",
|
||||
"checkLibPaths": "node ./packages/tools/checkLibPaths.js",
|
||||
"circularDependencyCheck": "madge --warning --circular --extensions js ./",
|
||||
"clean": "npm run clean --workspaces --if-present && node packages/tools/clean && yarn cache clean",
|
||||
"dependencyTree": "madge",
|
||||
@@ -28,9 +31,9 @@
|
||||
"linter-ci": "eslint --resolve-plugins-relative-to . --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter-precommit": "eslint --resolve-plugins-relative-to . --fix --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"linter": "eslint --resolve-plugins-relative-to . --fix --quiet --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"postinstall": "yarn run build",
|
||||
"publishAll": "git pull && yarn run build && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "yarn run build && export PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" && node packages/tools/release-android.js",
|
||||
"postinstall": "gulp build",
|
||||
"publishAll": "git pull && yarn run buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@11/bin:$PATH\" node packages/tools/release-android.js",
|
||||
"releaseAndroidClean": "node packages/tools/release-android.js",
|
||||
"releaseCli": "node packages/tools/release-cli.js",
|
||||
"releaseClipper": "node packages/tools/release-clipper.js",
|
||||
@@ -39,6 +42,8 @@
|
||||
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
|
||||
"releasePluginRepoCli": "node packages/tools/release-plugin-repo-cli.js",
|
||||
"releaseServer": "node packages/tools/release-server.js",
|
||||
"cspell": "cspell",
|
||||
"spellcheck": "node packages/tools/spellcheck.js",
|
||||
"tagServerLatest": "node packages/tools/tagServerLatest.js",
|
||||
"buildServerDocker": "node packages/tools/buildServerDocker.js",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
@@ -58,6 +63,7 @@
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^4.6.0",
|
||||
"@typescript-eslint/parser": "^4.6.0",
|
||||
"cspell": "^5.20.0",
|
||||
"eslint": "^7.6.0",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-react": "^7.18.0",
|
||||
|
@@ -412,7 +412,7 @@ class AppGui {
|
||||
const widget = this.widget('mainWindow').focusedWidget;
|
||||
if (!widget) return null;
|
||||
|
||||
if (widget.name == 'noteList' || widget.name == 'folderList') {
|
||||
if (widget.name === 'noteList' || widget.name === 'folderList') {
|
||||
return widget.currentItem;
|
||||
}
|
||||
|
||||
@@ -521,11 +521,11 @@ class AppGui {
|
||||
const args = splitCommandString(cmd);
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] == '$n') {
|
||||
if (args[i] === '$n') {
|
||||
args[i] = note ? note.id : '';
|
||||
} else if (args[i] == '$b') {
|
||||
} else if (args[i] === '$b') {
|
||||
args[i] = folder ? folder.id : '';
|
||||
} else if (args[i] == '$c') {
|
||||
} else if (args[i] === '$c') {
|
||||
const item = this.activeListItem();
|
||||
args[i] = item ? item.id : '';
|
||||
}
|
||||
|
@@ -81,21 +81,21 @@ class Application extends BaseApplication {
|
||||
|
||||
pattern = pattern ? pattern.toString() : '';
|
||||
|
||||
if (type == BaseModel.TYPE_FOLDER && (pattern == Folder.conflictFolderTitle() || pattern == Folder.conflictFolderId())) return [Folder.conflictFolder()];
|
||||
if (type === BaseModel.TYPE_FOLDER && (pattern === Folder.conflictFolderTitle() || pattern === Folder.conflictFolderId())) return [Folder.conflictFolder()];
|
||||
|
||||
if (!options) options = {};
|
||||
|
||||
const parent = options.parent ? options.parent : app().currentFolder();
|
||||
const ItemClass = BaseItem.itemClass(type);
|
||||
|
||||
if (type == BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
|
||||
if (type === BaseModel.TYPE_NOTE && pattern.indexOf('*') >= 0) {
|
||||
// Handle it as pattern
|
||||
if (!parent) throw new Error(_('No notebook selected.'));
|
||||
return await Note.previews(parent.id, { titlePattern: pattern });
|
||||
} else {
|
||||
// Single item
|
||||
let item = null;
|
||||
if (type == BaseModel.TYPE_NOTE) {
|
||||
if (type === BaseModel.TYPE_NOTE) {
|
||||
if (!parent) throw new Error(_('No notebook has been specified.'));
|
||||
item = await ItemClass.loadFolderNoteByField(parent.id, 'title', pattern);
|
||||
} else {
|
||||
@@ -137,7 +137,7 @@ class Application extends BaseApplication {
|
||||
if (!options.booleanAnswerDefault) options.booleanAnswerDefault = 'y';
|
||||
if (!options.answers) options.answers = options.booleanAnswerDefault === 'y' ? [_('Y'), _('n')] : [_('N'), _('y')];
|
||||
|
||||
if (options.type == 'boolean') {
|
||||
if (options.type === 'boolean') {
|
||||
message += ` (${options.answers.join('/')})`;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ class Application extends BaseApplication {
|
||||
if (options.type === 'boolean') {
|
||||
if (answer === null) return false; // Pressed ESCAPE
|
||||
if (!answer) answer = options.answers[0];
|
||||
const positiveIndex = options.booleanAnswerDefault == 'y' ? 0 : 1;
|
||||
const positiveIndex = options.booleanAnswerDefault === 'y' ? 0 : 1;
|
||||
return answer.toLowerCase() === options.answers[positiveIndex].toLowerCase();
|
||||
} else {
|
||||
return answer;
|
||||
@@ -181,7 +181,7 @@ class Application extends BaseApplication {
|
||||
fs.readdirSync(__dirname).forEach(path => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
if (ext !== 'js') return;
|
||||
|
||||
const CommandClass = require(`./${path}`);
|
||||
let cmd = new CommandClass();
|
||||
|
@@ -12,7 +12,7 @@ async function handleAutocompletionPromise(line) {
|
||||
const words = getArguments(line);
|
||||
// If there is only one word and it is not already a command name then you
|
||||
// should look for commands it could be
|
||||
if (words.length == 1) {
|
||||
if (words.length === 1) {
|
||||
if (names.indexOf(words[0]) === -1) {
|
||||
const x = names.filter(n => n.indexOf(words[0]) === 0);
|
||||
if (x.length === 1) {
|
||||
@@ -78,38 +78,38 @@ async function handleAutocompletionPromise(line) {
|
||||
|
||||
const currentFolder = app().currentFolder();
|
||||
|
||||
if (argName == 'note' || argName == 'note-pattern') {
|
||||
if (argName === 'note' || argName === 'note-pattern') {
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
|
||||
l.push(...notes.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'notebook') {
|
||||
if (argName === 'notebook') {
|
||||
const folders = await Folder.search({ titlePattern: `${next}*` });
|
||||
l.push(...folders.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'item') {
|
||||
if (argName === 'item') {
|
||||
const notes = currentFolder ? await Note.previews(currentFolder.id, { titlePattern: `${next}*` }) : [];
|
||||
const folders = await Folder.search({ titlePattern: `${next}*` });
|
||||
l.push(...notes.map(n => n.title), folders.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'tag') {
|
||||
if (argName === 'tag') {
|
||||
const tags = await Tag.search({ titlePattern: `${next}*` });
|
||||
l.push(...tags.map(n => n.title));
|
||||
}
|
||||
|
||||
if (argName == 'file') {
|
||||
if (argName === 'file') {
|
||||
const files = await fs.readdir('.');
|
||||
l.push(...files);
|
||||
}
|
||||
|
||||
if (argName == 'tag-command') {
|
||||
if (argName === 'tag-command') {
|
||||
const c = filterList(['add', 'remove', 'list', 'notetags'], next);
|
||||
l.push(...c);
|
||||
}
|
||||
|
||||
if (argName == 'todo-command') {
|
||||
if (argName === 'todo-command') {
|
||||
const c = filterList(['toggle', 'clear'], next);
|
||||
l.push(...c);
|
||||
}
|
||||
|
@@ -52,7 +52,7 @@ function getCommands() {
|
||||
fs.readdirSync(__dirname).forEach(path => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path);
|
||||
if (ext != 'js') return;
|
||||
if (ext !== 'js') return;
|
||||
|
||||
const CommandClass = require(`./${path}`);
|
||||
const cmd = new CommandClass();
|
||||
|
@@ -222,7 +222,7 @@ async function main() {
|
||||
|
||||
for (const n in testUnits) {
|
||||
if (!testUnits.hasOwnProperty(n)) continue;
|
||||
if (onlyThisTest && n != onlyThisTest) continue;
|
||||
if (onlyThisTest && n !== onlyThisTest) continue;
|
||||
|
||||
await clearDatabase();
|
||||
const testName = n.substr(4).toLowerCase();
|
||||
|
@@ -21,7 +21,7 @@ cliUtils.printArray = function(logFunction, rows) {
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
const item = row[j];
|
||||
const width = item ? item.toString().length : 0;
|
||||
const align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
const align = typeof item === 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
|
||||
if (colAligns.length <= j) colAligns[j] = align;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ cliUtils.printArray = function(logFunction, rows) {
|
||||
for (let col = 0; col < colWidths.length; col++) {
|
||||
const item = rows[row][col];
|
||||
const width = colWidths[col];
|
||||
const dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
const dir = colAligns[col] === ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
line.push(stringPadding(item, width, ' ', dir));
|
||||
}
|
||||
logFunction(line.join(' '));
|
||||
@@ -45,13 +45,13 @@ cliUtils.parseFlags = function(flags) {
|
||||
for (let i = 0; i < flags.length; i++) {
|
||||
let f = flags[i].trim();
|
||||
|
||||
if (f.substr(0, 2) == '--') {
|
||||
if (f.substr(0, 2) === '--') {
|
||||
f = f.split(' ');
|
||||
output.long = f[0].substr(2).trim();
|
||||
if (f.length == 2) {
|
||||
if (f.length === 2) {
|
||||
output.arg = cliUtils.parseCommandArg(f[1].trim());
|
||||
}
|
||||
} else if (f.substr(0, 1) == '-') {
|
||||
} else if (f.substr(0, 1) === '-') {
|
||||
output.short = f.substr(1);
|
||||
}
|
||||
}
|
||||
@@ -65,9 +65,9 @@ cliUtils.parseCommandArg = function(arg) {
|
||||
const c2 = arg[arg.length - 1];
|
||||
const name = arg.substr(1, arg.length - 2);
|
||||
|
||||
if (c1 == '<' && c2 == '>') {
|
||||
if (c1 === '<' && c2 === '>') {
|
||||
return { required: true, name: name };
|
||||
} else if (c1 == '[' && c2 == ']') {
|
||||
} else if (c1 === '[' && c2 === ']') {
|
||||
return { required: false, name: name };
|
||||
} else {
|
||||
throw new Error(`Invalid command arg: ${arg}`);
|
||||
@@ -83,7 +83,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
const booleanFlags = [];
|
||||
const aliases = {};
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].length != 2) throw new Error(`Invalid options: ${options[i]}`);
|
||||
if (options[i].length !== 2) throw new Error(`Invalid options: ${options[i]}`);
|
||||
let flags = options[i][0];
|
||||
|
||||
flags = cliUtils.parseFlags(flags);
|
||||
@@ -117,7 +117,7 @@ cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
const argOptions = {};
|
||||
for (const key in args) {
|
||||
if (!args.hasOwnProperty(key)) continue;
|
||||
if (key == '_') continue;
|
||||
if (key === '_') continue;
|
||||
argOptions[key] = args[key];
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ cliUtils.promptConfirm = function(message, answers = null) {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
rl.question(`${message} `, answer => {
|
||||
const ok = !answer || answer.toLowerCase() == answers[0].toLowerCase();
|
||||
const ok = !answer || answer.toLowerCase() === answers[0].toLowerCase();
|
||||
rl.close();
|
||||
resolve(ok);
|
||||
});
|
||||
|
@@ -313,8 +313,16 @@ async function fetchAllNotes() {
|
||||
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('To **update** the resource content, you can make a PUT request with the same arguments:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl -X PUT -F \'data=@/path/to/file.jpg\' -F \'props={"title":"my modified title"}\' http://localhost:41184/resources/8fe1417d7b184324bf6b0122b76c4696');
|
||||
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('');
|
||||
lines.push('Or if you only need to update the resource properties (title, etc.), without changing the content, you can make a regular PUT request:');
|
||||
lines.push('');
|
||||
lines.push('\tcurl -X PUT --data \'{"title": "My new title"}\' http://localhost:41184/resources/8fe1417d7b184324bf6b0122b76c4696');
|
||||
lines.push('');
|
||||
lines.push('**From a plugin** the syntax to create a resource is also a bit special:');
|
||||
lines.push('');
|
||||
lines.push('```javascript');
|
||||
@@ -368,6 +376,11 @@ async function fetchAllNotes() {
|
||||
lines.push(`Sets the properties of the ${singular} with ID :id`);
|
||||
lines.push('');
|
||||
|
||||
if (model.type === BaseModel.TYPE_RESOURCE) {
|
||||
lines.push('You may also update the file data by specifying a file (See `POST /resources` example).');
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
lines.push(`## DELETE /${tableName}/:id`);
|
||||
lines.push('');
|
||||
lines.push(`Deletes the ${singular} with ID :id`);
|
||||
|
@@ -122,7 +122,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
|
||||
if (args.name == 'locale') {
|
||||
if (args.name === 'locale') {
|
||||
setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
|
@@ -44,7 +44,7 @@ class Command extends BaseCommand {
|
||||
queryOptions.orderBy = options.sort;
|
||||
queryOptions.orderByDir = 'ASC';
|
||||
}
|
||||
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir == 'ASC' ? 'DESC' : 'ASC';
|
||||
if (options.reverse === true) queryOptions.orderByDir = queryOptions.orderByDir === 'ASC' ? 'DESC' : 'ASC';
|
||||
queryOptions.caseInsensitive = true;
|
||||
if (options.type) {
|
||||
queryOptions.itemTypes = [];
|
||||
@@ -55,7 +55,7 @@ class Command extends BaseCommand {
|
||||
queryOptions.uncompletedTodosOnTop = Setting.value('uncompletedTodosOnTop');
|
||||
|
||||
let modelType = null;
|
||||
if (pattern == '/' || !app().currentFolder()) {
|
||||
if (pattern === '/' || !app().currentFolder()) {
|
||||
queryOptions.includeConflictFolder = true;
|
||||
items = await Folder.all(queryOptions);
|
||||
modelType = Folder.modelType();
|
||||
@@ -65,7 +65,7 @@ class Command extends BaseCommand {
|
||||
modelType = Note.modelType();
|
||||
}
|
||||
|
||||
if (options.format && options.format == 'json') {
|
||||
if (options.format && options.format === 'json') {
|
||||
this.stdout(JSON.stringify(items));
|
||||
} else {
|
||||
let hasTodos = false;
|
||||
@@ -88,7 +88,7 @@ class Command extends BaseCommand {
|
||||
row.push(BaseModel.shortId(item.id));
|
||||
shortIdShown = true;
|
||||
|
||||
if (modelType == Folder.modelType()) {
|
||||
if (modelType === Folder.modelType()) {
|
||||
row.push(await Folder.noteCount(item.id));
|
||||
}
|
||||
|
||||
|
@@ -133,7 +133,7 @@ class Command extends BaseCommand {
|
||||
|
||||
this.releaseLockFn_ = await Command.lockFile(lockFilePath);
|
||||
} catch (error) {
|
||||
if (error.code == 'ELOCKED') {
|
||||
if (error.code === 'ELOCKED') {
|
||||
const msg = _('Lock file is already being hold. If you know that no synchronisation is taking place, you may delete the lock file at "%s" and resume the operation.', error.file);
|
||||
this.stdout(msg);
|
||||
return;
|
||||
@@ -222,7 +222,7 @@ class Command extends BaseCommand {
|
||||
const newContext = await sync.start(options);
|
||||
Setting.setValue(contextKey, JSON.stringify(newContext));
|
||||
} catch (error) {
|
||||
if (error.code == 'alreadyStarted') {
|
||||
if (error.code === 'alreadyStarted') {
|
||||
this.stdout(error.message);
|
||||
} else {
|
||||
throw error;
|
||||
|
@@ -30,21 +30,21 @@ class Command extends BaseCommand {
|
||||
|
||||
const command = args['tag-command'];
|
||||
|
||||
if (command == 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
if (command === 'remove' && !tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
|
||||
if (command == 'add') {
|
||||
if (command === 'add') {
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
|
||||
if (!tag) tag = await Tag.save({ title: args.tag }, { userSideValidation: true });
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.addNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (command == 'remove') {
|
||||
} else if (command === 'remove') {
|
||||
if (!tag) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args.note));
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
await Tag.removeNote(tag.id, notes[i].id);
|
||||
}
|
||||
} else if (command == 'list') {
|
||||
} else if (command === 'list') {
|
||||
if (tag) {
|
||||
const notes = await Tag.notes(tag.id);
|
||||
notes.map(note => {
|
||||
@@ -75,7 +75,7 @@ class Command extends BaseCommand {
|
||||
this.stdout(tag.title);
|
||||
});
|
||||
}
|
||||
} else if (command == 'notetags') {
|
||||
} else if (command === 'notetags') {
|
||||
if (args.tag) {
|
||||
const note = await app().loadItem(BaseModel.TYPE_NOTE, args.tag);
|
||||
if (!note) throw new Error(_('Cannot find "%s".', args.tag));
|
||||
|
@@ -29,13 +29,13 @@ class Command extends BaseCommand {
|
||||
id: note.id,
|
||||
};
|
||||
|
||||
if (action == 'toggle') {
|
||||
if (action === 'toggle') {
|
||||
if (!note.is_todo) {
|
||||
toSave = Note.toggleIsTodo(note);
|
||||
} else {
|
||||
toSave.todo_completed = note.todo_completed ? 0 : time.unixMs();
|
||||
}
|
||||
} else if (action == 'clear') {
|
||||
} else if (action === 'clear') {
|
||||
toSave.is_todo = 0;
|
||||
}
|
||||
|
||||
|
@@ -2071,7 +2071,7 @@ function execCommand(client, command, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const childProcess = exec(cmd, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
if (error.signal == 'SIGTERM') {
|
||||
if (error.signal === 'SIGTERM') {
|
||||
resolve('Process was killed');
|
||||
} else {
|
||||
logger.error(stderr);
|
||||
@@ -2103,7 +2103,7 @@ async function clientItems(client) {
|
||||
function randomTag(items) {
|
||||
const tags = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type_ != 5) continue;
|
||||
if (items[i].type_ !== 5) continue;
|
||||
tags.push(items[i]);
|
||||
}
|
||||
|
||||
@@ -2113,7 +2113,7 @@ function randomTag(items) {
|
||||
function randomNote(items) {
|
||||
const notes = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type_ != 1) continue;
|
||||
if (items[i].type_ !== 1) continue;
|
||||
notes.push(items[i]);
|
||||
}
|
||||
|
||||
@@ -2131,11 +2131,11 @@ async function execRandomCommand(client) {
|
||||
const item = randomElement(items);
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ == 1) {
|
||||
if (item.type_ === 1) {
|
||||
return execCommand(client, `rm -f ${item.id}`);
|
||||
} else if (item.type_ == 2) {
|
||||
} else if (item.type_ === 2) {
|
||||
return execCommand(client, `rm -r -f ${item.id}`);
|
||||
} else if (item.type_ == 5) {
|
||||
} else if (item.type_ === 5) {
|
||||
// tag
|
||||
} else {
|
||||
throw new Error(`Unknown type: ${item.type_}`);
|
||||
@@ -2213,7 +2213,7 @@ function randomNextCheckTime() {
|
||||
|
||||
function findItem(items, itemId) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].id == itemId) return items[i];
|
||||
if (items[i].id === itemId) return items[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -2225,7 +2225,7 @@ function compareItems(item1, item2) {
|
||||
const p1 = item1[n];
|
||||
const p2 = item2[n];
|
||||
|
||||
if (n == 'notes_') {
|
||||
if (n === 'notes_') {
|
||||
p1.sort();
|
||||
p2.sort();
|
||||
if (JSON.stringify(p1) !== JSON.stringify(p2)) {
|
||||
@@ -2246,7 +2246,7 @@ function findMissingItems_(items1, items2) {
|
||||
let found = false;
|
||||
for (let j = 0; j < items2.length; j++) {
|
||||
const item2 = items2[j];
|
||||
if (item1.id == item2.id) {
|
||||
if (item1.id === item2.id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -2340,9 +2340,9 @@ async function main() {
|
||||
let state = 'commands';
|
||||
|
||||
setInterval(async () => {
|
||||
if (state == 'waitForSyncCheck') return;
|
||||
if (state === 'waitForSyncCheck') return;
|
||||
|
||||
if (state == 'syncCheck') {
|
||||
if (state === 'syncCheck') {
|
||||
state = 'waitForSyncCheck';
|
||||
const clientItems = [];
|
||||
// Up to 3 sync operations must be performed by each clients in order for them
|
||||
@@ -2371,7 +2371,7 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == 'waitForClients') {
|
||||
if (state === 'waitForClients') {
|
||||
for (let i = 0; i < clients.length; i++) {
|
||||
if (clients[i].activeCommandCount > 0) return;
|
||||
}
|
||||
@@ -2380,7 +2380,7 @@ async function main() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == 'commands') {
|
||||
if (state === 'commands') {
|
||||
if (nextSyncCheckTime <= time.unixMs()) {
|
||||
state = 'waitForClients';
|
||||
return;
|
||||
|
@@ -2,6 +2,7 @@ const Folder = require('@joplin/lib/models/Folder').default;
|
||||
const Tag = require('@joplin/lib/models/Tag').default;
|
||||
const BaseModel = require('@joplin/lib/BaseModel').default;
|
||||
const ListWidget = require('tkwidgets/ListWidget.js');
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const _ = require('@joplin/lib/locale')._;
|
||||
|
||||
class FolderListWidget extends ListWidget {
|
||||
@@ -25,6 +26,18 @@ class FolderListWidget extends ListWidget {
|
||||
output.push('-'.repeat(this.innerWidth));
|
||||
} else if (item.type_ === Folder.modelType()) {
|
||||
output.push(' '.repeat(this.folderDepth(this.folders, item.id)) + Folder.displayTitle(item));
|
||||
if (Setting.value('showNoteCounts')) {
|
||||
let noteCount = item.note_count;
|
||||
// Subtract children note_count from parent folder.
|
||||
if (this.folderHasChildren_(this.folders,item.id)) {
|
||||
for (let i = 0; i < this.folders.length; i++) {
|
||||
if (this.folders[i].parent_id === item.id) {
|
||||
noteCount -= this.folders[i].note_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
output.push(noteCount);
|
||||
}
|
||||
} else if (item.type_ === Tag.modelType()) {
|
||||
output.push(`[${Folder.displayTitle(item)}]`);
|
||||
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
|
||||
|
@@ -26,7 +26,7 @@ const sharp = require('sharp');
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local.js');
|
||||
const { FileApiDriverLocal } = require('@joplin/lib/file-api-driver-local');
|
||||
const EncryptionService = require('@joplin/lib/services/e2ee/EncryptionService').default;
|
||||
const envFromArgs = require('@joplin/lib/envFromArgs');
|
||||
const nodeSqlite = require('sqlite3');
|
||||
@@ -82,13 +82,13 @@ if (process.platform === 'win32') {
|
||||
|
||||
process.stdout.on('error', function(err) {
|
||||
// https://stackoverflow.com/questions/12329816/error-write-epipe-when-piping-node-output-to-head#15884508
|
||||
if (err.code == 'EPIPE') {
|
||||
if (err.code === 'EPIPE') {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
application.start(process.argv).catch(error => {
|
||||
if (error.code == 'flagError') {
|
||||
if (error.code === 'flagError') {
|
||||
console.error(error.message);
|
||||
console.error(_('Type `joplin help` for usage information.'));
|
||||
} else {
|
||||
|
@@ -45,7 +45,7 @@ while [ "$NUM" -lt 400 ]; do
|
||||
echo "config keychain.supported 0" >> "$CMD_FILE"
|
||||
echo "config sync.target 10" >> "$CMD_FILE"
|
||||
echo "config sync.10.username $USER_EMAIL" >> "$CMD_FILE"
|
||||
echo "config sync.10.password hunter1hunter2hunter3" >> "$CMD_FILE"
|
||||
echo "config sync.10.password 111111" >> "$CMD_FILE"
|
||||
echo "sync" >> "$CMD_FILE"
|
||||
|
||||
yarn start --profile "$PROFILE_DIR" batch "$CMD_FILE"
|
||||
|
@@ -33,14 +33,14 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "2.7.0",
|
||||
"version": "2.9.0",
|
||||
"bin": "./main.js",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@joplin/lib": "~2.7",
|
||||
"@joplin/renderer": "~2.7",
|
||||
"@joplin/lib": "~2.9",
|
||||
"@joplin/renderer": "~2.9",
|
||||
"aws-sdk": "^2.588.0",
|
||||
"chalk": "^4.1.0",
|
||||
"compare-version": "^0.1.2",
|
||||
@@ -67,7 +67,7 @@
|
||||
"yargs-parser": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@joplin/tools": "~2.7",
|
||||
"@joplin/tools": "~2.9",
|
||||
"@types/fs-extra": "^9.0.6",
|
||||
"@types/jest": "^26.0.15",
|
||||
"@types/node": "^14.14.6",
|
||||
|
@@ -60,16 +60,20 @@ describe('MdToHtml', function() {
|
||||
actualHtml = actualHtml.replace(/\r?\n/g, '\n');
|
||||
|
||||
if (actualHtml !== expectedHtml) {
|
||||
console.info('');
|
||||
console.info(`Error converting file: ${mdFilename}`);
|
||||
console.info('--------------------------------- Got:');
|
||||
console.info(actualHtml);
|
||||
console.info('--------------------------------- Raw:');
|
||||
console.info(actualHtml.split('\n'));
|
||||
console.info('--------------------------------- Expected:');
|
||||
console.info(expectedHtml.split('\n'));
|
||||
console.info('--------------------------------------------');
|
||||
console.info('');
|
||||
const msg: string[] = [
|
||||
'',
|
||||
`Error converting file: ${mdFilename}`,
|
||||
'--------------------------------- Got:',
|
||||
actualHtml,
|
||||
'--------------------------------- Raw:',
|
||||
actualHtml.split('\n'),
|
||||
'--------------------------------- Expected:',
|
||||
expectedHtml.split('\n'),
|
||||
'--------------------------------------------',
|
||||
'',
|
||||
];
|
||||
|
||||
console.info(msg.join('\n'));
|
||||
|
||||
expect(false).toBe(true);
|
||||
// return;
|
||||
@@ -242,9 +246,9 @@ describe('MdToHtml', function() {
|
||||
{
|
||||
const input = '# Head\nFruits\n- Apple\n';
|
||||
const result = await mdToHtml.render(input, null, { bodyOnly: true, mapsToLine: true });
|
||||
expect(result.html.trim()).toBe('<h1 id="head" class="maps-to-line" source-line="0">Head</h1>\n' +
|
||||
'<p class="maps-to-line" source-line="1">Fruits</p>\n' +
|
||||
'<ul>\n<li class="maps-to-line" source-line="2">Apple</li>\n</ul>'
|
||||
expect(result.html.trim()).toBe('<h1 id="head" class="maps-to-line" source-line="0" source-line-end="1">Head</h1>\n' +
|
||||
'<p class="maps-to-line" source-line="1" source-line-end="2">Fruits</p>\n' +
|
||||
'<ul>\n<li class="maps-to-line" source-line="2" source-line-end="3">Apple</li>\n</ul>'
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
@@ -30,7 +30,7 @@ describe('feature_NoteHistory', function() {
|
||||
});
|
||||
|
||||
afterEach(async (done) => {
|
||||
if (testApp !== null) await testApp.destroy();
|
||||
if (testApp) await testApp.destroy();
|
||||
testApp = null;
|
||||
done();
|
||||
});
|
||||
|
@@ -0,0 +1,4 @@
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="" title="some-title">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="some-alt-text">
|
||||
<img src=":/39e66095b2cd427e9f13464487514d2e" alt="some-alt-text" title="some-title">
|
@@ -0,0 +1,4 @@
|
||||

|
||||

|
||||

|
||||

|
0
packages/app-cli/tests/md_to_html/sanitize_11.html
Normal file
1
packages/app-cli/tests/md_to_html/sanitize_11.md
Normal file
@@ -0,0 +1 @@
|
||||
<iframe src=""><svg><style><img src="" onerror=this.onerror=confirm('vulnerable_to_XSS')
|
@@ -334,6 +334,12 @@ export enum SettingItemType {
|
||||
Button = 6,
|
||||
}
|
||||
|
||||
export enum SettingItemSubType {
|
||||
FilePathAndArgs = 'file_path_and_args',
|
||||
FilePath = 'file_path', // Not supported on mobile!
|
||||
DirectoryPath = 'directory_path', // Not supported on mobile!
|
||||
}
|
||||
|
||||
export enum AppType {
|
||||
Desktop = 'desktop',
|
||||
Mobile = 'mobile',
|
||||
@@ -350,6 +356,7 @@ export enum SettingStorage {
|
||||
export interface SettingItem {
|
||||
value: any;
|
||||
type: SettingItemType;
|
||||
subType?: SettingItemSubType;
|
||||
|
||||
label: string;
|
||||
description?: string;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import joplin from 'api';
|
||||
import { SettingItemType, ToolbarButtonLocation } from 'api/types';
|
||||
import { SettingItemSubType, SettingItemType, ToolbarButtonLocation } from 'api/types';
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
@@ -49,6 +49,33 @@ joplin.plugins.register({
|
||||
description: 'This setting will be saved to settings.json',
|
||||
['storage' as any]: 2, // Should be `storage: SettingStorage.File`
|
||||
},
|
||||
|
||||
'myFilePathAndArgs': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
subType: SettingItemSubType.FilePathAndArgs,
|
||||
section: 'myCustomSection',
|
||||
public: true,
|
||||
label: 'File path and args',
|
||||
},
|
||||
|
||||
'myFilePathOnly': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
subType: SettingItemSubType.FilePath,
|
||||
section: 'myCustomSection',
|
||||
public: true,
|
||||
label: 'File path',
|
||||
},
|
||||
|
||||
'myDirectory': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
subType: SettingItemSubType.DirectoryPath,
|
||||
section: 'myCustomSection',
|
||||
public: true,
|
||||
label: 'Directory path',
|
||||
},
|
||||
});
|
||||
|
||||
await joplin.commands.register({
|
||||
|
@@ -44,7 +44,7 @@ const processUser = async (userNum: number) => {
|
||||
|
||||
try {
|
||||
const userEmail = `user${userNum}@example.com`;
|
||||
const userPassword = 'hunter1hunter2hunter3';
|
||||
const userPassword = '111111';
|
||||
const commandFile = `${tempDir}/populateDatabase-${userNum}.txt`;
|
||||
const profileDir = `${homedir()}/.config/joplindev-populate/joplindev-testing-${userNum}`;
|
||||
|
||||
|
@@ -32,6 +32,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHtml(s) {
|
||||
return s
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function pageTitle() {
|
||||
const titleElements = document.getElementsByTagName('title');
|
||||
if (titleElements.length) return titleElements[0].text.trim();
|
||||
@@ -204,6 +213,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeName === 'embed') {
|
||||
const src = absoluteUrl(node.src);
|
||||
node.setAttribute('src', src);
|
||||
}
|
||||
|
||||
if (nodeName === 'object') {
|
||||
const data = absoluteUrl(node.data);
|
||||
node.setAttribute('data', data);
|
||||
}
|
||||
|
||||
cleanUpElement(convertToMarkup, node, imageSizes, imageIndexes);
|
||||
}
|
||||
}
|
||||
@@ -317,6 +336,9 @@
|
||||
}
|
||||
|
||||
function readabilityProcess() {
|
||||
|
||||
if (isPagePdf()) throw new Error('Could not parse PDF document with Readability');
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const readability = new Readability(documentForReadability());
|
||||
const article = readability.parse();
|
||||
@@ -329,6 +351,14 @@
|
||||
};
|
||||
}
|
||||
|
||||
function isPagePdf() {
|
||||
return document.contentType === 'application/pdf';
|
||||
}
|
||||
|
||||
function embedPageUrl() {
|
||||
return `<embed src="${escapeHtml(window.location.href)}" type="${escapeHtml(document.contentType)}" />`;
|
||||
}
|
||||
|
||||
async function prepareCommandResponse(command) {
|
||||
console.info(`Got command: ${command.name}`);
|
||||
const shouldSendToJoplin = !!command.shouldSendToJoplin;
|
||||
@@ -375,6 +405,10 @@
|
||||
|
||||
} else if (command.name === 'completePageHtml') {
|
||||
|
||||
if (isPagePdf()) {
|
||||
return clippedContentResponse(pageTitle(), embedPageUrl(), getImageSizes(document), getAnchorNames(document));
|
||||
}
|
||||
|
||||
hardcodePreStyles(document);
|
||||
addSvgClass(document);
|
||||
preProcessDocument(document);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Joplin Web Clipper [DEV]",
|
||||
"version": "2.7.0",
|
||||
"version": "2.9.0",
|
||||
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
|
||||
"homepage_url": "https://joplinapp.org",
|
||||
"content_security_policy": "script-src 'self'; object-src 'self'",
|
||||
|
@@ -16,6 +16,8 @@ function getAdditionalModulePaths(options = {}) {
|
||||
|
||||
// We need to explicitly check for null and undefined (and not a falsy value) because
|
||||
// TypeScript treats an empty string as `.`.
|
||||
//
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (baseUrl == null) {
|
||||
// If there's no baseUrl set we respect NODE_PATH
|
||||
// Note that NODE_PATH is deprecated and will be removed
|
||||
|
19
packages/app-clipper/popup/package-lock.json
generated
@@ -20253,6 +20253,19 @@
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "3.9.10",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unicode-canonical-property-names-ecmascript": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
|
||||
@@ -37995,6 +38008,12 @@
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.9.10",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
|
||||
"integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
|
||||
"peer": true
|
||||
},
|
||||
"unicode-canonical-property-names-ecmascript": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
|
||||
|
@@ -19,7 +19,7 @@
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<title>Joplin Web Clipper</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
|
@@ -67,7 +67,7 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
return choosePort(HOST, DEFAULT_PORT);
|
||||
})
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
if (!port) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
|
@@ -63,13 +63,15 @@ class AppComponent extends Component {
|
||||
contentScriptLoaded: false,
|
||||
selectedTags: [],
|
||||
contentScriptError: '',
|
||||
newNoteId: null,
|
||||
});
|
||||
|
||||
this.confirm_click = () => {
|
||||
this.confirm_click = async () => {
|
||||
const content = Object.assign({}, this.props.clippedContent);
|
||||
content.tags = this.state.selectedTags.join(',');
|
||||
content.parent_id = this.props.selectedFolderId;
|
||||
bridge().sendContentToJoplin(content);
|
||||
const response = await bridge().sendContentToJoplin(content);
|
||||
this.setState({ newNoteId: response.id });
|
||||
};
|
||||
|
||||
this.contentTitle_change = (event) => {
|
||||
@@ -402,6 +404,24 @@ class AppComponent extends Component {
|
||||
);
|
||||
};
|
||||
|
||||
const openNewNoteButton = () => {
|
||||
|
||||
if (!this.state.newNoteId) { return null; } else {
|
||||
return (
|
||||
// The jopin:// link must be opened in a new tab. When it's opened for the first time, a system dialog will ask for the user's permission.
|
||||
// The system dialog is too big to fit into the popup so the user will not be able to see the dialog buttons and get stuck.
|
||||
<a
|
||||
className="Button"
|
||||
href={`joplin://x-callback-url/openNote?id=${encodeURIComponent(this.state.newNoteId)}`}
|
||||
target="_blank"
|
||||
onClick={() => this.setState({ newNoteId: null })}
|
||||
>
|
||||
Open newly created note
|
||||
</a>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const tagDataListOptions = [];
|
||||
for (let i = 0; i < this.props.tags.length; i++) {
|
||||
const tag = this.props.tags[i];
|
||||
@@ -437,6 +457,7 @@ class AppComponent extends Component {
|
||||
</div>
|
||||
{ warningComponent }
|
||||
{ previewComponent }
|
||||
{ openNewNoteButton() }
|
||||
{ clipperStatusComp() }
|
||||
</div>
|
||||
);
|
||||
|
@@ -463,9 +463,11 @@ class Bridge {
|
||||
// This is the perfect Heisenbug - it happens always when opening the popup the first time EXCEPT
|
||||
// when the debugger is open. Then everything is working fine and the bug NEVER EVER happens,
|
||||
// so it's impossible to understand what's going on.
|
||||
await this.clipperApiExec('POST', 'notes', { nounce: this.nounce_++ }, content);
|
||||
const response = await this.clipperApiExec('POST', 'notes', { nounce: this.nounce_++ }, content);
|
||||
|
||||
this.dispatch({ type: 'CONTENT_UPLOAD', operation: { uploading: false, success: true } });
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (error.message === '{"error":"Duplicate Nounce"}') {
|
||||
this.dispatch({ type: 'CONTENT_UPLOAD', operation: { uploading: false, success: true } });
|
||||
|
2
packages/app-desktop/.gitignore
vendored
@@ -12,5 +12,5 @@ runForSharingCommands-*
|
||||
runForTestingCommands-*
|
||||
style.min.css
|
||||
build/lib/
|
||||
vendor/
|
||||
vendor/*
|
||||
!vendor/loadEmojiLib.js
|
||||
|
@@ -192,7 +192,7 @@ export default class ElectronAppWrapper {
|
||||
// We got the response from the renderer process:
|
||||
// save the response and try quit again.
|
||||
this.rendererProcessQuitReply_ = args;
|
||||
this.electronApp_.quit();
|
||||
this.quit();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -253,7 +253,7 @@ export default class ElectronAppWrapper {
|
||||
});
|
||||
}
|
||||
|
||||
async quit() {
|
||||
quit() {
|
||||
this.electronApp_.quit();
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ export default class ElectronAppWrapper {
|
||||
|
||||
if (!gotTheLock) {
|
||||
// Another instance is already running - exit
|
||||
this.electronApp_.quit();
|
||||
this.quit();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ export default class ElectronAppWrapper {
|
||||
});
|
||||
|
||||
this.electronApp_.on('window-all-closed', () => {
|
||||
this.electronApp_.quit();
|
||||
this.quit();
|
||||
});
|
||||
|
||||
this.electronApp_.on('activate', () => {
|
||||
|
@@ -24,7 +24,6 @@ import ExternalEditWatcher from '@joplin/lib/services/ExternalEditWatcher';
|
||||
import appReducer, { createAppDefaultState } from './app.reducer';
|
||||
const { FoldersScreenUtils } = require('@joplin/lib/folders-screen-utils.js');
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
const fs = require('fs-extra');
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
const packageInfo = require('./packageInfo.js');
|
||||
@@ -63,6 +62,7 @@ import ShareService from '@joplin/lib/services/share/ShareService';
|
||||
import checkForUpdates from './checkForUpdates';
|
||||
import { AppState } from './app.reducer';
|
||||
import syncDebugLog from '@joplin/lib/services/synchronizer/syncDebugLog';
|
||||
import eventManager from '@joplin/lib/eventManager';
|
||||
// import { runIntegrationTests } from '@joplin/lib/services/e2ee/ppkTestUtils';
|
||||
|
||||
const pluginClasses = [
|
||||
@@ -104,22 +104,22 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
protected async generalMiddleware(store: any, next: any, action: any) {
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'locale' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'locale' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
setLocale(Setting.value('locale'));
|
||||
// The bridge runs within the main process, with its own instance of locale.js
|
||||
// so it needs to be set too here.
|
||||
bridge().setLocale(Setting.value('locale'));
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'showTrayIcon' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'showTrayIcon' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
this.updateTray();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'style.editor.fontFamily' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'style.editor.fontFamily' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
this.updateEditorFont();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'windowContentZoomFactor' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (action.type === 'SETTING_UPDATE_ONE' && action.key === 'windowContentZoomFactor' || action.type === 'SETTING_UPDATE_ALL') {
|
||||
webFrame.setZoomFactor(Setting.value('windowContentZoomFactor') / 100);
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ class Application extends BaseApplication {
|
||||
await Folder.expandTree(newState.folders, action.folderId);
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
if (this.hasGui() && ((action.type === 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'theme', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key)) || action.type === 'SETTING_UPDATE_ALL')) {
|
||||
this.handleThemeAutoDetect();
|
||||
}
|
||||
|
||||
@@ -234,23 +234,6 @@ class Application extends BaseApplication {
|
||||
});
|
||||
}
|
||||
|
||||
async loadCustomCss(filePath: string) {
|
||||
let cssString = '';
|
||||
if (await fs.pathExists(filePath)) {
|
||||
try {
|
||||
cssString = await fs.readFile(filePath, 'utf-8');
|
||||
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = `Could not load custom css from ${filePath}\n${msg}`;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return cssString;
|
||||
}
|
||||
|
||||
private async checkForLegacyTemplates() {
|
||||
const templatesDir = `${Setting.value('profileDir')}/templates`;
|
||||
if (await shim.fsDriver().exists(templatesDir)) {
|
||||
@@ -258,7 +241,7 @@ class Application extends BaseApplication {
|
||||
const files = await shim.fsDriver().readDirStats(templatesDir);
|
||||
for (const file of files) {
|
||||
if (file.path.endsWith('.md')) {
|
||||
// There is atleast one template.
|
||||
// There is at least one template.
|
||||
this.store().dispatch({
|
||||
type: 'CONTAINS_LEGACY_TEMPLATES',
|
||||
});
|
||||
@@ -341,6 +324,18 @@ class Application extends BaseApplication {
|
||||
}, 500);
|
||||
}
|
||||
|
||||
public crashDetectionHandler() {
|
||||
// This handler conflicts with the single instance behaviour, so it's
|
||||
// not used for now.
|
||||
// https://discourse.joplinapp.org/t/pre-release-v2-8-is-now-available-updated-27-april/25158/56?u=laurent
|
||||
if (!Setting.value('wasClosedSuccessfully')) {
|
||||
const answer = confirm(_('The application did not close properly. Would you like to start in safe mode?'));
|
||||
Setting.setValue('isSafeMode', !!answer);
|
||||
}
|
||||
|
||||
Setting.setValue('wasClosedSuccessfully', false);
|
||||
}
|
||||
|
||||
public async start(argv: string[]): Promise<any> {
|
||||
// If running inside a package, the command line, instead of being "node.exe <path> <flags>" is "joplin.exe <flags>" so
|
||||
// insert an extra argument so that they can be processed in a consistent way everywhere.
|
||||
@@ -348,6 +343,8 @@ class Application extends BaseApplication {
|
||||
|
||||
argv = await super.start(argv);
|
||||
|
||||
// this.crashDetectionHandler();
|
||||
|
||||
await this.applySettingsSideEffects();
|
||||
|
||||
if (Setting.value('sync.upgradeState') === Setting.SYNC_UPGRADE_STATE_MUST_DO) {
|
||||
@@ -371,8 +368,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
// Loads app-wide styles. (Markdown preview-specific styles loaded in app.js)
|
||||
const filename = Setting.custom_css_files.JOPLIN_APP;
|
||||
await injectCustomStyles('appStyles', `${dir}/${filename}`);
|
||||
await injectCustomStyles('appStyles', Setting.customCssFilePath(Setting.customCssFilenames.JOPLIN_APP));
|
||||
|
||||
AlarmService.setDriver(new AlarmServiceDriverNode({ appName: packageInfo.build.appId }));
|
||||
AlarmService.setLogger(reg.logger());
|
||||
@@ -391,7 +387,7 @@ class Application extends BaseApplication {
|
||||
|
||||
PerFolderSortOrderService.initialize();
|
||||
|
||||
CommandService.instance().initialize(this.store(), Setting.value('env') == 'dev', stateToWhenClauseContext);
|
||||
CommandService.instance().initialize(this.store(), Setting.value('env') === 'dev', stateToWhenClauseContext);
|
||||
|
||||
for (const command of commands) {
|
||||
CommandService.instance().registerDeclaration(command.declaration);
|
||||
@@ -450,7 +446,7 @@ class Application extends BaseApplication {
|
||||
});
|
||||
|
||||
// Loads custom Markdown preview styles
|
||||
const cssString = await loadCustomCss(`${Setting.value('profileDir')}/userstyle.css`);
|
||||
const cssString = await loadCustomCss(Setting.customCssFilePath(Setting.customCssFilenames.RENDERED_MARKDOWN));
|
||||
this.store().dispatch({
|
||||
type: 'CUSTOM_CSS_APPEND',
|
||||
css: cssString,
|
||||
@@ -463,8 +459,9 @@ class Application extends BaseApplication {
|
||||
|
||||
await this.checkForLegacyTemplates();
|
||||
|
||||
// Note: Auto-update currently doesn't work in Linux: it downloads the update
|
||||
// but then doesn't install it on exit.
|
||||
// Note: Auto-update is a misnomer in the code.
|
||||
// The code below only checks, if a new version is available.
|
||||
// We only allow Windows and macOS users to automatically check for updates
|
||||
if (shim.isWindows() || shim.isMac()) {
|
||||
const runAutoUpdateCheck = () => {
|
||||
if (Setting.value('autoUpdateEnabled')) {
|
||||
@@ -523,6 +520,12 @@ class Application extends BaseApplication {
|
||||
|
||||
ResourceEditWatcher.instance().initialize(reg.logger(), (action: any) => { this.store().dispatch(action); }, (path: string) => bridge().openItem(path));
|
||||
|
||||
// Forwards the local event to the global event manager, so that it can
|
||||
// be picked up by the plugin manager.
|
||||
ResourceEditWatcher.instance().on('resourceChange', (event: any) => {
|
||||
eventManager.emit('resourceChange', event);
|
||||
});
|
||||
|
||||
RevisionService.instance().runInBackground();
|
||||
|
||||
// Make it available to the console window - useful to call revisionService.collectRevisions()
|
||||
@@ -532,8 +535,10 @@ class Application extends BaseApplication {
|
||||
migrationService: MigrationService.instance(),
|
||||
decryptionWorker: DecryptionWorker.instance(),
|
||||
commandService: CommandService.instance(),
|
||||
pluginService: PluginService.instance(),
|
||||
bridge: bridge(),
|
||||
debug: new DebugService(reg.db()),
|
||||
resourceService: ResourceService.instance(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -564,11 +569,17 @@ class Application extends BaseApplication {
|
||||
// setTimeout(() => {
|
||||
// this.dispatch({
|
||||
// type: 'DIALOG_OPEN',
|
||||
// name: 'editFolder',
|
||||
// props: { folderId: '3d90f7da26b947dc9c8c6c65e86cd231' },
|
||||
// name: 'syncWizard',
|
||||
// });
|
||||
// }, 2000);
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.dispatch({
|
||||
// type: 'DIALOG_OPEN',
|
||||
// name: 'editFolder',
|
||||
// });
|
||||
// }, 3000);
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.dispatch({
|
||||
// type: 'NAV_GO',
|
||||
@@ -579,22 +590,6 @@ class Application extends BaseApplication {
|
||||
// });
|
||||
// }, 2000);
|
||||
|
||||
|
||||
|
||||
|
||||
// const testData = {
|
||||
// "publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmKpb4JiYiY16pGOabje7uMsFd7DcMnruGxJ9HSpOiOduj3ApKqRu0xWCkGyqpekyOjjooZ98wVkDPUFsyVjN+kG8yKFn2xXC5SeRyhIVbdytjYiGshr6x+T9XVI+HnJKQF3WbrcqSOejlDXJv6u7jKrLAlOT3tkqEb0ZefhcEIajq6kNkH51R0lwsFnzxDIK3MW1wNzmiOfM92f8PFxiOBmUtVIngGPlNgyld1FzKN7Ypz1uS6GOqAtRm325qyfE/+2Jgb7WaDFT7VB5pHnOiojj9+xi1DvQWCbbIYXoMi0XVi9i2ZQfM32aFwiHez5UL61IMWUcqQ0/gldh4HFlAQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
// "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAmKpb4JiYiY16pGOabje7uMsFd7DcMnruGxJ9HSpOiOduj3ApKqRu0xWCkGyqpekyOjjooZ98wVkDPUFsyVjN+kG8yKFn2xXC5SeRyhIVbdytjYiGshr6x+T9XVI+HnJKQF3WbrcqSOejlDXJv6u7jKrLAlOT3tkqEb0ZefhcEIajq6kNkH51R0lwsFnzxDIK3MW1wNzmiOfM92f8PFxiOBmUtVIngGPlNgyld1FzKN7Ypz1uS6GOqAtRm325qyfE/+2Jgb7WaDFT7VB5pHnOiojj9+xi1DvQWCbbIYXoMi0XVi9i2ZQfM32aFwiHez5UL61IMWUcqQ0/gldh4HFlAQIDAQABAoIBADFFMffPZ9Nk7MLnPmz54cTnCPGzC63jDLuCAQ0LnWMDxiPW4AJaJUZMt+GioISBOWue+D1JOrsv3iLD3bcxyPBOjP33UYxcfpT0a1Ha+j2FriFygX4zxOIEnlyi8VdkLWCOqGj9BlGXKKzpmx4X76Sbbn9mt9+BGNm2vOUnaZcPTVuOI7K6xZynlzMRYSyhu7J0QdYVK44vZ/TjdD/4pgX+ezrGiwx7OCf/KctjvEoYtXYV2gkBOifOlqYOp0fMEC3mVAZfwpvDTbRchb7h0rxmxfKbWsjPtDblByXBLJZ3PGcKcmJlu4Qsfd2AgrY62r+DbNt3EhK072ZilYIfKD0CgYEAybcDbucr67dWMlFh5b79bvJugw6rj1V59Tp+RX9nKgzaiBUHLun6cK5hbgg9z3ejc2SWlX7D+eOyveVjhDlxUOCFURJLo2oPMRKwBBKJkOJhdtAjPzyceYI6Yj2lvtDeijcZfg8F9YqUTMfisDsEi1MbGnqawWwUerN9P5TjRBcCgYEAwcAfw8KTnQsvXPwWwh6Wabtz0bUAKzA/D6oWTR5IbkBfb3jNU8lmh9H66H0P18Nsa3vozA6buW2LDhHCFFkQ4PUTQVKok1qhAsvJBECxdwMqb5iAXk3Yk3qQYGhR23Zkp1u82wmpSaBLKGr+SL9/q5EamqiR3PQYx/aQTeIaFqcCgYAn/N/xXGKYl/++eeOuZ+5V0DmYQZBBGfDTbIUbweXxsBqiX4jNBBVhwTAPYBLgzhbZCVfQyxCOuVT10EOqMrkED35eVAIqoxvf3pSGOiaLUlV/+EMEhj9+1xI753y0FzQGsmWbV98WjiJYFkgaJ5j/BbqZxTRoo8RrjqmFsT5cgQKBgQCWTc4WlmbfSKMIloOtOf9jrMjvoWOtHXN+WmuMjfaQmR2wI13eJvqEWRA1tXdJ4c/FHk39p0OFOQbL9ljCYknmyhiS72XZUlBgE+kwhGNnuSv9gKftAKUH2+gO8j62awUwk8lRfxA2DsTfaQk1NGH9ncauviDR8QcccRmHYeTtNwKBgQCOvHiVaNw8XJIqt2r3j8pEJcr8LO+WNtLDU+h9NhM5a5NxfeRUlxdrqR0FXS4NkE6E3h9iLIRt2V+0bghzJMhKuwdjC0K6+jCb7ImV+Xcl9LNOQ1mPLBLS1jqdQnBS1ZPtcQpMrVi6dU9vVespylKEyGnQnUUtLgYrbO9OMrP1uQ==\n-----END RSA PRIVATE KEY-----",
|
||||
// "plaintext": "just testing",
|
||||
// "ciphertext": "LBicxglLvMyBin8uMpUnF5ARQ+KtAM563RViMepnOcyXa/NOJonNBixm+th+jX44\r\n/rie2ESbWg/FnlR4mHCEpTQJFXt12zpeXvtM8Hy1OQMud1B1Hc9hp1hhd1t6cuDz\r\n/Cs10n1+57V6zwHottYA6tn84cBn678SvPa/WTwgvb9lnBVZbesm3dVIr5uh2hk9\r\nNcVkmqyfi+ilkNQ3FIQfL+ciHvPFUIpljgIOipZhmufubdgMGW1HEUYlsmxLE7ce\r\ndpUQJoIbfKJ1x2dJRoeYsCjvcYFWdMUcg78HkXR+UcObP6zkK8cH33fb6PKKd8Z4\r\nToj4HROza8Dp7uCV5XyBTA=="
|
||||
// };
|
||||
// await checkTestData(testData);
|
||||
|
||||
// const testData = await createTestData();
|
||||
// await checkTestData(testData);
|
||||
|
||||
// await printTestData();
|
||||
|
||||
// await runIntegrationTests();
|
||||
|
||||
return null;
|
||||
|
@@ -9,6 +9,13 @@ interface LastSelectedPath {
|
||||
directory: string;
|
||||
}
|
||||
|
||||
interface OpenDialogOptions {
|
||||
properties?: string[];
|
||||
defaultPath?: string;
|
||||
createDirectory?: boolean;
|
||||
filters?: any[];
|
||||
}
|
||||
|
||||
export class Bridge {
|
||||
|
||||
private electronWrapper_: ElectronAppWrapper;
|
||||
@@ -155,14 +162,14 @@ export class Bridge {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
async showOpenDialog(options: any = null) {
|
||||
async showOpenDialog(options: OpenDialogOptions = null) {
|
||||
const { dialog } = require('electron');
|
||||
if (!options) options = {};
|
||||
let fileType = 'file';
|
||||
if (options.properties && options.properties.includes('openDirectory')) fileType = 'directory';
|
||||
if (!('defaultPath' in options) && (this.lastSelectedPaths_ as any)[fileType]) options.defaultPath = (this.lastSelectedPaths_ as any)[fileType];
|
||||
if (!('createDirectory' in options)) options.createDirectory = true;
|
||||
const { filePaths } = await dialog.showOpenDialog(this.window(), options);
|
||||
const { filePaths } = await dialog.showOpenDialog(this.window(), options as any);
|
||||
if (filePaths && filePaths.length) {
|
||||
(this.lastSelectedPaths_ as any)[fileType] = dirname(filePaths[0]);
|
||||
}
|
||||
@@ -258,7 +265,7 @@ export class Bridge {
|
||||
}
|
||||
}
|
||||
|
||||
restart() {
|
||||
restart(linuxSafeRestart = true) {
|
||||
// Note that in this case we are not sending the "appClose" event
|
||||
// to notify services and component that the app is about to close
|
||||
// but for the current use-case it's not really needed.
|
||||
@@ -269,7 +276,7 @@ export class Bridge {
|
||||
execPath: process.env.PORTABLE_EXECUTABLE_FILE,
|
||||
};
|
||||
app.relaunch(options);
|
||||
} else if (shim.isLinux()) {
|
||||
} else if (shim.isLinux() && linuxSafeRestart) {
|
||||
this.showInfoMessageBox(_('The app is now going to close. Please relaunch it to complete the process.'));
|
||||
} else {
|
||||
app.relaunch();
|
||||
|
@@ -4,7 +4,7 @@ import { _ } from '@joplin/lib/locale';
|
||||
import bridge from './services/bridge';
|
||||
import KvStore from '@joplin/lib/services/KvStore';
|
||||
const { fileExtension } = require('@joplin/lib/path-utils');
|
||||
const ArrayUtils = require('@joplin/lib/ArrayUtils');
|
||||
import * as ArrayUtils from '@joplin/lib/ArrayUtils';
|
||||
const packageInfo = require('./packageInfo.js');
|
||||
const compareVersions = require('compare-versions');
|
||||
|
||||
@@ -86,7 +86,7 @@ async function fetchLatestRelease(options: CheckForUpdateOptions) {
|
||||
const ext = fileExtension(asset.name);
|
||||
if (platform === 'win32' && ext === 'exe') {
|
||||
if (shim.isPortable()) {
|
||||
found = asset.name == 'JoplinPortable.exe';
|
||||
found = asset.name === 'JoplinPortable.exe';
|
||||
} else {
|
||||
found = !!asset.name.match(/^Joplin-Setup-[\d.]+\.exe$/);
|
||||
}
|
||||
|
19
packages/app-desktop/commands/editProfileConfig.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { openFileWithExternalEditor } from '@joplin/lib/services/ExternalEditWatcher/utils';
|
||||
import bridge from '../services/bridge';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'editProfileConfig',
|
||||
label: () => _('Edit profile configuration...'),
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (_context: CommandContext) => {
|
||||
await openFileWithExternalEditor(`${Setting.value('rootProfileDir')}/profiles.json`, bridge());
|
||||
},
|
||||
enabledCondition: 'hasMultiProfiles',
|
||||
};
|
||||
};
|
@@ -1,5 +1,6 @@
|
||||
// AUTO-GENERATED using `gulp buildCommandIndex`
|
||||
import * as copyDevCommand from './copyDevCommand';
|
||||
import * as editProfileConfig from './editProfileConfig';
|
||||
import * as exportFolders from './exportFolders';
|
||||
import * as exportNotes from './exportNotes';
|
||||
import * as focusElement from './focusElement';
|
||||
@@ -8,11 +9,16 @@ import * as replaceMisspelling from './replaceMisspelling';
|
||||
import * as restoreNoteRevision from './restoreNoteRevision';
|
||||
import * as startExternalEditing from './startExternalEditing';
|
||||
import * as stopExternalEditing from './stopExternalEditing';
|
||||
import * as switchProfile from './switchProfile';
|
||||
import * as switchProfile1 from './switchProfile1';
|
||||
import * as switchProfile2 from './switchProfile2';
|
||||
import * as switchProfile3 from './switchProfile3';
|
||||
import * as toggleExternalEditing from './toggleExternalEditing';
|
||||
import * as toggleSafeMode from './toggleSafeMode';
|
||||
|
||||
const index:any[] = [
|
||||
copyDevCommand,
|
||||
editProfileConfig,
|
||||
exportFolders,
|
||||
exportNotes,
|
||||
focusElement,
|
||||
@@ -21,6 +27,10 @@ const index:any[] = [
|
||||
restoreNoteRevision,
|
||||
startExternalEditing,
|
||||
stopExternalEditing,
|
||||
switchProfile,
|
||||
switchProfile1,
|
||||
switchProfile2,
|
||||
switchProfile3,
|
||||
toggleExternalEditing,
|
||||
toggleSafeMode,
|
||||
];
|
||||
|
@@ -1,19 +1,12 @@
|
||||
import CommandService, { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { AppState } from '../app.reducer';
|
||||
import bridge from '../services/bridge';
|
||||
import { isInsideContainer } from '@joplin/lib/dom';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'replaceMisspelling',
|
||||
};
|
||||
|
||||
function isInsideContainer(node: any, className: string): boolean {
|
||||
while (node) {
|
||||
if (node.classList && node.classList.contains(className)) return true;
|
||||
node = node.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext, suggestion: string) => {
|
||||
|
26
packages/app-desktop/commands/switchProfile.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { saveProfileConfig } from '@joplin/lib/services/profileConfig';
|
||||
import { ProfileConfig } from '@joplin/lib/services/profileConfig/types';
|
||||
import restart from '../services/restart';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'switchProfile',
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext, profileId: string) => {
|
||||
const currentConfig = context.state.profileConfig;
|
||||
if (currentConfig.currentProfileId === profileId) return;
|
||||
|
||||
const newConfig: ProfileConfig = {
|
||||
...currentConfig,
|
||||
currentProfileId: profileId,
|
||||
};
|
||||
|
||||
await saveProfileConfig(`${Setting.value('rootProfileDir')}/profiles.json`, newConfig);
|
||||
await restart(false);
|
||||
},
|
||||
};
|
||||
};
|
16
packages/app-desktop/commands/switchProfile1.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import CommandService, { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { profileIdByIndex } from '@joplin/lib/services/profileConfig';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'switchProfile1',
|
||||
label: () => _('Switch to profile %d', 1),
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext) => {
|
||||
await CommandService.instance().execute('switchProfile', profileIdByIndex(context.state.profileConfig, 0));
|
||||
},
|
||||
};
|
||||
};
|
16
packages/app-desktop/commands/switchProfile2.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import CommandService, { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { profileIdByIndex } from '@joplin/lib/services/profileConfig';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'switchProfile2',
|
||||
label: () => _('Switch to profile %d', 2),
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext) => {
|
||||
await CommandService.instance().execute('switchProfile', profileIdByIndex(context.state.profileConfig, 1));
|
||||
},
|
||||
};
|
||||
};
|
16
packages/app-desktop/commands/switchProfile3.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import CommandService, { CommandRuntime, CommandDeclaration, CommandContext } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { profileIdByIndex } from '@joplin/lib/services/profileConfig';
|
||||
|
||||
export const declaration: CommandDeclaration = {
|
||||
name: 'switchProfile3',
|
||||
label: () => _('Switch to profile %d', 3),
|
||||
};
|
||||
|
||||
export const runtime = (): CommandRuntime => {
|
||||
return {
|
||||
execute: async (context: CommandContext) => {
|
||||
await CommandService.instance().execute('switchProfile', profileIdByIndex(context.state.profileConfig, 2));
|
||||
},
|
||||
};
|
||||
};
|