mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-31 19:19:34 +02:00
Compare commits
73 Commits
v3.0.14
...
fix-move-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6457733697 | ||
|
|
0e3a661dd0 | ||
|
|
fba350ed1e | ||
|
|
76bfbc7316 | ||
|
|
7683d8fa5b | ||
|
|
3fe5352b56 | ||
|
|
a86d9a9c0c | ||
|
|
a68f74bc1b | ||
|
|
18310698f6 | ||
|
|
020244231f | ||
|
|
59085d7b19 | ||
|
|
c15410e168 | ||
|
|
2962f13457 | ||
|
|
bfc77fc9a4 | ||
|
|
7e88ec88ee | ||
|
|
9ef07f22af | ||
|
|
268343be3e | ||
|
|
956e5373d1 | ||
|
|
919fa9bdf1 | ||
|
|
e06192c5b4 | ||
|
|
b5be5e0b59 | ||
|
|
05695cfcc8 | ||
|
|
423e1c6816 | ||
|
|
6db1cf5cc1 | ||
|
|
2e4a87abd9 | ||
|
|
c26988134f | ||
|
|
bcffdd0f91 | ||
|
|
de1051d52d | ||
|
|
b1a360e445 | ||
|
|
49e85dfa87 | ||
|
|
452ff12071 | ||
|
|
1b6fc40633 | ||
|
|
82b28f8263 | ||
|
|
6e47eae30a | ||
|
|
4040f2ecc4 | ||
|
|
2293866c61 | ||
|
|
2cb4a10076 | ||
|
|
2f7b8d3377 | ||
|
|
983220b2f2 | ||
|
|
ca2848e491 | ||
|
|
48e5c4d908 | ||
|
|
5774dd8c60 | ||
|
|
9d65184f42 | ||
|
|
395b2750e8 | ||
|
|
3bfb1d57a5 | ||
|
|
e59b432007 | ||
|
|
efbc566386 | ||
|
|
2576f1dd00 | ||
|
|
7d9388bd27 | ||
|
|
1979cd2ea4 | ||
|
|
7bd5dfb772 | ||
|
|
ac7c88218b | ||
|
|
fb642233c8 | ||
|
|
6e2a19d7e0 | ||
|
|
4d4993c570 | ||
|
|
916e097cb3 | ||
|
|
6def76e1bb | ||
|
|
d93ec27c9e | ||
|
|
15329597a5 | ||
|
|
49caf23436 | ||
|
|
e6d8401c56 | ||
|
|
11a5e8c180 | ||
|
|
5bd7a081c1 | ||
|
|
a740a5db81 | ||
|
|
a61f2efacf | ||
|
|
51a253f3e2 | ||
|
|
19ed753079 | ||
|
|
4a85c49f5d | ||
|
|
16dd4b3359 | ||
|
|
9279c671ac | ||
|
|
225b21977e | ||
|
|
026b9212c4 | ||
|
|
5ce59c6125 |
281
apps/desktop/package-lock.json
generated
281
apps/desktop/package-lock.json
generated
@@ -1,35 +1,34 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/server": "10.38.3",
|
||||
"better-sqlite3-multiple-ciphers": "^9.5.0",
|
||||
"electron-trpc": "0.5.2",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "^11.2.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.2.1",
|
||||
"icojs": "^0.17.1",
|
||||
"sodium-native": "^4.1.1",
|
||||
"icojs": "^0.19.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.6.2",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.16.1",
|
||||
"@types/yargs": "^17.0.24",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@types/node": "20.14.8",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"chokidar": "^3.5.3",
|
||||
"electron": "^29.3.1",
|
||||
"electron": "^30.4.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"esbuild": "^0.23.0",
|
||||
"kysely": "^0.27.3",
|
||||
"node-abi": "^3.67.0",
|
||||
"node-gyp-build": "^4.8.0",
|
||||
"prebuildify": "^6.0.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
@@ -42,6 +41,7 @@
|
||||
"../../packages/crypto": {
|
||||
"name": "@notesnook/crypto",
|
||||
"version": "2.0.7",
|
||||
"extraneous": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/sodium": "file:../sodium"
|
||||
@@ -768,6 +768,26 @@
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@jimp/bmp": {
|
||||
"version": "0.22.12",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz",
|
||||
"integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==",
|
||||
"dependencies": {
|
||||
"@jimp/utils": "^0.22.12",
|
||||
"bmp-js": "^0.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@jimp/custom": ">=0.3.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@jimp/utils": {
|
||||
"version": "0.22.12",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz",
|
||||
"integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/cross-spawn-promise": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
|
||||
@@ -820,10 +840,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook/crypto": {
|
||||
"resolved": "../../packages/crypto",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -834,6 +850,11 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sec-ant/readable-stream": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
|
||||
"integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||
@@ -846,6 +867,15 @@
|
||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@streetwriters/kysely": {
|
||||
"version": "0.27.4",
|
||||
"resolved": "https://registry.npmjs.org/@streetwriters/kysely/-/kysely-0.27.4.tgz",
|
||||
"integrity": "sha512-c2p+wtX8WESSVjJAc16j4lT44w/g1DvJFEIeKj/CFy36vmi0uq9FOAzxc50VtRc7rp0UlECCfl3Sxd+BTZOHFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@szmarczak/http-timer": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||
@@ -873,20 +903,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/client": {
|
||||
"version": "10.38.3",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.38.3.tgz",
|
||||
"integrity": "sha512-hHPsElTL4sB+UGzuAZ4iwRVHjELrk/Nsl2owsYw9ITJz3EY7VWRsQ6vK48kJvlHPYPhP+efID5UOgyZMs4bFXA==",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.45.2.tgz",
|
||||
"integrity": "sha512-ykALM5kYWTLn1zYuUOZ2cPWlVfrXhc18HzBDyRhoPYN0jey4iQHEFSEowfnhg1RvYnrAVjNBgHNeSAXjrDbGwg==",
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@trpc/server": "10.38.3"
|
||||
"@trpc/server": "10.45.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/server": {
|
||||
"version": "10.38.3",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.38.3.tgz",
|
||||
"integrity": "sha512-9s8/kwo2IDB5hwB2SKZZrfevRhdb1f9fdXtIYd3lbQuf2jQaC/LyQuHaIQjDQoUx9updBfsHXcFFPiCP1DL6pg==",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.45.2.tgz",
|
||||
"integrity": "sha512-wOrSThNNE4HUnuhJG6PfDRp4L2009KDVxsd+2VYH8ro6o/7/jwYZ8Uu5j+VaW+mOmc8EHerHzGcdbGNQSAUPgg==",
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
]
|
||||
@@ -943,10 +973,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz",
|
||||
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==",
|
||||
"devOptional": true
|
||||
"version": "20.14.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz",
|
||||
"integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/plist": {
|
||||
"version": "3.0.2",
|
||||
@@ -974,9 +1007,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/yargs": {
|
||||
"version": "17.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
|
||||
"integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==",
|
||||
"version": "17.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
|
||||
"integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/yargs-parser": "*"
|
||||
@@ -1212,9 +1245,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/better-sqlite3-multiple-ciphers": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3-multiple-ciphers/-/better-sqlite3-multiple-ciphers-9.5.0.tgz",
|
||||
"integrity": "sha512-6A9xBRvssONJW07Lur6pmkaUwlCGz1bnjFmXrrAR3qXETUBk92OI4C/+LhMOatn5wQ8AQzLScFZC/CKUpxkTaw==",
|
||||
"version": "11.2.1",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3-multiple-ciphers/-/better-sqlite3-multiple-ciphers-11.2.1.tgz",
|
||||
"integrity": "sha512-qYZ9GnZMnSOek/d00KnaXsECRFoMrNXSu9ubgeHaQi/5310+OQisaNo7FqBCCQlucPk15+etHgLwNHCeS6QzWQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
@@ -1896,9 +1929,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "29.3.1",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-29.3.1.tgz",
|
||||
"integrity": "sha512-auge1/6RVqgUd6TgIq88wKdUCJi2cjESi3jy7d+6X4JzvBGprKBqMJ8JSSFpu/Px1YJrFUKAxfy6SC+TQf1uLw==",
|
||||
"version": "30.4.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-30.4.0.tgz",
|
||||
"integrity": "sha512-ric3KLPQ9anXYjtTDkj5NbEcXZqRUwqxrxTviIjLdMdHqd5O+hkSHEzXgbSJUOt+7uw+zZuybn9+IM9y7iEpqg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
@@ -1955,9 +1988,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-trpc": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-trpc/-/electron-trpc-0.5.2.tgz",
|
||||
"integrity": "sha512-lJTeTwrd/E1C3VGFvdSBQggdmdDeHGrrpnuiB1e3bQR/1f91HmprySMygs9e4i12+CLqR+RIyKTQWLKCNjy5/Q==",
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-trpc/-/electron-trpc-0.6.1.tgz",
|
||||
"integrity": "sha512-Yj13UrjjjOW4+TD06YunAML2tgmtSYJMiFw6E6r1D4in/0EZ2MRwMoQc7AtMPAA6In23e+Kmq71e8h0ir+c3Jg==",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
@@ -1982,15 +2015,6 @@
|
||||
"tiny-typed-emitter": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@types/node": {
|
||||
"version": "20.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@@ -2145,21 +2169,37 @@
|
||||
}
|
||||
},
|
||||
"node_modules/file-type": {
|
||||
"version": "16.5.4",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
|
||||
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
|
||||
"version": "19.4.1",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-19.4.1.tgz",
|
||||
"integrity": "sha512-RuWzwF2L9tCHS76KR/Mdh+DwJZcFCzrhrPXpOw6MlEfl/o31fjpTikzcKlYuyeV7e7ftdCGVJTNOCzkYD/aLbw==",
|
||||
"dependencies": {
|
||||
"readable-web-to-node-stream": "^3.0.0",
|
||||
"strtok3": "^6.2.4",
|
||||
"token-types": "^4.1.1"
|
||||
"get-stream": "^9.0.1",
|
||||
"strtok3": "^8.1.0",
|
||||
"token-types": "^6.0.0",
|
||||
"uint8array-extras": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/file-type/node_modules/get-stream": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
|
||||
"integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
|
||||
"dependencies": {
|
||||
"@sec-ant/readable-stream": "^0.4.1",
|
||||
"is-stream": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
@@ -2580,19 +2620,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/icojs": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/icojs/-/icojs-0.17.1.tgz",
|
||||
"integrity": "sha512-yGqa/9Uq82EAAq5V0Earig1SUubOi5ogRj/XEDiwAv/jewP9p3p/qIu/2zHWG5f8VKxRuNZB5xNgIzDxAxtPQg==",
|
||||
"version": "0.19.4",
|
||||
"resolved": "https://registry.npmjs.org/icojs/-/icojs-0.19.4.tgz",
|
||||
"integrity": "sha512-86oNepPk2jAmbb96BPeucZI7HoSBobFlXDhhjIbwRb3wkQpvdBO5HO9KtMUNzMFT3qqQZsjLsfW+L0/9Rl9VqA==",
|
||||
"dependencies": {
|
||||
"bmp-js": "0.1.0",
|
||||
"@jimp/bmp": "^0.22.12",
|
||||
"decode-ico": "^0.4.1",
|
||||
"file-type": "^16.5.4",
|
||||
"file-type": "^19.0.0",
|
||||
"jpeg-js": "^0.4.4",
|
||||
"pngjs": "^6.0.0",
|
||||
"to-data-view": "^1.1.0"
|
||||
"pngjs": "^7.0.0",
|
||||
"to-data-view": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.19.1"
|
||||
"node": ">=18.17.1"
|
||||
}
|
||||
},
|
||||
"node_modules/icojs/node_modules/to-data-view": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-2.0.0.tgz",
|
||||
"integrity": "sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-corefoundation": {
|
||||
@@ -2725,6 +2773,17 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
|
||||
"integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isbinaryfile": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz",
|
||||
@@ -2868,15 +2927,6 @@
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/kysely": {
|
||||
"version": "0.27.3",
|
||||
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.27.3.tgz",
|
||||
"integrity": "sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
@@ -3055,9 +3105,9 @@
|
||||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.54.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz",
|
||||
"integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==",
|
||||
"version": "3.67.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz",
|
||||
"integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
@@ -3075,6 +3125,7 @@
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz",
|
||||
"integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
@@ -3200,11 +3251,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/peek-readable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
|
||||
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.2.0.tgz",
|
||||
"integrity": "sha512-U94a+eXHzct7vAd19GH3UQ2dH4Satbng0MyYTMaQatL0pvYYL5CTPR25HBhKtecl+4bfu1/i3vC6k0hydO5Vcw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@@ -3244,11 +3295,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
|
||||
"integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
"node": ">=14.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
@@ -3389,21 +3440,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-web-to-node-stream": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
|
||||
"integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
|
||||
"dependencies": {
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -3416,6 +3452,11 @@
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.13.11",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
@@ -3667,15 +3708,6 @@
|
||||
"npm": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sodium-native": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.1.1.tgz",
|
||||
"integrity": "sha512-LXkAfRd4FHtkQS4X6g+nRcVaN7mWVNepV06phIsC6+IZFvGh1voW5TNQiQp2twVaMf05gZqQjuS+uWLM6gHhNQ==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"node-gyp-build": "^4.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
@@ -3780,15 +3812,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/strtok3": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
|
||||
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-8.1.0.tgz",
|
||||
"integrity": "sha512-ExzDvHYPj6F6QkSNe/JxSlBxTh3OrI6wrAIz53ulxo1c4hBJ1bT9C/JrAthEKHWG9riVH3Xzg7B03Oxty6S2Lw==",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"peek-readable": "^4.1.0"
|
||||
"peek-readable": "^5.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@@ -3918,15 +3950,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/token-types": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
|
||||
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz",
|
||||
"integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"ieee754": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@@ -3989,6 +4021,17 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uint8array-extras": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz",
|
||||
"integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.14.1",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.14.1.tgz",
|
||||
@@ -4002,7 +4045,7 @@
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
@@ -11,26 +11,25 @@
|
||||
"repository": "https://github.com/streetwriters/notesnook",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/server": "10.38.3",
|
||||
"better-sqlite3-multiple-ciphers": "^9.5.0",
|
||||
"electron-trpc": "0.5.2",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "^11.2.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.2.1",
|
||||
"icojs": "^0.17.1",
|
||||
"sodium-native": "^4.1.1",
|
||||
"icojs": "^0.19.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.6.2",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.16.1",
|
||||
"@types/yargs": "^17.0.24",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@types/node": "20.14.8",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"chokidar": "^3.5.3",
|
||||
"electron": "^29.3.1",
|
||||
"electron": "^30.4.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"esbuild": "^0.23.0",
|
||||
"kysely": "^0.27.3",
|
||||
"node-abi": "^3.67.0",
|
||||
"node-gyp-build": "^4.8.0",
|
||||
"prebuildify": "^6.0.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
@@ -159,7 +158,8 @@
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": true,
|
||||
"createDesktopShortcut": "always"
|
||||
"createDesktopShortcut": "always",
|
||||
"deleteAppDataOnUninstall": true
|
||||
},
|
||||
"linux": {
|
||||
"target": [
|
||||
|
||||
@@ -94,7 +94,7 @@ async function patchBetterSQLite3() {
|
||||
);
|
||||
const json = JSON.parse(await readFile(jsonPath, "utf-8"));
|
||||
|
||||
json.version = "9.5.1";
|
||||
json.version = "11.2.2";
|
||||
json.homepage = "https://github.com/thecodrr/better-sqlite3-multiple-ciphers";
|
||||
json.repository.url =
|
||||
"git://github.com/thecodrr/better-sqlite3-multiple-ciphers.git";
|
||||
|
||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { Database, Statement } from "better-sqlite3-multiple-ciphers";
|
||||
import type { QueryResult } from "kysely";
|
||||
import type { QueryResult } from "@streetwriters/kysely";
|
||||
|
||||
type SQLiteCompatibleType =
|
||||
| number
|
||||
|
||||
@@ -29,19 +29,37 @@ type Progress = { percent: number };
|
||||
|
||||
const t = initTRPC.create();
|
||||
let cancellationToken: CancellationToken | undefined = undefined;
|
||||
let downloadTimeout: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
export const updaterRouter = t.router({
|
||||
autoUpdates: t.procedure.query(() => config.automaticUpdates),
|
||||
install: t.procedure.query(() => autoUpdater.quitAndInstall()),
|
||||
download: t.procedure.query(async () => {
|
||||
if (cancellationToken) return;
|
||||
cancellationToken = new CancellationToken();
|
||||
await autoUpdater
|
||||
.downloadUpdate(cancellationToken)
|
||||
.finally(() => (cancellationToken = undefined));
|
||||
clearTimeout(downloadTimeout);
|
||||
await new Promise<string[]>((resolve, reject) => {
|
||||
downloadTimeout = setTimeout(async () => {
|
||||
cancellationToken = new CancellationToken();
|
||||
autoUpdater.isUpdaterActive();
|
||||
await autoUpdater
|
||||
.downloadUpdate(cancellationToken)
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.finally(() => (cancellationToken = undefined));
|
||||
}, 1000);
|
||||
});
|
||||
}),
|
||||
check: t.procedure.query(async () => {
|
||||
await autoUpdater.checkForUpdates().catch(console.error);
|
||||
if (cancellationToken) return;
|
||||
clearTimeout(downloadTimeout);
|
||||
await new Promise<void>((resolve) => {
|
||||
downloadTimeout = setTimeout(async () => {
|
||||
await autoUpdater
|
||||
.checkForUpdates()
|
||||
.catch(console.error)
|
||||
.finally(resolve);
|
||||
}, 1000);
|
||||
});
|
||||
}),
|
||||
|
||||
toggleAutoUpdates: t.procedure
|
||||
|
||||
@@ -20,14 +20,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { ELECTRON_TRPC_CHANNEL } from "electron-trpc/main";
|
||||
import { type RendererGlobalElectronTRPC } from "electron-trpc/src/types";
|
||||
import type { NNCrypto } from "@notesnook/crypto";
|
||||
// import type { NNCrypto } from "@notesnook/crypto";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { platform } from "os";
|
||||
|
||||
declare global {
|
||||
var os: () => "mas" | ReturnType<typeof platform>;
|
||||
var electronTRPC: RendererGlobalElectronTRPC;
|
||||
var NativeNNCrypto: (new () => NNCrypto) | undefined;
|
||||
// var NativeNNCrypto: (new () => NNCrypto) | undefined;
|
||||
}
|
||||
|
||||
process.once("loaded", async () => {
|
||||
@@ -40,5 +40,5 @@ process.once("loaded", async () => {
|
||||
globalThis.electronTRPC = electronTRPC;
|
||||
});
|
||||
|
||||
globalThis.NativeNNCrypto = require("@notesnook/crypto").NNCrypto;
|
||||
// globalThis.NativeNNCrypto = require("@notesnook/crypto").NNCrypto;
|
||||
globalThis.os = () => (MAC_APP_STORE ? "mas" : platform());
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { NativeImage, nativeImage } from "electron";
|
||||
import path from "path";
|
||||
import { isDevelopment } from "./index";
|
||||
import { parse, ParsedImage } from "icojs";
|
||||
import { ParsedImage, parseICO } from "icojs";
|
||||
import { getSystemTheme } from "./theme";
|
||||
import { readFile } from "fs/promises";
|
||||
|
||||
@@ -71,7 +71,7 @@ export class AssetManager {
|
||||
`${icon}${prefix}.ico`
|
||||
);
|
||||
const icoBuffer = await readFile(icoPath);
|
||||
const images = await parse(icoBuffer, "image/png");
|
||||
const images = await parseICO(icoBuffer, "image/png");
|
||||
ALL_ICONS.push({ id: icon, images, prefix });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@ import { Platform } from "react-native";
|
||||
import * as Gzip from "react-native-gzip";
|
||||
import EventSource from "../../utils/sse/even-source-ios";
|
||||
import AndroidEventSource from "../../utils/sse/event-source";
|
||||
import { SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from "kysely";
|
||||
import {
|
||||
SqliteAdapter,
|
||||
SqliteIntrospector,
|
||||
SqliteQueryCompiler
|
||||
} from "@streetwriters/kysely";
|
||||
import filesystem from "../filesystem";
|
||||
import Storage from "./storage";
|
||||
import { RNSqliteDriver } from "./sqlite.kysely";
|
||||
|
||||
@@ -18,7 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { initialize } from "@notesnook/core/dist/logger";
|
||||
import { SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from "kysely";
|
||||
import {
|
||||
SqliteAdapter,
|
||||
SqliteIntrospector,
|
||||
SqliteQueryCompiler
|
||||
} from "@streetwriters/kysely";
|
||||
import { Platform } from "react-native";
|
||||
import { setLogger } from ".";
|
||||
import { RNSqliteDriver } from "./sqlite.kysely";
|
||||
|
||||
@@ -17,8 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { DatabaseConnection, Driver, QueryResult } from "kysely";
|
||||
import { CompiledQuery } from "kysely";
|
||||
import type {
|
||||
DatabaseConnection,
|
||||
Driver,
|
||||
QueryResult
|
||||
} from "@streetwriters/kysely";
|
||||
import { CompiledQuery } from "@streetwriters/kysely";
|
||||
import { QuickSQLiteConnection, open } from "react-native-quick-sqlite";
|
||||
|
||||
type Config = { dbName: string; async: boolean; location: string };
|
||||
|
||||
@@ -43,6 +43,7 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
DatabaseLogger.log(`File Exists already: ${filename}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
const attachment = await db.attachments.attachment(filename);
|
||||
const size = await getUploadedFileSize(filename);
|
||||
|
||||
@@ -90,7 +91,8 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
DatabaseLogger.log(`Download starting: ${filename}`);
|
||||
let request = RNFetchBlob.config({
|
||||
path: tempFilePath,
|
||||
IOSBackgroundTask: true
|
||||
IOSBackgroundTask: true,
|
||||
overwrite: true
|
||||
})
|
||||
.fetch("GET", downloadUrl, null)
|
||||
.progress(async (recieved, total) => {
|
||||
@@ -122,6 +124,11 @@ export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
|
||||
let status = response.info().status;
|
||||
useAttachmentStore.getState().remove(filename);
|
||||
|
||||
if (exists(originalFilePath)) {
|
||||
await RNFetchBlob.fs.unlink(originalFilePath).catch(console.log);
|
||||
}
|
||||
|
||||
await RNFetchBlob.fs.mv(tempFilePath, originalFilePath);
|
||||
|
||||
if (!(await exists(filename))) {
|
||||
|
||||
@@ -167,7 +167,7 @@ export const Component = ({ close, promo }) => {
|
||||
>
|
||||
(
|
||||
{Platform.OS === "android"
|
||||
? pricing.product?.subscriptionOfferDetails[0].pricingPhases
|
||||
? pricing.product?.subscriptionOfferDetails[0]?.pricingPhases
|
||||
.pricingPhaseList?.[0].formattedPrice
|
||||
: pricing.product?.localizedPrice}{" "}
|
||||
/ mo)
|
||||
|
||||
@@ -85,7 +85,7 @@ export const PricingItem = ({
|
||||
>
|
||||
{Platform.OS === "android"
|
||||
? (product.data as RNIap.SubscriptionAndroid | undefined)
|
||||
?.subscriptionOfferDetails[0].pricingPhases
|
||||
?.subscriptionOfferDetails?.[0]?.pricingPhases
|
||||
.pricingPhaseList?.[0]?.formattedPrice
|
||||
: (product.data as RNIap.SubscriptionIOS | undefined)
|
||||
?.localizedPrice}
|
||||
|
||||
@@ -393,7 +393,7 @@ export const PricingPlans = ({
|
||||
>
|
||||
{Platform.OS === "android"
|
||||
? (product.data as RNIap.SubscriptionAndroid)
|
||||
?.subscriptionOfferDetails[0].pricingPhases
|
||||
?.subscriptionOfferDetails[0]?.pricingPhases
|
||||
.pricingPhaseList?.[0]?.formattedPrice
|
||||
: (product.data as RNIap.SubscriptionIOS)
|
||||
?.introductoryPrice ||
|
||||
|
||||
@@ -19,17 +19,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { FeatureType } from "./components/sheets/new-feature";
|
||||
|
||||
export const features: FeatureType[] = [
|
||||
{
|
||||
title: "Full offline mode",
|
||||
body: "Enable full offline mode from Settings -> Account -> Sync Settings. This will allow you to keep all your attachments and data offline on the client"
|
||||
},
|
||||
{
|
||||
title: "Backup with attachments",
|
||||
body: "You can now backup your notes alongwith all your attachments - kind of like a full account snapshot."
|
||||
},
|
||||
{
|
||||
title: "Self hosting",
|
||||
body: "This release also adds initial support for changing server URLs i.e. to connect your own instance of Notesnook. Please note that this is still experimental and may not work as expected."
|
||||
}
|
||||
];
|
||||
export const features: FeatureType[] = [];
|
||||
|
||||
@@ -95,6 +95,7 @@ import {
|
||||
import { getGithubVersion } from "../utils/github-version";
|
||||
import { tabBarRef } from "../utils/global-refs";
|
||||
import { sleep } from "../utils/time";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
|
||||
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
|
||||
const { disableSync, disableAutoSync } = SettingsService.get();
|
||||
@@ -254,9 +255,9 @@ async function saveEditorState() {
|
||||
movedAway: editorState().movedAway,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
MMKV.setString("appState", state);
|
||||
NotesnookModule.setAppState(state);
|
||||
} else {
|
||||
MMKV.removeItem("appState");
|
||||
NotesnookModule.setAppState("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +633,7 @@ export const useAppEvents = () => {
|
||||
Sync.run("global", false, "full");
|
||||
reconnectSSE();
|
||||
await checkForShareExtensionLaunchedInBackground();
|
||||
MMKV.removeItem("appState");
|
||||
NotesnookModule.setAppState("");
|
||||
let user = await db.user.getUser();
|
||||
if (user && !user?.isEmailConfirmed) {
|
||||
try {
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
"react-native-wheel-color-picker": "^1.3.1",
|
||||
"tinycolor2": "1.6.0",
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/react-query": "10.38.3",
|
||||
"@trpc/server": "10.38.3",
|
||||
"kysely": "^0.26.3",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/react-query": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"pathe": "1.1.2"
|
||||
},
|
||||
"sideEffects": false
|
||||
|
||||
@@ -660,9 +660,9 @@ export const useEditor = (
|
||||
lock.current = true;
|
||||
|
||||
// Handle this case where note was locked on another device and synced.
|
||||
const locked = await db.vaults.itemExists(
|
||||
currentNotes.current[noteId] as ItemReference
|
||||
);
|
||||
const locked = note
|
||||
? await db.vaults.itemExists(note as ItemReference)
|
||||
: false;
|
||||
|
||||
if (note) {
|
||||
if (!locked && tab?.noteLocked) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import { useTabStore } from "./use-tab-store";
|
||||
import { parseInternalLink } from "@notesnook/core";
|
||||
import { eOnLoadNote } from "../../../utils/events";
|
||||
import { db } from "../../../common/database";
|
||||
import { NotesnookModule } from "../../../utils/notesnook-module";
|
||||
export const textInput = createRef<TextInput>();
|
||||
export const editorController =
|
||||
createRef<useEditorType>() as MutableRefObject<useEditorType>;
|
||||
@@ -165,7 +166,7 @@ const canRestoreAppState = (appState: AppState) => {
|
||||
let appState: AppState | undefined;
|
||||
export function getAppState() {
|
||||
if (appState && canRestoreAppState(appState)) return appState as AppState;
|
||||
const json = MMKV.getString("appState");
|
||||
const json = NotesnookModule.getAppState();
|
||||
if (json) {
|
||||
appState = JSON.parse(json) as AppState;
|
||||
if (canRestoreAppState(appState)) {
|
||||
@@ -180,7 +181,7 @@ export function getAppState() {
|
||||
|
||||
export function clearAppState() {
|
||||
appState = undefined;
|
||||
MMKV.removeItem("appState");
|
||||
NotesnookModule.setAppState("");
|
||||
}
|
||||
|
||||
export async function openInternalLink(url: string) {
|
||||
|
||||
@@ -1490,9 +1490,9 @@ NOTE: Creating a backup with attachments can take a while, and also fail complet
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "join-mastodom",
|
||||
id: "join-mastodon",
|
||||
name: "Follow us on Mastodon",
|
||||
description: "We are on mastodom",
|
||||
description: "We are on mastodon",
|
||||
icon: "mastodon",
|
||||
modifer: () => {
|
||||
Linking.openURL("https://fosstodon.org/@notesnook").catch(
|
||||
|
||||
@@ -90,7 +90,7 @@ export const Subscription = () => {
|
||||
|
||||
function getPrice() {
|
||||
return Platform.OS === "android"
|
||||
? monthlyPlan?.product?.subscriptionOfferDetails[0].pricingPhases
|
||||
? monthlyPlan?.product?.subscriptionOfferDetails[0]?.pricingPhases
|
||||
.pricingPhaseList?.[0]?.formattedPrice
|
||||
: monthlyPlan?.product?.localizedPrice;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ const onBoot = async () => {
|
||||
try {
|
||||
if (!SettingsService.getProperty("backgroundSync")) {
|
||||
DatabaseLogger.info("BACKGROUND SYNC ON BOOT DISABLED");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,22 +35,21 @@ import dayjs, { Dayjs } from "dayjs";
|
||||
import { encodeNonAsciiHTML } from "entities";
|
||||
import { Platform } from "react-native";
|
||||
import { db, setupDatabase } from "../common/database";
|
||||
import { MMKV } from "../common/database/mmkv";
|
||||
import { presentDialog } from "../components/dialog/functions";
|
||||
import { useTabStore } from "../screens/editor/tiptap/use-tab-store";
|
||||
import { editorState } from "../screens/editor/tiptap/utils";
|
||||
import { useRelationStore } from "../stores/use-relation-store";
|
||||
import { useReminderStore } from "../stores/use-reminder-store";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { eOnLoadNote } from "../utils/events";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import { tabBarRef } from "../utils/global-refs";
|
||||
import { convertNoteToText } from "../utils/note-to-text";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
import { sleep } from "../utils/time";
|
||||
import { DDS } from "./device-detection";
|
||||
import { eSendEvent } from "./event-manager";
|
||||
import Navigation from "./navigation";
|
||||
import SettingsService from "./settings";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import { useTabStore } from "../screens/editor/tiptap/use-tab-store";
|
||||
|
||||
let pinned: DisplayedNotification[] = [];
|
||||
|
||||
@@ -126,7 +125,7 @@ const onEvent = async ({ type, detail }: Event) => {
|
||||
if (type === EventType.PRESS) {
|
||||
notifee.decrementBadgeCount();
|
||||
if (notification?.data?.type === "quickNote") return;
|
||||
MMKV.removeItem("appState");
|
||||
NotesnookModule.setAppState("");
|
||||
if (notification?.data?.type === "reminder" && notification?.id) {
|
||||
const reminder = await db.reminders?.reminder(
|
||||
notification.id?.split("_")[0]
|
||||
@@ -410,9 +409,7 @@ async function loadNote(id: string, jump: boolean) {
|
||||
if (!DDS.isTab && jump) {
|
||||
tabBarRef.current?.goToPage(1);
|
||||
}
|
||||
|
||||
MMKV.setString(
|
||||
"appState",
|
||||
NotesnookModule.setAppState(
|
||||
JSON.stringify({
|
||||
editing: true,
|
||||
movedAway: false,
|
||||
|
||||
@@ -23,13 +23,17 @@ interface NotesnookModuleInterface {
|
||||
getActivityName: () => Promise<string>;
|
||||
setBackgroundColor: (color: string) => void;
|
||||
setSecureMode: (enabled: boolean) => void;
|
||||
setAppState: (appState: string) => void;
|
||||
getAppState: () => string;
|
||||
}
|
||||
|
||||
export const NotesnookModule: NotesnookModuleInterface = Platform.select({
|
||||
ios: {
|
||||
getActivityName: () => {},
|
||||
setBackgroundColor: () => {},
|
||||
setSecureMode: () => {}
|
||||
setSecureMode: () => {},
|
||||
setAppState: () => {},
|
||||
getAppState: () => {}
|
||||
},
|
||||
android: NativeModules.NNativeModule
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3025
|
||||
versionCode 3027
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.streetwriters.notesnook;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.app.ActivityManager;
|
||||
import com.facebook.react.HeadlessJsTaskService;
|
||||
@@ -19,8 +20,12 @@ public class BootRecieverService extends BroadcastReceiver {
|
||||
network connections
|
||||
**/
|
||||
Intent serviceIntent = new Intent(context, BootTaskService.class);
|
||||
context.startService(serviceIntent);
|
||||
HeadlessJsTaskService.acquireWakeLockNow(context);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(serviceIntent);
|
||||
} else {
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
HeadlessJsTaskService.acquireWakeLockNow(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
package com.streetwriters.notesnook;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.facebook.react.HeadlessJsTaskService;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BootTaskService extends HeadlessJsTaskService {
|
||||
|
||||
Notification notification;
|
||||
@Override
|
||||
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
|
||||
Log.d("BootTask", "Task Started");
|
||||
return new HeadlessJsTaskConfig(
|
||||
"com.streetwriters.notesnook.BOOT_TASK",
|
||||
Arguments.createMap(),
|
||||
@@ -17,4 +26,31 @@ public class BootTaskService extends HeadlessJsTaskService {
|
||||
false // optional: defines whether or not the task is allowed in foreground. Default is false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadlessJsTaskFinish(int taskId) {
|
||||
super.onHeadlessJsTaskFinish(taskId);
|
||||
Log.d("BootTask", "Task completed");
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel("com.streetwriters.notesnook",
|
||||
"Default",
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
|
||||
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
|
||||
notification = new NotificationCompat.Builder(this, channel.getId())
|
||||
.setContentTitle("Sync on boot")
|
||||
.setContentText("")
|
||||
.setSmallIcon(R.drawable.ic_stat_name)
|
||||
.build();
|
||||
startForeground(1, notification);
|
||||
}
|
||||
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.streetwriters.notesnook;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.service.quicksettings.Tile;
|
||||
@@ -9,11 +11,24 @@ import androidx.annotation.RequiresApi;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public class NotesnookTileService extends TileService {
|
||||
@SuppressLint("StartActivityAndCollapseDeprecated")
|
||||
@Override
|
||||
public void onClick() {
|
||||
super.onClick();
|
||||
Intent intent = new Intent(this.getApplicationContext(), ShareActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityAndCollapse(intent);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
startActivityAndCollapse(
|
||||
PendingIntent.getActivity(
|
||||
this.getApplicationContext(),
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
);
|
||||
} else {
|
||||
startActivityAndCollapse(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package com.streetwriters.notesnook;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.ammarahmed.mmkv.MMKV;
|
||||
|
||||
public class OnClearFromRecentService extends Service {
|
||||
|
||||
static {
|
||||
System.loadLibrary("rnmmkv");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
@@ -30,15 +25,12 @@ public class OnClearFromRecentService extends Service {
|
||||
@Override
|
||||
public void onTaskRemoved(Intent rootIntent) {
|
||||
try {
|
||||
MMKV.initialize(getApplicationContext());
|
||||
MMKV mmkv = MMKV.mmkvWithID("default",MMKV.SINGLE_PROCESS_MODE);
|
||||
mmkv.removeValueForKey("appState");
|
||||
SharedPreferences appStateDetails = getApplicationContext().getSharedPreferences("appStateDetails", MODE_PRIVATE);
|
||||
SharedPreferences.Editor edit = appStateDetails.edit();
|
||||
edit.remove("appState");
|
||||
edit.apply();
|
||||
stopSelf();
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
} catch (UnsatisfiedLinkError | Exception e) {
|
||||
}
|
||||
//System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.streetwriters.notesnook;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
@@ -67,6 +70,21 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setAppState(final String appState) {
|
||||
SharedPreferences appStateDetails = getReactApplicationContext().getSharedPreferences("appStateDetails", Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor edit = appStateDetails.edit();
|
||||
edit.putString("appState", appState);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String getAppState() {
|
||||
SharedPreferences appStateDetails = getReactApplicationContext().getSharedPreferences("appStateDetails", Context.MODE_PRIVATE);
|
||||
String appStateValue = appStateDetails.getString("appState", "");
|
||||
return appStateValue.isEmpty() ? null : appStateValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
- Added full offline mode with enable downloading attachments on sync
|
||||
- Now you can change sync server urls in the app settings to use your own self hosted servers
|
||||
- Now you can take backups with attachments included
|
||||
- Removed all kinds of telemetry and analytics
|
||||
- Fix crash when launching Notesnook from Notification tiles
|
||||
- Fix app crashing on background on boot
|
||||
- Fix self-hosted server urls not working
|
||||
- Bug fixes and small improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -11,6 +11,10 @@ import NetInfo from "@react-native-community/netinfo";
|
||||
import { enableFreeze } from "react-native-screens";
|
||||
import {BackgroundSync} from '../app/services/background-sync';
|
||||
|
||||
BackgroundSync.registerHeadlessTask();
|
||||
BackgroundSync.start();
|
||||
Notifications.init();
|
||||
|
||||
enableFreeze(true);
|
||||
NetInfo.configure({
|
||||
reachabilityUrl: "https://notesnook.com",
|
||||
@@ -19,8 +23,7 @@ NetInfo.configure({
|
||||
return response?.status >= 200 && response?.status < 300;
|
||||
}
|
||||
});
|
||||
BackgroundSync.start();
|
||||
Notifications.init();
|
||||
|
||||
|
||||
const appName = appJson.name;
|
||||
if (Config.isTesting) {
|
||||
|
||||
@@ -1061,7 +1061,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1135,7 +1135,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1166,7 +1166,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1240,7 +1240,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1399,7 +1399,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1411,7 +1411,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1442,7 +1442,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1455,7 +1455,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1485,7 +1485,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1559,7 +1559,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1590,7 +1590,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2112;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1665,7 +1665,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.15;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
12
apps/mobile/package-lock.json
generated
12
apps/mobile/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.15",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.15",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -23811,17 +23811,19 @@
|
||||
"name": "@notesnook/sodium",
|
||||
"version": "2.0.7",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"libsodium-wrappers-sumo": "^0.7.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/libsodium-wrappers-sumo": "0.7.5",
|
||||
"@types/libsodium-wrappers-sumo": "0.7.8",
|
||||
"benny": "^3.7.1",
|
||||
"libsodium-wrappers-sumo": "^0.7.11",
|
||||
"sodium-native": "^4.1.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"vitest": "^0.32.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"libsodium-wrappers-sumo": ">=0.7",
|
||||
"sodium-native": ">=4"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.15",
|
||||
"version": "3.0.17",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
25
apps/theme-builder/package-lock.json
generated
25
apps/theme-builder/package-lock.json
generated
@@ -17,7 +17,7 @@
|
||||
"@notesnook/web": "file:../web",
|
||||
"@theme-ui/components": "^0.14.7",
|
||||
"@theme-ui/core": "^0.14.7",
|
||||
"@trpc/client": "^10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"clipboard-polyfill": "^4.0.0",
|
||||
"file-saver": "^2.0.5",
|
||||
@@ -979,7 +979,7 @@
|
||||
},
|
||||
"../web": {
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.0.13",
|
||||
"version": "3.0.17",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -993,7 +993,7 @@
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.0.0",
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
@@ -1007,13 +1007,14 @@
|
||||
"@notesnook/web-clipper": "file:../../extensions/web-clipper",
|
||||
"@react-pdf-viewer/core": "^3.12.0",
|
||||
"@react-pdf-viewer/toolbar": "^3.12.0",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@tanstack/react-virtual": "^3.0.1",
|
||||
"@theme-ui/color": "^0.16.1",
|
||||
"@theme-ui/components": "^0.16.1",
|
||||
"@theme-ui/core": "^0.16.1",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/react-query": "10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/react-query": "10.45.2",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"async-mutex": "^0.4.0",
|
||||
"axios": "^1.3.4",
|
||||
@@ -1031,8 +1032,6 @@
|
||||
"hash-wasm": "^4.9.0",
|
||||
"hotkeys-js": "^3.8.3",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"libsodium-wrappers": "^0.7.13",
|
||||
"mac-scrollbar": "^0.13.5",
|
||||
"marked": "^4.1.0",
|
||||
"mutative": "^1.0.6",
|
||||
@@ -1068,7 +1067,7 @@
|
||||
"@playwright/test": "^1.43.1",
|
||||
"@swc/core": "^1.5.24",
|
||||
"@swc/plugin-react-remove-properties": "^2.0.4",
|
||||
"@trpc/server": "10.38.3",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/event-source-polyfill": "^1.0.1",
|
||||
"@types/file-saver": "^2.0.5",
|
||||
@@ -2019,14 +2018,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/client": {
|
||||
"version": "10.38.3",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.38.3.tgz",
|
||||
"integrity": "sha512-hHPsElTL4sB+UGzuAZ4iwRVHjELrk/Nsl2owsYw9ITJz3EY7VWRsQ6vK48kJvlHPYPhP+efID5UOgyZMs4bFXA==",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.45.2.tgz",
|
||||
"integrity": "sha512-ykALM5kYWTLn1zYuUOZ2cPWlVfrXhc18HzBDyRhoPYN0jey4iQHEFSEowfnhg1RvYnrAVjNBgHNeSAXjrDbGwg==",
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@trpc/server": "10.38.3"
|
||||
"@trpc/server": "10.45.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"@notesnook/web": "file:../web",
|
||||
"@theme-ui/components": "^0.14.7",
|
||||
"@theme-ui/core": "^0.14.7",
|
||||
"@trpc/client": "^10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"clipboard-polyfill": "^4.0.0",
|
||||
"file-saver": "^2.0.5",
|
||||
|
||||
498
apps/web/package-lock.json
generated
498
apps/web/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.0.0",
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
@@ -34,13 +34,14 @@
|
||||
"@notesnook/web-clipper": "file:../../extensions/web-clipper",
|
||||
"@react-pdf-viewer/core": "^3.12.0",
|
||||
"@react-pdf-viewer/toolbar": "^3.12.0",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@tanstack/react-virtual": "^3.0.1",
|
||||
"@theme-ui/color": "^0.16.1",
|
||||
"@theme-ui/components": "^0.16.1",
|
||||
"@theme-ui/core": "^0.16.1",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/react-query": "10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/react-query": "10.45.2",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"async-mutex": "^0.4.0",
|
||||
"axios": "^1.3.4",
|
||||
@@ -58,8 +59,6 @@
|
||||
"hash-wasm": "^4.9.0",
|
||||
"hotkeys-js": "^3.8.3",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"libsodium-wrappers": "^0.7.13",
|
||||
"mac-scrollbar": "^0.13.5",
|
||||
"marked": "^4.1.0",
|
||||
"mutative": "^1.0.6",
|
||||
@@ -95,7 +94,7 @@
|
||||
"@playwright/test": "^1.43.1",
|
||||
"@swc/core": "^1.5.24",
|
||||
"@swc/plugin-react-remove-properties": "^2.0.4",
|
||||
"@trpc/server": "10.38.3",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/event-source-polyfill": "^1.0.1",
|
||||
"@types/file-saver": "^2.0.5",
|
||||
@@ -137,7 +136,7 @@
|
||||
},
|
||||
"../../extensions/web-clipper": {
|
||||
"name": "@notesnook/web-clipper",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@emotion/react": "11.11.1",
|
||||
@@ -26854,7 +26853,8 @@
|
||||
"@microsoft/signalr": "^8.0.0",
|
||||
"@notesnook/logger": "file:../logger",
|
||||
"@readme/data-urls": "^3.0.0",
|
||||
"@streetwriters/showdown": "^3.0.7-alpha",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@streetwriters/showdown": "^3.0.8-alpha",
|
||||
"async-mutex": "^0.3.2",
|
||||
"dayjs": "1.11.9",
|
||||
"dom-serializer": "^2.0.0",
|
||||
@@ -26865,7 +26865,6 @@
|
||||
"html-to-text": "^9.0.5",
|
||||
"htmlparser2": "^8.0.1",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"linkedom": "^0.14.17",
|
||||
"liqe": "^1.13.0",
|
||||
"mime-db": "1.52.0",
|
||||
@@ -28477,13 +28476,6 @@
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"../../packages/core/node_modules/kysely": {
|
||||
"version": "0.26.3",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"../../packages/core/node_modules/leac": {
|
||||
"version": "0.6.0",
|
||||
"license": "MIT",
|
||||
@@ -29903,70 +29895,76 @@
|
||||
"@notesnook/core": "file:../core",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
"@notesnook/ui": "file:../ui",
|
||||
"@social-embed/lib": "^0.0.2-next.1",
|
||||
"@tiptap/core": "2.2.4",
|
||||
"@tiptap/extension-character-count": "2.2.4",
|
||||
"@tiptap/extension-color": "2.2.4",
|
||||
"@tiptap/extension-font-family": "2.2.4",
|
||||
"@tiptap/extension-history": "2.2.4",
|
||||
"@tiptap/extension-horizontal-rule": "2.2.4",
|
||||
"@tiptap/extension-list-keymap": "2.2.4",
|
||||
"@tiptap/extension-placeholder": "2.2.4",
|
||||
"@tiptap/extension-subscript": "2.2.4",
|
||||
"@tiptap/extension-superscript": "2.2.4",
|
||||
"@tiptap/extension-table": "2.2.4",
|
||||
"@tiptap/extension-table-cell": "2.2.4",
|
||||
"@tiptap/extension-table-header": "2.2.4",
|
||||
"@tiptap/extension-table-row": "2.2.4",
|
||||
"@tiptap/extension-task-item": "2.2.4",
|
||||
"@tiptap/extension-task-list": "2.2.4",
|
||||
"@tiptap/extension-text-align": "2.2.4",
|
||||
"@tiptap/extension-text-style": "2.2.4",
|
||||
"@tiptap/extension-underline": "2.2.4",
|
||||
"@tiptap/pm": "2.2.4",
|
||||
"@tiptap/starter-kit": "2.2.4",
|
||||
"@social-embed/lib": "^0.1.0-next.7",
|
||||
"@tiptap/core": "2.6.6",
|
||||
"@tiptap/extension-blockquote": "^2.6.6",
|
||||
"@tiptap/extension-bullet-list": "^2.6.6",
|
||||
"@tiptap/extension-character-count": "2.6.6",
|
||||
"@tiptap/extension-code": "^2.6.6",
|
||||
"@tiptap/extension-color": "2.6.6",
|
||||
"@tiptap/extension-font-family": "2.6.6",
|
||||
"@tiptap/extension-heading": "^2.6.6",
|
||||
"@tiptap/extension-history": "2.6.6",
|
||||
"@tiptap/extension-horizontal-rule": "2.6.6",
|
||||
"@tiptap/extension-list-item": "^2.6.6",
|
||||
"@tiptap/extension-list-keymap": "2.6.6",
|
||||
"@tiptap/extension-ordered-list": "^2.6.6",
|
||||
"@tiptap/extension-placeholder": "2.6.6",
|
||||
"@tiptap/extension-subscript": "2.6.6",
|
||||
"@tiptap/extension-superscript": "2.6.6",
|
||||
"@tiptap/extension-table": "2.6.6",
|
||||
"@tiptap/extension-table-cell": "2.6.6",
|
||||
"@tiptap/extension-table-header": "2.6.6",
|
||||
"@tiptap/extension-table-row": "2.6.6",
|
||||
"@tiptap/extension-task-item": "2.6.6",
|
||||
"@tiptap/extension-task-list": "2.6.6",
|
||||
"@tiptap/extension-text-align": "2.6.6",
|
||||
"@tiptap/extension-text-style": "2.6.6",
|
||||
"@tiptap/extension-underline": "2.6.6",
|
||||
"@tiptap/pm": "2.6.6",
|
||||
"@tiptap/starter-kit": "2.6.6",
|
||||
"alfaaz": "^1.1.0",
|
||||
"async-mutex": "^0.4.0",
|
||||
"clipboard-polyfill": "4.0.0",
|
||||
"detect-indent": "^7.0.0",
|
||||
"entities": "^4.5.0",
|
||||
"katex": "0.16.9",
|
||||
"async-mutex": "^0.5.0",
|
||||
"clipboard-polyfill": "4.1.0",
|
||||
"detect-indent": "^7.0.1",
|
||||
"entities": "^5.0.0",
|
||||
"katex": "0.16.11",
|
||||
"linkifyjs": "^4.1.3",
|
||||
"nanoid": "^4.0.1",
|
||||
"nanoid": "^5.0.7",
|
||||
"prism-themes": "^1.9.0",
|
||||
"prosemirror-codemark": "^0.4.2",
|
||||
"prosemirror-view": "1.33.1",
|
||||
"re-resizable": "^6.9.11",
|
||||
"prosemirror-view": "1.34.2",
|
||||
"re-resizable": "^6.9.18",
|
||||
"react-colorful": "^5.6.1",
|
||||
"redent": "^4.0.0",
|
||||
"refractor": "^4.8.1",
|
||||
"strip-indent": "^4.0.0",
|
||||
"unfurl.js": "^6.3.2"
|
||||
"unfurl.js": "^6.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/react": "11.11.1",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@emotion/react": "11.13.3",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@theme-ui/components": "^0.16.1",
|
||||
"@theme-ui/core": "^0.16.1",
|
||||
"@types/katex": "^0.14.0",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@types/react": "^18.2.39",
|
||||
"@types/react-color": "^3.0.6",
|
||||
"@types/react-dom": "^18.2.17",
|
||||
"@theme-ui/components": "^0.16.2",
|
||||
"@theme-ui/core": "^0.16.2",
|
||||
"@types/katex": "^0.16.7",
|
||||
"@types/prismjs": "^1.26.4",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-color": "^3.0.12",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-modal": "^3.16.3 ",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"framer-motion": "^10.16.8",
|
||||
"happy-dom": "^8.9.0",
|
||||
"@types/tinycolor2": "^1.4.6",
|
||||
"framer-motion": "^11.5.4",
|
||||
"happy-dom": "^15.7.4",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"prosemirror-test-builder": "^1.1.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"prosemirror-test-builder": "^1.1.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-modal": "3.16.1",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"vitest": "^0.29.2",
|
||||
"web-vitals": "^2.1.4",
|
||||
"zustand": "4.4.7"
|
||||
"vitest": "^2.0.5",
|
||||
"web-vitals": "^4.2.3",
|
||||
"zustand": "4.5.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": ">=11",
|
||||
@@ -33094,17 +33092,19 @@
|
||||
"../../packages/sodium": {
|
||||
"name": "@notesnook/sodium",
|
||||
"version": "2.0.7",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"libsodium-wrappers-sumo": "^0.7.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/libsodium-wrappers-sumo": "0.7.5",
|
||||
"@types/libsodium-wrappers-sumo": "0.7.8",
|
||||
"benny": "^3.7.1",
|
||||
"libsodium-wrappers-sumo": "^0.7.11",
|
||||
"sodium-native": "^4.1.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"vitest": "^0.32.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"libsodium-wrappers-sumo": ">=0.7",
|
||||
"sodium-native": ">=4"
|
||||
}
|
||||
},
|
||||
@@ -33713,12 +33713,10 @@
|
||||
},
|
||||
"../../packages/sodium/node_modules/libsodium-sumo": {
|
||||
"version": "0.7.11",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"../../packages/sodium/node_modules/libsodium-wrappers-sumo": {
|
||||
"version": "0.7.11",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"libsodium-sumo": "^0.7.11"
|
||||
@@ -37729,30 +37727,29 @@
|
||||
},
|
||||
"../desktop": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.13",
|
||||
"version": "3.0.17",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/server": "10.38.3",
|
||||
"better-sqlite3-multiple-ciphers": "^9.5.0",
|
||||
"electron-trpc": "0.5.2",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "^11.2.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.2.1",
|
||||
"icojs": "^0.17.1",
|
||||
"sodium-native": "^4.1.1",
|
||||
"icojs": "^0.19.4",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.6.2",
|
||||
"yargs": "^17.7.2",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.16.1",
|
||||
"@types/yargs": "^17.0.24",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@types/node": "20.14.8",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"chokidar": "^3.5.3",
|
||||
"electron": "^29.3.1",
|
||||
"electron": "^30.4.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"esbuild": "^0.23.0",
|
||||
"kysely": "^0.27.3",
|
||||
"node-abi": "^3.67.0",
|
||||
"node-gyp-build": "^4.8.0",
|
||||
"prebuildify": "^6.0.1",
|
||||
"tree-kill": "^1.2.2",
|
||||
@@ -38137,10 +38134,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"../desktop/node_modules/@notesnook/crypto": {
|
||||
"resolved": "../../packages/crypto",
|
||||
"link": true
|
||||
},
|
||||
"../desktop/node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"dev": true,
|
||||
@@ -39884,14 +39877,6 @@
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"../desktop/node_modules/kysely": {
|
||||
"version": "0.27.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"../desktop/node_modules/lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"license": "MIT"
|
||||
@@ -40061,6 +40046,7 @@
|
||||
},
|
||||
"../desktop/node_modules/node-gyp-build": {
|
||||
"version": "4.8.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
@@ -40582,14 +40568,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"../desktop/node_modules/sodium-native": {
|
||||
"version": "4.1.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-gyp-build": "^4.8.0"
|
||||
}
|
||||
},
|
||||
"../desktop/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"dev": true,
|
||||
@@ -41038,54 +41016,69 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-browser": {
|
||||
"version": "3.6.0",
|
||||
"license": "MIT",
|
||||
"version": "3.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.23.0.tgz",
|
||||
"integrity": "sha512-+QgdMvaeEpdtgRTD7AHHq9aw8uga7mXVHV1KshO1RQ2uI5B55xJ4aEpGlg/ga3H+0arEVcRfT4ZVmX7QLXiCVw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "14.5.0"
|
||||
"@azure/msal-common": "14.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-common": {
|
||||
"version": "14.5.0",
|
||||
"license": "MIT",
|
||||
"version": "14.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.14.2.tgz",
|
||||
"integrity": "sha512-XV0P5kSNwDwCA/SjIxTe9mEAsKB0NqGNSuaVrkCCE2lAyBr/D6YtD80Vkdp4tjWnPFwjzkwldjr1xU/facOJog==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node": {
|
||||
"version": "2.6.0",
|
||||
"license": "MIT",
|
||||
"version": "2.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.13.1.tgz",
|
||||
"integrity": "sha512-sijfzPNorKt6+9g1/miHwhj6Iapff4mPQx1azmmZExgzUROqWTM1o3ACyxDja0g47VpowFy/sxTM/WsuCyXTiw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "14.5.0",
|
||||
"@azure/msal-common": "14.14.2",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"uuid": "^8.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16|| 18 || 20"
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node-extensions": {
|
||||
"version": "1.0.8",
|
||||
"license": "MIT",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node-extensions/-/msal-node-extensions-1.1.0.tgz",
|
||||
"integrity": "sha512-tn4ULOjUb7FRI1KMTBnS3kflcV0oI3xdG0b0IEhOufmxhQAGs5hIaugE+HxvNw4y7ceFpOm7r6zzzrTj0NFtvg==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "14.5.0",
|
||||
"@azure/msal-common": "14.14.0",
|
||||
"@azure/msal-node-runtime": "^0.13.6-alpha.0",
|
||||
"keytar": "^7.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16 || 18 || 20"
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node-extensions/node_modules/@azure/msal-common": {
|
||||
"version": "14.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.14.0.tgz",
|
||||
"integrity": "sha512-OxcOk9H1/1fktHh6//VCORgSNJc2dCQObTm6JNmL824Z6iZSO6eFo/Bttxe0hETn9B+cr7gDouTQtsRq3YPuSQ==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node-runtime": {
|
||||
"version": "0.13.6-alpha.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node-runtime/-/msal-node-runtime-0.13.6-alpha.0.tgz",
|
||||
"integrity": "sha512-Tu5e4wBFiaiBLrOu7bsJF7FYknFH9XIOvUyCqCnmLJFMMOUnYULZ7fOFYuintFFcNPMOT2u8BVfSCPxETri5ng==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@@ -43047,7 +43040,8 @@
|
||||
},
|
||||
"node_modules/@microsoft/microsoft-graph-client": {
|
||||
"version": "3.0.7",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/microsoft-graph-client/-/microsoft-graph-client-3.0.7.tgz",
|
||||
"integrity": "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"tslib": "^2.2.0"
|
||||
@@ -43103,14 +43097,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/core": {
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/core/-/core-2.1.1.tgz",
|
||||
"integrity": "sha512-aVCvRPLQCwCzhqJ9/MZ4HtT8xtRGPS+JY5/pJD27ggEhzyF9OOd+AT9ugf7w2lpbTIP8f/3Nsn/CXiCJgDO98w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/enex": "^1.7.0",
|
||||
"@notesnook-importer/onenote": "^1.7.0",
|
||||
"@notesnook-importer/storage": "^1.7.0",
|
||||
"@notesnook-importer/znel": "^1.7.0",
|
||||
"@notesnook-importer/enex": "^1.8.1",
|
||||
"@notesnook-importer/onenote": "^1.8.1",
|
||||
"@notesnook-importer/storage": "^1.8.1",
|
||||
"@notesnook-importer/znel": "^1.8.1",
|
||||
"@skiff-org/skiff-crypto": "^1.0.3",
|
||||
"@stablelib/chacha20poly1305": "^1.0.1",
|
||||
"@standardnotes/features": "1.58.0",
|
||||
"@standardnotes/models": "1.42.0",
|
||||
"@streamparser/json": "^0.0.10",
|
||||
@@ -43124,6 +43121,7 @@
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-is-element": "^2.1.3",
|
||||
"htmlparser2": "^8.0.1",
|
||||
"magic-bytes.js": "^1.8.0",
|
||||
"rehype-stringify": "^9.0.3",
|
||||
"remark": "^14.0.3",
|
||||
"remark-comments": "^1.2.9",
|
||||
@@ -43133,7 +43131,8 @@
|
||||
"remark-supersub": "^1.0.0",
|
||||
"spark-md5": "^3.0.2",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/core/node_modules/fflate": {
|
||||
@@ -43141,8 +43140,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@notesnook-importer/enex": {
|
||||
"version": "1.7.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/enex/-/enex-1.8.1.tgz",
|
||||
"integrity": "sha512-k+DzJQPr/79rKg0hnml/ZHS9PX/4vm/ndOfF6PLdTBJsoAVgYhEOkroSwm8oA6V1j9Bn1Ew/7jpssKoUGqebsg==",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1",
|
||||
"css-select": "^5.1.0",
|
||||
@@ -43154,8 +43154,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/onenote": {
|
||||
"version": "1.7.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/onenote/-/onenote-1.8.1.tgz",
|
||||
"integrity": "sha512-4xTPNHn9E/Fb5BnpqLghNLporgyHNOJTitzdJwBvNWAfomfS/limFPYNyfwYRFbX/Uq1drSKzdv0uAvq8/dhiQ==",
|
||||
"dependencies": {
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
"css-select": "^5.1.0",
|
||||
@@ -43173,22 +43174,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/onenote/node_modules/dotenv": {
|
||||
"version": "16.3.1",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "16.4.5",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
||||
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/motdotla/dotenv?sponsor=1"
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/@notesnook-importer/storage": {
|
||||
"version": "1.7.0",
|
||||
"license": "GPL-3.0-or-later"
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/storage/-/storage-1.8.1.tgz",
|
||||
"integrity": "sha512-/IFBI+yZHQOvD+vPLcKvixhbS9TJ4pfQcCkl3WvWZWDwHDYhkSL2Yf2bIgayPxjXWL/U8089tJt8hzWGmsecfw=="
|
||||
},
|
||||
"node_modules/@notesnook-importer/znel": {
|
||||
"version": "1.7.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@notesnook-importer/znel/-/znel-1.8.1.tgz",
|
||||
"integrity": "sha512-YkbDfzWREN/HW/Cg6cnZk4eajVEyMdMpxbF3qn2R5YaLWl8Rffa5bm1d/QlGf8u2XL6dyT9Q1tQ5MJ4umKfJvQ==",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1",
|
||||
"css-select": "^5.1.0",
|
||||
@@ -43570,6 +43574,100 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@skiff-org/skiff-crypto": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@skiff-org/skiff-crypto/-/skiff-crypto-1.0.3.tgz",
|
||||
"integrity": "sha512-SGHUUo+hLqkyjirX1/ucJIZBVPloV3BYIntIIIKpIe8gfyAVi7rfQ3X6NDer/rf3yUA8YPHPxvedhh8/SWUHzg==",
|
||||
"dependencies": {
|
||||
"@stablelib/chacha20poly1305": "^1.0.1",
|
||||
"argon2-browser": "^1.18.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"buffer": "^6.0.3",
|
||||
"fflate": "^0.7.3",
|
||||
"futoin-hkdf": "^1.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"randombytes": "^2.1.0",
|
||||
"semver": "^7.3.4",
|
||||
"tslib": "^2.4.0",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"varint": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@skiff-org/skiff-crypto/node_modules/fflate": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
|
||||
"integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw=="
|
||||
},
|
||||
"node_modules/@skiff-org/skiff-crypto/node_modules/semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/aead": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/aead/-/aead-1.0.1.tgz",
|
||||
"integrity": "sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg=="
|
||||
},
|
||||
"node_modules/@stablelib/binary": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz",
|
||||
"integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==",
|
||||
"dependencies": {
|
||||
"@stablelib/int": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/chacha": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/chacha/-/chacha-1.0.1.tgz",
|
||||
"integrity": "sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==",
|
||||
"dependencies": {
|
||||
"@stablelib/binary": "^1.0.1",
|
||||
"@stablelib/wipe": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/chacha20poly1305": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz",
|
||||
"integrity": "sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==",
|
||||
"dependencies": {
|
||||
"@stablelib/aead": "^1.0.1",
|
||||
"@stablelib/binary": "^1.0.1",
|
||||
"@stablelib/chacha": "^1.0.1",
|
||||
"@stablelib/constant-time": "^1.0.1",
|
||||
"@stablelib/poly1305": "^1.0.1",
|
||||
"@stablelib/wipe": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/constant-time/-/constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg=="
|
||||
},
|
||||
"node_modules/@stablelib/int": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz",
|
||||
"integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w=="
|
||||
},
|
||||
"node_modules/@stablelib/poly1305": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/poly1305/-/poly1305-1.0.1.tgz",
|
||||
"integrity": "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==",
|
||||
"dependencies": {
|
||||
"@stablelib/constant-time": "^1.0.1",
|
||||
"@stablelib/wipe": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@stablelib/wipe": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz",
|
||||
"integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg=="
|
||||
},
|
||||
"node_modules/@standardnotes/auth": {
|
||||
"version": "3.19.4",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
@@ -43653,6 +43751,14 @@
|
||||
"version": "0.0.10",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@streetwriters/kysely": {
|
||||
"version": "0.27.4",
|
||||
"resolved": "https://registry.npmjs.org/@streetwriters/kysely/-/kysely-0.27.4.tgz",
|
||||
"integrity": "sha512-c2p+wtX8WESSVjJAc16j4lT44w/g1DvJFEIeKj/CFy36vmi0uq9FOAzxc50VtRc7rp0UlECCfl3Sxd+BTZOHFg==",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@styled-system/background": {
|
||||
"version": "5.1.2",
|
||||
"license": "MIT",
|
||||
@@ -44223,36 +44329,39 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/client": {
|
||||
"version": "10.38.3",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.45.2.tgz",
|
||||
"integrity": "sha512-ykALM5kYWTLn1zYuUOZ2cPWlVfrXhc18HzBDyRhoPYN0jey4iQHEFSEowfnhg1RvYnrAVjNBgHNeSAXjrDbGwg==",
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@trpc/server": "10.38.3"
|
||||
"@trpc/server": "10.45.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/react-query": {
|
||||
"version": "10.38.3",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/react-query/-/react-query-10.45.2.tgz",
|
||||
"integrity": "sha512-BAqb9bGZIscroradlNx+Cc9522R+idY3BOSf5z0jHUtkxdMbjeGKxSSMxxu7JzoLqSIEC+LVzL3VvF8sdDWaZQ==",
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@tanstack/react-query": "^4.18.0",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/server": "10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@trpc/server": {
|
||||
"version": "10.38.3",
|
||||
"version": "10.45.2",
|
||||
"resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.45.2.tgz",
|
||||
"integrity": "sha512-wOrSThNNE4HUnuhJG6PfDRp4L2009KDVxsd+2VYH8ro6o/7/jwYZ8Uu5j+VaW+mOmc8EHerHzGcdbGNQSAUPgg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
"https://trpc.io/sponsor"
|
||||
],
|
||||
"license": "MIT"
|
||||
]
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.4",
|
||||
@@ -44647,6 +44756,11 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/argon2-browser": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/argon2-browser/-/argon2-browser-1.18.0.tgz",
|
||||
"integrity": "sha512-ImVAGIItnFnvET1exhsQB7apRztcoC5TnlSqernMJDUjbc/DLq3UEYeXFrLPrlaIl8cVfwnXb6wX2KpFf2zxHw=="
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "1.0.10",
|
||||
"license": "MIT",
|
||||
@@ -44926,7 +45040,8 @@
|
||||
},
|
||||
"node_modules/boolbase": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
@@ -44980,7 +45095,6 @@
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -45334,7 +45448,8 @@
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "5.1.0",
|
||||
"license": "BSD-2-Clause",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0",
|
||||
"css-what": "^6.1.0",
|
||||
@@ -45348,7 +45463,8 @@
|
||||
},
|
||||
"node_modules/css-what": {
|
||||
"version": "6.1.0",
|
||||
"license": "BSD-2-Clause",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
|
||||
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
@@ -46310,6 +46426,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/futoin-hkdf": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.5.3.tgz",
|
||||
"integrity": "sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "3.0.2",
|
||||
"license": "ISC",
|
||||
@@ -46745,6 +46869,8 @@
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
@@ -46752,7 +46878,6 @@
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
@@ -46798,7 +46923,6 @@
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"devOptional": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -47223,7 +47347,8 @@
|
||||
},
|
||||
"node_modules/isomorphic-fetch": {
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
|
||||
"integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.1",
|
||||
"whatwg-fetch": "^3.4.1"
|
||||
@@ -47392,8 +47517,9 @@
|
||||
},
|
||||
"node_modules/keytar": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
|
||||
"integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^4.3.0",
|
||||
@@ -47414,13 +47540,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/kysely": {
|
||||
"version": "0.26.3",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/leven": {
|
||||
"version": "3.1.0",
|
||||
"dev": true,
|
||||
@@ -47429,17 +47548,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/libsodium": {
|
||||
"version": "0.7.13",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/libsodium-wrappers": {
|
||||
"version": "0.7.13",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"libsodium": "^0.7.13"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"license": "MIT"
|
||||
@@ -47474,7 +47582,6 @@
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
@@ -47586,6 +47693,11 @@
|
||||
"version": "0.13.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-bytes.js": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
|
||||
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.10",
|
||||
"dev": true,
|
||||
@@ -48634,7 +48746,8 @@
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "4.3.0",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
|
||||
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
@@ -48719,7 +48832,8 @@
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"license": "BSD-2-Clause",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
|
||||
"dependencies": {
|
||||
"boolbase": "^1.0.0"
|
||||
},
|
||||
@@ -49190,7 +49304,6 @@
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
@@ -50060,7 +50173,8 @@
|
||||
},
|
||||
"node_modules/spark-md5": {
|
||||
"version": "3.0.2",
|
||||
"license": "(WTFPL OR MIT)"
|
||||
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
||||
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
@@ -50502,6 +50616,11 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
|
||||
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
|
||||
},
|
||||
"node_modules/type-detect": {
|
||||
"version": "4.0.8",
|
||||
"dev": true,
|
||||
@@ -50819,7 +50938,8 @@
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
@@ -50841,6 +50961,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/varint": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
|
||||
"integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
|
||||
},
|
||||
"node_modules/vfile": {
|
||||
"version": "5.3.7",
|
||||
"license": "MIT",
|
||||
@@ -51124,7 +51249,8 @@
|
||||
},
|
||||
"node_modules/whatwg-fetch": {
|
||||
"version": "3.6.20",
|
||||
"license": "MIT"
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
|
||||
"integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="
|
||||
},
|
||||
"node_modules/whatwg-mimetype": {
|
||||
"version": "3.0.0",
|
||||
@@ -51673,6 +51799,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "4.4.7",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.14",
|
||||
"version": "3.0.17",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
@@ -18,7 +18,7 @@
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.0.0",
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
@@ -32,13 +32,13 @@
|
||||
"@notesnook/web-clipper": "file:../../extensions/web-clipper",
|
||||
"@react-pdf-viewer/core": "^3.12.0",
|
||||
"@react-pdf-viewer/toolbar": "^3.12.0",
|
||||
"@tanstack/react-query": "^4.29.19",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@tanstack/react-virtual": "^3.0.1",
|
||||
"@theme-ui/color": "^0.16.1",
|
||||
"@theme-ui/components": "^0.16.1",
|
||||
"@theme-ui/core": "^0.16.1",
|
||||
"@trpc/client": "10.38.3",
|
||||
"@trpc/react-query": "10.38.3",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/react-query": "10.45.2",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"async-mutex": "^0.4.0",
|
||||
"axios": "^1.3.4",
|
||||
@@ -56,8 +56,7 @@
|
||||
"hash-wasm": "^4.9.0",
|
||||
"hotkeys-js": "^3.8.3",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"libsodium-wrappers": "^0.7.13",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"mac-scrollbar": "^0.13.5",
|
||||
"marked": "^4.1.0",
|
||||
"mutative": "^1.0.6",
|
||||
@@ -93,7 +92,7 @@
|
||||
"@playwright/test": "^1.43.1",
|
||||
"@swc/core": "^1.5.24",
|
||||
"@swc/plugin-react-remove-properties": "^2.0.4",
|
||||
"@trpc/server": "10.38.3",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/event-source-polyfill": "^1.0.1",
|
||||
"@types/file-saver": "^2.0.5",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -116,12 +116,10 @@ export async function checkAttachment(hash: string) {
|
||||
if (!attachment) return { failed: "Attachment not found." };
|
||||
|
||||
try {
|
||||
const size = await lazify(
|
||||
import("../interfaces/fs"),
|
||||
({ getUploadedFileSize }) => getUploadedFileSize(hash)
|
||||
await lazify(import("../interfaces/fs"), ({ checkUpload }) =>
|
||||
checkUpload(hash, attachment.chunkSize, attachment.size)
|
||||
);
|
||||
if (size === 0) throw new Error("File length is 0.");
|
||||
else if (size === -1) throw new Error("File verification check failed.");
|
||||
await db.attachments.markAsFailed(attachment.id);
|
||||
} catch (e) {
|
||||
const reason = e instanceof Error ? e.message : "Unknown error.";
|
||||
await db.attachments.markAsFailed(attachment.id, reason);
|
||||
|
||||
@@ -21,6 +21,8 @@ import { store as noteStore } from "../stores/note-store";
|
||||
import { store as notebookStore } from "../stores/notebook-store";
|
||||
import { store as attachmentStore } from "../stores/attachment-store";
|
||||
import { store as reminderStore } from "../stores/reminder-store";
|
||||
import { store as tagStore } from "../stores/tag-store";
|
||||
import { store as appStore } from "../stores/app-store";
|
||||
import { db } from "./db";
|
||||
import { showToast } from "../utils/toast";
|
||||
import Vault from "./vault";
|
||||
@@ -59,6 +61,8 @@ async function moveNotesToTrash(ids: string[], confirm = true) {
|
||||
}
|
||||
|
||||
async function moveNotebooksToTrash(ids: string[]) {
|
||||
if (!ids.length) return;
|
||||
|
||||
const isMultiselect = ids.length > 1;
|
||||
if (isMultiselect) {
|
||||
if (!(await showMultiDeleteConfirmation(ids.length))) return;
|
||||
@@ -134,9 +138,42 @@ async function moveRemindersToTrash(ids: string[]) {
|
||||
showToast("success", `${pluralize(ids.length, "reminder")} deleted.`);
|
||||
}
|
||||
|
||||
async function deleteTags(ids: string[]) {
|
||||
if (
|
||||
!(await ConfirmDialog.show({
|
||||
title: "Are you sure?",
|
||||
message:
|
||||
"Are you sure you want to permanently delete these tags? This action is IRREVERSIBLE.",
|
||||
negativeButtonText: "No",
|
||||
positiveButtonText: "Yes"
|
||||
}))
|
||||
)
|
||||
return;
|
||||
|
||||
await TaskManager.startTask({
|
||||
type: "status",
|
||||
id: "deleteTags",
|
||||
title: "Deleting tags",
|
||||
action: async (report) => {
|
||||
report({
|
||||
text: `Deleting ${pluralize(ids.length, "tag")}...`
|
||||
});
|
||||
for (const id of ids) {
|
||||
await db.tags.remove(id);
|
||||
}
|
||||
await appStore.refreshNavItems();
|
||||
await tagStore.refresh();
|
||||
await noteStore.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
showToast("success", `${pluralize(ids.length, "tag")} deleted.`);
|
||||
}
|
||||
|
||||
export const Multiselect = {
|
||||
moveRemindersToTrash,
|
||||
moveNotebooksToTrash,
|
||||
moveNotesToTrash,
|
||||
deleteAttachments
|
||||
deleteAttachments,
|
||||
deleteTags
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
QueryResult,
|
||||
CompiledQuery,
|
||||
Driver
|
||||
} from "kysely";
|
||||
} from "@streetwriters/kysely";
|
||||
import { desktop } from "../desktop-bridge";
|
||||
import Worker from "./sqlite.worker.desktop.ts?worker";
|
||||
import type { SQLiteWorker } from "./sqlite.worker.desktop";
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
SqliteQueryCompiler,
|
||||
SqliteIntrospector,
|
||||
Dialect
|
||||
} from "kysely";
|
||||
} from "@streetwriters/kysely";
|
||||
import {
|
||||
WaSqliteWorkerMultipleTabDriver,
|
||||
WaSqliteWorkerSingleTabDriver
|
||||
|
||||
@@ -21,7 +21,7 @@ import type { SQLiteAPI, SQLiteCompatibleType } from "./sqlite-types";
|
||||
import { Factory, SQLITE_ROW, SQLiteError } from "./sqlite-api";
|
||||
import { expose, transfer } from "comlink";
|
||||
import type { RunMode } from "./type";
|
||||
import { QueryResult } from "kysely";
|
||||
import { QueryResult } from "@streetwriters/kysely";
|
||||
import { DatabaseSource } from "./sqlite-export";
|
||||
import { createSharedServicePort } from "./shared-service";
|
||||
import type { IDBBatchAtomicVFS } from "./IDBBatchAtomicVFS";
|
||||
|
||||
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { QueryResult } from "kysely";
|
||||
import type { QueryResult } from "@streetwriters/kysely";
|
||||
|
||||
export type Promisable<T> = T | Promise<T>;
|
||||
|
||||
|
||||
@@ -17,8 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { DatabaseConnection, Driver, QueryResult } from "kysely";
|
||||
import { CompiledQuery } from "kysely";
|
||||
import type {
|
||||
DatabaseConnection,
|
||||
Driver,
|
||||
QueryResult
|
||||
} from "@streetwriters/kysely";
|
||||
import { CompiledQuery } from "@streetwriters/kysely";
|
||||
import Worker from "./sqlite.worker.ts?worker";
|
||||
import type { SQLiteWorker } from "./sqlite.worker";
|
||||
import SQLiteSyncURI from "./wa-sqlite.wasm?url";
|
||||
|
||||
@@ -29,12 +29,22 @@ export type AccordionProps = {
|
||||
testId?: string;
|
||||
buttonSx?: FlexProps["sx"];
|
||||
titleSx?: FlexProps["sx"];
|
||||
containerSx?: FlexProps["sx"];
|
||||
};
|
||||
|
||||
export default function Accordion(
|
||||
props: PropsWithChildren<AccordionProps> & FlexProps
|
||||
) {
|
||||
const { isClosed, title, color, children, testId, sx, ...restProps } = props;
|
||||
const {
|
||||
isClosed,
|
||||
title,
|
||||
color,
|
||||
children,
|
||||
testId,
|
||||
sx,
|
||||
containerSx,
|
||||
...restProps
|
||||
} = props;
|
||||
const [isContentHidden, setIsContentHidden] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -69,8 +79,9 @@ export default function Accordion(
|
||||
</Flex>
|
||||
<Flex
|
||||
sx={{
|
||||
display: isContentHidden ? "none" : "flex",
|
||||
flexDirection: "column"
|
||||
flexDirection: "column",
|
||||
...containerSx,
|
||||
display: isContentHidden ? "none" : "flex"
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -57,6 +57,7 @@ import { Attachment as AttachmentType } from "@notesnook/core";
|
||||
import { useEditorStore } from "../../stores/editor-store";
|
||||
import { PromptDialog } from "../../dialogs/prompt";
|
||||
import { DialogManager } from "../../common/dialog-manager";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
|
||||
const FILE_ICONS: Record<string, Icon> = {
|
||||
"image/": FileImage,
|
||||
@@ -135,6 +136,13 @@ export function Attachment({
|
||||
Menu.openMenu(AttachmentMenuItems(item, status));
|
||||
}}
|
||||
onClick={onSelected}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await Multiselect.deleteAttachments(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
style={style}
|
||||
ref={rowRef}
|
||||
>
|
||||
|
||||
@@ -18,13 +18,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { Box, Flex, Image, Link, Text } from "@theme-ui/components";
|
||||
import { useStore as useThemeStore } from "../../stores/theme-store";
|
||||
import { getRandom } from "@notesnook/common";
|
||||
import { Box, Button, Flex, Image, Link, Text } from "@theme-ui/components";
|
||||
import { getRandom, usePromise } from "@notesnook/common";
|
||||
import Grberk from "../../assets/testimonials/grberk.jpeg";
|
||||
import Holenstein from "../../assets/testimonials/holenstein.jpg";
|
||||
import Jason from "../../assets/testimonials/jason.jpg";
|
||||
import Cameron from "../../assets/testimonials/cameron.jpg";
|
||||
import hosts from "@notesnook/core/dist/utils/constants";
|
||||
import { SettingsDialog } from "../../dialogs/settings";
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
@@ -74,10 +75,16 @@ function randomTitle() {
|
||||
}
|
||||
|
||||
function AuthContainer(props) {
|
||||
const colorScheme = useThemeStore((store) => store.colorScheme);
|
||||
const testimonial = useMemo(() => randomTestimonial(), []);
|
||||
const title = useMemo(() => randomTitle(), []);
|
||||
|
||||
const version = usePromise(
|
||||
async () =>
|
||||
await fetch(`${hosts.API_HOST}/version`)
|
||||
.then((r) => r.json())
|
||||
.catch(() => undefined)
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
@@ -165,7 +172,6 @@ function AuthContainer(props) {
|
||||
<Text variant={"heading"} sx={{ fontSize: 48 }}>
|
||||
{title}
|
||||
</Text>
|
||||
|
||||
<Text
|
||||
variant="body"
|
||||
mt={10}
|
||||
@@ -193,6 +199,34 @@ function AuthContainer(props) {
|
||||
<Text variant="subBody">@{testimonial.username}</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Flex
|
||||
mt={2}
|
||||
pt={2}
|
||||
sx={{
|
||||
justifyContent: "space-between",
|
||||
borderTop: "1px solid var(--border)",
|
||||
width: "100%"
|
||||
}}
|
||||
>
|
||||
<Text variant={"subBody"}>
|
||||
{version.status === "fulfilled" &&
|
||||
version.value.instance !== "default" ? (
|
||||
<>
|
||||
Using{" "}
|
||||
{version.value.instance + ` (v${version.value.version})`}
|
||||
</>
|
||||
) : (
|
||||
<>Using official Notesnook instance.</>
|
||||
)}
|
||||
</Text>
|
||||
<Button
|
||||
variant="anchor"
|
||||
onClick={() => SettingsDialog.show({ activeSection: "servers" })}
|
||||
>
|
||||
Configure
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
<Flex
|
||||
|
||||
@@ -50,6 +50,7 @@ function Header(props: HeaderProps) {
|
||||
const id =
|
||||
(await db.tags.find(value))?.id ??
|
||||
(await db.tags.add({ title: value }));
|
||||
if (!id) return;
|
||||
await db.relations.add({ id, type: "tag" }, { type: "note", id: noteId });
|
||||
await useTagStore.getState().refresh();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ export function GlobalErrorHandler(props: PropsWithChildren) {
|
||||
showBoundary(e.error || error);
|
||||
}
|
||||
function handleUnhandledRejection(e: PromiseRejectionEvent) {
|
||||
if (
|
||||
e.reason instanceof TypeError &&
|
||||
e.reason.message === "Error in input stream"
|
||||
)
|
||||
return;
|
||||
showBoundary(e.reason);
|
||||
}
|
||||
window.addEventListener("unhandledrejection", handleUnhandledRejection);
|
||||
|
||||
@@ -215,7 +215,8 @@ import {
|
||||
mdiWindowClose,
|
||||
mdiFileMusicOutline,
|
||||
mdiBroom,
|
||||
mdiServerSecurity
|
||||
mdiServerSecurity,
|
||||
mdiOpenInNew
|
||||
} from "@mdi/js";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Theme } from "@notesnook/theme";
|
||||
@@ -552,3 +553,4 @@ export const WindowRestore = createIcon(
|
||||
);
|
||||
export const WindowClose = createIcon(mdiWindowClose);
|
||||
export const ClearCache = createIcon(mdiBroom);
|
||||
export const OpenInNew = createIcon(mdiOpenInNew);
|
||||
|
||||
@@ -50,7 +50,8 @@ import {
|
||||
RemoveShortcutLink,
|
||||
Plus,
|
||||
Copy,
|
||||
Tag as TagIcon
|
||||
Tag as TagIcon,
|
||||
OpenInNew
|
||||
} from "../icons";
|
||||
import TimeAgo from "../time-ago";
|
||||
import ListItem from "../list-item";
|
||||
@@ -132,8 +133,9 @@ function Note(props: NoteProps) {
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
// @ts-expect-error write tests for this
|
||||
const selectedItems = selectionStore.get().selectedItems;
|
||||
await Multiselect.moveNotesToTrash([item.id, ...selectedItems]);
|
||||
await Multiselect.moveNotesToTrash(
|
||||
selectionStore.get().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
colors={{
|
||||
@@ -430,17 +432,53 @@ const menuItems: (
|
||||
{
|
||||
type: "button",
|
||||
key: "publish",
|
||||
isDisabled:
|
||||
//!isSynced ||
|
||||
!db.monographs.isPublished(note.id) && context?.locked,
|
||||
isDisabled: !db.monographs.isPublished(note.id) && context?.locked,
|
||||
icon: Publish.path,
|
||||
title: "Publish",
|
||||
isChecked: db.monographs.isPublished(note.id),
|
||||
onClick: async () => {
|
||||
const isPublished = db.monographs.isPublished(note.id);
|
||||
if (isPublished) await useMonographStore.getState().unpublish(note.id);
|
||||
else await showPublishView(note, "bottom");
|
||||
}
|
||||
menu: db.monographs.isPublished(note.id)
|
||||
? {
|
||||
items: [
|
||||
{
|
||||
type: "button",
|
||||
key: "open",
|
||||
title: "Open",
|
||||
icon: OpenInNew.path,
|
||||
onClick: async () => {
|
||||
const url = `https://monogr.ph/${note.id}`;
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "button",
|
||||
key: "copy-link",
|
||||
title: "Copy link",
|
||||
icon: Copy.path,
|
||||
onClick: async () => {
|
||||
const url = `https://monogr.ph/${note.id}`;
|
||||
await writeToClipboard({
|
||||
"text/plain": url,
|
||||
"text/html": `<a href="${url}">${note.title}</a>`,
|
||||
"text/markdown": `[${note.title}](${url})`
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
key: "sep"
|
||||
},
|
||||
{
|
||||
type: "button",
|
||||
key: "unpublish",
|
||||
title: "Unpublish",
|
||||
icon: Publish.path,
|
||||
onClick: async () => {
|
||||
await useMonographStore.getState().unpublish(note.id);
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
: undefined,
|
||||
onClick: () => showPublishView(note, "bottom")
|
||||
},
|
||||
{
|
||||
type: "button",
|
||||
|
||||
@@ -44,6 +44,7 @@ import { Notebook as NotebookType } from "@notesnook/core";
|
||||
import { handleDrop } from "../../common/drop-handler";
|
||||
import { useDragHandler } from "../../hooks/use-drag-handler";
|
||||
import { ConfirmDialog } from "../../dialogs/confirm";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
|
||||
type NotebookProps = {
|
||||
item: NotebookType;
|
||||
@@ -80,6 +81,13 @@ function Notebook(props: NotebookProps) {
|
||||
|
||||
handleDrop(e.dataTransfer, notebook);
|
||||
}}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await Multiselect.moveNotebooksToTrash(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
title={notebook.title}
|
||||
body={notebook.description as string}
|
||||
menuItems={notebookMenuItems}
|
||||
|
||||
@@ -43,6 +43,7 @@ import { MenuItem } from "@notesnook/ui";
|
||||
import { Reminder as ReminderType } from "@notesnook/core/dist/types";
|
||||
import { ConfirmDialog } from "../../dialogs/confirm";
|
||||
import { EditReminderDialog } from "../../dialogs/add-reminder-dialog";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
|
||||
const RECURRING_MODE_MAP = {
|
||||
week: "Weekly",
|
||||
@@ -74,6 +75,13 @@ function Reminder(props: ReminderProps) {
|
||||
isDisabled={reminder.disabled}
|
||||
isCompact={compact}
|
||||
onClick={() => EditReminderDialog.show({ reminderId: reminder.id })}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await Multiselect.moveRemindersToTrash(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
footer={
|
||||
<Flex
|
||||
sx={{
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
Update,
|
||||
SyncError,
|
||||
Alert,
|
||||
Issue,
|
||||
SyncOff,
|
||||
Icon
|
||||
} from "../icons";
|
||||
@@ -40,7 +39,6 @@ import { checkForUpdate, installUpdate } from "../../utils/updater";
|
||||
import { getTimeAgo, toTitleCase } from "@notesnook/common";
|
||||
import { User } from "@notesnook/core";
|
||||
import { showUpdateAvailableNotice } from "../../dialogs/confirm";
|
||||
import { IssueDialog } from "../../dialogs/issue-dialog";
|
||||
|
||||
function StatusBar() {
|
||||
const user = useUserStore((state) => state.user);
|
||||
|
||||
@@ -29,6 +29,8 @@ import { useCallback, useRef } from "react";
|
||||
import { handleDrop } from "../../common/drop-handler";
|
||||
import { useDragHandler } from "../../hooks/use-drag-handler";
|
||||
import { AddNotebookDialog } from "../../dialogs/add-notebook-dialog";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
import { Multiselect } from "../../common/multi-select";
|
||||
|
||||
type SubNotebookProps = {
|
||||
item: Notebook;
|
||||
@@ -112,6 +114,11 @@ function SubNotebook(props: SubNotebookProps) {
|
||||
});
|
||||
navigate(`/notebooks/${rootId}/${item.id}`);
|
||||
}
|
||||
} else if (e.code === "Delete") {
|
||||
console.log("Delete", useSelectionStore.getState().selectedItems);
|
||||
await Multiselect.moveNotebooksToTrash(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
title={
|
||||
|
||||
@@ -21,16 +21,14 @@ import ListItem from "../list-item";
|
||||
import { navigate } from "../../navigation";
|
||||
import { Text } from "@theme-ui/components";
|
||||
import { store as appStore } from "../../stores/app-store";
|
||||
import { store as tagStore } from "../../stores/tag-store";
|
||||
import { store as noteStore } from "../../stores/note-store";
|
||||
import { db } from "../../common/db";
|
||||
import { Edit, Shortcut, DeleteForver } from "../icons";
|
||||
import { showToast } from "../../utils/toast";
|
||||
import { pluralize } from "@notesnook/common";
|
||||
import { MenuItem } from "@notesnook/ui";
|
||||
import { Tag as TagType } from "@notesnook/core";
|
||||
import { handleDrop } from "../../common/drop-handler";
|
||||
import { EditTagDialog } from "../../dialogs/item-dialog";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
import { Multiselect } from "../../common/multi-select";
|
||||
|
||||
type TagProps = { item: TagType; totalNotes: number };
|
||||
function Tag(props: TagProps) {
|
||||
@@ -54,6 +52,13 @@ function Tag(props: TagProps) {
|
||||
{totalNotes}
|
||||
</Text>
|
||||
}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await Multiselect.deleteTags(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
menuItems={menuItems}
|
||||
onClick={() => {
|
||||
navigate(`/tags/${id}`);
|
||||
@@ -96,11 +101,7 @@ const menuItems: (tag: TagType, ids?: string[]) => MenuItem[] = (
|
||||
title: "Delete",
|
||||
icon: DeleteForver.path,
|
||||
onClick: async () => {
|
||||
await db.tags.remove(...ids);
|
||||
showToast("success", `${pluralize(ids.length, "tag")} deleted`);
|
||||
await appStore.refreshNavItems();
|
||||
await tagStore.refresh();
|
||||
await noteStore.refresh();
|
||||
await Multiselect.deleteTags(ids);
|
||||
},
|
||||
multiSelect: true
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import { MenuItem } from "@notesnook/ui";
|
||||
import { TrashItem as TrashItemType } from "@notesnook/core/dist/types";
|
||||
import { useEditorStore } from "../../stores/editor-store";
|
||||
import { showMultiPermanentDeleteConfirmation } from "../../dialogs/confirm";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
|
||||
type TrashItemProps = { item: TrashItemType; date: number };
|
||||
function TrashItem(props: TrashItemProps) {
|
||||
@@ -40,6 +41,11 @@ function TrashItem(props: TrashItemProps) {
|
||||
item={item}
|
||||
title={item.title}
|
||||
body={item.itemType === "note" ? item.headline : item.description}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await deleteTrash(useSelectionStore.getState().selectedItems);
|
||||
}
|
||||
}}
|
||||
footer={
|
||||
<Flex
|
||||
mt={1}
|
||||
@@ -87,14 +93,15 @@ const menuItems: (item: TrashItemType, ids?: string[]) => MenuItem[] = (
|
||||
icon: DeleteForver.path,
|
||||
variant: "dangerous",
|
||||
onClick: async () => {
|
||||
if (!(await showMultiPermanentDeleteConfirmation(ids.length))) return;
|
||||
await store.delete(...ids);
|
||||
showToast(
|
||||
"success",
|
||||
`${pluralize(ids.length, "item")} permanently deleted`
|
||||
);
|
||||
await deleteTrash(ids);
|
||||
},
|
||||
multiSelect: true
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
async function deleteTrash(ids: string[]) {
|
||||
if (!(await showMultiPermanentDeleteConfirmation(ids.length))) return;
|
||||
await store.delete(...ids);
|
||||
showToast("success", `${pluralize(ids.length, "item")} permanently deleted`);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ export function VirtualizedTable<T, C>(props: VirtualizedTableProps<T, C>) {
|
||||
containerRef.current?.closest(".ms-container") ||
|
||||
undefined
|
||||
}
|
||||
increaseViewportBy={300}
|
||||
computeItemKey={(index) => getItemKey(index)}
|
||||
defaultItemHeight={estimatedSize}
|
||||
fixedHeaderContent={() => <>{header}</>}
|
||||
|
||||
@@ -49,6 +49,8 @@ export const AddNotebookDialog = DialogManager.register(
|
||||
title: title.current,
|
||||
description: description.current
|
||||
});
|
||||
if (!id) return;
|
||||
|
||||
if (parentId) {
|
||||
await db.relations.add(
|
||||
{ type: "notebook", id: parentId },
|
||||
|
||||
@@ -197,14 +197,15 @@ export const AttachmentsDialog = DialogManager.register(
|
||||
variant="secondary"
|
||||
key={tool.title}
|
||||
title={tool.title}
|
||||
onClick={() =>
|
||||
tool.onClick({
|
||||
selected
|
||||
// : attachments.filter(
|
||||
// (a) => selected.indexOf(a.id) > -1
|
||||
// )
|
||||
})
|
||||
}
|
||||
onClick={() => {
|
||||
try {
|
||||
tool.onClick({
|
||||
selected
|
||||
});
|
||||
} catch (e) {
|
||||
showToast("error", (e as Error).message);
|
||||
}
|
||||
}}
|
||||
disabled={!selected.length}
|
||||
sx={{ bg: "transparent", p: 1 }}
|
||||
>
|
||||
@@ -254,7 +255,14 @@ export const AttachmentsDialog = DialogManager.register(
|
||||
>
|
||||
<Label>
|
||||
<Checkbox
|
||||
sx={{ width: 18, height: 18 }}
|
||||
sx={{
|
||||
width: 18,
|
||||
height: 18,
|
||||
color:
|
||||
selected.length === attachments.length
|
||||
? "accent"
|
||||
: "icon"
|
||||
}}
|
||||
onChange={async (e) => {
|
||||
setSelected(
|
||||
e.currentTarget.checked
|
||||
@@ -264,6 +272,7 @@ export const AttachmentsDialog = DialogManager.register(
|
||||
: []
|
||||
);
|
||||
}}
|
||||
checked={selected.length === attachments.length}
|
||||
/>
|
||||
</Label>
|
||||
</Text>
|
||||
|
||||
@@ -312,7 +312,7 @@ const sections: Section[] = [
|
||||
icon: Pin
|
||||
}
|
||||
],
|
||||
info: "* Free users can only create 3 notebooks (no limit on topics) and 5 tags."
|
||||
info: "* Free users can only create 20 notebooks and 5 tags."
|
||||
},
|
||||
|
||||
{
|
||||
@@ -399,8 +399,7 @@ const sections: Section[] = [
|
||||
{
|
||||
id: "backup-encryption",
|
||||
title: "Backup encryption",
|
||||
icon: EncryptedBackup,
|
||||
pro: true
|
||||
icon: EncryptedBackup
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -408,7 +407,6 @@ const sections: Section[] = [
|
||||
title: "Personalize & make Notesnook your own",
|
||||
detail:
|
||||
"Change app themes to match your style. Custom themes are coming soon.",
|
||||
pro: true,
|
||||
features: [
|
||||
{
|
||||
id: "10-themes",
|
||||
@@ -423,7 +421,8 @@ const sections: Section[] = [
|
||||
{
|
||||
id: "default-home-page",
|
||||
title: "Change default home page",
|
||||
icon: Home
|
||||
icon: Home,
|
||||
pro: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import { db } from "../common/db";
|
||||
import { getChangelog } from "../utils/version";
|
||||
import { downloadUpdate } from "../utils/updater";
|
||||
import { ErrorText } from "../components/error-text";
|
||||
import { pluralize } from "@notesnook/common";
|
||||
|
||||
type Check = { text: string; default?: boolean };
|
||||
export type ConfirmDialogProps<TCheckId extends string> = BaseDialogProps<
|
||||
@@ -143,7 +144,7 @@ export const ConfirmDialog = DialogManager.register(function ConfirmDialog<
|
||||
|
||||
export function showMultiDeleteConfirmation(length: number) {
|
||||
return ConfirmDialog.show({
|
||||
title: `Delete ${length} items?`,
|
||||
title: `Delete ${pluralize(length, "item")}?`,
|
||||
message: `These items will be **kept in your Trash for ${
|
||||
db.settings.getTrashCleanupInterval() || 7
|
||||
} days** after which they will be permanently deleted.`,
|
||||
@@ -154,7 +155,7 @@ export function showMultiDeleteConfirmation(length: number) {
|
||||
|
||||
export function showMultiPermanentDeleteConfirmation(length: number) {
|
||||
return ConfirmDialog.show({
|
||||
title: `Permanently delete ${length} items?`,
|
||||
title: `Permanently delete ${pluralize(length, "item")}?`,
|
||||
message:
|
||||
"These items will be **permanently deleted**. This is IRREVERSIBLE.",
|
||||
positiveButtonText: "Yes",
|
||||
|
||||
@@ -36,9 +36,6 @@ const QRCode = React.lazy(() => import("../re-exports/react-qrcode-logo"));
|
||||
type RecoveryKeyDialogProps = BaseDialogProps<false>;
|
||||
export const RecoveryKeyDialog = DialogManager.register(
|
||||
function RecoveryKeyDialog(props: RecoveryKeyDialogProps) {
|
||||
const email = usePromise(() =>
|
||||
db.user.getUser().then((user) => user?.email)
|
||||
);
|
||||
const key = usePromise(() =>
|
||||
db.user.getEncryptionKey().then((key) => key?.key)
|
||||
);
|
||||
@@ -124,6 +121,9 @@ export const RecoveryKeyDialog = DialogManager.register(
|
||||
variant="secondary"
|
||||
mt={1}
|
||||
onClick={async () => {
|
||||
const email = await db.user
|
||||
.getUser()
|
||||
.then((user) => user?.email || "user");
|
||||
const qrcode = document.getElementById(
|
||||
"react-qrcode-logo"
|
||||
) as HTMLCanvasElement | null;
|
||||
@@ -143,9 +143,12 @@ export const RecoveryKeyDialog = DialogManager.register(
|
||||
<Button
|
||||
variant="secondary"
|
||||
mt={1}
|
||||
onClick={() => {
|
||||
onClick={async () => {
|
||||
if (!key.value)
|
||||
return showToast("error", "No encryption key found.");
|
||||
const email = await db.user
|
||||
.getUser()
|
||||
.then((user) => user?.email || "user");
|
||||
FileSaver.saveAs(
|
||||
new Blob([Buffer.from(key.value)]),
|
||||
`${email}-notesnook-recoverykey.txt`
|
||||
|
||||
@@ -20,11 +20,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { useStore as useAppStore } from "../../../stores/app-store";
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { useDropzone } from "react-dropzone";
|
||||
import { Button, Flex, Input, Link, Text } from "@theme-ui/components";
|
||||
import { pluralize } from "@notesnook/common";
|
||||
import { Box, Button, Flex, Input, Link, Text } from "@theme-ui/components";
|
||||
import { db } from "../../../common/db";
|
||||
import { importFiles } from "../../../utils/importer";
|
||||
import { CheckCircleOutline } from "../../../components/icons";
|
||||
import Accordion from "../../../components/accordion";
|
||||
|
||||
type Provider = { title: string; link: string };
|
||||
const POPULAR_PROVIDERS: Provider[] = [
|
||||
{
|
||||
title: "Evernote",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-evernote"
|
||||
},
|
||||
{
|
||||
title: "Simplenote",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-simplenote"
|
||||
},
|
||||
{
|
||||
title: "Google Keep",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-google-keep"
|
||||
},
|
||||
{
|
||||
title: "Obsidian",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-obsidian"
|
||||
},
|
||||
{
|
||||
title: "Joplin",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-joplin"
|
||||
},
|
||||
{
|
||||
title: "Markdown files",
|
||||
link: "https://help.notesnook.com/importing-notes/import-notes-from-markdown-files"
|
||||
},
|
||||
{
|
||||
title: "other apps",
|
||||
link: "https://help.notesnook.com/importing-notes/"
|
||||
}
|
||||
];
|
||||
|
||||
export function Importer() {
|
||||
const [isDone, setIsDone] = useState(false);
|
||||
@@ -114,75 +146,81 @@ export function Importer() {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Flex sx={{ alignItems: "center", justifyContent: "space-between" }}>
|
||||
<Flex sx={{ flexDirection: "column" }}>
|
||||
<Text variant="title">
|
||||
{files.length
|
||||
? `${pluralize(files.length, "file")} ready for import`
|
||||
: "Select files to import"}
|
||||
<Accordion
|
||||
isClosed={false}
|
||||
title="How to import your notes from other apps?"
|
||||
containerSx={{
|
||||
px: 2,
|
||||
pb: 2,
|
||||
border: "1px solid var(--border)",
|
||||
borderTopWidth: 0,
|
||||
borderRadius: "default",
|
||||
borderTopLeftRadius: 0,
|
||||
borderTopRightRadius: 0
|
||||
}}
|
||||
>
|
||||
<Text variant="subtitle" sx={{ mt: 2 }}>
|
||||
Quick start guide:
|
||||
</Text>
|
||||
<Box as="ol" sx={{ my: 1 }}>
|
||||
<Text as="li" variant="body">
|
||||
Go to{" "}
|
||||
<Link href="https://importer.notesnook.com/" target="_blank">
|
||||
https://importer.notesnook.com/
|
||||
</Link>
|
||||
</Text>
|
||||
<Text
|
||||
variant={"body"}
|
||||
sx={{ color: "var(--paragraph-secondary)" }}
|
||||
>
|
||||
Please refer to the{" "}
|
||||
<Link
|
||||
href="https://help.notesnook.com/importing-notes/import-notes-from-evernote"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ color: "accent" }}
|
||||
>
|
||||
import guide
|
||||
</Link>{" "}
|
||||
for help regarding how to use the Notesnook Importer.
|
||||
<Text as="li" variant="body">
|
||||
Select the app you want to import from.
|
||||
</Text>
|
||||
</Flex>
|
||||
<Button
|
||||
variant="accent"
|
||||
onClick={async () => {
|
||||
setIsDone(false);
|
||||
setIsImporting(true);
|
||||
<Text as="li" variant="body">
|
||||
Drag drop or select the files you exported from the other app.
|
||||
</Text>
|
||||
<Text as="li" variant="body">
|
||||
Start the importer and wait for it to complete processing.
|
||||
</Text>
|
||||
<Text as="li" variant="body">
|
||||
Download the .zip file from the Importer.
|
||||
</Text>
|
||||
<Text as="li" variant="body">
|
||||
Drop the .zip file below to complete your import.
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
await db.syncer?.acquireLock(async () => {
|
||||
try {
|
||||
for await (const message of importFiles(files)) {
|
||||
switch (message.type) {
|
||||
case "error":
|
||||
setErrors((errors) => [...errors, message.error]);
|
||||
break;
|
||||
case "progress": {
|
||||
const { count } = message;
|
||||
if (notesCounter.current)
|
||||
notesCounter.current.innerText = `${count}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (e instanceof Error) {
|
||||
setErrors((errors) => [...errors, e as Error]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await useAppStore.getState().refresh();
|
||||
|
||||
setIsDone(true);
|
||||
setIsImporting(false);
|
||||
<Text variant={"body"} sx={{ fontWeight: "bold" }}>
|
||||
For detailed steps with screenshots, refer to the help article for
|
||||
each app:
|
||||
</Text>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr 1fr",
|
||||
gap: 1,
|
||||
mt: 1
|
||||
}}
|
||||
disabled={!files.length}
|
||||
>
|
||||
Start import
|
||||
</Button>
|
||||
</Flex>
|
||||
{POPULAR_PROVIDERS.map((provider) => (
|
||||
<Button
|
||||
key={provider.link}
|
||||
variant="icon"
|
||||
sx={{
|
||||
borderRadius: "default",
|
||||
border: "1px solid var(--border)",
|
||||
textAlign: "left"
|
||||
}}
|
||||
onClick={() => window.open(provider.link, "_blank")}
|
||||
>
|
||||
Import from {provider.title}
|
||||
</Button>
|
||||
))}
|
||||
</Box>
|
||||
</Accordion>
|
||||
<Flex
|
||||
{...getRootProps()}
|
||||
data-test-id="import-dialog-select-files"
|
||||
sx={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 200,
|
||||
minHeight: 200,
|
||||
flexShrink: 0,
|
||||
width: "full",
|
||||
border: "2px dashed var(--border)",
|
||||
@@ -199,31 +237,75 @@ export function Importer() {
|
||||
<br />
|
||||
<Text variant="subBody">Only .zip files are supported.</Text>
|
||||
</Text>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap", mt: 2 }}>
|
||||
{files.map((file, i) => (
|
||||
<Text
|
||||
key={file.name}
|
||||
p={1}
|
||||
sx={{
|
||||
":hover": { bg: "hover" },
|
||||
cursor: "pointer",
|
||||
borderRadius: "default"
|
||||
}}
|
||||
onClick={() => {
|
||||
setFiles((files) => {
|
||||
const cloned = files.slice();
|
||||
cloned.splice(i, 1);
|
||||
return cloned;
|
||||
});
|
||||
}}
|
||||
variant="body"
|
||||
title="Click to remove"
|
||||
>
|
||||
{file.name}
|
||||
</Text>
|
||||
))}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex my={1} sx={{ flexDirection: "column" }}>
|
||||
{files.map((file, i) => (
|
||||
<Text
|
||||
key={file.name}
|
||||
p={1}
|
||||
sx={{
|
||||
":hover": { bg: "hover" },
|
||||
cursor: "pointer",
|
||||
borderRadius: "default"
|
||||
}}
|
||||
onClick={() => {
|
||||
setFiles((files) => {
|
||||
const cloned = files.slice();
|
||||
cloned.splice(i, 1);
|
||||
return cloned;
|
||||
});
|
||||
}}
|
||||
variant="body"
|
||||
title="Click to remove"
|
||||
>
|
||||
{file.name}
|
||||
</Text>
|
||||
))}
|
||||
</Flex>
|
||||
{/* <Flex my={1} sx={{ flexDirection: "column" }}>
|
||||
|
||||
</Flex> */}
|
||||
<Button
|
||||
variant="accent"
|
||||
sx={{ alignSelf: "end", mt: 1 }}
|
||||
onClick={async () => {
|
||||
setIsDone(false);
|
||||
setIsImporting(true);
|
||||
|
||||
await db.syncer?.acquireLock(async () => {
|
||||
try {
|
||||
for await (const message of importFiles(files)) {
|
||||
switch (message.type) {
|
||||
case "error":
|
||||
setErrors((errors) => [...errors, message.error]);
|
||||
break;
|
||||
case "progress": {
|
||||
const { count } = message;
|
||||
if (notesCounter.current)
|
||||
notesCounter.current.innerText = `${count}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (e instanceof Error) {
|
||||
setErrors((errors) => [...errors, e as Error]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await useAppStore.getState().refresh();
|
||||
|
||||
setIsDone(true);
|
||||
setIsImporting(false);
|
||||
}}
|
||||
disabled={!files.length}
|
||||
>
|
||||
{files.length > 0
|
||||
? "Start import"
|
||||
: "Select files to start importing"}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
@@ -171,9 +171,6 @@ function ThemesList() {
|
||||
{filter.title}
|
||||
</Button>
|
||||
))}
|
||||
{themes.isLoading && !themes.isInitialLoading ? (
|
||||
<Loading color="accent" />
|
||||
) : null}
|
||||
</Flex>
|
||||
|
||||
<Flex sx={{ mt: 2, gap: 1 }}>
|
||||
@@ -238,6 +235,9 @@ function ThemesList() {
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{!themes.isInitialLoading && themes.isFetching ? (
|
||||
<Loading color="accent" sx={{ mt: 2 }} />
|
||||
) : null}
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -24,7 +24,18 @@ export const ImporterSettings: SettingsGroup[] = [
|
||||
{
|
||||
key: "importer",
|
||||
section: "importer",
|
||||
header: Importer,
|
||||
settings: []
|
||||
header: "Notesnook Importer",
|
||||
settings: [
|
||||
{
|
||||
key: "import-notes",
|
||||
title: "",
|
||||
components: [
|
||||
{
|
||||
type: "custom",
|
||||
component: Importer
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -77,7 +77,9 @@ import { AppLockSettings } from "./app-lock-settings";
|
||||
import { BaseDialogProps, DialogManager } from "../../common/dialog-manager";
|
||||
import { ServersSettings } from "./servers-settings";
|
||||
|
||||
type SettingsDialogProps = BaseDialogProps<false>;
|
||||
type SettingsDialogProps = BaseDialogProps<false> & {
|
||||
activeSection?: SectionKeys;
|
||||
};
|
||||
|
||||
const sectionGroups: SectionGroup[] = [
|
||||
{
|
||||
@@ -187,7 +189,9 @@ export const SettingsDialog = DialogManager.register(function SettingsDialog(
|
||||
props: SettingsDialogProps
|
||||
) {
|
||||
const [activeSettings, setActiveSettings] = useState<SettingsGroup[]>(
|
||||
SettingsGroups.filter((g) => g.section === "profile")
|
||||
SettingsGroups.filter(
|
||||
(g) => g.section === (props.activeSection || "profile")
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -205,6 +209,7 @@ export const SettingsDialog = DialogManager.register(function SettingsDialog(
|
||||
}}
|
||||
>
|
||||
<SettingsSideBar
|
||||
activeSection={props.activeSection}
|
||||
onNavigate={(settings) => {
|
||||
const scrollbar = document.getElementById("settings-scrollbar");
|
||||
if (scrollbar !== null) scrollbar.scrollTop = 0;
|
||||
@@ -233,10 +238,13 @@ export const SettingsDialog = DialogManager.register(function SettingsDialog(
|
||||
);
|
||||
});
|
||||
|
||||
type SettingsSideBarProps = { onNavigate: (settings: SettingsGroup[]) => void };
|
||||
type SettingsSideBarProps = {
|
||||
onNavigate: (settings: SettingsGroup[]) => void;
|
||||
activeSection?: SectionKeys;
|
||||
};
|
||||
function SettingsSideBar(props: SettingsSideBarProps) {
|
||||
const { onNavigate } = props;
|
||||
const [route, setRoute] = useState<SectionKeys>("profile");
|
||||
const { onNavigate, activeSection } = props;
|
||||
const [route, setRoute] = useState<SectionKeys>(activeSection || "profile");
|
||||
useUserStore((store) => store.isLoggedIn);
|
||||
|
||||
return (
|
||||
|
||||
@@ -110,6 +110,11 @@ export async function writeEncryptedFile(
|
||||
)
|
||||
.pipeTo(fileHandle.writeable);
|
||||
|
||||
if (!(await exists(fileHandle))) {
|
||||
await fileHandle.delete();
|
||||
throw new Error("Failed to encrypt file. Please try again.");
|
||||
}
|
||||
|
||||
AppEventManager.publish(AppEvents.fileEncrypted, {
|
||||
hash,
|
||||
total: 1,
|
||||
@@ -256,7 +261,11 @@ async function uploadFile(
|
||||
: await multiPartUploadFile(fileHandle, filename, requestOptions);
|
||||
|
||||
if (uploaded) {
|
||||
await checkUpload(filename);
|
||||
await checkUpload(
|
||||
filename,
|
||||
requestOptions.chunkSize,
|
||||
fileHandle.file.size
|
||||
);
|
||||
await fileHandle.addAdditionalData("uploaded", true);
|
||||
}
|
||||
|
||||
@@ -448,13 +457,21 @@ async function resetUpload(fileHandle: FileHandle) {
|
||||
await fileHandle.addAdditionalData("uploaded", false);
|
||||
}
|
||||
|
||||
async function checkUpload(filename: string) {
|
||||
export async function checkUpload(
|
||||
filename: string,
|
||||
chunkSize: number,
|
||||
expectedSize: number
|
||||
) {
|
||||
const size = await getUploadedFileSize(filename);
|
||||
const totalChunks = Math.ceil(size / chunkSize);
|
||||
const decryptedLength = size - totalChunks * ABYTES;
|
||||
const error =
|
||||
size === 0
|
||||
? `Upload verification failed: file size is 0. Please upload this file again. (File hash: ${filename})`
|
||||
? `File size is 0.`
|
||||
: size === -1
|
||||
? `Upload verification failed.`
|
||||
? `File verification check failed.`
|
||||
: expectedSize !== decryptedLength
|
||||
? `File size mismatch. Expected ${size} bytes but got ${decryptedLength} bytes.`
|
||||
: undefined;
|
||||
if (error) throw new Error(error);
|
||||
}
|
||||
@@ -612,6 +629,11 @@ export async function streamingDecryptFile(
|
||||
if (!fileMetadata) return false;
|
||||
|
||||
const fileHandle = await streamablefs.readFile(filename);
|
||||
logger.info("decrypting file", {
|
||||
filename,
|
||||
size: fileHandle?.file.size,
|
||||
actualSize: await fileHandle?.size()
|
||||
});
|
||||
if (!fileHandle) return false;
|
||||
|
||||
const { key, iv } = fileMetadata;
|
||||
|
||||
@@ -28,6 +28,7 @@ import { AttachmentStream } from "../utils/streams/attachment-stream";
|
||||
import { createZipStream } from "../utils/streams/zip-stream";
|
||||
import { createWriteStream } from "../utils/stream-saver";
|
||||
import { Attachment } from "@notesnook/core";
|
||||
import { TaskManager } from "../common/task-manager";
|
||||
|
||||
let abortController: AbortController | undefined = undefined;
|
||||
class AttachmentStore extends BaseStore<AttachmentStore> {
|
||||
@@ -80,25 +81,36 @@ class AttachmentStore extends BaseStore<AttachmentStore> {
|
||||
};
|
||||
|
||||
recheck = async (ids: string[]) => {
|
||||
for (const id of ids) {
|
||||
const attachment = await db.attachments.attachment(id);
|
||||
if (!attachment) continue;
|
||||
try {
|
||||
this._changeWorkingStatus(attachment.hash, "recheck");
|
||||
await TaskManager.startTask({
|
||||
type: "status",
|
||||
action: async (report) => {
|
||||
let i = 0;
|
||||
for (const id of ids) {
|
||||
report({
|
||||
text: `Checking attachments (${++i}/${ids.length})`
|
||||
});
|
||||
const attachment = await db.attachments.attachment(id);
|
||||
if (!attachment) continue;
|
||||
try {
|
||||
this._changeWorkingStatus(attachment.hash, "recheck");
|
||||
|
||||
const { failed, success } = await checkAttachment(attachment.hash);
|
||||
this._changeWorkingStatus(
|
||||
attachment.hash,
|
||||
undefined,
|
||||
success ? undefined : failed
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this._changeWorkingStatus(attachment.hash);
|
||||
if (e instanceof Error)
|
||||
showToast("error", `Rechecking failed: ${e.message}`);
|
||||
}
|
||||
}
|
||||
const { failed, success } = await checkAttachment(attachment.hash);
|
||||
this._changeWorkingStatus(
|
||||
attachment.hash,
|
||||
undefined,
|
||||
success ? undefined : failed
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
this._changeWorkingStatus(attachment.hash);
|
||||
if (e instanceof Error)
|
||||
showToast("error", `Rechecking failed: ${e.message}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
id: "checking-attachments",
|
||||
title: "Checking attachments"
|
||||
});
|
||||
};
|
||||
|
||||
rename = async (hash: string, newName: string) => {
|
||||
|
||||
@@ -802,10 +802,11 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
{ type, id: currentSession.context.id },
|
||||
{ id, type: "note" }
|
||||
);
|
||||
} else {
|
||||
const defaultNotebook = db.settings.getDefaultNotebook();
|
||||
if (defaultNotebook)
|
||||
await db.notes.addToNotebook(defaultNotebook, id);
|
||||
}
|
||||
const defaultNotebook = db.settings.getDefaultNotebook();
|
||||
if (defaultNotebook)
|
||||
await db.notes.addToNotebook(defaultNotebook, id);
|
||||
}
|
||||
|
||||
const attachmentsLength = await db.attachments
|
||||
|
||||
@@ -22,7 +22,7 @@ const FEATURE_CHECKS = {
|
||||
cache: false,
|
||||
indexedDB: false,
|
||||
clonableCryptoKey: false,
|
||||
applePaySupported: window.ApplePaySession?.canMakePayments()
|
||||
applePaySupported: !!window.ApplePaySession?.canMakePayments()
|
||||
};
|
||||
|
||||
async function isOPFSSupported() {
|
||||
|
||||
@@ -21,7 +21,8 @@ import { db } from "../common/db";
|
||||
import {
|
||||
Note,
|
||||
Notebook,
|
||||
ContentType
|
||||
ContentType,
|
||||
LegacyNotebook
|
||||
} from "@notesnook-importer/core/dist/src/models";
|
||||
import {
|
||||
ATTACHMENTS_DIRECTORY_NAME,
|
||||
@@ -145,6 +146,7 @@ async function processNote(entry: ZipEntry, attachments: Record<string, any>) {
|
||||
(await db.tags.add({
|
||||
title: tag
|
||||
}));
|
||||
if (!tagId) continue;
|
||||
|
||||
await db.relations.add(
|
||||
{
|
||||
@@ -166,6 +168,7 @@ async function processNote(entry: ZipEntry, attachments: Record<string, any>) {
|
||||
colorCode: colorCode,
|
||||
title: note.color
|
||||
}));
|
||||
if (!colorId) return;
|
||||
|
||||
await db.relations.add(
|
||||
{
|
||||
@@ -180,9 +183,16 @@ async function processNote(entry: ZipEntry, attachments: Record<string, any>) {
|
||||
}
|
||||
|
||||
for (const nb of notebooks) {
|
||||
const notebookId = await importNotebook(nb).catch(() => undefined);
|
||||
if (!notebookId) continue;
|
||||
await db.notes.addToNotebook(notebookId, noteId);
|
||||
if ("notebook" in nb) {
|
||||
const notebookId = await importLegacyNotebook(nb).catch(() => undefined);
|
||||
if (!notebookId) continue;
|
||||
await db.notes.addToNotebook(notebookId, noteId);
|
||||
} else {
|
||||
const notebookIds = await importNotebook(nb).catch(() => undefined);
|
||||
if (!notebookIds) continue;
|
||||
for (const notebookId of notebookIds)
|
||||
await db.notes.addToNotebook(notebookId, noteId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +201,11 @@ async function fileToJson<T>(file: ZipEntry) {
|
||||
return JSON.parse(text) as T;
|
||||
}
|
||||
|
||||
async function importNotebook(
|
||||
notebook: Notebook | undefined
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async function importLegacyNotebook(
|
||||
notebook: LegacyNotebook | undefined
|
||||
): Promise<string | undefined> {
|
||||
if (!notebook) return;
|
||||
const nb = await db.notebooks.find(notebook.notebook);
|
||||
@@ -202,3 +215,29 @@ async function importNotebook(
|
||||
title: notebook.notebook
|
||||
});
|
||||
}
|
||||
|
||||
async function importNotebook(
|
||||
notebook: Notebook,
|
||||
parentId?: string
|
||||
): Promise<string[]> {
|
||||
if (!notebook) return [];
|
||||
|
||||
const id =
|
||||
(await db.notebooks.find(notebook.title))?.id ||
|
||||
(await db.notebooks.add({
|
||||
title: notebook.title
|
||||
}));
|
||||
if (!id) throw new Error(`Failed to import notebook: ${notebook.title}`);
|
||||
|
||||
if (parentId)
|
||||
await db.relations.add(
|
||||
{ type: "notebook", id: parentId },
|
||||
{ type: "notebook", id: id }
|
||||
);
|
||||
|
||||
const assignedNotebooks: string[] = notebook.children.length > 0 ? [] : [id];
|
||||
for (const child of notebook.children || []) {
|
||||
assignedNotebooks.push(...(await importNotebook(child, id)));
|
||||
}
|
||||
return assignedNotebooks;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getFileNameWithExtension } from "@notesnook/core/dist/utils/filename";
|
||||
import { db } from "../../common/db";
|
||||
import { lazify } from "../lazify";
|
||||
import { showToast } from "../toast";
|
||||
import { makeUniqueFilename } from "./utils";
|
||||
import { ZipFile } from "./zip-stream";
|
||||
import { Attachment } from "@notesnook/core";
|
||||
import { logger } from "../logger";
|
||||
|
||||
export const METADATA_FILENAME = "metadata.json";
|
||||
const GROUP_ID = "all-attachments";
|
||||
@@ -33,66 +35,74 @@ export class AttachmentStream extends ReadableStream<ZipFile> {
|
||||
signal?: AbortSignal,
|
||||
onProgress?: (current: number) => void
|
||||
) {
|
||||
let index = 0;
|
||||
const counters: Record<string, number> = {};
|
||||
if (signal)
|
||||
signal.onabort = async () => {
|
||||
await db.fs().cancel(GROUP_ID);
|
||||
};
|
||||
|
||||
super({
|
||||
start() {},
|
||||
async pull(controller) {
|
||||
if (signal?.aborted) {
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
|
||||
onProgress && onProgress(index);
|
||||
const attachment = await resolve(ids[index++]);
|
||||
if (!attachment) return;
|
||||
try {
|
||||
if (
|
||||
!(await db
|
||||
.fs()
|
||||
.downloadFile(GROUP_ID, attachment.hash, attachment.chunkSize))
|
||||
)
|
||||
async start(controller) {
|
||||
const counters: Record<string, number> = {};
|
||||
let index = 0;
|
||||
for (const id of ids) {
|
||||
if (signal?.aborted) {
|
||||
controller.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const key = await db.attachments.decryptKey(attachment.key);
|
||||
if (!key) return;
|
||||
onProgress && onProgress(index++);
|
||||
const attachment = await resolve(id);
|
||||
if (!attachment) return;
|
||||
try {
|
||||
if (
|
||||
!(await db
|
||||
.fs()
|
||||
.downloadFile(GROUP_ID, attachment.hash, attachment.chunkSize))
|
||||
)
|
||||
return;
|
||||
|
||||
const file = await lazify(
|
||||
import("../../interfaces/fs"),
|
||||
({ decryptFile }) =>
|
||||
decryptFile(attachment.hash, {
|
||||
key,
|
||||
iv: attachment.iv,
|
||||
name: attachment.filename,
|
||||
type: attachment.mimeType,
|
||||
isUploaded: !!attachment.dateUploaded
|
||||
})
|
||||
);
|
||||
const key = await db.attachments.decryptKey(attachment.key);
|
||||
if (!key) return;
|
||||
|
||||
if (file) {
|
||||
const filePath: string = attachment.filename;
|
||||
controller.enqueue({
|
||||
path: makeUniqueFilename(filePath, counters),
|
||||
data: new Uint8Array(await file.arrayBuffer())
|
||||
});
|
||||
} else {
|
||||
throw new Error(
|
||||
`Failed to decrypt file (hash: ${attachment.hash}, filename: ${attachment.filename}).`
|
||||
const file = await lazify(
|
||||
import("../../interfaces/fs"),
|
||||
({ decryptFile }) =>
|
||||
decryptFile(attachment.hash, {
|
||||
key,
|
||||
iv: attachment.iv,
|
||||
name: attachment.filename,
|
||||
type: attachment.mimeType,
|
||||
isUploaded: !!attachment.dateUploaded
|
||||
})
|
||||
);
|
||||
|
||||
if (file) {
|
||||
const filePath: string =
|
||||
attachment.filename === attachment.hash
|
||||
? getFileNameWithExtension(
|
||||
attachment.hash,
|
||||
attachment.mimeType
|
||||
)
|
||||
: attachment.filename;
|
||||
controller.enqueue({
|
||||
path: makeUniqueFilename(filePath, counters),
|
||||
data: new Uint8Array(await file.arrayBuffer())
|
||||
});
|
||||
} else {
|
||||
throw new Error(
|
||||
`Failed to decrypt file (hash: ${attachment.hash}, filename: ${attachment.filename}).`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(e, "Failed to download attachment");
|
||||
showToast(
|
||||
"error",
|
||||
`Failed to download attachment: ${(e as Error).message} (hash: ${
|
||||
attachment.hash
|
||||
}, filename: ${attachment.filename})`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e, attachment);
|
||||
showToast("error", (e as Error).message);
|
||||
} finally {
|
||||
if (index === ids.length) {
|
||||
controller.close();
|
||||
}
|
||||
}
|
||||
controller.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,12 +24,19 @@ import type {
|
||||
} from "./task-scheduler.worker";
|
||||
import { wrap, Remote } from "comlink";
|
||||
import { showToast } from "./toast";
|
||||
import dayjs from "dayjs";
|
||||
import { logger } from "./logger";
|
||||
|
||||
let worker: globalThis.Worker | undefined;
|
||||
let scheduler: Remote<TaskSchedulerType> | undefined;
|
||||
|
||||
export class TaskScheduler {
|
||||
static async register(id: string, time: string, action: () => void) {
|
||||
if (!dayjs(time).isValid()) {
|
||||
logger.error(`Invalid cron expression: ${time}`);
|
||||
return;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
worker?.addEventListener("message", function handler(ev) {
|
||||
|
||||
@@ -118,19 +118,16 @@ export class WebExtensionServer implements Server {
|
||||
content: { type: "tiptap", data: content }
|
||||
});
|
||||
|
||||
if (id && clip.tags) {
|
||||
for (const id of clip.tags) {
|
||||
if (!(await db.tags.exists(id))) continue;
|
||||
await db.relations.add({ id: id, type: "tag" }, { id, type: "note" });
|
||||
}
|
||||
}
|
||||
|
||||
if (clip.refs && id && !clip.note) {
|
||||
for (const ref of clip.refs) {
|
||||
switch (ref.type) {
|
||||
case "notebook":
|
||||
if (!(await db.notebooks.exists(ref.id))) continue;
|
||||
await db.notes.addToNotebook(ref.id, id);
|
||||
break;
|
||||
case "tag":
|
||||
if (!(await db.tags.exists(ref.id))) continue;
|
||||
await db.relations.add(ref, { id, type: "note" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 159 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
1
docs/help/contents/faqs/README.md
Normal file
1
docs/help/contents/faqs/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# FAQs
|
||||
18
docs/help/contents/faqs/is-there-an-eta.md
Normal file
18
docs/help/contents/faqs/is-there-an-eta.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Is there an ETA for X feature?
|
||||
description: We do not provide any ETAs.
|
||||
---
|
||||
|
||||
# Is there an ETA for X feature?
|
||||
|
||||

|
||||
|
||||
We maintain an up-to-date [roadmap](https://notesnook.com/roadmap) which lists everything we are working on and everything we plan on adding in the future. There is no certainty _when_ something might land, though. It can be days, months, or even years before a feature becomes generally available. Asking us for ETAs is annoying and distracts us from what really matters.
|
||||
|
||||
## Why we don't provide ETAs
|
||||
|
||||
In case you are still curious, a huge part of developing any software are **deadlines**. Giving any ETA means we want to be held accountable for when a feature might land. That is something we cannot afford because another huge part of developing any software are **delays**. As any engineer might tell you, "X will land in 1 month" almost always means "X will land in 4 months".
|
||||
|
||||
Users do not understand or tolerate delays, and developers do not like incessant pestering on why something didn't land on X date when we said it'll land on X date. To avoid all these headaches we simply do not give out any ETAs. Obviously, internally we do have timelines for each feature but disclosing these is unnecessary.
|
||||
|
||||
In short, it'll land when it'll land. No promises.
|
||||
67
docs/help/contents/faqs/what-are-merge-conflicts.md
Normal file
67
docs/help/contents/faqs/what-are-merge-conflicts.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: What are merge conflicts?
|
||||
description: Merge conflicts occur when two or more devices edit the same note and then attempt to sync these changes. Since each device has a different version of the note, Notesnook cannot automatically determine which version should take precedence, resulting in a merge conflict.
|
||||
---
|
||||
|
||||
# What are merge conflicts?
|
||||
|
||||
Merge conflicts occur when two or more devices edit the same note and then attempt to sync these changes. Since each device has a different version of the note, Notesnook cannot automatically determine which version should take precedence, resulting in a merge conflict.
|
||||
|
||||
### Example:
|
||||
|
||||
Let’s say you’re using Notesnook on both your laptop and smartphone. You edit a note on your laptop making a lot of changes. Later, while commuting, you remember something important and edit the same note on your smartphone. When both devices eventually reconnect to the internet and sync, Notesnook detects that there are two different versions of the same note and triggers a merge conflict.
|
||||
|
||||
## Why do merge conflicts happen?
|
||||
|
||||
Merge conflicts happen because Notesnook cannot safely figure out which version of the name you want to keep. Unlike some apps that prioritize the most recent changes or attempt to merge content automatically (which can result in loss of important data or unwanted changes), Notesnook ensures you have full control over which version of a note you want to keep.
|
||||
|
||||
> info Both edits must be at least a minute apart
|
||||
>
|
||||
> The changes on both devices must be at least a minute apart for a merge conflict to occur. For example, if you are editing on both devices simultaneously (and both devices have a working sync), a merge conflict will NOT occur.
|
||||
|
||||
### Why doesn't Notesnook automatically resolve merge conflicts?
|
||||
|
||||
1. Automatic conflict resolution can lead to unintended data loss. For example, if both versions of a note contain unique but crucial information, merging them automatically might result in losing an important part of the information.
|
||||
2. By allowing you to manually resolve conflicts, you can review each version of the note and decide which one is correct or if you want to keep both (i.e. both versions contain important information).
|
||||
|
||||
## Where do I find the conflicted notes?
|
||||
|
||||
Conflicted notes appear at the very top of your notes list.
|
||||
|
||||
1. Navigate to Notes
|
||||
2. If you have any conflicts, you'll see them under the **Conflicted** group
|
||||
|
||||
## How to resolve merge conflicts
|
||||
|
||||
### [Desktop/Web](#/tab/web)
|
||||
|
||||
To resolve a merge conflict on your desktop or web app, follow these steps:
|
||||
|
||||
1. Locate the conflicted note at the top of your notes list.
|
||||
2. Click on the note to open the conflict resolution screen.
|
||||
3. On the conflict resolution screen, you’ll see two versions of your note side by side:
|
||||
1. **Current Note** is the version from the device you are using.
|
||||
2. **Incoming Note** is the version coming from the other device.
|
||||

|
||||
3. The red and green highlights on the left side show the changes you made. Red indicates deletions and green indicates additions.
|
||||
4. Review both versions and decide which one you want to keep.
|
||||
5. Click the **Keep** button on the version you want to retain.
|
||||
6. Click the **Discard** button on the version you don’t want to keep, or press **Save a Copy** if you want to keep both versions.
|
||||

|
||||
|
||||
### [Mobile](#/tab/mobile)
|
||||
|
||||
To resolve a merge conflict on your mobile device, follow these steps:
|
||||
|
||||
1. Locate the conflicted note at the top of your notes list.
|
||||
2. Tap on the note to open the conflict resolution screen.
|
||||
3. On the conflict resolution screen, you’ll see two versions of your note, one above the other:
|
||||
1. **This Device** is the version from the device you are using.
|
||||
2. **Incoming** is the version coming from the other device.
|
||||
<p><img src="/static/merge-conflicts-resolution-screen-mobile.png" alt="drawing" height="414"/></p>
|
||||
4. Review both versions and decide which one you want to keep.
|
||||
5. Press the **Keep** button on the version you want to retain.
|
||||
6. Press the **Discard** button on the version you don’t want to keep, or press **Save a Copy** if you want to keep both versions.
|
||||
<p><img src="/static/merge-conflicts-resolution-screen-mobile-2.png" alt="drawing" height="414"/></p>
|
||||
|
||||
---
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
title: Merge Conflicts
|
||||
description: Merge conflicts occur when there are conflicting note edits on different devices for the same note.
|
||||
---
|
||||
|
||||
# Merge Conflicts
|
||||
|
||||
## Why Merge Conflicts occur?
|
||||
|
||||
Merge conflicts occur when there are conflicting note edits on different devices for the same note.
|
||||
|
||||
## How Merge Conflicts occur?
|
||||
|
||||
Lets suppose that you have two devices running Notesnook:
|
||||
|
||||
1. A desktop
|
||||
2. A mobile device
|
||||
|
||||
Suppose that one of your devices is offline. Now if you made edits to one of your (same)notes on both your devices and **synched changes** a merge conflict will occur.
|
||||
|
||||
> info
|
||||
>
|
||||
> In order for a merge conflict to occur the changes on the (same)note on both devices should occur in more than a minute
|
||||
|
||||
## Where do Merge conflicts show
|
||||
|
||||
The conflicted notes appear at the very top of the notes list. Just navigate to the Notes page and you will see them right away (If there are any).
|
||||
|
||||
## How to Resolve Merge Conflicts
|
||||
|
||||
# [Desktop/Web](#/tab/web)
|
||||
|
||||
Follow these steps to resolve a Merge Conflict:
|
||||
|
||||
1. Go to the conflicted note. It appears at the top of your note list.
|
||||
2. Open the note. This will take you to a conflict resolution screen.
|
||||
3. On the conflict resolution screen two versions of your note will appear side by side. One will be from the device you are using (Current Note) and one will be from the server(Incomming Note).
|
||||
|
||||

|
||||
|
||||
4. Go through both versions and choose which one you want to keep.
|
||||
5. Press the Keep button on the note you want to keep.
|
||||
6. Press Discard button on the note you don't want to keep (you can also press the Save a Copy button if you want to keep it too).
|
||||
|
||||

|
||||
|
||||
# [Mobile](#/tab/mobile)
|
||||
|
||||
Follow these steps to resolve a Merge Conflict:
|
||||
|
||||
1. Go to the conflicted note. It appears at the top of your note list.
|
||||
2. Open the note. This will take you to a conflict resolution screen.
|
||||
3. On the Coflict Resolution Screen 2 versions of your note will appear above and below. One will be from the device you are using (Current Note) and one will be from the server(Incomming Note).
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/616381b6-17dc-4d2b-98a7-e7f2629f1925" alt="drawing" width="414" style="text-align:center"/>
|
||||
|
||||
4. Go through both versions and choose which one you want to keep.
|
||||
5. Press the Keep button on the note you want to keep.
|
||||
6. And Discard button on the note you don't want to keep (you can also press the Save a Copy button if you want to keep it too).
|
||||
|
||||
<img src="https://github.com/user-attachments/assets/699454f9-7840-4955-9c5f-1efd8c7963ea" alt="drawing" width="414"/>
|
||||
|
||||
---
|
||||
@@ -79,4 +79,7 @@ navigation:
|
||||
- path: custom-themes/create-a-theme-with-theme-builder.md
|
||||
- path: custom-themes/install-a-theme-from-file.md
|
||||
- path: custom-themes/publish-a-theme.md
|
||||
- path: merge-conflicts.md
|
||||
- path: faqs
|
||||
children:
|
||||
- path: faqs/what-are-merge-conflicts.md
|
||||
- path: faqs/is-there-an-eta.md
|
||||
|
||||
4
extensions/web-clipper/package-lock.json
generated
4
extensions/web-clipper/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/web-clipper",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/web-clipper",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.4",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@emotion/react": "11.11.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/web-clipper",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.4",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"dependencies": {
|
||||
|
||||
@@ -44,17 +44,15 @@ export interface Gateway {
|
||||
connect(): ClientMetadata;
|
||||
}
|
||||
|
||||
type SelectedTopicReference = ItemReference & {
|
||||
type: "topic";
|
||||
parentId: string;
|
||||
};
|
||||
|
||||
type SelectedNotebookReference = ItemReference & {
|
||||
type: "notebook";
|
||||
};
|
||||
type SelectedTagReference = ItemReference & {
|
||||
type: "tag";
|
||||
};
|
||||
|
||||
export type SelectedReference =
|
||||
| SelectedTopicReference
|
||||
| SelectedTagReference
|
||||
| SelectedNotebookReference;
|
||||
|
||||
export type Clip = {
|
||||
@@ -66,7 +64,6 @@ export type Clip = {
|
||||
width?: number;
|
||||
height?: number;
|
||||
pageTitle?: string;
|
||||
tags?: string[];
|
||||
note?: ItemReference;
|
||||
refs?: SelectedReference[];
|
||||
};
|
||||
|
||||
@@ -19,11 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { useState } from "react";
|
||||
import { Flex } from "@theme-ui/components";
|
||||
import { FilteredList } from "../filtered-list";
|
||||
import {
|
||||
NotebookReference,
|
||||
ItemReference,
|
||||
SelectedReference
|
||||
} from "../../common/bridge";
|
||||
import { NotebookReference, SelectedReference } from "../../common/bridge";
|
||||
import { Icons } from "../icons";
|
||||
import { useAppStore } from "../../stores/app-store";
|
||||
import { Picker } from "../picker";
|
||||
@@ -66,7 +62,7 @@ export const NotebookPicker = (props: NotebookPickerProps) => {
|
||||
<InlineTag
|
||||
key={item.id}
|
||||
title={item.title}
|
||||
icon={item.type === "topic" ? Icons.topic : Icons.notebook}
|
||||
icon={Icons.notebook}
|
||||
onClick={() =>
|
||||
setSelectedItems((items) => {
|
||||
const copy = items.slice();
|
||||
@@ -105,14 +101,6 @@ export const NotebookPicker = (props: NotebookPickerProps) => {
|
||||
renderItem={(item) => (
|
||||
<Notebook
|
||||
notebook={item}
|
||||
isTopicSelected={(topic) =>
|
||||
!!selectedItems.find(
|
||||
(n) =>
|
||||
n.id === topic.id &&
|
||||
n.type === "topic" &&
|
||||
n.parentId === item.id
|
||||
)
|
||||
}
|
||||
isSelected={
|
||||
!!selectedItems.find(
|
||||
(n) => n.id === item.id && n.type === "notebook"
|
||||
@@ -144,10 +132,9 @@ type NotebookProps = {
|
||||
notebook: NotebookReference;
|
||||
isSelected: boolean;
|
||||
onSelected: (notebook: SelectedReference) => void;
|
||||
isTopicSelected: (topic: ItemReference) => boolean;
|
||||
};
|
||||
function Notebook(props: NotebookProps) {
|
||||
const { notebook, isSelected, onSelected, isTopicSelected } = props;
|
||||
const { notebook, isSelected, onSelected } = props;
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
||||
@@ -24,25 +24,22 @@ import { useAppStore } from "../../stores/app-store";
|
||||
import { Picker } from "../picker";
|
||||
import { InlineTag } from "../inline-tag";
|
||||
import { CheckListItem } from "../check-list-item";
|
||||
import { SelectedReference } from "../../common/bridge";
|
||||
|
||||
type TagPickerProps = {
|
||||
selectedTags: string[];
|
||||
onSelected: (tags: string[]) => void;
|
||||
selectedTags: SelectedReference[];
|
||||
onSelected: (tags: SelectedReference[]) => void;
|
||||
};
|
||||
export const TagPicker = (props: TagPickerProps) => {
|
||||
const { onSelected } = props;
|
||||
const { selectedTags, onSelected } = props;
|
||||
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [selectedTags, setSelectedTags] = useState<string[]>(
|
||||
props.selectedTags || []
|
||||
);
|
||||
|
||||
const close = () => {
|
||||
setModalVisible(false);
|
||||
};
|
||||
|
||||
const open = () => {
|
||||
setSelectedTags(props.selectedTags || []);
|
||||
setModalVisible(true);
|
||||
};
|
||||
|
||||
@@ -57,20 +54,20 @@ export const TagPicker = (props: TagPickerProps) => {
|
||||
gap: 1
|
||||
}}
|
||||
>
|
||||
{props.selectedTags.length
|
||||
? props.selectedTags.map((tag) => (
|
||||
{selectedTags.length
|
||||
? selectedTags.map((tag) => (
|
||||
<InlineTag
|
||||
key={tag}
|
||||
key={tag.id}
|
||||
icon={Icons.tag}
|
||||
title={tag}
|
||||
title={tag.title}
|
||||
onClick={() => {
|
||||
setSelectedTags((items) => {
|
||||
const copy = items.slice();
|
||||
const index = copy.indexOf(tag);
|
||||
if (index > -1) copy.splice(index, 1);
|
||||
onSelected(copy);
|
||||
return copy;
|
||||
});
|
||||
const copy = selectedTags.slice();
|
||||
const index = copy.findIndex(
|
||||
(c) => c.type === "tag" && c.id === tag.id
|
||||
);
|
||||
if (index <= -1) return;
|
||||
copy.splice(index, 1);
|
||||
onSelected(copy);
|
||||
}}
|
||||
/>
|
||||
))
|
||||
@@ -102,18 +99,19 @@ export const TagPicker = (props: TagPickerProps) => {
|
||||
<CheckListItem
|
||||
title={`#${tag.title}`}
|
||||
onSelected={() => {
|
||||
setSelectedTags((items) => {
|
||||
const copy = items.slice();
|
||||
const index = copy.indexOf(tag.title);
|
||||
if (index > -1) {
|
||||
copy.splice(index, 1);
|
||||
} else {
|
||||
copy.push(tag.title);
|
||||
}
|
||||
return copy;
|
||||
});
|
||||
const copy = selectedTags.slice();
|
||||
const index = copy.findIndex(
|
||||
(c) => c.type === "tag" && c.id === tag.id
|
||||
);
|
||||
if (index <= -1) copy.push({ ...tag, type: "tag" });
|
||||
else copy.splice(index, 1);
|
||||
onSelected(copy);
|
||||
}}
|
||||
isSelected={selectedTags.indexOf(tag.title) > -1}
|
||||
isSelected={
|
||||
selectedTags.findIndex(
|
||||
(s) => s.type === "tag" && s.id === tag.id
|
||||
) > -1
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -110,7 +110,6 @@ export function Main() {
|
||||
const [isClipping, setIsClipping] = useState(false);
|
||||
const [note, setNote] = usePersistentState<ItemReference>("note");
|
||||
const [refs, setRefs] = usePersistentState<SelectedReference[]>("refs", []);
|
||||
const [tags, setTags] = usePersistentState<string[]>("tags", []);
|
||||
const [clipData, setClipData] = useState<ClipData>();
|
||||
const pageTitle = useRef<string>();
|
||||
|
||||
@@ -142,7 +141,12 @@ export function Main() {
|
||||
try {
|
||||
setIsClipping(true);
|
||||
setClipData(
|
||||
await clip(clipArea, clipMode, { ...DEFAULT_SETTINGS, ...settings })
|
||||
await clip(clipArea, clipMode, {
|
||||
...DEFAULT_SETTINGS,
|
||||
...settings,
|
||||
images: isPremium,
|
||||
inlineImages: isPremium
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -369,7 +373,7 @@ export function Main() {
|
||||
Organization
|
||||
</Text>
|
||||
|
||||
{refs?.length || tags?.length ? null : (
|
||||
{refs?.length ? null : (
|
||||
<NotePicker
|
||||
selectedNote={note}
|
||||
onSelected={(note) => setNote(note)}
|
||||
@@ -377,19 +381,19 @@ export function Main() {
|
||||
)}
|
||||
{note ? null : (
|
||||
<>
|
||||
{refs?.length || tags?.length ? null : (
|
||||
{refs?.length ? null : (
|
||||
<Text variant="subBody" sx={{ my: 1, textAlign: "center" }}>
|
||||
— or —
|
||||
</Text>
|
||||
)}
|
||||
<NotebookPicker
|
||||
selectedItems={refs || []}
|
||||
selectedItems={refs?.filter((r) => r.type === "notebook") || []}
|
||||
onSelected={(items) => setRefs(items)}
|
||||
/>
|
||||
<Box sx={{ mt: 1 }} />
|
||||
<TagPicker
|
||||
selectedTags={tags || []}
|
||||
onSelected={(tags) => setTags(tags)}
|
||||
selectedTags={refs?.filter((r) => r.type === "tag") || []}
|
||||
onSelected={(tags) => setRefs(tags)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -410,7 +414,6 @@ export function Main() {
|
||||
title,
|
||||
area: clipArea,
|
||||
mode: clipMode,
|
||||
tags,
|
||||
note,
|
||||
refs,
|
||||
pageTitle: pageTitle.current,
|
||||
|
||||
3
fastlane/metadata/android/en-US/changelogs/15119.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/15119.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
- Bug fixes and small improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
6
fastlane/metadata/android/en-US/changelogs/15124.txt
Normal file
6
fastlane/metadata/android/en-US/changelogs/15124.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
- Fix crash when launching Notesnook from Notification tiles
|
||||
- Fix app crashing on background on boot
|
||||
- Fix self-hosted server urls not working
|
||||
- Bug fixes and small improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -38,7 +38,7 @@ const BLACKLIST = [CLASSES.nodeSelected, CLASSES.nodeSelectionContainer];
|
||||
|
||||
const inlineOptions: InlineOptions = {
|
||||
fonts: false,
|
||||
images: true,
|
||||
images: false,
|
||||
stylesheets: true
|
||||
};
|
||||
|
||||
@@ -198,7 +198,11 @@ function enterNodeSelectionMode(doc: Document, config?: Config) {
|
||||
const inlined = await getInlinedNode(node as HTMLElement, {
|
||||
raster: false,
|
||||
fetchOptions: resolveFetchOptions(config),
|
||||
inlineOptions
|
||||
inlineOptions: {
|
||||
...inlineOptions,
|
||||
images: config?.images,
|
||||
inlineImages: config?.inlineImages
|
||||
}
|
||||
});
|
||||
if (!inlined) continue;
|
||||
div.appendChild(inlined);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { constructUrl, FetchOptions } from "./fetch";
|
||||
import { compare, calculate, SpecificityArray } from "specificity";
|
||||
import { tokenize } from "./css-tokenizer";
|
||||
import { stringify, parse, SelectorType } from "css-what";
|
||||
import { safeQuerySelectorAll } from "./utils";
|
||||
|
||||
const SHORTHANDS = [
|
||||
"animation",
|
||||
@@ -186,7 +187,8 @@ function walkRules(
|
||||
|
||||
for (const selector of selectors) {
|
||||
if (!selector || !selector.selector.trim()) continue;
|
||||
const elements = document.querySelectorAll(
|
||||
const elements = safeQuerySelectorAll(
|
||||
document,
|
||||
selector.selector
|
||||
) as NodeListOf<StyleableElement>;
|
||||
|
||||
@@ -210,7 +212,8 @@ function walkRules(
|
||||
}
|
||||
}
|
||||
|
||||
const elements = document.querySelectorAll(
|
||||
const elements = safeQuerySelectorAll(
|
||||
document,
|
||||
rule.selectorText
|
||||
) as NodeListOf<StyleableElement>;
|
||||
|
||||
|
||||
@@ -165,6 +165,14 @@ function getRootStylesheet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function safeQuerySelectorAll(root: Node, selector: string) {
|
||||
try {
|
||||
return (root as HTMLElement).querySelectorAll(selector);
|
||||
} catch (e) {
|
||||
return new NodeList();
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
injectCss,
|
||||
escape,
|
||||
@@ -179,5 +187,6 @@ export {
|
||||
asArray,
|
||||
escapeXhtml,
|
||||
width,
|
||||
height
|
||||
height,
|
||||
safeQuerySelectorAll
|
||||
};
|
||||
|
||||
8
packages/common/package-lock.json
generated
8
packages/common/package-lock.json
generated
@@ -35,7 +35,8 @@
|
||||
"@microsoft/signalr": "^8.0.0",
|
||||
"@notesnook/logger": "file:../logger",
|
||||
"@readme/data-urls": "^3.0.0",
|
||||
"@streetwriters/showdown": "^3.0.7-alpha",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@streetwriters/showdown": "^3.0.8-alpha",
|
||||
"async-mutex": "^0.3.2",
|
||||
"dayjs": "1.11.9",
|
||||
"dom-serializer": "^2.0.0",
|
||||
@@ -46,7 +47,6 @@
|
||||
"html-to-text": "^9.0.5",
|
||||
"htmlparser2": "^8.0.1",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"linkedom": "^0.14.17",
|
||||
"liqe": "^1.13.0",
|
||||
"mime-db": "1.52.0",
|
||||
@@ -1828,7 +1828,8 @@
|
||||
"@notesnook/crypto": "file:../crypto",
|
||||
"@notesnook/logger": "file:../logger",
|
||||
"@readme/data-urls": "^3.0.0",
|
||||
"@streetwriters/showdown": "^3.0.7-alpha",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@streetwriters/showdown": "^3.0.8-alpha",
|
||||
"@types/better-sqlite3": "^7.6.5",
|
||||
"@types/event-source-polyfill": "^1.0.1",
|
||||
"@types/html-to-text": "^9.0.0",
|
||||
@@ -1858,7 +1859,6 @@
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"katex": "0.16.2",
|
||||
"kysely": "^0.26.3",
|
||||
"linkedom": "^0.14.17",
|
||||
"liqe": "^1.13.0",
|
||||
"mime-db": "1.52.0",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user