Compare commits
851 Commits
sqlcipher_
...
v3.4.6
Author | SHA1 | Date | |
---|---|---|---|
|
4128061e40 | ||
|
432b0ca870 | ||
|
c484cd2e48 | ||
|
58f0725c6b | ||
|
bf8fbec0cd | ||
|
f1d452f130 | ||
|
26012cd7d5 | ||
|
a414241541 | ||
|
0f13bf9d51 | ||
|
c142c5c5c0 | ||
|
af5c0135dc | ||
|
8a811b9e78 | ||
|
602484f143 | ||
|
dc84db1657 | ||
|
f5882ecfcc | ||
|
30000c34ec | ||
|
6e3df1bd90 | ||
|
67196ac0b2 | ||
|
69646b5522 | ||
|
9147afce9a | ||
|
c92701c52f | ||
|
ab3e9d1a3e | ||
|
f9cab8843b | ||
|
c36289c024 | ||
|
60b6db8cd4 | ||
|
bbd8f6f40e | ||
|
34b7f4e1f8 | ||
|
06b681d897 | ||
|
f02a94bef5 | ||
|
ae6b57c5a5 | ||
|
88ab916008 | ||
|
97b0ffc263 | ||
|
ff8848d138 | ||
|
2b686e6318 | ||
|
b913d18882 | ||
|
a2c9a01722 | ||
|
000d23c20f | ||
|
9e9f2f2930 | ||
|
c5a1a759c7 | ||
|
0b6a1c75ba | ||
|
53a0f8ddbc | ||
|
67eabb5038 | ||
|
983fced410 | ||
|
4f5bbc1132 | ||
|
2f10235ecb | ||
|
cfa7d6cb31 | ||
|
f5d62a50fe | ||
|
b52f5435aa | ||
|
bfd5bfc004 | ||
|
82965fe991 | ||
|
b2c162c25b | ||
|
022e76fe8d | ||
|
4b2d1895fd | ||
|
534507a31f | ||
|
5b4a300c81 | ||
|
1de0a59313 | ||
|
f4dff92d2e | ||
|
a5d37a0dca | ||
|
75ef418b39 | ||
|
6bd702ae24 | ||
|
9ea1808766 | ||
|
59f8dd36a6 | ||
|
ea1d2e4878 | ||
|
46ab00bfe4 | ||
|
07465dd349 | ||
|
a288ffe338 | ||
|
dba62386b6 | ||
|
6704ab0d13 | ||
|
0312f2213d | ||
|
2ac0b66ef6 | ||
|
639b261ee4 | ||
|
82bc819a21 | ||
|
72f8ebe4ff | ||
|
8c8a38e704 | ||
|
358134038c | ||
|
1f4b32a241 | ||
|
2a216f1e61 | ||
|
3f75d770f7 | ||
|
b6d32831c6 | ||
|
788033cb5f | ||
|
4e685ec687 | ||
|
c60b703b9c | ||
|
f23e10a975 | ||
|
b9a71c0c3d | ||
|
f525c4179f | ||
|
1dd0ec619f | ||
|
d2ee5411d0 | ||
|
a2472cb3b7 | ||
|
ca8415f74a | ||
|
853b792367 | ||
|
56d477f1c1 | ||
|
020ba10c56 | ||
|
be09873c58 | ||
|
4d8a16bda7 | ||
|
f725d3895f | ||
|
0e19dce0d1 | ||
|
31c5058d5e | ||
|
4d760303bc | ||
|
23e63e5fec | ||
|
3880352f53 | ||
|
42a3c40702 | ||
|
8e585640e7 | ||
|
cd3fb4e7ad | ||
|
702b5b3c63 | ||
|
a80406dcb7 | ||
|
ea8b6485d8 | ||
|
1a2ef78726 | ||
|
63d5ffc796 | ||
|
15918a57aa | ||
|
032e8b5596 | ||
|
ee091ede52 | ||
|
763e3f7479 | ||
|
0089c62493 | ||
|
20d6d56c02 | ||
|
8b999f8dc6 | ||
|
0067ac126d | ||
|
c6f47a9084 | ||
|
22817317f1 | ||
|
9ba1c0db4e | ||
|
70d6c1225c | ||
|
b1f013a8c2 | ||
|
8c66349907 | ||
|
86b4f713ee | ||
|
f50dc6a536 | ||
|
825ce51a3c | ||
|
c5b6f0bca1 | ||
|
86934d502e | ||
|
c63ad17f98 | ||
|
c746b5fdc2 | ||
|
949fb85755 | ||
|
0f94cb8c17 | ||
|
7ba61bb585 | ||
|
00e4657a39 | ||
|
cbdc98553a | ||
|
e3c2589a12 | ||
|
56b3cc3dc2 | ||
|
d59a09fd29 | ||
|
5a64222276 | ||
|
012297d52a | ||
|
5e70bce2c3 | ||
|
4c3eca1f18 | ||
|
c899f63a41 | ||
|
c838b86413 | ||
|
90d6d1747a | ||
|
6e8ba8a536 | ||
|
ffeb5f887a | ||
|
65bde86263 | ||
|
1c236ca73c | ||
|
2881280100 | ||
|
954b48b779 | ||
|
53e7b672b0 | ||
|
ceaaab77e8 | ||
|
c29bbe96f7 | ||
|
db323ac585 | ||
|
dc8e3242f3 | ||
|
9705941538 | ||
|
0cf9981ac7 | ||
|
b93ee3469b | ||
|
73e5bc74a5 | ||
|
6c761b3fb4 | ||
|
e13985a952 | ||
|
8b912b22cf | ||
|
4c90cd62fe | ||
|
999ec8c11f | ||
|
d8e73f3141 | ||
|
3b1a4e8209 | ||
|
1ff0f0f1c8 | ||
|
68863db4bd | ||
|
f6b8462a5b | ||
|
f8d09ce847 | ||
|
f541618ed4 | ||
|
b023ddc4db | ||
|
3289b2ba30 | ||
|
0c52ac424d | ||
|
56529a1433 | ||
|
65981e5e8b | ||
|
798064b004 | ||
|
e5ffb7df4d | ||
|
49de4461d9 | ||
|
9cfd135bba | ||
|
e62cba5048 | ||
|
4d5097b585 | ||
|
e6b81d42c3 | ||
|
b705be33e1 | ||
|
984bb0f3ef | ||
|
cd158e584e | ||
|
91b0ea609d | ||
|
898888088c | ||
|
0a25b3bde6 | ||
|
ed8e709263 | ||
|
29e7594dc6 | ||
|
a0d38444bd | ||
|
e86e381fca | ||
|
0a6b8fb90a | ||
|
6c5293833d | ||
|
a2af3f460a | ||
|
30aff62d08 | ||
|
53fe12ab8a | ||
|
d52550e272 | ||
|
2c9084b9bc | ||
|
9dc5e0b73c | ||
|
c10a7aa4e8 | ||
|
e0e9edd395 | ||
|
d13f9626fa | ||
|
1bca9c1cf9 | ||
|
c9859a48fd | ||
|
add4ddfcb9 | ||
|
f92d5063cd | ||
|
98cb30631c | ||
|
c293ca2dd2 | ||
|
96d0035071 | ||
|
b2cdfd6358 | ||
|
89589981d0 | ||
|
9acda01d79 | ||
|
cc9f5cca07 | ||
|
bc1e83ba07 | ||
|
1ba1b028d8 | ||
|
6cb27e23ef | ||
|
2fee913ecf | ||
|
37b653dbdd | ||
|
4231f8cced | ||
|
3f9c60dd10 | ||
|
83f1fcc228 | ||
|
35e189ef6e | ||
|
a15bad37b1 | ||
|
b03e370d2b | ||
|
8b4ad0aaf7 | ||
|
c3575672b2 | ||
|
e840d0c3fd | ||
|
5227ba1adb | ||
|
ea49907327 | ||
|
0dd90a7542 | ||
|
a962f48b38 | ||
|
f68d2bbc7c | ||
|
65c9665a2a | ||
|
2c50ad36c5 | ||
|
7212269107 | ||
|
1387470f2a | ||
|
a6d5eb9b8e | ||
|
5d1a055d2a | ||
|
36910a2a9b | ||
|
b4a57a10aa | ||
|
bca8cb1c2d | ||
|
0b489a9c98 | ||
|
ce32651794 | ||
|
f0159cdd89 | ||
|
97652fa362 | ||
|
2af895477f | ||
|
4ddd5c4558 | ||
|
9d6aa1c739 | ||
|
3b27f84996 | ||
|
fc38691f3a | ||
|
d2274319f9 | ||
|
7746694dca | ||
|
a40448fed9 | ||
|
5ec79c74e2 | ||
|
bbba19eb40 | ||
|
75b89c7e09 | ||
|
f9af9a724c | ||
|
6e7c9c059d | ||
|
69ee435b0b | ||
|
204f1bf509 | ||
|
7a7a2c4cec | ||
|
441486acaa | ||
|
4684142df7 | ||
|
0a871ea44b | ||
|
901fe73c08 | ||
|
41553eb963 | ||
|
cada200575 | ||
|
13711c6a9c | ||
|
1a6acee5c8 | ||
|
0c2547a780 | ||
|
e0204d672b | ||
|
9c9b06de2d | ||
|
58f3344564 | ||
|
f6fef5a8ec | ||
|
e0211045db | ||
|
f757221d44 | ||
|
552ecc9064 | ||
|
7d4864193f | ||
|
81e2205a53 | ||
|
4e89890a23 | ||
|
60de33b8be | ||
|
84d6f5dfcb | ||
|
d0d80c0e4a | ||
|
798c1e1c2b | ||
|
1eef44d243 | ||
|
e5adaa7f74 | ||
|
671997af96 | ||
|
2bf968f9ad | ||
|
3e06dd989f | ||
|
3459355285 | ||
|
7406a89dc0 | ||
|
ace662cc79 | ||
|
0c5d5e59f3 | ||
|
b00aadb542 | ||
|
d6883e6ec1 | ||
|
6ac64ca0d9 | ||
|
9890d267a1 | ||
|
1a1335a7d5 | ||
|
67288f0b44 | ||
|
a0cd09cd5b | ||
|
6e5623ce6a | ||
|
032f26b1c5 | ||
|
d0030a904c | ||
|
a23d5d10b6 | ||
|
f9ccd15615 | ||
|
1f9f63d176 | ||
|
813f077312 | ||
|
6a5c85d3d7 | ||
|
1644f56447 | ||
|
85518edca1 | ||
|
ebc070b3c7 | ||
|
a33fb575fd | ||
|
ecc781ee39 | ||
|
f1ac95a1c7 | ||
|
098cabad40 | ||
|
4d01738029 | ||
|
3433293a0e | ||
|
02fd244096 | ||
|
00cd26fd82 | ||
|
38ca224a16 | ||
|
78e9ced96c | ||
|
bba6ede569 | ||
|
0fec577932 | ||
|
780d049502 | ||
|
a5d74e1ee7 | ||
|
d6b369b4f4 | ||
|
572e40c635 | ||
|
4af5c609fd | ||
|
8487fc1a34 | ||
|
a76fad3ddf | ||
|
a08af91153 | ||
|
3bcf221e52 | ||
|
0dd211c2fd | ||
|
b6fea2a4e2 | ||
|
73eb6cca38 | ||
|
449f49379d | ||
|
7a26d4f336 | ||
|
c4b951544b | ||
|
5746d4cdf6 | ||
|
71e4f35e79 | ||
|
5169371b68 | ||
|
24845bd7d8 | ||
|
00b7726cda | ||
|
ce9008998c | ||
|
776813acfe | ||
|
d13c213657 | ||
|
1895b3d067 | ||
|
863d00c595 | ||
|
1b8b1f7b2a | ||
|
ca8b68bd95 | ||
|
3c3e7c4854 | ||
|
aeab8e03ab | ||
|
a3cc34938b | ||
|
ec057e4e2e | ||
|
78eca9dfa9 | ||
|
174cc76ef4 | ||
|
ba5bb6e8ea | ||
|
0a8a19748e | ||
|
7884ce61a0 | ||
|
d7f2ffaa1e | ||
|
a79409dfa8 | ||
|
4777bd393c | ||
|
c7575e4726 | ||
|
efc5059d65 | ||
|
bd203ffe88 | ||
|
27717b46ac | ||
|
364b2496d6 | ||
|
b701992524 | ||
|
d00bd3b89d | ||
|
c80e789a8d | ||
|
503b31e67a | ||
|
1b5e538d6a | ||
|
c8cbe7271e | ||
|
7330efceaf | ||
|
da2229706c | ||
|
b81f5cb91e | ||
|
3b7a677302 | ||
|
0d176e434a | ||
|
ca46df5627 | ||
|
7389712093 | ||
|
3f3f7328f9 | ||
|
fda69c7a1e | ||
|
66ec4f8c51 | ||
|
d62ac838b8 | ||
|
487cb4f743 | ||
|
8eef48ac4b | ||
|
42a156c2bb | ||
|
caba91fdf6 | ||
|
360446cc79 | ||
|
8c0d5f4ac5 | ||
|
696fe4d5a6 | ||
|
c9027719dd | ||
|
c9936723c8 | ||
|
f6056b2d75 | ||
|
303ccce7d2 | ||
|
7a611ac5c5 | ||
|
45d1d862a1 | ||
|
99178fb1c6 | ||
|
1462284f2f | ||
|
c392854bdf | ||
|
2ebb3f039d | ||
|
c8fd9a2b39 | ||
|
869b1e6f98 | ||
|
ee04f28356 | ||
|
d3ac7ad1c3 | ||
|
da4e3fc5bb | ||
|
73808f5a25 | ||
|
c887a86fd8 | ||
|
b0d888ee73 | ||
|
d9c9bed393 | ||
|
f16b6e8887 | ||
|
9c8fcbe0c2 | ||
|
6760468da3 | ||
|
3d3e8a70fa | ||
|
9b65123335 | ||
|
8493decc03 | ||
|
c28e838f17 | ||
|
22779a7f15 | ||
|
f2aac66e56 | ||
|
b956da47fa | ||
|
8134390bf4 | ||
|
631211b40c | ||
|
144ed593cc | ||
|
47d0d3eb9e | ||
|
4498c5bc0f | ||
|
1716562292 | ||
|
efcfd12489 | ||
|
42f6a9d03d | ||
|
73a2075a69 | ||
|
c5ca0151a1 | ||
|
9ffeb8c725 | ||
|
884141c3e2 | ||
|
f0d1dd1dd0 | ||
|
70e7d8f820 | ||
|
100c35cf7f | ||
|
5b42f4f2a2 | ||
|
a47d7906af | ||
|
73ed17e851 | ||
|
484deb450b | ||
|
3d2ac91b8a | ||
|
0fc665d6d8 | ||
|
961349c1f3 | ||
|
ab95d728d9 | ||
|
ca653d3e88 | ||
|
945b309a4d | ||
|
ab17625ed8 | ||
|
8e8ab3bd80 | ||
|
591a56e510 | ||
|
86ee95a8d0 | ||
|
a527a278a9 | ||
|
eb1970fd1a | ||
|
1ecaaa1910 | ||
|
c75b48fbb1 | ||
|
608dbab453 | ||
|
291ba88224 | ||
|
bdbd16240b | ||
|
4f826c045a | ||
|
885fde4119 | ||
|
f8200efffc | ||
|
700ddf269a | ||
|
a755f09033 | ||
|
293eac9c04 | ||
|
f5e751c27a | ||
|
47e4f36f97 | ||
|
fa0dbddb9b | ||
|
c9eb9af741 | ||
|
d1cd8e9db4 | ||
|
16ebff78b4 | ||
|
423ae0d633 | ||
|
04a976e459 | ||
|
88c95cc91c | ||
|
24df674726 | ||
|
3faa95a066 | ||
|
60e27924ae | ||
|
d5830dd3a1 | ||
|
a4dacd65e6 | ||
|
cbf6d5506f | ||
|
80696fe324 | ||
|
1780a530c9 | ||
|
dc786e8178 | ||
|
e65fbecef0 | ||
|
5b2f409254 | ||
|
77a07c937e | ||
|
50c5139fa6 | ||
|
465defb194 | ||
|
12c688eb83 | ||
|
1a6059072a | ||
|
e2ef406aa2 | ||
|
dca28f8c2a | ||
|
a8ea71c349 | ||
|
b13e7c1a3f | ||
|
ecfef1a9da | ||
|
ffd9c8e0a0 | ||
|
a4b0d149bc | ||
|
c2b7228170 | ||
|
11c8f1e111 | ||
|
a1f37dc414 | ||
|
e4a20f505d | ||
|
dfa7ed0a5c | ||
|
f8bf799f00 | ||
|
c70faf50f7 | ||
|
e422a88bb0 | ||
|
74ef89d25b | ||
|
b6043489a0 | ||
|
37270479e2 | ||
|
318ca3de5f | ||
|
1f57a94225 | ||
|
cce2f66f01 | ||
|
277935b8b1 | ||
|
981759691d | ||
|
370f6bd70e | ||
|
067ce65532 | ||
|
302577ed43 | ||
|
5356a8ae36 | ||
|
4d790b6ffe | ||
|
b6d8dcee8d | ||
|
e5b2e22479 | ||
|
6e98a8ac2d | ||
|
6b60a88dcb | ||
|
765cde10fb | ||
|
8f97bb6ddf | ||
|
073984b9ef | ||
|
5e5a77786c | ||
|
7fa3a223b2 | ||
|
5c965d4b95 | ||
|
cc3da4fd09 | ||
|
34528d146f | ||
|
9c76560642 | ||
|
3cb621eb60 | ||
|
d9ba532889 | ||
|
5aca4bc72e | ||
|
54e7499aa2 | ||
|
941b70471f | ||
|
3f364a4a9b | ||
|
ae47667644 | ||
|
b191b1daf7 | ||
|
0e3b9fd929 | ||
|
5d0fa754ae | ||
|
70d76fa00f | ||
|
d72224a6b9 | ||
|
687516e695 | ||
|
3055873406 | ||
|
e58e419c1b | ||
|
ebd55cc505 | ||
|
712f4034f2 | ||
|
601774c611 | ||
|
7a810380fd | ||
|
52d71756a7 | ||
|
a6b430a066 | ||
|
5a97ce74bc | ||
|
e58e03c3d2 | ||
|
511645b1a5 | ||
|
b9ffc7ccec | ||
|
b585b8b75c | ||
|
f7d1dbde8f | ||
|
6009f1dd60 | ||
|
e50086134f | ||
|
25c66e2d00 | ||
|
6d89725c7a | ||
|
dfdabfc0da | ||
|
2059e96227 | ||
|
40e4afbc78 | ||
|
76a22c31cb | ||
|
175628b597 | ||
|
e7584644b5 | ||
|
13a572efa9 | ||
|
d85394681d | ||
|
c785388c51 | ||
|
27be923fe6 | ||
|
a7bfa21cd0 | ||
|
e9fe944744 | ||
|
b93a125f95 | ||
|
262c343f21 | ||
|
8aa37905f9 | ||
|
28b7251e16 | ||
|
2a5b227bf0 | ||
|
7223e9b87e | ||
|
82d9099ec0 | ||
|
c46502825d | ||
|
58688624fc | ||
|
355356dccc | ||
|
d4d12c0faa | ||
|
9218c7df1f | ||
|
f8f8db36b6 | ||
|
a8e30c5b54 | ||
|
ffd775a8f8 | ||
|
8d421d907e | ||
|
3206b1a792 | ||
|
37137f3867 | ||
|
e08fd0ea53 | ||
|
6265be924a | ||
|
079c4638fe | ||
|
6aba57f2f1 | ||
|
f083ffa73c | ||
|
40fd0db14e | ||
|
6379023165 | ||
|
66f6310c17 | ||
|
d6409b7826 | ||
|
1f68c5dcae | ||
|
bfe003a6c4 | ||
|
ddc75ecc13 | ||
|
e953290810 | ||
|
807bcdcf95 | ||
|
6bb289338e | ||
|
5f0e4bb598 | ||
|
84d97e4120 | ||
|
a9efdad059 | ||
|
388e5efe17 | ||
|
dfa340a137 | ||
|
cf626bee76 | ||
|
0fe97a1098 | ||
|
7c6c9b3e61 | ||
|
987c273376 | ||
|
0da05737c6 | ||
|
f71ffa1644 | ||
|
92a546a315 | ||
|
22ffa69382 | ||
|
e1a436f6f9 | ||
|
b3823025cf | ||
|
eccb8350fe | ||
|
66203bda56 | ||
|
0759fe0530 | ||
|
6d3c3a80ab | ||
|
a18bcac673 | ||
|
b3a3690b16 | ||
|
c3fe0edeeb | ||
|
56e2d3da89 | ||
|
3ffcf065fc | ||
|
9dd82259c6 | ||
|
2dbdf47239 | ||
|
2014fbf480 | ||
|
e847b1b902 | ||
|
26276efc03 | ||
|
4226044527 | ||
|
5ba6ac57d0 | ||
|
0058ac5f4b | ||
|
81f5a8463e | ||
|
9871717de4 | ||
|
62ca6cb70b | ||
|
bd49f3b280 | ||
|
cb3c9b4607 | ||
|
4e74ca93a3 | ||
|
5389e59057 | ||
|
3d15e64762 | ||
|
a8b18e9ab0 | ||
|
5876d57845 | ||
|
90f622b3e6 | ||
|
fd486e298a | ||
|
527627b8bb | ||
|
9638cab9ea | ||
|
5ad891e1f3 | ||
|
f8445a04e5 | ||
|
fc92a6ea63 | ||
|
418a2c17a5 | ||
|
c3cc412077 | ||
|
600000a59a | ||
|
a3be7b5222 | ||
|
52ffd46a6a | ||
|
587db433a8 | ||
|
5fb9d216fc | ||
|
bb50ad7c28 | ||
|
7a6a4e118a | ||
|
b7a652fb71 | ||
|
821558fe30 | ||
|
5280ec12cd | ||
|
a29e30e442 | ||
|
fe88703488 | ||
|
338dabf5da | ||
|
59447f4c45 | ||
|
04196e4485 | ||
|
d4fafd74d2 | ||
|
f185480ceb | ||
|
4da0abfef9 | ||
|
2e73ea2d9f | ||
|
8ac19d80ea | ||
|
911689a4ac | ||
|
5c73bda416 | ||
|
c94dbece42 | ||
|
e49e314bdb | ||
|
83452dd4c3 | ||
|
675e3125e4 | ||
|
da0a7faf12 | ||
|
9be533a19e | ||
|
050871bc65 | ||
|
8d6d7ca6d2 | ||
|
032f512cde | ||
|
b8c88af82d | ||
|
962128faa3 | ||
|
e17ef72111 | ||
|
287e0da4b4 | ||
|
471f5a72fe | ||
|
1e5c41dc48 | ||
|
716e5252c1 | ||
|
f10fd4b2da | ||
|
ff4d18dec3 | ||
|
020cd914af | ||
|
8dcfc81cee | ||
|
77048caeeb | ||
|
3438c58ec4 | ||
|
e74d5e7c23 | ||
|
c921976e9d | ||
|
c8a2802181 | ||
|
0f08688ce8 | ||
|
f5f7b1eb60 | ||
|
9d73e583b9 | ||
|
611e8df81a | ||
|
b0c9c4c8ce | ||
|
dad0b9448f | ||
|
c524f5a6b5 | ||
|
ee2b186752 | ||
|
76a3250707 | ||
|
e8144f9ee2 | ||
|
47f6b1ce33 | ||
|
f0121e7799 | ||
|
0acb14d0bf | ||
|
18ebd16428 | ||
|
6bc1965ec0 | ||
|
1fed875140 | ||
|
98fe57e87a | ||
|
5bcb2531f4 | ||
|
f6d69ef702 | ||
|
1f05a3212f | ||
|
ff0321e906 | ||
|
6b881b226e | ||
|
6a26ec8105 | ||
|
5966402d8b | ||
|
5198b598bb | ||
|
0a4c97c631 | ||
|
0bc62aa05e | ||
|
44d1e9e3ca | ||
|
0cef6cc611 | ||
|
3e5acfbc09 | ||
|
fe20ab11a1 | ||
|
675f55d152 | ||
|
b1edb84b49 | ||
|
ece7a4ccf0 | ||
|
cfd98d2723 | ||
|
2a17301a9f | ||
|
e3762dc3f8 | ||
|
0959a19d65 | ||
|
93219575b4 | ||
|
baaeea1307 | ||
|
de6c5d448f | ||
|
cc2cf5f521 | ||
|
ef513862a9 | ||
|
d07f3b5f16 | ||
|
a6079869bc | ||
|
2fdbb22481 | ||
|
c5bb88ddf4 | ||
|
5d7c78c361 | ||
|
808eb7d49a | ||
|
2142373fff | ||
|
20f7f37b49 | ||
|
04fc634092 | ||
|
d40c9d3ff9 | ||
|
224b4f619a | ||
|
88d1d4b7d1 | ||
|
6a22ffbcb1 | ||
|
d735cf64e0 | ||
|
d7d6fd5ccd | ||
|
23254e6ffd | ||
|
eb8bfd5aec | ||
|
cb5ffd968d | ||
|
7b2b3a4f80 | ||
|
cbfe109c41 | ||
|
c8b01d11d6 | ||
|
b042395fd1 | ||
|
ba5ad18093 | ||
|
ff15232a10 | ||
|
5a6e72197a | ||
|
de555b6871 | ||
|
9a2548a5e3 | ||
|
107996289f | ||
|
c3c0101555 | ||
|
45ee02036f | ||
|
64f3dae8cc | ||
|
0909479b7f | ||
|
a39b51cc97 | ||
|
10bb8ef1a9 | ||
|
60ba22b233 | ||
|
1bfd997be2 | ||
|
81e4a7fb74 | ||
|
360568d325 | ||
|
1aa0f11670 | ||
|
0430ccb3e7 | ||
|
c0d6c1eb0b | ||
|
215f09d73c | ||
|
1f192696de | ||
|
ab86b95fad | ||
|
0f07c0f53a | ||
|
a6d04c4781 | ||
|
bc27f47881 | ||
|
f381c91783 | ||
|
d1d75449f5 | ||
|
79dc12ae0a | ||
|
bbea5388ed | ||
|
99e773855e | ||
|
55b73347e5 | ||
|
7e8dee4906 | ||
|
69fb1ab104 | ||
|
67ae0ea2d1 | ||
|
cdb61b922b | ||
|
da80443796 | ||
|
1924dd31d2 | ||
|
b831d8c068 | ||
|
9a697a0e34 | ||
|
4ad1b49769 | ||
|
0d6c1067e3 | ||
|
0bdc38a6be | ||
|
7735fc9759 | ||
|
5c35569b5b | ||
|
5f02af9724 | ||
|
975f16d21c | ||
|
54428f5034 | ||
|
e6ef0d45c6 | ||
|
ebe9c38f9e | ||
|
ccebb9696e | ||
|
16ba072436 | ||
|
5a81e2ce84 | ||
|
8e407dd003 | ||
|
6118c572ac | ||
|
fd8393b2f9 | ||
|
15edc9fec7 | ||
|
35053f2996 | ||
|
8bd4770f33 | ||
|
4af459c762 | ||
|
6ad97a01a8 | ||
|
3e05b8daa0 | ||
|
41cb16f5c5 | ||
|
543ece86b0 | ||
|
44f98d6282 | ||
|
438bf29e5f | ||
|
0a1f960919 | ||
|
5bc7304c63 | ||
|
efec21156b | ||
|
85747317ee | ||
|
9f4a80cf89 | ||
|
1b3ebf4fb0 | ||
|
bcd10e380b | ||
|
1bc64cfdff | ||
|
ab46f6decd | ||
|
49535e4a3e | ||
|
4c35d811d6 | ||
|
0dec21b2bb | ||
|
ad8c9263e8 | ||
|
04de21a9fd | ||
|
d266ec92c4 | ||
|
63fce9cfb0 | ||
|
7c50e00fb4 |
17
.env-sample
@@ -15,6 +15,23 @@
|
||||
# POSTGRES_PORT=5432
|
||||
# POSTGRES_HOST=localhost
|
||||
|
||||
# =============================================================================
|
||||
# TRANSCRIBE CONFIG EXAMPLE
|
||||
# -----------------------------------------------------------------------------
|
||||
# This service is not required, and it will be ignored by using --profile server
|
||||
# when running docker-compose. If you want to use it, you need to set the
|
||||
# following environment variables.
|
||||
# =============================================================================
|
||||
|
||||
# TRANSCRIBE_API_KEY=secret_string_shared_between_server_and_transcribe
|
||||
# TRANSCRIBE_ENABLED=true
|
||||
|
||||
# QUEUE_DATABASE_NAME=transcribe
|
||||
# QUEUE_DATABASE_USER=transcribe
|
||||
# QUEUE_DATABASE_PASSWORD=transcribe
|
||||
# QUEUE_DATABASE_PORT=5431
|
||||
# HTR_CLI_IMAGES_FOLDER=/home/user/images_storage
|
||||
|
||||
# =============================================================================
|
||||
# DEV CONFIG EXAMPLE
|
||||
# -----------------------------------------------------------------------------
|
||||
|
34
.env-transcribe-sample
Normal file
@@ -0,0 +1,34 @@
|
||||
# =============================================================================
|
||||
# Required
|
||||
# -----------------------------------------------------------------------------
|
||||
# =============================================================================
|
||||
|
||||
SERVER_PORT=4567
|
||||
|
||||
API_KEY=random-string
|
||||
QUEUE_TTL=900000
|
||||
QUEUE_RETRY_COUNT=2
|
||||
QUEUE_MAINTENANCE_INTERVAL=30000
|
||||
|
||||
HTR_CLI_DOCKER_IMAGE=joplin/htr-cli:latest
|
||||
# Fullpath to images folder e.g.:
|
||||
#HTR_CLI_IMAGES_FOLDER=/home/user/joplin/packages/transcribe/images
|
||||
HTR_CLI_IMAGES_FOLDER=
|
||||
|
||||
QUEUE_DRIVER=pg
|
||||
# QUEUE_DRIVER=sqlite
|
||||
|
||||
FILE_STORAGE_MAINTENANCE_INTERVAL=3600000
|
||||
FILE_STORAGE_TTL=604800000 # one week
|
||||
|
||||
# =============================================================================
|
||||
# Queue driver
|
||||
# -----------------------------------------------------------------------------
|
||||
# =============================================================================
|
||||
#
|
||||
# QUEUE_DATABASE_NAME=./queue.sqlite3
|
||||
QUEUE_DATABASE_NAME=transcribe
|
||||
QUEUE_DATABASE_USER=transcribe
|
||||
QUEUE_DATABASE_PASSWORD=transcribe
|
||||
QUEUE_DATABASE_PORT=5432
|
||||
QUEUE_DATABASE_HOST=localhost
|
347
.eslintignore
@@ -55,6 +55,7 @@ packages/app-desktop/vendor/lib/
|
||||
packages/app-mobile/packageInfo.js
|
||||
packages/app-mobile/android
|
||||
packages/app-mobile/**/*.bundle.js
|
||||
packages/app-mobile/**/*.bundle.css
|
||||
packages/app-mobile/web/public/pluginAssets/**/*
|
||||
packages/app-mobile/ios
|
||||
packages/app-mobile/lib/rnInjectedJs/
|
||||
@@ -62,6 +63,7 @@ packages/app-mobile/locales
|
||||
packages/app-mobile/node_modules
|
||||
packages/app-mobile/pluginAssets/
|
||||
packages/fork-*
|
||||
!packages/fork-uslug
|
||||
packages/default-plugins/plugin-base-repo/
|
||||
packages/default-plugins/plugin-sources/
|
||||
packages/htmlpack/dist/
|
||||
@@ -73,10 +75,12 @@ packages/lib/services/database/types.ts
|
||||
packages/lib/vendor/
|
||||
packages/lib/vendor/fountain.min.js
|
||||
packages/lib/welcomeAssets.js
|
||||
packages/editor/*/vendor/
|
||||
packages/plugins/**/api
|
||||
packages/plugins/**/dist
|
||||
packages/server/dist/
|
||||
packages/utils/dist/
|
||||
packages/transcribe/dist/
|
||||
packages/tools/node_modules
|
||||
packages/tools/PortableAppsLauncher
|
||||
packages/turndown-plugin-gfm/
|
||||
@@ -94,6 +98,7 @@ packages/app-cli/app/app.js
|
||||
packages/app-cli/app/base-command.js
|
||||
packages/app-cli/app/command-apidoc.js
|
||||
packages/app-cli/app/command-attach.js
|
||||
packages/app-cli/app/command-batch.js
|
||||
packages/app-cli/app/command-cat.js
|
||||
packages/app-cli/app/command-config.js
|
||||
packages/app-cli/app/command-cp.js
|
||||
@@ -120,6 +125,8 @@ packages/app-cli/app/command-rmnote.test.js
|
||||
packages/app-cli/app/command-rmnote.js
|
||||
packages/app-cli/app/command-set.js
|
||||
packages/app-cli/app/command-settingschema.js
|
||||
packages/app-cli/app/command-share.test.js
|
||||
packages/app-cli/app/command-share.js
|
||||
packages/app-cli/app/command-sync.js
|
||||
packages/app-cli/app/command-testing.js
|
||||
packages/app-cli/app/command-use.js
|
||||
@@ -128,6 +135,9 @@ packages/app-cli/app/gui/FolderListWidget.js
|
||||
packages/app-cli/app/gui/StatusBarWidget.js
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js
|
||||
packages/app-cli/app/setupCommand.js
|
||||
packages/app-cli/app/utils/initializeCommandService.js
|
||||
packages/app-cli/app/utils/iterateStdin.js
|
||||
packages/app-cli/app/utils/shimInitCli.js
|
||||
packages/app-cli/app/utils/testUtils.js
|
||||
packages/app-cli/tests/HtmlToMd.js
|
||||
packages/app-cli/tests/MarkupToHtml.js
|
||||
@@ -149,7 +159,10 @@ packages/app-desktop/app.reducer.js
|
||||
packages/app-desktop/app.js
|
||||
packages/app-desktop/bridge.js
|
||||
packages/app-desktop/checkForUpdates.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.test.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.js
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyToClipboard.js
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
packages/app-desktop/commands/emptyTrash.js
|
||||
packages/app-desktop/commands/exportDeletionLog.test.js
|
||||
@@ -159,7 +172,9 @@ packages/app-desktop/commands/exportNotes.js
|
||||
packages/app-desktop/commands/focusElement.js
|
||||
packages/app-desktop/commands/index.js
|
||||
packages/app-desktop/commands/openNoteInNewWindow.js
|
||||
packages/app-desktop/commands/openPrimaryAppInstance.js
|
||||
packages/app-desktop/commands/openProfileDirectory.js
|
||||
packages/app-desktop/commands/openSecondaryAppInstance.js
|
||||
packages/app-desktop/commands/replaceMisspelling.js
|
||||
packages/app-desktop/commands/restoreNoteRevision.js
|
||||
packages/app-desktop/commands/startExternalEditing.js
|
||||
@@ -186,6 +201,7 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||
packages/app-desktop/gui/ConversionNotification/ConversionNotification.js
|
||||
packages/app-desktop/gui/Dialog.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
@@ -206,6 +222,7 @@ packages/app-desktop/gui/InlineCombobox.js
|
||||
packages/app-desktop/gui/ItemList.js
|
||||
packages/app-desktop/gui/JoplinCloudConfigScreen.js
|
||||
packages/app-desktop/gui/JoplinCloudLoginScreen.js
|
||||
packages/app-desktop/gui/JoplinCloudSignUpCallToAction.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
|
||||
packages/app-desktop/gui/KeymapConfig/styles/index.js
|
||||
@@ -264,6 +281,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useKeyboardRefocusHan
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useLinkTooltips.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTabIndenter.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTextPatternsLookup.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useWebViewApi.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteEditor.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
|
||||
@@ -272,6 +290,7 @@ packages/app-desktop/gui/NoteEditor/WarningBanner/BannerContent.js
|
||||
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteViewer.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementToolbar.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/index.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
|
||||
@@ -284,12 +303,14 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/getResourceBaseUrl.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/getWindowCommandPriority.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/types.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useConnectToEditorPlugin.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
|
||||
@@ -353,13 +374,16 @@ packages/app-desktop/gui/NoteSearchBar.js
|
||||
packages/app-desktop/gui/NoteStatusBar.js
|
||||
packages/app-desktop/gui/NoteTextViewer.js
|
||||
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
|
||||
packages/app-desktop/gui/NotyfContext.js
|
||||
packages/app-desktop/gui/OneDriveLoginScreen.js
|
||||
packages/app-desktop/gui/PasswordInput/LabelledPasswordInput.js
|
||||
packages/app-desktop/gui/PasswordInput/PasswordInput.js
|
||||
packages/app-desktop/gui/PasswordInput/types.js
|
||||
packages/app-desktop/gui/PdfViewer.js
|
||||
packages/app-desktop/gui/PluginNotification/PluginNotification.js
|
||||
packages/app-desktop/gui/PopupNotification/NotificationItem.js
|
||||
packages/app-desktop/gui/PopupNotification/PopupNotificationList.js
|
||||
packages/app-desktop/gui/PopupNotification/PopupNotificationProvider.js
|
||||
packages/app-desktop/gui/PopupNotification/types.js
|
||||
packages/app-desktop/gui/PromptDialog.js
|
||||
packages/app-desktop/gui/ResizableLayout/LayoutItemContainer.js
|
||||
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
|
||||
@@ -410,6 +434,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
|
||||
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
|
||||
packages/app-desktop/gui/Sidebar/styles/index.js
|
||||
packages/app-desktop/gui/Sidebar/types.js
|
||||
packages/app-desktop/gui/SsoLoginScreen/SsoLoginScreen.js
|
||||
packages/app-desktop/gui/StatusScreen/StatusScreen.js
|
||||
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
|
||||
packages/app-desktop/gui/SyncWizard/Dialog.js
|
||||
@@ -421,6 +446,7 @@ packages/app-desktop/gui/ToolbarBase.js
|
||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||
packages/app-desktop/gui/ToolbarSpace.js
|
||||
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
||||
packages/app-desktop/gui/TrashNotification/TrashNotificationMessage.js
|
||||
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/AppDialogs.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/ModalMessageOverlay.js
|
||||
@@ -435,7 +461,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/linkToNote.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
|
||||
@@ -524,15 +549,20 @@ packages/app-desktop/integration-tests/sidebar.spec.js
|
||||
packages/app-desktop/integration-tests/simpleBackup.spec.js
|
||||
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
|
||||
packages/app-desktop/integration-tests/util/createStartupArgs.js
|
||||
packages/app-desktop/integration-tests/util/evaluateWithRetry.js
|
||||
packages/app-desktop/integration-tests/util/extendedExpect.js
|
||||
packages/app-desktop/integration-tests/util/firstNonDevToolsWindow.js
|
||||
packages/app-desktop/integration-tests/util/getImageSourceSize.js
|
||||
packages/app-desktop/integration-tests/util/getMainWindow.js
|
||||
packages/app-desktop/integration-tests/util/retryOnFailure.js
|
||||
packages/app-desktop/integration-tests/util/setDarkMode.js
|
||||
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
|
||||
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
|
||||
packages/app-desktop/integration-tests/util/setSettingValue.js
|
||||
packages/app-desktop/integration-tests/util/test.js
|
||||
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
|
||||
packages/app-desktop/integration-tests/wcag.spec.js
|
||||
packages/app-desktop/main-html.js
|
||||
packages/app-desktop/main.js
|
||||
packages/app-desktop/playwright.config.js
|
||||
packages/app-desktop/plugins/GotoAnything.js
|
||||
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
|
||||
@@ -547,19 +577,23 @@ packages/app-desktop/services/plugins/UserWebview.js
|
||||
packages/app-desktop/services/plugins/UserWebviewDialog.js
|
||||
packages/app-desktop/services/plugins/UserWebviewDialogButtonBar.js
|
||||
packages/app-desktop/services/plugins/hooks/useContentSize.js
|
||||
packages/app-desktop/services/plugins/hooks/useFormData.js
|
||||
packages/app-desktop/services/plugins/hooks/useHtmlLoader.js
|
||||
packages/app-desktop/services/plugins/hooks/useMessageHandler.js
|
||||
packages/app-desktop/services/plugins/hooks/useScriptLoader.js
|
||||
packages/app-desktop/services/plugins/hooks/useSubmitHandler.js
|
||||
packages/app-desktop/services/plugins/hooks/useThemeCss.test.js
|
||||
packages/app-desktop/services/plugins/hooks/useThemeCss.js
|
||||
packages/app-desktop/services/plugins/hooks/useViewIsReady.js
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
|
||||
packages/app-desktop/services/plugins/types.js
|
||||
packages/app-desktop/services/restart.js
|
||||
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.test.js
|
||||
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
|
||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
|
||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
||||
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
||||
packages/app-desktop/tools/bundleJs.js
|
||||
packages/app-desktop/tools/copy7Zip.js
|
||||
packages/app-desktop/tools/generateLatestArm64Yml.js
|
||||
packages/app-desktop/tools/githubReleasesUtils.js
|
||||
@@ -574,13 +608,16 @@ packages/app-desktop/utils/customProtocols/constants.js
|
||||
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
|
||||
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
|
||||
packages/app-desktop/utils/customProtocols/registerCustomProtocols.js
|
||||
packages/app-desktop/utils/getAssetPath.js
|
||||
packages/app-desktop/utils/initializeCommandService.js
|
||||
packages/app-desktop/utils/isSafeToOpen.test.js
|
||||
packages/app-desktop/utils/isSafeToOpen.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.js
|
||||
packages/app-desktop/utils/sourceMapSetup.js
|
||||
packages/app-desktop/utils/window/types.js
|
||||
packages/app-mobile/PluginAssetsLoader.js
|
||||
packages/app-mobile/commands/dismissPluginPanels.js
|
||||
packages/app-mobile/commands/index.js
|
||||
packages/app-mobile/commands/newNote.test.js
|
||||
packages/app-mobile/commands/newNote.js
|
||||
@@ -590,19 +627,29 @@ packages/app-mobile/commands/scrollToHash.js
|
||||
packages/app-mobile/commands/util/goToNote.js
|
||||
packages/app-mobile/commands/util/showResource.js
|
||||
packages/app-mobile/components/BetaChip.js
|
||||
packages/app-mobile/components/BottomDrawer.js
|
||||
packages/app-mobile/components/CameraView/ActionButtons.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.jest.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.web.js
|
||||
packages/app-mobile/components/CameraView/Camera/types.js
|
||||
packages/app-mobile/components/CameraView/CameraView.test.js
|
||||
packages/app-mobile/components/CameraView/CameraView.js
|
||||
packages/app-mobile/components/CameraView/CameraView.web.js
|
||||
packages/app-mobile/components/CameraView/CameraViewMultiPage.test.js
|
||||
packages/app-mobile/components/CameraView/CameraViewMultiPage.js
|
||||
packages/app-mobile/components/CameraView/PhotoPreview.js
|
||||
packages/app-mobile/components/CameraView/ScannedBarcodes.js
|
||||
packages/app-mobile/components/CameraView/types.js
|
||||
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
|
||||
packages/app-mobile/components/CameraView/utils/testing.js
|
||||
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
|
||||
packages/app-mobile/components/Checkbox.js
|
||||
packages/app-mobile/components/ComboBox.test.js
|
||||
packages/app-mobile/components/ComboBox.js
|
||||
packages/app-mobile/components/DialogManager/PromptButton.js
|
||||
packages/app-mobile/components/DialogManager/PromptDialog.js
|
||||
packages/app-mobile/components/DialogManager/TextInputDialog.js
|
||||
packages/app-mobile/components/DialogManager/hooks/useDialogControl.js
|
||||
packages/app-mobile/components/DialogManager/index.js
|
||||
packages/app-mobile/components/DialogManager/types.js
|
||||
@@ -624,74 +671,72 @@ packages/app-mobile/components/ExtendedWebView/index.jest.js
|
||||
packages/app-mobile/components/ExtendedWebView/index.js
|
||||
packages/app-mobile/components/ExtendedWebView/index.web.js
|
||||
packages/app-mobile/components/ExtendedWebView/types.js
|
||||
packages/app-mobile/components/ExtendedWebView/utils/useCss.js
|
||||
packages/app-mobile/components/FolderPicker.js
|
||||
packages/app-mobile/components/Icon.js
|
||||
packages/app-mobile/components/IconButton.js
|
||||
packages/app-mobile/components/Modal.js
|
||||
packages/app-mobile/components/ModalDialog.js
|
||||
packages/app-mobile/components/NestableFlatList.js
|
||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
|
||||
packages/app-mobile/components/NoteBodyViewer/types.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/isEditableResource.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/applyTemplateToEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/polyfills.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/startAutosaveLoop.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/watchEditorForTemplateChanges.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/utils/useEditorMessenger.js
|
||||
packages/app-mobile/components/NoteEditor/MarkdownEditor.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js
|
||||
packages/app-mobile/components/NoteEditor/RichTextEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/RichTextEditor.js
|
||||
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
||||
packages/app-mobile/components/NoteEditor/WarningBanner.js
|
||||
packages/app-mobile/components/NoteEditor/commandDeclarations.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
|
||||
packages/app-mobile/components/NoteEditor/testing/createTestEditorProps.js
|
||||
packages/app-mobile/components/NoteEditor/types.js
|
||||
packages/app-mobile/components/NoteItem.js
|
||||
packages/app-mobile/components/NoteList.js
|
||||
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
||||
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
||||
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
||||
packages/app-mobile/components/SafeAreaView.js
|
||||
packages/app-mobile/components/ScreenHeader/Menu.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBanner.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBox.js
|
||||
packages/app-mobile/components/ScreenHeader/WebBetaButton.js
|
||||
packages/app-mobile/components/ScreenHeader/index.js
|
||||
packages/app-mobile/components/SearchInput.js
|
||||
packages/app-mobile/components/SelectDateTimeDialog.js
|
||||
packages/app-mobile/components/SideMenu.js
|
||||
packages/app-mobile/components/SideMenuContentNote.js
|
||||
packages/app-mobile/components/TagEditor.test.js
|
||||
packages/app-mobile/components/TagEditor.js
|
||||
packages/app-mobile/components/TextInput.js
|
||||
packages/app-mobile/components/ToggleSpaceButton.js
|
||||
packages/app-mobile/components/accessibility/AccessibleModalMenu.js
|
||||
packages/app-mobile/components/accessibility/AccessibleView.test.js
|
||||
packages/app-mobile/components/accessibility/AccessibleView.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/AutoFocusProvider.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/FocusControl.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/FocusControlProvider.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/MainAppContent.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/ModalWrapper.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/types.js
|
||||
packages/app-mobile/components/app-nav.js
|
||||
packages/app-mobile/components/base-screen.js
|
||||
packages/app-mobile/components/biometrics/BiometricPopup.js
|
||||
packages/app-mobile/components/biometrics/biometricAuthenticate.js
|
||||
packages/app-mobile/components/biometrics/sensorInfo.js
|
||||
packages/app-mobile/components/buttons/FloatingActionButton.js
|
||||
packages/app-mobile/components/buttons/LabelledIconButton.js
|
||||
packages/app-mobile/components/buttons/MultiTouchableOpacity.js
|
||||
packages/app-mobile/components/buttons/TextButton.js
|
||||
packages/app-mobile/components/buttons/index.js
|
||||
packages/app-mobile/components/getResponsiveValue.test.js
|
||||
@@ -699,6 +744,7 @@ packages/app-mobile/components/getResponsiveValue.js
|
||||
packages/app-mobile/components/global-style.js
|
||||
packages/app-mobile/components/plugins/PluginNotification.js
|
||||
packages/app-mobile/components/plugins/PluginRunner.js
|
||||
packages/app-mobile/components/plugins/PluginRunnerWebView.test.js
|
||||
packages/app-mobile/components/plugins/PluginRunnerWebView.js
|
||||
packages/app-mobile/components/plugins/backgroundPage/initializeDialogWebView.js
|
||||
packages/app-mobile/components/plugins/backgroundPage/initializePluginBackgroundIframe.js
|
||||
@@ -738,8 +784,11 @@ packages/app-mobile/components/screens/ConfigScreen/SectionSelector/SectionTab.j
|
||||
packages/app-mobile/components/screens/ConfigScreen/SectionSelector/index.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingComponent.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingItem.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingTextInput.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/ValidatedIntegerInput.test.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/ValidatedIntegerInput.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/InstalledPluginBox.js
|
||||
@@ -767,6 +816,8 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/types.js
|
||||
packages/app-mobile/components/screens/DocumentScanner/DocumentScanner.js
|
||||
packages/app-mobile/components/screens/DocumentScanner/NotePreview.js
|
||||
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
|
||||
packages/app-mobile/components/screens/LogScreen.js
|
||||
packages/app-mobile/components/screens/Note/Note.test.js
|
||||
@@ -778,14 +829,21 @@ packages/app-mobile/components/screens/Note/commands/insertDateTime.js
|
||||
packages/app-mobile/components/screens/Note/commands/setTags.js
|
||||
packages/app-mobile/components/screens/Note/commands/toggleVisiblePanes.js
|
||||
packages/app-mobile/components/screens/Note/types.js
|
||||
packages/app-mobile/components/screens/NoteRevisionViewer.test.js
|
||||
packages/app-mobile/components/screens/NoteRevisionViewer.js
|
||||
packages/app-mobile/components/screens/NoteTagsDialog.js
|
||||
packages/app-mobile/components/screens/Notes.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.js
|
||||
packages/app-mobile/components/screens/Notes/Notes.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.js
|
||||
packages/app-mobile/components/screens/SearchScreen/index.js
|
||||
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
|
||||
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
|
||||
packages/app-mobile/components/screens/ShareManager/index.test.js
|
||||
packages/app-mobile/components/screens/ShareManager/index.js
|
||||
packages/app-mobile/components/screens/ShareNoteDialog.test.js
|
||||
packages/app-mobile/components/screens/ShareNoteDialog.js
|
||||
packages/app-mobile/components/screens/SsoLoginScreen.js
|
||||
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
|
||||
packages/app-mobile/components/screens/dropbox-login.js
|
||||
packages/app-mobile/components/screens/encryption-config.test.js
|
||||
@@ -798,6 +856,38 @@ packages/app-mobile/components/voiceTyping/AudioRecordingBanner.js
|
||||
packages/app-mobile/components/voiceTyping/RecordingControls.js
|
||||
packages/app-mobile/components/voiceTyping/SpeechToTextBanner.js
|
||||
packages/app-mobile/components/voiceTyping/types.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/applyTemplateToEditor.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.test.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/startAutosaveLoop.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/types.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/watchEditorForTemplateChanges.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/utils/useEditorMessenger.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/contentScript.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/types.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/utils/useCodeMirrorPlugins.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.test.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/types.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/addPluginAssets.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/afterFullPageRender.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/makeResourceModel.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/types.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useContentScripts.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.test.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/convertHtmlToMarkdown.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/types.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/types.js
|
||||
packages/app-mobile/contentScripts/utils/polyfills.js
|
||||
packages/app-mobile/contentScripts/utils/readFileToBase64.js
|
||||
packages/app-mobile/contentScripts/utils/setUpLogger.js
|
||||
packages/app-mobile/gulpfile.js
|
||||
packages/app-mobile/index.web.js
|
||||
packages/app-mobile/root.js
|
||||
@@ -820,7 +910,7 @@ packages/app-mobile/services/voiceTyping/whisper.js
|
||||
packages/app-mobile/setupQuickActions.js
|
||||
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
|
||||
packages/app-mobile/tools/buildInjectedJs/constants.js
|
||||
packages/app-mobile/tools/buildInjectedJs/copyJs.js
|
||||
packages/app-mobile/tools/buildInjectedJs/copyAssets.js
|
||||
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
|
||||
packages/app-mobile/tools/copyAssets.js
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
@@ -829,11 +919,13 @@ packages/app-mobile/utils/ShareUtils.js
|
||||
packages/app-mobile/utils/TlsUtils.js
|
||||
packages/app-mobile/utils/appDefaultState.js
|
||||
packages/app-mobile/utils/autodetectTheme.js
|
||||
packages/app-mobile/utils/buildStartupTasks.js
|
||||
packages/app-mobile/utils/checkPermissions.js
|
||||
packages/app-mobile/utils/createRootStyle.js
|
||||
packages/app-mobile/utils/database-driver-react-native.js
|
||||
packages/app-mobile/utils/database-driver-react-native.web.js
|
||||
packages/app-mobile/utils/debounce.js
|
||||
packages/app-mobile/utils/focusView.js
|
||||
packages/app-mobile/utils/fs-driver/constants.js
|
||||
packages/app-mobile/utils/fs-driver/fs-driver-rn.js
|
||||
packages/app-mobile/utils/fs-driver/fs-driver-rn.web.js
|
||||
@@ -846,20 +938,23 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
|
||||
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
|
||||
packages/app-mobile/utils/getPackageInfo.js
|
||||
packages/app-mobile/utils/getVersionInfoText.js
|
||||
packages/app-mobile/utils/hooks/useKeyboardVisible.js
|
||||
packages/app-mobile/utils/hooks/useBackHandler.js
|
||||
packages/app-mobile/utils/hooks/useKeyboardState.js
|
||||
packages/app-mobile/utils/hooks/useOnLongPressProps.js
|
||||
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
|
||||
packages/app-mobile/utils/hooks/useSafeAreaPadding.js
|
||||
packages/app-mobile/utils/image/fileToImage.web.js
|
||||
packages/app-mobile/utils/image/getImageDimensions.js
|
||||
packages/app-mobile/utils/image/resizeImage.js
|
||||
packages/app-mobile/utils/initializeCommandService.js
|
||||
packages/app-mobile/utils/injectedJs.js
|
||||
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
|
||||
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
|
||||
packages/app-mobile/utils/lockToSingleInstance.js
|
||||
packages/app-mobile/utils/makeShowMessageBox.test.js
|
||||
packages/app-mobile/utils/makeShowMessageBox.js
|
||||
packages/app-mobile/utils/pickDocument.js
|
||||
packages/app-mobile/utils/polyfills/bufferPolyfill.js
|
||||
packages/app-mobile/utils/polyfills/crypto-polyfill/index.js
|
||||
packages/app-mobile/utils/polyfills/index.js
|
||||
packages/app-mobile/utils/setupNotifications.js
|
||||
packages/app-mobile/utils/shareFile.js
|
||||
@@ -872,6 +967,7 @@ packages/app-mobile/utils/testing/createMockReduxStore.js
|
||||
packages/app-mobile/utils/testing/getWebViewDomById.js
|
||||
packages/app-mobile/utils/testing/getWebViewWindowById.js
|
||||
packages/app-mobile/utils/testing/setupGlobalStore.js
|
||||
packages/app-mobile/utils/testing/testingLibrary.js
|
||||
packages/app-mobile/utils/types.js
|
||||
packages/app-mobile/web/serviceWorker.js
|
||||
packages/app-mobile/web/webpack.config.js
|
||||
@@ -882,7 +978,6 @@ packages/default-plugins/commands/editPatch.js
|
||||
packages/default-plugins/utils/getCurrentCommitHash.js
|
||||
packages/default-plugins/utils/getPathToPatchFileFor.js
|
||||
packages/default-plugins/utils/readRepositoryJson.js
|
||||
packages/default-plugins/utils/waitForCliInput.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
|
||||
@@ -897,43 +992,69 @@ packages/editor/CodeMirror/editorCommands/duplicateLine.js
|
||||
packages/editor/CodeMirror/editorCommands/editorCommands.js
|
||||
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
|
||||
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
|
||||
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.test.js
|
||||
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.js
|
||||
packages/editor/CodeMirror/editorCommands/jumpToHash.test.js
|
||||
packages/editor/CodeMirror/editorCommands/jumpToHash.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.bulletedVsChecklist.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.js
|
||||
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
|
||||
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
|
||||
packages/editor/CodeMirror/editorCommands/supportsCommand.js
|
||||
packages/editor/CodeMirror/extensions/biDirectionalTextExtension.js
|
||||
packages/editor/CodeMirror/extensions/ctrlClickActionExtension.js
|
||||
packages/editor/CodeMirror/extensions/ctrlClickCheckboxExtension.js
|
||||
packages/editor/CodeMirror/extensions/keyUpHandlerExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/ctrlClickLinksExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/followLinkTooltipExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/links/followLinkTooltipExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/referenceLinksStateField.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/findLineMatchingLink.test.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/findLineMatchingLink.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/getUrlAtPosition.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/openLink.js
|
||||
packages/editor/CodeMirror/extensions/markdownDecorationExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownDecorationExtension.js
|
||||
packages/editor/CodeMirror/extensions/markdownHighlightExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownHighlightExtension.js
|
||||
packages/editor/CodeMirror/extensions/markdownMathExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownMathExtension.js
|
||||
packages/editor/CodeMirror/extensions/modifierKeyCssExtension.js
|
||||
packages/editor/CodeMirror/extensions/overwriteModeExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/overwriteModeExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/addFormattingClasses.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderBlockImages.test.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderBlockImages.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderingExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceBulletLists.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceCheckboxes.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceDividers.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceFormatCharacters.js
|
||||
packages/editor/CodeMirror/extensions/rendering/types.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/makeBlockReplaceExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/makeInlineReplaceExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/nodeIntersectsSelection.js
|
||||
packages/editor/CodeMirror/extensions/searchExtension.js
|
||||
packages/editor/CodeMirror/extensions/selectedNoteIdExtension.js
|
||||
packages/editor/CodeMirror/getScrollFraction.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownMathExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownMathExtension.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
|
||||
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
|
||||
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
|
||||
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/decoratorExtension.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.js
|
||||
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.test.js
|
||||
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.js
|
||||
packages/editor/CodeMirror/markdown/utils/stripBlockquote.js
|
||||
packages/editor/CodeMirror/index.js
|
||||
packages/editor/CodeMirror/pluginApi/PluginLoader.js
|
||||
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
|
||||
packages/editor/CodeMirror/testUtil/createEditorControl.js
|
||||
packages/editor/CodeMirror/testUtil/createEditorSettings.js
|
||||
packages/editor/CodeMirror/testUtil/createTestEditor.js
|
||||
packages/editor/CodeMirror/testUtil/findNodesWithName.js
|
||||
packages/editor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testUtil/typeText.js
|
||||
packages/editor/CodeMirror/testing/createEditorControl.js
|
||||
packages/editor/CodeMirror/testing/createTestEditor.js
|
||||
packages/editor/CodeMirror/testing/findNodesWithName.js
|
||||
packages/editor/CodeMirror/testing/forceFullParse.js
|
||||
packages/editor/CodeMirror/testing/loadLanguages.js
|
||||
packages/editor/CodeMirror/testing/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testing/typeText.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/utils/biDirectionalTextExtension.js
|
||||
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
|
||||
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.test.js
|
||||
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.js
|
||||
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
|
||||
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
|
||||
packages/editor/CodeMirror/utils/formatting/isIndentationEquivalent.js
|
||||
@@ -952,15 +1073,63 @@ packages/editor/CodeMirror/utils/handleLinkEditRequests.js
|
||||
packages/editor/CodeMirror/utils/handlePasteEvent.js
|
||||
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
|
||||
packages/editor/CodeMirror/utils/isInSyntaxNode.js
|
||||
packages/editor/CodeMirror/utils/keyUpHandlerExtension.js
|
||||
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
|
||||
packages/editor/CodeMirror/utils/overwriteModeExtension.js
|
||||
packages/editor/CodeMirror/utils/searchExtension.js
|
||||
packages/editor/CodeMirror/utils/selectedNoteIdExtension.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/allLanguages.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/defaultLanguage.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/lookUpLanguage.js
|
||||
packages/editor/CodeMirror/utils/markdown/getCheckboxAtPosition.js
|
||||
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.test.js
|
||||
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.js
|
||||
packages/editor/CodeMirror/utils/markdown/stripBlockquote.js
|
||||
packages/editor/CodeMirror/utils/markdown/toggleCheckboxAt.js
|
||||
packages/editor/CodeMirror/utils/setupVim.js
|
||||
packages/editor/ProseMirror/commands.test.js
|
||||
packages/editor/ProseMirror/commands.js
|
||||
packages/editor/ProseMirror/createEditor.js
|
||||
packages/editor/ProseMirror/index.js
|
||||
packages/editor/ProseMirror/plugins/detailsPlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/detailsPlugin.js
|
||||
packages/editor/ProseMirror/plugins/inputRulesPlugin.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/createEditorDialog.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/joplinEditablePlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/joplinEditablePlugin.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/postProcessRenderedHtml.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditorApiPlugin.js
|
||||
packages/editor/ProseMirror/plugins/keymapPlugin.js
|
||||
packages/editor/ProseMirror/plugins/linkTooltipPlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/linkTooltipPlugin.js
|
||||
packages/editor/ProseMirror/plugins/listPlugin.js
|
||||
packages/editor/ProseMirror/plugins/originalMarkupPlugin.js
|
||||
packages/editor/ProseMirror/plugins/resourcePlaceholderPlugin.js
|
||||
packages/editor/ProseMirror/plugins/searchPlugin.js
|
||||
packages/editor/ProseMirror/schema.js
|
||||
packages/editor/ProseMirror/styles.js
|
||||
packages/editor/ProseMirror/testing/createTestEditor.js
|
||||
packages/editor/ProseMirror/types.js
|
||||
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
|
||||
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
|
||||
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
|
||||
packages/editor/ProseMirror/utils/dom/createButton.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextArea.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextNode.js
|
||||
packages/editor/ProseMirror/utils/dom/createUniqueId.js
|
||||
packages/editor/ProseMirror/utils/extractSelectedLinesTo.test.js
|
||||
packages/editor/ProseMirror/utils/extractSelectedLinesTo.js
|
||||
packages/editor/ProseMirror/utils/forEachHeading.js
|
||||
packages/editor/ProseMirror/utils/jumpToHash.js
|
||||
packages/editor/ProseMirror/utils/makeLinksClickableInElement.js
|
||||
packages/editor/ProseMirror/utils/preprocessEditorInput.test.js
|
||||
packages/editor/ProseMirror/utils/preprocessEditorInput.js
|
||||
packages/editor/ProseMirror/utils/sanitizeHtml.js
|
||||
packages/editor/ProseMirror/utils/trimEmptyParagraphs.js
|
||||
packages/editor/ProseMirror/vendor/changedDescendants.js
|
||||
packages/editor/ProseMirror/vendor/splitBlockAs.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
packages/editor/events.js
|
||||
packages/editor/polyfills.js
|
||||
packages/editor/testing/createEditorSettings.js
|
||||
packages/editor/testing/setUpLogger.js
|
||||
packages/editor/types.js
|
||||
packages/editor/utils/getFileFromPasteEvent.js
|
||||
packages/fork-htmlparser2/src/CollectingHandler.js
|
||||
packages/fork-htmlparser2/src/FeedHandler.spec.js
|
||||
packages/fork-htmlparser2/src/FeedHandler.js
|
||||
@@ -975,13 +1144,18 @@ packages/fork-htmlparser2/src/__tests__/events.js
|
||||
packages/fork-htmlparser2/src/__tests__/stream.js
|
||||
packages/fork-htmlparser2/src/index.spec.js
|
||||
packages/fork-htmlparser2/src/index.js
|
||||
packages/fork-uslug/lib/uslug.test.js
|
||||
packages/fork-uslug/lib/uslug.js
|
||||
packages/generator-joplin/generators/app/templates/api/index.js
|
||||
packages/generator-joplin/generators/app/templates/api/noteListType.js
|
||||
packages/generator-joplin/generators/app/templates/api/types.js
|
||||
packages/generator-joplin/generators/app/templates/api_index.js
|
||||
packages/generator-joplin/generators/app/templates/src/index.js
|
||||
packages/generator-joplin/tools/updateCategories.js
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/index.test.js
|
||||
packages/htmlpack/index.js
|
||||
packages/htmlpack/packToString.js
|
||||
packages/htmlpack/utils/parseHtmlAsync.js
|
||||
packages/lib/ArrayUtils.js
|
||||
packages/lib/AsyncActionQueue.test.js
|
||||
packages/lib/AsyncActionQueue.js
|
||||
@@ -1000,12 +1174,15 @@ packages/lib/JoplinDatabase.js
|
||||
packages/lib/JoplinError.js
|
||||
packages/lib/JoplinServerApi.js
|
||||
packages/lib/ObjectUtils.js
|
||||
packages/lib/PerformanceLogger.test.js
|
||||
packages/lib/PerformanceLogger.js
|
||||
packages/lib/PoorManIntervals.js
|
||||
packages/lib/RotatingLogs.test.js
|
||||
packages/lib/RotatingLogs.js
|
||||
packages/lib/SyncTargetFilesystem.js
|
||||
packages/lib/SyncTargetJoplinCloud.js
|
||||
packages/lib/SyncTargetJoplinServer.js
|
||||
packages/lib/SyncTargetJoplinServerSAML.js
|
||||
packages/lib/SyncTargetNone.js
|
||||
packages/lib/SyncTargetOneDrive.js
|
||||
packages/lib/SyncTargetRegistry.js
|
||||
@@ -1016,21 +1193,36 @@ packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/clipperUtils.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.test.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.js
|
||||
packages/lib/commands/deleteNote.js
|
||||
packages/lib/commands/historyBackward.js
|
||||
packages/lib/commands/historyForward.js
|
||||
packages/lib/commands/index.js
|
||||
packages/lib/commands/leaveSharedFolder.js
|
||||
packages/lib/commands/openMasterPasswordDialog.js
|
||||
packages/lib/commands/permanentlyDeleteNote.js
|
||||
packages/lib/commands/renderMarkup.test.js
|
||||
packages/lib/commands/renderMarkup.js
|
||||
packages/lib/commands/showEditorPlugin.js
|
||||
packages/lib/commands/synchronize.js
|
||||
packages/lib/commands/toggleAllFolders.test.js
|
||||
packages/lib/commands/toggleAllFolders.js
|
||||
packages/lib/commands/toggleEditorPlugin.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.test.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.js
|
||||
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextDismissLinkClick.js
|
||||
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextReadMoreLinkClick.js
|
||||
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
|
||||
packages/lib/components/shared/NoteRevisionViewer/getHelpMessage.js
|
||||
packages/lib/components/shared/NoteRevisionViewer/useDeleteHistoryClick.js
|
||||
packages/lib/components/shared/SamlShared.js
|
||||
packages/lib/components/shared/ShareNoteDialog/onUnshareNoteClick.js
|
||||
packages/lib/components/shared/ShareNoteDialog/types.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useOnShareLinkClick.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useShareStatusMessage.js
|
||||
packages/lib/components/shared/SsoScreenShared.js
|
||||
packages/lib/components/shared/config/config-shared.js
|
||||
packages/lib/components/shared/config/plugins/types.js
|
||||
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
|
||||
@@ -1063,12 +1255,15 @@ packages/lib/fs-driver-base.js
|
||||
packages/lib/fs-driver-node.js
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/geolocation-node.js
|
||||
packages/lib/getAppName.test.js
|
||||
packages/lib/getAppName.js
|
||||
packages/lib/hooks/plugins/usePlugin.js
|
||||
packages/lib/hooks/plugins/useVisiblePluginEditorViewIds.js
|
||||
packages/lib/hooks/useAsyncEffect.js
|
||||
packages/lib/hooks/useElementSize.js
|
||||
packages/lib/hooks/useEventListener.js
|
||||
packages/lib/hooks/useNowEffect.test.js
|
||||
packages/lib/hooks/useNowEffect.js
|
||||
packages/lib/hooks/usePlugin.js
|
||||
packages/lib/hooks/usePrevious.js
|
||||
packages/lib/hooks/useQueuedAsyncEffect.test.js
|
||||
packages/lib/hooks/useQueuedAsyncEffect.js
|
||||
@@ -1123,6 +1318,7 @@ packages/lib/models/settings/settingValidations.js
|
||||
packages/lib/models/settings/types.js
|
||||
packages/lib/models/utils/areAllFoldersCollapsed.test.js
|
||||
packages/lib/models/utils/areAllFoldersCollapsed.js
|
||||
packages/lib/models/utils/getCanBeCollapsedFolderIds.test.js
|
||||
packages/lib/models/utils/getCanBeCollapsedFolderIds.js
|
||||
packages/lib/models/utils/getCollator.js
|
||||
packages/lib/models/utils/getConflictFolderId.js
|
||||
@@ -1193,6 +1389,7 @@ packages/lib/services/database/migrations/44.js
|
||||
packages/lib/services/database/migrations/45.js
|
||||
packages/lib/services/database/migrations/46.js
|
||||
packages/lib/services/database/migrations/47.js
|
||||
packages/lib/services/database/migrations/48.js
|
||||
packages/lib/services/database/migrations/index.js
|
||||
packages/lib/services/database/sqlStringToLines.js
|
||||
packages/lib/services/database/types.js
|
||||
@@ -1261,6 +1458,8 @@ packages/lib/services/ocr/OcrDriverBase.js
|
||||
packages/lib/services/ocr/OcrService.test.js
|
||||
packages/lib/services/ocr/OcrService.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTesseract.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTranscribe.test.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTranscribe.js
|
||||
packages/lib/services/ocr/utils/filterOcrText.test.js
|
||||
packages/lib/services/ocr/utils/filterOcrText.js
|
||||
packages/lib/services/ocr/utils/types.js
|
||||
@@ -1308,12 +1507,14 @@ packages/lib/services/plugins/testing/MockPluginRunner.js
|
||||
packages/lib/services/plugins/utils/createViewHandle.js
|
||||
packages/lib/services/plugins/utils/executeSandboxCall.js
|
||||
packages/lib/services/plugins/utils/getActivePluginEditorView.js
|
||||
packages/lib/services/plugins/utils/getActivePluginEditorViews.js
|
||||
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
|
||||
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
|
||||
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingValue.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorView.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorViewIds.js
|
||||
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.test.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.js
|
||||
@@ -1428,6 +1629,7 @@ packages/lib/shim-init-node.js
|
||||
packages/lib/shim.js
|
||||
packages/lib/string-utils.test.js
|
||||
packages/lib/string-utils.js
|
||||
packages/lib/testing/plugins/createTestPlugin.js
|
||||
packages/lib/testing/share/makeMockShareInvitation.js
|
||||
packages/lib/testing/share/mockShareService.js
|
||||
packages/lib/testing/syncTargetUtils.js
|
||||
@@ -1469,11 +1671,13 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
|
||||
packages/lib/utils/joplinCloud/index.js
|
||||
packages/lib/utils/joplinCloud/types.js
|
||||
packages/lib/utils/markupLanguageUtils.js
|
||||
packages/lib/utils/prefixWithHttps.js
|
||||
packages/lib/utils/processStartFlags.js
|
||||
packages/lib/utils/replaceUnsupportedCharacters.test.js
|
||||
packages/lib/utils/replaceUnsupportedCharacters.js
|
||||
packages/lib/utils/resolvePathWithinDir.test.js
|
||||
packages/lib/utils/resolvePathWithinDir.js
|
||||
packages/lib/utils/types/pdfJs.js
|
||||
packages/lib/utils/userFetcher.js
|
||||
packages/lib/utils/webDAVUtils.test.js
|
||||
packages/lib/utils/webDAVUtils.js
|
||||
@@ -1565,6 +1769,19 @@ packages/tools/checkIgnoredFiles.js
|
||||
packages/tools/checkLibPaths.test.js
|
||||
packages/tools/checkLibPaths.js
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/fuzzer/ActionTracker.js
|
||||
packages/tools/fuzzer/Client.js
|
||||
packages/tools/fuzzer/ClientPool.js
|
||||
packages/tools/fuzzer/Server.js
|
||||
packages/tools/fuzzer/constants.js
|
||||
packages/tools/fuzzer/sync-fuzzer.js
|
||||
packages/tools/fuzzer/types.js
|
||||
packages/tools/fuzzer/utils/SeededRandom.js
|
||||
packages/tools/fuzzer/utils/getNumberProperty.js
|
||||
packages/tools/fuzzer/utils/getProperty.js
|
||||
packages/tools/fuzzer/utils/getStringProperty.js
|
||||
packages/tools/fuzzer/utils/openDebugSession.js
|
||||
packages/tools/fuzzer/utils/retryWithCount.js
|
||||
packages/tools/generate-database-types.js
|
||||
packages/tools/generate-images.js
|
||||
packages/tools/git-changelog.test.js
|
||||
@@ -1595,6 +1812,8 @@ packages/tools/release-electron.js
|
||||
packages/tools/release-ios.js
|
||||
packages/tools/release-plugin-repo-cli.js
|
||||
packages/tools/release-server.js
|
||||
packages/tools/release-transcribe.js
|
||||
packages/tools/saveClaConsentRecords.js
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/spellcheck.js
|
||||
packages/tools/tagServerLatest.js
|
||||
|
@@ -23,6 +23,9 @@ module.exports = {
|
||||
'FileSystemCreateWritableOptions': 'readonly',
|
||||
'FileSystemHandle': 'readonly',
|
||||
'IDBTransactionMode': 'readonly',
|
||||
'FlatArray': 'readonly',
|
||||
'BigInt': 'readonly',
|
||||
'globalThis': 'readonly',
|
||||
|
||||
// ServiceWorker
|
||||
'ExtendableEvent': 'readonly',
|
||||
@@ -57,6 +60,8 @@ module.exports = {
|
||||
'tinymce': 'readonly',
|
||||
|
||||
'JSX': 'readonly',
|
||||
|
||||
'NodeJS': 'readonly',
|
||||
},
|
||||
'parserOptions': {
|
||||
'ecmaVersion': 2018,
|
||||
@@ -309,7 +314,7 @@ module.exports = {
|
||||
selector: 'interface',
|
||||
format: null,
|
||||
'filter': {
|
||||
'regex': '^(RSA|RSAKeyPair)$',
|
||||
'regex': '^(RSA|RSAKeyPair|iOS.*)$',
|
||||
'match': true,
|
||||
},
|
||||
},
|
||||
|
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Feature Requests
|
||||
url: https://discourse.joplinapp.org/c/features/
|
||||
about: Discuss ideas for new features or changes
|
||||
- name: Support
|
||||
url: https://discourse.joplinapp.org/c/support/
|
||||
about: Please ask for help here
|
||||
about: Please ask for help here
|
||||
|
34
.github/scripts/publish_docker_manifest.sh
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
VERSION=$(echo "$GIT_TAG_NAME" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
|
||||
|
||||
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||
echo "VERSION=$VERSION"
|
||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
||||
|
||||
# Check if it's a server release, otherwise exit
|
||||
if [[ $GIT_TAG_NAME != $SERVER_TAG_PREFIX-* ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest inspect $SERVER_REPOSITORY:arm64-$VERSION > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Image $SERVER_REPOSITORY:arm64-$VERSION does not exist on the remote registry."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest inspect $SERVER_REPOSITORY:amd64-$VERSION > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Image $SERVER_REPOSITORY:amd64-$VERSION does not exist on the remote registry."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker manifest create $SERVER_REPOSITORY:$VERSION \
|
||||
$SERVER_REPOSITORY:arm64-$VERSION \
|
||||
$SERVER_REPOSITORY:amd64-$VERSION
|
||||
|
||||
docker manifest annotate $SERVER_REPOSITORY:$VERSION $SERVER_REPOSITORY:arm64-$VERSION --arch arm64
|
||||
docker manifest annotate $SERVER_REPOSITORY:$VERSION $SERVER_REPOSITORY:amd64-$VERSION --arch amd64
|
||||
|
||||
docker manifest push $SERVER_REPOSITORY:$VERSION
|
50
.github/scripts/run_ci.sh
vendored
@@ -7,9 +7,13 @@
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
ROOT_DIR="$SCRIPT_DIR/../.."
|
||||
|
||||
TRANSCRIBE_TAG_PREFIX=transcribe
|
||||
TRANSCRIBE_REPOSITORY=joplin/transcribe
|
||||
|
||||
IS_PULL_REQUEST=0
|
||||
IS_DESKTOP_RELEASE=0
|
||||
IS_SERVER_RELEASE=0
|
||||
IS_TRANSCRIBE_RELEASE=0
|
||||
IS_LINUX=0
|
||||
IS_MACOS=0
|
||||
|
||||
@@ -23,6 +27,10 @@ if [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
||||
IS_SERVER_RELEASE=1
|
||||
fi
|
||||
|
||||
if [[ $GIT_TAG_NAME = $TRANSCRIBE_TAG_PREFIX-* ]]; then
|
||||
IS_TRANSCRIBE_RELEASE=1
|
||||
fi
|
||||
|
||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||
IS_DESKTOP_RELEASE=1
|
||||
fi
|
||||
@@ -35,18 +43,45 @@ else
|
||||
IS_MACOS=1
|
||||
fi
|
||||
|
||||
DOCKER_IMAGE_PLATFORM="linux/amd64"
|
||||
|
||||
# Tests can randomly fail in some cases, so only run them when not publishing
|
||||
# a release
|
||||
RUN_TESTS=0
|
||||
|
||||
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ]; then
|
||||
if [ "$IS_SERVER_RELEASE" = 0 ] && [ "$IS_DESKTOP_RELEASE" = 0 ] && [ "$IS_TRANSCRIBE_RELEASE" = 0 ]; then
|
||||
RUN_TESTS=1
|
||||
fi
|
||||
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
if [ "$IS_SERVER_RELEASE" == "0" ] && [ "$IS_TRANSCRIBE_RELEASE" == "0" ]; then
|
||||
# We exit now because nothing works properly with the ARM64 architecture.
|
||||
# We only proceed if building the server image.
|
||||
echo "Running on ARM64 and not trying to build server image - early exit"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
# Canvas is only needed for tests and it doesn't build in ARM64 so remove it
|
||||
RUN_TESTS=0
|
||||
cd "$ROOT_DIR/packages/lib"
|
||||
yarn remove canvas
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
DOCKER_IMAGE_PLATFORM="linux/arm64"
|
||||
|
||||
# Delete certain directories because `yarn install` will fail on ARM64.
|
||||
rm -rf app-desktop
|
||||
rm -rf app-mobile
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Print environment
|
||||
# =============================================================================
|
||||
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "RUNNER_ARCH=$RUNNER_ARCH"
|
||||
echo "GITHUB_WORKFLOW=$GITHUB_WORKFLOW"
|
||||
echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
|
||||
echo "GITHUB_REF=$GITHUB_REF"
|
||||
@@ -55,11 +90,14 @@ 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 "TRANSCRIBE_TAG_PREFIX=$TRANSCRIBE_TAG_PREFIX"
|
||||
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
|
||||
|
||||
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
||||
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
||||
echo "IS_DESKTOP_RELEASE=$IS_DESKTOP_RELEASE"
|
||||
echo "IS_SERVER_RELEASE=$IS_SERVER_RELEASE"
|
||||
echo "IS_TRANSCRIBE_RELEASE=$IS_TRANSCRIBE_RELEASE"
|
||||
echo "RUN_TESTS=$RUN_TESTS"
|
||||
echo "IS_LINUX=$IS_LINUX"
|
||||
echo "IS_MACOS=$IS_MACOS"
|
||||
@@ -91,7 +129,7 @@ if [ "$RUN_TESTS" == "1" ]; then
|
||||
# On Linux, we run the Joplin Server tests using PostgreSQL
|
||||
if [ "$IS_LINUX" == "1" ]; then
|
||||
echo "Running Joplin Server tests using PostgreSQL..."
|
||||
sudo docker compose --file docker-compose.db-dev.yml up -d
|
||||
sudo docker compose --parallel 1 --file docker-compose.db-dev.yml up -d
|
||||
cmdResult=$?
|
||||
if [ $cmdResult -ne 0 ]; then
|
||||
exit $cmdResult
|
||||
@@ -275,9 +313,13 @@ if [ "$IS_DESKTOP_RELEASE" == "1" ]; then
|
||||
USE_HARD_LINKS=false yarn dist
|
||||
fi
|
||||
elif [[ $IS_LINUX = 1 ]] && [ "$IS_SERVER_RELEASE" == "1" ]; then
|
||||
echo "Step: Building Docker Image..."
|
||||
echo "Step: Building Joplin Server Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
||||
elif [[ $IS_LINUX = 1 ]] && [ "$IS_TRANSCRIBE_RELEASE" == "1" ]; then
|
||||
echo "Step: Building Joplin Transcribe Docker Image..."
|
||||
cd "$ROOT_DIR"
|
||||
yarn buildServerDocker --docker-file Dockerfile.transcribe --platform $DOCKER_IMAGE_PLATFORM --tag-name $GIT_TAG_NAME --push-images --repository $TRANSCRIBE_REPOSITORY
|
||||
else
|
||||
echo "Step: Building but *not* publishing desktop application..."
|
||||
|
||||
|
2
.github/workflows/automerge.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- id: automerge
|
||||
name: automerge
|
||||
uses: "pascalgn/automerge-action@v0.16.3"
|
||||
uses: "pascalgn/automerge-action@v0.16.4"
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
MERGE_METHOD: "squash"
|
||||
|
6
.github/workflows/build-macos-m1.yml
vendored
@@ -8,12 +8,12 @@ jobs:
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: olegtarasov/get-tag@v2.1.3
|
||||
- uses: olegtarasov/get-tag@v2.1.4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
# We need to pin the version to 18.15, because 18.16+ fails with this error:
|
||||
# https://github.com/facebook/react-native/issues/36440
|
||||
node-version: '18.15.0'
|
||||
node-version: '18.20.8'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
# See github-action-main.yml for explanation
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Set Publish Flag
|
||||
run: |
|
||||
|
2
.github/workflows/cla.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
# the below token should have repo scope and must be manually added by you in the repository's secret
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
with:
|
||||
path-to-signatures: 'readme/cla_signatures.json'
|
||||
path-to-signatures: 'readme/cla/signatures.json'
|
||||
path-to-document: 'https://github.com/laurent22/joplin/blob/dev/readme/cla.md' # e.g. a CLA or a DCO document
|
||||
# branch should not be protected
|
||||
branch: 'cla_signatures'
|
||||
|
108
.github/workflows/github-actions-main.yml
vendored
@@ -9,50 +9,14 @@ jobs:
|
||||
matrix:
|
||||
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
|
||||
# https://github.com/actions/runner-images/issues/6709
|
||||
os: [macos-13, ubuntu-20.04, windows-2019]
|
||||
os: [macos-13, ubuntu-22.04, windows-2025, ubuntu-22.04-arm]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Trying to fix random networking issues on Windows
|
||||
# https://github.com/actions/runner-images/issues/1187#issuecomment-686735760
|
||||
- name: Disable TCP/UDP offload on Windows
|
||||
if: runner.os == 'Windows'
|
||||
run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
|
||||
|
||||
- name: Disable TCP/UDP offload on Linux
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Disable TCP/UDP offload on macOS
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_tx=0
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_rx=0
|
||||
|
||||
# Silence apt-get update errors (for example when a module doesn't
|
||||
# exist) since otherwise it will make the whole build fails, even though
|
||||
# it might work without update. libsecret-1-dev is required for keytar -
|
||||
# https://github.com/atom/node-keytar
|
||||
|
||||
- name: Install Linux dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y gettext
|
||||
sudo apt-get install -y libsecret-1-dev
|
||||
sudo apt-get install -y translate-toolkit
|
||||
sudo apt-get install -y rsync
|
||||
# Provides a virtual display on Linux. Used for Playwright integration
|
||||
# testing.
|
||||
sudo apt-get install -y xvfb
|
||||
|
||||
- name: Install macOs dependencies
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
# Required for building the canvas package
|
||||
brew install pango
|
||||
- name: Setup build environment
|
||||
uses: ./.github/workflows/shared/setup-build-environment
|
||||
|
||||
- name: Install Docker Engine
|
||||
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get install -y apt-transport-https
|
||||
@@ -62,44 +26,20 @@ jobs:
|
||||
sudo apt-get install -y lsb-release
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo \
|
||||
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: olegtarasov/get-tag@v2.1.3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
# We need to pin the version to 18.15, because 18.16+ fails with this error:
|
||||
# https://github.com/facebook/react-native/issues/36440
|
||||
node-version: '18.15.0'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
# https://yarnpkg.com/getting-started/install
|
||||
corepack enable
|
||||
|
||||
# Login to Docker only if we're on a server release tag. If we run this on
|
||||
# a pull request it will fail because the PR doesn't have access to
|
||||
# secrets
|
||||
- uses: docker/login-action@v3
|
||||
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||
if: runner.os == 'Linux' && (startsWith(github.ref, 'refs/tags/server-v') || startsWith(github.ref, 'refs/tags/transcribe-v'))
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
# macos-latest ships with Python 3.12 by default, but this removes a
|
||||
# utility that's used by electron-builder (distutils) so we need to pin
|
||||
# Python to an earlier version.
|
||||
# Fixes error `ModuleNotFoundError: No module named 'distutils'`
|
||||
# Ref: https://github.com/nodejs/node-gyp/issues/2869
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Run tests, build and publish Linux and macOS apps
|
||||
if: runner.os == 'Linux' || runner.os == 'macOs'
|
||||
env:
|
||||
@@ -143,6 +83,15 @@ jobs:
|
||||
run: |
|
||||
yarn install && cd packages/app-desktop && yarn dist --publish=never
|
||||
|
||||
- name: Publish Docker manifest
|
||||
if: runner.os == 'Linux'
|
||||
env:
|
||||
SERVER_REPOSITORY: joplin/server
|
||||
SERVER_TAG_PREFIX: server
|
||||
run: |
|
||||
chmod 700 "${GITHUB_WORKSPACE}/.github/scripts/publish_docker_manifest.sh"
|
||||
"${GITHUB_WORKSPACE}/.github/scripts/publish_docker_manifest.sh"
|
||||
|
||||
ServerDockerImage:
|
||||
if: github.repository == 'laurent22/joplin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -150,7 +99,7 @@ jobs:
|
||||
matrix:
|
||||
# Do not use unbuntu-latest because it causes `The operation was canceled` failures:
|
||||
# https://github.com/actions/runner-images/issues/6709
|
||||
os: [ubuntu-20.04]
|
||||
os: [ubuntu-22.04, ubuntu-22.04-arm]
|
||||
steps:
|
||||
|
||||
- name: Install Docker Engine
|
||||
@@ -162,17 +111,16 @@ jobs:
|
||||
sudo apt-get install -y lsb-release
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo \
|
||||
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install Yarn
|
||||
run: |
|
||||
@@ -183,20 +131,28 @@ jobs:
|
||||
env:
|
||||
BUILD_SEQUENCIAL: 1
|
||||
run: |
|
||||
if [ "$RUNNER_ARCH" == "ARM64" ]; then
|
||||
DOCKER_IMAGE_PLATFORM="linux/arm64"
|
||||
fi
|
||||
|
||||
echo "RUNNER_OS=$RUNNER_OS"
|
||||
echo "RUNNER_ARCH=$RUNNER_ARCH"
|
||||
echo "DOCKER_IMAGE_PLATFORM=$DOCKER_IMAGE_PLATFORM"
|
||||
|
||||
yarn install
|
||||
yarn buildServerDocker --tag-name server-v0.0.0 --repository joplin/server
|
||||
yarn buildServerDocker --docker-file Dockerfile.server --platform $DOCKER_IMAGE_PLATFORM --tag-name server-v0.0.0 --repository joplin/server
|
||||
|
||||
# Basic test to ensure that the created build is valid. It should exit with
|
||||
# code 0 if it works.
|
||||
docker run joplin/server:0.0.0-beta node dist/app.js migrate list
|
||||
# code 0 if it works.
|
||||
docker run joplin/server:$(dpkg --print-architecture)-0.0.0 node dist/app.js migrate list
|
||||
|
||||
- name: Check HTTP request
|
||||
run: |
|
||||
# Need to pass environment variables:
|
||||
docker run -p 22300:22300 joplin/server:0.0.0-beta node dist/app.js --env dev &
|
||||
docker run -p 22300:22300 joplin/server:$(dpkg --print-architecture)-0.0.0 node dist/app.js --env dev &
|
||||
|
||||
# Wait for server to start
|
||||
sleep 30
|
||||
sleep 120
|
||||
|
||||
# Check if status code is correct
|
||||
# if the actual_status DOES NOT include the expected_status
|
||||
|
75
.github/workflows/shared/setup-build-environment/action.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: 'Setup build environment'
|
||||
description: 'Install Joplin build dependencies'
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
# Trying to fix random networking issues on Windows
|
||||
# https://github.com/actions/runner-images/issues/1187#issuecomment-686735760
|
||||
# - name: Disable TCP/UDP offload on Windows
|
||||
# if: runner.os == 'Windows'
|
||||
# shell: pwsh
|
||||
# run: Disable-NetAdapterChecksumOffload -Name * -TcpIPv4 -UdpIPv4 -TcpIPv6 -UdpIPv6
|
||||
|
||||
- name: Disable TCP/UDP offload on Linux
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: sudo ethtool -K eth0 tx off rx off
|
||||
|
||||
- name: Disable TCP/UDP offload on macOS
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_tx=0
|
||||
sudo sysctl -w net.link.generic.system.hwcksum_rx=0
|
||||
|
||||
# Silence apt-get update errors (for example when a module doesn't
|
||||
# exist) since otherwise it will make the whole build fails, even though
|
||||
# it might work without update. libsecret-1-dev is required for keytar -
|
||||
# https://github.com/atom/node-keytar
|
||||
|
||||
- name: Install Linux dependencies
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y gettext
|
||||
sudo apt-get install -y libsecret-1-dev
|
||||
sudo apt-get install -y translate-toolkit
|
||||
sudo apt-get install -y rsync
|
||||
# Provides a virtual display on Linux. Used for Playwright integration
|
||||
# testing.
|
||||
sudo apt-get install -y xvfb
|
||||
|
||||
- name: Install macOs dependencies
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
# Required for building the canvas package
|
||||
brew install pango
|
||||
|
||||
- uses: olegtarasov/get-tag@v2.1.4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
if: ${{ runner.os != 'Windows' }}
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18.20.8'
|
||||
# Disable the cache on ARM runners. For now, we don't run "yarn install" on these
|
||||
# environments and this breaks actions/setup-node.
|
||||
# See https://github.com/laurent22/joplin/commit/47d0d3eb9e89153a609fb5441344da10904c6308#commitcomment-159577783.
|
||||
# cache: ${{ (!contains(runner.os, 'arm') && 'yarn') || '' }}
|
||||
|
||||
- name: Install Yarn
|
||||
shell: bash
|
||||
run: |
|
||||
# https://yarnpkg.com/getting-started/install
|
||||
corepack enable
|
||||
|
||||
# macos-latest ships with Python 3.12 by default, but this removes a
|
||||
# utility that's used by electron-builder (distutils) so we need to pin
|
||||
# Python to an earlier version.
|
||||
# Fixes error `ModuleNotFoundError: No module named 'distutils'`
|
||||
# Ref: https://github.com/nodejs/node-gyp/issues/2869
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
35
.github/workflows/ui-tests.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Joplin UI tests
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
Main:
|
||||
# Don't run on forks
|
||||
if: github.repository == 'laurent22/joplin'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, windows-2025]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup build environment
|
||||
uses: ./.github/workflows/shared/setup-build-environment
|
||||
- name: Build
|
||||
run: yarn install
|
||||
env:
|
||||
# The onenote-converter package uses Rust, which isn't installed on all CI
|
||||
# runners. Since the onenote-converter doesn't have UI tests, it can be excluded
|
||||
# from build:
|
||||
SKIP_ONENOTE_CONVERTER_BUILD: 1
|
||||
- name: Run UI tests
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${GITHUB_WORKSPACE}/packages/app-desktop/
|
||||
bash ./integration-tests/run-ci.sh
|
||||
# See https://playwright.dev/docs/ci-intro#setting-up-github-actions
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report-${{ matrix.os }}
|
||||
path: packages/app-desktop/playwright-report/
|
||||
retention-days: 7
|
345
.gitignore
vendored
@@ -46,6 +46,7 @@ sync_staging.sh
|
||||
TODO.md
|
||||
packages/tools/commit_hook.txt
|
||||
packages/tools/github_oauth_token.txt
|
||||
packages/app-desktop/main-html-out.js
|
||||
lerna-debug.log
|
||||
.env
|
||||
docs/**/*.mustache
|
||||
@@ -58,6 +59,7 @@ docs/**/*.mustache
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/joplin-empty-package
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
@@ -69,6 +71,7 @@ packages/app-cli/app/app.js
|
||||
packages/app-cli/app/base-command.js
|
||||
packages/app-cli/app/command-apidoc.js
|
||||
packages/app-cli/app/command-attach.js
|
||||
packages/app-cli/app/command-batch.js
|
||||
packages/app-cli/app/command-cat.js
|
||||
packages/app-cli/app/command-config.js
|
||||
packages/app-cli/app/command-cp.js
|
||||
@@ -95,6 +98,8 @@ packages/app-cli/app/command-rmnote.test.js
|
||||
packages/app-cli/app/command-rmnote.js
|
||||
packages/app-cli/app/command-set.js
|
||||
packages/app-cli/app/command-settingschema.js
|
||||
packages/app-cli/app/command-share.test.js
|
||||
packages/app-cli/app/command-share.js
|
||||
packages/app-cli/app/command-sync.js
|
||||
packages/app-cli/app/command-testing.js
|
||||
packages/app-cli/app/command-use.js
|
||||
@@ -103,6 +108,9 @@ packages/app-cli/app/gui/FolderListWidget.js
|
||||
packages/app-cli/app/gui/StatusBarWidget.js
|
||||
packages/app-cli/app/services/plugins/PluginRunner.js
|
||||
packages/app-cli/app/setupCommand.js
|
||||
packages/app-cli/app/utils/initializeCommandService.js
|
||||
packages/app-cli/app/utils/iterateStdin.js
|
||||
packages/app-cli/app/utils/shimInitCli.js
|
||||
packages/app-cli/app/utils/testUtils.js
|
||||
packages/app-cli/tests/HtmlToMd.js
|
||||
packages/app-cli/tests/MarkupToHtml.js
|
||||
@@ -124,7 +132,10 @@ packages/app-desktop/app.reducer.js
|
||||
packages/app-desktop/app.js
|
||||
packages/app-desktop/bridge.js
|
||||
packages/app-desktop/checkForUpdates.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.test.js
|
||||
packages/app-desktop/commands/convertNoteToMarkdown.js
|
||||
packages/app-desktop/commands/copyDevCommand.js
|
||||
packages/app-desktop/commands/copyToClipboard.js
|
||||
packages/app-desktop/commands/editProfileConfig.js
|
||||
packages/app-desktop/commands/emptyTrash.js
|
||||
packages/app-desktop/commands/exportDeletionLog.test.js
|
||||
@@ -134,7 +145,9 @@ packages/app-desktop/commands/exportNotes.js
|
||||
packages/app-desktop/commands/focusElement.js
|
||||
packages/app-desktop/commands/index.js
|
||||
packages/app-desktop/commands/openNoteInNewWindow.js
|
||||
packages/app-desktop/commands/openPrimaryAppInstance.js
|
||||
packages/app-desktop/commands/openProfileDirectory.js
|
||||
packages/app-desktop/commands/openSecondaryAppInstance.js
|
||||
packages/app-desktop/commands/replaceMisspelling.js
|
||||
packages/app-desktop/commands/restoreNoteRevision.js
|
||||
packages/app-desktop/commands/startExternalEditing.js
|
||||
@@ -161,6 +174,7 @@ packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||
packages/app-desktop/gui/ConversionNotification/ConversionNotification.js
|
||||
packages/app-desktop/gui/Dialog.js
|
||||
packages/app-desktop/gui/DialogButtonRow.js
|
||||
packages/app-desktop/gui/DialogButtonRow/useKeyboardHandler.js
|
||||
@@ -181,6 +195,7 @@ packages/app-desktop/gui/InlineCombobox.js
|
||||
packages/app-desktop/gui/ItemList.js
|
||||
packages/app-desktop/gui/JoplinCloudConfigScreen.js
|
||||
packages/app-desktop/gui/JoplinCloudLoginScreen.js
|
||||
packages/app-desktop/gui/JoplinCloudSignUpCallToAction.js
|
||||
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
|
||||
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
|
||||
packages/app-desktop/gui/KeymapConfig/styles/index.js
|
||||
@@ -239,6 +254,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useKeyboardRefocusHan
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useLinkTooltips.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTabIndenter.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useTextPatternsLookup.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/useWebViewApi.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteEditor.js
|
||||
packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.js
|
||||
@@ -247,6 +263,7 @@ packages/app-desktop/gui/NoteEditor/WarningBanner/BannerContent.js
|
||||
packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteBody.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteTitle.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementNoteViewer.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/focusElementToolbar.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/index.js
|
||||
packages/app-desktop/gui/NoteEditor/commands/pasteAsText.js
|
||||
@@ -259,12 +276,14 @@ packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/clipboardUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenu.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/contextMenuUtils.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/getResourceBaseUrl.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/getWindowCommandPriority.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/index.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/markupRenderOptions.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.test.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/resourceHandling.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/types.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useConnectToEditorPlugin.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useDropHandler.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useEffectiveNoteId.js
|
||||
packages/app-desktop/gui/NoteEditor/utils/useFolder.js
|
||||
@@ -328,13 +347,16 @@ packages/app-desktop/gui/NoteSearchBar.js
|
||||
packages/app-desktop/gui/NoteStatusBar.js
|
||||
packages/app-desktop/gui/NoteTextViewer.js
|
||||
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
|
||||
packages/app-desktop/gui/NotyfContext.js
|
||||
packages/app-desktop/gui/OneDriveLoginScreen.js
|
||||
packages/app-desktop/gui/PasswordInput/LabelledPasswordInput.js
|
||||
packages/app-desktop/gui/PasswordInput/PasswordInput.js
|
||||
packages/app-desktop/gui/PasswordInput/types.js
|
||||
packages/app-desktop/gui/PdfViewer.js
|
||||
packages/app-desktop/gui/PluginNotification/PluginNotification.js
|
||||
packages/app-desktop/gui/PopupNotification/NotificationItem.js
|
||||
packages/app-desktop/gui/PopupNotification/PopupNotificationList.js
|
||||
packages/app-desktop/gui/PopupNotification/PopupNotificationProvider.js
|
||||
packages/app-desktop/gui/PopupNotification/types.js
|
||||
packages/app-desktop/gui/PromptDialog.js
|
||||
packages/app-desktop/gui/ResizableLayout/LayoutItemContainer.js
|
||||
packages/app-desktop/gui/ResizableLayout/MoveButtons.js
|
||||
@@ -385,6 +407,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.js
|
||||
packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js
|
||||
packages/app-desktop/gui/Sidebar/styles/index.js
|
||||
packages/app-desktop/gui/Sidebar/types.js
|
||||
packages/app-desktop/gui/SsoLoginScreen/SsoLoginScreen.js
|
||||
packages/app-desktop/gui/StatusScreen/StatusScreen.js
|
||||
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
|
||||
packages/app-desktop/gui/SyncWizard/Dialog.js
|
||||
@@ -396,6 +419,7 @@ packages/app-desktop/gui/ToolbarBase.js
|
||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||
packages/app-desktop/gui/ToolbarSpace.js
|
||||
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
||||
packages/app-desktop/gui/TrashNotification/TrashNotificationMessage.js
|
||||
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/AppDialogs.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/ModalMessageOverlay.js
|
||||
@@ -410,7 +434,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/exportPdf.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/gotoAnything.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/hideModalMessage.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/index.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/leaveSharedFolder.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/linkToNote.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newFolder.js
|
||||
@@ -499,15 +522,20 @@ packages/app-desktop/integration-tests/sidebar.spec.js
|
||||
packages/app-desktop/integration-tests/simpleBackup.spec.js
|
||||
packages/app-desktop/integration-tests/util/activateMainMenuItem.js
|
||||
packages/app-desktop/integration-tests/util/createStartupArgs.js
|
||||
packages/app-desktop/integration-tests/util/evaluateWithRetry.js
|
||||
packages/app-desktop/integration-tests/util/extendedExpect.js
|
||||
packages/app-desktop/integration-tests/util/firstNonDevToolsWindow.js
|
||||
packages/app-desktop/integration-tests/util/getImageSourceSize.js
|
||||
packages/app-desktop/integration-tests/util/getMainWindow.js
|
||||
packages/app-desktop/integration-tests/util/retryOnFailure.js
|
||||
packages/app-desktop/integration-tests/util/setDarkMode.js
|
||||
packages/app-desktop/integration-tests/util/setFilePickerResponse.js
|
||||
packages/app-desktop/integration-tests/util/setMessageBoxResponse.js
|
||||
packages/app-desktop/integration-tests/util/setSettingValue.js
|
||||
packages/app-desktop/integration-tests/util/test.js
|
||||
packages/app-desktop/integration-tests/util/waitForNextOpenPath.js
|
||||
packages/app-desktop/integration-tests/wcag.spec.js
|
||||
packages/app-desktop/main-html.js
|
||||
packages/app-desktop/main.js
|
||||
packages/app-desktop/playwright.config.js
|
||||
packages/app-desktop/plugins/GotoAnything.js
|
||||
packages/app-desktop/services/autoUpdater/AutoUpdaterService.test.js
|
||||
@@ -522,19 +550,23 @@ packages/app-desktop/services/plugins/UserWebview.js
|
||||
packages/app-desktop/services/plugins/UserWebviewDialog.js
|
||||
packages/app-desktop/services/plugins/UserWebviewDialogButtonBar.js
|
||||
packages/app-desktop/services/plugins/hooks/useContentSize.js
|
||||
packages/app-desktop/services/plugins/hooks/useFormData.js
|
||||
packages/app-desktop/services/plugins/hooks/useHtmlLoader.js
|
||||
packages/app-desktop/services/plugins/hooks/useMessageHandler.js
|
||||
packages/app-desktop/services/plugins/hooks/useScriptLoader.js
|
||||
packages/app-desktop/services/plugins/hooks/useSubmitHandler.js
|
||||
packages/app-desktop/services/plugins/hooks/useThemeCss.test.js
|
||||
packages/app-desktop/services/plugins/hooks/useThemeCss.js
|
||||
packages/app-desktop/services/plugins/hooks/useViewIsReady.js
|
||||
packages/app-desktop/services/plugins/hooks/useWebviewToPluginMessages.js
|
||||
packages/app-desktop/services/plugins/types.js
|
||||
packages/app-desktop/services/restart.js
|
||||
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.test.js
|
||||
packages/app-desktop/services/sortOrder/PerFolderSortOrderService.js
|
||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.test.js
|
||||
packages/app-desktop/services/sortOrder/notesSortOrderUtils.js
|
||||
packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.js
|
||||
packages/app-desktop/tools/bundleJs.js
|
||||
packages/app-desktop/tools/copy7Zip.js
|
||||
packages/app-desktop/tools/generateLatestArm64Yml.js
|
||||
packages/app-desktop/tools/githubReleasesUtils.js
|
||||
@@ -549,13 +581,16 @@ packages/app-desktop/utils/customProtocols/constants.js
|
||||
packages/app-desktop/utils/customProtocols/handleCustomProtocols.test.js
|
||||
packages/app-desktop/utils/customProtocols/handleCustomProtocols.js
|
||||
packages/app-desktop/utils/customProtocols/registerCustomProtocols.js
|
||||
packages/app-desktop/utils/getAssetPath.js
|
||||
packages/app-desktop/utils/initializeCommandService.js
|
||||
packages/app-desktop/utils/isSafeToOpen.test.js
|
||||
packages/app-desktop/utils/isSafeToOpen.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.test.js
|
||||
packages/app-desktop/utils/restartInSafeModeFromMain.js
|
||||
packages/app-desktop/utils/sourceMapSetup.js
|
||||
packages/app-desktop/utils/window/types.js
|
||||
packages/app-mobile/PluginAssetsLoader.js
|
||||
packages/app-mobile/commands/dismissPluginPanels.js
|
||||
packages/app-mobile/commands/index.js
|
||||
packages/app-mobile/commands/newNote.test.js
|
||||
packages/app-mobile/commands/newNote.js
|
||||
@@ -565,19 +600,29 @@ packages/app-mobile/commands/scrollToHash.js
|
||||
packages/app-mobile/commands/util/goToNote.js
|
||||
packages/app-mobile/commands/util/showResource.js
|
||||
packages/app-mobile/components/BetaChip.js
|
||||
packages/app-mobile/components/BottomDrawer.js
|
||||
packages/app-mobile/components/CameraView/ActionButtons.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.jest.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.js
|
||||
packages/app-mobile/components/CameraView/Camera/index.web.js
|
||||
packages/app-mobile/components/CameraView/Camera/types.js
|
||||
packages/app-mobile/components/CameraView/CameraView.test.js
|
||||
packages/app-mobile/components/CameraView/CameraView.js
|
||||
packages/app-mobile/components/CameraView/CameraView.web.js
|
||||
packages/app-mobile/components/CameraView/CameraViewMultiPage.test.js
|
||||
packages/app-mobile/components/CameraView/CameraViewMultiPage.js
|
||||
packages/app-mobile/components/CameraView/PhotoPreview.js
|
||||
packages/app-mobile/components/CameraView/ScannedBarcodes.js
|
||||
packages/app-mobile/components/CameraView/types.js
|
||||
packages/app-mobile/components/CameraView/utils/fitRectIntoBounds.js
|
||||
packages/app-mobile/components/CameraView/utils/testing.js
|
||||
packages/app-mobile/components/CameraView/utils/useBarcodeScanner.js
|
||||
packages/app-mobile/components/Checkbox.js
|
||||
packages/app-mobile/components/ComboBox.test.js
|
||||
packages/app-mobile/components/ComboBox.js
|
||||
packages/app-mobile/components/DialogManager/PromptButton.js
|
||||
packages/app-mobile/components/DialogManager/PromptDialog.js
|
||||
packages/app-mobile/components/DialogManager/TextInputDialog.js
|
||||
packages/app-mobile/components/DialogManager/hooks/useDialogControl.js
|
||||
packages/app-mobile/components/DialogManager/index.js
|
||||
packages/app-mobile/components/DialogManager/types.js
|
||||
@@ -599,74 +644,72 @@ packages/app-mobile/components/ExtendedWebView/index.jest.js
|
||||
packages/app-mobile/components/ExtendedWebView/index.js
|
||||
packages/app-mobile/components/ExtendedWebView/index.web.js
|
||||
packages/app-mobile/components/ExtendedWebView/types.js
|
||||
packages/app-mobile/components/ExtendedWebView/utils/useCss.js
|
||||
packages/app-mobile/components/FolderPicker.js
|
||||
packages/app-mobile/components/Icon.js
|
||||
packages/app-mobile/components/IconButton.js
|
||||
packages/app-mobile/components/Modal.js
|
||||
packages/app-mobile/components/ModalDialog.js
|
||||
packages/app-mobile/components/NestableFlatList.js
|
||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/NoteBodyViewer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/Renderer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/noteBodyViewerBundle.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/types.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/addPluginAssets.js
|
||||
packages/app-mobile/components/NoteBodyViewer/bundledJs/utils/makeResourceModel.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useContentScripts.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.test.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useEditPopup.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnMessage.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useRenderer.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useRerenderHandler.js
|
||||
packages/app-mobile/components/NoteBodyViewer/hooks/useSource.js
|
||||
packages/app-mobile/components/NoteBodyViewer/types.js
|
||||
packages/app-mobile/components/NoteEditor/CodeMirror/CodeMirror.js
|
||||
packages/app-mobile/components/NoteEditor/EditLinkDialog.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/autosave.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/isEditableResource.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/applyTemplateToEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/polyfills.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/startAutosaveLoop.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/watchEditorForTemplateChanges.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.js
|
||||
packages/app-mobile/components/NoteEditor/ImageEditor/utils/useEditorMessenger.js
|
||||
packages/app-mobile/components/NoteEditor/MarkdownEditor.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/NoteEditor.js
|
||||
packages/app-mobile/components/NoteEditor/RichTextEditor.test.js
|
||||
packages/app-mobile/components/NoteEditor/RichTextEditor.js
|
||||
packages/app-mobile/components/NoteEditor/SearchPanel.js
|
||||
packages/app-mobile/components/NoteEditor/WarningBanner.js
|
||||
packages/app-mobile/components/NoteEditor/commandDeclarations.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useCodeMirrorPlugins.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.test.js
|
||||
packages/app-mobile/components/NoteEditor/hooks/useEditorCommandHandler.js
|
||||
packages/app-mobile/components/NoteEditor/testing/createTestEditorProps.js
|
||||
packages/app-mobile/components/NoteEditor/types.js
|
||||
packages/app-mobile/components/NoteItem.js
|
||||
packages/app-mobile/components/NoteList.js
|
||||
packages/app-mobile/components/ProfileSwitcher/ProfileEditor.js
|
||||
packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.js
|
||||
packages/app-mobile/components/ProfileSwitcher/useProfileConfig.js
|
||||
packages/app-mobile/components/SafeAreaView.js
|
||||
packages/app-mobile/components/ScreenHeader/Menu.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBanner.test.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBanner.js
|
||||
packages/app-mobile/components/ScreenHeader/WarningBox.js
|
||||
packages/app-mobile/components/ScreenHeader/WebBetaButton.js
|
||||
packages/app-mobile/components/ScreenHeader/index.js
|
||||
packages/app-mobile/components/SearchInput.js
|
||||
packages/app-mobile/components/SelectDateTimeDialog.js
|
||||
packages/app-mobile/components/SideMenu.js
|
||||
packages/app-mobile/components/SideMenuContentNote.js
|
||||
packages/app-mobile/components/TagEditor.test.js
|
||||
packages/app-mobile/components/TagEditor.js
|
||||
packages/app-mobile/components/TextInput.js
|
||||
packages/app-mobile/components/ToggleSpaceButton.js
|
||||
packages/app-mobile/components/accessibility/AccessibleModalMenu.js
|
||||
packages/app-mobile/components/accessibility/AccessibleView.test.js
|
||||
packages/app-mobile/components/accessibility/AccessibleView.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/AutoFocusProvider.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/FocusControl.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/FocusControlProvider.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/MainAppContent.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/ModalWrapper.js
|
||||
packages/app-mobile/components/accessibility/FocusControl/types.js
|
||||
packages/app-mobile/components/app-nav.js
|
||||
packages/app-mobile/components/base-screen.js
|
||||
packages/app-mobile/components/biometrics/BiometricPopup.js
|
||||
packages/app-mobile/components/biometrics/biometricAuthenticate.js
|
||||
packages/app-mobile/components/biometrics/sensorInfo.js
|
||||
packages/app-mobile/components/buttons/FloatingActionButton.js
|
||||
packages/app-mobile/components/buttons/LabelledIconButton.js
|
||||
packages/app-mobile/components/buttons/MultiTouchableOpacity.js
|
||||
packages/app-mobile/components/buttons/TextButton.js
|
||||
packages/app-mobile/components/buttons/index.js
|
||||
packages/app-mobile/components/getResponsiveValue.test.js
|
||||
@@ -674,6 +717,7 @@ packages/app-mobile/components/getResponsiveValue.js
|
||||
packages/app-mobile/components/global-style.js
|
||||
packages/app-mobile/components/plugins/PluginNotification.js
|
||||
packages/app-mobile/components/plugins/PluginRunner.js
|
||||
packages/app-mobile/components/plugins/PluginRunnerWebView.test.js
|
||||
packages/app-mobile/components/plugins/PluginRunnerWebView.js
|
||||
packages/app-mobile/components/plugins/backgroundPage/initializeDialogWebView.js
|
||||
packages/app-mobile/components/plugins/backgroundPage/initializePluginBackgroundIframe.js
|
||||
@@ -713,8 +757,11 @@ packages/app-mobile/components/screens/ConfigScreen/SectionSelector/SectionTab.j
|
||||
packages/app-mobile/components/screens/ConfigScreen/SectionSelector/index.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingComponent.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingItem.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingTextInput.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingsButton.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/SettingsToggle.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/ValidatedIntegerInput.test.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/ValidatedIntegerInput.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/configScreenStyles.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/InstalledPluginBox.js
|
||||
@@ -742,6 +789,8 @@ packages/app-mobile/components/screens/ConfigScreen/plugins/utils/usePluginItem.
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useRepoApi.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/plugins/utils/useUpdateState.js
|
||||
packages/app-mobile/components/screens/ConfigScreen/types.js
|
||||
packages/app-mobile/components/screens/DocumentScanner/DocumentScanner.js
|
||||
packages/app-mobile/components/screens/DocumentScanner/NotePreview.js
|
||||
packages/app-mobile/components/screens/JoplinCloudLoginScreen.js
|
||||
packages/app-mobile/components/screens/LogScreen.js
|
||||
packages/app-mobile/components/screens/Note/Note.test.js
|
||||
@@ -753,14 +802,21 @@ packages/app-mobile/components/screens/Note/commands/insertDateTime.js
|
||||
packages/app-mobile/components/screens/Note/commands/setTags.js
|
||||
packages/app-mobile/components/screens/Note/commands/toggleVisiblePanes.js
|
||||
packages/app-mobile/components/screens/Note/types.js
|
||||
packages/app-mobile/components/screens/NoteRevisionViewer.test.js
|
||||
packages/app-mobile/components/screens/NoteRevisionViewer.js
|
||||
packages/app-mobile/components/screens/NoteTagsDialog.js
|
||||
packages/app-mobile/components/screens/Notes.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.js
|
||||
packages/app-mobile/components/screens/Notes/Notes.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.js
|
||||
packages/app-mobile/components/screens/SearchScreen/index.js
|
||||
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
|
||||
packages/app-mobile/components/screens/ShareManager/IncomingShareItem.js
|
||||
packages/app-mobile/components/screens/ShareManager/index.test.js
|
||||
packages/app-mobile/components/screens/ShareManager/index.js
|
||||
packages/app-mobile/components/screens/ShareNoteDialog.test.js
|
||||
packages/app-mobile/components/screens/ShareNoteDialog.js
|
||||
packages/app-mobile/components/screens/SsoLoginScreen.js
|
||||
packages/app-mobile/components/screens/UpgradeSyncTargetScreen.js
|
||||
packages/app-mobile/components/screens/dropbox-login.js
|
||||
packages/app-mobile/components/screens/encryption-config.test.js
|
||||
@@ -773,6 +829,38 @@ packages/app-mobile/components/voiceTyping/AudioRecordingBanner.js
|
||||
packages/app-mobile/components/voiceTyping/RecordingControls.js
|
||||
packages/app-mobile/components/voiceTyping/SpeechToTextBanner.js
|
||||
packages/app-mobile/components/voiceTyping/types.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/applyTemplateToEditor.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.test.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/startAutosaveLoop.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/types.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/contentScript/watchEditorForTemplateChanges.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/imageEditorBundle/utils/useEditorMessenger.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/contentScript.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/types.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/markdownEditorBundle/utils/useCodeMirrorPlugins.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.test.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/Renderer.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/types.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/addPluginAssets.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/afterFullPageRender.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/contentScript/utils/makeResourceModel.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/types.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useContentScripts.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.test.js
|
||||
packages/app-mobile/contentScripts/rendererBundle/utils/useEditPopup.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/convertHtmlToMarkdown.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/contentScript/index.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/types.js
|
||||
packages/app-mobile/contentScripts/richTextEditorBundle/useWebViewSetup.js
|
||||
packages/app-mobile/contentScripts/types.js
|
||||
packages/app-mobile/contentScripts/utils/polyfills.js
|
||||
packages/app-mobile/contentScripts/utils/readFileToBase64.js
|
||||
packages/app-mobile/contentScripts/utils/setUpLogger.js
|
||||
packages/app-mobile/gulpfile.js
|
||||
packages/app-mobile/index.web.js
|
||||
packages/app-mobile/root.js
|
||||
@@ -795,7 +883,7 @@ packages/app-mobile/services/voiceTyping/whisper.js
|
||||
packages/app-mobile/setupQuickActions.js
|
||||
packages/app-mobile/tools/buildInjectedJs/BundledFile.js
|
||||
packages/app-mobile/tools/buildInjectedJs/constants.js
|
||||
packages/app-mobile/tools/buildInjectedJs/copyJs.js
|
||||
packages/app-mobile/tools/buildInjectedJs/copyAssets.js
|
||||
packages/app-mobile/tools/buildInjectedJs/gulpTasks.js
|
||||
packages/app-mobile/tools/copyAssets.js
|
||||
packages/app-mobile/utils/ShareExtension.js
|
||||
@@ -804,11 +892,13 @@ packages/app-mobile/utils/ShareUtils.js
|
||||
packages/app-mobile/utils/TlsUtils.js
|
||||
packages/app-mobile/utils/appDefaultState.js
|
||||
packages/app-mobile/utils/autodetectTheme.js
|
||||
packages/app-mobile/utils/buildStartupTasks.js
|
||||
packages/app-mobile/utils/checkPermissions.js
|
||||
packages/app-mobile/utils/createRootStyle.js
|
||||
packages/app-mobile/utils/database-driver-react-native.js
|
||||
packages/app-mobile/utils/database-driver-react-native.web.js
|
||||
packages/app-mobile/utils/debounce.js
|
||||
packages/app-mobile/utils/focusView.js
|
||||
packages/app-mobile/utils/fs-driver/constants.js
|
||||
packages/app-mobile/utils/fs-driver/fs-driver-rn.js
|
||||
packages/app-mobile/utils/fs-driver/fs-driver-rn.web.js
|
||||
@@ -821,20 +911,23 @@ packages/app-mobile/utils/fs-driver/testUtil/createFilesFromPathRecord.js
|
||||
packages/app-mobile/utils/fs-driver/testUtil/verifyDirectoryMatches.js
|
||||
packages/app-mobile/utils/getPackageInfo.js
|
||||
packages/app-mobile/utils/getVersionInfoText.js
|
||||
packages/app-mobile/utils/hooks/useKeyboardVisible.js
|
||||
packages/app-mobile/utils/hooks/useBackHandler.js
|
||||
packages/app-mobile/utils/hooks/useKeyboardState.js
|
||||
packages/app-mobile/utils/hooks/useOnLongPressProps.js
|
||||
packages/app-mobile/utils/hooks/useReduceMotionEnabled.js
|
||||
packages/app-mobile/utils/hooks/useSafeAreaPadding.js
|
||||
packages/app-mobile/utils/image/fileToImage.web.js
|
||||
packages/app-mobile/utils/image/getImageDimensions.js
|
||||
packages/app-mobile/utils/image/resizeImage.js
|
||||
packages/app-mobile/utils/initializeCommandService.js
|
||||
packages/app-mobile/utils/injectedJs.js
|
||||
packages/app-mobile/utils/ipc/RNToWebViewMessenger.js
|
||||
packages/app-mobile/utils/ipc/WebViewToRNMessenger.js
|
||||
packages/app-mobile/utils/lockToSingleInstance.js
|
||||
packages/app-mobile/utils/makeShowMessageBox.test.js
|
||||
packages/app-mobile/utils/makeShowMessageBox.js
|
||||
packages/app-mobile/utils/pickDocument.js
|
||||
packages/app-mobile/utils/polyfills/bufferPolyfill.js
|
||||
packages/app-mobile/utils/polyfills/crypto-polyfill/index.js
|
||||
packages/app-mobile/utils/polyfills/index.js
|
||||
packages/app-mobile/utils/setupNotifications.js
|
||||
packages/app-mobile/utils/shareFile.js
|
||||
@@ -847,6 +940,7 @@ packages/app-mobile/utils/testing/createMockReduxStore.js
|
||||
packages/app-mobile/utils/testing/getWebViewDomById.js
|
||||
packages/app-mobile/utils/testing/getWebViewWindowById.js
|
||||
packages/app-mobile/utils/testing/setupGlobalStore.js
|
||||
packages/app-mobile/utils/testing/testingLibrary.js
|
||||
packages/app-mobile/utils/types.js
|
||||
packages/app-mobile/web/serviceWorker.js
|
||||
packages/app-mobile/web/webpack.config.js
|
||||
@@ -857,7 +951,6 @@ packages/default-plugins/commands/editPatch.js
|
||||
packages/default-plugins/utils/getCurrentCommitHash.js
|
||||
packages/default-plugins/utils/getPathToPatchFileFor.js
|
||||
packages/default-plugins/utils/readRepositoryJson.js
|
||||
packages/default-plugins/utils/waitForCliInput.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5BuiltInOptions.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.js
|
||||
packages/editor/CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.js
|
||||
@@ -872,43 +965,69 @@ packages/editor/CodeMirror/editorCommands/duplicateLine.js
|
||||
packages/editor/CodeMirror/editorCommands/editorCommands.js
|
||||
packages/editor/CodeMirror/editorCommands/insertLineAfter.test.js
|
||||
packages/editor/CodeMirror/editorCommands/insertLineAfter.js
|
||||
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.test.js
|
||||
packages/editor/CodeMirror/editorCommands/insertNewlineContinueMarkup.js
|
||||
packages/editor/CodeMirror/editorCommands/jumpToHash.test.js
|
||||
packages/editor/CodeMirror/editorCommands/jumpToHash.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.bulletedVsChecklist.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/editorCommands/markdownCommands.js
|
||||
packages/editor/CodeMirror/editorCommands/sortSelectedLines.test.js
|
||||
packages/editor/CodeMirror/editorCommands/sortSelectedLines.js
|
||||
packages/editor/CodeMirror/editorCommands/supportsCommand.js
|
||||
packages/editor/CodeMirror/extensions/biDirectionalTextExtension.js
|
||||
packages/editor/CodeMirror/extensions/ctrlClickActionExtension.js
|
||||
packages/editor/CodeMirror/extensions/ctrlClickCheckboxExtension.js
|
||||
packages/editor/CodeMirror/extensions/keyUpHandlerExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/ctrlClickLinksExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/followLinkTooltipExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/links/followLinkTooltipExtension.js
|
||||
packages/editor/CodeMirror/extensions/links/referenceLinksStateField.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/findLineMatchingLink.test.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/findLineMatchingLink.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/getUrlAtPosition.js
|
||||
packages/editor/CodeMirror/extensions/links/utils/openLink.js
|
||||
packages/editor/CodeMirror/extensions/markdownDecorationExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownDecorationExtension.js
|
||||
packages/editor/CodeMirror/extensions/markdownHighlightExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownHighlightExtension.js
|
||||
packages/editor/CodeMirror/extensions/markdownMathExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/markdownMathExtension.js
|
||||
packages/editor/CodeMirror/extensions/modifierKeyCssExtension.js
|
||||
packages/editor/CodeMirror/extensions/overwriteModeExtension.test.js
|
||||
packages/editor/CodeMirror/extensions/overwriteModeExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/addFormattingClasses.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderBlockImages.test.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderBlockImages.js
|
||||
packages/editor/CodeMirror/extensions/rendering/renderingExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceBulletLists.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceCheckboxes.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceDividers.js
|
||||
packages/editor/CodeMirror/extensions/rendering/replaceFormatCharacters.js
|
||||
packages/editor/CodeMirror/extensions/rendering/types.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/makeBlockReplaceExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/makeInlineReplaceExtension.js
|
||||
packages/editor/CodeMirror/extensions/rendering/utils/nodeIntersectsSelection.js
|
||||
packages/editor/CodeMirror/extensions/searchExtension.js
|
||||
packages/editor/CodeMirror/extensions/selectedNoteIdExtension.js
|
||||
packages/editor/CodeMirror/getScrollFraction.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownHighlightExtension.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownMathExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/MarkdownMathExtension.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/allLanguages.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/defaultLanguage.js
|
||||
packages/editor/CodeMirror/markdown/codeBlockLanguages/lookUpLanguage.js
|
||||
packages/editor/CodeMirror/markdown/computeSelectionFormatting.test.js
|
||||
packages/editor/CodeMirror/markdown/computeSelectionFormatting.js
|
||||
packages/editor/CodeMirror/markdown/decoratorExtension.test.js
|
||||
packages/editor/CodeMirror/markdown/decoratorExtension.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.bulletedVsChecklist.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.js
|
||||
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.test.js
|
||||
packages/editor/CodeMirror/markdown/utils/renumberSelectedLists.js
|
||||
packages/editor/CodeMirror/markdown/utils/stripBlockquote.js
|
||||
packages/editor/CodeMirror/index.js
|
||||
packages/editor/CodeMirror/pluginApi/PluginLoader.js
|
||||
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.js
|
||||
packages/editor/CodeMirror/testUtil/createEditorControl.js
|
||||
packages/editor/CodeMirror/testUtil/createEditorSettings.js
|
||||
packages/editor/CodeMirror/testUtil/createTestEditor.js
|
||||
packages/editor/CodeMirror/testUtil/findNodesWithName.js
|
||||
packages/editor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testUtil/typeText.js
|
||||
packages/editor/CodeMirror/testing/createEditorControl.js
|
||||
packages/editor/CodeMirror/testing/createTestEditor.js
|
||||
packages/editor/CodeMirror/testing/findNodesWithName.js
|
||||
packages/editor/CodeMirror/testing/forceFullParse.js
|
||||
packages/editor/CodeMirror/testing/loadLanguages.js
|
||||
packages/editor/CodeMirror/testing/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testing/typeText.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/utils/biDirectionalTextExtension.js
|
||||
packages/editor/CodeMirror/utils/formatting/RegionSpec.js
|
||||
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.test.js
|
||||
packages/editor/CodeMirror/utils/formatting/computeSelectionFormatting.js
|
||||
packages/editor/CodeMirror/utils/formatting/findInlineMatch.test.js
|
||||
packages/editor/CodeMirror/utils/formatting/findInlineMatch.js
|
||||
packages/editor/CodeMirror/utils/formatting/isIndentationEquivalent.js
|
||||
@@ -927,15 +1046,63 @@ packages/editor/CodeMirror/utils/handleLinkEditRequests.js
|
||||
packages/editor/CodeMirror/utils/handlePasteEvent.js
|
||||
packages/editor/CodeMirror/utils/isCursorAtBeginning.js
|
||||
packages/editor/CodeMirror/utils/isInSyntaxNode.js
|
||||
packages/editor/CodeMirror/utils/keyUpHandlerExtension.js
|
||||
packages/editor/CodeMirror/utils/overwriteModeExtension.test.js
|
||||
packages/editor/CodeMirror/utils/overwriteModeExtension.js
|
||||
packages/editor/CodeMirror/utils/searchExtension.js
|
||||
packages/editor/CodeMirror/utils/selectedNoteIdExtension.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/allLanguages.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/defaultLanguage.js
|
||||
packages/editor/CodeMirror/utils/markdown/codeBlockLanguages/lookUpLanguage.js
|
||||
packages/editor/CodeMirror/utils/markdown/getCheckboxAtPosition.js
|
||||
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.test.js
|
||||
packages/editor/CodeMirror/utils/markdown/renumberSelectedLists.js
|
||||
packages/editor/CodeMirror/utils/markdown/stripBlockquote.js
|
||||
packages/editor/CodeMirror/utils/markdown/toggleCheckboxAt.js
|
||||
packages/editor/CodeMirror/utils/setupVim.js
|
||||
packages/editor/ProseMirror/commands.test.js
|
||||
packages/editor/ProseMirror/commands.js
|
||||
packages/editor/ProseMirror/createEditor.js
|
||||
packages/editor/ProseMirror/index.js
|
||||
packages/editor/ProseMirror/plugins/detailsPlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/detailsPlugin.js
|
||||
packages/editor/ProseMirror/plugins/inputRulesPlugin.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/createEditorDialog.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/joplinEditablePlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/joplinEditablePlugin.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditablePlugin/postProcessRenderedHtml.js
|
||||
packages/editor/ProseMirror/plugins/joplinEditorApiPlugin.js
|
||||
packages/editor/ProseMirror/plugins/keymapPlugin.js
|
||||
packages/editor/ProseMirror/plugins/linkTooltipPlugin.test.js
|
||||
packages/editor/ProseMirror/plugins/linkTooltipPlugin.js
|
||||
packages/editor/ProseMirror/plugins/listPlugin.js
|
||||
packages/editor/ProseMirror/plugins/originalMarkupPlugin.js
|
||||
packages/editor/ProseMirror/plugins/resourcePlaceholderPlugin.js
|
||||
packages/editor/ProseMirror/plugins/searchPlugin.js
|
||||
packages/editor/ProseMirror/schema.js
|
||||
packages/editor/ProseMirror/styles.js
|
||||
packages/editor/ProseMirror/testing/createTestEditor.js
|
||||
packages/editor/ProseMirror/types.js
|
||||
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
|
||||
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
|
||||
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
|
||||
packages/editor/ProseMirror/utils/dom/createButton.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextArea.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextNode.js
|
||||
packages/editor/ProseMirror/utils/dom/createUniqueId.js
|
||||
packages/editor/ProseMirror/utils/extractSelectedLinesTo.test.js
|
||||
packages/editor/ProseMirror/utils/extractSelectedLinesTo.js
|
||||
packages/editor/ProseMirror/utils/forEachHeading.js
|
||||
packages/editor/ProseMirror/utils/jumpToHash.js
|
||||
packages/editor/ProseMirror/utils/makeLinksClickableInElement.js
|
||||
packages/editor/ProseMirror/utils/preprocessEditorInput.test.js
|
||||
packages/editor/ProseMirror/utils/preprocessEditorInput.js
|
||||
packages/editor/ProseMirror/utils/sanitizeHtml.js
|
||||
packages/editor/ProseMirror/utils/trimEmptyParagraphs.js
|
||||
packages/editor/ProseMirror/vendor/changedDescendants.js
|
||||
packages/editor/ProseMirror/vendor/splitBlockAs.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
packages/editor/events.js
|
||||
packages/editor/polyfills.js
|
||||
packages/editor/testing/createEditorSettings.js
|
||||
packages/editor/testing/setUpLogger.js
|
||||
packages/editor/types.js
|
||||
packages/editor/utils/getFileFromPasteEvent.js
|
||||
packages/fork-htmlparser2/src/CollectingHandler.js
|
||||
packages/fork-htmlparser2/src/FeedHandler.spec.js
|
||||
packages/fork-htmlparser2/src/FeedHandler.js
|
||||
@@ -950,13 +1117,18 @@ packages/fork-htmlparser2/src/__tests__/events.js
|
||||
packages/fork-htmlparser2/src/__tests__/stream.js
|
||||
packages/fork-htmlparser2/src/index.spec.js
|
||||
packages/fork-htmlparser2/src/index.js
|
||||
packages/fork-uslug/lib/uslug.test.js
|
||||
packages/fork-uslug/lib/uslug.js
|
||||
packages/generator-joplin/generators/app/templates/api/index.js
|
||||
packages/generator-joplin/generators/app/templates/api/noteListType.js
|
||||
packages/generator-joplin/generators/app/templates/api/types.js
|
||||
packages/generator-joplin/generators/app/templates/api_index.js
|
||||
packages/generator-joplin/generators/app/templates/src/index.js
|
||||
packages/generator-joplin/tools/updateCategories.js
|
||||
packages/htmlpack/src/index.js
|
||||
packages/htmlpack/index.test.js
|
||||
packages/htmlpack/index.js
|
||||
packages/htmlpack/packToString.js
|
||||
packages/htmlpack/utils/parseHtmlAsync.js
|
||||
packages/lib/ArrayUtils.js
|
||||
packages/lib/AsyncActionQueue.test.js
|
||||
packages/lib/AsyncActionQueue.js
|
||||
@@ -975,12 +1147,15 @@ packages/lib/JoplinDatabase.js
|
||||
packages/lib/JoplinError.js
|
||||
packages/lib/JoplinServerApi.js
|
||||
packages/lib/ObjectUtils.js
|
||||
packages/lib/PerformanceLogger.test.js
|
||||
packages/lib/PerformanceLogger.js
|
||||
packages/lib/PoorManIntervals.js
|
||||
packages/lib/RotatingLogs.test.js
|
||||
packages/lib/RotatingLogs.js
|
||||
packages/lib/SyncTargetFilesystem.js
|
||||
packages/lib/SyncTargetJoplinCloud.js
|
||||
packages/lib/SyncTargetJoplinServer.js
|
||||
packages/lib/SyncTargetJoplinServerSAML.js
|
||||
packages/lib/SyncTargetNone.js
|
||||
packages/lib/SyncTargetOneDrive.js
|
||||
packages/lib/SyncTargetRegistry.js
|
||||
@@ -991,21 +1166,36 @@ packages/lib/array.js
|
||||
packages/lib/callbackUrlUtils.test.js
|
||||
packages/lib/callbackUrlUtils.js
|
||||
packages/lib/clipperUtils.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.test.js
|
||||
packages/lib/commands/convertHtmlToMarkdown.js
|
||||
packages/lib/commands/deleteNote.js
|
||||
packages/lib/commands/historyBackward.js
|
||||
packages/lib/commands/historyForward.js
|
||||
packages/lib/commands/index.js
|
||||
packages/lib/commands/leaveSharedFolder.js
|
||||
packages/lib/commands/openMasterPasswordDialog.js
|
||||
packages/lib/commands/permanentlyDeleteNote.js
|
||||
packages/lib/commands/renderMarkup.test.js
|
||||
packages/lib/commands/renderMarkup.js
|
||||
packages/lib/commands/showEditorPlugin.js
|
||||
packages/lib/commands/synchronize.js
|
||||
packages/lib/commands/toggleAllFolders.test.js
|
||||
packages/lib/commands/toggleAllFolders.js
|
||||
packages/lib/commands/toggleEditorPlugin.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.test.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.js
|
||||
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextDismissLinkClick.js
|
||||
packages/lib/components/shared/NoteEditor/WarningBanner/onRichTextReadMoreLinkClick.js
|
||||
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
|
||||
packages/lib/components/shared/NoteRevisionViewer/getHelpMessage.js
|
||||
packages/lib/components/shared/NoteRevisionViewer/useDeleteHistoryClick.js
|
||||
packages/lib/components/shared/SamlShared.js
|
||||
packages/lib/components/shared/ShareNoteDialog/onUnshareNoteClick.js
|
||||
packages/lib/components/shared/ShareNoteDialog/types.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useOnShareLinkClick.js
|
||||
packages/lib/components/shared/ShareNoteDialog/useShareStatusMessage.js
|
||||
packages/lib/components/shared/SsoScreenShared.js
|
||||
packages/lib/components/shared/config/config-shared.js
|
||||
packages/lib/components/shared/config/plugins/types.js
|
||||
packages/lib/components/shared/config/plugins/useOnDeleteHandler.js
|
||||
@@ -1038,12 +1228,15 @@ packages/lib/fs-driver-base.js
|
||||
packages/lib/fs-driver-node.js
|
||||
packages/lib/fsDriver.test.js
|
||||
packages/lib/geolocation-node.js
|
||||
packages/lib/getAppName.test.js
|
||||
packages/lib/getAppName.js
|
||||
packages/lib/hooks/plugins/usePlugin.js
|
||||
packages/lib/hooks/plugins/useVisiblePluginEditorViewIds.js
|
||||
packages/lib/hooks/useAsyncEffect.js
|
||||
packages/lib/hooks/useElementSize.js
|
||||
packages/lib/hooks/useEventListener.js
|
||||
packages/lib/hooks/useNowEffect.test.js
|
||||
packages/lib/hooks/useNowEffect.js
|
||||
packages/lib/hooks/usePlugin.js
|
||||
packages/lib/hooks/usePrevious.js
|
||||
packages/lib/hooks/useQueuedAsyncEffect.test.js
|
||||
packages/lib/hooks/useQueuedAsyncEffect.js
|
||||
@@ -1098,6 +1291,7 @@ packages/lib/models/settings/settingValidations.js
|
||||
packages/lib/models/settings/types.js
|
||||
packages/lib/models/utils/areAllFoldersCollapsed.test.js
|
||||
packages/lib/models/utils/areAllFoldersCollapsed.js
|
||||
packages/lib/models/utils/getCanBeCollapsedFolderIds.test.js
|
||||
packages/lib/models/utils/getCanBeCollapsedFolderIds.js
|
||||
packages/lib/models/utils/getCollator.js
|
||||
packages/lib/models/utils/getConflictFolderId.js
|
||||
@@ -1168,6 +1362,7 @@ packages/lib/services/database/migrations/44.js
|
||||
packages/lib/services/database/migrations/45.js
|
||||
packages/lib/services/database/migrations/46.js
|
||||
packages/lib/services/database/migrations/47.js
|
||||
packages/lib/services/database/migrations/48.js
|
||||
packages/lib/services/database/migrations/index.js
|
||||
packages/lib/services/database/sqlStringToLines.js
|
||||
packages/lib/services/database/types.js
|
||||
@@ -1236,6 +1431,8 @@ packages/lib/services/ocr/OcrDriverBase.js
|
||||
packages/lib/services/ocr/OcrService.test.js
|
||||
packages/lib/services/ocr/OcrService.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTesseract.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTranscribe.test.js
|
||||
packages/lib/services/ocr/drivers/OcrDriverTranscribe.js
|
||||
packages/lib/services/ocr/utils/filterOcrText.test.js
|
||||
packages/lib/services/ocr/utils/filterOcrText.js
|
||||
packages/lib/services/ocr/utils/types.js
|
||||
@@ -1283,12 +1480,14 @@ packages/lib/services/plugins/testing/MockPluginRunner.js
|
||||
packages/lib/services/plugins/utils/createViewHandle.js
|
||||
packages/lib/services/plugins/utils/executeSandboxCall.js
|
||||
packages/lib/services/plugins/utils/getActivePluginEditorView.js
|
||||
packages/lib/services/plugins/utils/getActivePluginEditorViews.js
|
||||
packages/lib/services/plugins/utils/getPluginIssueReportUrl.test.js
|
||||
packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
|
||||
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingValue.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorView.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorViewIds.js
|
||||
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.test.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.js
|
||||
@@ -1403,6 +1602,7 @@ packages/lib/shim-init-node.js
|
||||
packages/lib/shim.js
|
||||
packages/lib/string-utils.test.js
|
||||
packages/lib/string-utils.js
|
||||
packages/lib/testing/plugins/createTestPlugin.js
|
||||
packages/lib/testing/share/makeMockShareInvitation.js
|
||||
packages/lib/testing/share/mockShareService.js
|
||||
packages/lib/testing/syncTargetUtils.js
|
||||
@@ -1444,11 +1644,13 @@ packages/lib/utils/ipc/utils/separateCallbacksFromSerializableArray.js
|
||||
packages/lib/utils/joplinCloud/index.js
|
||||
packages/lib/utils/joplinCloud/types.js
|
||||
packages/lib/utils/markupLanguageUtils.js
|
||||
packages/lib/utils/prefixWithHttps.js
|
||||
packages/lib/utils/processStartFlags.js
|
||||
packages/lib/utils/replaceUnsupportedCharacters.test.js
|
||||
packages/lib/utils/replaceUnsupportedCharacters.js
|
||||
packages/lib/utils/resolvePathWithinDir.test.js
|
||||
packages/lib/utils/resolvePathWithinDir.js
|
||||
packages/lib/utils/types/pdfJs.js
|
||||
packages/lib/utils/userFetcher.js
|
||||
packages/lib/utils/webDAVUtils.test.js
|
||||
packages/lib/utils/webDAVUtils.js
|
||||
@@ -1540,6 +1742,19 @@ packages/tools/checkIgnoredFiles.js
|
||||
packages/tools/checkLibPaths.test.js
|
||||
packages/tools/checkLibPaths.js
|
||||
packages/tools/convertThemesToCss.js
|
||||
packages/tools/fuzzer/ActionTracker.js
|
||||
packages/tools/fuzzer/Client.js
|
||||
packages/tools/fuzzer/ClientPool.js
|
||||
packages/tools/fuzzer/Server.js
|
||||
packages/tools/fuzzer/constants.js
|
||||
packages/tools/fuzzer/sync-fuzzer.js
|
||||
packages/tools/fuzzer/types.js
|
||||
packages/tools/fuzzer/utils/SeededRandom.js
|
||||
packages/tools/fuzzer/utils/getNumberProperty.js
|
||||
packages/tools/fuzzer/utils/getProperty.js
|
||||
packages/tools/fuzzer/utils/getStringProperty.js
|
||||
packages/tools/fuzzer/utils/openDebugSession.js
|
||||
packages/tools/fuzzer/utils/retryWithCount.js
|
||||
packages/tools/generate-database-types.js
|
||||
packages/tools/generate-images.js
|
||||
packages/tools/git-changelog.test.js
|
||||
@@ -1570,6 +1785,8 @@ packages/tools/release-electron.js
|
||||
packages/tools/release-ios.js
|
||||
packages/tools/release-plugin-repo-cli.js
|
||||
packages/tools/release-server.js
|
||||
packages/tools/release-transcribe.js
|
||||
packages/tools/saveClaConsentRecords.js
|
||||
packages/tools/setupNewRelease.js
|
||||
packages/tools/spellcheck.js
|
||||
packages/tools/tagServerLatest.js
|
||||
|
1
.husky/pre-commit
Normal file
@@ -0,0 +1 @@
|
||||
corepack yarn lint-staged
|
@@ -8,6 +8,7 @@
|
||||
"@joplin/fork-sax",
|
||||
"@joplin/fork-uslug",
|
||||
"@joplin/htmlpack",
|
||||
"@joplin/transcribe",
|
||||
"@joplin/lib",
|
||||
"@joplin/onenote-converter",
|
||||
"@joplin/pdf-viewer",
|
||||
|
3
.vscode/settings.json
vendored
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"cSpell.enabled": true
|
||||
"cSpell.enabled": true,
|
||||
"editor.insertSpaces": false
|
||||
}
|
10
.yarn/joplin-empty-package/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# @joplin/empty
|
||||
|
||||
An empty package. This package can be used to exclude certain dependencies from build.
|
||||
|
||||
For example, the `canvas` dependency is an optional dependency of `pdfjs-dist`. However, it isn't used by Joplin and can cause build to fail in certain environments. The `@joplin/empty` package can exclude `canvas` from the build by adding a resolution to `resolutions` in the top-level `package.json`. For example, resolving `canvas@npm:^2.11` to `file:./packages/empty/`.
|
||||
|
||||
See also:
|
||||
- [Yarn docs: Manifest resolutions](https://yarnpkg.com/configuration/manifest#resolutions)
|
||||
- [GitHub comment: Yarn: Ignoring packages](https://github.com/yarnpkg/yarn/issues/4611#issuecomment-1370284462)
|
||||
|
10
.yarn/joplin-empty-package/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@joplin/empty",
|
||||
"version": "0.0.0",
|
||||
"description": "An empty package, used as a way to exclude certain packages from build",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/laurent22/joplin.git"
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
diff --git a/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
index a5bb95eec3337b93a2338a2869a2bda176c91cae..87817688eb280c2f702c26dc35558c6a0a4db1ea 100644
|
||||
--- a/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
+++ b/android/src/newarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
@@ -42,12 +42,20 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> implement
|
||||
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
|
||||
ReactSlider slider = (ReactSlider)seekbar;
|
||||
|
||||
- if(progress < slider.getLowerLimit()) {
|
||||
- progress = slider.getLowerLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
- } else if (progress > slider.getUpperLimit()) {
|
||||
- progress = slider.getUpperLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
+ // During initialization, lowerLimit can be greater than upperLimit.
|
||||
+ //
|
||||
+ // If a change event is received during this, we need a check to prevent
|
||||
+ // infinite recursion.
|
||||
+ //
|
||||
+ // Issue: https://github.com/callstack/react-native-slider/issues/571
|
||||
+ if (slider.getLowerLimit() <= slider.getUpperLimit()) {
|
||||
+ if(progress < slider.getLowerLimit()) {
|
||||
+ progress = slider.getLowerLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ } else if (progress > slider.getUpperLimit()) {
|
||||
+ progress = slider.getUpperLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ }
|
||||
}
|
||||
|
||||
ReactContext reactContext = (ReactContext) seekbar.getContext();
|
||||
diff --git a/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java b/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
index 3ff5930f85a3cd92c2549925f41058abb188a57e..ab3681fdfe0b736c97020e1434e450c8183e6f18 100644
|
||||
--- a/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
+++ b/android/src/oldarch/java/com/reactnativecommunity/slider/ReactSliderManager.java
|
||||
@@ -30,12 +30,20 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> {
|
||||
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
|
||||
ReactSlider slider = (ReactSlider)seekbar;
|
||||
|
||||
- if(progress < slider.getLowerLimit()) {
|
||||
- progress = slider.getLowerLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
- } else if(progress > slider.getUpperLimit()) {
|
||||
- progress = slider.getUpperLimit();
|
||||
- seekbar.setProgress(progress);
|
||||
+ // During initialization, lowerLimit can be greater than upperLimit.
|
||||
+ //
|
||||
+ // If a change event is received during this, we need a check to prevent
|
||||
+ // infinite recursion.
|
||||
+ //
|
||||
+ // Issue: https://github.com/callstack/react-native-slider/issues/571
|
||||
+ if (slider.getLowerLimit() <= slider.getUpperLimit()) {
|
||||
+ if(progress < slider.getLowerLimit()) {
|
||||
+ progress = slider.getLowerLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ } else if (progress > slider.getUpperLimit()) {
|
||||
+ progress = slider.getUpperLimit();
|
||||
+ seekbar.setProgress(progress);
|
||||
+ }
|
||||
}
|
||||
|
||||
ReactContext reactContext = (ReactContext) seekbar.getContext();
|
@@ -1,33 +0,0 @@
|
||||
diff --git a/lib/runner/index.js b/lib/runner/index.js
|
||||
index 87e3b3957619728e3ed1ca61e2d83df1c49f928f..6d5ab905415da0577341c8f5b67d4806adcf7549 100644
|
||||
--- a/lib/runner/index.js
|
||||
+++ b/lib/runner/index.js
|
||||
@@ -68,15 +68,19 @@ function run([, scriptPath, hookName = '', HUSKY_GIT_PARAMS], getStdinFn = get_s
|
||||
return 0;
|
||||
}
|
||||
catch (err) {
|
||||
- const noVerifyMessage = [
|
||||
- 'commit-msg',
|
||||
- 'pre-commit',
|
||||
- 'pre-rebase',
|
||||
- 'pre-push'
|
||||
- ].includes(hookName)
|
||||
- ? '(add --no-verify to bypass)'
|
||||
- : '(cannot be bypassed with --no-verify due to Git specs)';
|
||||
- console.log(`husky > ${hookName} hook failed ${noVerifyMessage}`);
|
||||
+ // We do not want to print this "add --no-verify to bypass" message because that's
|
||||
+ // literally what some developers do instead of trying to fix the errors.
|
||||
+
|
||||
+ // const noVerifyMessage = [
|
||||
+ // 'commit-msg',
|
||||
+ // 'pre-commit',
|
||||
+ // 'pre-rebase',
|
||||
+ // 'pre-push'
|
||||
+ // ].includes(hookName)
|
||||
+ // ? '(add --no-verify to bypass)'
|
||||
+ // : '(cannot be bypassed with --no-verify due to Git specs)';
|
||||
+
|
||||
+ console.log(`husky > ${hookName} hook failed (Please fix the errors listed above and try again)`);
|
||||
return err.code;
|
||||
}
|
||||
});
|
@@ -1,6 +1,22 @@
|
||||
|
||||
# We remove the `canvas` optional dependency because electron-rebuild fails to build it, and
|
||||
# the `canvas` API is already part of Electron
|
||||
diff --git a/build/pdf.js b/build/pdf.js
|
||||
index 4acf16b1d6f9351bda1a98649ea4f926618fe617..f63dbc6050ca63ca8e8ed982edea134103fa15dd 100644
|
||||
--- a/build/pdf.js
|
||||
+++ b/build/pdf.js
|
||||
@@ -6244,8 +6244,9 @@ class NodeFilterFactory extends _base_factory.BaseFilterFactory {}
|
||||
exports.NodeFilterFactory = NodeFilterFactory;
|
||||
class NodeCanvasFactory extends _base_factory.BaseCanvasFactory {
|
||||
_createCanvas(width, height) {
|
||||
- const Canvas = require("canvas");
|
||||
- return Canvas.createCanvas(width, height);
|
||||
+ throw new Error('Node canvas disabled');
|
||||
+ // const Canvas = require("canvas");
|
||||
+ // return Canvas.createCanvas(width, height);
|
||||
}
|
||||
}
|
||||
exports.NodeCanvasFactory = NodeCanvasFactory;
|
||||
diff --git a/package.json b/package.json
|
||||
index 105811f53d508486e08a60dc1b6e437cd24d7427..dea6a4e6612c4a4006cc482e46ff5270dcfda1e5 100644
|
||||
--- a/package.json
|
||||
|
@@ -1,25 +0,0 @@
|
||||
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
index 8a719ca35af1cc3a4192c5c5f8258fd4f7fea990..5f8831f81cd164a4f627423427ead92fa286b115 100644
|
||||
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
@@ -37,7 +37,7 @@ import com.facebook.react.uimanager.common.ViewUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
-import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -149,7 +149,10 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
}
|
||||
|
||||
private class ConcurrentOperationQueue {
|
||||
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
|
||||
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
|
||||
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
|
||||
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
|
||||
+ private final Queue<UIThreadOperation> mQueue = new LinkedBlockingQueue<>();
|
||||
@Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
|
||||
@AnyThread
|
205
.yarn/patches/react-native-npm-0.79.2-9db13eddfe.patch
Normal file
@@ -0,0 +1,205 @@
|
||||
# This patch fixes two issues:
|
||||
# - Updates RCTDeviceInfo.m to match https://github.com/facebook/react-native/commit/0b8db7e5e814cfbf9974cc5b6ceb64e8006d8a3c.
|
||||
# This fixes an issue in which useWindowDimensions returns incorrect
|
||||
# values in landscape mode in iOS.
|
||||
# This should be fixed in React Native 0.80. See https://github.com/facebook/react-native/issues/51086.
|
||||
# - Updates NativeAnimatedModule.java to work around an Android 12-specific crash.
|
||||
diff --git a/React/CoreModules/RCTDeviceInfo.mm b/React/CoreModules/RCTDeviceInfo.mm
|
||||
index 6b4fcef852252e8d4ac2aceb12175fdfafb4def7..8ceab21e8653d429876d10e2d12ed1342780ad7d 100644
|
||||
--- a/React/CoreModules/RCTDeviceInfo.mm
|
||||
+++ b/React/CoreModules/RCTDeviceInfo.mm
|
||||
@@ -14,9 +14,7 @@
|
||||
#import <React/RCTEventDispatcherProtocol.h>
|
||||
#import <React/RCTInitializing.h>
|
||||
#import <React/RCTInvalidating.h>
|
||||
-#import <React/RCTKeyWindowValuesProxy.h>
|
||||
#import <React/RCTUtils.h>
|
||||
-#import <React/RCTWindowSafeAreaProxy.h>
|
||||
#import <atomic>
|
||||
|
||||
#import "CoreModulesPlugins.h"
|
||||
@@ -31,8 +29,13 @@ using namespace facebook::react;
|
||||
NSDictionary *_currentInterfaceDimensions;
|
||||
BOOL _isFullscreen;
|
||||
std::atomic<BOOL> _invalidated;
|
||||
+ NSDictionary *_constants;
|
||||
+
|
||||
+ __weak UIWindow *_applicationWindow;
|
||||
}
|
||||
|
||||
+static NSString *const kFrameKeyPath = @"frame";
|
||||
+
|
||||
@synthesize moduleRegistry = _moduleRegistry;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
@@ -40,14 +43,26 @@ RCT_EXPORT_MODULE()
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
- [[RCTKeyWindowValuesProxy sharedInstance] startObservingWindowSizeIfNecessary];
|
||||
+ _applicationWindow = RCTKeyWindow();
|
||||
+ [_applicationWindow addObserver:self forKeyPath:kFrameKeyPath options:NSKeyValueObservingOptionNew context:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
+ ofObject:(id)object
|
||||
+ change:(NSDictionary *)change
|
||||
+ context:(void *)context
|
||||
+{
|
||||
+ if ([keyPath isEqualToString:kFrameKeyPath]) {
|
||||
+ [self interfaceFrameDidChange];
|
||||
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTWindowFrameDidChangeNotification object:self];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
- return NO;
|
||||
+ return YES;
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
@@ -81,7 +96,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
- _currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance].currentInterfaceOrientation;
|
||||
+ _currentInterfaceOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(interfaceFrameDidChange)
|
||||
@@ -98,6 +113,15 @@ RCT_EXPORT_MODULE()
|
||||
selector:@selector(invalidate)
|
||||
name:RCTBridgeWillInvalidateModulesNotification
|
||||
object:nil];
|
||||
+
|
||||
+ _constants = @{
|
||||
+ @"Dimensions" : [self _exportedDimensions],
|
||||
+ // Note:
|
||||
+ // This prop is deprecated and will be removed in a future release.
|
||||
+ // Please use this only for a quick and temporary solution.
|
||||
+ // Use <SafeAreaView> instead.
|
||||
+ @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
|
||||
+ };
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
@@ -120,6 +144,8 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillInvalidateModulesNotification object:nil];
|
||||
|
||||
+ [_applicationWindow removeObserver:self forKeyPath:kFrameKeyPath];
|
||||
+
|
||||
#if TARGET_OS_IOS
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
#endif
|
||||
@@ -132,8 +158,13 @@ static BOOL RCTIsIPhoneNotched()
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
dispatch_once(&onceToken, ^{
|
||||
+ RCTAssertMainQueue();
|
||||
+
|
||||
// 20pt is the top safeArea value in non-notched devices
|
||||
- isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance].currentSafeAreaInsets.top > 20;
|
||||
+ UIWindow *keyWindow = RCTKeyWindow();
|
||||
+ if (keyWindow) {
|
||||
+ isIPhoneNotched = keyWindow.safeAreaInsets.top > 20;
|
||||
+ }
|
||||
});
|
||||
#endif
|
||||
|
||||
@@ -142,11 +173,13 @@ static BOOL RCTIsIPhoneNotched()
|
||||
|
||||
static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
{
|
||||
+ RCTAssertMainQueue();
|
||||
UIScreen *mainScreen = UIScreen.mainScreen;
|
||||
CGSize screenSize = mainScreen.bounds.size;
|
||||
+ UIView *mainWindow = RCTKeyWindow();
|
||||
|
||||
// We fallback to screen size if a key window is not found.
|
||||
- CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance].windowSize;
|
||||
+ CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize;
|
||||
|
||||
NSDictionary<NSString *, NSNumber *> *dimsWindow = @{
|
||||
@"width" : @(windowSize.width),
|
||||
@@ -170,7 +203,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil");
|
||||
RCTAccessibilityManager *accessibilityManager =
|
||||
(RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"];
|
||||
- RCTAssert(accessibilityManager, @"Failed to get exported dimensions: AccessibilityManager is nil");
|
||||
+ // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases.
|
||||
+ // We default the fontScale to 1.0 in this case. This should be okay: if we assume
|
||||
+ // that accessibilityManager will eventually become available, js will eventually
|
||||
+ // be updated with the correct fontScale.
|
||||
CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0;
|
||||
return RCTExportedDimensions(fontScale);
|
||||
}
|
||||
@@ -182,14 +218,7 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
|
||||
- (NSDictionary<NSString *, id> *)getConstants
|
||||
{
|
||||
- return @{
|
||||
- @"Dimensions" : [self _exportedDimensions],
|
||||
- // Note:
|
||||
- // This prop is deprecated and will be removed in a future release.
|
||||
- // Please use this only for a quick and temporary solution.
|
||||
- // Use <SafeAreaView> instead.
|
||||
- @"isIPhoneX_deprecated" : @(RCTIsIPhoneNotched()),
|
||||
- };
|
||||
+ return _constants;
|
||||
}
|
||||
|
||||
- (void)didReceiveNewContentSizeMultiplier
|
||||
@@ -209,10 +238,11 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
|
||||
- (void)interfaceOrientationDidChange
|
||||
{
|
||||
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
|
||||
- UIWindow *keyWindow = RCTKeyWindow();
|
||||
- UIInterfaceOrientation nextOrientation = keyWindow.windowScene.interfaceOrientation;
|
||||
+ UIApplication *application = RCTSharedApplication();
|
||||
+ UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
|
||||
|
||||
- BOOL isRunningInFullScreen = CGRectEqualToRect(keyWindow.frame, keyWindow.screen.bounds);
|
||||
+ BOOL isRunningInFullScreen =
|
||||
+ CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds);
|
||||
// We are catching here two situations for multitasking view:
|
||||
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
|
||||
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
|
||||
@@ -276,3 +306,4 @@ Class RCTDeviceInfoCls(void)
|
||||
{
|
||||
return RCTDeviceInfo.class;
|
||||
}
|
||||
+
|
||||
diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
index cf14e51cf5f561b84f1b6ace8410fc77d626758e..abc8c64adf26fbf73429aee7fd4f76877e98849a 100644
|
||||
--- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
+++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java
|
||||
@@ -42,6 +42,7 @@ import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
@@ -155,8 +156,15 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
}
|
||||
|
||||
private class ConcurrentOperationQueue {
|
||||
- private final Queue<UIThreadOperation> mQueue = new ConcurrentLinkedQueue<>();
|
||||
- @Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
+ // Patch: Use LinkedBlockingQueue instead of ConcurrentLinkedQueue.
|
||||
+ // In some versions of Android, ConcurrentLinkedQueue is known to drop
|
||||
+ // items, causing crashing. See https://github.com/laurent22/joplin/issues/8425
|
||||
+ private final Queue<UIThreadOperation> mQueue = (
|
||||
+ // The issue exists for Android 12, which corresponds to API levels 31 and 32.
|
||||
+ Build.VERSION.SDK_INT == 31 || Build.VERSION.SDK_INT == 32
|
||||
+ ) ? new LinkedBlockingQueue<>() : new ConcurrentLinkedQueue<>();
|
||||
+
|
||||
+ @Nullable private UIThreadOperation mPeekedOperation = null;
|
||||
|
||||
@AnyThread
|
||||
boolean isEmpty() {
|
@@ -0,0 +1,64 @@
|
||||
# This patch improves the note actions menu (the kebab menu)'s accessibility
|
||||
# by labelling its dismiss button.
|
||||
diff --git a/build/rnpm.js b/build/rnpm.js
|
||||
index 47bc91a88b9e2246a0ce4295f9f932da6a572461..75b5a22bdcbc2594238bcf953df6d54e18cc7793 100644
|
||||
--- a/build/rnpm.js
|
||||
+++ b/build/rnpm.js
|
||||
@@ -1267,7 +1267,9 @@
|
||||
onPress = _this$props.onPress,
|
||||
style = _this$props.style;
|
||||
return React__default.createElement(reactNative.TouchableWithoutFeedback, {
|
||||
- onPress: onPress
|
||||
+ onPress: onPress,
|
||||
+ accessibilityLabel: _this$props.accessibilityLabel,
|
||||
+ accessibilityRole: 'button',
|
||||
}, React__default.createElement(reactNative.Animated.View, {
|
||||
style: [styles.fullscreen, {
|
||||
opacity: this.fadeAnim
|
||||
@@ -1282,7 +1284,8 @@
|
||||
}(React.Component);
|
||||
|
||||
Backdrop.propTypes = {
|
||||
- onPress: propTypes.func.isRequired
|
||||
+ onPress: propTypes.func.isRequired,
|
||||
+ accessibilityLabel: propTypes.string,
|
||||
};
|
||||
var styles = reactNative.StyleSheet.create({
|
||||
fullscreen: {
|
||||
@@ -1352,6 +1355,7 @@
|
||||
style: styles$1.placeholder
|
||||
}, React__default.createElement(Backdrop, {
|
||||
onPress: ctx._onBackdropPress,
|
||||
+ accessibilityLabel: this.props.closeButtonLabel,
|
||||
style: backdropStyles,
|
||||
ref: ctx.onBackdropRef
|
||||
}), ctx._makeOptions());
|
||||
@@ -1784,6 +1788,7 @@
|
||||
}), React__default.createElement(MenuPlaceholder, {
|
||||
ctx: this,
|
||||
backdropStyles: customStyles.backdrop,
|
||||
+ closeButtonLabel: this.props.closeButtonLabel,
|
||||
ref: this._onPlaceholderRef
|
||||
}))));
|
||||
}
|
||||
@@ -1854,7 +1859,7 @@
|
||||
var _options$props = options.props,
|
||||
optionsContainerStyle = _options$props.optionsContainerStyle,
|
||||
renderOptionsContainer = _options$props.renderOptionsContainer,
|
||||
- customStyles = _options$props.customStyles;
|
||||
+ customStyles = _options$props.customStyles || {};
|
||||
var optionsRenderer = renderOptionsContainer || defaultOptionsContainerRenderer;
|
||||
var isOutside = !triggerLayout || !optionsLayout;
|
||||
|
||||
diff --git a/src/index.d.ts b/src/index.d.ts
|
||||
index 7e1ef2e441a665e97c304984080399f9646395df..673c4f713757abfb1851cba0d4560020c83e5f50 100644
|
||||
--- a/src/index.d.ts
|
||||
+++ b/src/index.d.ts
|
||||
@@ -18,6 +18,7 @@ declare module "react-native-popup-menu" {
|
||||
menuProviderWrapper?: StyleProp<ViewStyle>;
|
||||
backdrop?: StyleProp<ViewStyle>;
|
||||
};
|
||||
+ closeButtonLabel: string;
|
||||
backHandler?: boolean | Function;
|
||||
skipInstanceCheck?: boolean;
|
||||
children: React.ReactNode;
|
875
.yarn/releases/yarn-3.8.3.cjs
vendored
942
.yarn/releases/yarn-4.9.2.cjs
vendored
Executable file
11
.yarnrc.yml
@@ -2,17 +2,20 @@ nmHoistingLimits: workspaces
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
compressionLevel: mixed
|
||||
enableGlobalCache: false
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.8.3.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.9.2.cjs
|
||||
|
||||
logFilters:
|
||||
|
||||
# Disable useless non-actionable warnings.
|
||||
# https://github.com/yarnpkg/yarn/issues/4064
|
||||
|
||||
# e.g. "Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details."
|
||||
- code: YN0086
|
||||
level: discard
|
||||
|
||||
# eg "@joplin/app-desktop@workspace:packages/app-desktop provides react (p87edd) with version 18.2.0, which doesn't satisfy what @testing-library/react-hooks and some of its descendants request"
|
||||
- code: YN0060
|
||||
level: discard
|
||||
|
77
Assets/JoplinLetterBlue.svg
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 682.66669 682.66669"
|
||||
height="682.66669"
|
||||
width="682.66669"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
sodipodi:docname="JoplinLetterBlue.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview13"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.77490232"
|
||||
inkscape:cx="366.49781"
|
||||
inkscape:cy="360.69062"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="708"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<defs
|
||||
id="defs6">
|
||||
<linearGradient
|
||||
id="linearGradient26"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(-4387.91,4387.91,4387.91,4387.91,4753.95,366.05)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0">
|
||||
<stop
|
||||
id="stop22"
|
||||
offset="0"
|
||||
style="stop-opacity:1;stop-color:#004caf" />
|
||||
<stop
|
||||
id="stop24"
|
||||
offset="1"
|
||||
style="stop-opacity:1;stop-color:#1f95f8" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath829"><path
|
||||
id="path831"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.999997"
|
||||
d="M 3961.59,4435.23 H 2570.18 c -13.15,0 -23.78,-10.64 -23.78,-23.77 v -441.84 c 0,-14.87 12.04,-26.92 26.92,-26.92 h 190.77 c 77.16,0 139.73,-59.35 146.43,-134.77 V 3505 3336.23 1728.75 1717.36 h -0.052 c 0.48,-16.84 -0.1898,-33.4 -1.83,-49.71 -0.18,-2.38 -0.5003,-4.73 -0.7902,-7.09 -1.0998,-9.53 -2.3199,-19.01 -4.17,-28.29 -1.0098,-5.29 -2.4399,-10.44 -3.7098,-15.65 -1.71,-6.93 -3.09,-13.97 -5.22,-20.75 -12.5802,-40.27 -32.4702,-77.62 -59.9802,-110.5 -1.0098,-1.17 -2.2599,-2.25 -3.2598,-3.41 -8.3901,-9.72 -17.2002,-19.19 -26.9502,-28.06 -9.84,-8.95 -20.2599,-17.27 -31.2099,-25 -77.8401,-55.14 -182.61,-79.4 -299.67,-68.2 -149.2599,14.03 -297.3399,81.72 -417.03,190.62 -119.6701,108.89 -194.08,243.62 -209.4799,379.41 -13.8501,121.48 22.5498,228.38 102.42,301.05 0.21,0.1598 0.3997,0.3098 0.5602,0.48 3.09,2.77 6.4901,5.2 9.6701,7.87 57.16,47.89 131.6701,76.91 216.7,84.91 0.96,0.09 1.8801,0.24 2.79,0.3203 8.9499,0.79 18.0699,1.15 27.27,1.49 4.8099,0.1598 9.5601,0.5003 14.4399,0.54 1.62,0.023 3.1602,0.1898 4.7802,0.1898 2.8998,0 5.91,-0.3803 8.8098,-0.42 13.4001,-0.21 26.9001,-0.7601 40.6701,-1.9401 1.74,-0.1402 3.3999,-0.08 5.19,-0.24 1.2699,-0.1297 2.5299,-0.4102 3.8001,-0.54 78,-7.82 155.2299,-31.11 228.5199,-66.3999 1.53,-0.068 3.3,-0.54 5.5099,-1.7601 22.34,-12.3399 26.6201,0.9 27.2801,9.6501 v 382.2399 282.8201 c 0,19.05 -13.2501,35.8999 -31.83,39.99 -394.7601,86.88 -782.08,-3.5501 -1055.38,-252.3401 -238.7499,-217.1799 -354.24,-530.5799 -316.8201,-859.7899 33.39,-293.23 183.9102,-574.94 423.88,-793.33 233.8901,-212.79003 531.69,-345.86006 838.8801,-374.80106 42.33,-3.918 84.8601,-5.93797 126.36,-5.93797 293.3799,0 565.6099,100.59802 766.54,283.37903 190.3401,173.3 304.35,411.27 321.0799,670.16 l 1.55,1697.91 h 0.1703 v 453.97 h 0.06 v 7.92 c 1.72,80.1199 67.05,144.58 147.61,144.58 h 190.77 c 14.8599,0 26.9199,12.05 26.9199,26.9199 v 441.84 c 0,13.13 -10.6299,23.77 -23.7799,23.77" /></clipPath></defs>
|
||||
<g
|
||||
id="g14"
|
||||
transform="matrix(0.13333333,0,0,-0.13333333,0,682.66667)"
|
||||
mask="none"
|
||||
clip-path="url(#clipPath829)">
|
||||
<g
|
||||
clip-path="url(#clipPath20)"
|
||||
id="g16">
|
||||
<path
|
||||
id="path28"
|
||||
style="fill:url(#linearGradient26);fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 3873.89,0 H 1246.11 C 560.754,0 0,560.75 0,1246.11 V 3873.88 C 0,4559.25 560.754,5120 1246.11,5120 H 3873.89 C 4559.25,5120 5120,4559.25 5120,3873.88 V 1246.11 C 5120,560.75 4559.25,0 3873.89,0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
@@ -48,7 +48,7 @@ const updateListWithDetails = function (dom, el, detail) {
|
||||
};
|
||||
|
||||
const removeStyles = (dom, element: HTMLElement, styles: string[]) => {
|
||||
Tools.each(styles, (style) => dom.setStyle(element, { [style]: '' }));
|
||||
Tools.each(styles, (style) => dom.setStyle(element, style, ''));
|
||||
};
|
||||
|
||||
const getEndPointNode = function (editor, rng, start, root) {
|
||||
|
@@ -1300,4 +1300,9 @@ footer .bottom-links-row p {
|
||||
|
||||
:lang(zh-cn) #plans-section .faq {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.cfa-button {
|
||||
margin-top: 10px;
|
||||
}
|
BIN
Assets/WebsiteAssets/images/joplin_server_business/main.png
Normal file
After Width: | Height: | Size: 430 KiB |
BIN
Assets/WebsiteAssets/images/joplin_server_business/publish.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
Assets/WebsiteAssets/images/joplin_server_business/self_host.jpg
Normal file
After Width: | Height: | Size: 434 KiB |
BIN
Assets/WebsiteAssets/images/joplin_server_business/share.jpg
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
Assets/WebsiteAssets/images/joplin_server_business/teams.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
Assets/WebsiteAssets/images/news/20250428-collapse-all.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Assets/WebsiteAssets/images/news/20250428-link-notes.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
Assets/WebsiteAssets/images/news/20250428-new-note-menu.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/BestEtf.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/DamanGame.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/EssayService.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/EssayWriterPro.png
Normal file
After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.1 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/Freespinny.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/HomeworkGuy.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/PaperWriter.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/TiktokRise.jpg
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
Assets/WebsiteAssets/images/sponsors/WritePaper.png
Normal file
After Width: | Height: | Size: 16 KiB |
@@ -80,7 +80,7 @@ async function setupDownloadPage() {
|
||||
|
||||
if (href.indexOf('-Setup') > 0) downloadLinks['windows'] = href;
|
||||
if (href.indexOf('.dmg') > 0) downloadLinks['macOs'] = href;
|
||||
if (href.endsWith('arm64.DMG')) downloadLinks['macOsM1'] = href;
|
||||
if (href.indexOf('arm64.DMG') > 0) downloadLinks['macOsM1'] = href;
|
||||
if (href.indexOf('.AppImage') > 0) downloadLinks['linux'] = href;
|
||||
});
|
||||
|
||||
@@ -98,6 +98,8 @@ async function setupDownloadPage() {
|
||||
} else {
|
||||
const os = await getOs();
|
||||
|
||||
console.info('Found OS: ' + os);
|
||||
|
||||
if (os === 'macOsUndefined') {
|
||||
// If we don't know which macOS version it is, we let the user choose.
|
||||
$('.main-content .intro').html('<p class="macos-m1-info">The macOS release is available for Intel processors or for Apple Silicon (M1) processors. Please select your version:</p>');
|
||||
|
215
Assets/WebsiteAssets/locales/hr_HR.po
Normal file
@@ -0,0 +1,215 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Milo Ivir <mail@mivirtype.de>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: hr_HR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:13
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:9
|
||||
msgid "/month"
|
||||
msgstr "/mjesec"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/partials/plan.mustache:19
|
||||
msgid "/year"
|
||||
msgstr "/godina"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:8
|
||||
msgid ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> allows you to "
|
||||
"synchronise your notes across devices. It also lets you publish notes, and "
|
||||
"collaborate on notebooks with your friends, family or colleagues."
|
||||
msgstr ""
|
||||
"<a href=\"https://joplincloud.com\">Joplin Cloud</a> omogućuje "
|
||||
"sinkronizaciju bilješki na različitim uređajima. Omogućuje i objavljivanje "
|
||||
"bilješki i suradnju na bilježnicama s prijateljima, obitelji ili kolegama."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:205
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow-lg\">Customise</span> it"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow-lg\">Prilagodi</span> uslugu"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:104
|
||||
msgid "<span class=\"frame-bg frame-bg-yellow\">Multimedia</span> notes"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Multimedijske</span> bilješke"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:256
|
||||
msgid "100% <span class=\"frame-bg frame-bg-yellow-lg\">your data</span>"
|
||||
msgstr "100 % <span class=\"frame-bg frame-bg-yellow-lg\">tvoji podaci</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:298
|
||||
msgid "A <span class=\"frame-bg frame-bg-yellow-lg\">French</span> Alternative"
|
||||
msgstr ""
|
||||
"<span class=\"frame-bg frame-bg-yellow-lg\">Francuska</span> alternativa"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:236
|
||||
msgid ""
|
||||
"Access your notes from your computer, phone or tablet by synchronising with "
|
||||
"various services, including Joplin Cloud, Dropbox and OneDrive. The app is "
|
||||
"available on Windows, macOS, Linux, Android and iOS. A terminal app is also "
|
||||
"available!"
|
||||
msgstr ""
|
||||
"Pristupi svojim bilješkama s računala, mobitela ili tableta sinkronizacijom "
|
||||
"s raznim uslugama, uključujući Joplin Cloud, Dropbox i OneDrive. Program je "
|
||||
"dostupan za Windows, macOS, Linux, Android i iOS sustave. Dostupan je i "
|
||||
"program za terminal!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:49
|
||||
msgid ""
|
||||
"Already have a Joplin Cloud account? <a href=\"https://"
|
||||
"joplincloud.com\">Login now</a>"
|
||||
msgstr ""
|
||||
"Već imaš Joplin Cloud račun? <a href=\"https://joplincloud.com\">Prijavi se "
|
||||
"sada</a>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:208
|
||||
msgid ""
|
||||
"Customise the app with plugins, custom themes and multiple text editors "
|
||||
"(Rich Text or Markdown). Or create your own scripts and plugins using the "
|
||||
"Extension API."
|
||||
msgstr ""
|
||||
"Prilagodi program pomoću dodataka, prilagođenih tema i uređivača teksta "
|
||||
"(formatirani tekst ili Markdown). Ili izradi vlastita skripta i dodatke "
|
||||
"pomoću API-ja za proširenja."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:242
|
||||
msgid "Download it now"
|
||||
msgstr "Preuzmi sada"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:112
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:63
|
||||
msgid "Download the app"
|
||||
msgstr "Preuzmi program"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:213
|
||||
msgid "Find out more"
|
||||
msgstr "Saznaj više"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:54
|
||||
msgid "Free your <span class=\"frame-bg frame-bg-blue\">notes</span>"
|
||||
msgstr "Oslobodi svoje <span class=\"frame-bg frame-bg-blue\">bilješke</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:175
|
||||
msgid "Get the clipper"
|
||||
msgstr "Nabavi Clipper"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:107
|
||||
msgid ""
|
||||
"Images, videos, PDFs and audio files are supported. Create math expressions "
|
||||
"and diagrams directly from the app. Take photos with the mobile app and save "
|
||||
"them to a note."
|
||||
msgstr ""
|
||||
"Podržane su slike, videozapisi, PDF-ovi i audio datoteke. Stvori matematičke "
|
||||
"izraze i dijagrame izravno iz programa. Snimaj fotografije s programom za "
|
||||
"mobitel i spremi ih u bilješku."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:327
|
||||
msgid "In the <span class=\"frame-bg frame-bg-yellow\">Press</span>"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Recenzije</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:5
|
||||
msgid "Joplin Cloud <span class=\"frame-bg frame-bg-yellow\">plans</span>"
|
||||
msgstr "Joplin Cloud <span class=\"frame-bg frame-bg-yellow\">tarife</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:301
|
||||
msgid ""
|
||||
"Joplin Cloud is based in France. This means your data is protected by strict "
|
||||
"European Union privacy laws. In addition, Joplin Cloud implements strong end-"
|
||||
"to-end encryption so that not even us can have access to your data."
|
||||
msgstr ""
|
||||
"Joplin Cloud ima sjedište u Francuskoj. To znači da su tvoji podaci "
|
||||
"zaštićeni strogim zakonima o privatnosti Europske unije. Osim toga, Joplin "
|
||||
"Cloud implementira snažno sveobuhvatno šifriranje (end-to-end encryption) "
|
||||
"tako da čak ni mi ne možemo pristupiti tvojim podacima."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:57
|
||||
msgid ""
|
||||
"Joplin is an open source note-taking app. Capture your thoughts and securely "
|
||||
"access them from any device."
|
||||
msgstr ""
|
||||
"Joplin je program za bilješke otvorenog koda. Zabilježi svoje misli i "
|
||||
"sigurno im pristupi s bilo kojeg uređaja."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:262
|
||||
msgid "More about E2EE"
|
||||
msgstr "Više o E2EE"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:391
|
||||
msgid "Our <span class=\"frame-bg frame-bg-blue-lg\">sponsors</span>"
|
||||
msgstr "Naši <span class=\"frame-bg frame-bg-blue-lg\">sponzori</span>"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:23
|
||||
msgid "Pay Monthly"
|
||||
msgstr "Plaćaj mjesečno"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/plans.mustache:30
|
||||
msgid "Pay Yearly"
|
||||
msgstr "Plaćaj godišnje"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:167
|
||||
msgid ""
|
||||
"Save <span class=\"frame-bg frame-bg-blue\">web pages</span> <br>as notes"
|
||||
msgstr ""
|
||||
"Spremaj <span class=\"frame-bg frame-bg-blue\">web stranice</span> <br>kao "
|
||||
"bilješke"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:65
|
||||
msgid "Sign up with Joplin Cloud"
|
||||
msgstr "Registriraj se na Joplin Cloud"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:394
|
||||
msgid "Thank you for your support!"
|
||||
msgstr "Hvala ti na podršci!"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:257
|
||||
msgid ""
|
||||
"The app is open source and your notes are saved to an open format, so you'll "
|
||||
"always have access to them. Uses End-To-End Encryption (E2EE) to secure your "
|
||||
"notes and ensure no-one but yourself can access them."
|
||||
msgstr ""
|
||||
"Program je otvorenog koda i tvoje se bilješke spremaju u otvorenom formatu, "
|
||||
"tako da ćeš im uvijek moći pristupiti. Program koristi sveobuhvatno "
|
||||
"šifriranje – engl. End-To-End Encryption (E2EE) – kako bi zaštitila tvoje "
|
||||
"bilješke i osigurala da im nitko osim tebe ne može pristupiti."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:144
|
||||
msgid "Try it now"
|
||||
msgstr "Isprobaj sada"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:170
|
||||
msgid ""
|
||||
"Use the web clipper extension, available on Chrome and Firefox, to save web "
|
||||
"pages or take screenshots as notes."
|
||||
msgstr ""
|
||||
"Koristi proširenje Web Clipper, dostupno za Chrome i Firefox, za spremanje "
|
||||
"web stranica ili snimanje ekrana kao bilješku."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:138
|
||||
msgid ""
|
||||
"With Joplin Cloud, share your notes with your friends, family or colleagues "
|
||||
"and collaborate on them."
|
||||
msgstr ""
|
||||
"Joplin Cloud ti omogućuje da dijeliš bilješke s prijateljima, obitelji ili "
|
||||
"kolegama te da na njima surađujete."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:137
|
||||
msgid "Work <span class=\"frame-bg frame-bg-yellow\">together</span>"
|
||||
msgstr "<span class=\"frame-bg frame-bg-yellow\">Surađuj</span> s drugima"
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:141
|
||||
msgid ""
|
||||
"You can also publish a note to the internet and share the URL with others."
|
||||
msgstr "Bilješke možeš objaviti i na internetu te dijeliti URL s drugima."
|
||||
|
||||
#: /Users/laurent/src/joplin/Assets/WebsiteAssets/templates/front.mustache:233
|
||||
msgid ""
|
||||
"Your notes, <span class=\"frame-bg frame-bg-blue-lg\">everywhere</span> you "
|
||||
"are"
|
||||
msgstr ""
|
||||
"Tvoje bilješke, <span class=\"frame-bg frame-bg-blue-lg\">gdje god</span> se "
|
||||
"nalaziš"
|
@@ -1,4 +1,43 @@
|
||||
<?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>Tue, 14 Jan 2025 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Tue, 14 Jan 2025 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 3.2]]></title><description><![CDATA[<h2>Import OneNote Archives<a name="import-onenote-archives" href="#import-onenote-archives" class="heading-anchor">🔗</a></h2>
|
||||
<?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, 28 Apr 2025 00:00:00 GMT</lastBuildDate><atom:link href="https://joplinapp.org/rss.xml" rel="self" type="application/rss+xml"/><pubDate>Mon, 28 Apr 2025 00:00:00 GMT</pubDate><item><title><![CDATA[What's new in Joplin 3.3]]></title><description><![CDATA[<h2>Desktop application<a name="desktop-application" href="#desktop-application" class="heading-anchor">🔗</a></h2>
|
||||
<h3>Accessibility improvements<a name="accessibility-improvements" href="#accessibility-improvements" class="heading-anchor">🔗</a></h3>
|
||||
<p>The Joplin 3.3 release introduces significant accessibility enhancements designed to make the application more inclusive and user-friendly. Users can now benefit from improved keyboard navigation, thanks to newly added shortcuts and clearer labels that streamline interaction across the interface. We've also added a "go to viewer" menu item that moves focus from the note editor to the note viewer. Focus is moved to the location in the viewer corresponding to the location of the cursor in the editor.</p>
|
||||
<p>Screen reader support has been bolstered, ensuring elements like the note list and sidebar are easier to toggle and interact with. These updates make the application more usable for individuals relying on assistive technologies.</p>
|
||||
<p>Additionally, visual improvements, including increased contrast for UI components such as URLs, sidebars, and scrollbars, enhance readability for users with visual impairments. This focus on clarity ensures a more comfortable user experience.</p>
|
||||
<p>The Rich Text Editor has also received accessibility-focused updates, allowing for more seamless interaction with code blocks using either a keyboard or touchscreen. These refinements highlight Joplin's dedication to creating an accessible and equitable experience for all users.</p>
|
||||
<h3>Button to collapse and expand all notebooks<a name="button-to-collapse-and-expand-all-notebooks" href="#button-to-collapse-and-expand-all-notebooks" class="heading-anchor">🔗</a></h3>
|
||||
<p>Joplin 3.3 introduces a convenient "Collapse/Expand All" button for notebooks, allowing you to quickly adjust the visibility of your notebook hierarchy. This feature simplifies navigation by letting you expand all notebooks to locate specific notes or collapse them for a tidier interface!</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20250428-collapse-all.png" alt=""></p>
|
||||
<h3>New dialog to select a note and link to it<a name="new-dialog-to-select-a-note-and-link-to-it" href="#new-dialog-to-select-a-note-and-link-to-it" class="heading-anchor">🔗</a></h3>
|
||||
<p>A new dialog has been added to make linking to notes easier. By pressing Shift+Option+L on macOS or Shift+Alt+L on Windows and Linux, you can quickly bring up a search box. Simply type the name of the note you want to link to, and the link will be added to your current note!</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20250428-link-notes.png" alt=""></p>
|
||||
<h3>Support for multiple instances of Joplin<a name="support-for-multiple-instances-of-joplin" href="#support-for-multiple-instances-of-joplin" class="heading-anchor">🔗</a></h3>
|
||||
<p>Joplin Desktop now <a href="https://joplinapp.org/help/apps/multiple_instances">lets you run multiple instances at once</a>! This means you can easily separate your work and personal notes, or use Joplin across different virtual desktops. Each instance runs independently with its own settings, plugins, and notes, so nothing overlaps. You can open a second instance through in menu <strong>File => Open secondary app instance...</strong>, and customise it however you like!</p>
|
||||
<h3>Improved Rich Text editor<a name="improved-rich-text-editor" href="#improved-rich-text-editor" class="heading-anchor">🔗</a></h3>
|
||||
<p>This version includes multiple improvements and bug fixes to the Rich Text Editor. In particular it has now been upgraded to TinyMCE v6, and it adds support for Markdown auto-replacement. For example, typing <code>==highlight==</code> creates highlighted text. Auto-replacement can be disabled in settings.</p>
|
||||
<h2>Mobile application<a name="mobile-application" href="#mobile-application" class="heading-anchor">🔗</a></h2>
|
||||
<h3>Accessibility improvements<a name="accessibility-improvements-1" href="#accessibility-improvements-1" class="heading-anchor">🔗</a></h3>
|
||||
<p>Like the desktop app, the mobile app includes several accessibility improvements designed to enhance the user experience for those relying on assistive technologies. Focus handling has been improved in the note actions menu and modal dialogs, ensuring smoother navigation for screen reader users. Additionally, the default modal close button is now accessible, and issues with invisible buttons being focusable have been resolved.</p>
|
||||
<p>Other updates include better contrast for faded URLs in the Markdown editor, making them more readable for users with visual impairments. The encryption configuration screen has been improved for better accessibility, and screen reader support has been added for creating and editing profiles. These changes collectively improve navigation, readability, and usability for all users.</p>
|
||||
<h3>Support attaching audio recordings<a name="support-attaching-audio-recordings" href="#support-attaching-audio-recordings" class="heading-anchor">🔗</a></h3>
|
||||
<p>You can now easily capture and include audio recordings directly within your notes. To use this feature, open the kebab menu and select "Record audio." You can then to record your audio input. When finished, the app automatically attaches the recorded audio file to the note. This functionality is perfect for capturing ideas, reminders, or supplementary audio information in a quick and intuitive way.</p>
|
||||
<h3>Improved voice typing feature<a name="improved-voice-typing-feature" href="#improved-voice-typing-feature" class="heading-anchor">🔗</a></h3>
|
||||
<p>The voice typing feature in Android has undergone a significant improvement, making it more accurate. Previously introduced in version 2.11, the feature allowed you to transcribe speech into text but lacked punctuation and struggled with accuracy in certain scenarios. The revamped version now leverages Whisper, an advanced AI model, to deliver improved recognition, including automatic punctuation and paragraph formatting.</p>
|
||||
<p>Despite its advancements, the feature is currently in beta due to the demanding nature of the required AI models. While it defaults to a smaller, less accurate model to accommodate older devices, you can <a href="https://github.com/joplin/voice-typing-models/releases">manually download and switch to more accurate models</a> for better performance.</p>
|
||||
<p>As previously, the feature remains entirely offline, ensuring that private recordings are never sent to third-party servers, a distinct privacy advantage over similar solutions from Google or Apple. Additionally it means you can use the feature even when you don't have an internet connection. We plan to refine this feature further, eventually defaulting to the more accurate model as stability improves.</p>
|
||||
<h3>Improved new note menu<a name="improved-new-note-menu" href="#improved-new-note-menu" class="heading-anchor">🔗</a></h3>
|
||||
<p>The redesigned "New Note" menu takes note creation to a whole new level of flexibility and convenience. Previously, this menu only offered options to create a new note or a new to-do. With the latest update, you now have quick access to a variety of shortcuts, enabling you to attach files, record audio, capture photo notes, or even create drawings directly from the menu. This intuitive redesign makes it easier to choose the format that best suits your needs.</p>
|
||||
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20250428-new-note-menu.png" alt=""></p>
|
||||
<h2>Security and bug fixes<a name="security-and-bug-fixes" href="#security-and-bug-fixes" class="heading-anchor">🔗</a></h2>
|
||||
<p>As always, we continue to reinforce the security of Joplin. This version implements a robust content security policy for the Rich Text Editor, safeguarding the application against malicious content.</p>
|
||||
<p>In total, this version delivers 39 bug fixes on desktop and 17 on mobile, enhancing both the security and stability of the application.</p>
|
||||
<h2>Full changelogs<a name="full-changelogs" href="#full-changelogs" class="heading-anchor">🔗</a></h2>
|
||||
<p>This is just an overview of the main features. The full changelogs are available there:</p>
|
||||
<ul>
|
||||
<li>Desktop: <a href="https://joplinapp.org/help/about/changelog/desktop">https://joplinapp.org/help/about/changelog/desktop</a></li>
|
||||
<li>Android: <a href="https://joplinapp.org/help/about/changelog/android/">https://joplinapp.org/help/about/changelog/android/</a></li>
|
||||
<li>iOS: <a href="https://joplinapp.org/help/about/changelog/ios/">https://joplinapp.org/help/about/changelog/ios/</a></li>
|
||||
</ul>
|
||||
]]></description><link>https://joplinapp.org/news/20250428-release-3-3</link><guid isPermaLink="false">20250428-release-3-3</guid><pubDate>Mon, 28 Apr 2025 00:00:00 GMT</pubDate><twitter-text>What's new in Joplin 3.3</twitter-text></item><item><title><![CDATA[What's new in Joplin 3.2]]></title><description><![CDATA[<h2>Import OneNote Archives<a name="import-onenote-archives" href="#import-onenote-archives" class="heading-anchor">🔗</a></h2>
|
||||
<p>Joplin now supports importing OneNote archives, a significant step for users transitioning from OneNote. Microsoft has long made it challenging to leave OneNote, offering limited export options and complex formats that make it difficult for app developers to support it. Despite these hurdles, @pedr tackled these issues head-on, developing an import tool that simplifies the process. This addition makes Joplin a practical choice for those looking to move away from OneNote's ecosystem.</p>
|
||||
<p>To use this feature, select <strong>File</strong> => <strong>Import</strong> => <strong>ZIP - OneNote Notebook</strong></p>
|
||||
<h2>Multi-window support<a name="multi-window-support" href="#multi-window-support" class="heading-anchor">🔗</a></h2>
|
||||
@@ -413,10 +452,4 @@ sys 0m38.013s</p>
|
||||
<p>You will be part of a small team, so you will have an opportunity for a high-impact role, targeting hundreds of thousands of users.</p>
|
||||
<p>If you're interested please contact us at job-AT-joplin.cloud</p>
|
||||
<p>No agencies please.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20221209-job</link><guid isPermaLink="false">20221209-job</guid><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><twitter-text>Joplin is hiring!</twitter-text></item><item><title><![CDATA[Modernising and securing Joplin, one package at a time]]></title><description><![CDATA[<p>If you watch the <a href="https://github.com/laurent22/joplin">Joplin source code repository</a>, you may have noticed a lot of Renovate pull requests lately. This <a href="https://www.mend.io/free-developer-tools/renovate/">Renovate tool</a> is a way to manage dependencies - it automatically finds what needs to be updated, then upgrade it to the latest version, and create a pull request. If all tests pass, we can then merge this pull request. So far we have merged 267 of these pull requests.</p>
|
||||
<p>Updating Joplin packages was long due. It is necessary so that we don't fall behind and end up using unsupported or deprecated packages. We also benefit from bug fixes and performance improvements. It is also important in terms of security, since recent package versions usually include various security fixes.</p>
|
||||
<p>We used to rely on a tool called "npm audit" to do this, however it no longer works on the Joplin codebase, and it was always risky to use it since it would update multiple packages in one command - so if something went wrong it was difficult to find the culprit.</p>
|
||||
<p>Renovate on the other hand upgrades packages one at a time, and run our test units to ensure everything is still working as expected. It also upgrades multiple instances of the same package across the monorepo, which is convenient to keep our code consistent. It also has a number of options to make our life easier, such as the ability to automatically merge a pull request for patch releases since this is usually safe (when a package is, for example upgraded from 1.0.1 to 1.0.3).</p>
|
||||
<p>Although Renovate automates the package upgrades it doesn't mean all upgrades are straightforward - our tests won't catch all issues, so the apps might end up being broken or cannot be compiled anymore. So there's manual work involved to get everything working after certain upgrades - for the most part this has been done and the apps appear to be stable so far.</p>
|
||||
<p>This will however be an important part of pre-release 2.10 (or should it be 3.0?) - we hope that everything works but we may need your support to try this version and report any glitch you may have found. As always pre-release regressions have the highest priority so we aim to fix them as quickly as possible.</p>
|
||||
]]></description><link>https://joplinapp.org/news/20221115-renovate</link><guid isPermaLink="false">20221115-renovate</guid><pubDate>Tue, 15 Nov 2022 00:00:00 GMT</pubDate><twitter-text>Modernising and securing Joplin, one package at a time</twitter-text></item></channel></rss>
|
||||
]]></description><link>https://joplinapp.org/news/20221209-job</link><guid isPermaLink="false">20221209-job</guid><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><twitter-text>Joplin is hiring!</twitter-text></item></channel></rss>
|
@@ -398,7 +398,7 @@
|
||||
|
||||
<div class="text-center sponsors-org">
|
||||
{{#sponsors.orgs}}
|
||||
<a class="sponsor-org-item" href="{{url}}"><img title="{{title}}" src="{{imageBaseUrl}}/sponsors/{{imageName}}"></a>
|
||||
<a class="sponsor-org-item" href="{{url}}"><img alt="{{alt}}" title="{{title}}" src="{{imageBaseUrl}}/sponsors/{{imageName}}"></a>
|
||||
{{/sponsors.orgs}}
|
||||
</div>
|
||||
|
||||
|
@@ -1,24 +1,28 @@
|
||||
<div class="col-12 col-lg-4 account-type-{{priceMonthly.accountType}}">
|
||||
<div class="col-12 col-lg-4 account-type-{{priceMonthly.accountType}} hosting-type-{{hostingType}}">
|
||||
<div class="price-container {{#featured}}price-container-blue{{/featured}}">
|
||||
<div class="price-row">
|
||||
<div class="plan-type">
|
||||
<img src="{{imageBaseUrl}}/{{iconName}}.png"/> {{title}}
|
||||
<div class="price-row">
|
||||
<div class="plan-type">
|
||||
<img src="{{imageBaseUrl}}/{{iconName}}.png"/> {{title}}
|
||||
</div>
|
||||
|
||||
{{#priceMonthly.formattedMonthlyAmount}}
|
||||
<div class="plan-price plan-price-monthly">
|
||||
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month"> <span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
|
||||
</div>
|
||||
|
||||
<div class="plan-price plan-price-yearly">
|
||||
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month"> <span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
|
||||
</div>
|
||||
{{/priceMonthly.formattedMonthlyAmount}}
|
||||
</div>
|
||||
|
||||
<div class="plan-price plan-price-monthly">
|
||||
{{priceMonthly.formattedMonthlyAmount}}<sub class="per-month"> <span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
|
||||
{{#priceYearly.formattedMonthlyAmount}}
|
||||
<div class="plan-price-yearly-per-year">
|
||||
<div>
|
||||
({{priceYearly.formattedAmount}}<sub class="per-year"> <span translate>/year</span></sub>)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="plan-price plan-price-yearly">
|
||||
{{priceYearly.formattedMonthlyAmount}}<sub class="per-month"> <span translate>/month</span>{{#footnote}} (*){{/footnote}}</sub>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="plan-price-yearly-per-year">
|
||||
<div>
|
||||
({{priceYearly.formattedAmount}}<sub class="per-year"> <span translate>/year</span></sub>)
|
||||
</div>
|
||||
</div>
|
||||
{{/priceYearly.formattedMonthlyAmount}}
|
||||
|
||||
{{#featureLabelsOn}}
|
||||
<p><i class="fas fa-check feature feature-on"></i>{{.}}</p>
|
||||
@@ -29,7 +33,11 @@
|
||||
{{/featureLabelsOff}}
|
||||
|
||||
<p class="text-center subscribe-wrapper">
|
||||
<a id="subscribeButton-{{name}}" href="{{cfaUrl}}" class="button-link btn-white subscribeButton">{{cfaLabel}}</a>
|
||||
<a id="subscribeButton-{{name}}" href="{{cfaUrl}}" class="button-link btn-white subscribeButton cfa-button">{{cfaLabel}}</a>
|
||||
|
||||
{{#learnMoreUrl}}
|
||||
<a id="learnMore-{{name}}" href="{{learnMoreUrl}}" class="button-link btn-white learnMoreButton cfa-button">Learn more</a>
|
||||
{{/learnMoreUrl}}
|
||||
</p>
|
||||
|
||||
{{#footnote}}<sub>(*) {{.}}</sub>{{/footnote}}
|
||||
|
@@ -1,23 +1,91 @@
|
||||
<div id="plans-section" class="env-{{env}}">
|
||||
<style>
|
||||
.toggle-container {
|
||||
display: flex;
|
||||
border: 2px solid black;
|
||||
border-radius: 100px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
margin-top: 20px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.toggle-option {
|
||||
flex: 1;
|
||||
padding: 10px 20px;
|
||||
text-align: center;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.toggle-container {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12 title-box">
|
||||
<h1 translate class="text-center">
|
||||
Joplin Cloud <span class="frame-bg frame-bg-yellow">plans</span>
|
||||
Our synchronisation and sharing <span class="frame-bg frame-bg-yellow">solutions</span>
|
||||
</h1>
|
||||
<p translate class="text-center sub-title">
|
||||
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
|
||||
Synchronise and share your notes with our range of plans.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toggle-container" id="toggle">
|
||||
<div class="toggle-option active toggle-button-managed">Managed hosting</div>
|
||||
<div class="toggle-option inactive toggle-button-self">Self-hosting</div>
|
||||
</div>
|
||||
|
||||
<noscript>
|
||||
<div class="alert alert-danger alert-env-dev" role="alert" style='text-align: center; margin-top: 10px;'>
|
||||
To use this page please enable JavaScript!
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<div style="display: flex; justify-content: center; margin-top: 1.2em">
|
||||
<div class="row hosting-type-managed">
|
||||
<div class="col-12 title-box">
|
||||
<h1 translate class="text-center">
|
||||
Joplin Cloud
|
||||
</h1>
|
||||
<p translate class="text-center sub-title">
|
||||
<a href="https://joplincloud.com">Joplin Cloud</a> allows you to synchronise your notes across devices. It also lets you publish notes, and collaborate on notebooks with your friends, family or colleagues.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row hosting-type-self">
|
||||
<div class="col-12 title-box">
|
||||
<h1 translate class="text-center">
|
||||
Joplin Server Business
|
||||
</h1>
|
||||
<p translate class="text-center sub-title">
|
||||
Joplin Server Business is a synchronisation server that you can install on your own infrastructure, so that your data remains private and secure within your business.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; justify-content: center; margin-top: 1.2em" class="hosting-type-managed">
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="pay-monthly-radio" class="form-check-input" type="radio" name="pay-radio" checked value="monthly">
|
||||
<label translate style="font-weight: bold" class="form-check-label" for="pay-monthly-radio">
|
||||
@@ -46,7 +114,11 @@
|
||||
{{> plan}}
|
||||
{{/plans.teams}}
|
||||
|
||||
<p translate class="joplin-cloud-login-info">Already have a Joplin Cloud account? <a href="https://joplincloud.com">Login now</a></p>
|
||||
{{#plans.joplinServerBusiness}}
|
||||
{{> plan}}
|
||||
{{/plans.joplinServerBusiness}}
|
||||
|
||||
<p translate class="joplin-cloud-login-info hosting-type-managed">Already have a Joplin Cloud account? <a href="https://joplincloud.com">Login now</a></p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -147,5 +219,29 @@
|
||||
$('.feature-description-' + featureId).toggle(200);
|
||||
});
|
||||
});
|
||||
|
||||
const setHostingType = (type) => {
|
||||
const other = type === 'managed' ? 'self' : 'managed';
|
||||
$('.toggle-button-' + type).addClass('active');
|
||||
$('.toggle-button-' + type).removeClass('inactive');
|
||||
$('.toggle-button-' + other).addClass('inactive');
|
||||
$('.toggle-button-' + other).removeClass('active');
|
||||
|
||||
$('.hosting-type-' + type).show();
|
||||
$('.hosting-type-' + other).hide();
|
||||
}
|
||||
|
||||
$('.toggle-button-managed').click((event) => {
|
||||
event.preventDefault();
|
||||
setHostingType('managed');
|
||||
});
|
||||
|
||||
$('.toggle-button-self').click((event) => {
|
||||
event.preventDefault();
|
||||
setHostingType('self');
|
||||
});
|
||||
|
||||
const initialHostingType = urlQuery.get('hosting') ? urlQuery.get('hosting') : 'managed';
|
||||
setHostingType(initialHostingType);
|
||||
</script>
|
||||
</div>
|
||||
|
@@ -7,6 +7,9 @@ FROM node:18 AS builder
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
python3 tini \
|
||||
# needed for node-canvas for ARM32 platform.
|
||||
# See also https://github.com/Automattic/node-canvas/wiki/Installation:-Ubuntu-and-other-Debian-based-systems
|
||||
libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enables Yarn
|
||||
@@ -14,7 +17,6 @@ RUN corepack enable
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
COPY .yarn/plugins ./.yarn/plugins
|
||||
COPY .yarn/releases ./.yarn/releases
|
||||
COPY .yarn/patches ./.yarn/patches
|
||||
COPY package.json .
|
||||
@@ -47,9 +49,9 @@ RUN sed --in-place '/onenote-converter/d' ./packages/lib/package.json
|
||||
# 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
|
||||
RUN --mount=type=cache,target=/build/.yarn/cache --mount=type=cache,target=/build/.yarn/berry/cache\
|
||||
BUILD_SEQUENCIAL=1 yarn config set cacheFolder /build/.yarn/cache \
|
||||
&& yarn install --inline-builds
|
||||
|
||||
# =============================================================================
|
||||
# Final stage - we copy only the relevant files from the build stage and start
|
||||
@@ -81,10 +83,11 @@ CMD ["yarn", "start-prod"]
|
||||
ARG BUILD_DATE
|
||||
ARG REVISION
|
||||
ARG VERSION
|
||||
ARG SOURCE
|
||||
LABEL org.opencontainers.image.created="$BUILD_DATE" \
|
||||
org.opencontainers.image.title="Joplin Server" \
|
||||
org.opencontainers.image.description="Docker image for Joplin Server" \
|
||||
org.opencontainers.image.url="https://joplinapp.org/" \
|
||||
org.opencontainers.image.revision="$REVISION" \
|
||||
org.opencontainers.image.source="https://github.com/laurent22/joplin.git" \
|
||||
org.opencontainers.image.version="${VERSION}"
|
||||
org.opencontainers.image.source="$SOURCE" \
|
||||
org.opencontainers.image.version="$VERSION"
|
||||
|
50
Dockerfile.transcribe
Normal file
@@ -0,0 +1,50 @@
|
||||
FROM node:18-bullseye
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
ca-certificates curl \
|
||||
python3 tini
|
||||
|
||||
## install docker
|
||||
RUN install -m 0755 -d /etc/apt/keyrings
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
RUN chmod a+r /etc/apt/keyrings/docker.asc
|
||||
RUN echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
|
||||
$(. /etc/os-release && echo bullseye) stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY .yarn/releases ./.yarn/releases
|
||||
COPY .yarn/patches ./.yarn/patches
|
||||
COPY package.json .
|
||||
COPY .yarnrc.yml .
|
||||
COPY yarn.lock .
|
||||
COPY gulpfile.js .
|
||||
COPY tsconfig.json .
|
||||
COPY packages/lib ./packages/lib
|
||||
COPY packages/utils ./packages/utils
|
||||
COPY packages/tools ./packages/tools
|
||||
COPY packages/renderer ./packages/renderer
|
||||
COPY packages/htmlpack ./packages/htmlpack
|
||||
COPY packages/transcribe ./packages/transcribe
|
||||
|
||||
# We don't want to build onenote-converter since it is not used by the server
|
||||
RUN sed --in-place '/onenote-converter/d' ./packages/lib/package.json
|
||||
|
||||
RUN BUILD_SEQUENCIAL=1 yarn install --inline-builds \
|
||||
&& yarn cache clean \
|
||||
&& rm -rf .yarn/berry
|
||||
|
||||
WORKDIR /app/packages/transcribe
|
||||
|
||||
# Start the Node.js application
|
||||
CMD ["yarn", "start"]
|
@@ -67,10 +67,23 @@ showHelp() {
|
||||
fi
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Setup Download Helper: DL
|
||||
#-----------------------------------------------------
|
||||
if [[ `command -v wget2` ]]; then
|
||||
DL='wget2 -qO'
|
||||
elif [[ `command -v wget` ]]; then
|
||||
DL='wget -qO'
|
||||
elif [[ `command -v curl` ]]; then
|
||||
DL='curl -sLo'
|
||||
else
|
||||
print "${COLOR_RED}Error: wget2, wget, and curl not found. Please install one of these tools.${COLOR_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#-----------------------------------------------------
|
||||
# PARSE ARGUMENTS
|
||||
#-----------------------------------------------------
|
||||
|
||||
optspec=":h-:"
|
||||
while getopts "${optspec}" OPT; do
|
||||
[ "${OPT}" = " " ] && continue
|
||||
@@ -140,9 +153,9 @@ fi
|
||||
|
||||
# Get the latest version to download
|
||||
if [[ "$INCLUDE_PRE_RELEASE" == true ]]; then
|
||||
RELEASE_VERSION=$(wget -qO - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1)
|
||||
RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1)
|
||||
else
|
||||
RELEASE_VERSION=$(wget -qO - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")')
|
||||
RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")')
|
||||
fi
|
||||
|
||||
# Check if it's in the latest version
|
||||
@@ -163,8 +176,8 @@ fi
|
||||
#-----------------------------------------------------
|
||||
print 'Downloading Joplin...'
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE"
|
||||
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
|
||||
$DL "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE"
|
||||
$DL "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
|
||||
|
||||
#-----------------------------------------------------
|
||||
print 'Installing Joplin...'
|
||||
@@ -287,7 +300,7 @@ echo "$RELEASE_VERSION" > "${INSTALL_DIR}/VERSION"
|
||||
|
||||
#-----------------------------------------------------
|
||||
if [[ "$SHOW_CHANGELOG" == true ]]; then
|
||||
NOTES=$(wget -qO - https://api.github.com/repos/laurent22/joplin/releases/latest | grep -Po '"body": "\K.*(?=")')
|
||||
NOTES=$($DL - https://api.github.com/repos/laurent22/joplin/releases/latest | grep -Po '"body": "\K.*(?=")')
|
||||
print "${COLOR_BLUE}Changelog:${COLOR_RESET}\n${NOTES}"
|
||||
fi
|
||||
|
||||
|
@@ -31,7 +31,7 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
|
||||
# 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://www.hosting.de/nextcloud/?mtm_campaign=managed-nextcloud&mtm_kwd=joplinapp&mtm_source=joplinapp-webseite&mtm_medium=banner"><img title="Hosting.de" width="256" src="https://joplinapp.org/images/sponsors/HostingDe.png"/></a> <a href="https://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp"><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com"><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a> <a href="https://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.png"/></a> <a href="https://stormlikes.com/"><img title="Stormlikes" width="256" src="https://joplinapp.org/images/sponsors/Stormlikes.png"/></a> <a href="https://route4me.com"><img title="Route4Me" width="256" src="https://joplinapp.org/images/sponsors/Route4Me.png"/></a> <a href="https://casinoreviews.net"><img title="Casino Reviews" width="256" src="https://joplinapp.org/images/sponsors/CasinoReviews.png"/></a> <a href="https://useviral.com.br/"><img title="Comprar seguidores Instagram" width="256" src="https://joplinapp.org/images/sponsors/Useviral.png"/></a> <a href="https://ca.edubirdie.com/"><img title="Achieve academic success with Edubirdie — your trusted partner for expert writing assistance and resources!" width="256" src="https://joplinapp.org/images/sponsors/Edubirdie.png" alt="EduBirdie"/></a> <a href="https://topagency.webflow.io"><img title="WebDesignAgency" width="256" src="https://joplinapp.org/images/sponsors/WebDesignAgency.png" alt="web design agency"/></a> <a href="https://realgambling.ca/"><img title="RealGambling.ca" width="256" src="https://joplinapp.org/images/sponsors/RealGambling.png" alt="RealGambling.ca"/></a> <a href="https://essaypro.com/"><img title="write an essay online with EssayPro" width="256" src="https://joplinapp.org/images/sponsors/EssayPro.png" alt="write an essay online with EssayPro"/></a> <a href="https://www.slotozilla.com/nz/no-deposit-bonus"><img title="casino without making any upfront cost" width="256" src="https://joplinapp.org/images/sponsors/Slotozilla.png" alt="casino without making any upfront cost"/></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://citricsheep.com"><img title="Citric Sheep" width="256" src="https://joplinapp.org/images/sponsors/CitricSheep.png"/></a> <a href="https://sorted.travel/?utm_source=joplinapp"><img title="Sorted Travel" width="256" src="https://joplinapp.org/images/sponsors/SortedTravel.png"/></a> <a href="https://celebian.com"><img title="Celebian" width="256" src="https://joplinapp.org/images/sponsors/Celebian.png"/></a> <a href="https://bestkru.com"><img title="BestKru" width="256" src="https://joplinapp.org/images/sponsors/BestKru.png"/></a> <a href="https://www.socialfollowers.uk/buy-tiktok-followers/"><img title="Social Followers" width="256" src="https://joplinapp.org/images/sponsors/SocialFollowers.png"/></a> <a href="https://stormlikes.com/"><img title="Stormlikes" width="256" src="https://joplinapp.org/images/sponsors/Stormlikes.png"/></a> <a href="https://route4me.com"><img title="Route4Me" width="256" src="https://joplinapp.org/images/sponsors/Route4Me.png"/></a> <a href="https://topagency.webflow.io"><img title="WebDesignAgency" width="256" src="https://joplinapp.org/images/sponsors/WebDesignAgency.png" alt="topagency"/></a> <a href="https://www.slotozilla.com/nz/no-deposit-bonus"><img title="casino without making any upfront cost" width="256" src="https://joplinapp.org/images/sponsors/Slotozilla.png" alt="casino without making any upfront cost"/></a> <a href="https://essayservice.com"><img title="quick and reliable service to write my paper for me" width="256" src="https://joplinapp.org/images/sponsors/EssayService.png" alt="quick and reliable service to write my paper for me"/></a> <a href="https://writepaper.com/"><img title="best service to write my paper for me" width="256" src="https://joplinapp.org/images/sponsors/WritePaper.png" alt="best service to write my paper for me"/></a> <a href="https://paperwriter.com/"><img title="high-quality paper writing service PaperWriter" width="256" src="https://joplinapp.org/images/sponsors/PaperWriter.png" alt="high-quality paper writing service PaperWriter"/></a> <a href="https://www.bestetf.net/"><img title="BestETF" width="256" src="https://joplinapp.org/images/sponsors/BestEtf.png" alt="BestETF"/></a> <a href="https://freespinny.io/free-spins-no-deposit/"><img title="Freespinny.io Free Spins Bonus site" width="256" src="https://joplinapp.org/images/sponsors/Freespinny.png" alt="Freespinny.io Free Spins Bonus site"/></a> <a href="https://damangameplay.in"><img title="Daman Game" width="256" src="https://joplinapp.org/images/sponsors/DamanGame.png" alt="Daman Game"/></a>
|
||||
<!-- SPONSORS-ORG -->
|
||||
|
||||
* * *
|
||||
@@ -40,8 +40,7 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
|
||||
| | | | |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/97193607?s=96&v=4"/></br>[Akhil-CM](https://github.com/Akhil-CM) | <img width="50" src="https://avatars2.githubusercontent.com/u/552452?s=96&v=4"/></br>[andypiper](https://github.com/andypiper) | <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/67130?s=96&v=4"/></br>[chr15m](https://github.com/chr15m) |
|
||||
| <img width="50" src="https://avatars2.githubusercontent.com/u/1177810?s=96&v=4"/></br>[felixstorm](https://github.com/felixstorm) | <img width="50" src="https://avatars2.githubusercontent.com/u/8030470?s=96&v=4"/></br>[Galliver7](https://github.com/Galliver7) | <img width="50" src="https://avatars2.githubusercontent.com/u/64712218?s=96&v=4"/></br>[Hegghammer](https://github.com/Hegghammer) | <img width="50" src="https://avatars2.githubusercontent.com/u/11947658?s=96&v=4"/></br>[KentBrockman](https://github.com/KentBrockman) |
|
||||
| <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/327998?s=96&v=4"/></br>[sif](https://github.com/sif) | <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/1177810?s=96&v=4"/></br>[felixstorm](https://github.com/felixstorm) | <img width="50" src="https://avatars2.githubusercontent.com/u/11947658?s=96&v=4"/></br>[KentBrockman](https://github.com/KentBrockman) | <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/668977?s=96&v=4"/></br>[ugoertz](https://github.com/ugoertz) |
|
||||
| | | | |
|
||||
<!-- SPONSORS-GITHUB -->
|
||||
|
||||
@@ -50,9 +49,10 @@ Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/read
|
||||
Name | Description
|
||||
--- | ---
|
||||
[Support Forum](https://discourse.joplinapp.org/) | This is the main place for general discussion about Joplin, user support, software development questions, and to discuss new features. Also where the latest beta versions are released and discussed.
|
||||
[Patreon page](https://www.patreon.com/joplin) |The latest news are often posted there
|
||||
[Bluesky feed](https://bsky.app/profile/joplinapp.bsky.social) | Follow us on Bluesky
|
||||
[Mastodon feed](https://mastodon.social/@joplinapp) | Follow us on Mastodon
|
||||
[Patreon page](https://www.patreon.com/joplin) |The latest news are often posted there
|
||||
[YouTube](https://www.youtube.com/@joplinapp) | Discover information and tutorials on how to use the apps
|
||||
[Discord server](https://discord.gg/VSj7AFHvpq) | Our chat server
|
||||
[LinkedIn](https://www.linkedin.com/company/joplin) | Our LinkedIn page
|
||||
[Lemmy Community](https://sopuli.xyz/c/joplinapp) | Also a good place to get help
|
||||
|
15
crowdin.yml
@@ -6,18 +6,19 @@ files:
|
||||
- source: /readme/**/*
|
||||
translation: /readme/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
|
||||
ignore:
|
||||
- /**/*.jpg
|
||||
- /**/*.json
|
||||
- /**/*.png
|
||||
- /**/*.yml
|
||||
- /readme/_i18n
|
||||
- /readme/i18n
|
||||
- /readme/about/changelog
|
||||
- /readme/about/stats.md
|
||||
- /readme/api
|
||||
- /readme/dev
|
||||
- /readme/news
|
||||
- /readme/cla.md
|
||||
- /readme/connection_check.md
|
||||
- /readme/dev
|
||||
- /readme/i18n
|
||||
- /readme/licenses.md
|
||||
- /readme/news
|
||||
- /readme/privacy.md
|
||||
- /**/*.yml
|
||||
- /**/*.json
|
||||
- /**/*.png
|
||||
- /**/*.jpg
|
||||
|
11
devbox.json
@@ -5,27 +5,24 @@
|
||||
"version": "latest",
|
||||
"platforms": ["aarch64-darwin", "x86_64-darwin"],
|
||||
},
|
||||
"yarn": "latest",
|
||||
"yarn": "1.22.19",
|
||||
"vips.dev": {
|
||||
"platforms": ["aarch64-darwin"],
|
||||
},
|
||||
"nodejs": "latest",
|
||||
"nodejs": "23.10.0",
|
||||
"pkg-config": "latest",
|
||||
"pixman": "latest",
|
||||
"cairo.dev": "",
|
||||
"pango.dev": "",
|
||||
"darwin.apple_sdk.frameworks.Foundation": { // satisfies missing CoreText/CoreText.h
|
||||
// https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/darwin/apple-sdk/default.nix
|
||||
"version": "",
|
||||
"platforms": ["aarch64-darwin", "x86_64-darwin"],
|
||||
},
|
||||
"python": "latest",
|
||||
"python": "3.13.3",
|
||||
"bat": "latest",
|
||||
"electron": {
|
||||
"version": "latest",
|
||||
"excluded_platforms": ["aarch64-darwin", "x86_64-darwin"],
|
||||
},
|
||||
"git": "latest",
|
||||
"git": "2.48.1",
|
||||
},
|
||||
"shell": {
|
||||
"init_hook": [
|
||||
|
@@ -21,7 +21,7 @@ version: '2'
|
||||
services:
|
||||
|
||||
postgresql-master:
|
||||
image: 'bitnami/postgresql:16.3.0'
|
||||
image: 'bitnami/postgresql:17.3.0'
|
||||
ports:
|
||||
- '5432:5432'
|
||||
environment:
|
||||
@@ -38,7 +38,7 @@ services:
|
||||
- POSTGRESQL_EXTRA_FLAGS=-c work_mem=100000 -c log_statement=all
|
||||
|
||||
postgresql-slave:
|
||||
image: 'bitnami/postgresql:16.3.0'
|
||||
image: 'bitnami/postgresql:17.3.0'
|
||||
ports:
|
||||
- '5433:5432'
|
||||
depends_on:
|
||||
|
@@ -17,11 +17,21 @@
|
||||
|
||||
version: '3'
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
transcribe-network:
|
||||
shared-network:
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:16
|
||||
profiles:
|
||||
- full
|
||||
- server
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
networks:
|
||||
- app-network
|
||||
ports:
|
||||
- "5432:5432"
|
||||
restart: unless-stopped
|
||||
@@ -31,10 +41,17 @@ services:
|
||||
- POSTGRES_DB=${POSTGRES_DATABASE}
|
||||
app:
|
||||
image: joplin/server:latest
|
||||
profiles:
|
||||
- full
|
||||
- server
|
||||
depends_on:
|
||||
- db
|
||||
- transcribe
|
||||
ports:
|
||||
- "22300:22300"
|
||||
networks:
|
||||
- app-network
|
||||
- shared-network
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_PORT=22300
|
||||
@@ -45,3 +62,48 @@ services:
|
||||
- POSTGRES_USER=${POSTGRES_USER}
|
||||
- POSTGRES_PORT=${POSTGRES_PORT}
|
||||
- POSTGRES_HOST=db
|
||||
- TRANSCRIBE_API_KEY=${TRANSCRIBE_API_KEY}
|
||||
- TRANSCRIBE_BASE_URL=http://transcribe:4567
|
||||
- TRANSCRIBE_ENABLED=${TRANSCRIBE_ENABLED}
|
||||
transcribe-db:
|
||||
image: postgres:16
|
||||
profiles:
|
||||
- full
|
||||
volumes:
|
||||
- ./data/transcribe-postgres:/var/lib/postgresql/data
|
||||
networks:
|
||||
- transcribe-network
|
||||
ports:
|
||||
- "${QUEUE_DATABASE_PORT}:5432"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=${QUEUE_DATABASE_PASSWORD}
|
||||
- POSTGRES_USER=${QUEUE_DATABASE_USER}
|
||||
- POSTGRES_DB=${QUEUE_DATABASE_NAME}
|
||||
command: -p ${QUEUE_DATABASE_PORT}
|
||||
transcribe:
|
||||
image: joplin/transcribe:latest
|
||||
profiles:
|
||||
- full
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ${HTR_CLI_IMAGES_FOLDER}:/app/packages/transcribe/images
|
||||
depends_on:
|
||||
- transcribe-db
|
||||
ports:
|
||||
- "4567:4567"
|
||||
networks:
|
||||
- transcribe-network
|
||||
- shared-network
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_PORT=4567
|
||||
- DB_CLIENT=pg
|
||||
- QUEUE_DATABASE_NAME=${QUEUE_DATABASE_NAME}
|
||||
- QUEUE_DATABASE_USER=${QUEUE_DATABASE_USER}
|
||||
- QUEUE_DATABASE_PASSWORD=${QUEUE_DATABASE_PASSWORD}
|
||||
- QUEUE_DATABASE_PORT=${QUEUE_DATABASE_PORT}
|
||||
- QUEUE_DATABASE_HOST=transcribe-db
|
||||
- API_KEY=${TRANSCRIBE_API_KEY}
|
||||
- HTR_CLI_IMAGES_FOLDER=${HTR_CLI_IMAGES_FOLDER}
|
||||
|
||||
|
13
fastlane/metadata/android/hr/full_description.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
<strong>Joplin</strong> je besplatan program otvorenog koda za bilješke i popis zadataka koji može obraditi veliki broj bilješki organizirane u bilježnice. Bilješke se mogu pretraživati, kopirati, označavati i mijenjati izravno iz programa ili iz vlastitog uređivača teksta.
|
||||
|
||||
Bilješke su u <a href="https://joplinapp.org/help/apps/markdown">Markdown formatu</a>.
|
||||
|
||||
Iz Evernotea izvezene bilješke <a href="https://joplinapp.org/help/apps/import_export">mogu se uvesti</a> u Joplin, uključujući formatirani sadržaj (koji se pretvara u Markdown), resurse (slike, privitke itd.) i potpune metapodatke (geografski podaci mjesta, vrijeme aktualiziranja, vrijeme stvaranja itd.). Mogu se uvesti i obične Markdown datoteke.
|
||||
|
||||
Joplin radi ponajprije s lokalnim podacima (offline first), što znači da uvijek imaš sve svoje podatke na mobitelu ili računalu. To osigurava da su tvoje bilješke uvijek dostupne, bez obzira je li imaš internetsku vezu ili ne.</p>
|
||||
|
||||
Bilješke se mogu sigurno <a href="https://joplinapp.org/help/apps/sync">sinkronizirati</a> pomoću <a href="https://joplinapp.org/help/apps/sync/e2ee">sveobuhvatnog šifriranja</a> s raznim uslugama u oblaku, uključujući Nextcloud, Dropbox, OneDrive i <a href="https://joplinapp.org/plans/">Joplin Cloud</a>.
|
||||
|
||||
Pretraživanje cijelog teksta dostupno je na svim platformama za brzo pronalaženje potrebnih informacija. Program se može prilagoditi pomoću dodataka i tema, a možeš stvoriti i vlastite.
|
||||
|
||||
Program je dostupan za Windows, Linux, macOS, Android i iOS sustave. <a href="https://joplinapp.org/help/apps/clipper">Web Clipper</a>, za spremanje web stranica i snimaka ekrana iz tvog preglednika, je također dostupan za <a href="https://addons.mozilla.org/firefox/addon/joplin-web-clipper/">Firefox</a> i <a href="https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek">Chrome</a>.
|
1
fastlane/metadata/android/hr/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Program za bilješke i popis zadataka sa sinkronizacijom između Linuxa, macOS-a, Windowsa i mobitela
|
@@ -339,6 +339,7 @@
|
||||
"packages/renderer/MdToHtml/rules/fence.js": true,
|
||||
"packages/renderer/MdToHtml/rules/mermaid.js": true,
|
||||
"packages/renderer/MdToHtml/rules/sanitize_html.js": true,
|
||||
"packages/transcribe/dist": true,
|
||||
"packages/server/db-*.sqlite": true,
|
||||
"packages/server/dist/": true,
|
||||
"packages/utils/dist/": true,
|
||||
|
66
package.json
@@ -10,14 +10,14 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"yarn": "3.8.3"
|
||||
"yarn": "4.9.2"
|
||||
},
|
||||
"scripts": {
|
||||
"buildApiDoc": "yarn workspace joplin start apidoc ../../readme/api/references/rest_api.md",
|
||||
"buildScriptIndexes": "node packages/tools/gulp/tasks/buildScriptIndexesRun.js",
|
||||
"buildParallel": "yarn workspaces foreach --verbose --interlaced --parallel --jobs 2 --topological run build && yarn tsc",
|
||||
"buildParallel": "yarn workspaces foreach --worktree --verbose --interlaced --parallel --jobs 2 --topological-dev run build && yarn tsc",
|
||||
"buildPluginDoc": "cd packages/generate-plugin-doc && yarn buildPluginDoc_",
|
||||
"buildSequential": "yarn workspaces foreach --verbose --interlaced --topological run build && yarn tsc",
|
||||
"buildSequential": "yarn workspaces foreach --worktree --verbose --interlaced --topological-dev run build && yarn tsc",
|
||||
"buildServerDocker": "node packages/tools/buildServerDocker.js",
|
||||
"buildSettingJsonSchema": "yarn workspace joplin start settingschema ../../../joplin-website/docs/schema/settings.json",
|
||||
"buildTranslations": "node packages/tools/build-translation.js",
|
||||
@@ -38,7 +38,8 @@
|
||||
"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",
|
||||
"packageJsonLint": "node ./packages/tools/packageJsonLint.js",
|
||||
"postinstall": "gulp build",
|
||||
"syncFuzzer": "node ./packages/tools/fuzzer/sync-fuzzer.js",
|
||||
"postinstall": "husky && gulp build",
|
||||
"postPreReleasesToForum": "node ./packages/tools/postPreReleasesToForum",
|
||||
"publishAll": "git pull && yarn buildParallel && lerna version --yes --no-private --no-git-tag-version && gulp completePublishAll",
|
||||
"releaseAndroid": "PATH=\"/usr/local/opt/openjdk@17/bin:$PATH\" node packages/tools/release-android.js",
|
||||
@@ -50,72 +51,73 @@
|
||||
"releasePluginGenerator": "node packages/tools/release-plugin-generator.js",
|
||||
"releasePluginRepoCli": "node packages/tools/release-plugin-repo-cli.js",
|
||||
"releaseServer": "node packages/tools/release-server.js",
|
||||
"releaseTranscribe": "node packages/tools/release-transcribe.js",
|
||||
"saveClaConsentRecords": "node packages/tools/saveClaConsentRecords.js",
|
||||
"setupNewRelease": "node ./packages/tools/setupNewRelease",
|
||||
"spellcheck": "node packages/tools/spellcheck.js",
|
||||
"tagServerLatest": "node packages/tools/tagServerLatest.js",
|
||||
"test-ci": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test-ci",
|
||||
"test": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 2 run test",
|
||||
"tsc": "yarn workspaces foreach --parallel --verbose --interlaced run tsc",
|
||||
"test-ci": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 2 run test-ci",
|
||||
"test": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 2 run test",
|
||||
"tsc": "yarn workspaces foreach --worktree --parallel --verbose --interlaced run tsc",
|
||||
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
|
||||
"updateMarkdownDoc": "node ./packages/tools/updateMarkdownDoc",
|
||||
"updateNews": "node ./packages/tools/website/updateNews",
|
||||
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
|
||||
"validateFilenames": "node ./packages/tools/validateFilenames.js",
|
||||
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
|
||||
"watch": "yarn workspaces foreach --worktree --parallel --verbose --interlaced --jobs 999 run watch",
|
||||
"watchWebsite": "nodemon --delay 1 --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --watch packages/doc-builder/build --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "corepack yarn lint-staged"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@crowdin/cli": "3",
|
||||
"@crowdin/cli": "4",
|
||||
"@joplin/utils": "~2.12",
|
||||
"@seiyab/eslint-plugin-react-hooks": "4.5.1-beta.0",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
"cspell": "5.21.2",
|
||||
"eslint": "8.57.0",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-interactive": "10.8.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-jest": "27.9.0",
|
||||
"eslint-plugin-promise": "6.2.0",
|
||||
"eslint-plugin-react": "7.34.3",
|
||||
"eslint-plugin-promise": "6.6.0",
|
||||
"eslint-plugin-react": "7.37.4",
|
||||
"execa": "5.1.1",
|
||||
"fs-extra": "11.2.0",
|
||||
"glob": "10.4.5",
|
||||
"glob": "11.0.2",
|
||||
"gulp": "4.0.2",
|
||||
"husky": "3.1.0",
|
||||
"husky": "9.1.7",
|
||||
"lerna": "3.22.1",
|
||||
"lint-staged": "15.2.8",
|
||||
"madge": "7.0.0",
|
||||
"npm-package-json-lint": "7.1.0",
|
||||
"typescript": "5.4.5"
|
||||
"lint-staged": "15.5.2",
|
||||
"madge": "8.0.0",
|
||||
"npm-package-json-lint": "8.0.0",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"eslint-plugin-github": "4.10.2",
|
||||
"http-server": "14.1.1",
|
||||
"node-gyp": "9.4.1",
|
||||
"nodemon": "3.1.7"
|
||||
"node-gyp": "11.2.0",
|
||||
"nodemon": "3.1.10"
|
||||
},
|
||||
"packageManager": "yarn@3.8.3",
|
||||
"packageManager": "yarn@4.9.2",
|
||||
"resolutions": {
|
||||
"react-native-camera@4.2.1": "patch:react-native-camera@npm%3A4.2.1#./.yarn/patches/react-native-camera-npm-4.2.1-24b2600a7e.patch",
|
||||
"react-native-vosk@0.1.12": "patch:react-native-vosk@npm%3A0.1.12#./.yarn/patches/react-native-vosk-npm-0.1.12-76b1caaae8.patch",
|
||||
"eslint": "patch:eslint@8.57.0#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
|
||||
"eslint": "patch:eslint@8.57.1#./.yarn/patches/eslint-npm-8.39.0-d92bace04d.patch",
|
||||
"app-builder-lib@24.4.0": "patch:app-builder-lib@npm%3A24.4.0#./.yarn/patches/app-builder-lib-npm-24.4.0-05322ff057.patch",
|
||||
"nanoid": "patch:nanoid@npm%3A3.3.7#./.yarn/patches/nanoid-npm-3.3.7-98824ba130.patch",
|
||||
"pdfjs-dist": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
|
||||
"@react-native-community/slider": "patch:@react-native-community/slider@npm%3A4.4.4#./.yarn/patches/@react-native-community-slider-npm-4.4.4-d78e472f48.patch",
|
||||
"husky": "patch:husky@npm%3A3.1.0#./.yarn/patches/husky-npm-3.1.0-5cc13e4e34.patch",
|
||||
"chokidar@^2.0.0": "3.5.3",
|
||||
"react-native@0.74.1": "patch:react-native@npm%3A0.74.1#./.yarn/patches/react-native-npm-0.74.1-754c02ae9e.patch",
|
||||
"rn-fetch-blob@0.12.0": "patch:rn-fetch-blob@npm%3A0.12.0#./.yarn/patches/rn-fetch-blob-npm-0.12.0-cf02e3c544.patch",
|
||||
"app-builder-lib@26.0.0-alpha.7": "patch:app-builder-lib@npm%3A26.0.0-alpha.7#./.yarn/patches/app-builder-lib-npm-26.0.0-alpha.7-e1b3dca119.patch",
|
||||
"app-builder-lib@24.13.3": "patch:app-builder-lib@npm%3A24.13.3#./.yarn/patches/app-builder-lib-npm-24.13.3-86a66c0bf3.patch",
|
||||
"react-native-sqlite-storage@6.0.1": "patch:react-native-sqlite-storage@npm%3A6.0.1#./.yarn/patches/react-native-sqlite-storage-npm-6.0.1-8369d747bd.patch",
|
||||
"react-native-paper@5.13.1": "patch:react-native-paper@npm%3A5.13.1#./.yarn/patches/react-native-paper-npm-5.13.1-f153e542e2.patch"
|
||||
"react-native-paper@5.13.1": "patch:react-native-paper@npm%3A5.13.1#./.yarn/patches/react-native-paper-npm-5.13.1-f153e542e2.patch",
|
||||
"react-native-popup-menu@0.17.0": "patch:react-native-popup-menu@npm%3A0.17.0#./.yarn/patches/react-native-popup-menu-npm-0.17.0-8b745d88dd.patch",
|
||||
"react-native@0.79.2": "patch:react-native@npm%3A0.79.2#./.yarn/patches/react-native-npm-0.79.2-9db13eddfe.patch",
|
||||
"pdfjs-dist@2.16.105": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
|
||||
"pdfjs-dist@*": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
|
||||
"pdfjs-dist@3.11.174": "patch:pdfjs-dist@npm%3A3.11.174#./.yarn/patches/pdfjs-dist-npm-3.11.174-67f2fee6d6.patch",
|
||||
"canvas@npm:^2.11.2": "link:./.yarn/joplin-empty-package/",
|
||||
"node-gyp@npm:^9.0.0": "11.2.0"
|
||||
}
|
||||
}
|
||||
|
@@ -380,6 +380,13 @@ class AppGui {
|
||||
this.widget('noteList').toggleShowIds();
|
||||
}
|
||||
|
||||
toggleFolderCollapse() {
|
||||
const folderList = this.widget('folderList');
|
||||
if (folderList && folderList.toggleFolderCollapse) {
|
||||
folderList.toggleFolderCollapse();
|
||||
}
|
||||
}
|
||||
|
||||
widget(name) {
|
||||
if (name === 'root') return this.rootWidget_;
|
||||
return this.rootWidget_.childByName(name);
|
||||
@@ -506,6 +513,8 @@ class AppGui {
|
||||
this.toggleNoteMetadata();
|
||||
} else if (cmd === 'toggle_ids') {
|
||||
this.toggleFolderIds();
|
||||
} else if (cmd === 'toggle_folder_collapse') {
|
||||
this.toggleFolderCollapse();
|
||||
} else if (cmd === 'enter_command_line_mode') {
|
||||
const cmd = await this.widget('statusBar').prompt();
|
||||
if (!cmd) return;
|
||||
|
@@ -6,19 +6,18 @@ import Folder from '@joplin/lib/models/Folder';
|
||||
import BaseItem from '@joplin/lib/models/BaseItem';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import Tag from '@joplin/lib/models/Tag';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import Setting, { Env } from '@joplin/lib/models/Setting';
|
||||
import { reg } from '@joplin/lib/registry.js';
|
||||
import { fileExtension } from '@joplin/lib/path-utils';
|
||||
import { splitCommandString } from '@joplin/utils';
|
||||
import { dirname, fileExtension } from '@joplin/lib/path-utils';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { pathExists, readFile, readdirSync } from 'fs-extra';
|
||||
import RevisionService from '@joplin/lib/services/RevisionService';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import setupCommand from './setupCommand';
|
||||
import { FolderEntity, NoteEntity } from '@joplin/lib/services/database/types';
|
||||
import initializeCommandService from './utils/initializeCommandService';
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const Cache = require('@joplin/lib/Cache');
|
||||
const { splitCommandBatch } = require('@joplin/lib/string-utils');
|
||||
|
||||
class Application extends BaseApplication {
|
||||
|
||||
@@ -76,6 +75,12 @@ class Application extends BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
public async loadItemOrFail(type: ModelType | 'folderOrNote', pattern: string) {
|
||||
const output = await this.loadItem(type, pattern);
|
||||
if (!output) throw new Error(_('Cannot find "%s".', pattern));
|
||||
return output;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
public async loadItems(type: ModelType | 'folderOrNote', pattern: string, options: any = null): Promise<(FolderEntity | NoteEntity)[]> {
|
||||
if (type === 'folderOrNote') {
|
||||
@@ -215,6 +220,7 @@ class Application extends BaseApplication {
|
||||
return { ...this.commandMetadata_ };
|
||||
}
|
||||
|
||||
|
||||
public hasGui() {
|
||||
return this.gui() && !this.gui().isDummy();
|
||||
}
|
||||
@@ -325,6 +331,7 @@ class Application extends BaseApplication {
|
||||
{ keys: ['mb'], type: 'prompt', command: 'mkbook ""', cursorPosition: -2 },
|
||||
{ keys: ['yn'], type: 'prompt', command: 'cp $n ""', cursorPosition: -2 },
|
||||
{ keys: ['dn'], type: 'prompt', command: 'mv $n ""', cursorPosition: -2 },
|
||||
{ keys: ['z'], type: 'function', command: 'toggle_folder_collapse' },
|
||||
];
|
||||
|
||||
// Filter the keymap item by command so that items in keymap.json can override
|
||||
@@ -374,22 +381,6 @@ class Application extends BaseApplication {
|
||||
return output;
|
||||
}
|
||||
|
||||
public async commandList(argv: string[]) {
|
||||
if (argv.length && argv[0] === 'batch') {
|
||||
const commands = [];
|
||||
const commandLines = splitCommandBatch(await readFile(argv[1], 'utf-8'));
|
||||
|
||||
for (const commandLine of commandLines) {
|
||||
if (!commandLine.trim()) continue;
|
||||
const splitted = splitCommandString(commandLine.trim());
|
||||
commands.push(splitted);
|
||||
}
|
||||
return commands;
|
||||
} else {
|
||||
return [argv];
|
||||
}
|
||||
}
|
||||
|
||||
// We need this special case here because by the time the `version` command
|
||||
// runs, the keychain has already been setup.
|
||||
public checkIfKeychainEnabled(argv: string[]) {
|
||||
@@ -397,8 +388,12 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
public async start(argv: string[]) {
|
||||
const keychainEnabled = this.checkIfKeychainEnabled(argv);
|
||||
// TODO: Currently, `pluginAssetDir` needs to be set differently for each platform and requires
|
||||
// a call to Setting.setConstant. Ideally, this would be done in a way that requires users to
|
||||
// set this constant on startup.
|
||||
Setting.setConstant('pluginAssetDir', `${dirname(require.resolve('@joplin/renderer'))}/assets`);
|
||||
|
||||
const keychainEnabled = this.checkIfKeychainEnabled(argv);
|
||||
argv = await super.start(argv, { keychainEnabled });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
@@ -408,22 +403,24 @@ class Application extends BaseApplication {
|
||||
|
||||
this.initRedux();
|
||||
|
||||
// Since the settings need to be loaded before the store is created, it will never
|
||||
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
|
||||
// initialised. So we manually call dispatchUpdateAll() to force an update.
|
||||
Setting.dispatchUpdateAll();
|
||||
|
||||
if (!shim.sharpEnabled()) this.logger().warn('Sharp is disabled - certain image-related features will not be available');
|
||||
|
||||
initializeCommandService(this.store(), Setting.value('env') === Env.Dev);
|
||||
|
||||
// If we have some arguments left at this point, it's a command
|
||||
// so execute it.
|
||||
if (argv.length) {
|
||||
this.gui_ = this.dummyGui();
|
||||
|
||||
this.currentFolder_ = await Folder.load(Setting.value('activeFolderId'));
|
||||
|
||||
await this.applySettingsSideEffects();
|
||||
|
||||
await this.refreshCurrentFolder();
|
||||
try {
|
||||
const commands = await this.commandList(argv);
|
||||
for (const command of commands) {
|
||||
await this.execCommand(command);
|
||||
}
|
||||
await this.execCommand(argv);
|
||||
} catch (error) {
|
||||
if (this.showStackTraces_) {
|
||||
console.error(error);
|
||||
@@ -448,11 +445,6 @@ class Application extends BaseApplication {
|
||||
this.gui_.setLogger(this.logger());
|
||||
await this.gui_.start();
|
||||
|
||||
// Since the settings need to be loaded before the store is created, it will never
|
||||
// receive the SETTING_UPDATE_ALL even, which mean state.settings will not be
|
||||
// initialised. So we manually call dispatchUpdateAll() to force an update.
|
||||
Setting.dispatchUpdateAll();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
await refreshFolders((action: any) => this.store().dispatch(action), '');
|
||||
|
||||
|
@@ -1,19 +0,0 @@
|
||||
const BaseCommand = require('./base-command').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
usage() {
|
||||
return 'batch <file-path>';
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Runs the commands contained in the text file. There should be one command per line.');
|
||||
}
|
||||
|
||||
async action() {
|
||||
// Implementation is in app.js::commandList()
|
||||
throw new Error('No implemented');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command;
|
79
packages/app-cli/app/command-batch.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { splitCommandBatch } from '@joplin/lib/string-utils';
|
||||
import BaseCommand from './base-command';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { splitCommandString } from '@joplin/utils';
|
||||
import iterateStdin from './utils/iterateStdin';
|
||||
import { readFile } from 'fs-extra';
|
||||
import app from './app';
|
||||
|
||||
interface Options {
|
||||
'file-path': string;
|
||||
options: {
|
||||
'continue-on-failure': boolean;
|
||||
};
|
||||
}
|
||||
|
||||
class Command extends BaseCommand {
|
||||
public usage() {
|
||||
return 'batch <file-path>';
|
||||
}
|
||||
|
||||
public options() {
|
||||
return [
|
||||
// These are present mostly for testing purposes
|
||||
['--continue-on-failure', 'Continue running commands when one command in the batch fails.'],
|
||||
];
|
||||
}
|
||||
|
||||
public description() {
|
||||
return _('Runs the commands contained in the text file. There should be one command per line.');
|
||||
}
|
||||
|
||||
private streamCommands_ = async function*(filePath: string) {
|
||||
const processLines = function*(lines: string) {
|
||||
const commandLines = splitCommandBatch(lines);
|
||||
|
||||
for (const command of commandLines) {
|
||||
if (!command.trim()) continue;
|
||||
yield splitCommandString(command.trim());
|
||||
}
|
||||
};
|
||||
|
||||
if (filePath === '-') { // stdin
|
||||
// Iterating over standard input conflicts with the CLI app's GUI.
|
||||
if (app().hasGui()) {
|
||||
throw new Error(_('Reading commands from standard input is only available in CLI mode.'));
|
||||
}
|
||||
|
||||
for await (const lines of iterateStdin('command> ')) {
|
||||
yield* processLines(lines);
|
||||
}
|
||||
} else {
|
||||
const data = await readFile(filePath, 'utf-8');
|
||||
yield* processLines(data);
|
||||
}
|
||||
};
|
||||
|
||||
public async action(options: Options) {
|
||||
let lastError;
|
||||
for await (const command of this.streamCommands_(options['file-path'])) {
|
||||
try {
|
||||
await app().refreshCurrentFolder();
|
||||
await app().execCommand(command);
|
||||
} catch (error) {
|
||||
if (options.options['continue-on-failure']) {
|
||||
app().stdout(error.message);
|
||||
lastError = error;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastError) {
|
||||
throw lastError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command;
|
@@ -13,7 +13,7 @@ describe('command-done', () => {
|
||||
});
|
||||
|
||||
it('should make a note as "done"', async () => {
|
||||
const note = await Note.save({ title: 'hello', is_todo: 1, todo_completed: 0 });
|
||||
const note = await Note.save({ title: 'hello', is_todo: 1, todo_completed: 0, parent_id: '' });
|
||||
|
||||
const command = setupCommandForTesting(Command);
|
||||
|
||||
|
@@ -26,6 +26,7 @@ class Command extends BaseCommand {
|
||||
['-v, --verbose', 'More verbose output for the `target-status` command'],
|
||||
['-o, --output <directory>', 'Output directory'],
|
||||
['--retry-failed-items', 'Applies to `decrypt` command - retries decrypting items that previously could not be decrypted.'],
|
||||
['-f, --force', 'Do not ask for input on failure'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ class Command extends BaseCommand {
|
||||
this.stdout(line.join('\n'));
|
||||
break;
|
||||
} catch (error) {
|
||||
if (error.code === 'masterKeyNotLoaded') {
|
||||
if (error.code === 'masterKeyNotLoaded' && !args.options.force) {
|
||||
const ok = await askForMasterKey(error);
|
||||
if (!ok) return;
|
||||
continue;
|
||||
|
@@ -6,6 +6,7 @@ import app from './app';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { ImportOptions } from '@joplin/lib/services/interop/types';
|
||||
import { unique } from '@joplin/lib/array';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
|
||||
class Command extends BaseCommand {
|
||||
public override usage() {
|
||||
@@ -32,14 +33,16 @@ class Command extends BaseCommand {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
public override async action(args: any) {
|
||||
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
|
||||
let destinationFolder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
|
||||
|
||||
if (args.notebook && !folder) throw new Error(_('Cannot find "%s".', args.notebook));
|
||||
if (args.notebook && !destinationFolder) throw new Error(_('Cannot find "%s".', args.notebook));
|
||||
|
||||
if (!destinationFolder) destinationFolder = await Folder.defaultFolder();
|
||||
|
||||
const importOptions: ImportOptions = {};
|
||||
importOptions.path = args.path;
|
||||
importOptions.format = args.options.format ? args.options.format : 'auto';
|
||||
importOptions.destinationFolderId = folder ? folder.id : null;
|
||||
importOptions.destinationFolderId = destinationFolder ? destinationFolder.id : null;
|
||||
|
||||
let lastProgress = '';
|
||||
|
||||
|
@@ -26,8 +26,7 @@ class Command extends BaseCommand {
|
||||
const pattern = args['notebook'];
|
||||
const force = args.options && args.options.force === true;
|
||||
|
||||
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
|
||||
if (!folder) throw new Error(_('Cannot find "%s".', pattern));
|
||||
const folder = await app().loadItemOrFail(BaseModel.TYPE_FOLDER, pattern);
|
||||
|
||||
const permanent = args.options?.permanent === true || !!folder.deleted_time;
|
||||
const ellipsizedFolderTitle = substrWithEllipsis(folder.title, 0, 32);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import BaseCommand from './base-command';
|
||||
import app from './app';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { _, _n } from '@joplin/lib/locale';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import BaseModel, { DeleteOptions } from '@joplin/lib/BaseModel';
|
||||
import { NoteEntity } from '@joplin/lib/services/database/types';
|
||||
@@ -31,13 +31,13 @@ class Command extends BaseCommand {
|
||||
|
||||
let ok = true;
|
||||
if (!force && notes.length > 1) {
|
||||
ok = await this.prompt(_('%d notes match this pattern. Delete them?', notes.length), { booleanAnswerDefault: 'n' });
|
||||
ok = await this.prompt(_n('%d note matches this pattern. Delete it?', '%d notes match this pattern. Delete them?', notes.length, notes.length), { booleanAnswerDefault: 'n' });
|
||||
}
|
||||
|
||||
const permanent = (args.options?.permanent === true) || notes.every(n => !!n.deleted_time);
|
||||
if (!force && permanent) {
|
||||
const message = (
|
||||
notes.length === 1 ? _('This will permanently delete the note "%s". Continue?', notes[0].title) : _('%d notes will be permanently deleted. Continue?', notes.length)
|
||||
_n('%d note will be permanently deleted. Continue?', '%d notes will be permanently deleted. Continue?', notes.length, notes.length)
|
||||
);
|
||||
ok = await this.prompt(message, { booleanAnswerDefault: 'n' });
|
||||
}
|
||||
|
@@ -14,17 +14,25 @@ class Command extends BaseCommand {
|
||||
return `${_('Start, stop or check the API server. To specify on which port it should run, set the api.port config variable. Commands are (%s).', ['start', 'stop', 'status'].join('|'))} This is an experimental feature - use at your own risks! It is recommended that the server runs off its own separate profile so that no two CLI instances access that profile at the same time. Use --profile to specify the profile path.`;
|
||||
}
|
||||
|
||||
options() {
|
||||
return [
|
||||
['--exit-early', 'Allow the command to exit while the server is still running. The server will still stop when the app exits. Valid only for the `start` subcommand.'],
|
||||
['--quiet', 'Log less information to the console. More verbose logs will still be available through log-clipper.txt.'],
|
||||
];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
const command = args.command;
|
||||
|
||||
const ClipperServer = require('@joplin/lib/ClipperServer').default;
|
||||
ClipperServer.instance().initialize();
|
||||
const stdoutFn = (...s) => this.stdout(s.join(' '));
|
||||
const ignoreOutputFn = ()=>{};
|
||||
const clipperLogger = new Logger();
|
||||
clipperLogger.addTarget('file', { path: `${Setting.value('profileDir')}/log-clipper.txt` });
|
||||
clipperLogger.addTarget('console', { console: {
|
||||
info: stdoutFn,
|
||||
warn: stdoutFn,
|
||||
info: args.options.quiet ? ignoreOutputFn : stdoutFn,
|
||||
warn: args.options.quiet ? ignoreOutputFn : stdoutFn,
|
||||
error: stdoutFn,
|
||||
} });
|
||||
ClipperServer.instance().setDispatch(() => {});
|
||||
@@ -38,7 +46,11 @@ class Command extends BaseCommand {
|
||||
this.stdout(_('Server is already running on port %d', runningOnPort));
|
||||
} else {
|
||||
await shim.fsDriver().writeFile(pidPath, process.pid.toString(), 'utf-8');
|
||||
await ClipperServer.instance().start(); // Never exit
|
||||
const promise = ClipperServer.instance().start();
|
||||
|
||||
if (!args.options['exit-early']) {
|
||||
await promise; // Never exit
|
||||
}
|
||||
}
|
||||
} else if (command === 'status') {
|
||||
this.stdout(runningOnPort ? _('Server is running on port %d', runningOnPort) : _('Server is not running.'));
|
||||
|
179
packages/app-cli/app/command-share.test.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
import mockShareService, { ApiMock } from '@joplin/lib/testing/share/mockShareService';
|
||||
import { setupCommandForTesting, setupApplication } from './utils/testUtils';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import ShareService from '@joplin/lib/services/share/ShareService';
|
||||
import BaseItem from '@joplin/lib/models/BaseItem';
|
||||
import { ModelType } from '@joplin/lib/BaseModel';
|
||||
import { ShareInvitation, ShareUserStatus, StateShare } from '@joplin/lib/services/share/reducer';
|
||||
import app from './app';
|
||||
const Command = require('./command-share');
|
||||
|
||||
const setUpCommand = () => {
|
||||
const output: string[] = [];
|
||||
const stdout = (content: string) => {
|
||||
output.push(...content.split('\n'));
|
||||
};
|
||||
|
||||
const command = setupCommandForTesting(Command, stdout);
|
||||
return { command, output };
|
||||
};
|
||||
|
||||
const shareId = 'test-id';
|
||||
const defaultFolderShare: StateShare = {
|
||||
id: shareId,
|
||||
type: ModelType.Folder,
|
||||
folder_id: 'some-folder-id-here',
|
||||
note_id: undefined,
|
||||
master_key_id: undefined,
|
||||
user: {
|
||||
full_name: 'Test user',
|
||||
email: 'test@localhost',
|
||||
id: 'some-user-id',
|
||||
},
|
||||
};
|
||||
|
||||
const mockShareServiceForFolderSharing = (eventHandlerOverrides: Partial<ApiMock>&{ onExec?: undefined }) => {
|
||||
const invitations: ShareInvitation[] = [];
|
||||
|
||||
mockShareService({
|
||||
getShareInvitations: async () => ({
|
||||
items: invitations,
|
||||
}),
|
||||
getShares: async () => ({ items: [defaultFolderShare] }),
|
||||
getShareUsers: async (_id: string) => ({ items: [] }),
|
||||
postShareUsers: async (_id, _body) => { },
|
||||
postShares: async () => ({ id: shareId }),
|
||||
...eventHandlerOverrides,
|
||||
}, ShareService.instance(), app().store());
|
||||
|
||||
return {
|
||||
addInvitation: (invitation: Partial<ShareInvitation>) => {
|
||||
const defaultInvitation: ShareInvitation = {
|
||||
share: defaultFolderShare,
|
||||
id: 'some-invitation-id',
|
||||
master_key: undefined,
|
||||
status: ShareUserStatus.Waiting,
|
||||
can_read: 1,
|
||||
can_write: 1,
|
||||
};
|
||||
|
||||
invitations.push({ ...defaultInvitation, ...invitation });
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
describe('command-share', () => {
|
||||
beforeEach(async () => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
await setupApplication();
|
||||
BaseItem.shareService_ = ShareService.instance();
|
||||
});
|
||||
|
||||
test('should allow adding a user to a share', async () => {
|
||||
const folder = await Folder.save({ title: 'folder1' });
|
||||
|
||||
let lastShareUserUpdate: unknown|null = null;
|
||||
mockShareServiceForFolderSharing({
|
||||
getShares: async () => {
|
||||
const isShared = !!lastShareUserUpdate;
|
||||
if (isShared) {
|
||||
return {
|
||||
items: [{ ...defaultFolderShare, folder_id: folder.id }],
|
||||
};
|
||||
} else {
|
||||
return { items: [] };
|
||||
}
|
||||
},
|
||||
// Called when a new user is added to a share
|
||||
postShareUsers: async (_id, body) => {
|
||||
lastShareUserUpdate = body;
|
||||
},
|
||||
});
|
||||
|
||||
const { command } = setUpCommand();
|
||||
|
||||
// Should share read-write by default
|
||||
await command.action({
|
||||
'command': 'add',
|
||||
'notebook': 'folder1',
|
||||
'user': 'test@localhost',
|
||||
options: {},
|
||||
});
|
||||
expect(lastShareUserUpdate).toMatchObject({
|
||||
email: 'test@localhost',
|
||||
can_write: 1,
|
||||
can_read: 1,
|
||||
});
|
||||
|
||||
// Should also support sharing as read only
|
||||
await command.action({
|
||||
'command': 'add',
|
||||
'notebook': 'folder1',
|
||||
'user': 'test2@localhost',
|
||||
options: {
|
||||
'read-only': true,
|
||||
},
|
||||
});
|
||||
expect(lastShareUserUpdate).toMatchObject({
|
||||
email: 'test2@localhost',
|
||||
can_write: 0,
|
||||
can_read: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
{
|
||||
label: 'should list a single pending invitation',
|
||||
invitations: [{ id: 'test', status: ShareUserStatus.Waiting }],
|
||||
expectedOutput: [
|
||||
'Incoming shares:',
|
||||
'\tWaiting: Notebook some-folder-id-here from test@localhost',
|
||||
'All shared folders:',
|
||||
'\tNone',
|
||||
].join('\n'),
|
||||
},
|
||||
{
|
||||
label: 'should list accepted invitations for non-existent folders with [None] as the folder title',
|
||||
invitations: [
|
||||
{ id: 'test2', status: ShareUserStatus.Accepted },
|
||||
],
|
||||
expectedOutput: [
|
||||
'Incoming shares:',
|
||||
'\tAccepted: Notebook [None] from test@localhost',
|
||||
'All shared folders:',
|
||||
'\tNone',
|
||||
].join('\n'),
|
||||
},
|
||||
{
|
||||
label: 'should not list rejected shares',
|
||||
invitations: [
|
||||
{ id: 'test3', status: ShareUserStatus.Rejected },
|
||||
],
|
||||
expectedOutput: [
|
||||
'Incoming shares:',
|
||||
'\tNone',
|
||||
'All shared folders:',
|
||||
'\tNone',
|
||||
].join('\n'),
|
||||
},
|
||||
])('share invitations: $label', async ({ invitations, expectedOutput }) => {
|
||||
const mock = mockShareServiceForFolderSharing({});
|
||||
for (const invitation of invitations) {
|
||||
mock.addInvitation(invitation);
|
||||
}
|
||||
|
||||
await ShareService.instance().refreshShareInvitations();
|
||||
|
||||
const { command, output } = setUpCommand();
|
||||
await command.action({
|
||||
'command': 'list',
|
||||
options: {},
|
||||
});
|
||||
|
||||
expect(output.join('\n')).toBe(expectedOutput);
|
||||
});
|
||||
});
|
||||
|
297
packages/app-cli/app/command-share.ts
Normal file
@@ -0,0 +1,297 @@
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import BaseCommand from './base-command';
|
||||
import app from './app';
|
||||
import { reg } from '@joplin/lib/registry';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
import ShareService from '@joplin/lib/services/share/ShareService';
|
||||
import { ModelType } from '@joplin/lib/BaseModel';
|
||||
import { FolderEntity } from '@joplin/lib/services/database/types';
|
||||
import { ShareUserStatus } from '@joplin/lib/services/share/reducer';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import invitationRespond from '@joplin/lib/services/share/invitationRespond';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
import { substrWithEllipsis } from '@joplin/lib/string-utils';
|
||||
|
||||
const logger = Logger.create('command-share');
|
||||
|
||||
type Args = {
|
||||
command: string;
|
||||
// eslint-disable-next-line id-denylist -- The "notebook" identifier comes from the UI.
|
||||
notebook?: string;
|
||||
user?: string;
|
||||
options: {
|
||||
'read-only'?: boolean;
|
||||
json?: boolean;
|
||||
force?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const folderTitle = (folder: FolderEntity|null) => {
|
||||
return folder ? substrWithEllipsis(folder.title, 0, 32) : _('[None]');
|
||||
};
|
||||
|
||||
const getShareState = () => app().store().getState().shareService;
|
||||
const getShareFromFolderId = (folderId: string) => {
|
||||
const shareState = getShareState();
|
||||
const allShares = shareState.shares;
|
||||
const share = allShares.find(share => share.folder_id === folderId);
|
||||
return share;
|
||||
};
|
||||
|
||||
const getShareUsers = (folderId: string) => {
|
||||
const share = getShareFromFolderId(folderId);
|
||||
if (!share) {
|
||||
throw new Error(`No share found for folder ${folderId}`);
|
||||
}
|
||||
return getShareState().shareUsers[share.id];
|
||||
};
|
||||
|
||||
|
||||
class Command extends BaseCommand {
|
||||
public usage() {
|
||||
return 'share <command> [notebook] [user]';
|
||||
}
|
||||
|
||||
public description() {
|
||||
return [
|
||||
_('Shares or unshares the specified [notebook] with [user]. Requires Joplin Cloud or Joplin Server.'),
|
||||
_('Commands: `add`, `remove`, `list`, `delete`, `accept`, `leave`, and `reject`.'),
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
public options() {
|
||||
return [
|
||||
['--read-only', _('Don\'t allow the share recipient to write to the shared notebook. Valid only for the `add` subcommand.')],
|
||||
['-f, --force', _('Do not ask for user confirmation.')],
|
||||
['--json', _('Prefer JSON output.')],
|
||||
];
|
||||
}
|
||||
|
||||
public async action(args: Args) {
|
||||
const commandShareAdd = async (folder: FolderEntity, email: string) => {
|
||||
await reg.waitForSyncFinishedThenSync();
|
||||
|
||||
const share = await ShareService.instance().shareFolder(folder.id);
|
||||
|
||||
const permissions = {
|
||||
can_read: 1,
|
||||
can_write: args.options['read-only'] ? 0 : 1,
|
||||
};
|
||||
logger.debug('Sharing folder', folder.id, 'with', email, 'permissions=', permissions);
|
||||
|
||||
await ShareService.instance().addShareRecipient(share.id, share.master_key_id, email, permissions);
|
||||
|
||||
await ShareService.instance().refreshShares();
|
||||
await ShareService.instance().refreshShareUsers(share.id);
|
||||
|
||||
await reg.waitForSyncFinishedThenSync();
|
||||
};
|
||||
|
||||
const commandShareRemove = async (folder: FolderEntity, email: string) => {
|
||||
await ShareService.instance().refreshShares();
|
||||
|
||||
const share = getShareFromFolderId(folder.id);
|
||||
if (!share) {
|
||||
throw new Error(`No share found for folder ${folder.id}`);
|
||||
}
|
||||
|
||||
await ShareService.instance().refreshShareUsers(share.id);
|
||||
|
||||
const shareUsers = getShareUsers(folder.id);
|
||||
if (!shareUsers) {
|
||||
throw new Error(`No share found for folder ${folder.id}`);
|
||||
}
|
||||
|
||||
const targetUser = shareUsers.find(user => user.user?.email === email);
|
||||
if (!targetUser) {
|
||||
throw new Error(`No recipient found with email ${email}`);
|
||||
}
|
||||
|
||||
await ShareService.instance().deleteShareRecipient(targetUser.id);
|
||||
this.stdout(_('Removed %s from share.', targetUser.user.email));
|
||||
};
|
||||
|
||||
const commandShareList = async () => {
|
||||
let folder = null;
|
||||
if (args.notebook) {
|
||||
folder = await app().loadItemOrFail(ModelType.Folder, args.notebook);
|
||||
}
|
||||
|
||||
await ShareService.instance().maintenance();
|
||||
|
||||
if (folder) {
|
||||
const share = getShareFromFolderId(folder.id);
|
||||
await ShareService.instance().refreshShareUsers(share.id);
|
||||
|
||||
const shareUsers = getShareUsers(folder.id);
|
||||
const output = {
|
||||
folderTitle: folderTitle(folder),
|
||||
sharedWith: (shareUsers ?? []).map(user => ({
|
||||
email: user.user.email,
|
||||
readOnly: user.can_read && !user.can_write,
|
||||
})),
|
||||
};
|
||||
|
||||
if (args.options.json) {
|
||||
this.stdout(JSON.stringify(output));
|
||||
} else {
|
||||
this.stdout(_('Folder "%s" is shared with:', output.folderTitle));
|
||||
for (const user of output.sharedWith) {
|
||||
this.stdout(`\t${user.email}\t${user.readOnly ? _('(Read-only)') : ''}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const shareState = getShareState();
|
||||
const output = {
|
||||
invitations: shareState.shareInvitations.map(invitation => ({
|
||||
accepted: invitation.status === ShareUserStatus.Accepted,
|
||||
waiting: invitation.status === ShareUserStatus.Waiting,
|
||||
rejected: invitation.status === ShareUserStatus.Rejected,
|
||||
folderId: invitation.share.folder_id,
|
||||
fromUser: {
|
||||
email: invitation.share.user?.email,
|
||||
},
|
||||
})),
|
||||
shares: shareState.shares.map(share => ({
|
||||
isFolder: !!share.folder_id,
|
||||
isNote: !!share.note_id,
|
||||
itemId: share.folder_id ?? share.note_id,
|
||||
fromUser: {
|
||||
email: share.user?.email,
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
if (args.options.json) {
|
||||
this.stdout(JSON.stringify(output));
|
||||
} else {
|
||||
this.stdout(_('Incoming shares:'));
|
||||
let loggedInvitation = false;
|
||||
for (const invitation of output.invitations) {
|
||||
let message;
|
||||
if (invitation.waiting) {
|
||||
message = _('Waiting: Notebook %s from %s', invitation.folderId, invitation.fromUser.email);
|
||||
}
|
||||
if (invitation.accepted) {
|
||||
const folder = await Folder.load(invitation.folderId);
|
||||
message = _('Accepted: Notebook %s from %s', folderTitle(folder), invitation.fromUser.email);
|
||||
}
|
||||
|
||||
if (message) {
|
||||
this.stdout(`\t${message}`);
|
||||
loggedInvitation = true;
|
||||
}
|
||||
}
|
||||
if (!loggedInvitation) {
|
||||
this.stdout(`\t${_('None')}`);
|
||||
}
|
||||
|
||||
this.stdout(_('All shared folders:'));
|
||||
if (output.shares.length) {
|
||||
for (const share of output.shares) {
|
||||
let title;
|
||||
if (share.isFolder) {
|
||||
title = folderTitle(await Folder.load(share.itemId));
|
||||
} else {
|
||||
title = share.itemId;
|
||||
}
|
||||
|
||||
if (share.fromUser?.email) {
|
||||
this.stdout(`\t${_('%s from %s', title, share.fromUser?.email)}`);
|
||||
} else {
|
||||
this.stdout(`\t${title} - ${share.itemId}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.stdout(`\t${_('None')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const commandShareAcceptOrReject = async (folderId: string, accept: boolean) => {
|
||||
await ShareService.instance().maintenance();
|
||||
|
||||
const shareState = getShareState();
|
||||
const invitations = shareState.shareInvitations.filter(invitation => {
|
||||
return invitation.share.folder_id === folderId && invitation.status === ShareUserStatus.Waiting;
|
||||
});
|
||||
if (invitations.length === 0) throw new Error('No such invitation found');
|
||||
|
||||
// If there are multiple invitations for the same folder, stop early to avoid
|
||||
// accepting the wrong invitation.
|
||||
if (invitations.length > 1) throw new Error('Multiple invitations found with the same ID');
|
||||
|
||||
const invitation = invitations[0];
|
||||
|
||||
this.stdout(accept ? _('Accepting share...') : _('Rejecting share...'));
|
||||
await invitationRespond(invitation.id, invitation.share.folder_id, invitation.master_key, accept);
|
||||
};
|
||||
|
||||
const commandShareAccept = (folderId: string) => (
|
||||
commandShareAcceptOrReject(folderId, true)
|
||||
);
|
||||
|
||||
const commandShareReject = (folderId: string) => (
|
||||
commandShareAcceptOrReject(folderId, false)
|
||||
);
|
||||
|
||||
const commandShareDelete = async (folder: FolderEntity) => {
|
||||
const force = args.options.force;
|
||||
const ok = force ? true : await this.prompt(
|
||||
_('Unshare notebook "%s"? This may cause other users to lose access to the notebook.', folderTitle(folder)),
|
||||
{ booleanAnswerDefault: 'n' },
|
||||
);
|
||||
if (!ok) return;
|
||||
|
||||
logger.info('Unsharing folder', folder.id);
|
||||
await ShareService.instance().unshareFolder(folder.id);
|
||||
await reg.scheduleSync();
|
||||
};
|
||||
|
||||
if (args.command === 'add' || args.command === 'remove' || args.command === 'delete') {
|
||||
if (!args.notebook) throw new Error('[notebook] is required');
|
||||
const folder = await app().loadItemOrFail(ModelType.Folder, args.notebook);
|
||||
|
||||
if (args.command === 'delete') {
|
||||
return commandShareDelete(folder);
|
||||
} else {
|
||||
if (!args.user) throw new Error('[user] is required');
|
||||
|
||||
const email = args.user;
|
||||
if (args.command === 'add') {
|
||||
return commandShareAdd(folder, email);
|
||||
} else if (args.command === 'remove') {
|
||||
return commandShareRemove(folder, email);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (args.command === 'leave') {
|
||||
const folder = args.notebook ? await app().loadItemOrFail(ModelType.Folder, args.notebook) : null;
|
||||
|
||||
await ShareService.instance().maintenance();
|
||||
|
||||
return CommandService.instance().execute(
|
||||
'leaveSharedFolder', folder?.id, { force: args.options.force },
|
||||
);
|
||||
}
|
||||
|
||||
if (args.command === 'list') {
|
||||
return commandShareList();
|
||||
}
|
||||
|
||||
if (args.command === 'accept') {
|
||||
return commandShareAccept(args.notebook);
|
||||
}
|
||||
|
||||
if (args.command === 'reject') {
|
||||
return commandShareReject(args.notebook);
|
||||
}
|
||||
|
||||
throw new Error(`Unknown subcommand: ${args.command}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command;
|
@@ -17,6 +17,7 @@ import { pathExists, writeFile } from 'fs-extra';
|
||||
import { checkIfLoginWasSuccessful, generateApplicationConfirmUrl } from '@joplin/lib/services/joplinCloudUtils';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
import { uuidgen } from '@joplin/lib/uuid';
|
||||
import ShareService from '@joplin/lib/services/share/ShareService';
|
||||
|
||||
const logger = Logger.create('command-sync');
|
||||
|
||||
@@ -230,6 +231,10 @@ class Command extends BaseCommand {
|
||||
return cleanUp();
|
||||
}
|
||||
|
||||
// Refresh share invitations -- if running without a GUI, some of the
|
||||
// maintenance tasks may otherwise be skipped.
|
||||
await ShareService.instance().maintenance();
|
||||
|
||||
this.stdout(_('Starting synchronisation...'));
|
||||
|
||||
const contextKey = `sync.${this.syncTargetId_}.context`;
|
||||
|
@@ -4,7 +4,7 @@ import Note from '@joplin/lib/models/Note';
|
||||
import uuid from '@joplin/lib/uuid';
|
||||
import populateDatabase from '@joplin/lib/services/debug/populateDatabase';
|
||||
import { readCredentialFile } from '@joplin/lib/utils/credentialFiles';
|
||||
import JoplinServerApi from '@joplin/lib/JoplinServerApi';
|
||||
import JoplinServerApi, { Session } from '@joplin/lib/JoplinServerApi';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
function randomElement(array: any[]): any {
|
||||
@@ -107,6 +107,7 @@ class Command extends BaseCommand {
|
||||
userContentBaseUrl: () => joplinServerAuth.userContentBaseUrl,
|
||||
username: () => joplinServerAuth.email,
|
||||
password: () => joplinServerAuth.password,
|
||||
session: (): Session => null,
|
||||
});
|
||||
|
||||
const apiPut = async () => {
|
||||
|
@@ -2,6 +2,7 @@ import BaseCommand from './base-command';
|
||||
import app from './app';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import BaseModel from '@joplin/lib/BaseModel';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
|
||||
class Command extends BaseCommand {
|
||||
public override usage() {
|
||||
@@ -20,6 +21,18 @@ class Command extends BaseCommand {
|
||||
public override async action(args: any) {
|
||||
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args['notebook']);
|
||||
if (!folder) throw new Error(_('Cannot find "%s".', args['notebook']));
|
||||
|
||||
// Auto-expand parent folders in GUI if present
|
||||
if (app().gui() && app().gui().widget && app().gui().widget('folderList')) {
|
||||
const folderListWidget = app().gui().widget('folderList');
|
||||
if (folderListWidget.expandToFolder) {
|
||||
// Get all folders to pass to expandToFolder
|
||||
const folders = await Folder.all();
|
||||
folderListWidget.folders = folders; // Ensure widget has current folders
|
||||
folderListWidget.expandToFolder(folder.id);
|
||||
}
|
||||
}
|
||||
|
||||
app().switchCurrentFolder(folder);
|
||||
}
|
||||
}
|
||||
|
@@ -4,11 +4,14 @@ import BaseModel from '@joplin/lib/BaseModel';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import { FolderEntity } from '@joplin/lib/services/database/types';
|
||||
import { getDisplayParentId, getTrashFolderId } from '@joplin/lib/services/trash';
|
||||
import {
|
||||
getDisplayParentId,
|
||||
getTrashFolderId,
|
||||
} from '@joplin/lib/services/trash';
|
||||
const ListWidget = require('tkwidgets/ListWidget.js');
|
||||
|
||||
export default class FolderListWidget extends ListWidget {
|
||||
|
||||
export default class FolderListWidget extends ListWidget {
|
||||
private folders_: FolderEntity[] = [];
|
||||
|
||||
public constructor() {
|
||||
@@ -31,7 +34,18 @@ export default class FolderListWidget extends ListWidget {
|
||||
if (item === '-') {
|
||||
output.push('-'.repeat(this.innerWidth));
|
||||
} else if (item.type_ === Folder.modelType()) {
|
||||
output.push(' '.repeat(this.folderDepth(this.folders, item.id)));
|
||||
const depth = this.folderDepth(this.folders, item.id);
|
||||
output.push(' '.repeat(depth));
|
||||
|
||||
// Add collapse/expand indicator
|
||||
const hasChildren = this.folderHasChildren_(this.folders, item.id);
|
||||
if (hasChildren) {
|
||||
const collapsedFolders = Setting.value('collapsedFolderIds');
|
||||
const isCollapsed = collapsedFolders.includes(item.id);
|
||||
output.push(isCollapsed ? '[+] ' : '[-] ');
|
||||
} else {
|
||||
output.push(' '); // Space for alignment
|
||||
}
|
||||
|
||||
if (this.showIds) {
|
||||
output.push(Folder.shortId(item.id));
|
||||
@@ -65,7 +79,10 @@ export default class FolderListWidget extends ListWidget {
|
||||
let output = 0;
|
||||
while (true) {
|
||||
const folder = BaseModel.byId(folders, folderId);
|
||||
const folderParentId = getDisplayParentId(folder, folders.find(f => f.id === folder.parent_id));
|
||||
const folderParentId = getDisplayParentId(
|
||||
folder,
|
||||
folders.find((f) => f.id === folder.parent_id),
|
||||
);
|
||||
if (!folder || !folderParentId) return output;
|
||||
output++;
|
||||
folderId = folderParentId;
|
||||
@@ -153,7 +170,10 @@ export default class FolderListWidget extends ListWidget {
|
||||
public folderHasChildren_(folders: FolderEntity[], folderId: string) {
|
||||
for (let i = 0; i < folders.length; i++) {
|
||||
const folder = folders[i];
|
||||
const folderParentId = getDisplayParentId(folder, folders.find(f => f.id === folder.parent_id));
|
||||
const folderParentId = getDisplayParentId(
|
||||
folder,
|
||||
folders.find((f) => f.id === folder.parent_id),
|
||||
);
|
||||
if (folderParentId === folderId) return true;
|
||||
}
|
||||
return false;
|
||||
@@ -161,7 +181,12 @@ export default class FolderListWidget extends ListWidget {
|
||||
|
||||
public render() {
|
||||
if (this.updateItems_) {
|
||||
this.logger().debug('Rebuilding items...', this.notesParentType, this.selectedJoplinItemId, this.selectedSearchId);
|
||||
this.logger().debug(
|
||||
'Rebuilding items...',
|
||||
this.notesParentType,
|
||||
this.selectedJoplinItemId,
|
||||
this.selectedSearchId,
|
||||
);
|
||||
const wasSelectedItemId = this.selectedJoplinItemId;
|
||||
const previousParentType = this.notesParentType;
|
||||
|
||||
@@ -170,12 +195,20 @@ export default class FolderListWidget extends ListWidget {
|
||||
const orderFolders = (parentId: string) => {
|
||||
for (let i = 0; i < this.folders.length; i++) {
|
||||
const f = this.folders[i];
|
||||
const originalParent = this.folders_.find(f => f.id === f.parent_id);
|
||||
const originalParent = this.folders_.find(
|
||||
(f) => f.id === f.parent_id,
|
||||
);
|
||||
|
||||
const folderParentId = getDisplayParentId(f, originalParent); // f.parent_id ? f.parent_id : '';
|
||||
if (folderParentId === parentId) {
|
||||
newItems.push(f);
|
||||
if (this.folderHasChildren_(this.folders, f.id)) orderFolders(f.id);
|
||||
// Only recurse into children if the folder is not collapsed
|
||||
if (this.folderHasChildren_(this.folders, f.id)) {
|
||||
const collapsedFolders = Setting.value('collapsedFolderIds');
|
||||
if (!collapsedFolders.includes(f.id)) {
|
||||
orderFolders(f.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -221,4 +254,53 @@ export default class FolderListWidget extends ListWidget {
|
||||
const index = this.itemIndexByKey('id', itemId);
|
||||
this.currentIndex = index >= 0 ? index : 0;
|
||||
}
|
||||
|
||||
public toggleFolderCollapse() {
|
||||
const item = this.currentItem;
|
||||
if (item && item.type_ === Folder.modelType() && this.folderHasChildren_(this.folders, item.id)) {
|
||||
const collapsedFolders = Setting.value('collapsedFolderIds');
|
||||
const isCollapsed = collapsedFolders.includes(item.id);
|
||||
if (isCollapsed) {
|
||||
const newCollapsed = collapsedFolders.filter((id: string) => id !== item.id);
|
||||
Setting.setValue('collapsedFolderIds', newCollapsed);
|
||||
} else {
|
||||
Setting.setValue('collapsedFolderIds', [...collapsedFolders, item.id]);
|
||||
}
|
||||
this.updateItems_ = true;
|
||||
this.invalidate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public expandToFolder(folderId: string) {
|
||||
// Find all parent folders and expand them
|
||||
const parentsToExpand: string[] = [];
|
||||
let currentId = folderId;
|
||||
|
||||
while (currentId) {
|
||||
const folder = BaseModel.byId(this.folders, currentId);
|
||||
if (!folder) break;
|
||||
|
||||
const parentId = getDisplayParentId(
|
||||
folder,
|
||||
this.folders.find((f) => f.id === folder.parent_id),
|
||||
);
|
||||
if (parentId) {
|
||||
parentsToExpand.unshift(parentId);
|
||||
currentId = parentId;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand all parent folders
|
||||
const collapsedFolders = Setting.value('collapsedFolderIds');
|
||||
const newCollapsed = collapsedFolders.filter((id: string) => !parentsToExpand.includes(id));
|
||||
Setting.setValue('collapsedFolderIds', newCollapsed);
|
||||
|
||||
this.updateItems_ = true;
|
||||
this.invalidate();
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ const Setting = require('@joplin/lib/models/Setting').default;
|
||||
const Revision = require('@joplin/lib/models/Revision').default;
|
||||
const Logger = require('@joplin/utils/Logger').default;
|
||||
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
const shimInitCli = require('./utils/shimInitCli').default;
|
||||
const shim = require('@joplin/lib/shim').default;
|
||||
const { _ } = require('@joplin/lib/locale');
|
||||
const FileApiDriverLocal = require('@joplin/lib/file-api-driver-local').default;
|
||||
@@ -73,7 +73,7 @@ function appVersion() {
|
||||
return p.version;
|
||||
}
|
||||
|
||||
shimInit({ sharp, keytar, appVersion, nodeSqlite });
|
||||
shimInitCli({ sharp, keytar, appVersion, nodeSqlite });
|
||||
|
||||
const logger = new Logger();
|
||||
Logger.initializeGlobalLogger(logger);
|
||||
|
14
packages/app-cli/app/utils/initializeCommandService.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
import stateToWhenClauseContext from '@joplin/lib/services/commands/stateToWhenClauseContext';
|
||||
import libCommands from '@joplin/lib/commands/index';
|
||||
import { State } from '@joplin/lib/reducer';
|
||||
import { Store } from 'redux';
|
||||
|
||||
export default function initializeCommandService(store: Store<State>, devMode: boolean) {
|
||||
CommandService.instance().initialize(store, devMode, stateToWhenClauseContext);
|
||||
|
||||
for (const command of libCommands) {
|
||||
CommandService.instance().registerDeclaration(command.declaration);
|
||||
CommandService.instance().registerRuntime(command.declaration.name, command.runtime());
|
||||
}
|
||||
}
|
54
packages/app-cli/app/utils/iterateStdin.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { createInterface } from 'readline/promises';
|
||||
|
||||
const iterateStdin = async function*(prompt: string) {
|
||||
let nextLineListeners: (()=> void)[] = [];
|
||||
const dispatchAllListeners = () => {
|
||||
const listeners = nextLineListeners;
|
||||
nextLineListeners = [];
|
||||
for (const listener of listeners) {
|
||||
listener();
|
||||
}
|
||||
};
|
||||
|
||||
const rl = createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
rl.setPrompt(prompt);
|
||||
|
||||
let buffer: string[] = [];
|
||||
rl.on('line', (line) => {
|
||||
buffer.push(line);
|
||||
dispatchAllListeners();
|
||||
});
|
||||
|
||||
let done = false;
|
||||
rl.on('close', () => {
|
||||
done = true;
|
||||
dispatchAllListeners();
|
||||
});
|
||||
|
||||
const readNextLines = () => {
|
||||
return new Promise<string|null>(resolve => {
|
||||
if (done) {
|
||||
resolve(null);
|
||||
} else if (buffer.length > 0) {
|
||||
resolve(buffer.join('\n'));
|
||||
buffer = [];
|
||||
} else {
|
||||
nextLineListeners.push(() => {
|
||||
resolve(buffer.join('\n'));
|
||||
buffer = [];
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
while (!done) {
|
||||
rl.prompt();
|
||||
const lines = await readNextLines();
|
||||
yield lines;
|
||||
}
|
||||
};
|
||||
|
||||
export default iterateStdin;
|
32
packages/app-cli/app/utils/shimInitCli.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import shim, { ShowMessageBoxOptions } from '@joplin/lib/shim';
|
||||
import type { ShimInitOptions } from '@joplin/lib/shim-init-node';
|
||||
import app from '../app';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
const { shimInit } = require('@joplin/lib/shim-init-node.js');
|
||||
|
||||
const shimInitCli = (options: ShimInitOptions) => {
|
||||
shimInit(options);
|
||||
|
||||
shim.showMessageBox = async (message: string, options: ShowMessageBoxOptions) => {
|
||||
const gui = app()?.gui();
|
||||
let answers = options.buttons ?? [_('OK'), _('Cancel')];
|
||||
|
||||
if (options.type === 'error' || options.type === 'info') {
|
||||
answers = [];
|
||||
}
|
||||
|
||||
message += answers.length ? `(${answers.join(', ')})` : '';
|
||||
|
||||
const answer = await gui.prompt(options.title ?? '', `${message} `, { answers });
|
||||
|
||||
if (answers.includes(answer)) {
|
||||
return answers.indexOf(answer);
|
||||
} else if (answer) {
|
||||
return answers.findIndex(a => a.startsWith(answer));
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
};
|
||||
|
||||
export default shimInitCli;
|
@@ -15,4 +15,7 @@ export const setupApplication = async () => {
|
||||
// such notebook.
|
||||
await Folder.save({ title: 'default' });
|
||||
await app().refreshCurrentFolder();
|
||||
|
||||
// Some tests also need access to the Redux store
|
||||
app().initRedux();
|
||||
};
|
||||
|
@@ -35,15 +35,15 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.0",
|
||||
"bin": "./main.js",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@joplin/lib": "~3.3",
|
||||
"@joplin/renderer": "~3.3",
|
||||
"@joplin/utils": "~3.3",
|
||||
"@joplin/lib": "~3.4",
|
||||
"@joplin/renderer": "~3.4",
|
||||
"@joplin/utils": "~3.4",
|
||||
"aws-sdk": "2.1340.0",
|
||||
"chalk": "4.1.2",
|
||||
"compare-version": "0.1.2",
|
||||
@@ -55,28 +55,29 @@
|
||||
"node-rsa": "1.1.1",
|
||||
"open": "8.4.2",
|
||||
"proper-lockfile": "4.1.2",
|
||||
"redux": "4.2.1",
|
||||
"server-destroy": "1.0.1",
|
||||
"sharp": "0.33.4",
|
||||
"sharp": "0.34.2",
|
||||
"sprintf-js": "1.1.3",
|
||||
"sqlite3": "5.1.6",
|
||||
"string-padding": "1.0.2",
|
||||
"strip-ansi": "6.0.1",
|
||||
"tcp-port-used": "1.0.2",
|
||||
"terminal-kit": "3.1.1",
|
||||
"terminal-kit": "3.1.2",
|
||||
"tkwidgets": "0.5.27",
|
||||
"url-parse": "1.5.10",
|
||||
"word-wrap": "1.2.5",
|
||||
"yargs-parser": "21.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@joplin/tools": "~3.3",
|
||||
"@joplin/tools": "~3.4",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/jest": "29.5.12",
|
||||
"@types/node": "18.19.67",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.101",
|
||||
"@types/proper-lockfile": "^4.1.2",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.7.0",
|
||||
"temp": "0.9.4",
|
||||
"typescript": "5.4.5"
|
||||
"typescript": "5.8.2"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
|
||||
import MarkupToHtml, { MarkupLanguage } from '@joplin/renderer/MarkupToHtml';
|
||||
import { RenderResult } from '@joplin/renderer/types';
|
||||
import MarkupToHtml from '@joplin/renderer/MarkupToHtml';
|
||||
import { RenderResult, MarkupLanguage } from '@joplin/renderer/types';
|
||||
|
||||
describe('MarkupToHtml', () => {
|
||||
|
||||
|
1
packages/app-cli/tests/html_to_md/comments_in_style.html
Normal file
@@ -0,0 +1 @@
|
||||
<p><span style="/* Comment */ text-decoration: underline;">Test</span>. In the past, <span style="font-size: auto;/* Test! */">comments</span> in CSS have caused issues.</p>
|
1
packages/app-cli/tests/html_to_md/comments_in_style.md
Normal file
@@ -0,0 +1 @@
|
||||
<ins>Test</ins>. In the past, comments in CSS have caused issues.
|
@@ -0,0 +1 @@
|
||||
<p>Some **format** characters $need$ to be `escaped`, if the characters were included directly in HTML.</p>
|
@@ -0,0 +1 @@
|
||||
Some \*\*format\*\* characters \$need\$ to be \`escaped\`, if the characters were included directly in HTML.
|
@@ -0,0 +1,13 @@
|
||||
<p>A task list created by the TipTap editor:</p>
|
||||
<ul data-type="taskList">
|
||||
<li><label contenteditable="false"><input type="checkbox"><span></span></label>
|
||||
<div>
|
||||
<p>Testing...</p>
|
||||
</div>
|
||||
</li>
|
||||
<li><label contenteditable="false"><input type="checkbox"><span></span></label>
|
||||
<div>
|
||||
<p>testing</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
@@ -0,0 +1,5 @@
|
||||
A task list created by the TipTap editor:
|
||||
|
||||
- [ ] Testing...
|
||||
|
||||
- [ ] testing
|
26
packages/app-cli/tests/html_to_md/task_lists.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<p>List 1:</p>
|
||||
<ul>
|
||||
<li><label><input type="checkbox"/>This</label></li>
|
||||
<li><label><input type="checkbox" checked/>is a test.</label></li>
|
||||
</ul>
|
||||
<p>List 2:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<input type="checkbox" id="checkbox-1"/><label for="checkbox-1">This</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" checked id="checkbox-2"/><label for="checkbox-2">is another test.</label>
|
||||
</li>
|
||||
</ul>
|
||||
<p>List 3:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<input type="checkbox" id="checkbox-a1"/><label for="checkbox-a1">This</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" checked id="checkbox-a2"/><label for="checkbox-a2">is another test.</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" checked id="checkbox-a3"/><label for="checkbox-a3"></label>
|
||||
</li>
|
||||
</ul>
|