mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
Compare commits
153 Commits
gen_stack
...
fix-clippe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe3bc9743b | ||
|
|
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 | ||
|
|
b7c81a956c | ||
|
|
873f976fd3 | ||
|
|
7d8a16c463 | ||
|
|
f5841985fa | ||
|
|
da86cbbe32 | ||
|
|
ed115d3f9e | ||
|
|
e52e74523a | ||
|
|
7e43c3b373 | ||
|
|
e6db186b62 | ||
|
|
998e62ade7 | ||
|
|
ac16bc74fc | ||
|
|
2aee26b082 | ||
|
|
a188920d96 | ||
|
|
1f3defc28c | ||
|
|
7aeeabfb3a | ||
|
|
6641d3e625 | ||
|
|
72031617eb | ||
|
|
78090b700b | ||
|
|
f2f8d81b98 | ||
|
|
84d68ca67b | ||
|
|
6368e47712 | ||
|
|
0f17b01a74 | ||
|
|
025e23356a | ||
|
|
ac85002dff | ||
|
|
3a23e4fbaf | ||
|
|
3547663af8 | ||
|
|
c5dfc02085 | ||
|
|
bb9a6431bf | ||
|
|
624d3d7ce8 | ||
|
|
170b0aa49a | ||
|
|
07cfd74506 | ||
|
|
1d40054ac0 | ||
|
|
5cd37f4b64 | ||
|
|
25675f71e8 | ||
|
|
202534fca9 | ||
|
|
a57558d8ab | ||
|
|
f1c201dca9 | ||
|
|
a73bff83fa | ||
|
|
e4428299bc | ||
|
|
487567ffbc | ||
|
|
efd83e6de3 | ||
|
|
a07230f707 | ||
|
|
35a2e11afd | ||
|
|
cf4a7a3d34 | ||
|
|
86e661ccd6 | ||
|
|
e7be9b35ed | ||
|
|
53a367b0b2 | ||
|
|
b6206e2ca7 | ||
|
|
a910c819f2 | ||
|
|
6dd7a4960f | ||
|
|
c4e15b8f90 | ||
|
|
f458a4b86a | ||
|
|
8a44a7b99a | ||
|
|
25065c01a0 | ||
|
|
87ae9e86e7 | ||
|
|
782c53b622 | ||
|
|
cb52b390ab | ||
|
|
5a49941003 | ||
|
|
6797b9b621 | ||
|
|
031a1b31b4 | ||
|
|
4e5762be45 | ||
|
|
7a6ba5d1d1 | ||
|
|
cc3ccd041d | ||
|
|
31453dc098 | ||
|
|
2e84099c80 | ||
|
|
5bbc0cd452 | ||
|
|
22aae401ba | ||
|
|
97f135cd07 | ||
|
|
976f933233 | ||
|
|
95fe1044d6 | ||
|
|
677201e979 | ||
|
|
6ec9370afb | ||
|
|
bea0f1ab0e | ||
|
|
5357be4741 | ||
|
|
02fdec74ce | ||
|
|
dbc907ceeb | ||
|
|
7bb53a5e0c | ||
|
|
69cb24149d | ||
|
|
438d412ae9 | ||
|
|
1b71edef45 | ||
|
|
a4c0e8412b | ||
|
|
fbcb8675ca | ||
|
|
fbf5c82d04 | ||
|
|
fa40c539ed | ||
|
|
f3218fdc31 | ||
|
|
d12ed967e3 | ||
|
|
b6021dc76b | ||
|
|
f95442a828 | ||
|
|
846aae312e | ||
|
|
68fdbcb7fc | ||
|
|
b938c58b67 | ||
|
|
759fba06ae | ||
|
|
10e24ae632 | ||
|
|
341032c884 | ||
|
|
aa1fa0ca81 | ||
|
|
398432efde | ||
|
|
57ddaafc16 | ||
|
|
e4a755c69f | ||
|
|
053f70cdb4 | ||
|
|
cdcdc43cad | ||
|
|
f1111191b1 | ||
|
|
529e2a4dfd | ||
|
|
d88d07a2b0 | ||
|
|
197ff36c20 | ||
|
|
d94474de79 | ||
|
|
fcf0e0c531 | ||
|
|
24048ebfbe | ||
|
|
5ae8cdd5b9 | ||
|
|
74187b335f | ||
|
|
16fc689299 | ||
|
|
578a9de680 | ||
|
|
62d475b2ef | ||
|
|
69c902c6c1 | ||
|
|
c8c1028cbc | ||
|
|
313807c384 | ||
|
|
5dc0e15094 |
2
.github/workflows/android.publish.yml
vendored
2
.github/workflows/android.publish.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Use specific Java version for the builds
|
||||
uses: joschi/setup-jdk@v2
|
||||
with:
|
||||
java-version: "11"
|
||||
java-version: "17"
|
||||
architecture: "x64"
|
||||
|
||||
- name: Install node modules
|
||||
|
||||
14
.github/workflows/ios.publish.yml
vendored
14
.github/workflows/ios.publish.yml
vendored
@@ -89,13 +89,13 @@ jobs:
|
||||
- name: CCache Stats After Build
|
||||
run: ccache -sv
|
||||
|
||||
# - name: "Upload app to TestFlight"
|
||||
# uses: apple-actions/upload-testflight-build@v1
|
||||
# with:
|
||||
# app-path: Notesnook.ipa
|
||||
# issuer-id: ${{ secrets.API_KEY_ISSUER_ID }}
|
||||
# api-key-id: ${{ secrets.API_KEY_ID }}
|
||||
# api-private-key: ${{ secrets.API_KEY }}
|
||||
- name: "Upload app to TestFlight"
|
||||
uses: apple-actions/upload-testflight-build@v1
|
||||
with:
|
||||
app-path: Notesnook.ipa
|
||||
issuer-id: ${{ secrets.API_KEY_ISSUER_ID }}
|
||||
api-key-id: ${{ secrets.API_KEY_ID }}
|
||||
api-private-key: ${{ secrets.API_KEY }}
|
||||
|
||||
- name: Upload Notesnook.ipa to Github
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
371
apps/desktop/package-lock.json
generated
371
apps/desktop/package-lock.json
generated
@@ -1,23 +1,21 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.13",
|
||||
"version": "3.0.17",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"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",
|
||||
"electron-updater": "^6.2.1",
|
||||
"icojs": "^0.17.1",
|
||||
"sodium-native": "^4.1.1",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.6.2",
|
||||
"zod": "^3.21.4"
|
||||
@@ -42,6 +40,7 @@
|
||||
"../../packages/crypto": {
|
||||
"name": "@notesnook/crypto",
|
||||
"version": "2.0.7",
|
||||
"extraneous": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook/sodium": "file:../sodium"
|
||||
@@ -113,7 +112,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz",
|
||||
"integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^2.2.0",
|
||||
@@ -134,7 +132,6 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
@@ -148,7 +145,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
@@ -157,7 +153,6 @@
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
@@ -166,7 +161,6 @@
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
@@ -820,10 +814,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",
|
||||
@@ -838,7 +828,6 @@
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -850,7 +839,6 @@
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"defer-to-connect": "^2.0.0"
|
||||
},
|
||||
@@ -895,7 +883,6 @@
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/http-cache-semantics": "*",
|
||||
"@types/keyv": "^3.1.4",
|
||||
@@ -924,14 +911,12 @@
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
|
||||
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
|
||||
},
|
||||
"node_modules/@types/keyv": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
||||
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@@ -945,8 +930,7 @@
|
||||
"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
|
||||
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA=="
|
||||
},
|
||||
"node_modules/@types/plist": {
|
||||
"version": "3.0.2",
|
||||
@@ -962,7 +946,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
|
||||
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@@ -992,7 +975,6 @@
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
@@ -1133,6 +1115,80 @@
|
||||
"electron-builder-squirrel-windows": "24.13.3"
|
||||
}
|
||||
},
|
||||
"node_modules/archiver": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz",
|
||||
"integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"archiver-utils": "^2.1.0",
|
||||
"async": "^3.2.4",
|
||||
"buffer-crc32": "^0.2.1",
|
||||
"readable-stream": "^3.6.0",
|
||||
"readdir-glob": "^1.1.2",
|
||||
"tar-stream": "^2.2.0",
|
||||
"zip-stream": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/archiver-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.4",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"lazystream": "^1.0.0",
|
||||
"lodash.defaults": "^4.2.0",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.union": "^4.6.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"readable-stream": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/archiver-utils/node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/archiver-utils/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/archiver-utils/node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@@ -1272,7 +1328,6 @@
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
@@ -1323,7 +1378,6 @@
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
@@ -1386,7 +1440,6 @@
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
|
||||
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10.6.0"
|
||||
}
|
||||
@@ -1395,7 +1448,6 @@
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
|
||||
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^5.1.0",
|
||||
@@ -1515,7 +1567,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
|
||||
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-response": "^1.0.0"
|
||||
},
|
||||
@@ -1569,6 +1620,22 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/compress-commons": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
|
||||
"integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"buffer-crc32": "^0.2.13",
|
||||
"crc32-stream": "^4.0.2",
|
||||
"normalize-path": "^3.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -1636,7 +1703,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||
"optional": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/crc": {
|
||||
"version": "3.8.0",
|
||||
@@ -1647,6 +1714,33 @@
|
||||
"buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/crc-32": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"crc32": "bin/crc32.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/crc32-stream": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz",
|
||||
"integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"crc-32": "^1.2.0",
|
||||
"readable-stream": "^3.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -1739,7 +1833,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@@ -1748,7 +1841,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
|
||||
"integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
@@ -1782,7 +1874,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
|
||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/dir-compare": {
|
||||
@@ -1899,7 +1990,6 @@
|
||||
"version": "29.3.1",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-29.3.1.tgz",
|
||||
"integrity": "sha512-auge1/6RVqgUd6TgIq88wKdUCJi2cjESi3jy7d+6X4JzvBGprKBqMJ8JSSFpu/Px1YJrFUKAxfy6SC+TQf1uLw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@electron/get": "^2.0.0",
|
||||
@@ -1939,6 +2029,19 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder-squirrel-windows": {
|
||||
"version": "24.13.3",
|
||||
"resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-24.13.3.tgz",
|
||||
"integrity": "sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"app-builder-lib": "24.13.3",
|
||||
"archiver": "^5.3.1",
|
||||
"builder-util": "24.13.1",
|
||||
"fs-extra": "^10.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-publish": {
|
||||
"version": "24.13.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.13.1.tgz",
|
||||
@@ -1986,7 +2089,6 @@
|
||||
"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"
|
||||
}
|
||||
@@ -2008,7 +2110,6 @@
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
|
||||
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -2023,7 +2124,6 @@
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
|
||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
@@ -2077,7 +2177,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -2098,7 +2197,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"get-stream": "^5.1.0",
|
||||
@@ -2139,7 +2237,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
@@ -2294,7 +2391,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
@@ -2309,7 +2405,6 @@
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
|
||||
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
@@ -2325,7 +2420,6 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
@@ -2400,7 +2494,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
|
||||
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"boolean": "^3.0.1",
|
||||
@@ -2418,7 +2511,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
|
||||
"integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"define-properties": "^1.1.3"
|
||||
@@ -2434,7 +2526,6 @@
|
||||
"version": "11.8.6",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
|
||||
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^4.0.0",
|
||||
"@szmarczak/http-timer": "^4.0.5",
|
||||
@@ -2464,7 +2555,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
@@ -2486,7 +2576,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.1"
|
||||
@@ -2499,7 +2588,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -2512,7 +2600,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -2536,8 +2623,7 @@
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
|
||||
},
|
||||
"node_modules/http-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
@@ -2557,7 +2643,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
|
||||
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.0.0"
|
||||
@@ -2725,6 +2810,13 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/isbinaryfile": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz",
|
||||
@@ -2820,8 +2912,7 @@
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
@@ -2833,7 +2924,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
@@ -2863,7 +2953,6 @@
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz",
|
||||
"integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
@@ -2882,27 +2971,107 @@
|
||||
"resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="
|
||||
},
|
||||
"node_modules/lazystream": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
||||
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"readable-stream": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/lazystream/node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lazystream/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lazystream/node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.defaults": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash.difference": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
||||
"integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash.escaperegexp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
|
||||
"integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="
|
||||
},
|
||||
"node_modules/lodash.flatten": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
|
||||
"integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash.union": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
|
||||
"integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lowercase-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -2922,7 +3091,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
@@ -2968,7 +3136,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
@@ -3075,6 +3242,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",
|
||||
@@ -3094,7 +3262,6 @@
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -3118,7 +3285,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -3136,7 +3302,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
|
||||
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -3214,8 +3379,7 @@
|
||||
"node_modules/pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -3293,11 +3457,17 @@
|
||||
"prebuildify": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -3337,7 +3507,6 @@
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -3404,6 +3573,16 @@
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/readdir-glob": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
|
||||
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"minimatch": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -3427,14 +3606,12 @@
|
||||
"node_modules/resolve-alpn": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
|
||||
"dev": true
|
||||
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
|
||||
},
|
||||
"node_modules/responselike": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
|
||||
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lowercase-keys": "^2.0.0"
|
||||
},
|
||||
@@ -3455,7 +3632,6 @@
|
||||
"version": "2.15.4",
|
||||
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
|
||||
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"boolean": "^3.0.1",
|
||||
@@ -3535,14 +3711,12 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.13.1"
|
||||
@@ -3558,7 +3732,6 @@
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -3667,15 +3840,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",
|
||||
@@ -3699,7 +3863,6 @@
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/stat-mode": {
|
||||
@@ -3799,7 +3962,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.1.0"
|
||||
},
|
||||
@@ -4001,8 +4163,7 @@
|
||||
"node_modules/undici-types": {
|
||||
"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
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
@@ -4151,12 +4312,48 @@
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/zip-stream": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
|
||||
"integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"archiver-utils": "^3.0.4",
|
||||
"compress-commons": "^4.1.2",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/zip-stream/node_modules/archiver-utils": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz",
|
||||
"integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.2.3",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"lazystream": "^1.0.0",
|
||||
"lodash.defaults": "^4.2.0",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.union": "^4.6.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.21.4",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.13",
|
||||
"version": "3.0.17",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
@@ -11,14 +11,12 @@
|
||||
"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",
|
||||
"electron-updater": "^6.2.1",
|
||||
"icojs": "^0.17.1",
|
||||
"sodium-native": "^4.1.1",
|
||||
"typed-emitter": "^2.1.0",
|
||||
"yargs": "^17.6.2",
|
||||
"zod": "^3.21.4"
|
||||
|
||||
@@ -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());
|
||||
|
||||
2
apps/mobile/.gitignore
vendored
2
apps/mobile/.gitignore
vendored
@@ -38,7 +38,7 @@ DerivedData
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
*.hprof
|
||||
ios/.xcode.env.local
|
||||
**/.xcode.env.local
|
||||
# Android/IntelliJ
|
||||
#
|
||||
rn-build-deps/
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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 { Platform } from "react-native";
|
||||
import { MMKV } from "../database/mmkv";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
|
||||
const WEBSITE_ID = "3c6890ce-8410-49d5-8831-15fb2eb28a21";
|
||||
const baseUrl = "https://analytics.streetwriters.co/api/collect";
|
||||
|
||||
const UA =
|
||||
Platform.OS === "ios"
|
||||
? "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1"
|
||||
: `
|
||||
Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36`;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Routes} route
|
||||
* @param {Routes[]} conditions
|
||||
* @returns
|
||||
*/
|
||||
async function canUpdateAnalytics(route, conditions = []) {
|
||||
if (!useSettingStore?.getState()?.settings?.telemetry) return false;
|
||||
let eventsList = MMKV.getString("notesnookUserEvents");
|
||||
|
||||
if (eventsList) {
|
||||
eventsList = JSON.parse(eventsList);
|
||||
}
|
||||
|
||||
if (eventsList && eventsList[route]) {
|
||||
console.log("analytics: event already sent", route);
|
||||
return false;
|
||||
}
|
||||
if (route !== "/welcome") {
|
||||
for (let cond of conditions) {
|
||||
if (!eventsList || !eventsList[cond]) {
|
||||
console.log("analytics: conditions not met for event", route, cond);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("analytics: will send event", route);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function saveAnalytics(route, value = true) {
|
||||
let eventsList = MMKV.getString("notesnookUserEvents");
|
||||
if (eventsList) {
|
||||
eventsList = JSON.parse(eventsList);
|
||||
} else {
|
||||
eventsList = {};
|
||||
}
|
||||
eventsList[route] = value;
|
||||
MMKV.setString("notesnookUserEvents", JSON.stringify(eventsList));
|
||||
}
|
||||
|
||||
/**
|
||||
*@typedef {"/welcome" | "/home" | "/signup" | "/first-note" | "/account-created" | "/pro-sheet" | "/pro-plans" | "/iap-native" | "/pro-screen" | "/editor" | "/editor-toolbar" | "/properties" | "/sidemenu"} Routes
|
||||
* @param {Routes} prevRoute
|
||||
* @param {Routes} route
|
||||
* @param {Routes[]} conditions
|
||||
* @param {boolean} once
|
||||
* @returns
|
||||
*/
|
||||
|
||||
async function pageView(
|
||||
route,
|
||||
prevRoute = "",
|
||||
conditions = ["/welcome"],
|
||||
once = true
|
||||
) {
|
||||
if (__DEV__) return;
|
||||
if (!(await canUpdateAnalytics(route, conditions)) && once) return;
|
||||
let body = {
|
||||
payload: {
|
||||
website: WEBSITE_ID,
|
||||
url: `notesnook-${Platform.OS}${prevRoute}${route}`,
|
||||
referrer: `https://notesnook.com/notesnook-${Platform.OS}${prevRoute}`,
|
||||
hostname: `notesnook-${Platform.OS}`,
|
||||
language: "en-US",
|
||||
screen: "1920x1080"
|
||||
},
|
||||
type: "pageview"
|
||||
};
|
||||
|
||||
try {
|
||||
let response = await fetch(baseUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": UA
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
console.log("analytics: event sent", route);
|
||||
await saveAnalytics(route);
|
||||
return await response.text();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendEvent(type, value, once = true) {
|
||||
if (__DEV__) return;
|
||||
if (!(await canUpdateAnalytics(type)) && once) return;
|
||||
let body = {
|
||||
payload: {
|
||||
website: WEBSITE_ID,
|
||||
url: "/",
|
||||
event_type: type,
|
||||
event_value: value,
|
||||
hostname: "notesnook-android-app",
|
||||
language: "en-US",
|
||||
screen: "1920x1080"
|
||||
},
|
||||
type: "event"
|
||||
};
|
||||
|
||||
try {
|
||||
let response = await fetch(baseUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": UA
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
console.log(response.status);
|
||||
return await response.text();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
sendEvent,
|
||||
pageView,
|
||||
saveAnalytics
|
||||
};
|
||||
@@ -28,29 +28,7 @@ import filesystem from "../filesystem";
|
||||
import Storage from "./storage";
|
||||
import { RNSqliteDriver } from "./sqlite.kysely";
|
||||
import { getDatabaseKey } from "./encryption";
|
||||
|
||||
database.host(
|
||||
__DEV__
|
||||
? {
|
||||
API_HOST: "https://api.notesnook.com",
|
||||
AUTH_HOST: "https://auth.streetwriters.co",
|
||||
SSE_HOST: "https://events.streetwriters.co",
|
||||
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
|
||||
ISSUES_HOST: "https://issues.streetwriters.co"
|
||||
// API_HOST: "http://192.168.43.5:5264",
|
||||
// AUTH_HOST: "http://192.168.43.5:8264",
|
||||
// SSE_HOST: "http://192.168.43.5:7264",
|
||||
// SUBSCRIPTIONS_HOST: "http://192.168.43.5:9264",
|
||||
// ISSUES_HOST: "http://192.168.43.5:2624"
|
||||
}
|
||||
: {
|
||||
API_HOST: "https://api.notesnook.com",
|
||||
AUTH_HOST: "https://auth.streetwriters.co",
|
||||
SSE_HOST: "https://events.streetwriters.co",
|
||||
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
|
||||
ISSUES_HOST: "https://issues.streetwriters.co"
|
||||
}
|
||||
);
|
||||
import SettingsService from "../../services/settings";
|
||||
|
||||
export async function setupDatabase(password) {
|
||||
const key = await getDatabaseKey(password);
|
||||
@@ -59,6 +37,15 @@ export async function setupDatabase(password) {
|
||||
|
||||
console.log("Opening database with key:", !!key);
|
||||
|
||||
database.host({
|
||||
API_HOST: "https://api.notesnook.com",
|
||||
AUTH_HOST: "https://auth.streetwriters.co",
|
||||
SSE_HOST: "https://events.streetwriters.co",
|
||||
SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
|
||||
ISSUES_HOST: "https://issues.streetwriters.co",
|
||||
...(SettingsService.getProperty("serverUrls") || {})
|
||||
});
|
||||
|
||||
database.setup({
|
||||
storage: Storage,
|
||||
eventsource: Platform.OS === "ios" ? EventSource : AndroidEventSource,
|
||||
|
||||
@@ -21,15 +21,15 @@ import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import {
|
||||
decrypt,
|
||||
decryptMulti,
|
||||
deriveCryptoKey,
|
||||
encrypt,
|
||||
encryptMulti,
|
||||
generateCryptoKey,
|
||||
getCryptoKey,
|
||||
getRandomBytes,
|
||||
hash,
|
||||
removeCryptoKey,
|
||||
decryptMulti,
|
||||
encryptMulti
|
||||
removeCryptoKey
|
||||
} from "./encryption";
|
||||
import { MMKV } from "./mmkv";
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import { Dimensions, Image, Platform } from "react-native";
|
||||
import ImageResizer from "@bam.tech/react-native-image-resizer";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
|
||||
console.log("hello world");
|
||||
/**
|
||||
* Scale down & compress images to screen width
|
||||
* for loading in editor.
|
||||
|
||||
@@ -18,24 +18,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Sodium from "@ammarahmed/react-native-sodium";
|
||||
import {
|
||||
getFileNameWithExtension,
|
||||
isImage,
|
||||
isDocument
|
||||
} from "@notesnook/core/dist/utils/filename";
|
||||
import { getFileNameWithExtension } from "@notesnook/core/dist/utils/filename";
|
||||
import React from "react";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { subscribe, zip } from "react-native-zip-archive";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { ShareComponent } from "../../components/sheets/export-notes/share";
|
||||
import { ToastManager, presentSheet } from "../../services/event-manager";
|
||||
import { useAttachmentStore } from "../../stores/use-attachment-store";
|
||||
import { IOS_APPGROUPID } from "../../utils/constants";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import Storage from "../database/storage";
|
||||
import { cacheDir, copyFileAsync, releasePermissions } from "./utils";
|
||||
import { createCacheDir, exists } from "./io";
|
||||
import { IOS_APPGROUPID } from "../../utils/constants";
|
||||
import { cacheDir, copyFileAsync, releasePermissions } from "./utils";
|
||||
|
||||
export const FileDownloadStatus = {
|
||||
Success: 1,
|
||||
@@ -211,7 +207,11 @@ export default async function downloadAttachment(
|
||||
try {
|
||||
await db
|
||||
.fs()
|
||||
.downloadFile(options.groupId || attachment.hash, attachment.hash);
|
||||
.downloadFile(
|
||||
options.groupId || attachment.hash,
|
||||
attachment.hash,
|
||||
attachment.chunkSize
|
||||
);
|
||||
if (!(await exists(attachment.hash))) {
|
||||
DatabaseLogger.log("Attachment does not exist after download.");
|
||||
return;
|
||||
@@ -259,15 +259,6 @@ export default async function downloadAttachment(
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
attachment.dateUploaded &&
|
||||
!isImage(attachment.mimeType) &&
|
||||
!isDocument(attachment.mimeType)
|
||||
) {
|
||||
RNFetchBlob.fs
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}`)
|
||||
.catch(console.log);
|
||||
}
|
||||
if (Platform.OS === "ios" && !options.cache) {
|
||||
fileUri = folder.uri + `/${filename}`;
|
||||
}
|
||||
@@ -287,7 +278,6 @@ export default async function downloadAttachment(
|
||||
|
||||
return fileUri;
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
if (attachment.dateUploaded) {
|
||||
RNFetchBlob.fs
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}`)
|
||||
@@ -296,6 +286,7 @@ export default async function downloadAttachment(
|
||||
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.hash}_dcache`)
|
||||
.catch(console.log);
|
||||
}
|
||||
DatabaseLogger.error(e);
|
||||
useAttachmentStore.getState().remove(attachment.hash);
|
||||
if (options.throwError) {
|
||||
throw e;
|
||||
|
||||
@@ -17,31 +17,54 @@ 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 hosts from "@notesnook/core/dist/utils/constants";
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import { useAttachmentStore } from "../../stores/use-attachment-store";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import { cacheDir, fileCheck } from "./utils";
|
||||
import { createCacheDir, exists } from "./io";
|
||||
import { ABYTES, cacheDir, getUploadedFileSize, parseS3Error } from "./utils";
|
||||
|
||||
export async function downloadFile(filename, data, cancelToken) {
|
||||
if (!data) {
|
||||
DatabaseLogger.log(`Error downloading file: ${filename}, reason: No data`);
|
||||
export async function downloadFile(filename, requestOptions, cancelToken) {
|
||||
if (!requestOptions) {
|
||||
DatabaseLogger.log(
|
||||
`Error downloading file: ${filename}, reason: No requestOptions`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
DatabaseLogger.log(`Downloading ${filename}`);
|
||||
await createCacheDir();
|
||||
let { url, headers } = data;
|
||||
let path = `${cacheDir}/${filename}`;
|
||||
|
||||
let { url, headers, chunkSize } = requestOptions;
|
||||
let tempFilePath = `${cacheDir}/${filename}_temp`;
|
||||
let originalFilePath = `${cacheDir}/${filename}`;
|
||||
try {
|
||||
if (await exists(filename)) {
|
||||
DatabaseLogger.log(`File Exists already: ${filename}`);
|
||||
return true;
|
||||
}
|
||||
const attachment = await db.attachments.attachment(filename);
|
||||
const size = await getUploadedFileSize(filename);
|
||||
|
||||
if (size === -1) {
|
||||
const error = `Uploaded file verification failed. (File hash: ${filename})`;
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
if (size === 0) {
|
||||
const error = `File length is 0. Please upload this file again from the attachment manager. (File hash: ${filename})`;
|
||||
await db.attachments.markAsFailed(attachment.id, error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const totalChunks = Math.ceil(size / chunkSize);
|
||||
const decryptedLength = size - totalChunks * ABYTES;
|
||||
|
||||
if (attachment && attachment.size !== decryptedLength) {
|
||||
const error = `File length mismatch. Expected ${attachment.size} but got ${decryptedLength} bytes. Please upload this file again from the attachment manager. (File hash: ${filename})`;
|
||||
await db.attachments.markAsFailed(attachment.id, error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
let res = await fetch(url, {
|
||||
method: "GET",
|
||||
@@ -63,34 +86,51 @@ export async function downloadFile(filename, data, cancelToken) {
|
||||
);
|
||||
throw new Error("Unable to resolve download url");
|
||||
}
|
||||
let totalSize = 0;
|
||||
|
||||
DatabaseLogger.log(`Download starting: ${filename}`);
|
||||
let request = RNFetchBlob.config({
|
||||
path: path,
|
||||
path: tempFilePath,
|
||||
IOSBackgroundTask: true
|
||||
})
|
||||
.fetch("GET", downloadUrl, null)
|
||||
.progress((recieved, total) => {
|
||||
.progress(async (recieved, total) => {
|
||||
useAttachmentStore
|
||||
.getState()
|
||||
.setProgress(0, total, filename, recieved, "download");
|
||||
totalSize = total;
|
||||
|
||||
DatabaseLogger.log(`Downloading: ${filename}, ${recieved}/${total}`);
|
||||
});
|
||||
|
||||
cancelToken.cancel = () => {
|
||||
useAttachmentStore.getState().remove(filename);
|
||||
request.cancel();
|
||||
RNFetchBlob.fs.unlink(tempFilePath).catch(console.log);
|
||||
DatabaseLogger.log(`Download cancelled: ${filename}`);
|
||||
};
|
||||
|
||||
let response = await request;
|
||||
await fileCheck(response, totalSize);
|
||||
console.log(response.info().headers);
|
||||
|
||||
const contentType =
|
||||
response.info().headers?.["content-type"] ||
|
||||
response.info().headers?.["Content-Type"];
|
||||
|
||||
if (contentType === "application/xml") {
|
||||
const error = parseS3Error(await response.text());
|
||||
throw new Error(`[${error.Code}] ${error.Message}`);
|
||||
}
|
||||
|
||||
let status = response.info().status;
|
||||
useAttachmentStore.getState().remove(filename);
|
||||
await RNFetchBlob.fs.mv(tempFilePath, originalFilePath);
|
||||
|
||||
if (!(await exists(filename))) {
|
||||
throw new Error("File size mismatch");
|
||||
}
|
||||
|
||||
return status >= 200 && status < 300;
|
||||
} catch (e) {
|
||||
if (e.message !== "canceled") {
|
||||
if (e.message !== "canceled" && !e.message.includes("NoSuchKey")) {
|
||||
ToastManager.show({
|
||||
heading: "Error downloading file",
|
||||
message: e.message,
|
||||
@@ -106,7 +146,8 @@ export async function downloadFile(filename, data, cancelToken) {
|
||||
}
|
||||
|
||||
useAttachmentStore.getState().remove(filename);
|
||||
RNFetchBlob.fs.unlink(path).catch(console.log);
|
||||
RNFetchBlob.fs.unlink(tempFilePath).catch(console.log);
|
||||
RNFetchBlob.fs.unlink(originalFilePath).catch(console.log);
|
||||
DatabaseLogger.error(e, {
|
||||
url,
|
||||
headers
|
||||
@@ -115,37 +156,23 @@ export async function downloadFile(filename, data, cancelToken) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUploadedFileSize(hash) {
|
||||
try {
|
||||
const url = `${hosts.API_HOST}/s3?name=${hash}`;
|
||||
const token = await db.tokenManager.getAccessToken();
|
||||
const attachmentInfo = await fetch(url, {
|
||||
method: "HEAD",
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
const contentLength = parseInt(
|
||||
attachmentInfo.headers?.get("content-length")
|
||||
);
|
||||
return isNaN(contentLength) ? 0 : contentLength;
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkAttachment(hash) {
|
||||
const internetState = await NetInfo.fetch();
|
||||
const isInternetReachable =
|
||||
internetState.isConnected && internetState.isInternetReachable;
|
||||
if (!isInternetReachable) return { success: true };
|
||||
if (!isInternetReachable) return;
|
||||
const attachment = await db.attachments.attachment(hash);
|
||||
if (!attachment) return { failed: "Attachment not found." };
|
||||
|
||||
try {
|
||||
const size = await getUploadedFileSize(hash);
|
||||
console.log("File Size", size);
|
||||
if (size === -1) return { success: true };
|
||||
|
||||
if (size === 0) return { failed: "File length is 0." };
|
||||
if (size === 0)
|
||||
return {
|
||||
failed: `File length is 0. Please upload this file again from the attachment manager. (File hash: ${hash})`
|
||||
};
|
||||
} catch (e) {
|
||||
return { failed: e?.message };
|
||||
}
|
||||
|
||||
@@ -17,17 +17,22 @@ 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 { checkAttachment, downloadFile, getUploadedFileSize } from "./download";
|
||||
import { checkAttachment, downloadFile } from "./download";
|
||||
import {
|
||||
clearFileStorage,
|
||||
deleteFile,
|
||||
exists,
|
||||
readEncrypted,
|
||||
writeEncryptedBase64,
|
||||
hashBase64
|
||||
hashBase64,
|
||||
clearCache,
|
||||
deleteCacheFileByName,
|
||||
deleteCacheFileByPath,
|
||||
bulkExists,
|
||||
getCacheSize
|
||||
} from "./io";
|
||||
import { uploadFile } from "./upload";
|
||||
import { cancelable } from "./utils";
|
||||
import { cancelable, getUploadedFileSize } from "./utils";
|
||||
|
||||
export default {
|
||||
readEncrypted,
|
||||
@@ -39,5 +44,10 @@ export default {
|
||||
exists,
|
||||
clearFileStorage,
|
||||
getUploadedFileSize,
|
||||
checkAttachment
|
||||
checkAttachment,
|
||||
clearCache,
|
||||
deleteCacheFileByName,
|
||||
deleteCacheFileByPath,
|
||||
bulkExists,
|
||||
getCacheSize
|
||||
};
|
||||
|
||||
@@ -20,9 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import Sodium from "@ammarahmed/react-native-sodium";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { eSendEvent } from "../../services/event-manager";
|
||||
import { IOS_APPGROUPID } from "../../utils/constants";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import { cacheDir, cacheDirOld, getRandomId } from "./utils";
|
||||
import { ABYTES, cacheDir, cacheDirOld, getRandomId } from "./utils";
|
||||
|
||||
export async function readEncrypted(filename, key, cipherData) {
|
||||
await migrateFilesFromCache();
|
||||
@@ -158,7 +159,35 @@ export async function migrateFilesFromCache() {
|
||||
}
|
||||
}
|
||||
|
||||
const ABYTES = 17;
|
||||
export async function clearCache() {
|
||||
await RNFetchBlob.fs.unlink(cacheDir).catch(console.log);
|
||||
await createCacheDir();
|
||||
eSendEvent("cache-cleared");
|
||||
}
|
||||
|
||||
export async function deleteCacheFileByPath(path) {
|
||||
await RNFetchBlob.fs.unlink(path).catch(console.log);
|
||||
}
|
||||
|
||||
export async function deleteCacheFileByName(name) {
|
||||
const iosAppGroup =
|
||||
Platform.OS === "ios"
|
||||
? await RNFetchBlob.fs.pathForAppGroup(IOS_APPGROUPID)
|
||||
: null;
|
||||
const appGroupPath = `${iosAppGroup}/${name}`;
|
||||
await RNFetchBlob.fs.unlink(appGroupPath).catch(console.log);
|
||||
await RNFetchBlob.fs.unlink(`${cacheDir}/${name}`).catch(console.log);
|
||||
}
|
||||
|
||||
export async function deleteDCacheFiles() {
|
||||
const files = await RNFetchBlob.fs.ls(cacheDir);
|
||||
for (const file of files) {
|
||||
if (file.includes("_dcache")) {
|
||||
await RNFetchBlob.fs.unlink(file).catch(console.log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function exists(filename) {
|
||||
let path = `${cacheDir}/${filename}`;
|
||||
|
||||
@@ -200,3 +229,29 @@ export async function exists(filename) {
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
export async function bulkExists(files) {
|
||||
const cacheFiles = await RNFetchBlob.fs.ls(cacheDir);
|
||||
let missingFiles = files.filter((file) => !cacheFiles.includes(file));
|
||||
|
||||
if (Platform.OS === "ios") {
|
||||
const iosAppGroup =
|
||||
Platform.OS === "ios"
|
||||
? await RNFetchBlob.fs.pathForAppGroup(IOS_APPGROUPID)
|
||||
: null;
|
||||
const appGroupFiles = await RNFetchBlob.fs.ls(iosAppGroup);
|
||||
missingFiles = missingFiles.filter((file) => !appGroupFiles.includes(file));
|
||||
}
|
||||
|
||||
return missingFiles;
|
||||
}
|
||||
|
||||
export async function getCacheSize() {
|
||||
const stat = await RNFetchBlob.fs.lstat(`file://` + cacheDir);
|
||||
let total = 0;
|
||||
console.log("Total files", stat.length);
|
||||
stat.forEach((s) => {
|
||||
total += parseInt(s.size);
|
||||
});
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -17,32 +17,30 @@ 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 RNFetchBlob from "react-native-blob-util";
|
||||
import { useAttachmentStore } from "../../stores/use-attachment-store";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import { cacheDir } from "./utils";
|
||||
import { isImage, isDocument } from "@notesnook/core/dist/utils/filename";
|
||||
import { Platform } from "react-native";
|
||||
import { IOS_APPGROUPID } from "../../utils/constants";
|
||||
import { createCacheDir } from "./io";
|
||||
import { getUploadedFileSize } from "./download";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import { useAttachmentStore } from "../../stores/use-attachment-store";
|
||||
import { IOS_APPGROUPID } from "../../utils/constants";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import { createCacheDir } from "./io";
|
||||
import { cacheDir, getUploadedFileSize } from "./utils";
|
||||
|
||||
export async function uploadFile(filename, data, cancelToken) {
|
||||
if (!data) return false;
|
||||
let { url, headers } = data;
|
||||
export async function uploadFile(filename, requestOptions, cancelToken) {
|
||||
if (!requestOptions) return false;
|
||||
let { url, headers } = requestOptions;
|
||||
await createCacheDir();
|
||||
DatabaseLogger.info(`Preparing to upload file: ${filename}`);
|
||||
|
||||
try {
|
||||
const uploadedFileSize = await getUploadedFileSize(filename);
|
||||
|
||||
if (uploadedFileSize === -1) {
|
||||
DatabaseLogger.log("Upload verification failed.");
|
||||
return false;
|
||||
const error = `Uploaded file verification failed. (File hash: ${filename})`;
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const isUploaded = uploadedFileSize !== 0;
|
||||
if (isUploaded) {
|
||||
if (uploadedFileSize !== 0) {
|
||||
DatabaseLogger.log(`File ${filename} is already uploaded.`);
|
||||
return true;
|
||||
}
|
||||
@@ -117,9 +115,6 @@ export async function uploadFile(filename, data, cancelToken) {
|
||||
);
|
||||
let attachment = await db.attachments.attachment(filename);
|
||||
if (!attachment) return result;
|
||||
if (!isImage(attachment.mimeType) && !isDocument(attachment.mimeType)) {
|
||||
RNFetchBlob.fs.unlink(`${cacheDir}/${filename}`).catch(console.log);
|
||||
}
|
||||
} else {
|
||||
const fileInfo = await RNFetchBlob.fs.stat(uploadFilePath);
|
||||
throw new Error(
|
||||
|
||||
@@ -17,10 +17,13 @@ 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 * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { DatabaseLogger, db } from "../database";
|
||||
import hosts from "@notesnook/core/dist/utils/constants";
|
||||
|
||||
export const ABYTES = 17;
|
||||
export const cacheDirOld = RNFetchBlob.fs.dirs.CacheDir;
|
||||
|
||||
export const cacheDir =
|
||||
@@ -34,24 +37,36 @@ export function getRandomId(prefix) {
|
||||
.replace("0.", prefix || "");
|
||||
}
|
||||
|
||||
export function extractValueFromXmlTag(code, xml) {
|
||||
if (!xml.includes(code)) return `Unknown ${code}`;
|
||||
return xml.slice(
|
||||
xml.indexOf(`<${code}>`) + code.length + 2,
|
||||
xml.indexOf(`</${code}>`)
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {string | undefined} data
|
||||
* @returns
|
||||
*/
|
||||
export function parseS3Error(data) {
|
||||
const xml = typeof data === "string" ? data : null;
|
||||
|
||||
export async function fileCheck(response, totalSize) {
|
||||
if (totalSize < 1000) {
|
||||
let text = await response.text();
|
||||
if (text.startsWith("<?xml")) {
|
||||
let errorJson = {
|
||||
Code: extractValueFromXmlTag("Code", text),
|
||||
Message: extractValueFromXmlTag("Message", text)
|
||||
};
|
||||
throw new Error(`${errorJson.Code}: ${errorJson.Message}`);
|
||||
const error = {
|
||||
Code: "UNKNOWN",
|
||||
Message: xml
|
||||
};
|
||||
|
||||
try {
|
||||
if (!xml) return error;
|
||||
const doc = new DOMParser().parseFromString(xml, "text/xml");
|
||||
|
||||
const ErrorElement = doc.getElementsByTagName("Error")[0];
|
||||
if (!ErrorElement) return error;
|
||||
|
||||
for (const child of ErrorElement.children) {
|
||||
if (
|
||||
child.textContent &&
|
||||
(child.tagName === "Code" || child.tagName === "Message")
|
||||
)
|
||||
error[child.tagName] = child.textContent;
|
||||
}
|
||||
return error;
|
||||
} catch (e) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,12 +74,11 @@ export function cancelable(operation) {
|
||||
const cancelToken = {
|
||||
cancel: () => {}
|
||||
};
|
||||
return (filename, { url, headers }) => {
|
||||
return (filename, requestOptions) => {
|
||||
return {
|
||||
execute: () => operation(filename, { url, headers }, cancelToken),
|
||||
execute: () => operation(filename, requestOptions, cancelToken),
|
||||
cancel: async () => {
|
||||
await cancelToken.cancel();
|
||||
RNFetchBlob.fs.unlink(`${cacheDir}/${filename}`).catch(console.log);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -91,3 +105,21 @@ export async function releasePermissions(path) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUploadedFileSize(hash) {
|
||||
try {
|
||||
const url = `${hosts.API_HOST}/s3?name=${hash}`;
|
||||
const token = await db.tokenManager.getAccessToken();
|
||||
const attachmentInfo = await fetch(url, {
|
||||
method: "HEAD",
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
const contentLength = parseInt(
|
||||
attachmentInfo.headers?.get("content-length")
|
||||
);
|
||||
return isNaN(contentLength) ? 0 : contentLength;
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,12 +118,14 @@ const Actions = ({
|
||||
setLoading({
|
||||
name: "Run file check"
|
||||
});
|
||||
const res = await filesystem.checkAttachment(attachment.hash);
|
||||
if (res.failed) {
|
||||
db.attachments.markAsFailed(attachment.id, res.failed);
|
||||
setFailed(res.failed);
|
||||
const result = await filesystem.checkAttachment(attachment.hash);
|
||||
if (!result) return;
|
||||
|
||||
if (result.failed) {
|
||||
db.attachments.markAsFailed(attachment.id, result.failed);
|
||||
setFailed(result.failed);
|
||||
ToastManager.show({
|
||||
heading: "File check failed with error: " + res.failed,
|
||||
heading: "File check failed with error: " + result.failed,
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
|
||||
@@ -122,10 +122,11 @@ export const AttachmentDialog = ({ note }: { note?: Note }) => {
|
||||
const attachment = (await attachments.item(i))?.item;
|
||||
if (!attachment) continue;
|
||||
const result = await filesystem.checkAttachment(attachment.hash);
|
||||
if (!result) return;
|
||||
if (result.failed) {
|
||||
await db.attachments.markAsFailed(attachment.hash, result.failed);
|
||||
} else {
|
||||
await db.attachments.markAsFailed(attachment.id, undefined);
|
||||
await db.attachments.markAsFailed(attachment.id);
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
|
||||
@@ -68,7 +68,8 @@ export const ChangePassword = () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const result = await BackupService.run(false, "change-password-dialog");
|
||||
if (!result) throw new Error("Failed to create backup");
|
||||
if (result.error)
|
||||
throw new Error(`Failed to create backup: ${result.error}`);
|
||||
|
||||
await db.user.clearSessions();
|
||||
await db.user.changePassword(oldPassword.current, password.current);
|
||||
|
||||
@@ -35,6 +35,7 @@ import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { hideAuth } from "./common";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import SettingsService from "../../services/settings";
|
||||
|
||||
export const Signup = ({ changeMode, trial }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -77,6 +78,7 @@ export const Signup = ({ changeMode, trial }) => {
|
||||
clearMessage();
|
||||
setEmailVerifyMessage();
|
||||
hideAuth();
|
||||
SettingsService.setProperty("encryptedBackup", true);
|
||||
await sleep(300);
|
||||
if (trial) {
|
||||
PremiumService.sheet(null, null, true);
|
||||
|
||||
@@ -83,7 +83,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
setLoading(false);
|
||||
setTimeout(() => {
|
||||
passwordInputRef.current?.focus();
|
||||
}, 1);
|
||||
}, 500);
|
||||
callback && callback(true);
|
||||
}
|
||||
callback && callback(false);
|
||||
|
||||
@@ -23,6 +23,7 @@ import { AnnouncementDialog } from "../announcements";
|
||||
import AuthModal from "../auth/auth-modal";
|
||||
import { SessionExpired } from "../auth/session-expired";
|
||||
import { Dialog } from "../dialog";
|
||||
import { AppLockPassword } from "../dialogs/applock-password";
|
||||
import JumpToSectionDialog from "../dialogs/jump-to-section";
|
||||
import { LoadingDialog } from "../dialogs/loading";
|
||||
import PDFPreview from "../dialogs/pdf-preview";
|
||||
@@ -35,8 +36,7 @@ import { Expiring } from "../premium/expiring";
|
||||
import SheetProvider from "../sheet-provider";
|
||||
import RateAppSheet from "../sheets/rate-app";
|
||||
import RecoveryKeySheet from "../sheets/recovery-key";
|
||||
import RestoreDataSheet from "../sheets/restore-data";
|
||||
import { AppLockPassword } from "../dialogs/applock-password";
|
||||
import Progress from "../dialogs/progress";
|
||||
|
||||
const DialogProvider = () => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -52,7 +52,6 @@ const DialogProvider = () => {
|
||||
<RecoveryKeySheet colors={colors} />
|
||||
<SheetProvider />
|
||||
<SheetProvider context="sync_progress" />
|
||||
<RestoreDataSheet />
|
||||
<ResultDialog />
|
||||
<VaultDialog colors={colors} />
|
||||
<RateAppSheet />
|
||||
@@ -62,6 +61,7 @@ const DialogProvider = () => {
|
||||
<SessionExpired />
|
||||
<PDFPreview />
|
||||
<JumpToSectionDialog />
|
||||
<Progress />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -32,21 +32,29 @@ const DialogContainer = ({
|
||||
}: ViewProps & {
|
||||
width?: any;
|
||||
height?: any;
|
||||
noBorder?: boolean;
|
||||
}) => {
|
||||
const { colors } = useThemeColors();
|
||||
|
||||
return (
|
||||
<View
|
||||
{...restProps}
|
||||
style={{
|
||||
...getElevationStyle(5),
|
||||
width: width || DDS.isTab ? 500 : "85%",
|
||||
maxHeight: height || 450,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.primary.background,
|
||||
paddingTop: 12,
|
||||
...getContainerBorder(colors.secondary.background, 0.8, 0.05)
|
||||
}}
|
||||
style={[
|
||||
style,
|
||||
{
|
||||
width: width || DDS.isTab ? 500 : "85%",
|
||||
maxHeight: height || 450,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.primary.background,
|
||||
paddingTop: 12
|
||||
},
|
||||
restProps?.noBorder
|
||||
? {}
|
||||
: {
|
||||
...getElevationStyle(5),
|
||||
...getContainerBorder(colors.secondary.background, 0.8, 0.05)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ type DialogInfo = {
|
||||
paragraph?: string;
|
||||
positiveText?: string;
|
||||
negativeText?: string;
|
||||
positivePress?: (value: any) => void;
|
||||
positivePress?: (...args: any[]) => void;
|
||||
onClose?: () => void;
|
||||
positiveType?:
|
||||
| "transparent"
|
||||
@@ -45,6 +45,15 @@ type DialogInfo = {
|
||||
context: "global" | "local" | (string & {});
|
||||
secureTextEntry?: boolean;
|
||||
keyboardType?: string;
|
||||
check?: {
|
||||
info: string;
|
||||
type?: string;
|
||||
defaultValue?: boolean;
|
||||
};
|
||||
notice: {
|
||||
text: string;
|
||||
type: "alert" | "information";
|
||||
};
|
||||
};
|
||||
|
||||
export function presentDialog(data: Partial<DialogInfo>): void {
|
||||
|
||||
@@ -37,6 +37,7 @@ import DialogHeader from "./dialog-header";
|
||||
import { useCallback } from "react";
|
||||
import { Button } from "../ui/button";
|
||||
import { getContainerBorder } from "../../utils/colors";
|
||||
import { Notice } from "../ui/notice";
|
||||
|
||||
export const Dialog = ({ context = "global" }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -62,7 +63,8 @@ export const Dialog = ({ context = "global" }) => {
|
||||
disableBackdropClosing: false,
|
||||
check: {
|
||||
info: "Check",
|
||||
type: "transparent"
|
||||
type: "transparent",
|
||||
defaultValue: false
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,7 +88,7 @@ export const Dialog = ({ context = "global" }) => {
|
||||
if (!data.context) data.context = "global";
|
||||
if (data.context !== context) return;
|
||||
setDialogInfo(data);
|
||||
setChecked(false);
|
||||
setChecked(data.check?.defaultValue);
|
||||
values.current.inputValue = data.defaultValue;
|
||||
setVisible(true);
|
||||
},
|
||||
@@ -180,6 +182,19 @@ export const Dialog = ({ context = "global" }) => {
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{dialogInfo?.notice ? (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
>
|
||||
<Notice
|
||||
type={dialogInfo.notice.type || "information"}
|
||||
text={dialogInfo.notice.text}
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{dialogInfo.check ? (
|
||||
<>
|
||||
<Button
|
||||
@@ -198,7 +213,7 @@ export const Dialog = ({ context = "global" }) => {
|
||||
iconSize={20}
|
||||
width="100%"
|
||||
title={dialogInfo.check.info}
|
||||
type={checked ? dialogInfo.check.type || "selected" : "plain"}
|
||||
type={checked ? dialogInfo.check.type || "plain" : "plain"}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -44,6 +44,7 @@ import { ProgressBarComponent } from "../../ui/svg/lazy";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { sleep } from "../../../utils/time";
|
||||
import { MMKV } from "../../../common/database/mmkv";
|
||||
import { deleteCacheFileByPath } from "../../../common/filesystem/io";
|
||||
|
||||
const WIN_WIDTH = Dimensions.get("window").width;
|
||||
const WIN_HEIGHT = Dimensions.get("window").height;
|
||||
@@ -124,6 +125,7 @@ const PDFPreview = () => {
|
||||
);
|
||||
|
||||
const close = () => {
|
||||
deleteCacheFileByPath(pdfSource);
|
||||
setPDFSource(null);
|
||||
setVisible(false);
|
||||
setPassword("");
|
||||
|
||||
198
apps/mobile/app/components/dialogs/progress/index.tsx
Normal file
198
apps/mobile/app/components/dialogs/progress/index.tsx
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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 { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useEffect } from "react";
|
||||
import { View } from "react-native";
|
||||
import { eSendEvent, eSubscribeEvent } from "../../../services/event-manager";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
import { Dialog } from "../../dialog";
|
||||
import BaseDialog from "../../dialog/base-dialog";
|
||||
import DialogContainer from "../../dialog/dialog-container";
|
||||
import { Button } from "../../ui/button";
|
||||
import { ProgressBarComponent } from "../../ui/svg/lazy";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
|
||||
export type ProgressOptions = {
|
||||
progress?: string;
|
||||
cancelCallback?: () => void;
|
||||
title?: string;
|
||||
paragraph?: string;
|
||||
fillBackground?: boolean;
|
||||
canHideProgress?: boolean;
|
||||
};
|
||||
|
||||
export const PROGRESS_EVENTS = {
|
||||
start: "startProgress",
|
||||
end: "endProgress",
|
||||
update: "updateProgress"
|
||||
};
|
||||
|
||||
export default function Progress() {
|
||||
const { colors } = useThemeColors();
|
||||
const [progress, setProgress] = React.useState<string | undefined>();
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
const cancelCallback = React.useRef<() => void>();
|
||||
const [data, setData] = React.useState<{
|
||||
title?: string;
|
||||
paragraph?: string;
|
||||
fillBackground?: boolean;
|
||||
canHideProgress?: boolean;
|
||||
}>();
|
||||
|
||||
useEffect(() => {
|
||||
const events = [
|
||||
eSubscribeEvent(PROGRESS_EVENTS.start, (options: ProgressOptions) => {
|
||||
setProgress(options.progress);
|
||||
cancelCallback.current = options.cancelCallback;
|
||||
console.log("options", options.fillBackground);
|
||||
setData({
|
||||
title: options.title,
|
||||
paragraph: options.paragraph,
|
||||
fillBackground: options.fillBackground,
|
||||
canHideProgress: options.canHideProgress
|
||||
});
|
||||
setVisible(true);
|
||||
}),
|
||||
eSubscribeEvent(PROGRESS_EVENTS.end, () => {
|
||||
setProgress(undefined);
|
||||
setVisible(false);
|
||||
setData(undefined);
|
||||
cancelCallback.current?.();
|
||||
cancelCallback.current = undefined;
|
||||
}),
|
||||
eSubscribeEvent(PROGRESS_EVENTS.update, (options: ProgressOptions) => {
|
||||
setProgress(options.progress);
|
||||
if (options.cancelCallback) {
|
||||
cancelCallback.current = options.cancelCallback;
|
||||
}
|
||||
|
||||
const data: ProgressOptions = {};
|
||||
if (options.title) data.title = options.title;
|
||||
if (options.paragraph) data.paragraph = options.paragraph;
|
||||
if (options.fillBackground)
|
||||
data.fillBackground = options.fillBackground;
|
||||
|
||||
setData((current) => {
|
||||
return {
|
||||
...current,
|
||||
...data
|
||||
};
|
||||
});
|
||||
})
|
||||
];
|
||||
return () => {
|
||||
events.forEach((event) => event?.unsubscribe());
|
||||
cancelCallback.current = undefined;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return !visible ? null : (
|
||||
<BaseDialog
|
||||
background={data?.fillBackground ? colors.primary.background : undefined}
|
||||
visible
|
||||
>
|
||||
<DialogContainer
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
paddingBottom: 10
|
||||
}}
|
||||
noBorder={data?.fillBackground ? true : false}
|
||||
>
|
||||
<Dialog context="local" />
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 12,
|
||||
gap: 10,
|
||||
paddingBottom: 20
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
color={colors.primary.paragraph}
|
||||
size={SIZE.lg}
|
||||
>
|
||||
{data?.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{progress ? progress : data?.paragraph}
|
||||
</Paragraph>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
width: 100,
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<ProgressBarComponent
|
||||
height={5}
|
||||
width={100}
|
||||
animated={true}
|
||||
useNativeDriver
|
||||
indeterminate
|
||||
indeterminateAnimationDuration={2000}
|
||||
unfilledColor={colors.secondary.background}
|
||||
color={colors.primary.accent}
|
||||
borderWidth={0}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{data?.canHideProgress ? null : (
|
||||
<Button
|
||||
title={cancelCallback.current ? "Cancel" : "Hide"}
|
||||
type="secondaryAccented"
|
||||
onPress={() => {
|
||||
if (cancelCallback.current) {
|
||||
cancelCallback.current?.();
|
||||
}
|
||||
setVisible(false);
|
||||
setProgress(undefined);
|
||||
setData(undefined);
|
||||
}}
|
||||
width="100%"
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</DialogContainer>
|
||||
</BaseDialog>
|
||||
);
|
||||
}
|
||||
|
||||
export function startProgress(options: ProgressOptions) {
|
||||
eSendEvent(PROGRESS_EVENTS.start, options);
|
||||
}
|
||||
|
||||
export function endProgress() {
|
||||
eSendEvent(PROGRESS_EVENTS.end);
|
||||
}
|
||||
|
||||
export function updateProgress(options: ProgressOptions) {
|
||||
eSendEvent(PROGRESS_EVENTS.update, options);
|
||||
}
|
||||
@@ -43,9 +43,6 @@ import { eSendEvent } from "../../services/event-manager";
|
||||
|
||||
const Intro = ({ navigation }) => {
|
||||
const { colors } = useThemeColors();
|
||||
const isTelemetryEnabled = useSettingStore(
|
||||
(state) => state.settings.telemetry
|
||||
);
|
||||
const { width, height } = useWindowDimensions();
|
||||
const deviceMode = useSettingStore((state) => state.deviceMode);
|
||||
const insets = useGlobalSafeAreaInsets();
|
||||
@@ -217,44 +214,6 @@ const Intro = ({ navigation }) => {
|
||||
type="accent"
|
||||
title="Get started"
|
||||
/>
|
||||
|
||||
<TouchableOpacity
|
||||
activeOpacity={1}
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignSelf: "center",
|
||||
width: "90%",
|
||||
marginBottom: 12,
|
||||
paddingHorizontal: 12,
|
||||
justifyContent: "center",
|
||||
padding: 12,
|
||||
maxWidth: 500
|
||||
}}
|
||||
onPress={() => {
|
||||
SettingsService.set({ telemetry: !isTelemetryEnabled });
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
size={SIZE.md}
|
||||
name={
|
||||
isTelemetryEnabled ? "checkbox-marked" : "checkbox-blank-outline"
|
||||
}
|
||||
color={
|
||||
isTelemetryEnabled ? colors.primary.accent : colors.primary.icon
|
||||
}
|
||||
/>
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
marginLeft: 6
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
>
|
||||
Help improve Notesnook by sending completely anonymized{" "}
|
||||
<Heading size={SIZE.xs}>private analytics and bug reports.</Heading>
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
@@ -95,9 +95,9 @@ export default function Migrate() {
|
||||
await sleep(1);
|
||||
const { error, report } = await BackupService.run(false, "local");
|
||||
if (error) {
|
||||
ToastManager.error(error, "Backup failed");
|
||||
ToastManager.error(error as Error, "Backup failed");
|
||||
if (report) {
|
||||
reportError(error);
|
||||
reportError(error as Error);
|
||||
}
|
||||
setLoading(false);
|
||||
return;
|
||||
|
||||
@@ -1,600 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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 { getFormattedDate } from "@notesnook/common";
|
||||
import { EVENTS } from "@notesnook/core/dist/common";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, Platform, View } from "react-native";
|
||||
import { FlatList } from "react-native-actions-sheet";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import DocumentPicker from "react-native-document-picker";
|
||||
import * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { unzip } from "react-native-zip-archive";
|
||||
import { db } from "../../../common/database";
|
||||
import storage from "../../../common/database/storage";
|
||||
import { cacheDir, copyFileAsync } from "../../../common/filesystem/utils";
|
||||
import {
|
||||
ToastManager,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from "../../../services/event-manager";
|
||||
import Navigation from "../../../services/navigation";
|
||||
import SettingsService from "../../../services/settings";
|
||||
import { refreshAllStores } from "../../../stores/create-db-collection-store";
|
||||
import { eCloseRestoreDialog, eOpenRestoreDialog } from "../../../utils/events";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
import { Dialog } from "../../dialog";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import { presentDialog } from "../../dialog/functions";
|
||||
import { Toast } from "../../toast";
|
||||
import { Button } from "../../ui/button";
|
||||
import Seperator from "../../ui/seperator";
|
||||
import SheetWrapper from "../../ui/sheet";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
|
||||
const RestoreDataSheet = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [restoring, setRestoring] = useState(false);
|
||||
const sheet = useRef();
|
||||
useEffect(() => {
|
||||
const open = async () => {
|
||||
setVisible(true);
|
||||
setTimeout(() => {
|
||||
sheet.current?.show();
|
||||
}, 1);
|
||||
};
|
||||
eSubscribeEvent(eOpenRestoreDialog, open);
|
||||
eSubscribeEvent(eCloseRestoreDialog, close);
|
||||
return () => {
|
||||
eUnSubscribeEvent(eOpenRestoreDialog, open);
|
||||
eUnSubscribeEvent(eCloseRestoreDialog, close);
|
||||
};
|
||||
}, [close]);
|
||||
|
||||
const close = useCallback(() => {
|
||||
if (restoring) {
|
||||
showIsWorking();
|
||||
return;
|
||||
}
|
||||
sheet.current?.hide();
|
||||
setTimeout(() => {
|
||||
setVisible(false);
|
||||
}, 150);
|
||||
}, [restoring]);
|
||||
|
||||
const showIsWorking = () => {
|
||||
ToastManager.show({
|
||||
heading: "Restoring Backup",
|
||||
message: "Your backup data is being restored. please wait.",
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
};
|
||||
|
||||
return !visible ? null : (
|
||||
<SheetWrapper
|
||||
fwdRef={sheet}
|
||||
gestureEnabled={!restoring}
|
||||
closeOnTouchBackdrop={!restoring}
|
||||
onClose={() => {
|
||||
setVisible(false);
|
||||
close();
|
||||
}}
|
||||
>
|
||||
<RestoreDataComponent
|
||||
close={close}
|
||||
restoring={restoring}
|
||||
setRestoring={setRestoring}
|
||||
actionSheetRef={sheet}
|
||||
/>
|
||||
<Toast context="local" />
|
||||
</SheetWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default RestoreDataSheet;
|
||||
|
||||
const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
|
||||
const { colors } = useThemeColors();
|
||||
const [files, setFiles] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [backupDirectoryAndroid, setBackupDirectoryAndroid] = useState(false);
|
||||
const [progress, setProgress] = useState();
|
||||
useEffect(() => {
|
||||
const subscription = db.eventManager.subscribe(
|
||||
EVENTS.migrationProgress,
|
||||
(progress) => {
|
||||
setProgress(progress);
|
||||
}
|
||||
);
|
||||
return () => {
|
||||
subscription?.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
checkBackups();
|
||||
}, 1000);
|
||||
}, []);
|
||||
|
||||
const restore = async (item) => {
|
||||
if (restoring) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const file = Platform.OS === "ios" ? item.path : item.uri;
|
||||
console.log(file);
|
||||
if (file.endsWith(".nnbackupz")) {
|
||||
setRestoring(true);
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
const cacheFile = `file://${RNFetchBlob.fs.dirs.CacheDir}/backup.zip`;
|
||||
if (await RNFetchBlob.fs.exists(cacheFile)) {
|
||||
await RNFetchBlob.fs.unlink(cacheFile);
|
||||
}
|
||||
await RNFetchBlob.fs.createFile(cacheFile, "", "utf8");
|
||||
console.log("copying");
|
||||
await copyFileAsync(file, cacheFile);
|
||||
console.log("copied");
|
||||
await restoreFromZip(cacheFile);
|
||||
} else {
|
||||
await restoreFromZip(file, false);
|
||||
}
|
||||
} else if (file.endsWith(".nnbackup")) {
|
||||
let backup;
|
||||
if (Platform.OS === "android") {
|
||||
backup = await ScopedStorage.readFile(file, "utf8");
|
||||
} else {
|
||||
backup = await RNFetchBlob.fs.readFile(file, "utf8");
|
||||
}
|
||||
await restoreFromNNBackup(JSON.parse(backup));
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("error", e);
|
||||
setRestoring(false);
|
||||
backupError(e);
|
||||
}
|
||||
};
|
||||
|
||||
const withPassword = () => {
|
||||
return new Promise((resolve) => {
|
||||
let resolved = false;
|
||||
presentDialog({
|
||||
context: "local",
|
||||
title: "Encrypted backup",
|
||||
input: true,
|
||||
inputPlaceholder: "Password",
|
||||
paragraph: "Please enter password of this backup file",
|
||||
positiveText: "Restore",
|
||||
secureTextEntry: true,
|
||||
onClose: () => {
|
||||
if (resolved) return;
|
||||
resolve(undefined);
|
||||
},
|
||||
negativeText: "Cancel",
|
||||
positivePress: async (password, isEncryptionKey) => {
|
||||
resolve({
|
||||
value: password,
|
||||
isEncryptionKey
|
||||
});
|
||||
resolved = true;
|
||||
return true;
|
||||
},
|
||||
check: {
|
||||
info: "Use encryption key",
|
||||
type: "transparent"
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const checkBackups = async () => {
|
||||
try {
|
||||
let files = [];
|
||||
if (Platform.OS === "android") {
|
||||
let backupDirectory = SettingsService.get().backupDirectoryAndroid;
|
||||
if (backupDirectory) {
|
||||
setBackupDirectoryAndroid(backupDirectory);
|
||||
files = await ScopedStorage.listFiles(backupDirectory.uri);
|
||||
} else {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
let path = await storage.checkAndCreateDir("/backups/");
|
||||
files = await RNFetchBlob.fs.lstat(path);
|
||||
}
|
||||
files = files
|
||||
.filter((file) => {
|
||||
const name = Platform.OS === "android" ? file.name : file.filename;
|
||||
return name.endsWith(".nnbackup") || name.endsWith(".nnbackupz");
|
||||
})
|
||||
.sort(function (a, b) {
|
||||
let timeA = a.lastModified;
|
||||
let timeB = b.lastModified;
|
||||
return timeB - timeA;
|
||||
});
|
||||
setFiles(files);
|
||||
setLoading(false);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const restoreBackup = async (backup, password, key) => {
|
||||
await db.transaction(async () => {
|
||||
await db.backup.import(backup, password, key);
|
||||
});
|
||||
await db.initCollections();
|
||||
refreshAllStores();
|
||||
ToastManager.show({
|
||||
heading: "Backup restored successfully.",
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
Navigation.queueRoutesForUpdate();
|
||||
return true;
|
||||
};
|
||||
|
||||
const backupError = (e) => {
|
||||
console.log(e.stack);
|
||||
ToastManager.show({
|
||||
heading: "Restore failed",
|
||||
message:
|
||||
e.message ||
|
||||
"The selected backup data file is invalid. You must select a *.nnbackup file to restore.",
|
||||
type: "error",
|
||||
context: "local"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} file
|
||||
*/
|
||||
async function restoreFromZip(file, remove) {
|
||||
try {
|
||||
const zipOutputFolder = `${cacheDir}/backup_extracted`;
|
||||
if (await RNFetchBlob.fs.exists(zipOutputFolder)) {
|
||||
await RNFetchBlob.fs.unlink(zipOutputFolder);
|
||||
await RNFetchBlob.fs.mkdir(zipOutputFolder);
|
||||
}
|
||||
await unzip(file, zipOutputFolder);
|
||||
console.log("Unzipped files successfully to", zipOutputFolder);
|
||||
|
||||
const backupFiles = await RNFetchBlob.fs.ls(zipOutputFolder);
|
||||
|
||||
// if (backupFiles.findIndex((file) => file === ".nnbackup") === -1) {
|
||||
// throw new Error("Backup file is invalid");
|
||||
// }
|
||||
|
||||
await db.transaction(async () => {
|
||||
let password;
|
||||
let key;
|
||||
console.log(
|
||||
`Found ${backupFiles?.length} files to restore from backup`
|
||||
);
|
||||
for (const path of backupFiles) {
|
||||
if (path === ".nnbackup") continue;
|
||||
const filePath = `${zipOutputFolder}/${path}`;
|
||||
const data = await RNFetchBlob.fs.readFile(filePath, "utf8");
|
||||
const parsed = JSON.parse(data);
|
||||
|
||||
if (parsed.encrypted && !password) {
|
||||
console.log("Backup is encrypted...", "requesting password");
|
||||
const { value, isEncryptionKey } = await withPassword();
|
||||
|
||||
if (isEncryptionKey) {
|
||||
key = value;
|
||||
} else {
|
||||
password = value;
|
||||
}
|
||||
if (!password && !key) throw new Error("Failed to decrypt backup");
|
||||
}
|
||||
await db.backup.import(parsed, password, key);
|
||||
console.log("Imported", path);
|
||||
}
|
||||
});
|
||||
// Remove files from cache
|
||||
RNFetchBlob.fs.unlink(zipOutputFolder).catch(console.log);
|
||||
if (remove) {
|
||||
RNFetchBlob.fs.unlink(file).catch(console.log);
|
||||
}
|
||||
|
||||
refreshAllStores();
|
||||
Navigation.queueRoutesForUpdate();
|
||||
setRestoring(false);
|
||||
close();
|
||||
ToastManager.show({
|
||||
heading: "Backup restored successfully.",
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
} catch (e) {
|
||||
backupError(e);
|
||||
setRestoring(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} file
|
||||
*/
|
||||
async function restoreFromNNBackup(backup) {
|
||||
try {
|
||||
if (backup.data.iv && backup.data.salt) {
|
||||
const { value, isEncryptionKey } = await withPassword();
|
||||
|
||||
let key;
|
||||
let password;
|
||||
if (isEncryptionKey) {
|
||||
key = value;
|
||||
} else {
|
||||
password = value;
|
||||
}
|
||||
|
||||
if (key || password) {
|
||||
try {
|
||||
await restoreBackup(backup, password, key);
|
||||
close();
|
||||
setRestoring(false);
|
||||
} catch (e) {
|
||||
setRestoring(false);
|
||||
backupError(e);
|
||||
}
|
||||
} else {
|
||||
setRestoring(false);
|
||||
}
|
||||
} else {
|
||||
await restoreBackup(backup);
|
||||
setRestoring(false);
|
||||
close();
|
||||
}
|
||||
} catch (e) {
|
||||
setRestoring(false);
|
||||
backupError(e);
|
||||
}
|
||||
}
|
||||
|
||||
const button = {
|
||||
title: "Restore from files",
|
||||
onPress: async () => {
|
||||
if (restoring) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: true
|
||||
});
|
||||
console.log("disabled...");
|
||||
const file = await DocumentPicker.pickSingle({
|
||||
copyTo: "cachesDirectory"
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: false
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
if (file.name.endsWith(".nnbackupz")) {
|
||||
setRestoring(true);
|
||||
await restoreFromZip(file.fileCopyUri, true);
|
||||
} else if (file.name.endsWith(".nnbackup")) {
|
||||
RNFetchBlob.fs.unlink(file.fileCopyUri).catch(console.log);
|
||||
setRestoring(true);
|
||||
const data = await fetch(file.uri);
|
||||
await restoreFromNNBackup(await data.json());
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("error", e.stack);
|
||||
setTimeout(() => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: false
|
||||
});
|
||||
}, 1000);
|
||||
setRestoring(false);
|
||||
backupError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const renderItem = ({ item, index }) => (
|
||||
<View
|
||||
style={{
|
||||
minHeight: 50,
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
borderRadius: 0,
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 0.5,
|
||||
borderBottomColor: colors.primary.border
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
maxWidth: "75%"
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.sm} style={{ width: "100%", maxWidth: "100%" }}>
|
||||
{getFormattedDate(item?.lastModified * 1)}
|
||||
</Paragraph>
|
||||
<Paragraph size={SIZE.xs}>
|
||||
{(item.filename || item.name).replace(".nnbackup", "")}
|
||||
</Paragraph>
|
||||
</View>
|
||||
<Button
|
||||
title="Restore"
|
||||
height={30}
|
||||
type="accent"
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
fontSize={SIZE.sm - 1}
|
||||
onPress={() => restore(item, index)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<View>
|
||||
<Dialog context="local" />
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
paddingHorizontal: 8,
|
||||
paddingRight: 8,
|
||||
alignItems: "center",
|
||||
paddingTop: restoring ? 8 : 0
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Backups"
|
||||
paragraph={`All the backups are stored in ${
|
||||
Platform.OS === "ios"
|
||||
? "File Manager/Notesnook/Backups"
|
||||
: "selected backups folder."
|
||||
}`}
|
||||
button={button}
|
||||
/>
|
||||
</View>
|
||||
<Seperator half />
|
||||
<FlatList
|
||||
ListEmptyComponent={
|
||||
!restoring ? (
|
||||
loading ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 100
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color={colors.primary.accent}
|
||||
size={SIZE.lg}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 100
|
||||
}}
|
||||
>
|
||||
{Platform.OS === "android" && !backupDirectoryAndroid ? (
|
||||
<>
|
||||
<Button
|
||||
title="Select backups folder"
|
||||
icon="folder"
|
||||
onPress={async () => {
|
||||
let folder = await ScopedStorage.openDocumentTree(
|
||||
true
|
||||
);
|
||||
let subfolder;
|
||||
if (folder.name !== "Notesnook backups") {
|
||||
subfolder = await ScopedStorage.createDirectory(
|
||||
folder.uri,
|
||||
"Notesnook backups"
|
||||
);
|
||||
} else {
|
||||
subfolder = folder;
|
||||
}
|
||||
SettingsService.set({
|
||||
backupDirectoryAndroid: subfolder
|
||||
});
|
||||
setBackupDirectoryAndroid(subfolder);
|
||||
setLoading(true);
|
||||
checkBackups();
|
||||
}}
|
||||
style={{
|
||||
marginTop: 10,
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
height={30}
|
||||
width={null}
|
||||
/>
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center",
|
||||
marginTop: 5
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
textBreakStrategy="balanced"
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
Select the folder that includes your backup files to
|
||||
list them here.
|
||||
</Paragraph>
|
||||
</>
|
||||
) : (
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
No backups found
|
||||
</Paragraph>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 200
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator color={colors.primary.accent} />
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
Restoring {progress ? progress?.collection : null}
|
||||
{progress ? `(${progress.current}/${progress.total}) ` : null}
|
||||
...Please wait.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
keyExtractor={(item) => item.name || item.filename}
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
data={restoring || loading ? [] : files}
|
||||
renderItem={renderItem}
|
||||
ListFooterComponent={
|
||||
restoring || loading || files.length === 0 ? null : (
|
||||
<View
|
||||
style={{
|
||||
height: 200
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -112,7 +112,7 @@ export const Button = ({
|
||||
NativeTooltip.show(event, tooltipText, NativeTooltip.POSITIONS.TOP);
|
||||
}
|
||||
}}
|
||||
disabled={loading}
|
||||
disabled={loading || restProps.disabled}
|
||||
type={type}
|
||||
accentColor={accentColor}
|
||||
accentText={accentText}
|
||||
@@ -132,6 +132,7 @@ export const Button = ({
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "row",
|
||||
opacity: restProps?.disabled ? 0.5 : 1,
|
||||
...(style as ViewStyle)
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -41,6 +41,7 @@ import { SIZE } from "../../../utils/size";
|
||||
import { IconButton } from "../icon-button";
|
||||
import Paragraph from "../typography/paragraph";
|
||||
import phone from "phone";
|
||||
import isURL from "validator/lib/isURL";
|
||||
|
||||
interface InputProps extends TextInputProps {
|
||||
fwdRef?: RefObject<TextInput>;
|
||||
@@ -49,7 +50,8 @@ interface InputProps extends TextInputProps {
|
||||
| "email"
|
||||
| "confirmPassword"
|
||||
| "username"
|
||||
| "phonenumber";
|
||||
| "phonenumber"
|
||||
| "url";
|
||||
loading?: boolean;
|
||||
onSubmit?: (
|
||||
event: NativeSyntheticEvent<TextInputSubmitEditingEventData>
|
||||
@@ -151,6 +153,9 @@ const Input = ({
|
||||
case "confirmPassword":
|
||||
isError = customValidator && value === customValidator();
|
||||
break;
|
||||
case "url":
|
||||
isError = isURL(value);
|
||||
break;
|
||||
case "phonenumber": {
|
||||
const result = phone(value, {
|
||||
strictDetection: true,
|
||||
|
||||
@@ -26,10 +26,7 @@ import {
|
||||
} from "@notesnook/core/dist/common";
|
||||
import { EventManagerSubscription } from "@notesnook/core/dist/utils/event-manager";
|
||||
import notifee from "@notifee/react-native";
|
||||
import NetInfo, {
|
||||
NetInfoState,
|
||||
NetInfoSubscription
|
||||
} from "@react-native-community/netinfo";
|
||||
import NetInfo, { NetInfoSubscription } from "@react-native-community/netinfo";
|
||||
import React, { useCallback, useEffect, useRef } from "react";
|
||||
import {
|
||||
AppState,
|
||||
@@ -47,6 +44,7 @@ import { checkVersion } from "react-native-check-version";
|
||||
import Config from "react-native-config";
|
||||
import * as RNIap from "react-native-iap";
|
||||
import { DatabaseLogger, db, setupDatabase } from "../common/database";
|
||||
import { initializeLogger } from "../common/database/logger";
|
||||
import { MMKV } from "../common/database/mmkv";
|
||||
import Migrate from "../components/sheets/migrate";
|
||||
import NewFeature from "../components/sheets/new-feature";
|
||||
@@ -97,7 +95,6 @@ import {
|
||||
import { getGithubVersion } from "../utils/github-version";
|
||||
import { tabBarRef } from "../utils/global-refs";
|
||||
import { sleep } from "../utils/time";
|
||||
import { initializeLogger } from "../common/database/logger";
|
||||
|
||||
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
|
||||
const { disableSync, disableAutoSync } = SettingsService.get();
|
||||
@@ -362,6 +359,7 @@ const initializeDatabase = async (password?: string) => {
|
||||
try {
|
||||
await setupDatabase(password);
|
||||
await db.init();
|
||||
Sync.run();
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e as Error);
|
||||
ToastManager.error(e as Error, "Error initializing database", "global");
|
||||
@@ -391,18 +389,15 @@ export const useAppEvents = () => {
|
||||
]);
|
||||
|
||||
const syncedOnLaunch = useRef(false);
|
||||
|
||||
const refValues = useRef<
|
||||
Partial<{
|
||||
subsriptionSuccessListener: EmitterSubscription;
|
||||
subsriptionErrorListener: EmitterSubscription;
|
||||
isUserReady: boolean;
|
||||
prevState: AppStateStatus;
|
||||
showingDialog: boolean;
|
||||
removeInternetStateListener: NetInfoSubscription;
|
||||
isReconnecting: boolean;
|
||||
initialUrl: string;
|
||||
backupDidWait: boolean;
|
||||
isConnectingSSE: boolean;
|
||||
}>
|
||||
>({});
|
||||
|
||||
@@ -465,14 +460,31 @@ export const useAppEvents = () => {
|
||||
const user = await db.user.getUser();
|
||||
if (PremiumService.get() && user) {
|
||||
if (
|
||||
await BackupService.checkBackupRequired(SettingsService.get().reminder)
|
||||
SettingsService.get().backupDirectoryAndroid ||
|
||||
Platform.OS !== "android"
|
||||
) {
|
||||
if (
|
||||
!SettingsService.get().backupDirectoryAndroid &&
|
||||
Platform.OS === "android"
|
||||
)
|
||||
return;
|
||||
sleep(2000).then(() => BackupService.run());
|
||||
const partialBackup = await BackupService.checkBackupRequired(
|
||||
SettingsService.get().reminder,
|
||||
"lastBackupDate"
|
||||
);
|
||||
const fullBackup = await BackupService.checkBackupRequired(
|
||||
SettingsService.get().fullBackupReminder,
|
||||
"lastFullBackupDate"
|
||||
);
|
||||
|
||||
await sleep(2000);
|
||||
|
||||
if (partialBackup) {
|
||||
await BackupService.run();
|
||||
}
|
||||
|
||||
if (fullBackup) {
|
||||
await BackupService.run(true, undefined, "full");
|
||||
}
|
||||
}
|
||||
|
||||
if (SettingsService.getProperty("offlineMode")) {
|
||||
db.attachments.cacheAttachments().catch(console.log);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
@@ -533,7 +545,6 @@ export const useAppEvents = () => {
|
||||
setRecoveryKeyMessage();
|
||||
}
|
||||
if (!user?.isEmailConfirmed) setEmailVerifyMessage();
|
||||
refValues.current.isUserReady = true;
|
||||
|
||||
syncedOnLaunch.current = true;
|
||||
if (!isLogin) {
|
||||
@@ -607,18 +618,19 @@ export const useAppEvents = () => {
|
||||
}, [onSyncComplete, onUserUpdated]);
|
||||
|
||||
useEffect(() => {
|
||||
const onInternetStateChanged = async (state: NetInfoState) => {
|
||||
const onInternetStateChanged = async () => {
|
||||
if (!syncedOnLaunch.current) return;
|
||||
reconnectSSE(state);
|
||||
Sync.run("global", false, "full");
|
||||
reconnectSSE();
|
||||
};
|
||||
|
||||
const onAppStateChanged = async (state: AppStateStatus) => {
|
||||
if (state === "active") {
|
||||
notifee.setBadgeCount(0);
|
||||
updateStatusBarColor();
|
||||
|
||||
checkAutoBackup();
|
||||
await reconnectSSE();
|
||||
Sync.run("global", false, "full");
|
||||
reconnectSSE();
|
||||
await checkForShareExtensionLaunchedInBackground();
|
||||
MMKV.removeItem("appState");
|
||||
let user = await db.user.getUser();
|
||||
@@ -704,42 +716,15 @@ export const useAppEvents = () => {
|
||||
}
|
||||
}, [appLocked, syncing, checkAutoBackup]);
|
||||
|
||||
async function reconnectSSE(connection?: NetInfoState) {
|
||||
if (refValues.current?.isReconnecting || !refValues.current?.isUserReady)
|
||||
return;
|
||||
|
||||
if (useSettingStore.getState().appDidEnterBackgroundForAction) {
|
||||
useSettingStore.getState().setAppDidEnterBackgroundForAction(false);
|
||||
console.log("AppDidEnterForegroundAfterAction");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SettingsService.get().sessionExpired) {
|
||||
refValues.current.isReconnecting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
refValues.current.isReconnecting = true;
|
||||
let connectionState = connection;
|
||||
async function reconnectSSE() {
|
||||
try {
|
||||
if (!connectionState) {
|
||||
connectionState = await NetInfo.fetch();
|
||||
}
|
||||
|
||||
const user = await db.user.getUser();
|
||||
if (
|
||||
user &&
|
||||
connectionState.isConnected &&
|
||||
connectionState.isInternetReachable
|
||||
) {
|
||||
await db.connectSSE();
|
||||
} else {
|
||||
useUserStore.getState().setSyncing(false);
|
||||
await db.syncer.stop();
|
||||
}
|
||||
refValues.current.isReconnecting = false;
|
||||
if (refValues.current?.isConnectingSSE) return;
|
||||
refValues.current.isConnectingSSE = true;
|
||||
await db.connectSSE();
|
||||
refValues.current.isConnectingSSE = false;
|
||||
} catch (e) {
|
||||
refValues.current.isReconnecting = false;
|
||||
refValues.current.isConnectingSSE = false;
|
||||
DatabaseLogger.error(e as Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"html-to-text": "9.0.5",
|
||||
"phone": "^3.1.14",
|
||||
"qclone": "^1.2.0",
|
||||
"react-native-actions-sheet": "0.9.6",
|
||||
"react-native-actions-sheet": "0.9.7",
|
||||
"react-native-check-version": "https://github.com/flexible-agency/react-native-check-version",
|
||||
"react-native-drax": "^0.10.2",
|
||||
"react-native-image-zoom-viewer": "^3.0.1",
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Sodium from "@ammarahmed/react-native-sodium";
|
||||
import { isImage } from "@notesnook/core/dist/utils/filename";
|
||||
import { basename } from "pathe";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import DocumentPicker, {
|
||||
@@ -41,7 +42,6 @@ import { FILE_SIZE_LIMIT, IMAGE_SIZE_LIMIT } from "../../../utils/constants";
|
||||
import { eCloseSheet } from "../../../utils/events";
|
||||
import { useTabStore } from "./use-tab-store";
|
||||
import { editorController, editorState } from "./utils";
|
||||
import { basename } from "pathe";
|
||||
|
||||
const showEncryptionSheet = (file: DocumentPickerResponse) => {
|
||||
presentSheet({
|
||||
@@ -123,13 +123,13 @@ const file = async (fileOptions: PickerOptions) => {
|
||||
file.name,
|
||||
fileOptions
|
||||
))
|
||||
)
|
||||
return;
|
||||
) {
|
||||
throw new Error("Failed to attach file");
|
||||
}
|
||||
if (Platform.OS === "ios") await RNFetchBlob.fs.unlink(uri);
|
||||
|
||||
if (!fileOptions.tabId) return;
|
||||
if (
|
||||
fileOptions.tabId &&
|
||||
fileOptions.tabId !== undefined &&
|
||||
fileOptions.noteId &&
|
||||
useTabStore.getState().getNoteIdForTab(fileOptions.tabId) ===
|
||||
fileOptions.noteId
|
||||
@@ -158,16 +158,16 @@ const file = async (fileOptions: PickerOptions) => {
|
||||
fileOptions.tabId
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Failed to attach file, no tabId is set");
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
eSendEvent(eCloseSheet);
|
||||
}, 1000);
|
||||
eSendEvent(eCloseSheet);
|
||||
} catch (e) {
|
||||
eSendEvent(eCloseSheet);
|
||||
ToastManager.show({
|
||||
heading: (e as Error).message,
|
||||
message: "You need internet access to attach a file",
|
||||
heading: "Failed to attach file",
|
||||
message: (e as Error).message,
|
||||
type: "error",
|
||||
context: "global"
|
||||
});
|
||||
@@ -203,7 +203,6 @@ const camera = async (options: PickerOptions) => {
|
||||
type: "error",
|
||||
context: "global"
|
||||
});
|
||||
console.log("attachment error:", e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -32,9 +32,12 @@ import {
|
||||
TimeFormatPicker,
|
||||
TrashIntervalPicker,
|
||||
BackupReminderPicker,
|
||||
ApplockTimerPicker
|
||||
ApplockTimerPicker,
|
||||
BackupWithAttachmentsReminderPicker
|
||||
} from "./picker/pickers";
|
||||
import ThemeSelector from "./theme-selector";
|
||||
import { RestoreBackup } from "./restore-backup";
|
||||
import { ServersConfiguration } from "./server-config";
|
||||
|
||||
export const components: { [name: string]: ReactElement } = {
|
||||
colorpicker: <AccentColorPicker />,
|
||||
@@ -51,5 +54,8 @@ export const components: { [name: string]: ReactElement } = {
|
||||
"date-format-selector": <DateFormatPicker />,
|
||||
"time-format-selector": <TimeFormatPicker />,
|
||||
"theme-selector": <ThemeSelector />,
|
||||
"applock-timer": <ApplockTimerPicker />
|
||||
"applock-timer": <ApplockTimerPicker />,
|
||||
autobackupsattachments: <BackupWithAttachmentsReminderPicker />,
|
||||
backuprestore: <RestoreBackup />,
|
||||
"server-config": <ServersConfiguration />
|
||||
};
|
||||
|
||||
@@ -18,35 +18,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { NativeStackScreenProps } from "@react-navigation/native-stack";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import Animated, { FadeInDown } from "react-native-reanimated";
|
||||
import DelayLayout from "../../components/delay-layout";
|
||||
import BaseDialog from "../../components/dialog/base-dialog";
|
||||
import { ProgressBarComponent } from "../../components/ui/svg/lazy";
|
||||
import Heading from "../../components/ui/typography/heading";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { Header } from "../../components/header";
|
||||
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from "../../services/event-manager";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { SIZE } from "../../utils/size";
|
||||
import { SectionGroup } from "./section-group";
|
||||
import { settingsGroups } from "./settings-data";
|
||||
import { RouteParams, SettingSection } from "./types";
|
||||
import SettingsUserSection from "./user-section";
|
||||
import { Header } from "../../components/header";
|
||||
const keyExtractor = (item: SettingSection) => item.id;
|
||||
|
||||
const Home = ({
|
||||
navigation
|
||||
}: NativeStackScreenProps<RouteParams, "SettingsHome">) => {
|
||||
const { colors } = useThemeColors();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useNavigationFocus(navigation, {
|
||||
onFocus: () => {
|
||||
useNavigationStore.getState().setFocusedRouteId("Settings");
|
||||
@@ -62,16 +49,6 @@ const Home = ({
|
||||
<SectionGroup item={item} />
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
function settingsLoading(state: boolean) {
|
||||
setLoading(state || true);
|
||||
}
|
||||
eSubscribeEvent("settings-loading", settingsLoading);
|
||||
return () => {
|
||||
eUnSubscribeEvent("settings-loading", settingsLoading);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header
|
||||
@@ -81,57 +58,6 @@ const Home = ({
|
||||
id="Settings"
|
||||
/>
|
||||
<DelayLayout delay={300} type="settings">
|
||||
{loading && (
|
||||
//@ts-ignore // Migrate to typescript required.
|
||||
<BaseDialog animated={false} bounce={false} visible={true}>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.primary.background,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.primary.background,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.primary.paragraph} size={SIZE.lg}>
|
||||
Logging out
|
||||
</Heading>
|
||||
<Paragraph color={colors.secondary.paragraph}>
|
||||
Please wait while we log out and clear app data.
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
width: 100,
|
||||
marginTop: 15
|
||||
}}
|
||||
>
|
||||
<ProgressBarComponent
|
||||
height={5}
|
||||
width={100}
|
||||
animated={true}
|
||||
useNativeDriver
|
||||
indeterminate
|
||||
indeterminateAnimationDuration={2000}
|
||||
unfilledColor={colors.secondary.background}
|
||||
color={colors.primary.accent}
|
||||
borderWidth={0}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</BaseDialog>
|
||||
)}
|
||||
|
||||
<Animated.FlatList
|
||||
entering={FadeInDown}
|
||||
data={settingsGroups}
|
||||
|
||||
@@ -121,8 +121,8 @@ export const BackupReminderPicker = createSettingsPicker({
|
||||
SettingsService.set({ reminder: item });
|
||||
},
|
||||
formatValue: (item) => {
|
||||
return item === "useroff"
|
||||
? "Never"
|
||||
return item === "useroff" || item === "off" || item === "never"
|
||||
? "Off"
|
||||
: item.slice(0, 1).toUpperCase() + item.slice(1);
|
||||
},
|
||||
getItemKey: (item) => item,
|
||||
@@ -140,6 +140,31 @@ export const BackupReminderPicker = createSettingsPicker({
|
||||
}
|
||||
});
|
||||
|
||||
export const BackupWithAttachmentsReminderPicker = createSettingsPicker({
|
||||
getValue: () => useSettingStore.getState().settings.fullBackupReminder,
|
||||
updateValue: (item) => {
|
||||
SettingsService.set({ fullBackupReminder: item });
|
||||
},
|
||||
formatValue: (item) => {
|
||||
return item === "useroff" || item === "off" || item === "never"
|
||||
? "Off"
|
||||
: item.slice(0, 1).toUpperCase() + item.slice(1);
|
||||
},
|
||||
getItemKey: (item) => item,
|
||||
options: ["never", "weekly", "monthly"],
|
||||
compareValue: (current, item) => current === item,
|
||||
premium: true,
|
||||
requiresVerification: () => {
|
||||
return (
|
||||
!useSettingStore.getState().settings.encryptedBackup &&
|
||||
useUserStore.getState().user
|
||||
);
|
||||
},
|
||||
onCheckOptionIsPremium: (item) => {
|
||||
return item !== "never";
|
||||
}
|
||||
});
|
||||
|
||||
export const ApplockTimerPicker = createSettingsPicker({
|
||||
getValue: () => useSettingStore.getState().settings.appLockTimer,
|
||||
updateValue: (item) => {
|
||||
|
||||
558
apps/mobile/app/screens/settings/restore-backup/index.tsx
Normal file
558
apps/mobile/app/screens/settings/restore-backup/index.tsx
Normal file
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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 { formatBytes, getFormattedDate } from "@notesnook/common";
|
||||
import { LegacyBackupFile } from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { ActivityIndicator, FlatList, Platform, View } from "react-native";
|
||||
import RNFetchBlob, { ReactNativeBlobUtilStat } from "react-native-blob-util";
|
||||
import DocumentPicker from "react-native-document-picker";
|
||||
import * as ScopedStorage from "react-native-scoped-storage";
|
||||
import { unzip } from "react-native-zip-archive";
|
||||
import { DatabaseLogger, db } from "../../../common/database";
|
||||
import storage from "../../../common/database/storage";
|
||||
import { deleteCacheFileByName } from "../../../common/filesystem/io";
|
||||
import { cacheDir, copyFileAsync } from "../../../common/filesystem/utils";
|
||||
import { presentDialog } from "../../../components/dialog/functions";
|
||||
import {
|
||||
endProgress,
|
||||
startProgress,
|
||||
updateProgress
|
||||
} from "../../../components/dialogs/progress";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
import Heading from "../../../components/ui/typography/heading";
|
||||
import Paragraph from "../../../components/ui/typography/paragraph";
|
||||
import { SectionItem } from "../../../screens/settings/section-item";
|
||||
import { ToastManager } from "../../../services/event-manager";
|
||||
import Navigation from "../../../services/navigation";
|
||||
import SettingsService from "../../../services/settings";
|
||||
import { refreshAllStores } from "../../../stores/create-db-collection-store";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import { SIZE } from "../../../utils/size";
|
||||
|
||||
type PasswordOrKey = { password?: string; encryptionKey?: string };
|
||||
|
||||
const withPassword = () => {
|
||||
return new Promise<PasswordOrKey>((resolve) => {
|
||||
let resolved = false;
|
||||
presentDialog({
|
||||
context: "local",
|
||||
title: "Encrypted backup",
|
||||
input: true,
|
||||
inputPlaceholder: "Password",
|
||||
paragraph: "Please enter password of this backup file",
|
||||
positiveText: "Restore",
|
||||
secureTextEntry: true,
|
||||
onClose: () => {
|
||||
if (resolved) return;
|
||||
resolve({});
|
||||
},
|
||||
negativeText: "Cancel",
|
||||
positivePress: async (password, isEncryptionKey) => {
|
||||
resolve({
|
||||
encryptionKey: isEncryptionKey ? password : undefined,
|
||||
password: isEncryptionKey ? undefined : password
|
||||
});
|
||||
resolved = true;
|
||||
return true;
|
||||
},
|
||||
check: {
|
||||
info: "Use encryption key",
|
||||
type: "transparent"
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const restoreBackup = async (options: {
|
||||
uri: string;
|
||||
deleteFile?: boolean;
|
||||
}) => {
|
||||
try {
|
||||
const isLegacyBackup = options.uri.endsWith(".nnbackup");
|
||||
|
||||
startProgress({
|
||||
title: "Restoring backup",
|
||||
paragraph: "Preparing to restore backup file...",
|
||||
canHideProgress: false
|
||||
});
|
||||
|
||||
let filePath = options.uri;
|
||||
let deleteBackupFile = options.deleteFile;
|
||||
|
||||
if (!isLegacyBackup) {
|
||||
if (Platform.OS === "android") {
|
||||
updateProgress({
|
||||
progress: `Copying backup file to cache...`
|
||||
});
|
||||
const cacheFile = `file://${RNFetchBlob.fs.dirs.CacheDir}/backup.zip`;
|
||||
if (await RNFetchBlob.fs.exists(cacheFile)) {
|
||||
await RNFetchBlob.fs.unlink(cacheFile);
|
||||
}
|
||||
|
||||
await RNFetchBlob.fs.createFile(cacheFile, "", "utf8");
|
||||
if (filePath.startsWith("content://")) {
|
||||
await copyFileAsync(filePath, cacheFile);
|
||||
} else {
|
||||
await RNFetchBlob.fs.cp(filePath, cacheFile);
|
||||
}
|
||||
filePath = cacheFile;
|
||||
deleteBackupFile = true;
|
||||
}
|
||||
|
||||
const zipOutputFolder = `${cacheDir}/backup_extracted`;
|
||||
if (await RNFetchBlob.fs.exists(zipOutputFolder)) {
|
||||
await RNFetchBlob.fs.unlink(zipOutputFolder);
|
||||
await RNFetchBlob.fs.mkdir(zipOutputFolder);
|
||||
}
|
||||
updateProgress({
|
||||
progress: `Extracting files from backup...`
|
||||
});
|
||||
await unzip(filePath, zipOutputFolder);
|
||||
|
||||
const extractedBackupFiles = await RNFetchBlob.fs.ls(zipOutputFolder);
|
||||
|
||||
const extractedAttachments = extractedBackupFiles.includes("attachments")
|
||||
? await RNFetchBlob.fs.ls(`${zipOutputFolder}/attachments`)
|
||||
: [];
|
||||
|
||||
const attachmentsKeyPath: any = extractedAttachments?.find(
|
||||
(path) => path === ".attachments_key"
|
||||
);
|
||||
const attachmentsKey = attachmentsKeyPath
|
||||
? await JSON.parse(
|
||||
await RNFetchBlob.fs.readFile(
|
||||
`${zipOutputFolder}/attachments/${attachmentsKeyPath}`,
|
||||
"utf8"
|
||||
)
|
||||
)
|
||||
: undefined;
|
||||
|
||||
let count = 0;
|
||||
await db.transaction(async () => {
|
||||
let passwordOrKey: PasswordOrKey;
|
||||
for (const path of extractedBackupFiles) {
|
||||
if (path === ".nnbackup" || path === "attachments") continue;
|
||||
|
||||
updateProgress({
|
||||
progress: `Restoring data (${count++}/${
|
||||
extractedBackupFiles.length
|
||||
})`
|
||||
});
|
||||
|
||||
const filePath = `${zipOutputFolder}/${path}`;
|
||||
const data = await RNFetchBlob.fs.readFile(filePath, "utf8");
|
||||
const backup = JSON.parse(data);
|
||||
|
||||
const isEncryptedBackup = backup.encrypted;
|
||||
|
||||
passwordOrKey = !isEncryptedBackup
|
||||
? ({} as PasswordOrKey)
|
||||
: await withPassword();
|
||||
|
||||
if (
|
||||
isEncryptedBackup &&
|
||||
!passwordOrKey?.encryptionKey &&
|
||||
!passwordOrKey?.password
|
||||
) {
|
||||
endProgress();
|
||||
throw new Error("Failed to decrypt backup");
|
||||
}
|
||||
|
||||
await db.backup.import(backup, {
|
||||
...passwordOrKey,
|
||||
attachmentsKey: attachmentsKey
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await db.initCollections();
|
||||
count = 0;
|
||||
for (const path of extractedAttachments) {
|
||||
if (path === ".attachments_key") continue;
|
||||
updateProgress({
|
||||
progress: `Restoring attachments (${count++}/${
|
||||
extractedAttachments.length
|
||||
})`
|
||||
});
|
||||
const hash = path;
|
||||
const attachment = await db.attachments.attachment(hash as string);
|
||||
if (!attachment) continue;
|
||||
|
||||
console.log("Saving attachment file", hash);
|
||||
await deleteCacheFileByName(hash);
|
||||
await RNFetchBlob.fs.cp(
|
||||
`${zipOutputFolder}/attachments/${hash}`,
|
||||
`${cacheDir}/${hash}`
|
||||
);
|
||||
}
|
||||
updateProgress({
|
||||
progress: `Cleaning up...`
|
||||
});
|
||||
// Remove files from cache
|
||||
RNFetchBlob.fs.unlink(zipOutputFolder).catch(console.log);
|
||||
if (Platform.OS === "android" || deleteBackupFile) {
|
||||
RNFetchBlob.fs.unlink(filePath).catch(console.log);
|
||||
}
|
||||
} else {
|
||||
updateProgress({
|
||||
progress: `Reading backup file...`
|
||||
});
|
||||
const rawData =
|
||||
Platform.OS === "android"
|
||||
? await ScopedStorage.readFile(filePath, "utf8")
|
||||
: await RNFetchBlob.fs.readFile(filePath, "utf8");
|
||||
const backup: LegacyBackupFile = JSON.parse(rawData) as LegacyBackupFile;
|
||||
|
||||
const isEncryptedBackup =
|
||||
typeof backup.data !== "string" && backup.data.cipher;
|
||||
|
||||
updateProgress({
|
||||
progress: isEncryptedBackup
|
||||
? `Backup is encrypted, decrypting...`
|
||||
: "Preparing to restore backup file..."
|
||||
});
|
||||
|
||||
const { encryptionKey, password } = isEncryptedBackup
|
||||
? ({} as PasswordOrKey)
|
||||
: await withPassword();
|
||||
|
||||
if (isEncryptedBackup && !encryptionKey && !password) {
|
||||
endProgress();
|
||||
throw new Error("Failed to decrypt backup");
|
||||
}
|
||||
|
||||
await db.transaction(async () => {
|
||||
updateProgress({
|
||||
progress: "Restoring backup..."
|
||||
});
|
||||
await db.backup.import(backup, {
|
||||
encryptionKey,
|
||||
password
|
||||
});
|
||||
});
|
||||
endProgress();
|
||||
}
|
||||
|
||||
ToastManager.show({
|
||||
heading: "Backup restored successfully",
|
||||
type: "success"
|
||||
});
|
||||
|
||||
await db.initCollections();
|
||||
refreshAllStores();
|
||||
Navigation.queueRoutesForUpdate();
|
||||
endProgress();
|
||||
} catch (e) {
|
||||
endProgress();
|
||||
DatabaseLogger.error(e as Error);
|
||||
ToastManager.error(e as Error, `Failed to restore backup`);
|
||||
}
|
||||
};
|
||||
|
||||
const BACKUP_FILES_CACHE: (ReactNativeBlobUtilStat | ScopedStorage.FileType)[] =
|
||||
[];
|
||||
|
||||
export const RestoreBackup = () => {
|
||||
const { colors } = useThemeColors();
|
||||
const [files, setFiles] =
|
||||
useState<(ReactNativeBlobUtilStat | ScopedStorage.FileType)[]>(
|
||||
BACKUP_FILES_CACHE
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [backupDirectoryAndroid, setBackupDirectoryAndroid] =
|
||||
useState<ScopedStorage.FileType>();
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
checkBackups();
|
||||
}, 1000);
|
||||
}, []);
|
||||
|
||||
const checkBackups = async () => {
|
||||
try {
|
||||
let files: (ReactNativeBlobUtilStat | ScopedStorage.FileType)[] = [];
|
||||
if (Platform.OS === "android") {
|
||||
const backupDirectory = SettingsService.get().backupDirectoryAndroid;
|
||||
if (backupDirectory) {
|
||||
setBackupDirectoryAndroid(backupDirectory);
|
||||
files = await ScopedStorage.listFiles(backupDirectory.uri);
|
||||
} else {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const path = await storage.checkAndCreateDir("/backups/");
|
||||
files = await RNFetchBlob.fs.lstat(path);
|
||||
}
|
||||
files = files
|
||||
.filter((file) => {
|
||||
const name =
|
||||
Platform.OS === "android"
|
||||
? (file as ScopedStorage.FileType).name
|
||||
: (file as ReactNativeBlobUtilStat).filename;
|
||||
return name.endsWith(".nnbackup") || name.endsWith(".nnbackupz");
|
||||
})
|
||||
.sort(function (a, b) {
|
||||
const timeA = a.lastModified;
|
||||
const timeB = b.lastModified;
|
||||
return timeB - timeA;
|
||||
});
|
||||
|
||||
setFiles(files);
|
||||
BACKUP_FILES_CACHE.splice(0, BACKUP_FILES_CACHE.length, ...files);
|
||||
} catch (e) {
|
||||
e;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const renderItem = React.useCallback(
|
||||
({
|
||||
item,
|
||||
index
|
||||
}: {
|
||||
item: ReactNativeBlobUtilStat | ScopedStorage.FileType;
|
||||
index: number;
|
||||
}) => <BackupItem item={item} index={index} />,
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FlatList
|
||||
data={[0]}
|
||||
renderItem={() => {
|
||||
return (
|
||||
<View>
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "restore-from-files",
|
||||
name: "Restore from files",
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: true
|
||||
});
|
||||
const file = await DocumentPicker.pickSingle({
|
||||
copyTo: "cachesDirectory"
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
useUserStore.setState({
|
||||
disableAppLockRequests: false
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
restoreBackup({
|
||||
uri:
|
||||
Platform.OS === "android"
|
||||
? (("file://" + file.fileCopyUri) as string)
|
||||
: (file.fileCopyUri as string),
|
||||
deleteFile: true
|
||||
});
|
||||
},
|
||||
description:
|
||||
"Select a backup file from your device to restore backup"
|
||||
}}
|
||||
/>
|
||||
|
||||
{Platform.OS === "android" ? (
|
||||
<SectionItem
|
||||
item={{
|
||||
id: "select-backup-folder",
|
||||
name: "Select folder with backup files",
|
||||
icon: "folder",
|
||||
modifer: async () => {
|
||||
const folder = await ScopedStorage.openDocumentTree(true);
|
||||
let subfolder;
|
||||
if (folder.name !== "Notesnook backups") {
|
||||
subfolder = await ScopedStorage.createDirectory(
|
||||
folder.uri,
|
||||
"Notesnook backups"
|
||||
);
|
||||
} else {
|
||||
subfolder = folder;
|
||||
}
|
||||
SettingsService.set({
|
||||
backupDirectoryAndroid: subfolder
|
||||
});
|
||||
setBackupDirectoryAndroid(subfolder);
|
||||
setLoading(true);
|
||||
checkBackups();
|
||||
},
|
||||
description:
|
||||
"Select folder where Notesnook backup files are stored to view and restore them from the app"
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<FlatList
|
||||
ListHeaderComponent={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.primary.background,
|
||||
marginBottom: 10
|
||||
}}
|
||||
>
|
||||
<Heading color={colors.primary.accent} size={SIZE.xs}>
|
||||
RECENT BACKUPS
|
||||
</Heading>
|
||||
</View>
|
||||
}
|
||||
stickyHeaderIndices={[0]}
|
||||
ListEmptyComponent={
|
||||
loading ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color={colors.primary.accent}
|
||||
size={SIZE.lg}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
height: 300,
|
||||
paddingHorizontal: 50
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
No backups were found.{" "}
|
||||
{!backupDirectoryAndroid
|
||||
? `Please select a folder with backup files to view them here.`
|
||||
: null}
|
||||
</Paragraph>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
windowSize={2}
|
||||
keyExtractor={(item) =>
|
||||
(item as ScopedStorage.FileType).name ||
|
||||
(item as ReactNativeBlobUtilStat).filename
|
||||
}
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
style={{
|
||||
height: 200
|
||||
}}
|
||||
/>
|
||||
}
|
||||
data={files}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const BackupItem = ({
|
||||
item,
|
||||
index
|
||||
}: {
|
||||
item: ReactNativeBlobUtilStat | ScopedStorage.FileType;
|
||||
index: number;
|
||||
}) => {
|
||||
const { colors } = useThemeColors();
|
||||
|
||||
const isLegacyBackup =
|
||||
item.path?.endsWith(".nnbackup") ||
|
||||
(item as ScopedStorage.FileType).uri?.endsWith(".nnbackup");
|
||||
const itemName = (
|
||||
(item as ReactNativeBlobUtilStat).filename ||
|
||||
(item as ScopedStorage.FileType).name
|
||||
)
|
||||
.replace(".nnbackupz", "")
|
||||
.replace(".nnbackup", "");
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
borderRadius: 0,
|
||||
flexDirection: "row",
|
||||
borderBottomWidth: 0.5,
|
||||
borderBottomColor: colors.primary.border,
|
||||
paddingVertical: 12
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<Paragraph size={SIZE.sm}>{itemName}</Paragraph>
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
style={{ width: "100%", maxWidth: "100%" }}
|
||||
>
|
||||
Created on {getFormattedDate(item?.lastModified, "date-time")}
|
||||
{isLegacyBackup ? "(Legacy backup)" : ""} (
|
||||
{formatBytes((item as ReactNativeBlobUtilStat).size)})
|
||||
</Paragraph>
|
||||
</View>
|
||||
<Button
|
||||
title="Restore"
|
||||
type="secondaryAccented"
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
height: 35
|
||||
}}
|
||||
onPress={() => {
|
||||
presentDialog({
|
||||
title: `Restore ${itemName}`,
|
||||
paragraph: `Are you sure you want to restore this backup?`,
|
||||
positiveText: "Restore",
|
||||
negativeText: "Cancel",
|
||||
positivePress: async () => {
|
||||
console.log("file path", (item as ScopedStorage.FileType).uri);
|
||||
restoreBackup({
|
||||
uri:
|
||||
Platform.OS === "android"
|
||||
? (item as ScopedStorage.FileType).uri
|
||||
: (item as ReactNativeBlobUtilStat).path
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
213
apps/mobile/app/screens/settings/server-config.tsx
Normal file
213
apps/mobile/app/screens/settings/server-config.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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 { isServerCompatible } from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { presentDialog } from "../../components/dialog/functions";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import Input from "../../components/ui/input";
|
||||
import { Notice } from "../../components/ui/notice";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { HostId, HostIds } from "../../stores/use-setting-store";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
|
||||
export const ServerIds = ["notesnook-sync", "auth", "sse"] as const;
|
||||
export type ServerId = (typeof ServerIds)[number];
|
||||
type Server = {
|
||||
id: ServerId;
|
||||
host: HostId;
|
||||
title: string;
|
||||
example: string;
|
||||
description: string;
|
||||
};
|
||||
type VersionResponse = {
|
||||
version: number;
|
||||
id: string;
|
||||
instance: string;
|
||||
};
|
||||
const SERVERS: Server[] = [
|
||||
{
|
||||
id: "notesnook-sync",
|
||||
host: "API_HOST",
|
||||
title: "Sync server",
|
||||
example: "http://localhost:4326",
|
||||
description: "Server used to sync your notes & other data between devices."
|
||||
},
|
||||
{
|
||||
id: "auth",
|
||||
host: "AUTH_HOST",
|
||||
title: "Auth server",
|
||||
example: "http://localhost:5326",
|
||||
description: "Server used for login/sign up and authentication."
|
||||
},
|
||||
{
|
||||
id: "sse",
|
||||
host: "SSE_HOST",
|
||||
title: "Events server",
|
||||
example: "http://localhost:7326",
|
||||
description: "Server used to receive important notifications & events."
|
||||
}
|
||||
];
|
||||
export function ServersConfiguration() {
|
||||
const { colors } = useThemeColors();
|
||||
const [error, setError] = useState<string>();
|
||||
const [success, setSuccess] = useState<boolean>();
|
||||
const [urls, setUrls] = useState<Partial<Record<HostId, string>>>(
|
||||
SettingsService.getProperty("serverUrls") || {}
|
||||
);
|
||||
const isLoggedIn = useUserStore((state) => !!state.user);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
gap: 12,
|
||||
marginTop: 12
|
||||
}}
|
||||
>
|
||||
{isLoggedIn ? (
|
||||
<Notice
|
||||
text="You must log out in order to change/reset server URLs."
|
||||
type="alert"
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<View style={{ flexDirection: "column" }}>
|
||||
{SERVERS.map((server) => (
|
||||
<Input
|
||||
key={server.id}
|
||||
editable={!isLoggedIn}
|
||||
placeholder={`${server.id} e.g. ${server.example}`}
|
||||
validationType="url"
|
||||
defaultValue={urls[server.host]}
|
||||
errorMessage="Please enter a valid URL."
|
||||
onChangeText={(value) =>
|
||||
setUrls((s) => {
|
||||
s[server.host] = value;
|
||||
return s;
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
||||
{error ? (
|
||||
<Paragraph
|
||||
style={{
|
||||
paddingVertical: 12
|
||||
}}
|
||||
color={colors.error.paragraph}
|
||||
>
|
||||
{error}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
{success === true ? (
|
||||
<Paragraph
|
||||
style={{
|
||||
paddingVertical: 12
|
||||
}}
|
||||
color={colors.success.paragraph}
|
||||
>
|
||||
Connected to all servers sucessfully.
|
||||
</Paragraph>
|
||||
) : null}
|
||||
<View style={{ marginTop: 1, justifyContent: "flex-end", gap: 12 }}>
|
||||
<Button
|
||||
disabled={isLoggedIn}
|
||||
type="secondary"
|
||||
width="100%"
|
||||
onPress={async () => {
|
||||
try {
|
||||
for (const host of HostIds) {
|
||||
const url = urls[host];
|
||||
const server = SERVERS.find((s) => s.host === host)!;
|
||||
if (!url) throw new Error("All server urls are required.");
|
||||
const version = await fetch(`${url}/version`)
|
||||
.then((r) => r.json() as Promise<VersionResponse>)
|
||||
.catch(() => undefined);
|
||||
if (!version)
|
||||
throw new Error(`Could not connect to ${server.title}.`);
|
||||
if (version.id !== server.id)
|
||||
throw new Error(
|
||||
`The URL you have given (${url}) does not point to the ${server.title}.`
|
||||
);
|
||||
if (!isServerCompatible(version.version)) {
|
||||
throw new Error(
|
||||
`The server version is not compatible with the app.`
|
||||
);
|
||||
}
|
||||
}
|
||||
setSuccess(true);
|
||||
setError(undefined);
|
||||
} catch (e) {
|
||||
setError((e as Error).message);
|
||||
}
|
||||
}}
|
||||
title="Test connection"
|
||||
/>
|
||||
|
||||
<Button
|
||||
type="accent"
|
||||
disabled={isLoggedIn}
|
||||
width="100%"
|
||||
onPress={async () => {
|
||||
if (!success) {
|
||||
ToastManager.show({
|
||||
heading: "Test connection before changing server urls"
|
||||
});
|
||||
return;
|
||||
}
|
||||
SettingsService.setProperty(
|
||||
"serverUrls",
|
||||
urls as Record<HostId, string>
|
||||
);
|
||||
|
||||
presentDialog({
|
||||
title: "Server url changed",
|
||||
paragraph: "Restart the app for changes to take effect.",
|
||||
negativeText: "Done"
|
||||
});
|
||||
}}
|
||||
title="Save"
|
||||
/>
|
||||
|
||||
<Button
|
||||
disabled={isLoggedIn}
|
||||
type="error"
|
||||
width="100%"
|
||||
title="Reset server urls"
|
||||
onPress={async () => {
|
||||
if (isLoggedIn) return;
|
||||
SettingsService.setProperty("serverUrls", undefined);
|
||||
presentDialog({
|
||||
title: "Server urls reset",
|
||||
paragraph: "Restart the app for changes to take effect.",
|
||||
negativeText: "Done"
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -17,6 +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 { formatBytes } from "@notesnook/common";
|
||||
import notifee from "@notifee/react-native";
|
||||
import dayjs from "dayjs";
|
||||
import React from "react";
|
||||
@@ -24,12 +25,19 @@ import { Appearance, Linking, Platform } from "react-native";
|
||||
import { getVersion } from "react-native-device-info";
|
||||
import * as RNIap from "react-native-iap";
|
||||
import { enabled } from "react-native-privacy-snapshot";
|
||||
import { db } from "../../common/database";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
import { DatabaseLogger, db } from "../../common/database";
|
||||
import { MMKV } from "../../common/database/mmkv";
|
||||
import filesystem from "../../common/filesystem";
|
||||
import { AttachmentDialog } from "../../components/attachments";
|
||||
import { ChangePassword } from "../../components/auth/change-password";
|
||||
import { presentDialog } from "../../components/dialog/functions";
|
||||
import { AppLockPassword } from "../../components/dialogs/applock-password";
|
||||
import {
|
||||
endProgress,
|
||||
startProgress,
|
||||
updateProgress
|
||||
} from "../../components/dialogs/progress";
|
||||
import { ChangeEmail } from "../../components/sheets/change-email";
|
||||
import ExportNotesSheet from "../../components/sheets/export-notes";
|
||||
import { Issue } from "../../components/sheets/github/issue";
|
||||
@@ -42,6 +50,7 @@ import BiometricService from "../../services/biometrics";
|
||||
import {
|
||||
ToastManager,
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
openVault,
|
||||
presentSheet
|
||||
} from "../../services/event-manager";
|
||||
@@ -60,8 +69,7 @@ import {
|
||||
eCloseSheet,
|
||||
eCloseSimpleDialog,
|
||||
eOpenLoginDialog,
|
||||
eOpenRecoveryKeyDialog,
|
||||
eOpenRestoreDialog
|
||||
eOpenRecoveryKeyDialog
|
||||
} from "../../utils/events";
|
||||
import { NotesnookModule } from "../../utils/notesnook-module";
|
||||
import { sleep } from "../../utils/time";
|
||||
@@ -70,7 +78,6 @@ import { useDragState } from "./editor/state";
|
||||
import { verifyUser, verifyUserWithApplock } from "./functions";
|
||||
import { SettingSection } from "./types";
|
||||
import { getTimeLeft } from "./user-section";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
|
||||
type User = any;
|
||||
|
||||
@@ -331,45 +338,144 @@ export const settingsGroups: SettingSection[] = [
|
||||
},
|
||||
description: "Verify your subscription to Notesnook Pro"
|
||||
},
|
||||
{
|
||||
id: "clear-cache",
|
||||
name: "Clear cache",
|
||||
icon: "delete",
|
||||
modifer: async () => {
|
||||
presentDialog({
|
||||
title: "Clear cache",
|
||||
paragraph: "Are you sure you want to clear the cache?",
|
||||
positiveText: "Clear",
|
||||
positivePress: async () => {
|
||||
filesystem.clearCache();
|
||||
ToastManager.show({
|
||||
heading: "Cache cleared",
|
||||
message: "All cached attachments have been removed",
|
||||
type: "success"
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
description(current) {
|
||||
return `Clear all cached attachments. Current cache size: ${
|
||||
current as number
|
||||
}`;
|
||||
},
|
||||
useHook: () => {
|
||||
const [cacheSize, setCacheSize] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
filesystem.getCacheSize().then(setCacheSize).catch(console.log);
|
||||
const sub = eSubscribeEvent("cache-cleared", () => {
|
||||
setCacheSize(0);
|
||||
});
|
||||
return () => {
|
||||
sub?.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
return formatBytes(cacheSize);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
id: "logout",
|
||||
name: "Log out",
|
||||
name: "Logout",
|
||||
description:
|
||||
"Logging out will clear all data stored on THIS DEVICE.",
|
||||
"Logging out will clear all data stored on this device.",
|
||||
icon: "logout",
|
||||
modifer: () => {
|
||||
modifer: async () => {
|
||||
const hasUnsyncedChanges = await db.hasUnsyncedChanges();
|
||||
presentDialog({
|
||||
title: "Logout",
|
||||
paragraph:
|
||||
"Logging out will clear all data stored on THIS DEVICE. Make sure you have synced all your changes before logging out.",
|
||||
"Are you sure you want to logout and clear all data stored on this device?",
|
||||
positiveText: "Logout",
|
||||
positivePress: async () => {
|
||||
try {
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
setTimeout(async () => {
|
||||
eSendEvent("settings-loading", true);
|
||||
Navigation.popToTop();
|
||||
check: {
|
||||
info: "Take a backup before logging out",
|
||||
defaultValue: true
|
||||
},
|
||||
notice: hasUnsyncedChanges
|
||||
? {
|
||||
text: "You have unsynced notes. Take a backup or sync your notes to avoid losing your critical data.",
|
||||
type: "alert"
|
||||
}
|
||||
: undefined,
|
||||
positivePress: async (_, takeBackup) => {
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
startProgress({
|
||||
fillBackground: true,
|
||||
title: "Logging out",
|
||||
canHideProgress: true,
|
||||
paragraph:
|
||||
"Please wait while we log out and clear app data."
|
||||
});
|
||||
|
||||
Navigation.navigate("Notes");
|
||||
|
||||
if (takeBackup) {
|
||||
updateProgress({
|
||||
progress: "Taking a backup of your notes"
|
||||
});
|
||||
|
||||
try {
|
||||
const result = await BackupService.run(
|
||||
false,
|
||||
"local",
|
||||
"partial"
|
||||
);
|
||||
if (result.error) throw result.error as Error;
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
const error = e;
|
||||
const canLogout = await new Promise((resolve) => {
|
||||
presentDialog({
|
||||
context: "local",
|
||||
title: "Backup failed",
|
||||
paragraph: `${
|
||||
(error as Error).message
|
||||
}. Do you want to continue logging out?`,
|
||||
positiveText: "Continue",
|
||||
positivePress: () => {
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!canLogout) {
|
||||
endProgress();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress({
|
||||
progress: "Logging out... please wait"
|
||||
});
|
||||
|
||||
await db.user?.logout();
|
||||
setLoginMessage();
|
||||
await PremiumService.setPremiumStatus();
|
||||
await BiometricService.resetCredentials();
|
||||
MMKV.clearStore();
|
||||
clearAllStores();
|
||||
refreshAllStores();
|
||||
setImmediate(() => {
|
||||
refreshAllStores();
|
||||
});
|
||||
Navigation.queueRoutesForUpdate();
|
||||
SettingsService.resetSettings();
|
||||
useUserStore.getState().setUser(null);
|
||||
useUserStore.getState().setSyncing(false);
|
||||
Navigation.goBack();
|
||||
Navigation.popToTop();
|
||||
setTimeout(() => {
|
||||
eSendEvent("settings-loading", false);
|
||||
}, 3000);
|
||||
}, 300);
|
||||
} catch (e) {
|
||||
ToastManager.error(e as Error, "Error logging out");
|
||||
eSendEvent("settings-loading", false);
|
||||
}
|
||||
endProgress();
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
ToastManager.error(e as Error, "Error logging out");
|
||||
endProgress();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -395,12 +501,18 @@ export const settingsGroups: SettingSection[] = [
|
||||
try {
|
||||
const verified = await db.user?.verifyPassword(value);
|
||||
if (verified) {
|
||||
eSendEvent("settings-loading", true);
|
||||
await db.user?.deleteUser(value);
|
||||
await BiometricService.resetCredentials();
|
||||
SettingsService.set({
|
||||
introCompleted: true
|
||||
});
|
||||
setTimeout(async () => {
|
||||
startProgress({
|
||||
title: "Deleting account",
|
||||
paragraph: "Please wait while we delete your account"
|
||||
});
|
||||
Navigation.navigate("Notes");
|
||||
await db.user?.deleteUser(value);
|
||||
await BiometricService.resetCredentials();
|
||||
SettingsService.set({
|
||||
introCompleted: true
|
||||
});
|
||||
}, 300);
|
||||
} else {
|
||||
ToastManager.show({
|
||||
heading: "Incorrect password",
|
||||
@@ -411,9 +523,9 @@ export const settingsGroups: SettingSection[] = [
|
||||
});
|
||||
}
|
||||
|
||||
eSendEvent("settings-loading", false);
|
||||
endProgress();
|
||||
} catch (e) {
|
||||
eSendEvent("settings-loading", false);
|
||||
endProgress();
|
||||
console.log(e);
|
||||
ToastManager.error(
|
||||
e as Error,
|
||||
@@ -434,6 +546,25 @@ export const settingsGroups: SettingSection[] = [
|
||||
type: "screen",
|
||||
icon: "autorenew",
|
||||
sections: [
|
||||
{
|
||||
id: "offline-mode",
|
||||
name: "Full offline mode",
|
||||
description: "Download everything including attachments on sync",
|
||||
type: "switch",
|
||||
property: "offlineMode",
|
||||
modifer: () => {
|
||||
const current = SettingsService.get().offlineMode;
|
||||
if (current) {
|
||||
SettingsService.setProperty("offlineMode", false);
|
||||
db.fs().cancel("offline-mode");
|
||||
return;
|
||||
}
|
||||
PremiumService.verify(() => {
|
||||
SettingsService.setProperty("offlineMode", true);
|
||||
db.attachments.cacheAttachments().catch(console.log);
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "auto-sync",
|
||||
name: "Disable auto sync",
|
||||
@@ -689,6 +820,14 @@ export const settingsGroups: SettingSection[] = [
|
||||
type: "switch"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "servers",
|
||||
type: "screen",
|
||||
name: "Servers",
|
||||
description: "Configure server URLs for Notesnook",
|
||||
icon: "server",
|
||||
component: "server-config"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -696,15 +835,6 @@ export const settingsGroups: SettingSection[] = [
|
||||
id: "privacy-security",
|
||||
name: "Privacy and security",
|
||||
sections: [
|
||||
{
|
||||
id: "temeltery",
|
||||
type: "switch",
|
||||
name: "Telemetry",
|
||||
icon: "radar",
|
||||
description:
|
||||
"Contribute towards a better Notesnook. All tracking information is anonymous.",
|
||||
property: "telemetry"
|
||||
},
|
||||
{
|
||||
id: "marketing-emails",
|
||||
type: "switch",
|
||||
@@ -1041,7 +1171,8 @@ export const settingsGroups: SettingSection[] = [
|
||||
{
|
||||
id: "backup-now",
|
||||
name: "Backup now",
|
||||
description: "Create a backup of your data",
|
||||
description:
|
||||
"Take a partial backup of your data that does not include attachments",
|
||||
modifer: async () => {
|
||||
const user = useUserStore.getState().user;
|
||||
if (!user || SettingsService.getProperty("encryptedBackup")) {
|
||||
@@ -1052,14 +1183,41 @@ export const settingsGroups: SettingSection[] = [
|
||||
verifyUser(null, () => BackupService.run(true));
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "backup-now",
|
||||
name: "Backup now with attachments",
|
||||
hidden: () => !useUserStore.getState().user,
|
||||
description: "Take a full backup of your data with all attachments",
|
||||
modifer: async () => {
|
||||
const user = useUserStore.getState().user;
|
||||
if (!user || SettingsService.getProperty("encryptedBackup")) {
|
||||
await BackupService.run(true, undefined, "full");
|
||||
return;
|
||||
}
|
||||
|
||||
verifyUser(null, () =>
|
||||
BackupService.run(true, undefined, "full")
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "auto-backups",
|
||||
type: "component",
|
||||
name: "Automatic backups",
|
||||
description:
|
||||
"Backup your data once every week or daily automatically.",
|
||||
"Set the interval to create a partial backup (without attachments) automatically.",
|
||||
component: "autobackups"
|
||||
},
|
||||
{
|
||||
id: "auto-backups-with-attachments",
|
||||
type: "component",
|
||||
hidden: () => !useUserStore.getState().user,
|
||||
name: "Automatic backups with attachments",
|
||||
description: `Set the interval to create a backup (with attachments) automatically.
|
||||
|
||||
NOTE: Creating a backup with attachments can take a while, and also fail completely. The app will try to resume/restart the backup in case of interruptions.`,
|
||||
component: "autobackupsattachments"
|
||||
},
|
||||
{
|
||||
id: "select-backup-dir",
|
||||
name: "Select backup directory",
|
||||
@@ -1151,9 +1309,8 @@ export const settingsGroups: SettingSection[] = [
|
||||
id: "restore-backup",
|
||||
name: "Restore backup",
|
||||
description: "Restore backup from phone storage.",
|
||||
modifer: () => {
|
||||
eSendEvent(eOpenRestoreDialog);
|
||||
}
|
||||
type: "screen",
|
||||
component: "backuprestore"
|
||||
},
|
||||
{
|
||||
id: "export-notes",
|
||||
@@ -1333,9 +1490,9 @@ export const settingsGroups: SettingSection[] = [
|
||||
}
|
||||
},
|
||||
{
|
||||
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(
|
||||
|
||||
@@ -16,14 +16,15 @@ GNU General Public License for more details.
|
||||
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 { Platform } from "react-native";
|
||||
import BackgroundFetch from "@ammarahmed/react-native-background-fetch";
|
||||
import { AppRegistry, AppState, Platform } from "react-native";
|
||||
import {
|
||||
beginBackgroundTask,
|
||||
endBackgroundTask
|
||||
} from "react-native-begin-background-task";
|
||||
import BackgroundFetch from "@ammarahmed/react-native-background-fetch";
|
||||
import { DatabaseLogger, db, setupDatabase } from "../common/database";
|
||||
import { AppState, AppRegistry } from "react-native";
|
||||
import { deleteDCacheFiles } from "../common/filesystem/io";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import Notifications from "./notifications";
|
||||
import SettingsService from "./settings";
|
||||
|
||||
@@ -114,15 +115,19 @@ async function onBackgroundSyncStarted() {
|
||||
await db.init();
|
||||
}
|
||||
const user = await db.user?.getUser();
|
||||
if (user) {
|
||||
if (user && !useUserStore.getState().syncing) {
|
||||
useUserStore.getState().setSyncing(true);
|
||||
await db.sync({
|
||||
type: "full",
|
||||
force: false
|
||||
});
|
||||
useUserStore.getState().setSyncing(false);
|
||||
}
|
||||
await Notifications.setupReminders();
|
||||
deleteDCacheFiles();
|
||||
DatabaseLogger.info("BACKGROUND SYNC COMPLETE");
|
||||
} catch (e) {
|
||||
useUserStore.getState().setSyncing(false);
|
||||
DatabaseLogger.error(e as Error);
|
||||
console.log("BACKGROUND SYNC ERROR", (e as Error).message);
|
||||
}
|
||||
@@ -132,11 +137,13 @@ const onBoot = async () => {
|
||||
try {
|
||||
if (!SettingsService.getProperty("backgroundSync")) {
|
||||
DatabaseLogger.info("BACKGROUND SYNC ON BOOT DISABLED");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DatabaseLogger.info("BOOT TASK STARTED");
|
||||
if (!db.isInitialized) {
|
||||
await setupDatabase();
|
||||
await db.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ 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 { sanitizeFilename } from "@notesnook/common";
|
||||
import { formatDate } from "@notesnook/core/dist/utils/date";
|
||||
import { Platform } from "react-native";
|
||||
import RNFetchBlob from "react-native-blob-util";
|
||||
import FileViewer from "react-native-file-viewer";
|
||||
@@ -25,8 +27,14 @@ import Share from "react-native-share";
|
||||
import { zip } from "react-native-zip-archive";
|
||||
import { DatabaseLogger, db } from "../common/database";
|
||||
import storage from "../common/database/storage";
|
||||
import filesystem from "../common/filesystem";
|
||||
import { cacheDir, copyFileAsync } from "../common/filesystem/utils";
|
||||
import { presentDialog } from "../components/dialog/functions";
|
||||
import {
|
||||
endProgress,
|
||||
startProgress,
|
||||
updateProgress
|
||||
} from "../components/dialogs/progress";
|
||||
import { eCloseSheet } from "../utils/events";
|
||||
import { sleep } from "../utils/time";
|
||||
import { ToastManager, eSendEvent, presentSheet } from "./event-manager";
|
||||
@@ -37,14 +45,14 @@ const MS_WEEK = MS_DAY * 7;
|
||||
const MONTH = MS_DAY * 30;
|
||||
|
||||
async function getDirectoryAndroid() {
|
||||
let folder = await ScopedStorage.openDocumentTree(true);
|
||||
const folder = await ScopedStorage.openDocumentTree(true);
|
||||
if (!folder) return null;
|
||||
let subfolder;
|
||||
if (!folder.name.includes("Notesnook backups")) {
|
||||
let folderFiles = await ScopedStorage.listFiles(folder.uri);
|
||||
for (let f of folderFiles) {
|
||||
if (f.type === "directory" && f.name === "Notesnook backups") {
|
||||
subfolder = f;
|
||||
const files = await ScopedStorage.listFiles(folder.uri);
|
||||
for (const file of files) {
|
||||
if (file.type === "directory" && file.name === "Notesnook backups") {
|
||||
subfolder = file;
|
||||
}
|
||||
}
|
||||
if (!subfolder) {
|
||||
@@ -67,10 +75,10 @@ async function checkBackupDirExists(reset = false, context = "global") {
|
||||
let dir = SettingsService.get().backupDirectoryAndroid;
|
||||
if (reset) dir = null;
|
||||
if (dir) {
|
||||
let allDirs = await ScopedStorage.getPersistedUriPermissions();
|
||||
const allDirs = await ScopedStorage.getPersistedUriPermissions();
|
||||
let exists = allDirs.findIndex((d) => {
|
||||
return d === dir.uri || dir.uri.includes(d);
|
||||
});
|
||||
return d === dir?.uri || dir?.uri.includes(d);
|
||||
}) as number | boolean;
|
||||
exists = exists !== -1;
|
||||
dir = exists ? dir : null;
|
||||
}
|
||||
@@ -100,7 +108,7 @@ async function checkBackupDirExists(reset = false, context = "global") {
|
||||
return dir;
|
||||
}
|
||||
|
||||
async function presentBackupCompleteSheet(backupFilePath) {
|
||||
async function presentBackupCompleteSheet(backupFilePath: string) {
|
||||
presentSheet({
|
||||
title: "Backup complete",
|
||||
icon: "cloud-upload",
|
||||
@@ -123,7 +131,7 @@ async function presentBackupCompleteSheet(backupFilePath) {
|
||||
showOpenWithDialog: true,
|
||||
showAppsSuggestions: true,
|
||||
shareFile: true
|
||||
}).catch(console.log);
|
||||
} as any).catch(console.log);
|
||||
}
|
||||
},
|
||||
actionText: "Share"
|
||||
@@ -142,10 +150,10 @@ async function presentBackupCompleteSheet(backupFilePath) {
|
||||
});
|
||||
}
|
||||
|
||||
async function updateNextBackupTime() {
|
||||
async function updateNextBackupTime(type: "full" | "partial") {
|
||||
SettingsService.set({
|
||||
nextBackupRequestTime: Date.now() + 86400000 * 3,
|
||||
lastBackupDate: Date.now()
|
||||
[type === "full" ? "lastFullBackupDate" : "lastBackupDate"]: Date.now()
|
||||
});
|
||||
}
|
||||
/**
|
||||
@@ -153,77 +161,124 @@ async function updateNextBackupTime() {
|
||||
* @param {string=} context
|
||||
* @returns {Promise<{path?: string, error?: Error, report?: boolean}}>
|
||||
*/
|
||||
async function run(progress = false, context) {
|
||||
let androidBackupDirectory = await checkBackupDirExists(false, context);
|
||||
async function run(
|
||||
progress = false,
|
||||
context?: string,
|
||||
backupType: "full" | "partial" = "partial"
|
||||
) {
|
||||
console.log("Creating backup:", backupType, progress, context);
|
||||
|
||||
const androidBackupDirectory = (await checkBackupDirExists(
|
||||
false,
|
||||
context
|
||||
)) as ScopedStorage.FileType;
|
||||
|
||||
if (!androidBackupDirectory)
|
||||
return {
|
||||
error: new Error("Backup directory not selected"),
|
||||
report: false
|
||||
};
|
||||
|
||||
let path;
|
||||
|
||||
if (Platform.OS === "ios") {
|
||||
path = await storage.checkAndCreateDir("/backups");
|
||||
}
|
||||
|
||||
const backupFileName = sanitizeFilename(
|
||||
`${formatDate(Date.now(), {
|
||||
type: "date-time",
|
||||
dateFormat: "YYYY-MM-DD",
|
||||
timeFormat: "24-hour"
|
||||
})}-${new Date().getSeconds()}${backupType === "full" ? "-full" : ""}`,
|
||||
{ replacement: "-" }
|
||||
);
|
||||
|
||||
if (progress) {
|
||||
presentSheet({
|
||||
title: "Backing up your data",
|
||||
paragraph:
|
||||
"All your backups are stored in 'Phone Storage/Notesnook/backups/' folder",
|
||||
progress: true
|
||||
startProgress({
|
||||
title: `Creating ${backupType === "full" ? "a full " : ""}backup`,
|
||||
paragraph: `Please wait while we create a backup of your data. This may take a few minutes.`,
|
||||
progress: undefined
|
||||
});
|
||||
}
|
||||
|
||||
let path;
|
||||
let backupFileName = "notesnook_backup_" + Date.now();
|
||||
|
||||
if (Platform.OS === "ios") {
|
||||
path = await storage.checkAndCreateDir("/backups/");
|
||||
}
|
||||
|
||||
const zipSourceFolder = `${cacheDir}/${backupFileName}`;
|
||||
const zipSourceFolder = `${cacheDir}/backup_temp`;
|
||||
const zipOutputFile =
|
||||
Platform.OS === "ios"
|
||||
? `${path}/${backupFileName}.nnbackupz`
|
||||
: `${cacheDir}/${backupFileName}.nnbackupz`;
|
||||
|
||||
try {
|
||||
if (await RNFetchBlob.fs.exists(zipSourceFolder))
|
||||
await RNFetchBlob.fs.unlink(zipSourceFolder);
|
||||
} catch (e) {}
|
||||
|
||||
await RNFetchBlob.fs.unlink(zipSourceFolder).catch(console.log);
|
||||
await RNFetchBlob.fs.mkdir(zipSourceFolder);
|
||||
|
||||
const attachmentsDir = zipSourceFolder + "/attachments";
|
||||
if (backupType === "full") {
|
||||
await RNFetchBlob.fs.mkdir(attachmentsDir);
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await db.user.getUser();
|
||||
for await (const file of db.backup.export(
|
||||
"mobile",
|
||||
SettingsService.get().encryptedBackup && user
|
||||
)) {
|
||||
console.log("Writing backup chunk of size...", file?.data?.length);
|
||||
await RNFetchBlob.fs.writeFile(
|
||||
`${zipSourceFolder}/${file.path}`,
|
||||
file.data,
|
||||
"utf8"
|
||||
);
|
||||
for await (const file of db.backup.export({
|
||||
type: "mobile",
|
||||
encrypt: SettingsService.get().encryptedBackup && !!user,
|
||||
mode: backupType
|
||||
})) {
|
||||
if (file.type === "file") {
|
||||
updateProgress({
|
||||
progress: `Writing backup chunk of size... ${file?.data?.length}`
|
||||
});
|
||||
await RNFetchBlob.fs.writeFile(
|
||||
`${zipSourceFolder}/${file.path}`,
|
||||
file.data,
|
||||
"utf8"
|
||||
);
|
||||
} else if (file.type === "attachment") {
|
||||
updateProgress({
|
||||
progress: `Saving attachments in backup... ${file.hash}`
|
||||
});
|
||||
if (await filesystem.exists(file.hash)) {
|
||||
await RNFetchBlob.fs.cp(
|
||||
`${cacheDir}/${file.hash}`,
|
||||
`${attachmentsDir}/${file.hash}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress({
|
||||
progress: "Creating backup zip file..."
|
||||
});
|
||||
|
||||
await zip(zipSourceFolder, zipOutputFile);
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
// Move the zip to user selected directory.
|
||||
const file = await ScopedStorage.createFile(
|
||||
androidBackupDirectory.uri,
|
||||
androidBackupDirectory?.uri,
|
||||
`${backupFileName}.nnbackupz`,
|
||||
"application/nnbackupz"
|
||||
);
|
||||
console.log("Copying zip file...");
|
||||
await copyFileAsync(`file://${zipOutputFile}`, file.uri);
|
||||
console.log("Copyied zip file...");
|
||||
|
||||
console.log("Copied zip file...");
|
||||
path = file.uri;
|
||||
} else {
|
||||
path = zipOutputFile;
|
||||
}
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(console.log);
|
||||
updateNextBackupTime();
|
||||
|
||||
let showBackupCompleteSheet =
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(console.log);
|
||||
if (Platform.OS === "android") {
|
||||
RNFetchBlob.fs.unlink(zipOutputFile).catch(console.log);
|
||||
}
|
||||
|
||||
updateNextBackupTime(backupType || "partial");
|
||||
|
||||
if (progress) {
|
||||
endProgress();
|
||||
}
|
||||
|
||||
const canShowCompletionStatus =
|
||||
progress && SettingsService.get().showBackupCompleteSheet;
|
||||
|
||||
if (context) {
|
||||
@@ -234,15 +289,12 @@ async function run(progress = false, context) {
|
||||
|
||||
await sleep(300);
|
||||
|
||||
if (showBackupCompleteSheet) {
|
||||
if (canShowCompletionStatus) {
|
||||
presentBackupCompleteSheet(path);
|
||||
} else {
|
||||
progress && eSendEvent(eCloseSheet);
|
||||
}
|
||||
|
||||
ToastManager.show({
|
||||
heading: "Backup successful",
|
||||
message: "Your backup is stored in Notesnook folder on your phone.",
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
@@ -251,16 +303,26 @@ async function run(progress = false, context) {
|
||||
path: path
|
||||
};
|
||||
} catch (e) {
|
||||
ToastManager.error(e, "Backup failed", context || "global");
|
||||
ToastManager.error(e as Error, "Backup failed", context || "global");
|
||||
|
||||
if (e?.message?.includes("android.net.Uri") && androidBackupDirectory) {
|
||||
if (
|
||||
(e as Error)?.message?.includes("android.net.Uri") &&
|
||||
androidBackupDirectory
|
||||
) {
|
||||
SettingsService.setProperty("backupDirectoryAndroid", null);
|
||||
return run(progress, context);
|
||||
return run(progress, context, backupType);
|
||||
}
|
||||
|
||||
RNFetchBlob.fs.unlink(zipSourceFolder).catch(console.log);
|
||||
if (Platform.OS === "android") {
|
||||
RNFetchBlob.fs.unlink(zipOutputFile).catch(console.log);
|
||||
}
|
||||
|
||||
DatabaseLogger.error(e);
|
||||
await sleep(300);
|
||||
progress && eSendEvent(eCloseSheet);
|
||||
if (progress) {
|
||||
endProgress();
|
||||
}
|
||||
return {
|
||||
error: e,
|
||||
report: true
|
||||
@@ -268,34 +330,41 @@ async function run(progress = false, context) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getLastBackupDate() {
|
||||
return SettingsService.get().lastBackupDate;
|
||||
}
|
||||
async function checkBackupRequired(
|
||||
type: "daily" | "off" | "useroff" | "weekly" | "monthly" | "never",
|
||||
lastBackupDateType: "lastBackupDate" | "lastFullBackupDate" = "lastBackupDate"
|
||||
) {
|
||||
console.log(lastBackupDateType, type);
|
||||
if (type === "off" || type === "useroff" || type === "never" || !type) return;
|
||||
const now = Date.now();
|
||||
const lastBackupDate = SettingsService.getProperty(lastBackupDateType) as
|
||||
| number
|
||||
| "never";
|
||||
|
||||
async function checkBackupRequired(type) {
|
||||
if (type === "off" || type === "useroff") return;
|
||||
let now = Date.now();
|
||||
let lastBackupDate = await getLastBackupDate();
|
||||
if (!lastBackupDate || lastBackupDate === "never") {
|
||||
if (
|
||||
lastBackupDate === undefined ||
|
||||
lastBackupDate === "never" ||
|
||||
lastBackupDate === 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
lastBackupDate = parseInt(lastBackupDate);
|
||||
|
||||
if (type === "daily" && lastBackupDate + MS_DAY < now) {
|
||||
DatabaseLogger.info("Daily backup started");
|
||||
DatabaseLogger.info(`Daily backup started: ${type}`);
|
||||
return true;
|
||||
} else if (type === "weekly" && lastBackupDate + MS_WEEK < now) {
|
||||
DatabaseLogger.info("Weekly backup started");
|
||||
DatabaseLogger.info(`Weekly backup started: ${type}`);
|
||||
return true;
|
||||
} else if (type === "monthly" && lastBackupDate + MONTH < now) {
|
||||
DatabaseLogger.info("Monthly backup started");
|
||||
DatabaseLogger.info(`Monthly backup started: ${type}`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const checkAndRun = async () => {
|
||||
let settings = SettingsService.get();
|
||||
if (await checkBackupRequired(settings.reminder)) {
|
||||
const settings = SettingsService.get();
|
||||
if (await checkBackupRequired(settings?.reminder)) {
|
||||
try {
|
||||
await run();
|
||||
} catch (e) {
|
||||
@@ -30,6 +30,7 @@ import { scale, updateSize } from "../utils/size";
|
||||
import { DatabaseLogger } from "../common/database";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
|
||||
function reset() {
|
||||
const settings = get();
|
||||
if (settings.reminder !== "off" && settings.reminder !== "useroff") {
|
||||
@@ -40,10 +41,15 @@ function reset() {
|
||||
}
|
||||
|
||||
function resetSettings() {
|
||||
MMKV.setString(
|
||||
"appSettings",
|
||||
JSON.stringify({ ...defaultSettings, introCompleted: true })
|
||||
);
|
||||
const settings: SettingStore["settings"] = {
|
||||
...defaultSettings,
|
||||
introCompleted: true,
|
||||
serverUrls: get().serverUrls,
|
||||
backupDirectoryAndroid: undefined
|
||||
};
|
||||
|
||||
MMKV.setString("appSettings", JSON.stringify(settings));
|
||||
set(settings);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@ export const ignoredMessages = [
|
||||
"Sync already running",
|
||||
"Not allowed to start service intent",
|
||||
"WebSocket failed to connect",
|
||||
"Failed to start the HttpConnection before"
|
||||
"Failed to start the HttpConnection before",
|
||||
"Could not connect to the Sync server",
|
||||
"Network request failed"
|
||||
];
|
||||
let pendingSync: any = undefined;
|
||||
let syncTimer: NodeJS.Timeout;
|
||||
@@ -61,58 +63,45 @@ const run = async (
|
||||
|
||||
clearTimeout(syncTimer);
|
||||
syncTimer = setTimeout(async () => {
|
||||
const status = await NetInfo.fetch();
|
||||
const userstore = useUserStore.getState();
|
||||
userstore.setSyncing(true);
|
||||
const user = await db.user.getUser();
|
||||
if (!status.isInternetReachable) {
|
||||
DatabaseLogger.warn("Internet not reachable");
|
||||
}
|
||||
|
||||
if (
|
||||
!user ||
|
||||
!status.isInternetReachable ||
|
||||
SettingsService.get().disableSync
|
||||
) {
|
||||
if (!user || SettingsService.get().disableSync) {
|
||||
userstore.setSyncing(false);
|
||||
initAfterSync();
|
||||
pendingSync = undefined;
|
||||
return onCompleted?.(SyncStatus.Failed);
|
||||
}
|
||||
userstore.setSyncing(true);
|
||||
|
||||
let error = null;
|
||||
let error: Error | undefined = undefined;
|
||||
|
||||
try {
|
||||
await BackgroundSync.doInBackground(async () => {
|
||||
try {
|
||||
await db.sync({
|
||||
type: type,
|
||||
force: forced
|
||||
force: forced,
|
||||
offlineMode: SettingsService.get().offlineMode
|
||||
});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
error = e as Error;
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
if (error) throw error;
|
||||
} catch (e) {
|
||||
error = e;
|
||||
error = e as Error;
|
||||
DatabaseLogger.error(error, "[Client] Failed to sync");
|
||||
if (
|
||||
!ignoredMessages.find((message) =>
|
||||
(e as Error).message?.includes(message)
|
||||
) &&
|
||||
userstore.user &&
|
||||
status.isConnected &&
|
||||
status.isInternetReachable
|
||||
!ignoredMessages.find((message) => error?.message?.includes(message)) &&
|
||||
userstore.user
|
||||
) {
|
||||
userstore.setSyncing(false, SyncStatus.Failed);
|
||||
const status = await NetInfo.fetch();
|
||||
if (status.isConnected && status.isInternetReachable) {
|
||||
ToastManager.error(e as Error, "Sync failed", context);
|
||||
}
|
||||
}
|
||||
|
||||
DatabaseLogger.error(e, "[Client] Failed to sync");
|
||||
} finally {
|
||||
initAfterSync();
|
||||
userstore.setSyncing(
|
||||
@@ -120,16 +109,14 @@ const run = async (
|
||||
error ? SyncStatus.Failed : SyncStatus.Passed
|
||||
);
|
||||
onCompleted?.(error ? SyncStatus.Failed : SyncStatus.Passed);
|
||||
setImmediate(() => {
|
||||
if (pendingSync)
|
||||
Sync.run(
|
||||
pendingSync.context,
|
||||
pendingSync.forced,
|
||||
pendingSync.type,
|
||||
pendingSync.onCompleted,
|
||||
pendingSync.lastSyncTime
|
||||
);
|
||||
});
|
||||
if (pendingSync)
|
||||
Sync.run(
|
||||
pendingSync.context,
|
||||
pendingSync.forced,
|
||||
pendingSync.type,
|
||||
pendingSync.onCompleted,
|
||||
pendingSync.lastSyncTime
|
||||
);
|
||||
}
|
||||
}, 300);
|
||||
};
|
||||
|
||||
@@ -25,6 +25,8 @@ import { FileType } from "react-native-scoped-storage";
|
||||
import create, { State } from "zustand";
|
||||
import { ThemeDark, ThemeLight, ThemeDefinition } from "@notesnook/theme";
|
||||
import { Reminder } from "@notesnook/core/dist/types";
|
||||
export const HostIds = ["API_HOST", "AUTH_HOST", "SSE_HOST"] as const;
|
||||
export type HostId = (typeof HostIds)[number];
|
||||
|
||||
export type Settings = {
|
||||
showToolbarOnTop?: boolean;
|
||||
@@ -32,7 +34,8 @@ export type Settings = {
|
||||
fontScale?: number;
|
||||
forcePortraitOnTablet?: boolean;
|
||||
useSystemTheme?: boolean;
|
||||
reminder?: string;
|
||||
reminder: "daily" | "off" | "useroff" | "weekly" | "monthly";
|
||||
fullBackupReminder: "never" | "weekly" | "monthly";
|
||||
encryptedBackup?: boolean;
|
||||
homepage?: string;
|
||||
sort?: string;
|
||||
@@ -42,7 +45,6 @@ export type Settings = {
|
||||
appLockTimer: number;
|
||||
appLockEnabled?: boolean;
|
||||
appLockMode?: "none" | "background" | "launch";
|
||||
telemetry?: boolean;
|
||||
notebooksListMode?: "normal" | "compact";
|
||||
notesListMode?: "normal" | "compact";
|
||||
devMode?: boolean;
|
||||
@@ -52,8 +54,8 @@ export type Settings = {
|
||||
rateApp?: boolean | number;
|
||||
migrated?: boolean;
|
||||
introCompleted?: boolean;
|
||||
nextBackupRequestTime?: number | undefined;
|
||||
lastBackupDate?: number | undefined;
|
||||
nextBackupRequestTime?: number;
|
||||
lastBackupDate?: number;
|
||||
userEmailConfirmed?: boolean;
|
||||
recoveryKeySaved?: boolean;
|
||||
backupDirectoryAndroid?: FileType | null;
|
||||
@@ -82,6 +84,10 @@ export type Settings = {
|
||||
backgroundSync?: boolean;
|
||||
applockKeyboardType: "numeric" | "default";
|
||||
settingsVersion?: number;
|
||||
backupType: "full" | "partial";
|
||||
offlineMode?: boolean;
|
||||
lastFullBackupDate?: number;
|
||||
serverUrls?: Record<HostId, string>;
|
||||
};
|
||||
|
||||
type DimensionsType = {
|
||||
@@ -127,6 +133,12 @@ export const defaultSettings: SettingStore["settings"] = {
|
||||
applockKeyboardType: "numeric",
|
||||
appLockTimer: 0,
|
||||
showToolbarOnTop: false,
|
||||
disableAutoSync: false,
|
||||
disableRealtimeSync: false,
|
||||
disableSync: false,
|
||||
appLockEnabled: false,
|
||||
backupDirectoryAndroid: null,
|
||||
offlineMode: false,
|
||||
showKeyboardOnOpen: false,
|
||||
fontScale: 1,
|
||||
forcePortraitOnTablet: false,
|
||||
@@ -139,7 +151,6 @@ export const defaultSettings: SettingStore["settings"] = {
|
||||
screenshotMode: true,
|
||||
privacyScreen: false,
|
||||
appLockMode: "none",
|
||||
telemetry: false,
|
||||
notebooksListMode: "normal",
|
||||
notesListMode: "normal",
|
||||
devMode: false,
|
||||
@@ -150,7 +161,7 @@ export const defaultSettings: SettingStore["settings"] = {
|
||||
migrated: false,
|
||||
introCompleted: Config.isTesting ? true : false,
|
||||
nextBackupRequestTime: undefined,
|
||||
lastBackupDate: undefined,
|
||||
lastBackupDate: 0,
|
||||
userEmailConfirmed: false,
|
||||
recoveryKeySaved: false,
|
||||
showBackupCompleteSheet: true,
|
||||
@@ -171,7 +182,10 @@ export const defaultSettings: SettingStore["settings"] = {
|
||||
biometricsAuthEnabled: false,
|
||||
appLockHasPasswordSecurity: false,
|
||||
backgroundSync: true,
|
||||
settingsVersion: 0
|
||||
settingsVersion: 0,
|
||||
backupType: "partial",
|
||||
fullBackupReminder: "never",
|
||||
lastFullBackupDate: 0
|
||||
};
|
||||
|
||||
export const useSettingStore = create<SettingStore>((set, get) => ({
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
source 'https://rubygems.org'
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby ">= 2.6.10"
|
||||
gem 'cocoapods', '~> 1.12'
|
||||
# Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
|
||||
# bound in the template on Cocoapods with next React Native release.
|
||||
gem 'cocoapods', '>= 1.13', '< 1.15'
|
||||
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
|
||||
@@ -1,5 +1,7 @@
|
||||
apply plugin: "com.android.application"
|
||||
apply plugin: "org.jetbrains.kotlin.android"
|
||||
apply plugin: "com.facebook.react"
|
||||
|
||||
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
@@ -47,7 +49,6 @@ react {
|
||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
|
||||
hermesFlags = ["-O", "-output-source-map"]
|
||||
}
|
||||
println(projectDir);
|
||||
|
||||
/**
|
||||
* Set this to true to create two separate APKs instead of one:
|
||||
@@ -96,10 +97,14 @@ def getNpmVersion() {
|
||||
return jsonPackage["version"]
|
||||
}
|
||||
|
||||
def isBuildingAAB = gradle.startParameter.getTaskNames().any { it.contains("bundleRelease") }
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
compileSdk rootProject.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
@@ -111,7 +116,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3020
|
||||
versionCode 3027
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
@@ -163,8 +168,12 @@ android {
|
||||
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
jniLibs {
|
||||
useLegacyPackaging isBuildingAAB == false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
@@ -178,9 +187,15 @@ android {
|
||||
defaultConfig.versionCode * 5 + versionCodes.get(abi)
|
||||
println("Fdroid Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
|
||||
} else {
|
||||
println("Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
|
||||
output.versionCodeOverride =
|
||||
if (isBuildingAAB) {
|
||||
output.versionCodeOverride = 4 * 1048576 + defaultConfig.versionCode
|
||||
println("AAB version code: ${output.versionCodeOverride}");
|
||||
} else {
|
||||
output.versionCodeOverride =
|
||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||
println("Version code: ${output.versionCodeOverride} for abi ${versionCodes.get(abi)}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -203,13 +218,7 @@ dependencies {
|
||||
|
||||
androidTestImplementation('com.wix:detox:+')
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
|
||||
|
||||
if (hermesEnabled.toBoolean()) {
|
||||
implementation("com.facebook.react:hermes-android")
|
||||
} else {
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="28"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package com.streetwriters.notesnook;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
import com.facebook.flipper.core.FlipperClient;
|
||||
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceEventListener;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class ReactNativeFlipper {
|
||||
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||
|
||||
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||
|
||||
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||
NetworkingModule.setCustomClientBuilder(
|
||||
new NetworkingModule.CustomClientBuilder() {
|
||||
@Override
|
||||
public void apply(OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||
}
|
||||
});
|
||||
client.addPlugin(networkFlipperPlugin);
|
||||
client.start();
|
||||
|
||||
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||
// Hence we run if after all native modules have been initialized
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" tools:node="remove" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
|
||||
@@ -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,65 +0,0 @@
|
||||
package com.streetwriters.notesnook;
|
||||
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost;
|
||||
|
||||
public class MainApplication extends MultiDexApplication implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new DefaultReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
packages.add(new NNativeModulePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNewArchEnabled() {
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean isHermesEnabled() {
|
||||
return BuildConfig.IS_HERMES_ENABLED;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||
DefaultNewArchitectureEntryPoint.load();
|
||||
}
|
||||
com.streetwriters.notesnook.ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.streetwriters.notesnook
|
||||
|
||||
import android.app.Application
|
||||
import com.facebook.react.PackageList
|
||||
import com.facebook.react.ReactApplication
|
||||
import com.facebook.react.ReactHost
|
||||
import com.facebook.react.ReactNativeHost
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
|
||||
override val reactNativeHost: ReactNativeHost =
|
||||
object : DefaultReactNativeHost(this) {
|
||||
override fun getPackages(): List<ReactPackage> =
|
||||
PackageList(this).packages.apply {
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// add(MyReactNativePackage())
|
||||
add(NNativeModulePackage());
|
||||
}
|
||||
|
||||
override fun getJSMainModuleName(): String = "index"
|
||||
|
||||
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
||||
|
||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
|
||||
}
|
||||
|
||||
override val reactHost: ReactHost
|
||||
get() = getDefaultReactHost(applicationContext, reactNativeHost)
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
SoLoader.init(this, false)
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||
load()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ public class ShareApplication extends MultiDexApplication implements ReactApplic
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "33.0.0"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 33
|
||||
targetSdkVersion = 33
|
||||
ext.kotlinVersion = '1.8.0'
|
||||
buildToolsVersion = "34.0.0"
|
||||
minSdkVersion = 23
|
||||
compileSdkVersion = 34
|
||||
targetSdkVersion = 34
|
||||
kotlinVersion = '1.9.22'
|
||||
androidXAnnotation = "1.1.0"
|
||||
androidXCoreVersion = "1.7.0"
|
||||
androidXCore = "1.7.0"
|
||||
@@ -23,10 +23,11 @@ buildscript {
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.facebook.react.rootproject"
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
@@ -38,9 +39,9 @@ allprojects {
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
}
|
||||
// tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
// kotlinOptions {
|
||||
// jvmTarget = "11"
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.182.0
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
29
apps/mobile/native/android/gradlew
vendored
29
apps/mobile/native/android/gradlew
vendored
@@ -83,10 +83,8 @@ done
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,10 +131,13 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
||||
20
apps/mobile/native/android/gradlew.bat
vendored
20
apps/mobile/native/android/gradlew.bat
vendored
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
- Bug fixes and performance improvements
|
||||
- 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!
|
||||
@@ -2,7 +2,7 @@ const env = process.env.BABEL_ENV || process.env.NODE_ENV;
|
||||
const configs = {
|
||||
env: {
|
||||
development: {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
@@ -18,7 +18,7 @@ const configs = {
|
||||
]
|
||||
},
|
||||
test: {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
'react-native-reanimated/plugin',
|
||||
@@ -40,7 +40,7 @@ const configs = {
|
||||
|
||||
},
|
||||
production: {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
'transform-remove-console',
|
||||
'@babel/plugin-transform-named-capturing-groups-regex',
|
||||
|
||||
Binary file not shown.
@@ -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) {
|
||||
|
||||
38
apps/mobile/native/ios/Make Note/PrivacyInfo.xprivacy
Normal file
38
apps/mobile/native/ios/Make Note/PrivacyInfo.xprivacy
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array>
|
||||
</array>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
38
apps/mobile/native/ios/NotesWidget/PrivacyInfo.xprivacy
Normal file
38
apps/mobile/native/ios/NotesWidget/PrivacyInfo.xprivacy
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array>
|
||||
</array>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -14,6 +14,7 @@
|
||||
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
2DCD954D1E0B4F2C00145EB5 /* NotesnookTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* NotesnookTests.m */; };
|
||||
2E4BF736C2EB268ED3FD9C29 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */; };
|
||||
6510E6D72877215700DACAA9 /* build.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 6510E6D62877215700DACAA9 /* build.bundle */; };
|
||||
6515C42F2580AA3000E83E39 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6515C42E2580AA2F00E83E39 /* StoreKit.framework */; };
|
||||
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */; };
|
||||
@@ -42,6 +43,7 @@
|
||||
87CE5B71DC72F3D95B7B1AA5 /* libPods-Notesnook-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A03E3F5851D27269540E147C /* libPods-Notesnook-tvOSTests.a */; };
|
||||
A79A93DC9D0CAE8703462151 /* libPods-Notesnook-NotesnookTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 068FA9BDFA207A50B0A9E597 /* libPods-Notesnook-NotesnookTests.a */; };
|
||||
C619D096A9DE2070DBEAC70F /* libPods-Make Note.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C4AF691C324D95337F2FB0A /* libPods-Make Note.a */; };
|
||||
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */; };
|
||||
F50BF8BC21F8B58EB2B5A31A /* libPods-Notesnook-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 16C0296DE7A2B4102817F5C1 /* libPods-Notesnook-tvOS.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -110,6 +112,7 @@
|
||||
2D02E4901E0B4A5D006451C7 /* Notesnook-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Notesnook-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
41D57E9831C724F59F18FBAE /* libPods-Notesnook-Add to Notes.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook-Add to Notes.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
47AE097A087A651BD60CAD7B /* Pods-Notesnook-Make Note.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-Make Note.release.xcconfig"; path = "Target Support Files/Pods-Notesnook-Make Note/Pods-Notesnook-Make Note.release.xcconfig"; sourceTree = "<group>"; };
|
||||
4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Notesnook/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
4BD34AE0C0FD2416E48803B8 /* libPods-Notesnook.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4C4AF691C324D95337F2FB0A /* libPods-Make Note.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Make Note.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6510E6D62877215700DACAA9 /* build.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = build.bundle; path = "../../../../packages/editor-mobile/build.bundle"; sourceTree = "<group>"; };
|
||||
@@ -149,6 +152,7 @@
|
||||
88211800FA8BF60638327ADE /* Pods-Make Note.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Make Note.debug.xcconfig"; path = "Target Support Files/Pods-Make Note/Pods-Make Note.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
A03E3F5851D27269540E147C /* libPods-Notesnook-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Notesnook-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A84F3F0D50641D1CD4569B0E /* Pods-Make Note.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Make Note.release.xcconfig"; path = "Target Support Files/Pods-Make Note/Pods-Make Note.release.xcconfig"; sourceTree = "<group>"; };
|
||||
B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Notesnook/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
B9989E5C777BB11343A62D09 /* Pods-Notesnook-NotesnookTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-NotesnookTests.debug.xcconfig"; path = "Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D1710CA05FED221CC56D2BE1 /* Pods-Notesnook-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Notesnook-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-Notesnook-tvOSTests/Pods-Notesnook-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
@@ -243,6 +247,7 @@
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
65E0340A257B9FF100793428 /* File.swift */,
|
||||
65E03409257B9FF100793428 /* Notesnook-Bridging-Header.h */,
|
||||
4B679E87FDFB1312CAD6CF45 /* PrivacyInfo.xcprivacy */,
|
||||
);
|
||||
name = Notesnook;
|
||||
sourceTree = "<group>";
|
||||
@@ -315,6 +320,7 @@
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
DA84645424CFBF19A44D64B3 /* Pods */,
|
||||
B5216B66C0B4A91C0A69128B /* PrivacyInfo.xcprivacy */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -367,6 +373,7 @@
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
819D480147D052141ACC55A9 /* [CP] Copy Pods Resources */,
|
||||
310C868ED8D8299D75460154 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -390,6 +397,7 @@
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
240525450DF9ABA0F332B52E /* [CP] Copy Pods Resources */,
|
||||
65A7F34B255687E600699170 /* Embed App Extensions */,
|
||||
48C834D962D612F18A0388B3 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -556,6 +564,7 @@
|
||||
6510E6D72877215700DACAA9 /* build.bundle in Resources */,
|
||||
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */,
|
||||
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */,
|
||||
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -564,6 +573,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
|
||||
2E4BF736C2EB268ED3FD9C29 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -642,13 +652,13 @@
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -692,6 +702,42 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nexport NODE_BINARY=node\n../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh";
|
||||
};
|
||||
310C868ED8D8299D75460154 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
48C834D962D612F18A0388B3 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
52B9E42E0FD77D180139A8C7 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -763,13 +809,13 @@
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -806,11 +852,11 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Make Note/Pods-Make Note-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -1015,7 +1061,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1089,7 +1135,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1120,7 +1166,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1194,7 +1240,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1353,7 +1399,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1365,7 +1411,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1396,7 +1442,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1409,7 +1455,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1439,7 +1485,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1513,7 +1559,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1544,7 +1590,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2109;
|
||||
CURRENT_PROJECT_VERSION = 2114;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1619,7 +1665,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.12;
|
||||
MARKETING_VERSION = 3.0.17;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1638,7 +1684,7 @@
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -1696,8 +1742,13 @@
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
USE_HERMES = true;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -1707,7 +1758,7 @@
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++20";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -1758,8 +1809,13 @@
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
USE_HERMES = true;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -19,9 +19,16 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [self bundleURL];
|
||||
}
|
||||
|
||||
- (NSURL *)bundleURL
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
@@ -71,14 +71,11 @@
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Take a picture and add it to your note.</string>
|
||||
@@ -115,7 +112,7 @@
|
||||
<string>BootSplash</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
|
||||
37
apps/mobile/native/ios/Notesnook/PrivacyInfo.xcprivacy
Normal file
37
apps/mobile/native/ios/Notesnook/PrivacyInfo.xcprivacy
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
38
apps/mobile/native/ios/Notesnook/PrivacyInfo.xprivacy
Normal file
38
apps/mobile/native/ios/Notesnook/PrivacyInfo.xprivacy
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array>
|
||||
</array>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -14,16 +14,7 @@ require Pod::Executable.execute_command('node', ['-p',
|
||||
platform :ios, min_ios_version_supported
|
||||
prepare_react_native_project!
|
||||
|
||||
# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
|
||||
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
|
||||
#
|
||||
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
|
||||
# ```js
|
||||
# module.exports = {
|
||||
# dependencies: {
|
||||
# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
|
||||
# ```
|
||||
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
|
||||
|
||||
linkage = ENV['USE_FRAMEWORKS']
|
||||
if linkage != nil
|
||||
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
|
||||
@@ -38,22 +29,14 @@ pod 'MMKV'
|
||||
target 'Notesnook' do
|
||||
|
||||
config = use_native_modules!
|
||||
# Flags change depending on the env values.
|
||||
flags = get_default_flags()
|
||||
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# Hermes is now enabled by default. Disable by setting this flag to false.
|
||||
# Upcoming versions of React Native may rely on get_default_flags(), but
|
||||
# we make it explicit here to aid in the React Native upgrade process.
|
||||
:hermes_enabled => false,
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
# :flipper_configuration => flipper_config,
|
||||
# An absolute path to your application root.
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
|
||||
@@ -71,7 +54,7 @@ target 'Make Note' do
|
||||
# Hermes is now enabled by default. Disable by setting this flag to false.
|
||||
# Upcoming versions of React Native may rely on get_default_flags(), but
|
||||
# we make it explicit here to aid in the React Native upgrade process.
|
||||
:hermes_enabled => false,
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
# Enables Flipper.
|
||||
#
|
||||
@@ -118,9 +101,9 @@ post_install do |installer|
|
||||
react_native_path = "../../node_modules/react-native",
|
||||
# Set `mac_catalyst_enabled` to `true` in order to apply patches
|
||||
# necessary for Mac Catalyst builds
|
||||
:mac_catalyst_enabled => false
|
||||
:mac_catalyst_enabled => false,
|
||||
# :ccache_enabled => true
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
|
||||
@@ -130,7 +113,7 @@ post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
if target.name == "react-native-quick-sqlite" then
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'SQLITE_ENABLE_FTS5=1 SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT=1 HAVE_CIPHER_AES_128_CBC=0 HAVE_CIPHER_AES_256_CBC=0 HAVE_CIPHER_SQLCIPHER=0 HAVE_CIPHER_RC4=0 HAVE_CIPHER_CHACHA20=1 SQLITE_OMIT_PROGRESS_CALLBACK=1 SQLITE_MAX_EXPR_DEPTH=0 SQLITE_OMIT_DEPRECATED=1 SQLITE_LIKE_DOESNT_MATCH_BLOBS=1 SQLITE_DQS=0 SQLITE_DEFAULT_MEMSTATUS=0 SQLITE_USE_ALLOCA=1'
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = 'SQLITE_ENABLE_FTS5=1 SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT=1 HAVE_CIPHER_AES_128_CBC=0 HAVE_CIPHER_AES_256_CBC=0 HAVE_CIPHER_SQLCIPHER=0 HAVE_CIPHER_RC4=0 HAVE_CIPHER_CHACHA20=1 SQLITE_OMIT_PROGRESS_CALLBACK=1 SQLITE_MAX_EXPR_DEPTH=0 SQLITE_OMIT_DEPRECATED=1 SQLITE_LIKE_DOESNT_MATCH_BLOBS=1 SQLITE_DQS=0 SQLITE_DEFAULT_MEMSTATUS=0 SQLITE_USE_ALLOCA=1'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,12 +4,16 @@
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"overrides": {
|
||||
"react-native": "0.74.5",
|
||||
"react": "18.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ammarahmed/notifee-react-native": "7.4.7",
|
||||
"@ammarahmed/react-native-share-extension": "^3.0.0",
|
||||
"@ammarahmed/react-native-sodium": "1.5.4",
|
||||
"@bam.tech/react-native-image-resizer": "3.0.5",
|
||||
"@callstack/repack": "^3.2.0",
|
||||
"@callstack/repack": "^4.1.1",
|
||||
"@react-native-clipboard/clipboard": "^1.9.0",
|
||||
"@react-native-community/checkbox": "^0.5.8",
|
||||
"@react-native-community/datetimepicker": "6.6.0",
|
||||
@@ -20,9 +24,8 @@
|
||||
"@react-navigation/native": "^6.0.10",
|
||||
"@react-navigation/native-stack": "6.6.2",
|
||||
"@sayem314/react-native-keep-awake": "^1.0.4",
|
||||
"@shopify/flash-list": "1.4.0",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.72.0",
|
||||
"react-native": "0.74.5",
|
||||
"react-native-actions-shortcuts": "^1.0.1",
|
||||
"react-native-background-actions": "^2.6.6",
|
||||
"react-native-begin-background-task": "https://github.com/blockfirm/react-native-begin-background-task.git",
|
||||
@@ -36,31 +39,32 @@
|
||||
"react-native-exit-app": "https://github.com/ammarahm-ed/react-native-exit-app.git",
|
||||
"react-native-file-viewer": "^2.1.1",
|
||||
"react-native-fingerprint-scanner": "https://github.com/ammarahm-ed/react-native-fingerprint-scanner.git",
|
||||
"react-native-gesture-handler": "^2.12.0",
|
||||
"react-native-gesture-handler": "^2.18.0",
|
||||
"react-native-reanimated": "3.14.0",
|
||||
"react-native-safe-area-context": "^4.10.8",
|
||||
"react-native-screens": "^3.33.0",
|
||||
"react-native-webview": "^13.10.0",
|
||||
"@shopify/flash-list": "1.7.0",
|
||||
"react-native-vector-icons": "9.2.0",
|
||||
"react-native-get-random-values": "^1.7.0",
|
||||
"react-native-gzip": "1.1.0",
|
||||
"react-native-html-to-pdf-lite": "^0.9.1",
|
||||
"react-native-iap": "12.11.0",
|
||||
"react-native-iap": "12.15.1",
|
||||
"react-native-in-app-review": "4.3.3",
|
||||
"react-native-keychain": "4.0.5",
|
||||
"react-native-mmkv-storage": "^0.10.0-alpha.12",
|
||||
"react-native-mmkv-storage": "^0.10.2",
|
||||
"react-native-modal-datetime-picker": "14.0.0",
|
||||
"react-native-navigation-bar-color": "2.0.2",
|
||||
"react-native-notification-sounds": "0.5.5",
|
||||
"react-native-orientation": "https://github.com/yamill/react-native-orientation.git",
|
||||
"react-native-pdf": "6.6.2",
|
||||
"react-native-privacy-snapshot": "https://github.com/standardnotes/react-native-privacy-snapshot.git",
|
||||
"react-native-reanimated": "3.3.0",
|
||||
"react-native-safe-area-context": "^4.3.1",
|
||||
"react-native-scoped-storage": "^1.9.5",
|
||||
"react-native-screens": "^3.13.1",
|
||||
"react-native-securerandom": "^1.0.1",
|
||||
"react-native-share": "^7.2.0",
|
||||
"react-native-svg": "^12.3.0",
|
||||
"react-native-swiper-flatlist": "3.2.2",
|
||||
"react-native-tooltips": "^1.0.3",
|
||||
"react-native-vector-icons": "9.2.0",
|
||||
"react-native-webview": "^13.10.0",
|
||||
"react-native-zip-archive": "6.0.9",
|
||||
"react-native-quick-sqlite": "^8.0.6",
|
||||
"react-native-theme-switch-animation": "^0.6.0",
|
||||
@@ -76,19 +80,19 @@
|
||||
"@babel/plugin-transform-private-methods": "^7.22.5",
|
||||
"@babel/preset-env": "^7.20.0",
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@react-native/eslint-config": "^0.72.2",
|
||||
"@react-native/metro-config": "^0.72.6",
|
||||
"@react-native/eslint-config": "0.74.86",
|
||||
"@react-native/metro-config": "0.74.86",
|
||||
"@tsconfig/react-native": "^3.0.2",
|
||||
"@types/html-to-text": "^8.0.1",
|
||||
"@types/jest": "^29.2.1",
|
||||
"@types/metro-config": "^0.76.3",
|
||||
"@types/react": "^18.0.24",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-native": "^0.69.1",
|
||||
"@types/react-native-vector-icons": "^6.4.10",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.14.0",
|
||||
"@typescript-eslint/parser": "^5.14.0",
|
||||
"babel-jest": "^29.6.2",
|
||||
"babel-jest": "^29.6.3",
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
"babel-plugin-transform-remove-console": "6.9.4",
|
||||
@@ -100,12 +104,12 @@
|
||||
"eslint-plugin-react-native": "^4.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"expect": "^29.6.2",
|
||||
"jest": "^29.6.2",
|
||||
"jest": "^29.6.3",
|
||||
"jest-circus": "^29.6.2",
|
||||
"jest-image-snapshot": "^6.2.0",
|
||||
"metro-react-native-babel-preset": "0.76.5",
|
||||
"@react-native/babel-preset": "0.74.86",
|
||||
"pixelmatch": "^5.3.0",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier": "2.8.8",
|
||||
"react-native-actions-shortcuts": "^1.0.1",
|
||||
"react-native-bundle-visualizer": "^3.1.1",
|
||||
"react-native-cli-bump-version": "^1.3.0",
|
||||
|
||||
@@ -36,4 +36,10 @@ if (isGithubRelease) {
|
||||
}
|
||||
}
|
||||
|
||||
const repackCommands = require('@callstack/repack/commands');
|
||||
|
||||
config.commands = repackCommands.filter((command) =>
|
||||
command.name.startsWith('webpack')
|
||||
),
|
||||
|
||||
module.exports = config;
|
||||
|
||||
@@ -26,7 +26,7 @@ module.exports = (env) => {
|
||||
mode = "development",
|
||||
context = __dirname,
|
||||
entry = "./index.js",
|
||||
platform,
|
||||
platform = process.env.PLATFORM,
|
||||
minimize = mode === "production",
|
||||
devServer = undefined,
|
||||
bundleFilename = undefined,
|
||||
@@ -118,7 +118,8 @@ module.exports = (env) => {
|
||||
*/
|
||||
output: {
|
||||
clean: true,
|
||||
path: path.join(__dirname, "build/generated", platform),
|
||||
hashFunction: 'xxhash64',
|
||||
path: path.join(__dirname, 'build/generated', platform),
|
||||
filename: "index.bundle",
|
||||
chunkFilename: "[name].chunk.bundle",
|
||||
publicPath: Repack.getPublicPath({ platform, devServer }),
|
||||
@@ -172,7 +173,7 @@ module.exports = (env) => {
|
||||
"node_modules/.webpack-cache"
|
||||
),
|
||||
babelrc: false,
|
||||
presets: ["module:metro-react-native-babel-preset"],
|
||||
presets: ["module:@react-native/babel-preset"],
|
||||
plugins: [
|
||||
"react-native-reanimated/plugin",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex",
|
||||
@@ -184,7 +185,7 @@ module.exports = (env) => {
|
||||
{
|
||||
test: /\.mjs$|cjs$|js$|jsx$|ts$|tsx$/,
|
||||
include: [
|
||||
/node_modules(.*[/\\])+react/,
|
||||
/node_modules(.*[/\\])+react-native/,
|
||||
/node_modules(.*[/\\])+@react-native/,
|
||||
/node_modules(.*[/\\])+@react-navigation/,
|
||||
/node_modules(.*[/\\])+@react-native-community/,
|
||||
@@ -220,6 +221,7 @@ module.exports = (env) => {
|
||||
/node_modules(.*[/\\])+whatwg-url/,
|
||||
/node_modules(.*[/\\])+react-native-url-polyfill/,
|
||||
/node_modules(.*[/\\])+diffblazer/,
|
||||
/node_modules(.*[/\\])+react-freeze/,
|
||||
],
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
@@ -230,7 +232,7 @@ module.exports = (env) => {
|
||||
"node_modules/.webpack-cache"
|
||||
),
|
||||
babelrc: false,
|
||||
presets: ["module:metro-react-native-babel-preset"],
|
||||
presets: ["module:@react-native/babel-preset"],
|
||||
plugins: [
|
||||
"react-native-reanimated/plugin",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex",
|
||||
@@ -258,7 +260,7 @@ module.exports = (env) => {
|
||||
"node_modules/.webpack-cache"
|
||||
),
|
||||
babelrc: false,
|
||||
presets: [["module:metro-react-native-babel-preset"]],
|
||||
presets: [["module:@react-native/babel-preset"]],
|
||||
plugins:
|
||||
devServer && devServer.hmr
|
||||
? [
|
||||
|
||||
9633
apps/mobile/package-lock.json
generated
9633
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.12",
|
||||
"version": "3.0.17",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -25,10 +25,15 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"fonteditor-core": "^2.1.11",
|
||||
"listr": "^0.14.3",
|
||||
"otplib": "12.0.1",
|
||||
"patch-package": "7.0.0",
|
||||
"react-refresh": "0.14.0"
|
||||
},
|
||||
"overrides": {
|
||||
"react-native": "0.74.5",
|
||||
"react": "18.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
@@ -39,6 +44,8 @@
|
||||
"@notesnook/themes-server": "file:../../servers/themes",
|
||||
"diffblazer": "^1.0.1",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.72.0"
|
||||
"react-native": "0.74.5",
|
||||
"react-native-mmkv-storage": "^0.10.2",
|
||||
"react-native-actions-sheet": "^0.9.7"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/node_modules/@callstack/repack/android/build.gradle b/node_modules/@callstack/repack/android/build.gradle
|
||||
index e41f2f3..b04735e 100644
|
||||
--- a/node_modules/@callstack/repack/android/build.gradle
|
||||
+++ b/node_modules/@callstack/repack/android/build.gradle
|
||||
@@ -29,7 +29,7 @@ android {
|
||||
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
||||
buildToolsVersion getExtOrDefault('buildToolsVersion')
|
||||
defaultConfig {
|
||||
- minSdkVersion 16
|
||||
+ minSdkVersion 21
|
||||
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@@ -0,0 +1,11 @@
|
||||
diff --git a/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js b/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
|
||||
index 636c0d8..87f4ee6 100644
|
||||
--- a/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
|
||||
+++ b/node_modules/@react-native/community-cli-plugin/dist/utils/loadMetroConfig.js
|
||||
@@ -105,5 +105,6 @@ This warning will be removed in future (https://github.com/facebook/metro/issues
|
||||
...options,
|
||||
});
|
||||
const overrideConfig = getOverrideConfig(ctx, config);
|
||||
+ if (!overrideConfig.resolver.resolveRequest) delete overrideConfig.resolver.resolveRequest;
|
||||
return (0, _metroConfig.mergeConfig)(config, overrideConfig);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
diff --git a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
|
||||
index 6cbcc22..62d5422 100644
|
||||
--- a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
|
||||
+++ b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.d.ts
|
||||
@@ -12,6 +12,7 @@ export interface ConfigOptionsT {
|
||||
reporter?: any;
|
||||
config?: string;
|
||||
}
|
||||
+
|
||||
/**
|
||||
* Load Metro config.
|
||||
*
|
||||
diff --git a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
|
||||
index f26ef52..233a7c9 100644
|
||||
--- a/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
|
||||
+++ b/node_modules/@react-native-community/cli-plugin-metro/build/tools/loadMetroConfig.js
|
||||
@@ -82,6 +82,7 @@ async function loadMetroConfig(ctx, options = {}) {
|
||||
(0, _getDefaultMetroConfig.default)(ctx));
|
||||
return (0, _metroConfig().mergeConfig)(loadedConfig, overrideConfig);
|
||||
}
|
||||
+ if (!overrideConfig.resolver.resolveRequest) delete overrideConfig.resolver.resolveRequest;
|
||||
return (0, _metroConfig().mergeConfig)(await (0, _metroConfig().loadConfig)({
|
||||
cwd: ctx.root,
|
||||
...options
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/node_modules/jetifier/index.js b/node_modules/jetifier/index.js
|
||||
index ae3979c..ed609e9 100644
|
||||
--- a/node_modules/jetifier/index.js
|
||||
+++ b/node_modules/jetifier/index.js
|
||||
@@ -6,7 +6,7 @@ const cpus = require('os').cpus().length;
|
||||
|
||||
const arg = process.argv.slice(2)[0];
|
||||
const mode = arg && ((arg === 'reverse') || (arg === '-r')) ? 'reverse' : 'forward';
|
||||
-const SEARCH_DIR = 'node_modules';
|
||||
+const SEARCH_DIR = '../node_modules';
|
||||
|
||||
const classesMapping = getClassesMapping();
|
||||
const files = readDir(SEARCH_DIR);
|
||||
@@ -1,70 +0,0 @@
|
||||
diff --git a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
||||
index 7958519..25f58b1 100644
|
||||
--- a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
||||
+++ b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
||||
@@ -409,12 +409,12 @@ JSCRuntime::~JSCRuntime() {
|
||||
// has started.
|
||||
ctxInvalid_ = true;
|
||||
JSGlobalContextRelease(ctx_);
|
||||
-#ifndef NDEBUG
|
||||
- assert(
|
||||
- objectCounter_ == 0 && "JSCRuntime destroyed with a dangling API object");
|
||||
- assert(
|
||||
- stringCounter_ == 0 && "JSCRuntime destroyed with a dangling API string");
|
||||
-#endif
|
||||
+//#ifndef NDEBUG
|
||||
+// assert(
|
||||
+// objectCounter_ == 0 && "JSCRuntime destroyed with a dangling API object");
|
||||
+// assert(
|
||||
+// stringCounter_ == 0 && "JSCRuntime destroyed with a dangling API string");
|
||||
+//#endif
|
||||
}
|
||||
|
||||
std::shared_ptr<const jsi::PreparedJavaScript> JSCRuntime::prepareJavaScript(
|
||||
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env
|
||||
new file mode 100644
|
||||
index 0000000..361f5fb
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native/scripts/.packager.env
|
||||
@@ -0,0 +1 @@
|
||||
+export RCT_METRO_PORT=8081
|
||||
diff --git a/node_modules/react-native/scripts/launchPackager.command b/node_modules/react-native/scripts/launchPackager.command
|
||||
index efd1f2e..c2fbbb3 100755
|
||||
--- a/node_modules/react-native/scripts/launchPackager.command
|
||||
+++ b/node_modules/react-native/scripts/launchPackager.command
|
||||
@@ -10,7 +10,7 @@ clear
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
|
||||
-export PODS_ROOT="$THIS_DIR/../../../ios/Pods"
|
||||
+export PODS_ROOT="$THIS_DIR/../../../native/ios/Pods"
|
||||
WITH_ENVIRONMENT="$THIS_DIR/xcode/with-environment.sh"
|
||||
source $WITH_ENVIRONMENT
|
||||
|
||||
diff --git a/node_modules/react-native/scripts/packager.sh b/node_modules/react-native/scripts/packager.sh
|
||||
index cb8b101..519070a 100755
|
||||
--- a/node_modules/react-native/scripts/packager.sh
|
||||
+++ b/node_modules/react-native/scripts/packager.sh
|
||||
@@ -8,17 +8,16 @@
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
REACT_NATIVE_ROOT="$THIS_DIR/.."
|
||||
# Application root directory - General use case: react-native is a dependency
|
||||
-PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../.."}
|
||||
-
|
||||
+PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../../native"}
|
||||
# check and assign NODE_BINARY env
|
||||
# shellcheck disable=SC1090
|
||||
source "${THIS_DIR}/node-binary.sh"
|
||||
|
||||
# When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT
|
||||
-if [ ! -d "$THIS_DIR/../../../node_modules/react-native" ];
|
||||
-then
|
||||
- PROJECT_ROOT="$THIS_DIR/../../.."
|
||||
-fi
|
||||
+# if [ ! -d "$THIS_DIR/../../../node_modules/react-native" ];
|
||||
+# then
|
||||
+# PROJECT_ROOT="$THIS_DIR/../../.."
|
||||
+# fi
|
||||
# Start packager from PROJECT_ROOT
|
||||
cd "$PROJECT_ROOT" || exit
|
||||
"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start --custom-log-reporter-path "$THIS_DIR/packager-reporter.js" "$@"
|
||||
13
apps/mobile/patches/react-native+0.74.5.patch
Normal file
13
apps/mobile/patches/react-native+0.74.5.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/node_modules/react-native/scripts/packager.sh b/node_modules/react-native/scripts/packager.sh
|
||||
index 00d6ebc..6846832 100755
|
||||
--- a/node_modules/react-native/scripts/packager.sh
|
||||
+++ b/node_modules/react-native/scripts/packager.sh
|
||||
@@ -8,7 +8,7 @@
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
REACT_NATIVE_ROOT="$THIS_DIR/.."
|
||||
# Application root directory - General use case: react-native is a dependency
|
||||
-PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../.."}
|
||||
+PROJECT_ROOT=${PROJECT_ROOT:-"$THIS_DIR/../../../native"}
|
||||
|
||||
# check and assign NODE_BINARY env
|
||||
# shellcheck disable=SC1090
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,88 @@
|
||||
diff --git a/node_modules/react-native-quick-sqlite/.DS_Store b/node_modules/react-native-quick-sqlite/.DS_Store
|
||||
new file mode 100644
|
||||
index 0000000..02a6bbf
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/.DS_Store differ
|
||||
index 0000000..e69de29
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt
|
||||
new file mode 100644
|
||||
index 0000000..16ba95f
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/metadata_generation_command.txt
|
||||
@@ -0,0 +1,23 @@
|
||||
+ -H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android
|
||||
+-DCMAKE_SYSTEM_NAME=Android
|
||||
+-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
+-DCMAKE_SYSTEM_VERSION=21
|
||||
+-DANDROID_PLATFORM=android-21
|
||||
+-DANDROID_ABI=arm64-v8a
|
||||
+-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
|
||||
+-DANDROID_NDK=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620
|
||||
+-DCMAKE_ANDROID_NDK=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620
|
||||
+-DCMAKE_TOOLCHAIN_FILE=/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake
|
||||
+-DCMAKE_MAKE_PROGRAM=/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja
|
||||
+-DCMAKE_CXX_FLAGS=-O2 -fexceptions -frtti -std=c++1y -DONANDROID
|
||||
+-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a
|
||||
+-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a
|
||||
+-DCMAKE_BUILD_TYPE=Debug
|
||||
+-DCMAKE_FIND_ROOT_PATH=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a/prefab
|
||||
+-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a
|
||||
+-GNinja
|
||||
+-DANDROID_STL=c++_shared
|
||||
+-DSQLITE_FLAGS='-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC=0 -DHAVE_CIPHER_AES_256_CBC=0 -DHAVE_CIPHER_SQLCIPHER=0 -DHAVE_CIPHER_RC4=0 -DHAVE_CIPHER_CHACHA20=1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_USE_ALLOCA=1'
|
||||
+-DUSE_HERMES=true
|
||||
+ Build command args: []
|
||||
+ Version: 2
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json
|
||||
new file mode 100644
|
||||
index 0000000..1d61ce4
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/prefab_config.json
|
||||
@@ -0,0 +1,8 @@
|
||||
+{
|
||||
+ "enabled": true,
|
||||
+ "prefabPath": "/Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar",
|
||||
+ "packages": [
|
||||
+ "/Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab",
|
||||
+ "/Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab"
|
||||
+ ]
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt
|
||||
new file mode 100644
|
||||
index 0000000..a453b76
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/hash_key.txt
|
||||
@@ -0,0 +1,30 @@
|
||||
+# Values used to calculate the hash in this folder name.
|
||||
+# Should not depend on the absolute path of the project itself.
|
||||
+# - AGP: 8.2.1.
|
||||
+# - $NDK is the path to NDK 23.1.7779620.
|
||||
+# - $PROJECT is the path to the parent folder of the root Gradle build file.
|
||||
+# - $ABI is the ABI to be built with. The specific value doesn't contribute to the value of the hash.
|
||||
+# - $HASH is the hash value computed from this text.
|
||||
+# - $CMAKE is the path to CMake 3.22.1.
|
||||
+# - $NINJA is the path to Ninja.
|
||||
+-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android
|
||||
+-DCMAKE_SYSTEM_NAME=Android
|
||||
+-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
+-DCMAKE_SYSTEM_VERSION=21
|
||||
+-DANDROID_PLATFORM=android-21
|
||||
+-DANDROID_ABI=$ABI
|
||||
+-DCMAKE_ANDROID_ARCH_ABI=$ABI
|
||||
+-DANDROID_NDK=$NDK
|
||||
+-DCMAKE_ANDROID_NDK=$NDK
|
||||
+-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake
|
||||
+-DCMAKE_MAKE_PROGRAM=$NINJA
|
||||
+-DCMAKE_CXX_FLAGS=-O2 -fexceptions -frtti -std=c++1y -DONANDROID
|
||||
+-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI
|
||||
+-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI
|
||||
+-DCMAKE_BUILD_TYPE=Debug
|
||||
+-DCMAKE_FIND_ROOT_PATH=/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/prefab/$ABI/prefab
|
||||
+-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/$ABI
|
||||
+-GNinja
|
||||
+-DANDROID_STL=c++_shared
|
||||
+-DSQLITE_FLAGS='-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC=0 -DHAVE_CIPHER_AES_256_CBC=0 -DHAVE_CIPHER_SQLCIPHER=0 -DHAVE_CIPHER_RC4=0 -DHAVE_CIPHER_CHACHA20=1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_USE_ALLOCA=1'
|
||||
+-DUSE_HERMES=true
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/.settings/org.eclipse.buildship.core.prefs b/node_modules/react-native-quick-sqlite/android/.settings/org.eclipse.buildship.core.prefs
|
||||
deleted file mode 100644
|
||||
index 8c253d6..0000000
|
||||
@@ -21,12 +102,765 @@ index 8c253d6..0000000
|
||||
-override.workspace.settings=true
|
||||
-show.console.view=true
|
||||
-show.executions.view=true
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build.gradle b/node_modules/react-native-quick-sqlite/android/build.gradle
|
||||
index 96d2a74..c26e678 100644
|
||||
--- a/node_modules/react-native-quick-sqlite/android/build.gradle
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build.gradle
|
||||
@@ -63,7 +63,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
- minSdkVersion 21
|
||||
+ minSdkVersion safeExtGet("minSdkVersion", 23)
|
||||
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin
|
||||
new file mode 100644
|
||||
index 0000000..0d259dd
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/results.bin
|
||||
@@ -0,0 +1 @@
|
||||
+o/classes
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex
|
||||
new file mode 100644
|
||||
index 0000000..220a44f
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/.transforms/a5d230bd7410c4a394e68198eafb820e/transformed/classes/classes_dex/classes.dex differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java b/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java
|
||||
new file mode 100644
|
||||
index 0000000..bb02d55
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/generated/source/buildConfig/debug/com/reactnativequicksqlite/BuildConfig.java
|
||||
@@ -0,0 +1,10 @@
|
||||
+/**
|
||||
+ * Automatically generated file. DO NOT MODIFY
|
||||
+ */
|
||||
+package com.reactnativequicksqlite;
|
||||
+
|
||||
+public final class BuildConfig {
|
||||
+ public static final boolean DEBUG = Boolean.parseBoolean("true");
|
||||
+ public static final String LIBRARY_PACKAGE_NAME = "com.reactnativequicksqlite";
|
||||
+ public static final String BUILD_TYPE = "debug";
|
||||
+}
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml
|
||||
new file mode 100644
|
||||
index 0000000..65ada26
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml
|
||||
@@ -0,0 +1,7 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
+ package="com.reactnativequicksqlite" >
|
||||
+
|
||||
+ <uses-sdk android:minSdkVersion="21" />
|
||||
+
|
||||
+</manifest>
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json
|
||||
new file mode 100644
|
||||
index 0000000..c903659
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json
|
||||
@@ -0,0 +1,18 @@
|
||||
+{
|
||||
+ "version": 3,
|
||||
+ "artifactType": {
|
||||
+ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS",
|
||||
+ "kind": "Directory"
|
||||
+ },
|
||||
+ "applicationId": "com.reactnativequicksqlite",
|
||||
+ "variantName": "debug",
|
||||
+ "elements": [
|
||||
+ {
|
||||
+ "type": "SINGLE",
|
||||
+ "filters": [],
|
||||
+ "attributes": [],
|
||||
+ "outputFile": "AndroidManifest.xml"
|
||||
+ }
|
||||
+ ],
|
||||
+ "elementType": "File"
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties b/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties
|
||||
new file mode 100644
|
||||
index 0000000..1211b1e
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/aar_metadata/debug/aar-metadata.properties
|
||||
@@ -0,0 +1,6 @@
|
||||
+aarFormatVersion=1.0
|
||||
+aarMetadataVersion=1.0
|
||||
+minCompileSdk=1
|
||||
+minCompileSdkExtension=0
|
||||
+minAndroidGradlePluginVersion=1.0.0
|
||||
+coreLibraryDesugaringEnabled=false
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json
|
||||
new file mode 100644
|
||||
index 0000000..9e26dfe
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json
|
||||
@@ -0,0 +1 @@
|
||||
+{}
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar
|
||||
new file mode 100644
|
||||
index 0000000..d7046e6
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_library_classes_jar/debug/classes.jar differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar
|
||||
new file mode 100644
|
||||
index 0000000..1fff931
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_r_class_jar/debug/R.jar differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_symbol_list/debug/R.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/compile_symbol_list/debug/R.txt
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json
|
||||
new file mode 100644
|
||||
index 0000000..b6ba478
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/build_model.json
|
||||
@@ -0,0 +1,201 @@
|
||||
+{
|
||||
+ "info": {
|
||||
+ "name": "arm64-v8a",
|
||||
+ "bitness": 64,
|
||||
+ "isDefault": true,
|
||||
+ "isDeprecated": false,
|
||||
+ "architecture": "arm64",
|
||||
+ "triple": "aarch64-linux-android",
|
||||
+ "llvmTriple": "aarch64-none-linux-android"
|
||||
+ },
|
||||
+ "cxxBuildFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a",
|
||||
+ "soFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
|
||||
+ "soRepublishFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cmake/debug/obj/arm64-v8a",
|
||||
+ "abiPlatformVersion": 21,
|
||||
+ "cmake": {
|
||||
+ "effectiveConfiguration": {
|
||||
+ "inheritEnvironments": [],
|
||||
+ "variables": []
|
||||
+ }
|
||||
+ },
|
||||
+ "variant": {
|
||||
+ "buildSystemArgumentList": [
|
||||
+ "-DANDROID_STL\u003dc++_shared",
|
||||
+ "-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027",
|
||||
+ "-DUSE_HERMES\u003dtrue"
|
||||
+ ],
|
||||
+ "cFlagsList": [],
|
||||
+ "cppFlagsList": [
|
||||
+ "-O2",
|
||||
+ "-fexceptions",
|
||||
+ "-frtti",
|
||||
+ "-std\u003dc++1y",
|
||||
+ "-DONANDROID"
|
||||
+ ],
|
||||
+ "variantName": "debug",
|
||||
+ "isDebuggableEnabled": true,
|
||||
+ "validAbiList": [
|
||||
+ "armeabi-v7a",
|
||||
+ "arm64-v8a",
|
||||
+ "x86",
|
||||
+ "x86_64"
|
||||
+ ],
|
||||
+ "buildTargetSet": [],
|
||||
+ "implicitBuildTargetSet": [],
|
||||
+ "cmakeSettingsConfiguration": "android-gradle-plugin-predetermined-name",
|
||||
+ "module": {
|
||||
+ "cxxFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx",
|
||||
+ "intermediatesBaseFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates",
|
||||
+ "intermediatesFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx",
|
||||
+ "gradleModulePathName": ":react-native-quick-sqlite",
|
||||
+ "moduleRootFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android",
|
||||
+ "moduleBuildFile": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build.gradle",
|
||||
+ "makeFile": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "buildSystem": "CMAKE",
|
||||
+ "ndkFolder": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
|
||||
+ "ndkFolderBeforeSymLinking": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
|
||||
+ "ndkVersion": "23.1.7779620",
|
||||
+ "ndkSupportedAbiList": [
|
||||
+ "armeabi-v7a",
|
||||
+ "arm64-v8a",
|
||||
+ "x86",
|
||||
+ "x86_64"
|
||||
+ ],
|
||||
+ "ndkDefaultAbiList": [
|
||||
+ "armeabi-v7a",
|
||||
+ "arm64-v8a",
|
||||
+ "x86",
|
||||
+ "x86_64"
|
||||
+ ],
|
||||
+ "ndkDefaultStl": "LIBCXX_STATIC",
|
||||
+ "ndkMetaPlatforms": {
|
||||
+ "min": 16,
|
||||
+ "max": 31,
|
||||
+ "aliases": {
|
||||
+ "20": 19,
|
||||
+ "25": 24,
|
||||
+ "J": 16,
|
||||
+ "J-MR1": 17,
|
||||
+ "J-MR2": 18,
|
||||
+ "K": 19,
|
||||
+ "L": 21,
|
||||
+ "L-MR1": 22,
|
||||
+ "M": 23,
|
||||
+ "N": 24,
|
||||
+ "N-MR1": 24,
|
||||
+ "O": 26,
|
||||
+ "O-MR1": 27,
|
||||
+ "P": 28,
|
||||
+ "Q": 29,
|
||||
+ "R": 30,
|
||||
+ "S": 31
|
||||
+ }
|
||||
+ },
|
||||
+ "ndkMetaAbiList": [
|
||||
+ {
|
||||
+ "name": "armeabi-v7a",
|
||||
+ "bitness": 32,
|
||||
+ "isDefault": true,
|
||||
+ "isDeprecated": false,
|
||||
+ "architecture": "arm",
|
||||
+ "triple": "arm-linux-androideabi",
|
||||
+ "llvmTriple": "armv7-none-linux-androideabi"
|
||||
+ },
|
||||
+ {
|
||||
+ "name": "arm64-v8a",
|
||||
+ "bitness": 64,
|
||||
+ "isDefault": true,
|
||||
+ "isDeprecated": false,
|
||||
+ "architecture": "arm64",
|
||||
+ "triple": "aarch64-linux-android",
|
||||
+ "llvmTriple": "aarch64-none-linux-android"
|
||||
+ },
|
||||
+ {
|
||||
+ "name": "x86",
|
||||
+ "bitness": 32,
|
||||
+ "isDefault": true,
|
||||
+ "isDeprecated": false,
|
||||
+ "architecture": "x86",
|
||||
+ "triple": "i686-linux-android",
|
||||
+ "llvmTriple": "i686-none-linux-android"
|
||||
+ },
|
||||
+ {
|
||||
+ "name": "x86_64",
|
||||
+ "bitness": 64,
|
||||
+ "isDefault": true,
|
||||
+ "isDeprecated": false,
|
||||
+ "architecture": "x86_64",
|
||||
+ "triple": "x86_64-linux-android",
|
||||
+ "llvmTriple": "x86_64-none-linux-android"
|
||||
+ }
|
||||
+ ],
|
||||
+ "cmakeToolchainFile": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake",
|
||||
+ "cmake": {
|
||||
+ "cmakeExe": "/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/cmake"
|
||||
+ },
|
||||
+ "stlSharedObjectMap": {
|
||||
+ "LIBCXX_SHARED": {
|
||||
+ "armeabi-v7a": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so",
|
||||
+ "arm64-v8a": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so",
|
||||
+ "x86": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so",
|
||||
+ "x86_64": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so"
|
||||
+ },
|
||||
+ "LIBCXX_STATIC": {},
|
||||
+ "NONE": {},
|
||||
+ "SYSTEM": {}
|
||||
+ },
|
||||
+ "project": {
|
||||
+ "rootBuildGradleFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/native/android",
|
||||
+ "sdkFolder": "/Volumes/DataDrive/Android/sdk",
|
||||
+ "isBuildOnlyTargetAbiEnabled": true,
|
||||
+ "isCmakeBuildCohabitationEnabled": false,
|
||||
+ "isPrefabEnabled": true
|
||||
+ },
|
||||
+ "outputOptions": [],
|
||||
+ "ninjaExe": "/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja",
|
||||
+ "hasBuildTimeInformation": true
|
||||
+ },
|
||||
+ "prefabClassPaths": [
|
||||
+ "/Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar"
|
||||
+ ],
|
||||
+ "prefabPackages": [
|
||||
+ "/Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab",
|
||||
+ "/Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab"
|
||||
+ ],
|
||||
+ "prefabPackageConfigurations": [],
|
||||
+ "stlType": "c++_shared",
|
||||
+ "optimizationTag": "Debug"
|
||||
+ },
|
||||
+ "buildSettings": {
|
||||
+ "environmentVariables": []
|
||||
+ },
|
||||
+ "prefabFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a",
|
||||
+ "isActiveAbi": true,
|
||||
+ "fullConfigurationHash": "3u4yy1v4n5m1m3r6x453b2w4u42s4h63w1d2iu6l6v2q6n2d4154135b3h34",
|
||||
+ "fullConfigurationHashKey": "# Values used to calculate the hash in this folder name.\n# Should not depend on the absolute path of the project itself.\n# - AGP: 8.2.1.\n# - $NDK is the path to NDK 23.1.7779620.\n# - $PROJECT is the path to the parent folder of the root Gradle build file.\n# - $ABI is the ABI to be built with. The specific value doesn\u0027t contribute to the value of the hash.\n# - $HASH is the hash value computed from this text.\n# - $CMAKE is the path to CMake 3.22.1.\n# - $NINJA is the path to Ninja.\n-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android\n-DCMAKE_SYSTEM_NAME\u003dAndroid\n-DCMAKE_EXPORT_COMPILE_COMMANDS\u003dON\n-DCMAKE_SYSTEM_VERSION\u003d21\n-DANDROID_PLATFORM\u003dandroid-21\n-DANDROID_ABI\u003d$ABI\n-DCMAKE_ANDROID_ARCH_ABI\u003d$ABI\n-DANDROID_NDK\u003d$NDK\n-DCMAKE_ANDROID_NDK\u003d$NDK\n-DCMAKE_TOOLCHAIN_FILE\u003d$NDK/build/cmake/android.toolchain.cmake\n-DCMAKE_MAKE_PROGRAM\u003d$NINJA\n-DCMAKE_CXX_FLAGS\u003d-O2 -fexceptions -frtti -std\u003dc++1y -DONANDROID\n-DCMAKE_LIBRARY_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI\n-DCMAKE_RUNTIME_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/$HASH/obj/$ABI\n-DCMAKE_BUILD_TYPE\u003dDebug\n-DCMAKE_FIND_ROOT_PATH\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/prefab/$ABI/prefab\n-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/$HASH/$ABI\n-GNinja\n-DANDROID_STL\u003dc++_shared\n-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027\n-DUSE_HERMES\u003dtrue",
|
||||
+ "configurationArguments": [
|
||||
+ "-H/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android",
|
||||
+ "-DCMAKE_SYSTEM_NAME\u003dAndroid",
|
||||
+ "-DCMAKE_EXPORT_COMPILE_COMMANDS\u003dON",
|
||||
+ "-DCMAKE_SYSTEM_VERSION\u003d21",
|
||||
+ "-DANDROID_PLATFORM\u003dandroid-21",
|
||||
+ "-DANDROID_ABI\u003darm64-v8a",
|
||||
+ "-DCMAKE_ANDROID_ARCH_ABI\u003darm64-v8a",
|
||||
+ "-DANDROID_NDK\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
|
||||
+ "-DCMAKE_ANDROID_NDK\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620",
|
||||
+ "-DCMAKE_TOOLCHAIN_FILE\u003d/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake",
|
||||
+ "-DCMAKE_MAKE_PROGRAM\u003d/Volumes/DataDrive/Android/sdk/cmake/3.22.1/bin/ninja",
|
||||
+ "-DCMAKE_CXX_FLAGS\u003d-O2 -fexceptions -frtti -std\u003dc++1y -DONANDROID",
|
||||
+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
|
||||
+ "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/obj/arm64-v8a",
|
||||
+ "-DCMAKE_BUILD_TYPE\u003dDebug",
|
||||
+ "-DCMAKE_FIND_ROOT_PATH\u003d/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/prefab/arm64-v8a/prefab",
|
||||
+ "-B/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a",
|
||||
+ "-GNinja",
|
||||
+ "-DANDROID_STL\u003dc++_shared",
|
||||
+ "-DSQLITE_FLAGS\u003d\u0027-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC\u003d0 -DHAVE_CIPHER_AES_256_CBC\u003d0 -DHAVE_CIPHER_SQLCIPHER\u003d0 -DHAVE_CIPHER_RC4\u003d0 -DHAVE_CIPHER_CHACHA20\u003d1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK\u003d1 -DSQLITE_MAX_EXPR_DEPTH\u003d0 -DSQLITE_OMIT_DEPRECATED\u003d1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS\u003d1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS\u003d1 -DSQLITE_DQS\u003d0 -DSQLITE_DEFAULT_MEMSTATUS\u003d0 -DSQLITE_USE_ALLOCA\u003d1\u0027",
|
||||
+ "-DUSE_HERMES\u003dtrue"
|
||||
+ ],
|
||||
+ "stlLibraryFile": "/Volumes/DataDrive/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so",
|
||||
+ "intermediatesParentFolder": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4"
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt
|
||||
new file mode 100644
|
||||
index 0000000..34dc50a
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/generate_cxx_metadata_696_timing.txt
|
||||
@@ -0,0 +1,7 @@
|
||||
+# C/C++ build system timings
|
||||
+generate_cxx_metadata
|
||||
+ generate-prefab-packages
|
||||
+ exec-prefab 363ms
|
||||
+ generate-prefab-packages completed in 367ms
|
||||
+generate_cxx_metadata completed in 372ms
|
||||
+
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json
|
||||
new file mode 100644
|
||||
index 0000000..2030622
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/metadata_generation_record.json
|
||||
@@ -0,0 +1,80 @@
|
||||
+[
|
||||
+ {
|
||||
+ "level_": 0,
|
||||
+ "message_": "Start JSON generation. Platform version: 21 min SDK version: arm64-v8a",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ },
|
||||
+ {
|
||||
+ "level_": 0,
|
||||
+ "message_": "rebuilding JSON /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/.cxx/Debug/3u4yy1v4/arm64-v8a/android_gradle_build.json due to:",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ },
|
||||
+ {
|
||||
+ "level_": 0,
|
||||
+ "message_": "- no fingerprint file, will remove stale configuration folder",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ },
|
||||
+ {
|
||||
+ "level_": 0,
|
||||
+ "message_": "/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java \\\n --class-path \\\n /Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar \\\n com.google.prefab.cli.AppKt \\\n --build-system \\\n cmake \\\n --platform \\\n android \\\n --abi \\\n arm64-v8a \\\n --os-version \\\n 21 \\\n --stl \\\n c++_shared \\\n --ndk-version \\\n 23 \\\n --output \\\n /var/folders/8n/7d231mbx74v_dqslxq126wm40000gn/T/agp-prefab-staging14064479766908916482/staged-cli-output \\\n /Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab \\\n /Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab\n",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ },
|
||||
+ {
|
||||
+ "level_": 0,
|
||||
+ "message_": "Received process result: 0",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ },
|
||||
+ {
|
||||
+ "level_": 1,
|
||||
+ "message_": "com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/fabricjni. Rejected the following libraries:",
|
||||
+ "file_": "/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/CMakeLists.txt",
|
||||
+ "tag_": "debug|arm64-v8a",
|
||||
+ "diagnosticCode_": 0,
|
||||
+ "memoizedIsInitialized": 1,
|
||||
+ "unknownFields": {
|
||||
+ "fields": {}
|
||||
+ },
|
||||
+ "memoizedSize": -1,
|
||||
+ "memoizedHashCode": 0
|
||||
+ }
|
||||
+]
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command
|
||||
new file mode 100755
|
||||
index 0000000..76cf03e
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_command
|
||||
@@ -0,0 +1,20 @@
|
||||
+/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/java \
|
||||
+ --class-path \
|
||||
+ /Users/ammarahmed/.gradle/caches/modules-2/files-2.1/com.google.prefab/cli/2.0.0/f2702b5ca13df54e3ca92f29d6b403fb6285d8df/cli-2.0.0-all.jar \
|
||||
+ com.google.prefab.cli.AppKt \
|
||||
+ --build-system \
|
||||
+ cmake \
|
||||
+ --platform \
|
||||
+ android \
|
||||
+ --abi \
|
||||
+ arm64-v8a \
|
||||
+ --os-version \
|
||||
+ 21 \
|
||||
+ --stl \
|
||||
+ c++_shared \
|
||||
+ --ndk-version \
|
||||
+ 23 \
|
||||
+ --output \
|
||||
+ /var/folders/8n/7d231mbx74v_dqslxq126wm40000gn/T/agp-prefab-staging14064479766908916482/staged-cli-output \
|
||||
+ /Users/ammarahmed/.gradle/caches/transforms-4/af547bd0d6b859d6b490959996fda082/transformed/jetified-react-android-0.74.4-debug/prefab \
|
||||
+ /Users/ammarahmed/.gradle/caches/transforms-4/c7e26f7d3c2fc1a6636ff1467fc77795/transformed/jetified-fbjni-0.6.0/prefab
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt
|
||||
new file mode 100644
|
||||
index 0000000..f0ba97d
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stderr.txt
|
||||
@@ -0,0 +1,170 @@
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/fabricjni. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/folly_runtime. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/glog. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/hermes_executor. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jscexecutor. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jsi. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/jsinspector. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_codegen_rncore. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_cxxreactpackage. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_debug. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_nativemodule_core. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_newarchdefaults. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_animations. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_componentregistry. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_core. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_debug. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_graphics. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_imagemanager. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_mapbuffer. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_mounting. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_scheduler. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_textlayoutmanager. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_render_uimanager. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/react_utils. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/reactnativejni. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_image. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_legacyviewmanagerinterop. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_root. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_text. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_textinput. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/rrc_view. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/runtimeexecutor. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/turbomodulejsijni. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
+com.google.prefab.api.NoMatchingLibraryException: No compatible library found for //ReactAndroid/yoga. Rejected the following libraries:
|
||||
+android.arm64-v8a: User has minSdkVersion 21 but library was built for 23
|
||||
+android.armeabi-v7a: User is targeting arm64-v8a but library is for armeabi-v7a
|
||||
+android.x86: User is targeting arm64-v8a but library is for x86
|
||||
+android.x86_64: User is targeting arm64-v8a but library is for x86_64
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stdout.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/cxx/Debug/3u4yy1v4/logs/arm64-v8a/prefab_stdout.txt
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
|
||||
new file mode 100644
|
||||
index 0000000..dbce266
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
|
||||
@@ -0,0 +1 @@
|
||||
+#Thu Aug 01 12:36:04 PKT 2024
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
|
||||
new file mode 100644
|
||||
index 0000000..af54be8
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/generated/res/resValues/debug"/></dataSet><mergedItems/></merger>
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
|
||||
new file mode 100644
|
||||
index 0000000..a8ab2fe
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/shaders"/></dataSet></merger>
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml
|
||||
new file mode 100644
|
||||
index 0000000..e9d427d
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/incremental/packageDebugAssets/merger.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/assets"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/debug/assets"/></dataSet><dataSet config="generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/build/intermediates/shader_assets/debug/out"/></dataSet></merger>
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class
|
||||
new file mode 100644
|
||||
index 0000000..0e69a3b
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/BuildConfig.class differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class
|
||||
new file mode 100644
|
||||
index 0000000..08396d0
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/QuickSQLiteBridge.class differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class
|
||||
new file mode 100644
|
||||
index 0000000..2c123a9
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelModule.class differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class
|
||||
new file mode 100644
|
||||
index 0000000..d78a2bf
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/javac/debug/classes/com/reactnativequicksqlite/SequelPackage.class differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt
|
||||
new file mode 100644
|
||||
index 0000000..78ac5b8
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/local_only_symbol_list/debug/R-def.txt
|
||||
@@ -0,0 +1,2 @@
|
||||
+R_DEF: Internal format may change without notice
|
||||
+local
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
|
||||
new file mode 100644
|
||||
index 0000000..a67baa4
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
|
||||
@@ -0,0 +1,7 @@
|
||||
+1<?xml version="1.0" encoding="utf-8"?>
|
||||
+2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
+3 package="com.reactnativequicksqlite" >
|
||||
+4
|
||||
+5 <uses-sdk android:minSdkVersion="21" />
|
||||
+6
|
||||
+7</manifest>
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml b/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml
|
||||
new file mode 100644
|
||||
index 0000000..65ada26
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml
|
||||
@@ -0,0 +1,7 @@
|
||||
+<?xml version="1.0" encoding="utf-8"?>
|
||||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
+ package="com.reactnativequicksqlite" >
|
||||
+
|
||||
+ <uses-sdk android:minSdkVersion="21" />
|
||||
+
|
||||
+</manifest>
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json b/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json
|
||||
new file mode 100644
|
||||
index 0000000..0637a08
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/navigation_json/debug/navigation.json
|
||||
@@ -0,0 +1 @@
|
||||
+[]
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar b/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar
|
||||
new file mode 100644
|
||||
index 0000000..9fb3961
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt b/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt
|
||||
new file mode 100644
|
||||
index 0000000..1ab64fc
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt
|
||||
@@ -0,0 +1 @@
|
||||
+com.reactnativequicksqlite
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt b/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt
|
||||
new file mode 100644
|
||||
index 0000000..50600fe
|
||||
--- /dev/null
|
||||
+++ b/node_modules/react-native-quick-sqlite/android/build/outputs/logs/manifest-merger-debug-report.txt
|
||||
@@ -0,0 +1,17 @@
|
||||
+-- Merging decision tree log ---
|
||||
+manifest
|
||||
+ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:1-4:12
|
||||
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:1-4:12
|
||||
+ package
|
||||
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:2:11-47
|
||||
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
|
||||
+ xmlns:android
|
||||
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml:1:11-69
|
||||
+uses-sdk
|
||||
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
|
||||
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
|
||||
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
|
||||
+ android:targetSdkVersion
|
||||
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
|
||||
+ android:minSdkVersion
|
||||
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-quick-sqlite/android/src/main/AndroidManifest.xml
|
||||
diff --git a/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin b/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin
|
||||
new file mode 100644
|
||||
index 0000000..ef93f2f
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin differ
|
||||
diff --git a/node_modules/react-native-quick-sqlite/cpp/.DS_Store b/node_modules/react-native-quick-sqlite/cpp/.DS_Store
|
||||
new file mode 100644
|
||||
index 0000000..5008ddf
|
||||
Binary files /dev/null and b/node_modules/react-native-quick-sqlite/cpp/.DS_Store differ
|
||||
index 0000000..e69de29
|
||||
diff --git a/node_modules/react-native-quick-sqlite/cpp/sqlite3.c b/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
|
||||
index 51d5dbd..895536b 100644
|
||||
index 51d5dbd..f1295eb 100644
|
||||
--- a/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
|
||||
+++ b/node_modules/react-native-quick-sqlite/cpp/sqlite3.c
|
||||
@@ -1,6 +1,139 @@
|
||||
@@ -1681,7 +2515,7 @@ index 51d5dbd..895536b 100644
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif /* SQLITE3_H */
|
||||
|
||||
|
||||
+/* Function prototypes of SQLite3 Multiple Ciphers */
|
||||
+SQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);
|
||||
+SQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);
|
||||
@@ -104785,7 +105619,7 @@ index 51d5dbd..895536b 100644
|
||||
+
|
||||
+#endif
|
||||
diff --git a/node_modules/react-native-quick-sqlite/cpp/sqlite3.h b/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
|
||||
index 9b284d2..a12c6ab 100644
|
||||
index 9b284d2..bda794a 100644
|
||||
--- a/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
|
||||
+++ b/node_modules/react-native-quick-sqlite/cpp/sqlite3.h
|
||||
@@ -1,4 +1,50 @@
|
||||
|
||||
@@ -45,6 +45,7 @@ const EXTRA_ICON_NAMES = [
|
||||
"view-list-outline",
|
||||
"view-list",
|
||||
"tab-plus",
|
||||
"server",
|
||||
"play",
|
||||
"pause",
|
||||
"notebook-outline",
|
||||
|
||||
1
apps/theme-builder/package-lock.json
generated
1
apps/theme-builder/package-lock.json
generated
@@ -990,6 +990,7 @@
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@emotion/react": "11.11.1",
|
||||
"@hazae41/foras": "^2.1.4",
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook-importer/core": "^2.0.0",
|
||||
|
||||
@@ -258,7 +258,7 @@ export class NoteContextMenuModel extends BaseProperties {
|
||||
|
||||
const zip = await downloadAndReadFile(
|
||||
this.noteLocator.page(),
|
||||
this.menu.getItem(format),
|
||||
() => this.menu.getItem(format).click(),
|
||||
null
|
||||
);
|
||||
|
||||
|
||||
@@ -113,16 +113,17 @@ export class SettingsViewModel {
|
||||
const item = await this.navigation.findItem("Backup & export");
|
||||
await item?.click();
|
||||
|
||||
const backupData = this.page
|
||||
.locator(getTestId("setting-create-backup"))
|
||||
.locator("button");
|
||||
|
||||
if (password) {
|
||||
await backupData.click();
|
||||
await fillPasswordDialog(this.page, password);
|
||||
}
|
||||
|
||||
return await downloadAndReadFile(this.page, backupData, "utf-8");
|
||||
return await downloadAndReadFile(
|
||||
this.page,
|
||||
async () => {
|
||||
const backupData = this.page
|
||||
.locator(getTestId("setting-create-backup"))
|
||||
.locator("select");
|
||||
await backupData.selectOption({ value: "partial", label: "Backup" });
|
||||
if (password) await fillPasswordDialog(this.page, password);
|
||||
},
|
||||
"utf-8"
|
||||
);
|
||||
}
|
||||
|
||||
async restoreData(filename: string, password?: string) {
|
||||
|
||||
@@ -103,12 +103,12 @@ async function editNote(page: Page, note: Partial<Note>, noDelay = false) {
|
||||
|
||||
async function downloadAndReadFile(
|
||||
page: Page,
|
||||
action: Locator,
|
||||
action: () => Promise<void>,
|
||||
encoding: BufferEncoding | null | undefined = "utf-8"
|
||||
) {
|
||||
const [download] = await Promise.all([
|
||||
page.waitForEvent("download"),
|
||||
await action.click()
|
||||
action()
|
||||
]);
|
||||
|
||||
const dir = fs.mkdtempSync(join(tmpdir(), "nntests_"));
|
||||
|
||||
10205
apps/web/package-lock.json
generated
10205
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.0.13",
|
||||
"version": "3.0.17",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
@@ -15,9 +15,10 @@
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@emotion/react": "11.11.1",
|
||||
"@hazae41/foras": "^2.1.4",
|
||||
"@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",
|
||||
@@ -56,7 +57,6 @@
|
||||
"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",
|
||||
|
||||
@@ -22,11 +22,16 @@ import { useStore } from "./stores/app-store";
|
||||
import { useStore as useUserStore } from "./stores/user-store";
|
||||
import { useEditorStore } from "./stores/editor-store";
|
||||
import { useStore as useAnnouncementStore } from "./stores/announcement-store";
|
||||
import { resetNotices, scheduleBackups } from "./common/notices";
|
||||
import { useStore as useSettingStore } from "./stores/setting-store";
|
||||
import {
|
||||
resetNotices,
|
||||
scheduleBackups,
|
||||
scheduleFullBackups
|
||||
} from "./common/notices";
|
||||
import { introduceFeatures, showUpgradeReminderDialogs } from "./common";
|
||||
import { AppEventManager, AppEvents } from "./common/app-events";
|
||||
import { db } from "./common/db";
|
||||
import { EV, EVENTS } from "@notesnook/core/dist/common";
|
||||
import { CHECK_IDS, EV, EVENTS } from "@notesnook/core/dist/common";
|
||||
import { registerKeyMap } from "./common/key-map";
|
||||
import { isUserPremium } from "./hooks/use-is-user-premium";
|
||||
import { updateStatus, removeStatus, getStatus } from "./hooks/use-status";
|
||||
@@ -40,6 +45,7 @@ import { desktop } from "./common/desktop-bridge";
|
||||
import { BuyDialog } from "./dialogs/buy-dialog";
|
||||
import { FeatureDialog } from "./dialogs/feature-dialog";
|
||||
import { AnnouncementDialog } from "./dialogs/announcement-dialog";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
type AppEffectsProps = {
|
||||
setShow: (show: boolean) => void;
|
||||
@@ -64,11 +70,27 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
|
||||
if (isUserPremium()) {
|
||||
return { type, result: true };
|
||||
} else {
|
||||
showToast(
|
||||
"error",
|
||||
"Please upgrade your account to Pro to use this feature.",
|
||||
[{ text: "Upgrade now", onClick: () => BuyDialog.show({}) }]
|
||||
);
|
||||
let sentence = "Please upgrade your account to Pro ";
|
||||
switch (type) {
|
||||
case CHECK_IDS.noteColor:
|
||||
sentence += "to add colors.";
|
||||
break;
|
||||
case CHECK_IDS.noteTag:
|
||||
sentence += "to add more tags.";
|
||||
break;
|
||||
case CHECK_IDS.notebookAdd:
|
||||
sentence += "to add more notebooks.";
|
||||
break;
|
||||
case CHECK_IDS.vaultAdd:
|
||||
sentence += "to use the notes vault.";
|
||||
break;
|
||||
default:
|
||||
sentence += "to use this feature.";
|
||||
break;
|
||||
}
|
||||
showToast("error", sentence, [
|
||||
{ text: "Upgrade now", onClick: () => BuyDialog.show({}) }
|
||||
]);
|
||||
return { type, result: false };
|
||||
}
|
||||
}
|
||||
@@ -90,6 +112,10 @@ export default function AppEffects({ setShow }: AppEffectsProps) {
|
||||
if (onboardingKey) await OnboardingDialog.show({ type: onboardingKey });
|
||||
await FeatureDialog.show({ featureName: "highlights" });
|
||||
await scheduleBackups();
|
||||
await scheduleFullBackups();
|
||||
if (useSettingStore.getState().isFullOfflineMode)
|
||||
// NOTE: we deliberately don't await here because we don't want to pause execution.
|
||||
db.attachments.cacheAttachments().catch(logger.error);
|
||||
})();
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -125,7 +125,9 @@ function DesktopAppContents({ show, setShow }: DesktopAppContentsProps) {
|
||||
const middlePane = useRef<ImperativePanelHandle>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setIsNarrow(isTablet);
|
||||
const size = navPane.current?.getSize();
|
||||
// Toggle `isNarrow` to true if panel size isn't set to narrow by user
|
||||
setIsNarrow((size && size <= 5) || isTablet);
|
||||
}, [isTablet]);
|
||||
|
||||
// useEffect(() => {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user