mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-29 10:09:26 +02:00
Compare commits
206 Commits
mobile-ref
...
3.3.7-andr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbc74ec359 | ||
|
|
0dfc1dfa52 | ||
|
|
b9c14ef9aa | ||
|
|
3fec2b397f | ||
|
|
ec841caef7 | ||
|
|
c163fc3be4 | ||
|
|
1e04315596 | ||
|
|
9aef28b03d | ||
|
|
88628c650f | ||
|
|
9523fd52d8 | ||
|
|
8cc6df92f4 | ||
|
|
042656856a | ||
|
|
5921c61e98 | ||
|
|
c5cd214d97 | ||
|
|
b30c35e59d | ||
|
|
ce4fa13758 | ||
|
|
1f47df0f45 | ||
|
|
91109278b6 | ||
|
|
78e4672871 | ||
|
|
dbecd6a466 | ||
|
|
e690973107 | ||
|
|
17b14e0ac6 | ||
|
|
0f8da747f9 | ||
|
|
df7d91e4f3 | ||
|
|
7eefecd961 | ||
|
|
2ec764d862 | ||
|
|
5a9b9da47e | ||
|
|
c5a82bd779 | ||
|
|
9c2a807025 | ||
|
|
4fa1ea4380 | ||
|
|
351d412fdf | ||
|
|
38600bf2a5 | ||
|
|
4720456d63 | ||
|
|
5a2221c5d3 | ||
|
|
91ef98df4f | ||
|
|
68b921887b | ||
|
|
dea91c48a2 | ||
|
|
f2e91d4a5c | ||
|
|
47be00355d | ||
|
|
05c4051cc9 | ||
|
|
71fe6bbebc | ||
|
|
74ed529f16 | ||
|
|
24a6d8c3f9 | ||
|
|
14c1567c07 | ||
|
|
fb778f56ed | ||
|
|
1eb0ef0cbe | ||
|
|
a81c8d0064 | ||
|
|
36099c6b4d | ||
|
|
8f7a15e692 | ||
|
|
de4a660eb2 | ||
|
|
c53fab603f | ||
|
|
a3e11b62e0 | ||
|
|
5d1775151d | ||
|
|
a0f5880e2c | ||
|
|
3dc7e70890 | ||
|
|
2fa1fc8662 | ||
|
|
879a65a41c | ||
|
|
d5b68bf0da | ||
|
|
fd460d3e90 | ||
|
|
a74bd4972c | ||
|
|
0ed8839ea9 | ||
|
|
d7b0f2684a | ||
|
|
b5be9b3abf | ||
|
|
911105c409 | ||
|
|
200c842671 | ||
|
|
5e5930e9e8 | ||
|
|
fd64c1cf2d | ||
|
|
48e2916874 | ||
|
|
a4b0e5bfef | ||
|
|
0b56121a26 | ||
|
|
f3f61d0e19 | ||
|
|
faaf1eeadf | ||
|
|
4fbaecc24e | ||
|
|
4fb056095c | ||
|
|
2d6142381b | ||
|
|
d97d14e830 | ||
|
|
f2f3f7e393 | ||
|
|
50176d2b3a | ||
|
|
ece7b29005 | ||
|
|
8cd8e93487 | ||
|
|
8900a6b080 | ||
|
|
19d90fa221 | ||
|
|
2e5ff859eb | ||
|
|
06747575ee | ||
|
|
98bb8ca186 | ||
|
|
d5f68602b6 | ||
|
|
312999aa5b | ||
|
|
607a4d26f4 | ||
|
|
a88b6615e4 | ||
|
|
f900098201 | ||
|
|
d51aaa8eb1 | ||
|
|
e9a48ae028 | ||
|
|
90a0f619ec | ||
|
|
ed3662a636 | ||
|
|
26eda3b105 | ||
|
|
8f43882e29 | ||
|
|
e239597eb1 | ||
|
|
bf1ef07d3a | ||
|
|
7d2e1dab4c | ||
|
|
80392d394a | ||
|
|
9ffa4d38c3 | ||
|
|
efec2dc898 | ||
|
|
5bd032e480 | ||
|
|
c1bd4cfb01 | ||
|
|
0b943d8ecd | ||
|
|
75e22a591e | ||
|
|
66498e12ce | ||
|
|
d5fefd2f10 | ||
|
|
e2556d3228 | ||
|
|
2eb38d236e | ||
|
|
d9c57162f1 | ||
|
|
9f8f0e8413 | ||
|
|
ea52893be1 | ||
|
|
eef63d2028 | ||
|
|
14e0112e17 | ||
|
|
8ec9034fb2 | ||
|
|
dc5973d75d | ||
|
|
12126b2f9f | ||
|
|
9fa256be0e | ||
|
|
c103328098 | ||
|
|
ea2022bbe4 | ||
|
|
d7ced57319 | ||
|
|
2cc200dc2b | ||
|
|
baa74d0353 | ||
|
|
72b906da14 | ||
|
|
6db8c2fac2 | ||
|
|
09d5c0a65e | ||
|
|
0b6b6a02cc | ||
|
|
f49c673e8e | ||
|
|
64a8e9a075 | ||
|
|
e998b07ca5 | ||
|
|
c189279030 | ||
|
|
12ddd6f958 | ||
|
|
da06afda8a | ||
|
|
bf808b7a2e | ||
|
|
13476a3f50 | ||
|
|
cfdf77a7b5 | ||
|
|
070c90362a | ||
|
|
c8d9858a0c | ||
|
|
2685f60409 | ||
|
|
8d3bb5185c | ||
|
|
1f748a4026 | ||
|
|
b27f064ad4 | ||
|
|
27f781cc63 | ||
|
|
1427958eca | ||
|
|
436e09c255 | ||
|
|
cc9b2dd5b0 | ||
|
|
0ba25419f3 | ||
|
|
9238de4cb4 | ||
|
|
2d5fe1058c | ||
|
|
b01d1fc87e | ||
|
|
9f4c0a4c9a | ||
|
|
9eebda86c2 | ||
|
|
d43e856fea | ||
|
|
7af1596038 | ||
|
|
652f6eab0b | ||
|
|
fdaddfdb92 | ||
|
|
9a1adf2065 | ||
|
|
f10b258f58 | ||
|
|
7f558cbd41 | ||
|
|
641eb28ce7 | ||
|
|
2c59a5f6f9 | ||
|
|
712f02e61e | ||
|
|
e5ad405a23 | ||
|
|
cd1b78d8df | ||
|
|
3b1ca46945 | ||
|
|
96c1636f88 | ||
|
|
a10f949856 | ||
|
|
9ff4757ed6 | ||
|
|
17c1e77f54 | ||
|
|
187a2a7262 | ||
|
|
4621230549 | ||
|
|
d7cb3317a2 | ||
|
|
6d81f26864 | ||
|
|
5219814b5a | ||
|
|
bef9fd0fd0 | ||
|
|
2341293d92 | ||
|
|
215387f8a9 | ||
|
|
534b8c5ad0 | ||
|
|
b7b2ead9eb | ||
|
|
b3e34d68e1 | ||
|
|
39079612aa | ||
|
|
be1af3111f | ||
|
|
8dcff49797 | ||
|
|
687fb4e105 | ||
|
|
25ae780ad8 | ||
|
|
b695367e6c | ||
|
|
bb274a84fe | ||
|
|
364dccbf7a | ||
|
|
105fb0fc69 | ||
|
|
89c408981c | ||
|
|
110534edec | ||
|
|
00e2190b2d | ||
|
|
e5c3fc667e | ||
|
|
f76e0b7931 | ||
|
|
0457e4417f | ||
|
|
dae8b5c542 | ||
|
|
60107dd77f | ||
|
|
4f3e19aaa2 | ||
|
|
8c621f9f47 | ||
|
|
74544efd62 | ||
|
|
c30ccbb68d | ||
|
|
12e3335d52 | ||
|
|
f29439539d | ||
|
|
13c9fdba52 | ||
|
|
95f52fba51 |
@@ -7,7 +7,7 @@ runs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
node-version: 22.x
|
||||
cache: "npm"
|
||||
cache-dependency-path: |
|
||||
package-lock.json
|
||||
|
||||
5
.github/workflows/android.e2e.yml
vendored
5
.github/workflows/android.e2e.yml
vendored
@@ -47,6 +47,11 @@ jobs:
|
||||
- name: Install Detox CLI
|
||||
run: npm install detox-cli --global
|
||||
|
||||
- name: Check for typescript errors
|
||||
run: |
|
||||
cd apps/mobile
|
||||
npx tsc --noEmit
|
||||
|
||||
- name: Detox build
|
||||
run: |
|
||||
yarn build:android
|
||||
|
||||
@@ -73,6 +73,12 @@ jobs:
|
||||
- name: CCache Stats Before Build
|
||||
run: ccache -sv
|
||||
|
||||
- name: Check for typescript errors
|
||||
run: |
|
||||
npm run tx mobile:build
|
||||
cd apps/mobile
|
||||
npx tsc --noEmit
|
||||
|
||||
- name: Build unsigned app bundle
|
||||
run: yarn release:android:bundle
|
||||
|
||||
|
||||
6
.github/workflows/android.publish.yml
vendored
6
.github/workflows/android.publish.yml
vendored
@@ -73,6 +73,12 @@ jobs:
|
||||
- name: CCache Stats Before Build
|
||||
run: ccache -sv
|
||||
|
||||
- name: Check for typescript errors
|
||||
run: |
|
||||
npm run tx mobile:build
|
||||
cd apps/mobile
|
||||
npx tsc --noEmit
|
||||
|
||||
- name: Build unsigned app bundle
|
||||
run: yarn release:android:bundle
|
||||
|
||||
|
||||
3
.github/workflows/core.tests.yml
vendored
3
.github/workflows/core.tests.yml
vendored
@@ -52,7 +52,6 @@ jobs:
|
||||
echo "USER_PASSWORD=${{ secrets.USER_PASSWORD }}" >> $GITHUB_ENV
|
||||
echo "USER_TOTP_SECRET=${{ secrets.USER_TOTP_SECRET }}" >> $GITHUB_ENV
|
||||
echo "USER_HASHED_PASSWORD=${{ secrets.USER_HASHED_PASSWORD }}" >> $GITHUB_ENV
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Run all @notesnook/core tests
|
||||
run: npx nx test:e2e @notesnook/core
|
||||
run: npm run tx @notesnook/core:test:e2e
|
||||
|
||||
22
.github/workflows/desktop.publish.yml
vendored
22
.github/workflows/desktop.publish.yml
vendored
@@ -65,17 +65,13 @@ jobs:
|
||||
npm i --cpu x64 sqlite-better-trigram
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate desktop build (stable)
|
||||
if: ${{ inputs.release-track == 'stable' }}
|
||||
run: npx nx build:desktop @notesnook/web
|
||||
run: npm run tx @notesnook/web:build:desktop
|
||||
|
||||
- name: Generate desktop build (beta)
|
||||
if: ${{ inputs.release-track == 'beta' }}
|
||||
run: BETA=true npx nx build:desktop @notesnook/web
|
||||
run: BETA=true npm run tx @notesnook/web:build:desktop
|
||||
|
||||
- name: Build desktop bundle
|
||||
working-directory: ./apps/desktop
|
||||
@@ -199,9 +195,9 @@ jobs:
|
||||
CSC_LINK: ${{ secrets.mac_certs }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.mac_certs_password }}
|
||||
run: |
|
||||
npx nx run release --project @notesnook/desktop -- --variant=mas
|
||||
npm run tx @notesnook/desktop:release -- --variant=mas
|
||||
cd apps/desktop
|
||||
yarn electron-builder --config=electron-builder.config.js --mac mas --universal -p never
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build zip and dmg
|
||||
env:
|
||||
@@ -212,13 +208,13 @@ jobs:
|
||||
APPLE_API_KEY_ID: ${{ secrets.api_key_id }}
|
||||
APPLE_API_ISSUER: ${{ secrets.api_key_issuer_id }}
|
||||
run: |
|
||||
npx nx run release --project @notesnook/desktop
|
||||
npm run tx @notesnook/desktop:release
|
||||
cd apps/desktop
|
||||
if [ ${{ inputs.publish-github }} == true ]; then
|
||||
yarn electron-builder --config=electron-builder.config.js --mac zip dmg --arm64 --x64 -p always
|
||||
else
|
||||
yarn electron-builder --config=electron-builder.config.js --mac zip dmg --arm64 --x64 -p never
|
||||
fi
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Deploy to Testflight
|
||||
if: inputs.publish-apple && steps.appstore.outputs.app-version-latest != steps.app_metadata.outputs.app_version
|
||||
@@ -271,8 +267,7 @@ jobs:
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build Electron wrapper
|
||||
run: npx nx run release --project @notesnook/desktop
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run tx @notesnook/desktop:release
|
||||
|
||||
- name: Build snap
|
||||
if: inputs.publish-snap
|
||||
@@ -339,8 +334,7 @@ jobs:
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build Electron wrapper
|
||||
run: npx nx run release --project @notesnook/desktop
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run tx @notesnook/desktop:release
|
||||
|
||||
# - name: Build snap
|
||||
# if: inputs.publish-snap
|
||||
|
||||
15
.github/workflows/desktop.tests.yml
vendored
15
.github/workflows/desktop.tests.yml
vendored
@@ -33,12 +33,8 @@ jobs:
|
||||
npm ci --ignore-scripts --prefer-offline --no-audit
|
||||
npm run bootstrap -- --scope=web
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate desktop build
|
||||
run: npx nx build:desktop @notesnook/web
|
||||
run: npm run tx @notesnook/web:build:desktop
|
||||
|
||||
- name: Archive build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -70,8 +66,7 @@ jobs:
|
||||
npm run bootstrap -- --scope=desktop
|
||||
|
||||
- name: Build Electron wrapper
|
||||
run: npx nx run release --project @notesnook/desktop
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run tx @notesnook/desktop:release
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
@@ -114,8 +109,7 @@ jobs:
|
||||
npm run bootstrap -- --scope=desktop
|
||||
|
||||
- name: Build Electron wrapper
|
||||
run: npx nx run release --project @notesnook/desktop
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run tx @notesnook/desktop:release
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
@@ -164,8 +158,7 @@ jobs:
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build Electron wrapper
|
||||
run: npx nx run release --project @notesnook/desktop
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run tx @notesnook/desktop:release
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
|
||||
8
.github/workflows/editor.tests.yml
vendored
8
.github/workflows/editor.tests.yml
vendored
@@ -38,12 +38,8 @@ jobs:
|
||||
npm ci --ignore-scripts --prefer-offline --no-audit
|
||||
npm run bootstrap -- --scope=editor
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build editor
|
||||
run: npx nx build @notesnook/editor
|
||||
run: npm run tx @notesnook/editor:build
|
||||
|
||||
- name: Run all @notesnook/editor tests
|
||||
run: npx nx test @notesnook/editor
|
||||
run: npm run tx @notesnook/editor:test
|
||||
|
||||
8
.github/workflows/ios.publish.yml
vendored
8
.github/workflows/ios.publish.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
npm run bootstrap -- --scope=mobile
|
||||
|
||||
- name: Build packages
|
||||
run: npx nx run @notesnook/mobile:build
|
||||
run: npm run tx @notesnook/mobile:build
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
@@ -64,6 +64,12 @@ jobs:
|
||||
bundle install
|
||||
RCT_NEW_ARCH_ENABLED=0 bundle exec pod install
|
||||
|
||||
- name: Check for typescript errors
|
||||
run: |
|
||||
npm run tx mobile:build
|
||||
cd apps/mobile
|
||||
npx tsc --noEmit
|
||||
|
||||
- name: CCache Stats Before Build
|
||||
run: ccache -sv
|
||||
|
||||
|
||||
2
.github/workflows/monograph.publish.yml
vendored
2
.github/workflows/monograph.publish.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
echo ::set-output name=app_version::$(cat package.json | jq -r .version)
|
||||
|
||||
- name: Generate build
|
||||
run: npx nx build @notesnook/monograph
|
||||
run: npm run tx @notesnook/monograph:build
|
||||
|
||||
# Setup Buildx
|
||||
- name: Docker Setup Buildx
|
||||
|
||||
1
.github/workflows/theme-builder.publish.yml
vendored
1
.github/workflows/theme-builder.publish.yml
vendored
@@ -20,7 +20,6 @@ jobs:
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_API_TOKEN=${{ secrets.CLOUDFLARE_API_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
1
.github/workflows/vericrypt.publish.yml
vendored
1
.github/workflows/vericrypt.publish.yml
vendored
@@ -20,7 +20,6 @@ jobs:
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_API_TOKEN=${{ secrets.CLOUDFLARE_API_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
4
.github/workflows/web.benchmarks.yml
vendored
4
.github/workflows/web.benchmarks.yml
vendored
@@ -27,10 +27,6 @@ jobs:
|
||||
npm ci --ignore-scripts --prefer-offline --no-audit
|
||||
npm run bootstrap -- --scope=web
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build
|
||||
run: npm run build:web
|
||||
|
||||
|
||||
1
.github/workflows/web.publish.yml
vendored
1
.github/workflows/web.publish.yml
vendored
@@ -30,7 +30,6 @@ jobs:
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_API_TOKEN=${{ secrets.CLOUDFLARE_API_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
4
.github/workflows/web.tests.yml
vendored
4
.github/workflows/web.tests.yml
vendored
@@ -49,10 +49,6 @@ jobs:
|
||||
npm ci --ignore-scripts --prefer-offline --no-audit
|
||||
npm run bootstrap -- --scope=web
|
||||
|
||||
- name: Setup environment
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate test build
|
||||
run: npm run build:test:web
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ Notesnook is built using the following technologies:
|
||||
3. React Native — For mobile apps we are using React Native
|
||||
4. Electron — For desktop app
|
||||
5. NPM — listed here because we **don't** use Yarn or PNPM or XYZ across any of our projects.
|
||||
6. Nx — maintaining monorepos is hard but Nx makes it easier.
|
||||
|
||||
> **Note: Each project in the monorepo contains its own architecture details which you can refer to.**
|
||||
|
||||
|
||||
585
apps/desktop/package-lock.json
generated
585
apps/desktop/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.3.0",
|
||||
"version": "3.3.3",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/cjs/index.js",
|
||||
@@ -47,7 +47,7 @@
|
||||
"@types/node": "22.15.3",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"chokidar": "^4.0.3",
|
||||
"electron": "^36.0.0",
|
||||
"electron": "^37.0.0",
|
||||
"electron-builder": "^26.0.12",
|
||||
"esbuild": "0.21.5",
|
||||
"node-abi": "^4.5.0",
|
||||
|
||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import "./overrides";
|
||||
import { app, BrowserWindow, nativeTheme, shell } from "electron";
|
||||
import { app, BrowserWindow, nativeTheme, shell, dialog } from "electron";
|
||||
import { isDevelopment } from "./utils";
|
||||
import { registerProtocol, PROTOCOL_URL } from "./utils/protocol";
|
||||
import { configureAutoUpdater } from "./utils/autoupdater";
|
||||
@@ -182,6 +182,17 @@ async function createWindow() {
|
||||
app.once("ready", async () => {
|
||||
console.info("App ready. Opening window.");
|
||||
|
||||
if (app.runningUnderARM64Translation) {
|
||||
console.log("App is running under ARM64 translation");
|
||||
dialog.showMessageBoxSync({
|
||||
message:
|
||||
"Notesnook detected that it is running under ARM64 translation. For the best performance, please download the ARM64 build of Notesnook from our website.",
|
||||
type: "warning",
|
||||
buttons: ["Okay"],
|
||||
title: "Degraded Performance Warning"
|
||||
});
|
||||
}
|
||||
|
||||
if (config.customDns) enableCustomDns();
|
||||
else disableCustomDns();
|
||||
|
||||
|
||||
@@ -94,7 +94,9 @@ export async function encryptDatabaseKeyWithPassword(appLockPassword: string) {
|
||||
}
|
||||
|
||||
export async function restoreDatabaseKeyToKeyChain(appLockPassword: string) {
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(DB_KEY_CIPHER);
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(
|
||||
DB_KEY_CIPHER
|
||||
) as Cipher;
|
||||
const databaseKey = (await decrypt(
|
||||
{
|
||||
password: appLockPassword
|
||||
@@ -135,7 +137,9 @@ export async function clearAppLockVerificationCipher() {
|
||||
|
||||
export async function validateAppLockPassword(appLockPassword: string) {
|
||||
try {
|
||||
const appLockCipher: Cipher = CipherStorage.getMap(APPLOCK_CIPHER);
|
||||
const appLockCipher: Cipher = CipherStorage.getMap(
|
||||
APPLOCK_CIPHER
|
||||
) as Cipher;
|
||||
if (!appLockCipher) return true;
|
||||
const key = await Sodium.deriveKey(appLockPassword, appLockCipher.salt);
|
||||
const decrypted = await decrypt(key, appLockCipher);
|
||||
@@ -159,7 +163,9 @@ export function clearDatabaseKey() {
|
||||
export async function getDatabaseKey(appLockPassword?: string) {
|
||||
if (DB_KEY) return DB_KEY;
|
||||
if (appLockPassword) {
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap("databaseKeyCipher");
|
||||
const databaseKeyCipher: Cipher = CipherStorage.getMap(
|
||||
"databaseKeyCipher"
|
||||
) as Cipher;
|
||||
const databaseKey = await decrypt(
|
||||
{
|
||||
password: appLockPassword
|
||||
@@ -293,7 +299,7 @@ export async function deriveCryptoKey(data: SerializedKey) {
|
||||
|
||||
export async function getCryptoKey() {
|
||||
try {
|
||||
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER);
|
||||
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER) as Cipher;
|
||||
if (!keyCipher) {
|
||||
DatabaseLogger.info("User key cipher is null");
|
||||
return undefined;
|
||||
|
||||
@@ -39,7 +39,7 @@ export async function setupDatabase(password?: string) {
|
||||
const key = await getDatabaseKey(password);
|
||||
if (!key) throw new Error(strings.databaseSetupFailed());
|
||||
|
||||
// const base = `http://192.168.100.88`;
|
||||
// const base = `http://192.168.100.92`;
|
||||
|
||||
// database.host({
|
||||
// API_HOST: `${base}:5264`,
|
||||
|
||||
@@ -136,6 +136,12 @@ export const Storage: IStorage = {
|
||||
clear(): Promise<void> {
|
||||
return DefaultStorage.clear();
|
||||
},
|
||||
generateCryptoKeyPair() {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
decryptAsymmetric() {
|
||||
throw new Error("Not implemented");
|
||||
},
|
||||
getAllKeys(): Promise<string[]> {
|
||||
return DefaultStorage.getAllKeys();
|
||||
},
|
||||
|
||||
@@ -38,9 +38,6 @@ export function hideAuth(context) {
|
||||
context === "intro"
|
||||
) {
|
||||
Navigation.replace("FluidPanelsView");
|
||||
setTimeout(() => {
|
||||
Navigation.resetRootState();
|
||||
}, 1000);
|
||||
} else {
|
||||
Navigation.goBack();
|
||||
}
|
||||
|
||||
@@ -19,14 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions
|
||||
} from "react-native";
|
||||
import { TouchableOpacity, View, useWindowDimensions } from "react-native";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
||||
import { DDS } from "../../services/device-detection";
|
||||
import { eSendEvent } from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
@@ -47,8 +44,7 @@ import { hideAuth } from "./common";
|
||||
import { ForgotPassword } from "./forgot-password";
|
||||
import { AuthHeader } from "./header";
|
||||
import { useLogin } from "./use-login";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
||||
import SettingsService from "../../services/settings";
|
||||
|
||||
const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -81,7 +77,7 @@ export const Login = ({ changeMode }) => {
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
if (!PremiumService.get()) {
|
||||
if (!PremiumService.get() && !SettingsService.getProperty("serverUrls")) {
|
||||
Navigation.navigate("PayWall", {
|
||||
context: "signup",
|
||||
state: route.params.state,
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { TouchableOpacity, View, useWindowDimensions } from "react-native";
|
||||
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
||||
@@ -38,7 +39,7 @@ import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { AuthHeader } from "./header";
|
||||
import { SignupContext } from "./signup-context";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import SettingsService from "../../services/settings";
|
||||
|
||||
const SignupSteps = {
|
||||
signup: 0,
|
||||
@@ -91,11 +92,13 @@ export const Signup = ({ changeMode, welcome }) => {
|
||||
setLastSynced(await db.lastSynced());
|
||||
clearMessage();
|
||||
setEmailVerifyMessage();
|
||||
Navigation.navigate("PayWall", {
|
||||
canGoBack: false,
|
||||
state: route.params.state,
|
||||
context: "signup"
|
||||
});
|
||||
if (!SettingsService.getProperty("serverUrls")) {
|
||||
Navigation.navigate("PayWall", {
|
||||
canGoBack: false,
|
||||
state: route.params.state,
|
||||
context: "signup"
|
||||
});
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
setCurrentStep(SignupSteps.signup);
|
||||
|
||||
@@ -99,7 +99,7 @@ export const useLogin = (
|
||||
callback && callback(false);
|
||||
} catch (e) {
|
||||
callback && callback(false);
|
||||
if (e.message === "invalid_grant") {
|
||||
if ((e as Error).message === "invalid_grant") {
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
|
||||
@@ -35,29 +35,35 @@ import SheetProvider from "../sheet-provider";
|
||||
import RateAppSheet from "../sheets/rate-app";
|
||||
import RecoveryKeySheet from "../sheets/recovery-key";
|
||||
import Progress from "../dialogs/progress";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
|
||||
const DialogProvider = () => {
|
||||
const { colors } = useThemeColors();
|
||||
const isAppLoading = useSettingStore((state) => state.isAppLoading);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AppLockPassword />
|
||||
<LoadingDialog />
|
||||
<Dialog context="global" />
|
||||
<AuthModal colors={colors} />
|
||||
<MergeConflicts />
|
||||
<RecoveryKeySheet colors={colors} />
|
||||
<SheetProvider />
|
||||
<SheetProvider context="sync_progress" />
|
||||
<ResultDialog />
|
||||
<VaultDialog colors={colors} />
|
||||
<RateAppSheet />
|
||||
<ImagePreview />
|
||||
<AnnouncementDialog />
|
||||
<SessionExpired />
|
||||
<PDFPreview />
|
||||
<JumpToSectionDialog />
|
||||
<Dialog context="global" />
|
||||
<Progress />
|
||||
|
||||
{isAppLoading ? null : (
|
||||
<>
|
||||
<MergeConflicts />
|
||||
<RecoveryKeySheet colors={colors} />
|
||||
<ResultDialog />
|
||||
<VaultDialog colors={colors} />
|
||||
<RateAppSheet />
|
||||
<ImagePreview />
|
||||
<AnnouncementDialog />
|
||||
<SessionExpired />
|
||||
<PDFPreview />
|
||||
<JumpToSectionDialog />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -244,7 +244,7 @@ const PDFPreview = () => {
|
||||
textAlign: "center",
|
||||
marginRight: 4,
|
||||
borderRadius: 3,
|
||||
fontFamily: "OpenSans-Regular"
|
||||
fontFamily: "Inter-Regular"
|
||||
}}
|
||||
selectTextOnFocus
|
||||
keyboardType="decimal-pad"
|
||||
|
||||
@@ -41,7 +41,7 @@ export const openNotebook = (item: Notebook | BaseTrashItem<Notebook>) => {
|
||||
positiveText: strings.restore(),
|
||||
negativeText: strings.delete(),
|
||||
positivePress: async () => {
|
||||
if ((await db.trash.restore(item.id)) === false) return;
|
||||
await db.trash.restore(item.id);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useSelectionStore.getState().setSelectionMode(undefined);
|
||||
ToastManager.show({
|
||||
|
||||
@@ -117,7 +117,8 @@ export default function NotePreview({ session, content, note }) {
|
||||
{!session?.locked && !locked ? (
|
||||
<View
|
||||
style={{
|
||||
flex: 1
|
||||
flex: 1,
|
||||
backgroundColor: colors.primary.background
|
||||
}}
|
||||
>
|
||||
<ReadonlyEditor
|
||||
|
||||
@@ -44,6 +44,7 @@ import Config from "react-native-config";
|
||||
import * as RNIap from "react-native-iap";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
//@ts-ignore
|
||||
import ToggleSwitch from "toggle-switch-react-native";
|
||||
import {
|
||||
ANDROID_POLICE_SVG,
|
||||
@@ -60,6 +61,7 @@ import usePricingPlans, {
|
||||
PricingPlan
|
||||
} from "../../hooks/use-pricing-plans";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import PremiumService from "../../services/premium";
|
||||
import { getElevationStyle } from "../../utils/elevation";
|
||||
import { openLinkInBrowser } from "../../utils/functions";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
|
||||
@@ -74,7 +76,6 @@ import { IconButton } from "../ui/icon-button";
|
||||
import { SvgView } from "../ui/svg";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import PremiumService from "../../services/premium";
|
||||
|
||||
const Steps = {
|
||||
select: 1,
|
||||
@@ -114,15 +115,8 @@ const PayWall = (props: NavigationProps<"PayWall">) => {
|
||||
routeParams.state?.planId,
|
||||
routeParams.state?.productId
|
||||
);
|
||||
console.log(
|
||||
"selectPlan",
|
||||
routeParams.state?.planId,
|
||||
routeParams.state?.productId,
|
||||
(pricingPlans.selectedProduct as any).productId
|
||||
);
|
||||
}
|
||||
setStep(Steps.buy);
|
||||
console.log("Buy step");
|
||||
}
|
||||
}, [routeParams.state]);
|
||||
|
||||
@@ -926,7 +920,6 @@ const ReviewItem = (props: {
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const PricingPlanCard = ({
|
||||
plan,
|
||||
pricingPlans,
|
||||
@@ -939,7 +932,6 @@ const PricingPlanCard = ({
|
||||
setStep: (step: number) => void;
|
||||
}) => {
|
||||
const { colors } = useThemeColors();
|
||||
const isFreePlan = plan.id === "free";
|
||||
const [regionalDiscount, setRegionaDiscount] = useState<SKUResponse>();
|
||||
const { width } = useWindowDimensions();
|
||||
const isTablet = width > 600;
|
||||
@@ -949,19 +941,22 @@ const PricingPlanCard = ({
|
||||
regionalDiscount?.sku ||
|
||||
`notesnook.${plan.id}.${annualBilling ? "yearly" : "monthly"}`
|
||||
];
|
||||
console.log(regionalDiscount?.sku);
|
||||
const price = pricingPlans?.getPrice(
|
||||
product as RNIap.Subscription,
|
||||
pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0,
|
||||
annualBilling
|
||||
);
|
||||
|
||||
const WebPlan = pricingPlans?.getWebPlan(
|
||||
plan.id,
|
||||
annualBilling ? "yearly" : "monthly"
|
||||
);
|
||||
|
||||
const price = pricingPlans?.getPrice(
|
||||
pricingPlans.isGithubRelease && WebPlan
|
||||
? WebPlan
|
||||
: (product as RNIap.Subscription),
|
||||
pricingPlans.hasTrialOffer(plan.id, product?.productId) ? 1 : 0,
|
||||
annualBilling
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (pricingPlans?.isGithubRelease || !annualBilling) return;
|
||||
pricingPlans
|
||||
?.getRegionalDiscount(
|
||||
plan.id,
|
||||
@@ -972,7 +967,13 @@ const PricingPlanCard = ({
|
||||
.then((value) => {
|
||||
setRegionaDiscount(value);
|
||||
});
|
||||
}, []);
|
||||
}, [annualBilling]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!annualBilling) {
|
||||
setRegionaDiscount(undefined);
|
||||
}
|
||||
}, [annualBilling]);
|
||||
|
||||
const isSubscribed =
|
||||
product?.productId &&
|
||||
@@ -980,7 +981,7 @@ const PricingPlanCard = ({
|
||||
pricingPlans.isSubscribed();
|
||||
|
||||
const isNotReady =
|
||||
pricingPlans?.loadingPlans || (!price && !WebPlan?.price.gross);
|
||||
pricingPlans?.loadingPlans || (!price && !WebPlan?.price?.gross);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
@@ -1112,29 +1113,26 @@ const PricingPlanCard = ({
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{pricingPlans?.loadingPlans || (!price && !WebPlan?.price.gross) ? (
|
||||
{pricingPlans?.loadingPlans || (!price && !WebPlan?.price?.gross) ? (
|
||||
<ActivityIndicator size="small" color={colors.primary.accent} />
|
||||
) : (
|
||||
<View>
|
||||
<Paragraph size={AppFontSize.lg}>
|
||||
{isFreePlan
|
||||
? "0.00"
|
||||
: price ||
|
||||
`${WebPlan?.price.currency} ${WebPlan?.price.gross}`}{" "}
|
||||
{price || `${WebPlan?.price?.currency} ${WebPlan?.price?.gross}`}{" "}
|
||||
<Paragraph>/{strings.month()}</Paragraph>
|
||||
</Paragraph>
|
||||
|
||||
{isFreePlan || !product ? null : (
|
||||
{!product && !WebPlan ? null : (
|
||||
<Paragraph color={colors.secondary.paragraph} size={AppFontSize.xs}>
|
||||
{annualBilling
|
||||
? strings.billedAnnually(
|
||||
pricingPlans?.getStandardPrice(
|
||||
product as RNIap.Subscription
|
||||
(product || WebPlan) as any
|
||||
) as string
|
||||
)
|
||||
: strings.billedMonthly(
|
||||
pricingPlans?.getStandardPrice(
|
||||
product as RNIap.Subscription
|
||||
(product || WebPlan) as any
|
||||
) as string
|
||||
)}
|
||||
</Paragraph>
|
||||
|
||||
@@ -21,7 +21,13 @@ import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import dayjs from "dayjs";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { ScrollView, Text, TouchableOpacity, View } from "react-native";
|
||||
import {
|
||||
Linking,
|
||||
ScrollView,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from "react-native";
|
||||
import Config from "react-native-config";
|
||||
import * as RNIap from "react-native-iap";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
@@ -60,27 +66,24 @@ export const BuyPlan = (props: {
|
||||
return checkoutUrl ? (
|
||||
<View
|
||||
style={{
|
||||
flex: 1
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<WebView
|
||||
source={{
|
||||
uri: checkoutUrl
|
||||
<Paragraph>{strings.finishPurchaseInBrowser()}</Paragraph>
|
||||
<Button
|
||||
title={strings.next()}
|
||||
type="accent"
|
||||
onPress={() => {
|
||||
pricingPlans.finish();
|
||||
}}
|
||||
onMessage={(message) => {
|
||||
try {
|
||||
const data = JSON.parse(message.nativeEvent.data);
|
||||
if (data.success) {
|
||||
pricingPlans.finish();
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
domStorageEnabled
|
||||
javaScriptEnabled
|
||||
cacheEnabled
|
||||
enabled
|
||||
style={{
|
||||
flex: 1
|
||||
/>
|
||||
<Button
|
||||
title={strings.goBack()}
|
||||
onPress={() => {
|
||||
setCheckoutUrl(undefined);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
@@ -245,12 +248,14 @@ export const BuyPlan = (props: {
|
||||
}
|
||||
onPress={async () => {
|
||||
if (isGithubRelease) {
|
||||
setCheckoutUrl(
|
||||
await db.subscriptions.checkoutUrl(
|
||||
(pricingPlans.selectedProduct as Plan).plan,
|
||||
(pricingPlans.selectedProduct as Plan).period
|
||||
)
|
||||
const url = await db.subscriptions.checkoutUrl(
|
||||
(pricingPlans.selectedProduct as Plan).plan,
|
||||
(pricingPlans.selectedProduct as Plan).period
|
||||
);
|
||||
if (url) {
|
||||
setCheckoutUrl(url);
|
||||
Linking.openURL(url);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ import {
|
||||
presentSheet
|
||||
} from "../../../services/event-manager";
|
||||
import Exporter from "../../../services/exporter";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import { useSettingStore } from "../../../stores/use-setting-store";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import { getElevationStyle } from "../../../utils/elevation";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../../utils/size";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
@@ -83,7 +81,6 @@ const ExportNotesSheet = ({
|
||||
type: "pdf" | "txt" | "md" | "html" | "md-frontmatter"
|
||||
) => {
|
||||
if (exporting) return;
|
||||
if (!PremiumService.get() && type !== "txt") return;
|
||||
setExporting(true);
|
||||
update?.({ disableClosing: true } as PresentSheetOptions);
|
||||
setComplete(false);
|
||||
@@ -145,8 +142,7 @@ const ExportNotesSheet = ({
|
||||
await exportNoteAs("txt");
|
||||
},
|
||||
icon: "card-text",
|
||||
id: notesnook.ids.dialogs.export.text,
|
||||
pro: true
|
||||
id: notesnook.ids.dialogs.export.text
|
||||
},
|
||||
{
|
||||
title: "HTML",
|
||||
@@ -194,8 +190,7 @@ const ExportNotesSheet = ({
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL,
|
||||
justifyContent: "flex-start",
|
||||
borderRadius: 0,
|
||||
paddingHorizontal: DefaultAppStyles.GAP,
|
||||
opacity: item.pro ? 1 : 0.5
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
}}
|
||||
>
|
||||
<View
|
||||
|
||||
@@ -36,6 +36,7 @@ import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
import Config from "react-native-config";
|
||||
|
||||
export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -67,7 +68,8 @@ App version: ${getVersion()}
|
||||
Platform: ${Platform.OS}
|
||||
Device: ${getBrand() || ""}-${getModel() || ""}-${getSystemVersion() || ""}
|
||||
Pro: ${PremiumService.get()}
|
||||
Logged in: ${user ? "yes" : "no"}`,
|
||||
Logged in: ${user ? "yes" : "no"}
|
||||
Github Release: ${Config.GITHUB_RELEASE === "true" ? "Yes" : "No"}`,
|
||||
userId: user?.id
|
||||
});
|
||||
if (!issueUrl.current) {
|
||||
@@ -159,7 +161,7 @@ Logged in: ${user ? "yes" : "no"}`,
|
||||
borderColor: colors.primary.border,
|
||||
borderRadius: defaultBorderRadius,
|
||||
padding: DefaultAppStyles.GAP,
|
||||
fontFamily: "OpenSans-Regular",
|
||||
fontFamily: "Inter-Regular",
|
||||
marginBottom: DefaultAppStyles.GAP_VERTICAL,
|
||||
fontSize: AppFontSize.md,
|
||||
color: colors.primary.heading
|
||||
@@ -192,7 +194,7 @@ Logged in: ${user ? "yes" : "no"}`,
|
||||
borderColor: colors.primary.border,
|
||||
borderRadius: defaultBorderRadius,
|
||||
padding: DefaultAppStyles.GAP,
|
||||
fontFamily: "OpenSans-Regular",
|
||||
fontFamily: "Inter-Regular",
|
||||
maxHeight: 200,
|
||||
fontSize: AppFontSize.sm,
|
||||
marginBottom: 2.5,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "../../../services/event-manager";
|
||||
import Navigation from "../../../services/navigation";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import SettingsService from "../../../services/settings";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import { eCloseSheet } from "../../../utils/events";
|
||||
import { AppFontSize } from "../../../utils/size";
|
||||
@@ -37,7 +38,6 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
|
||||
const { colors } = useThemeColors();
|
||||
const pricingPlans = usePricingPlans();
|
||||
useEffect(() => {
|
||||
console.log("PaywallSheet mounted with feature:", props.feature);
|
||||
ToastManager.hide();
|
||||
if (!props.feature.availableOn) return;
|
||||
const plan = pricingPlans.pricingPlans.find(
|
||||
@@ -55,11 +55,11 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
|
||||
}, []);
|
||||
|
||||
const isSubscribedOnWeb =
|
||||
(PremiumService.get() &&
|
||||
PremiumService.get() &&
|
||||
(pricingPlans.user?.subscription?.provider ===
|
||||
SubscriptionProvider.PADDLE ||
|
||||
pricingPlans.user?.subscription?.provider ===
|
||||
SubscriptionProvider.PADDLE) ||
|
||||
pricingPlans.user?.subscription?.provider ===
|
||||
SubscriptionProvider.STREETWRITERS;
|
||||
SubscriptionProvider.STREETWRITERS);
|
||||
|
||||
const isCurrentPlatform =
|
||||
(pricingPlans.user?.subscription?.provider === SubscriptionProvider.APPLE &&
|
||||
@@ -194,25 +194,28 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
|
||||
width: "100%"
|
||||
}}
|
||||
onPress={() => {
|
||||
if (
|
||||
pricingPlans.user?.subscription.plan ===
|
||||
SubscriptionPlan.LEGACY_PRO ||
|
||||
!isCurrentPlatform
|
||||
) {
|
||||
ToastManager.show({
|
||||
message: strings.cannotChangePlan(),
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
if (PremiumService.get()) {
|
||||
if (
|
||||
pricingPlans.user?.subscription.plan ===
|
||||
SubscriptionPlan.LEGACY_PRO ||
|
||||
!isCurrentPlatform
|
||||
) {
|
||||
ToastManager.show({
|
||||
message: strings.cannotChangePlan(),
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSubscribedOnWeb) {
|
||||
ToastManager.show({
|
||||
message: strings.changePlanOnWeb(),
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSubscribedOnWeb) {
|
||||
ToastManager.show({
|
||||
message: strings.changePlanOnWeb(),
|
||||
context: "local"
|
||||
});
|
||||
return;
|
||||
}
|
||||
eSendEvent(eCloseSheet);
|
||||
if (!useUserStore.getState().user) {
|
||||
Navigation.navigate("Auth", {
|
||||
@@ -256,6 +259,7 @@ export default function PaywallSheet<Tid extends FeatureId>(props: {
|
||||
}
|
||||
|
||||
PaywallSheet.present = <Tid extends FeatureId>(feature: FeatureResult<Tid>) => {
|
||||
if (SettingsService.getProperty("serverUrls")) return;
|
||||
presentSheet({
|
||||
component: <PaywallSheet feature={feature} />
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ import Paragraph from "../../ui/typography/paragraph";
|
||||
import { SubscriptionPlan, SubscriptionProvider } from "@notesnook/core";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import PremiumService from "../../../services/premium";
|
||||
import SettingsService from "../../../services/settings";
|
||||
|
||||
export function PlanLimits() {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -84,10 +85,11 @@ export function PlanLimits() {
|
||||
</View>
|
||||
))}
|
||||
|
||||
{(user?.subscription?.provider === SubscriptionProvider.PADDLE ||
|
||||
{((user?.subscription?.provider === SubscriptionProvider.PADDLE ||
|
||||
user?.subscription?.provider === SubscriptionProvider.STREETWRITERS ||
|
||||
!isCurrentPlatform) &&
|
||||
PremiumService.get() ? null : (
|
||||
PremiumService.get()) ||
|
||||
SettingsService.getProperty("serverUrls") ? null : (
|
||||
<Button
|
||||
title={strings.changePlan()}
|
||||
onPress={() => {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
View
|
||||
} from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
//@ts-ignore
|
||||
import ToggleSwitch from "toggle-switch-react-native";
|
||||
import { db } from "../../../common/database";
|
||||
import { requestInAppReview } from "../../../services/app-review";
|
||||
|
||||
@@ -24,10 +24,11 @@ import { FlatList, View } from "react-native";
|
||||
import { DraxProvider, DraxScrollView } from "react-native-drax";
|
||||
import { db } from "../../common/database";
|
||||
import Navigation from "../../services/navigation";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { useMenuStore } from "../../stores/use-menu-store";
|
||||
import { useSettingStore } from "../../stores/use-setting-store";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { SUBSCRIPTION_STATUS } from "../../utils/constants";
|
||||
import { MenuItemsList } from "../../utils/menu-items";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import ReorderableList from "../list/reorderable-list";
|
||||
import { MenuItemProperties } from "../sheets/menu-item-properties";
|
||||
@@ -36,7 +37,6 @@ import { ColorSection } from "./color-section";
|
||||
import { MenuItem } from "./menu-item";
|
||||
import { PinnedSection } from "./pinned-section";
|
||||
import { SideMenuHeader } from "./side-menu-header";
|
||||
import { MenuItemsList } from "../../utils/menu-items";
|
||||
|
||||
const pro = {
|
||||
title: strings.upgradePlan(),
|
||||
@@ -140,9 +140,10 @@ export function SideMenuHome() {
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
{subscriptionType === SubscriptionPlan.FREE ||
|
||||
!subscriptionType ||
|
||||
!user ? (
|
||||
{(subscriptionType === SubscriptionPlan.FREE ||
|
||||
!subscriptionType ||
|
||||
!user) &&
|
||||
!SettingsService.getProperty("serverUrls") ? (
|
||||
<Button
|
||||
title={pro.title}
|
||||
style={{
|
||||
|
||||
@@ -239,7 +239,7 @@ const Input = ({
|
||||
flexShrink: 1,
|
||||
paddingBottom: DefaultAppStyles.GAP_VERTICAL - 4,
|
||||
paddingTop: DefaultAppStyles.GAP_VERTICAL - 4,
|
||||
fontFamily: "OpenSans-Regular",
|
||||
fontFamily: "Inter-Regular",
|
||||
...(inputStyle as ViewStyle)
|
||||
};
|
||||
|
||||
|
||||
@@ -132,7 +132,10 @@ const SheetWrapper = ({
|
||||
width: 100,
|
||||
backgroundColor: colors.secondary.background
|
||||
}}
|
||||
safeAreaInsets={insets}
|
||||
safeAreaInsets={{
|
||||
...insets,
|
||||
bottom: Platform.OS === "android" ? 0 : insets.bottom
|
||||
}}
|
||||
statusBarTranslucent
|
||||
drawUnderStatusBar={true}
|
||||
containerStyle={style}
|
||||
|
||||
@@ -171,7 +171,7 @@ const onAppOpenedFromURL = async (event: { url: string }) => {
|
||||
eSendEvent(eOnLoadNote, { newNote: true });
|
||||
fluidTabsRef.current?.goToPage("editor", false);
|
||||
return;
|
||||
} else if (url.startsWith("https://notesnook.com/open_note")) {
|
||||
} else if (url.startsWith("https://app.notesnook.com/open_note")) {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
const note = await db.notes.note(id);
|
||||
@@ -182,13 +182,13 @@ const onAppOpenedFromURL = async (event: { url: string }) => {
|
||||
fluidTabsRef.current?.goToPage("editor", false);
|
||||
}
|
||||
}
|
||||
} else if (url.startsWith("https://notesnook.com/open_reminder")) {
|
||||
} else if (url.startsWith("https://app.notesnook.com/open_reminder")) {
|
||||
const id = new URL(url).searchParams.get("id");
|
||||
if (id) {
|
||||
const reminder = await db.reminders.reminder(id);
|
||||
if (reminder) AddReminder.present(reminder);
|
||||
}
|
||||
} else if (url.startsWith("https://notesnook.com/new_reminder")) {
|
||||
} else if (url.startsWith("https://app.notesnook.com/new_reminder")) {
|
||||
const reminderFeature = await isFeatureAvailable("activeReminders");
|
||||
if (!reminderFeature.isAllowed) {
|
||||
ToastManager.show({
|
||||
@@ -780,13 +780,11 @@ export const useAppEvents = () => {
|
||||
if (!isAppLoading && !appLocked) {
|
||||
setTimeout(() => {
|
||||
sub = AppState.addEventListener("change", onAppStateChanged);
|
||||
if (
|
||||
refValues.current.initialUrl &&
|
||||
!refValues.current.initialUrl?.includes("open_note")
|
||||
) {
|
||||
if (refValues.current.initialUrl) {
|
||||
onAppOpenedFromURL({
|
||||
url: refValues.current.initialUrl!
|
||||
});
|
||||
refValues.current.initialUrl = undefined;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
|
||||
@@ -69,35 +69,6 @@ export default function useFeatureManager() {
|
||||
db.settings.setDefaultTag(undefined);
|
||||
}
|
||||
}
|
||||
const isAppLocked = useUserStore.getState().appLocked;
|
||||
let unsub: () => void;
|
||||
|
||||
if (isAppLocked) {
|
||||
unsub = useUserStore.subscribe((state) => {
|
||||
if (!state.appLocked && !features?.appLock?.isAllowed) {
|
||||
unsub();
|
||||
SettingsService.setProperty("appLockEnabled", false);
|
||||
setTimeout(() => {
|
||||
presentDialog({
|
||||
title: "App Lock Disabled",
|
||||
paragraph: features?.appLock?.error,
|
||||
positiveText: strings.upgrade(),
|
||||
negativeText: strings.cancel(),
|
||||
positivePress: async () => {
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
Navigation.navigate("PayWall", {
|
||||
context: "logged-in"
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return () => {
|
||||
unsub?.();
|
||||
};
|
||||
}, [features, plan]);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,6 +25,7 @@ import { DatabaseLogger, db } from "../common/database";
|
||||
import PremiumService from "../services/premium";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { useUserStore } from "../stores/use-user-store";
|
||||
import SettingsService from "../services/settings";
|
||||
function numberWithCommas(x: string) {
|
||||
const parts = x.toString().split(".");
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
@@ -201,7 +202,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
if (productId?.includes("5year")) return false;
|
||||
if (isGithubRelease) {
|
||||
if (
|
||||
user?.subscription.trialsAvailed?.some(
|
||||
user?.subscription?.trialsAvailed?.some(
|
||||
(plan) => plan === planIdToIndex(planId || currentPlan)
|
||||
)
|
||||
) {
|
||||
@@ -246,7 +247,10 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
});
|
||||
setPlans([...pricingPlans]);
|
||||
setUserCanRequestTrial(hasTrialOffer());
|
||||
if (Config.GITHUB_RELEASE === "true") {
|
||||
if (
|
||||
Config.GITHUB_RELEASE === "true" &&
|
||||
!SettingsService.getProperty("serverUrls")
|
||||
) {
|
||||
try {
|
||||
const products = WebPlanCache || (await db.pricing.products());
|
||||
WebPlanCache = products;
|
||||
@@ -264,14 +268,18 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
if (!product) return;
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
if (isGithubRelease)
|
||||
return `${(product as Plan).price.currency} ${
|
||||
if (isGithubRelease) {
|
||||
if (!(product as Plan)?.price) return null;
|
||||
return `${
|
||||
(product as Plan).currencySymbol || (product as Plan).currency
|
||||
} ${
|
||||
(product as Plan).period === "yearly"
|
||||
? ((product as Plan).price.gross / 12).toFixed(2)
|
||||
? (product as Plan).price.gross
|
||||
: (product as Plan).period === "5-year"
|
||||
? ((product as Plan).price.gross / (12 * 5)).toFixed(2)
|
||||
? (product as Plan).price.gross
|
||||
: (product as Plan).price.gross
|
||||
}`;
|
||||
}
|
||||
|
||||
const pricingPhaseListItem =
|
||||
(product as RNIap.SubscriptionAndroid)?.subscriptionOfferDetails?.[0]
|
||||
@@ -414,7 +422,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
offerIndex: number
|
||||
) => {
|
||||
if (isGithubRelease) {
|
||||
return (product as Plan).period;
|
||||
return (product as Plan)?.period;
|
||||
}
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
@@ -444,7 +452,7 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
if (isGithubRelease) {
|
||||
return {
|
||||
duration: 1,
|
||||
type: (product as Plan).period
|
||||
type: (product as Plan)?.period
|
||||
};
|
||||
}
|
||||
|
||||
@@ -591,14 +599,18 @@ const usePricingPlans = (options?: PricingPlansOptions) => {
|
||||
) => {
|
||||
if (!product) return null;
|
||||
|
||||
if (isGithubRelease)
|
||||
return `${(product as Plan).price.currency} ${
|
||||
if (isGithubRelease) {
|
||||
if (!(product as Plan)?.price) return null;
|
||||
return `${
|
||||
(product as Plan).currencySymbol || (product as Plan).currency
|
||||
} ${
|
||||
(product as Plan).period === "yearly"
|
||||
? ((product as Plan).price.gross / 12).toFixed(2)
|
||||
: (product as Plan).period === "5-year"
|
||||
? ((product as Plan).price.gross / (12 * 5)).toFixed(2)
|
||||
: (product as Plan).price.gross
|
||||
}`;
|
||||
}
|
||||
|
||||
const androidPricingPhase = (product as RNIap.SubscriptionAndroid)
|
||||
?.subscriptionOfferDetails?.[0].pricingPhases?.pricingPhaseList?.[
|
||||
|
||||
@@ -1,67 +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 { useEffect, useState } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { Subscription } from "react-native-iap";
|
||||
import PremiumService from "../services/premium";
|
||||
import { db } from "../common/database";
|
||||
import { Product } from "@notesnook/core";
|
||||
|
||||
const skuInfos: { [name: string]: Product | undefined } = {};
|
||||
|
||||
export const usePricing = (period: "monthly" | "yearly") => {
|
||||
const [current, setCurrent] = useState<{
|
||||
period: string;
|
||||
info?: Product;
|
||||
product?: Subscription;
|
||||
}>();
|
||||
|
||||
const getDefaultSku = (period: "monthly" | "yearly") => {
|
||||
return period === "monthly"
|
||||
? "com.streetwriters.notesnook.sub.mo"
|
||||
: "com.streetwriters.notesnook.sub.yr";
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const skuInfo =
|
||||
skuInfos[period] ||
|
||||
(await db.pricing?.sku(
|
||||
Platform.OS === "android" ? "android" : "ios",
|
||||
period
|
||||
));
|
||||
skuInfos[period] = skuInfo;
|
||||
|
||||
const products = (await (
|
||||
await PremiumService.loadProductsAndSubs()
|
||||
).subs) as Subscription[];
|
||||
let product = products.find((p) => p.productId === skuInfo?.sku);
|
||||
if (!product)
|
||||
product = products.find((p) => p.productId === getDefaultSku(period));
|
||||
setCurrent({
|
||||
info: skuInfo,
|
||||
period,
|
||||
product
|
||||
});
|
||||
})();
|
||||
}, [period]);
|
||||
|
||||
return current;
|
||||
};
|
||||
@@ -21,6 +21,7 @@ import React, { useCallback, useEffect } from "react";
|
||||
import { db } from "../common/database";
|
||||
import BiometricService from "../services/biometrics";
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
|
||||
const VaultStatusDefaults = {
|
||||
exists: false,
|
||||
@@ -36,6 +37,7 @@ export type VaultStatusType = {
|
||||
|
||||
export const useVaultStatus = () => {
|
||||
const [vaultStatus, setVaultStatus] = React.useState(VaultStatusDefaults);
|
||||
const isAppLoading = useSettingStore((state) => state.isAppLoading);
|
||||
|
||||
const checkVaultStatus = useCallback(() => {
|
||||
db.vault?.exists().then(async (exists) => {
|
||||
@@ -50,12 +52,13 @@ export const useVaultStatus = () => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAppLoading) return;
|
||||
checkVaultStatus();
|
||||
eSubscribeEvent("vaultUpdated", () => checkVaultStatus());
|
||||
return () => {
|
||||
eUnSubscribeEvent("vaultUpdated", () => checkVaultStatus());
|
||||
};
|
||||
}, [checkVaultStatus]);
|
||||
}, [checkVaultStatus, isAppLoading]);
|
||||
|
||||
return vaultStatus;
|
||||
};
|
||||
|
||||
@@ -258,12 +258,14 @@ export const RootNavigation = () => {
|
||||
(state) => state.settings.introCompleted
|
||||
);
|
||||
const clearSelection = useSelectionStore((state) => state.clearSelection);
|
||||
const resetTimer = React.useRef<NodeJS.Timeout>(undefined);
|
||||
const onStateChange = React.useCallback(
|
||||
(state: any) => {
|
||||
if (useSelectionStore.getState().selectionMode) {
|
||||
clearSelection();
|
||||
}
|
||||
setTimeout(() => {
|
||||
clearTimeout(resetTimer.current);
|
||||
resetTimer.current = setTimeout(() => {
|
||||
Navigation.resetRootState(state);
|
||||
}, 1000);
|
||||
hideAllTooltips();
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
"@trpc/react-query": "^10.45.2",
|
||||
"@trpc/server": "^10.45.2",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"async-mutex": "0.5.0"
|
||||
"async-mutex": "0.5.0",
|
||||
"react-async-hook": "^4.0.0"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import { AppFontSize, defaultBorderRadius } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { getFormattedDate, useIsFeatureAvailable } from "@notesnook/common";
|
||||
import PaywallSheet from "../../components/sheets/paywall";
|
||||
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
|
||||
|
||||
const ReminderModes =
|
||||
Platform.OS === "ios"
|
||||
@@ -89,6 +90,7 @@ const ReminderNotificationModes = {
|
||||
|
||||
export default function AddReminder(props: NavigationProps<"AddReminder">) {
|
||||
const { reminder, reference } = props.route.params;
|
||||
useNavigationFocus(props.navigation, { focusOnInit: true });
|
||||
const { colors, isDark } = useThemeColors();
|
||||
const [reminderMode, setReminderMode] = useState<Reminder["mode"]>(
|
||||
reminder?.mode || "once"
|
||||
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
import { fluidTabsRef } from "../../utils/global-refs";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { i18n } from "@lingui/core";
|
||||
import { useVaultStatus } from "../../hooks/use-vault-status";
|
||||
|
||||
const style: ViewStyle = {
|
||||
height: "100%",
|
||||
@@ -197,6 +198,7 @@ const Editor = React.memo(
|
||||
export default Editor;
|
||||
|
||||
const useLockedNoteHandler = () => {
|
||||
const vaultStatus = useVaultStatus();
|
||||
const tab = useTabStore((state) => state.getTab(state.currentTab));
|
||||
const tabRef = useRef(tab);
|
||||
tabRef.current = tab;
|
||||
@@ -217,15 +219,13 @@ const useLockedNoteHandler = () => {
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const biometry = await BiometricService.isBiometryAvailable();
|
||||
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||
useTabStore.setState({
|
||||
biometryAvailable: !!biometry,
|
||||
biometryEnrolled: !!fingerprint
|
||||
biometryAvailable: !!vaultStatus.isBiometryAvailable,
|
||||
biometryEnrolled: !!vaultStatus.biometryEnrolled
|
||||
});
|
||||
syncTabs("biometry");
|
||||
})();
|
||||
}, [tab?.id]);
|
||||
}, [tab?.id, vaultStatus.biometryEnrolled, vaultStatus.isBiometryAvailable]);
|
||||
|
||||
useEffect(() => {
|
||||
const unlockWithBiometrics = async () => {
|
||||
|
||||
@@ -59,6 +59,7 @@ export type Settings = {
|
||||
fontScale: number;
|
||||
markdownShortcuts: boolean;
|
||||
features: Record<any, any>;
|
||||
loggedIn: boolean;
|
||||
};
|
||||
|
||||
export type EditorProps = {
|
||||
|
||||
@@ -82,6 +82,7 @@ import { editorState, openInternalLink } from "./utils";
|
||||
import AddReminder from "../../add-reminder";
|
||||
import { isFeatureAvailable, useAreFeaturesAvailable } from "@notesnook/common";
|
||||
import PaywallSheet from "../../../components/sheets/paywall";
|
||||
import useNavigationStore from "../../../stores/use-navigation-store";
|
||||
|
||||
const publishNote = async () => {
|
||||
const user = useUserStore.getState().user;
|
||||
@@ -164,6 +165,7 @@ export const useEditorEvents = (
|
||||
state.timeFormat
|
||||
]);
|
||||
const handleBack = useRef<NativeEventSubscription>();
|
||||
const loggedIn = useUserStore((state) => !!state.user);
|
||||
const { fontScale } = useWindowDimensions();
|
||||
|
||||
const doubleSpacedLines = useSettingStore(
|
||||
@@ -223,7 +225,8 @@ export const useEditorEvents = (
|
||||
timeFormat: db.settings?.getTimeFormat(),
|
||||
fontScale,
|
||||
markdownShortcuts,
|
||||
features
|
||||
features,
|
||||
loggedIn
|
||||
});
|
||||
}, [
|
||||
fullscreen,
|
||||
@@ -241,7 +244,8 @@ export const useEditorEvents = (
|
||||
timeFormat,
|
||||
loading,
|
||||
fontScale,
|
||||
markdownShortcuts
|
||||
markdownShortcuts,
|
||||
loggedIn
|
||||
]);
|
||||
|
||||
const onBackPress = useCallback(async () => {
|
||||
@@ -274,7 +278,15 @@ export const useEditorEvents = (
|
||||
|
||||
const onHardwareBackPress = useCallback(() => {
|
||||
if (fluidTabsRef.current?.page() === "editor") {
|
||||
onBackPress();
|
||||
if (
|
||||
useNavigationStore.getState().currentRoute === "ManageTags" ||
|
||||
useNavigationStore.getState().currentRoute === "LinkNotebooks" ||
|
||||
useNavigationStore.getState().currentRoute === "AddReminder"
|
||||
) {
|
||||
Navigation.goBack();
|
||||
} else {
|
||||
onBackPress();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, [onBackPress]);
|
||||
@@ -547,9 +559,17 @@ export const useEditorEvents = (
|
||||
if (editor.state.current?.isFocused) {
|
||||
editor.state.current.isFocused = true;
|
||||
}
|
||||
PaywallSheet.present(
|
||||
await isFeatureAvailable(editorMessage.value.feature)
|
||||
);
|
||||
if (editorMessage.value.feature === "insertAttachment") {
|
||||
ToastManager.show({
|
||||
type: "info",
|
||||
message: strings.loginRequired()
|
||||
});
|
||||
} else {
|
||||
PaywallSheet.present(
|
||||
await isFeatureAvailable(editorMessage.value.feature)
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
case EditorEvents.monograph:
|
||||
publishNote();
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useRef } from "react";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { TextInput } from "react-native-gesture-handler";
|
||||
import { IconButton } from "../../components/ui/icon-button";
|
||||
@@ -36,6 +36,7 @@ export const SearchBar = ({
|
||||
onChangeText: (value: string) => void;
|
||||
loading?: boolean;
|
||||
}) => {
|
||||
const [clearButton, setClearButton] = useState(false);
|
||||
const selectionMode = useSelectionStore((state) => state.selectionMode);
|
||||
const isFocused = useNavigationStore(
|
||||
(state) => state.focusedRouteId === "Search"
|
||||
@@ -45,6 +46,7 @@ export const SearchBar = ({
|
||||
const inputRef = useRef<TextInput>(null);
|
||||
const _onChangeText = (value: string) => {
|
||||
onChangeText(value);
|
||||
setClearButton(!!value);
|
||||
};
|
||||
|
||||
return selectionMode && isFocused ? null : (
|
||||
@@ -84,7 +86,7 @@ export const SearchBar = ({
|
||||
testID="search-input"
|
||||
style={{
|
||||
fontSize: AppFontSize.sm,
|
||||
fontFamily: "OpenSans-Regular",
|
||||
fontFamily: "Inter-Regular",
|
||||
flexGrow: 1,
|
||||
color: colors.primary.paragraph,
|
||||
paddingTop: 0,
|
||||
@@ -100,6 +102,23 @@ export const SearchBar = ({
|
||||
autoCorrect={false}
|
||||
placeholderTextColor={colors.primary.placeholder}
|
||||
/>
|
||||
|
||||
{clearButton ? (
|
||||
<IconButton
|
||||
name="close"
|
||||
size={AppFontSize.xxl}
|
||||
top={10}
|
||||
testID="clear-search"
|
||||
bottom={10}
|
||||
onPress={() => {
|
||||
inputRef.current?.clear();
|
||||
onChangeText("");
|
||||
setClearButton(false);
|
||||
}}
|
||||
color={colors.primary.paragraph}
|
||||
type="plain"
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -43,6 +43,7 @@ import { ServersConfiguration } from "./server-config";
|
||||
import SoundPicker from "./sound-picker";
|
||||
import ThemeSelector from "./theme-selector";
|
||||
import { TitleFormat } from "./title-format";
|
||||
import { NotesnookCircle } from "./notesnook-circle";
|
||||
|
||||
export const components: { [name: string]: ReactElement } = {
|
||||
homeselector: <HomePicker />,
|
||||
@@ -69,5 +70,6 @@ export const components: { [name: string]: ReactElement } = {
|
||||
),
|
||||
"sidebar-tab-selector": <SidebarTabPicker />,
|
||||
"change-password": <ChangePassword />,
|
||||
"change-email": <ChangeEmail />
|
||||
"change-email": <ChangeEmail />,
|
||||
"notesnook-circle": <NotesnookCircle />
|
||||
};
|
||||
|
||||
@@ -185,7 +185,7 @@ export default function DebugLogs() {
|
||||
paragraph: strings.clearLogsConfirmation(currentLog.key),
|
||||
negativeText: strings.cancel(),
|
||||
positiveText: strings.clear(),
|
||||
positivePress: () => {
|
||||
positivePress: async () => {
|
||||
const index = logs.findIndex((l) => (l.key = currentLog.key));
|
||||
logManager?.delete(currentLog.key);
|
||||
if (logs.length > 1) {
|
||||
|
||||
213
apps/mobile/app/screens/settings/notesnook-circle.tsx
Normal file
213
apps/mobile/app/screens/settings/notesnook-circle.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import { CirclePartner, SubscriptionStatus } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import Clipboard from "@react-native-clipboard/clipboard";
|
||||
import { useState } from "react";
|
||||
import { useAsync } from "react-async-hook";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Image,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from "react-native";
|
||||
import { db } from "../../common/database";
|
||||
import AppIcon from "../../components/ui/AppIcon";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { Notice } from "../../components/ui/notice";
|
||||
import Heading from "../../components/ui/typography/heading";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
import PremiumService from "../../services/premium";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { openLinkInBrowser } from "../../utils/functions";
|
||||
import { Pressable } from "../../components/ui/pressable";
|
||||
|
||||
export const NotesnookCircle = () => {
|
||||
const user = useUserStore((state) => state.user);
|
||||
const isOnTrial =
|
||||
PremiumService.get() &&
|
||||
user?.subscription?.status === SubscriptionStatus.TRIAL;
|
||||
const isFree = !PremiumService.get();
|
||||
const partners = useAsync(db.circle.partners, []);
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
gap: DefaultAppStyles.GAP_VERTICAL,
|
||||
paddingHorizontal: DefaultAppStyles.GAP,
|
||||
paddingTop: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
{!isFree && !isOnTrial ? null : (
|
||||
<View>
|
||||
<Paragraph>
|
||||
{isFree
|
||||
? strings.freeUserCircleNotice()
|
||||
: strings.trialUserCircleNotice()}
|
||||
</Paragraph>
|
||||
|
||||
{!isOnTrial ? null : (
|
||||
<Button
|
||||
title={strings.upgradePlan()}
|
||||
onPress={() => {
|
||||
Navigation.navigate("PayWall", {
|
||||
canGoBack: true,
|
||||
context: useUserStore.getState().user
|
||||
? "logged-in"
|
||||
: "logged-out"
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
alignSelf: "flex-start",
|
||||
paddingHorizontal: 0
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{partners.loading ? <ActivityIndicator /> : null}
|
||||
|
||||
{partners.error ? (
|
||||
<Notice type="alert" text={partners.error.message} />
|
||||
) : null}
|
||||
|
||||
{partners.result?.map((item) => (
|
||||
<Partner item={item} available={!isFree && !isOnTrial} />
|
||||
))}
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const Partner = ({
|
||||
item,
|
||||
available
|
||||
}: {
|
||||
item: CirclePartner;
|
||||
available: boolean;
|
||||
}) => {
|
||||
const { colors } = useThemeColors();
|
||||
const [code, setCode] = useState<string>();
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
borderRadius: defaultBorderRadius,
|
||||
borderWidth: 1,
|
||||
borderColor: colors.primary.border,
|
||||
padding: DefaultAppStyles.GAP,
|
||||
gap: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<Heading>{item.name}</Heading>
|
||||
<Image
|
||||
src={item.logoBase64}
|
||||
style={{
|
||||
width: 40,
|
||||
height: 40
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Paragraph style={{ textAlign: "justify" }}>
|
||||
{item.longDescription.trim()}
|
||||
</Paragraph>
|
||||
|
||||
<Paragraph
|
||||
style={{
|
||||
alignSelf: "center"
|
||||
}}
|
||||
color={colors.primary.accent}
|
||||
>
|
||||
{item.offerDescription}
|
||||
</Paragraph>
|
||||
|
||||
{available ? (
|
||||
<>
|
||||
{!code ? (
|
||||
<Button
|
||||
type="accent"
|
||||
title={strings.redeemCode()}
|
||||
width="100%"
|
||||
onPress={() => {
|
||||
if (!PremiumService.get()) {
|
||||
Navigation.navigate("PayWall", {
|
||||
canGoBack: true,
|
||||
context: useUserStore.getState().user
|
||||
? "logged-in"
|
||||
: "logged-out"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
db.circle
|
||||
.redeem(item.id)
|
||||
.then((result) => setCode(result?.code))
|
||||
.catch((e) => ToastManager.error(e));
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
backgroundColor: colors.secondary.background,
|
||||
borderRadius: defaultBorderRadius,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: DefaultAppStyles.GAP_SMALL,
|
||||
borderWidth: 0.5,
|
||||
borderColor: colors.secondary.border,
|
||||
flexDirection: "row",
|
||||
gap: DefaultAppStyles.GAP_SMALL
|
||||
}}
|
||||
activeOpacity={0.9}
|
||||
onPress={() => {
|
||||
Clipboard.setString(code);
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={AppFontSize.lg}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{code}
|
||||
</Paragraph>
|
||||
|
||||
<AppIcon name="content-copy" />
|
||||
</TouchableOpacity>
|
||||
|
||||
{item.codeRedeemUrl ? (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
if (item.codeRedeemUrl) {
|
||||
openLinkInBrowser(
|
||||
item.codeRedeemUrl.replace("{{code}}", code)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
color={colors.secondary.paragraph}
|
||||
size={AppFontSize.xxs}
|
||||
>
|
||||
{strings.clickToDirectlyClaimPromo()}
|
||||
</Paragraph>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -26,18 +26,17 @@ import {
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { ActivityIndicator, TextInput, View } from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
//@ts-ignore
|
||||
import { FeatureResult, useIsFeatureAvailable } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
//@ts-ignore
|
||||
import ToggleSwitch from "toggle-switch-react-native";
|
||||
import PaywallSheet from "../../components/sheets/paywall";
|
||||
import AppIcon from "../../components/ui/AppIcon";
|
||||
import { IconButton } from "../../components/ui/icon-button";
|
||||
import Input from "../../components/ui/input";
|
||||
import { Pressable } from "../../components/ui/pressable";
|
||||
import Seperator from "../../components/ui/seperator";
|
||||
import Heading from "../../components/ui/typography/heading";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import SettingsService from "../../services/settings";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { SettingStore, useSettingStore } from "../../stores/use-setting-store";
|
||||
@@ -45,7 +44,6 @@ import { AppFontSize } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { components } from "./components";
|
||||
import { RouteParams, SettingSection } from "./types";
|
||||
import AppIcon from "../../components/ui/AppIcon";
|
||||
|
||||
const _SectionItem = ({ item }: { item: SettingSection }) => {
|
||||
const { colors } = useThemeColors();
|
||||
|
||||
@@ -32,6 +32,7 @@ import React from "react";
|
||||
import { Appearance, Linking, Platform } from "react-native";
|
||||
import { getVersion } from "react-native-device-info";
|
||||
import * as RNIap from "react-native-iap";
|
||||
//@ts-ignore
|
||||
import { enabled } from "react-native-privacy-snapshot";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
import { DatabaseLogger, db } from "../../common/database";
|
||||
@@ -81,15 +82,22 @@ export const settingsGroups: SettingSection[] = [
|
||||
{
|
||||
id: "subscription-status",
|
||||
useHook: () => useUserStore((state) => state.user),
|
||||
hidden: (current) =>
|
||||
!current ||
|
||||
(current as User).subscription?.plan === SubscriptionPlan.FREE,
|
||||
hidden: (current) => {
|
||||
const user = current as User;
|
||||
return (
|
||||
!user ||
|
||||
!user.subscription ||
|
||||
user.subscription.provider === undefined ||
|
||||
!strings.subscriptionProviderInfo[user?.subscription?.provider] ||
|
||||
user.subscription?.plan === SubscriptionPlan.FREE
|
||||
);
|
||||
},
|
||||
name: (current) => {
|
||||
const user = (current as User) || useUserStore.getState().user;
|
||||
return (
|
||||
strings.subscriptionProviderInfo[
|
||||
user?.subscription?.provider
|
||||
].title() || "Unknown provider"
|
||||
]?.title() || `Unknown provider id: ${user?.subscription?.provider}`
|
||||
);
|
||||
},
|
||||
icon: "credit-card",
|
||||
@@ -99,6 +107,8 @@ export const settingsGroups: SettingSection[] = [
|
||||
const subscriptionProviderInfo =
|
||||
strings.subscriptionProviderInfo[user?.subscription?.provider];
|
||||
|
||||
if (!subscriptionProviderInfo) return;
|
||||
|
||||
const isCurrentPlatform =
|
||||
(user.subscription?.provider === SubscriptionProvider.APPLE &&
|
||||
Platform.OS === "ios") ||
|
||||
@@ -615,6 +625,14 @@ export const settingsGroups: SettingSection[] = [
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "notesnook-circle",
|
||||
name: strings.notesnookCircle(),
|
||||
icon: "circle-outline",
|
||||
type: "screen",
|
||||
description: strings.notesnookCircleDesc(),
|
||||
component: "notesnook-circle"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -43,6 +43,7 @@ import { planToDisplayName } from "../../utils/constants";
|
||||
import { AppFontSize } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { SectionItem } from "./section-item";
|
||||
import SettingsService from "../../services/settings";
|
||||
|
||||
export const getTimeLeft = (t2) => {
|
||||
let daysRemaining = dayjs(t2).diff(dayjs(), "days");
|
||||
@@ -339,11 +340,13 @@ const SettingsUserSection = ({ item }) => {
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
|
||||
{(user.subscription?.provider === SubscriptionProvider.PADDLE ||
|
||||
{((user.subscription?.provider ===
|
||||
SubscriptionProvider.PADDLE ||
|
||||
user.subscription?.provider ===
|
||||
SubscriptionProvider.STREETWRITERS ||
|
||||
!isCurrentPlatform) &&
|
||||
PremiumService.get() ? null : (
|
||||
PremiumService.get()) ||
|
||||
SettingsService.getProperty("serverUrls") ? null : (
|
||||
<Button
|
||||
title={
|
||||
user.subscription?.plan !== SubscriptionPlan.FREE
|
||||
|
||||
@@ -580,7 +580,7 @@ function openSettingsDialog(context: string) {
|
||||
positivePress:
|
||||
Platform.OS === "ios"
|
||||
? undefined
|
||||
: () => {
|
||||
: async () => {
|
||||
resolve(true);
|
||||
},
|
||||
onClose: () => {
|
||||
|
||||
@@ -58,6 +58,7 @@ async function setPremiumStatus() {
|
||||
|
||||
async function loadProductsAndSubs() {
|
||||
try {
|
||||
if (Config.GITHUB_RELEASE === "true") throw new Error("Github release");
|
||||
if (!subs || subs.length === 0) {
|
||||
subs = await RNIap.getSubscriptions({
|
||||
skus: itemSkus
|
||||
|
||||
@@ -17,8 +17,15 @@ 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 { isFeatureAvailable } from "@notesnook/common";
|
||||
import { Profile, User } from "@notesnook/core";
|
||||
import create, { State } from "zustand";
|
||||
import SettingsService from "../services/settings";
|
||||
import { presentDialog } from "../components/dialog/functions";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { eSendEvent } from "../services/event-manager";
|
||||
import { eCloseSimpleDialog } from "../utils/events";
|
||||
import Navigation from "../services/navigation";
|
||||
|
||||
export enum SyncStatus {
|
||||
Passed,
|
||||
@@ -57,6 +64,28 @@ export const useUserStore = create<UserStore>((set) => ({
|
||||
setLastSynced: (lastSynced) => set({ lastSynced: lastSynced }),
|
||||
lockApp: (appLocked) => {
|
||||
set({ appLocked });
|
||||
if (!appLocked) {
|
||||
isFeatureAvailable("appLock").then((feature) => {
|
||||
if (!feature.isAllowed) {
|
||||
SettingsService.setProperty("appLockEnabled", false);
|
||||
setTimeout(() => {
|
||||
presentDialog({
|
||||
title: "App Lock Disabled",
|
||||
paragraph: feature?.error,
|
||||
positiveText: strings.upgrade(),
|
||||
negativeText: strings.cancel(),
|
||||
positivePress: async () => {
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
if (SettingsService.getProperty("serverUrls")) return;
|
||||
Navigation.navigate("PayWall", {
|
||||
context: "logged-in"
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
lastSyncStatus: SyncStatus.Never,
|
||||
disableAppLockRequests: false,
|
||||
|
||||
@@ -71,6 +71,7 @@ export function planToDisplayName(plan: SubscriptionPlan): string {
|
||||
return strings.freePlan();
|
||||
case SubscriptionPlan.ESSENTIAL:
|
||||
return strings.essentialPlan();
|
||||
case SubscriptionPlan.LEGACY_PRO:
|
||||
case SubscriptionPlan.PRO:
|
||||
return strings.proPlan();
|
||||
case SubscriptionPlan.BELIEVER:
|
||||
|
||||
@@ -33,6 +33,7 @@ import { useNotebookStore } from "../stores/use-notebook-store";
|
||||
import { useRelationStore } from "../stores/use-relation-store";
|
||||
import { useTagStore } from "../stores/use-tag-store";
|
||||
import { eUpdateNoteInEditor } from "./events";
|
||||
import { unlockVault } from "./unlock-vault";
|
||||
|
||||
export function getObfuscatedEmail(email: string) {
|
||||
if (!email) return "";
|
||||
@@ -56,7 +57,7 @@ function confirmDeleteAllNotes(
|
||||
title: strings.doActions.delete.notebook(items.length),
|
||||
positiveText: strings.delete(),
|
||||
negativeText: strings.cancel(),
|
||||
positivePress: (_inputValue, value) => {
|
||||
positivePress: async (_inputValue, value) => {
|
||||
setTimeout(() => {
|
||||
resolve({ delete: true, deleteNotes: value });
|
||||
});
|
||||
@@ -98,6 +99,30 @@ export const deleteItems = async (
|
||||
await db.reminders.remove(...itemIds);
|
||||
useRelationStore.getState().update();
|
||||
} else if (type === "note") {
|
||||
let someNotesLocked = false;
|
||||
|
||||
for (const id of itemIds) {
|
||||
if (
|
||||
await db.vaults.itemExists({
|
||||
id: id,
|
||||
type: "note"
|
||||
})
|
||||
) {
|
||||
someNotesLocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (someNotesLocked) {
|
||||
const unlocked = await unlockVault({
|
||||
title: strings.unlockVault(),
|
||||
paragraph: strings.unlockVaultDesc(),
|
||||
context: "global",
|
||||
requirePassword: true
|
||||
});
|
||||
if (!unlocked) return;
|
||||
}
|
||||
|
||||
for (const id of itemIds) {
|
||||
if (db.monographs.isPublished(id)) {
|
||||
ToastManager.show({
|
||||
@@ -108,6 +133,7 @@ export const deleteItems = async (
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
await db.notes.moveToTrash(id);
|
||||
|
||||
eSendEvent(
|
||||
@@ -157,7 +183,7 @@ export const deleteItems = async (
|
||||
heading: message,
|
||||
type: "success",
|
||||
func: async () => {
|
||||
if ((await db.trash.restore(...deletedIds)) === false) return;
|
||||
await db.trash.restore(...deletedIds);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useMenuStore.getState().setMenuPins();
|
||||
useMenuStore.getState().setColorNotes();
|
||||
|
||||
@@ -27,18 +27,20 @@ let unlockPromise: Promise<any> | undefined = undefined;
|
||||
export async function unlockVault({
|
||||
context,
|
||||
title,
|
||||
paragraph
|
||||
paragraph,
|
||||
requirePassword
|
||||
}: {
|
||||
context?: string;
|
||||
title: string;
|
||||
paragraph: string;
|
||||
requirePassword?: boolean;
|
||||
}) {
|
||||
if (unlockPromise) {
|
||||
return unlockPromise;
|
||||
}
|
||||
unlockPromise = new Promise(async (resolve) => {
|
||||
const result = await (async () => {
|
||||
if (db.vault.unlocked) return true;
|
||||
if (db.vault.unlocked && !requirePassword) return true;
|
||||
const biometry = await BiometricService.isBiometryAvailable();
|
||||
const fingerprint = await BiometricService.hasInternetCredentials();
|
||||
if (biometry && fingerprint) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { execSync } from "child_process";
|
||||
|
||||
//@ts-ignore
|
||||
import { pathExists, ensureDir } from "fs-extra";
|
||||
|
||||
import { resolveConfig } from "detox/internals";
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
/*
|
||||
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 { notesnook } from "../test.ids";
|
||||
import { TestBuilder } from "./utils";
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ describe("Search", () => {
|
||||
.typeTextById("search-input", "Test")
|
||||
.wait(1000)
|
||||
.isVisibleByText("1")
|
||||
.waitAndTapById("clear-search")
|
||||
.wait(2000)
|
||||
.isNotVisibleByText("1")
|
||||
.run();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { expect as jestExpect } from "@jest/globals";
|
||||
import { device as _device, expect } from "detox";
|
||||
import { readFileSync } from "fs";
|
||||
//@ts-ignore
|
||||
import { toMatchImageSnapshot } from "jest-image-snapshot";
|
||||
import type { RouteName } from "../../app/stores/use-navigation-store";
|
||||
import { notesnook } from "../test.ids";
|
||||
|
||||
@@ -124,7 +124,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3071
|
||||
versionCode 3076
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="com.streetwriters.notesnook" />
|
||||
<data android:scheme="notesnook" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
@@ -33,7 +33,7 @@ public class NotePreviewWidget extends AppWidgetProvider {
|
||||
intent.putExtra(OpenNoteId, note.getId());
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.putExtra(RCTNNativeModule.IntentType, "OpenNote");
|
||||
intent.setData(Uri.parse("https://notesnook.com/open_note?id=" + note.getId()));
|
||||
intent.setData(Uri.parse("https://app.notesnook.com/open_note?id=" + note.getId()));
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, getActivityOptionsBundle());
|
||||
views.setOnClickPendingIntent(R.id.open_note, pendingIntent);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class ReminderRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactor
|
||||
final Intent fillInIntent = new Intent();
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putString(ReminderViewsService.OpenReminderId, reminder.getId());
|
||||
fillInIntent.setData(Uri.parse("https://notesnook.com/open_reminder?id=" + reminder.getId()));
|
||||
fillInIntent.setData(Uri.parse("https://app.notesnook.com/open_reminder?id=" + reminder.getId()));
|
||||
fillInIntent.putExtra(RCTNNativeModule.IntentType, "OpenReminder");
|
||||
fillInIntent.putExtras(extras);
|
||||
views.setOnClickFillInIntent(R.id.reminder_item_btn, fillInIntent);
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ReminderWidgetProvider extends AppWidgetProvider {
|
||||
new_reminder_intent.putExtra(NewReminder, NewReminder);
|
||||
new_reminder_intent.setAction(Intent.ACTION_VIEW);
|
||||
new_reminder_intent.putExtra(RCTNNativeModule.IntentType, "NewReminder");
|
||||
new_reminder_intent.setData(Uri.parse("https://notesnook.com/new_reminder"));
|
||||
new_reminder_intent.setData(Uri.parse("https://app.notesnook.com/new_reminder"));
|
||||
PendingIntent pendingIntent2 = PendingIntent.getActivity(context, appWidgetId, new_reminder_intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, getActivityOptionsBundle());
|
||||
views.setOnClickPendingIntent(R.id.add_button, pendingIntent2);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="10dp"
|
||||
android:id="@+id/reminder_item_btn">
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="10dp"
|
||||
android:id="@+id/reminder_item_btn">
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
android:text="Upcoming Reminders"/>
|
||||
|
||||
<ImageButton
|
||||
android:layout_width="30dp"
|
||||
android:layout_width="35dp"
|
||||
android:id="@+id/add_button"
|
||||
android:layout_height="30dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/ic_newnote" />
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
- We have launches new pricing plans, Essential, Pro and Believer
|
||||
- Free users can now upload attachments and create private vault
|
||||
- Minor bug fixes and improvements
|
||||
- Bug fixes and minor improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -56,9 +56,10 @@
|
||||
<string>group.org.streetwriters.notesnook</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
<string>OpenSans-SemiBold.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>Inter-Bold.ttf</string>
|
||||
<string>Inter-SemiBold.ttf</string>
|
||||
<string>Inter-Regular.ttf</string>
|
||||
<string>Inter-Italic.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
||||
@@ -17,14 +17,15 @@
|
||||
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 */; };
|
||||
6517B7C22B6838EB0079FF37 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */; };
|
||||
6517B7C32B6838EB0079FF37 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */; };
|
||||
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */; };
|
||||
656835812BB29A9800144BAB /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 656835802BB29A8300144BAB /* OpenSans-Italic.ttf */; };
|
||||
6569927F2C5754F10041CD41 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */; };
|
||||
656992802C5754F10041CD41 /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */; };
|
||||
656992812C5754F10041CD41 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */; };
|
||||
653F4E082EA3887C009A42A2 /* Inter-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */; };
|
||||
653F4E092EA3887C009A42A2 /* Inter-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */; };
|
||||
653F4E0A2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */; };
|
||||
653F4E0B2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */; };
|
||||
653F4E0C2EA3887C009A42A2 /* Inter-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */; };
|
||||
653F4E0D2EA3887C009A42A2 /* Inter-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */; };
|
||||
653F4E0E2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */; };
|
||||
653F4E0F2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */; };
|
||||
6593E4A3281C345400492C50 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6593E4A2281C345400492C50 /* AppDelegate.mm */; };
|
||||
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */ = {isa = PBXBuildFile; fileRef = 659BE46625E11A5100E05671 /* notesnook-text.png */; };
|
||||
65AA857925E6DDEC00772A01 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65AA857825E6DDEC00772A01 /* WidgetKit.framework */; };
|
||||
@@ -117,12 +118,12 @@
|
||||
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>"; };
|
||||
6515C42E2580AA2F00E83E39 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Regular.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Regular.ttf"; sourceTree = "<group>"; };
|
||||
6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-SemiBold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-SemiBold.ttf"; sourceTree = "<group>"; };
|
||||
6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Bold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Bold.ttf"; sourceTree = "<group>"; };
|
||||
6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = Notesnook/BootSplash.storyboard; sourceTree = "<group>"; };
|
||||
6529D2B0257B4A2900B49BC3 /* NotesnookDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = NotesnookDebug.entitlements; path = Notesnook/NotesnookDebug.entitlements; sourceTree = "<group>"; };
|
||||
656835802BB29A8300144BAB /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "OpenSans-Italic.ttf"; path = "../../../../packages/editor-mobile/public/fonts/OpenSans-Italic.ttf"; sourceTree = "<group>"; };
|
||||
653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Bold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Bold.ttf"; sourceTree = SOURCE_ROOT; };
|
||||
653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Italic.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Italic.ttf"; sourceTree = SOURCE_ROOT; };
|
||||
653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-Regular.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-Regular.ttf"; sourceTree = SOURCE_ROOT; };
|
||||
653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Inter-SemiBold.ttf"; path = "../../../../packages/editor-mobile/public/fonts/Inter-SemiBold.ttf"; sourceTree = SOURCE_ROOT; };
|
||||
6593E4A2281C345400492C50 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Notesnook/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
659BE46625E11A5100E05671 /* notesnook-text.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "notesnook-text.png"; path = "Notesnook/Images.xcassets/notesnook-text.png"; sourceTree = "<group>"; };
|
||||
65A7F34F255689AD00699170 /* Notesnook.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Notesnook.entitlements; path = Notesnook/Notesnook.entitlements; sourceTree = "<group>"; };
|
||||
@@ -303,10 +304,10 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
656835802BB29A8300144BAB /* OpenSans-Italic.ttf */,
|
||||
6517B7C02B6838EB0079FF37 /* OpenSans-Bold.ttf */,
|
||||
6517B7BE2B6838EB0079FF37 /* OpenSans-Regular.ttf */,
|
||||
6517B7BF2B6838EB0079FF37 /* OpenSans-SemiBold.ttf */,
|
||||
653F4E042EA3887C009A42A2 /* Inter-Bold.ttf */,
|
||||
653F4E052EA3887C009A42A2 /* Inter-Italic.ttf */,
|
||||
653F4E062EA3887C009A42A2 /* Inter-Regular.ttf */,
|
||||
653F4E072EA3887C009A42A2 /* Inter-SemiBold.ttf */,
|
||||
65C400DD2A80B68D00AA3DF5 /* MaterialCommunityIcons.ttf */,
|
||||
65C149862A61151B005C40F1 /* extension.bundle */,
|
||||
6510E6D62877215700DACAA9 /* build.bundle */,
|
||||
@@ -555,15 +556,15 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
656835812BB29A9800144BAB /* OpenSans-Italic.ttf in Resources */,
|
||||
65C400DE2A80B68D00AA3DF5 /* MaterialCommunityIcons.ttf in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
6517B7C32B6838EB0079FF37 /* OpenSans-Bold.ttf in Resources */,
|
||||
6517B7C22B6838EB0079FF37 /* OpenSans-SemiBold.ttf in Resources */,
|
||||
6529A13E279BC4C70048D4A8 /* BootSplash.storyboard in Resources */,
|
||||
6510E6D72877215700DACAA9 /* build.bundle in Resources */,
|
||||
6517B7C12B6838EB0079FF37 /* OpenSans-Regular.ttf in Resources */,
|
||||
659BE46725E11A5100E05671 /* notesnook-text.png in Resources */,
|
||||
653F4E0C2EA3887C009A42A2 /* Inter-Bold.ttf in Resources */,
|
||||
653F4E0D2EA3887C009A42A2 /* Inter-Italic.ttf in Resources */,
|
||||
653F4E0E2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */,
|
||||
653F4E0F2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */,
|
||||
E7F9D56665C2F19F4A97BF49 /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -596,10 +597,11 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6569927F2C5754F10041CD41 /* OpenSans-Bold.ttf in Resources */,
|
||||
656992802C5754F10041CD41 /* OpenSans-Regular.ttf in Resources */,
|
||||
656992812C5754F10041CD41 /* OpenSans-SemiBold.ttf in Resources */,
|
||||
65C400DF2A80B6B600AA3DF5 /* MaterialCommunityIcons.ttf in Resources */,
|
||||
653F4E082EA3887C009A42A2 /* Inter-Bold.ttf in Resources */,
|
||||
653F4E092EA3887C009A42A2 /* Inter-Italic.ttf in Resources */,
|
||||
653F4E0A2EA3887C009A42A2 /* Inter-SemiBold.ttf in Resources */,
|
||||
653F4E0B2EA3887C009A42A2 /* Inter-Regular.ttf in Resources */,
|
||||
65C149872A61151B005C40F1 /* extension.bundle in Resources */,
|
||||
65B5014725A672B200E2D264 /* MainInterface.storyboard in Resources */,
|
||||
);
|
||||
@@ -652,6 +654,7 @@
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook/Pods-Notesnook-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
|
||||
@@ -663,6 +666,7 @@
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
|
||||
@@ -819,6 +823,7 @@
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Notesnook-NotesnookTests/Pods-Notesnook-NotesnookTests-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
|
||||
@@ -830,6 +835,7 @@
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
|
||||
@@ -1089,7 +1095,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1163,7 +1169,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1194,7 +1200,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1268,7 +1274,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1427,7 +1433,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1439,7 +1445,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1470,7 +1476,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1483,7 +1489,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1513,7 +1519,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1587,14 +1593,14 @@
|
||||
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
|
||||
);
|
||||
INFOPLIST_FILE = "Make Note/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1625,7 +1631,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2150;
|
||||
CURRENT_PROJECT_VERSION = 2155;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1700,14 +1706,14 @@
|
||||
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
|
||||
);
|
||||
INFOPLIST_FILE = "Make Note/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
|
||||
MARKETING_VERSION = 3.3.2;
|
||||
MARKETING_VERSION = 3.3.7;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "1"
|
||||
BundleIdentifier = "com.apple.mobilesafari"
|
||||
RemotePath = "/Applications/MobileSafari.app">
|
||||
RemotePath = "/Library/Developer/CoreSimulator/Volumes/iOS_22G86/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.6.simruntime/Contents/Resources/RuntimeRoot/Applications/MobileSafari.app">
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
@@ -92,6 +92,7 @@
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<!-- Do not change NSAllowsArbitraryLoads to true, or you will risk app rejection! -->
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
@@ -89,9 +88,10 @@
|
||||
<string>group.org.streetwriters.notesnook</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Italic.ttf</string>
|
||||
<string>OpenSans-SemiBold.ttf</string>
|
||||
<string>OpenSans-Regular.ttf</string>
|
||||
<string>Inter-Italic.ttf</string>
|
||||
<string>Inter-SemiBold.ttf</string>
|
||||
<string>Inter-Regular.ttf</string>
|
||||
<string>Inter-Bold.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
</array>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>3B52.1</string>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
|
||||
@@ -1273,11 +1273,11 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-keep-awake (1.3.1):
|
||||
- React-Core
|
||||
- react-native-mmkv-storage (0.11.2):
|
||||
- react-native-mmkv-storage (12.0.0):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- MMKV (~> 1.3.9)
|
||||
- MMKV (~> 1.3.14)
|
||||
- RCT-Folly (= 2024.11.18.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
@@ -1372,7 +1372,7 @@ PODS:
|
||||
- react-native-screenguard (1.0.0):
|
||||
- React-Core
|
||||
- SDWebImage (~> 5.11.1)
|
||||
- react-native-share-extension (2.9.0):
|
||||
- react-native-share-extension (2.9.5):
|
||||
- React
|
||||
- react-native-sodium (1.6.5):
|
||||
- React
|
||||
@@ -1770,15 +1770,53 @@ PODS:
|
||||
- Yoga
|
||||
- RNIap (12.16.2):
|
||||
- React-Core
|
||||
- RNImageCropPicker (0.40.2):
|
||||
- RNImageCropPicker (0.51.1):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2024.11.18.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-RCTImage
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.40.2)
|
||||
- TOCropViewController
|
||||
- RNImageCropPicker/QBImagePickerController (0.40.2):
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.51.1)
|
||||
- TOCropViewController (~> 2.8.0)
|
||||
- Yoga
|
||||
- RNImageCropPicker/QBImagePickerController (0.51.1):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- hermes-engine
|
||||
- RCT-Folly (= 2024.11.18.00)
|
||||
- RCTRequired
|
||||
- RCTTypeSafety
|
||||
- React-Core
|
||||
- React-debug
|
||||
- React-Fabric
|
||||
- React-featureflags
|
||||
- React-graphics
|
||||
- React-ImageManager
|
||||
- React-NativeModulesApple
|
||||
- React-RCTFabric
|
||||
- React-RCTImage
|
||||
- TOCropViewController
|
||||
- React-rendererdebug
|
||||
- React-utils
|
||||
- ReactCodegen
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- TOCropViewController (~> 2.8.0)
|
||||
- Yoga
|
||||
- RNKeychain (4.0.5):
|
||||
- React
|
||||
- RNNotifee (7.4.9):
|
||||
@@ -1975,7 +2013,7 @@ PODS:
|
||||
- SwiftyRSA (1.7.0):
|
||||
- SwiftyRSA/ObjC (= 1.7.0)
|
||||
- SwiftyRSA/ObjC (1.7.0)
|
||||
- TOCropViewController (2.7.4)
|
||||
- TOCropViewController (2.8.0)
|
||||
- toolbar-android (0.2.1):
|
||||
- React
|
||||
- Yoga (0.0.0)
|
||||
@@ -2425,7 +2463,7 @@ SPEC CHECKSUMS:
|
||||
react-native-image-resizer: 24c5d06fae2176dc0caed4b6396e02befb44064a
|
||||
react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400
|
||||
react-native-keep-awake: 03b74eebe4f2bb5e8478fc8f420651a92463b6f8
|
||||
react-native-mmkv-storage: 51c33c6f6678d67061059cce8189a57c3e47192e
|
||||
react-native-mmkv-storage: 935d661dc3913a41be70d041aa3ff860d6aa4873
|
||||
react-native-netinfo: 66c9ac0d0ae92a57a9ed99ab8a75429740700c73
|
||||
react-native-notification-sounds: ce106d58df0dd384bccbd2e84fb53accab7cc068
|
||||
react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa
|
||||
@@ -2434,7 +2472,7 @@ SPEC CHECKSUMS:
|
||||
react-native-quick-sqlite: 1bfc7f1e9acbe9a5aa5c4cc81712e9bde3ab7672
|
||||
react-native-safe-area-context: 9d72abf6d8473da73033b597090a80b709c0b2f1
|
||||
react-native-screenguard: 82437eeb0086a90b5e5d7e54130bb04fb406373e
|
||||
react-native-share-extension: bcb7e466390a9e50c742f4b1019d6f181aedd7ad
|
||||
react-native-share-extension: fdc6aaab51591a2d445df239c446aaa3a99658ec
|
||||
react-native-sodium: 285eec063e4232cb67347ef6a434b85e588d38cb
|
||||
react-native-theme-switch-animation: d90fe2de0d9e87a63cd6235d98cba6e7054e9a10
|
||||
react-native-webview: 079eca50edf657503318b66687dadfb903731aa8
|
||||
@@ -2479,7 +2517,7 @@ SPEC CHECKSUMS:
|
||||
RNFlashList: ff5a0b3113c4cda0eaf4b94df8572ccad3c40fd5
|
||||
RNGestureHandler: 92e89a04cd0d1c77f383a55d14c15e7f423f4c00
|
||||
RNIap: f94647b3a3dbd5fa08ad7ed847eb588aa5fe95fe
|
||||
RNImageCropPicker: 30d770b383d84e1067d82ea7b5ed4fff851bbbb2
|
||||
RNImageCropPicker: aa81bda9f887e20542b569938cde5ce50a4ec404
|
||||
RNKeychain: ffd0513e676445c637410b47249460cbf56bc9cb
|
||||
RNNotifee: dabf3cdd7bfd9340bb84358cc78f635af4bc80e2
|
||||
RNPrivacySnapshot: ccad3a548338c2f526bb7b1789af3fb0618b7d1d
|
||||
@@ -2495,7 +2533,7 @@ SPEC CHECKSUMS:
|
||||
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
TOCropViewController: 797deaf39c90e6e9ddd848d88817f6b9a8a09888
|
||||
toolbar-android: c426ed5bd3dcccfed20fd79533efc0d1ae0ef018
|
||||
Yoga: 31a098f74c16780569aebd614a0f37a907de0189
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -21,6 +21,7 @@
|
||||
"@react-navigation/native": "^6.0.10",
|
||||
"@react-navigation/native-stack": "6.6.2",
|
||||
"@sayem314/react-native-keep-awake": "^1.3.1",
|
||||
"react-native-image-crop-picker": "^0.51.1",
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.77.2",
|
||||
"react-native-actions-shortcuts": "^1.0.1",
|
||||
@@ -48,7 +49,7 @@
|
||||
"react-native-navigation-bar-color": "2.0.2",
|
||||
"react-native-notification-sounds": "0.5.5",
|
||||
"@shopify/flash-list": "^1.8.0",
|
||||
"react-native-mmkv-storage": "^0.11.2",
|
||||
"react-native-mmkv-storage": "^12.0.0",
|
||||
"react-native-quick-sqlite": "^8.2.7",
|
||||
"react-native-svg": "^15.12.0",
|
||||
"react-native-webview": "^13.13.5",
|
||||
@@ -61,7 +62,6 @@
|
||||
"react-native-zip-archive": "6.0.9",
|
||||
"react-native-theme-switch-animation": "^0.6.0",
|
||||
"@ammarahmed/react-native-background-fetch": "^4.2.2",
|
||||
"react-native-image-crop-picker": "^0.40.2",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-screenguard": "^1.0.0",
|
||||
"@formatjs/intl-locale": "4.0.0",
|
||||
@@ -72,10 +72,10 @@
|
||||
"react-native-begin-background-task": "github:blockfirm/react-native-begin-background-task",
|
||||
"react-native-privacy-snapshot": "github:standardnotes/react-native-privacy-snapshot",
|
||||
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.0",
|
||||
"react-native-pager-view": "^6.5.1",
|
||||
"react-native-tab-view": "^4.0.2",
|
||||
"react-native-orientation-locker": "^1.7.0"
|
||||
"react-native-orientation-locker": "^1.7.0",
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.1",
|
||||
|
||||
46
apps/mobile/package-lock.json
generated
46
apps/mobile/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.12",
|
||||
"version": "3.3.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.12",
|
||||
"version": "3.3.7",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -3730,7 +3730,7 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/core": "^2.2.2",
|
||||
"@notesnook-importer/core": "^2.2.5",
|
||||
"@notesnook/common": "file:../common",
|
||||
"@notesnook/intl": "file:../intl",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
@@ -3797,6 +3797,7 @@
|
||||
"happy-dom": "16.0.1",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"nodemon": "^3.1.7",
|
||||
"prismjs": "^1.30.0",
|
||||
"prosemirror-test-builder": "^1.1.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
@@ -28296,6 +28297,7 @@
|
||||
"pathe": "1.1.2",
|
||||
"phone": "^3.1.14",
|
||||
"qclone": "^1.2.0",
|
||||
"react-async-hook": "^4.0.0",
|
||||
"react-native-actions-sheet": "0.9.7",
|
||||
"react-native-check-version": "^1.3.0",
|
||||
"react-native-drax": "^0.10.2",
|
||||
@@ -28324,7 +28326,7 @@
|
||||
"@ammarahmed/react-native-background-fetch": "^4.2.2",
|
||||
"@ammarahmed/react-native-eventsource": "1.1.0",
|
||||
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.0",
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.5",
|
||||
"@ammarahmed/react-native-sodium": "^1.6.5",
|
||||
"@bam.tech/react-native-image-resizer": "3.0.11",
|
||||
"@callstack/repack": "~5.1.2",
|
||||
@@ -28359,10 +28361,10 @@
|
||||
"react-native-gzip": "1.1.0",
|
||||
"react-native-html-to-pdf-lite": "^0.9.1",
|
||||
"react-native-iap": "12.16.2",
|
||||
"react-native-image-crop-picker": "^0.40.2",
|
||||
"react-native-image-crop-picker": "^0.51.1",
|
||||
"react-native-in-app-review": "4.3.3",
|
||||
"react-native-keychain": "4.0.5",
|
||||
"react-native-mmkv-storage": "^0.11.2",
|
||||
"react-native-mmkv-storage": "^12.0.0",
|
||||
"react-native-modal-datetime-picker": "14.0.0",
|
||||
"react-native-navigation-bar-color": "2.0.2",
|
||||
"react-native-notification-sounds": "0.5.5",
|
||||
@@ -28470,9 +28472,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ammarahmed/react-native-share-extension": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.0.tgz",
|
||||
"integrity": "sha512-iEkpJQFZL5/WDPh7iRCLZREANgaaAHthDsPaAYT6sI4wieQcHZMBAnfRMwBEnC0BZ0WVxbQZdzJYez+dmwpr2g==",
|
||||
"version": "2.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.5.tgz",
|
||||
"integrity": "sha512-UTE8TSxkx+RFNgSJCCfD5FSdQ5IuMOsZzuuy0BVy46emRrpPw1fedJTtDbqyKrU8fwtKEIbzJWeQtjjRZlHxjQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-native": "^0.63.1"
|
||||
@@ -44133,6 +44135,19 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-async-hook": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-async-hook/-/react-async-hook-4.0.0.tgz",
|
||||
"integrity": "sha512-97lgjFkOcHCTYSrsKBpsXg3iVWM0LnzedB749iP76sb3/8Ouu4nHIkCLEOrQWHVYqrYxjF05NN6GHoXWFkB3Kw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8",
|
||||
"npm": ">=5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-devtools-core": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.2.tgz",
|
||||
@@ -44504,10 +44519,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-image-crop-picker": {
|
||||
"version": "0.40.2",
|
||||
"version": "0.51.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-crop-picker/-/react-native-image-crop-picker-0.51.1.tgz",
|
||||
"integrity": "sha512-GIFRyXJgv1dPceKd/hraK9q9V38v45rSg2ONR6RiSePcOJemkHpc/PMU86pq6lWPilDYHSxbZmea2pNMk85ayw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.40.0"
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-image-pan-zoom": {
|
||||
@@ -44575,9 +44593,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-mmkv-storage": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-mmkv-storage/-/react-native-mmkv-storage-0.11.2.tgz",
|
||||
"integrity": "sha512-/jbYNOUrwgVU09WyXDK6lFGXqBs+23oR9X37z3N68rwHNiXF5WDyXnT38dU2tF07ZlvmsobNHgdxgTu4kGQUKQ==",
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-mmkv-storage/-/react-native-mmkv-storage-12.0.0.tgz",
|
||||
"integrity": "sha512-sssZInILQBquytDDfjosjEdvevwMPk3fqQQjdjfnH362IcsBsApvtT8yJS406Mz9aJ6VhqVsZw/awltsUuPSYg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mmkv-link": "autolink/postlink/run.js"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.3.2",
|
||||
"version": "3.3.7",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -56,4 +56,4 @@
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.77.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
|
||||
index 5de0845..1b158d8 100644
|
||||
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
|
||||
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
|
||||
@@ -692,6 +692,7 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
|
||||
image.putString("mime", options.outMimeType);
|
||||
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
|
||||
index b9c494e..34ef800 100644
|
||||
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
|
||||
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/ImageCropPicker.java
|
||||
@@ -679,6 +679,7 @@ class ImageCropPicker implements ActivityEventListener {
|
||||
image.putInt("size", (int) new File(compressedImagePath).length());
|
||||
image.putString("modificationDate", String.valueOf(modificationDate));
|
||||
image.putString("filename", new File(path).getName());
|
||||
+ image.putString("sourceURL", path);
|
||||
|
||||
if (includeBase64) {
|
||||
image.putString("data", getBase64StringFromFile(compressedImagePath));
|
||||
diff --git a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
|
||||
index 9f20973..5e14da8 100644
|
||||
--- a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
|
||||
+++ b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.m
|
||||
@@ -595,8 +595,10 @@ - (void)qb_imagePickerController:
|
||||
NSString *mimeType = [self determineMimeTypeFromImageData:imageData];
|
||||
diff --git a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
|
||||
index 354ad09..622f779 100644
|
||||
--- a/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
|
||||
+++ b/node_modules/react-native-image-crop-picker/ios/src/ImageCropPicker.mm
|
||||
@@ -603,7 +603,10 @@ - (void)qb_imagePickerController:(QBImagePickerController *)imagePickerControlle
|
||||
Boolean isKnownMimeType = [mimeType length] > 0;
|
||||
|
||||
+ Boolean isHeicOrHeif = [mimeType isEqualToString:@"image/heic"] || [mimeType isEqualToString:@"image/heif"];
|
||||
+
|
||||
ImageResult *imageResult = [[ImageResult alloc] init];
|
||||
- if (isLossless && useOriginalWidth && useOriginalHeight && isKnownMimeType && !forceJpg) {
|
||||
+
|
||||
+ Boolean isHeicOrHeif = [mimeType isEqualToString:@"image/heic"] || [mimeType isEqualToString:@"image/heif"];
|
||||
+
|
||||
+ if (isLossless && useOriginalWidth && useOriginalHeight && isKnownMimeType && !forceJpg && !isHeicOrHeif) {
|
||||
// Use original, unmodified image
|
||||
imageResult.data = imageData;
|
||||
169
apps/mobile/patches/react-native-keychain+4.0.5.patch
Normal file
169
apps/mobile/patches/react-native-keychain+4.0.5.patch
Normal file
@@ -0,0 +1,169 @@
|
||||
diff --git a/node_modules/react-native-keychain/android/build.gradle b/node_modules/react-native-keychain/android/build.gradle
|
||||
index bd2fe04..53ce4b1 100755
|
||||
--- a/node_modules/react-native-keychain/android/build.gradle
|
||||
+++ b/node_modules/react-native-keychain/android/build.gradle
|
||||
@@ -51,5 +51,4 @@ dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'com.facebook.react:react-native:+' // From node_modules
|
||||
implementation 'androidx.annotation:annotation:1.1.0'
|
||||
- implementation 'com.facebook.conceal:conceal:1.1.3@aar'
|
||||
}
|
||||
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
index 61d061e..be49f8a 100644
|
||||
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
+++ b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
@@ -15,7 +15,6 @@ import com.oblador.keychain.PrefsStorage.ResultSet;
|
||||
import com.oblador.keychain.cipherStorage.CipherStorage;
|
||||
import com.oblador.keychain.cipherStorage.CipherStorage.DecryptionResult;
|
||||
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
|
||||
-import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
|
||||
import com.oblador.keychain.cipherStorage.CipherStorageKeystoreAESCBC;
|
||||
import com.oblador.keychain.exceptions.CryptoFailedException;
|
||||
import com.oblador.keychain.exceptions.EmptyParameterException;
|
||||
@@ -48,7 +47,6 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
super(reactContext);
|
||||
prefsStorage = new PrefsStorage(reactContext);
|
||||
|
||||
- addCipherStorageToMap(new CipherStorageFacebookConceal(reactContext));
|
||||
addCipherStorageToMap(new CipherStorageKeystoreAESCBC());
|
||||
}
|
||||
|
||||
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
|
||||
index 99448b1..792c24c 100644
|
||||
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
|
||||
+++ b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/PrefsStorage.java
|
||||
@@ -7,7 +7,6 @@ import android.util.Base64;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
|
||||
-import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
|
||||
|
||||
public class PrefsStorage {
|
||||
public static final String KEYCHAIN_DATA = "RN_KEYCHAIN";
|
||||
@@ -35,10 +34,6 @@ public class PrefsStorage {
|
||||
byte[] bytesForPassword = getBytesForPassword(service);
|
||||
String cipherStorageName = getCipherStorageName(service);
|
||||
if (bytesForUsername != null && bytesForPassword != null) {
|
||||
- if (cipherStorageName == null) {
|
||||
- // If the CipherStorage name is not found, we assume it is because the entry was written by an older version of this library. The older version used Facebook Conceal, so we default to that.
|
||||
- cipherStorageName = CipherStorageFacebookConceal.CIPHER_STORAGE_NAME;
|
||||
- }
|
||||
return new ResultSet(cipherStorageName, bytesForUsername, bytesForPassword);
|
||||
}
|
||||
return null;
|
||||
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java
|
||||
deleted file mode 100644
|
||||
index 3162f99..0000000
|
||||
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageFacebookConceal.java
|
||||
+++ /dev/null
|
||||
@@ -1,110 +0,0 @@
|
||||
-package com.oblador.keychain.cipherStorage;
|
||||
-
|
||||
-import android.os.Build;
|
||||
-import androidx.annotation.NonNull;
|
||||
-
|
||||
-import com.facebook.android.crypto.keychain.AndroidConceal;
|
||||
-import com.facebook.android.crypto.keychain.SharedPrefsBackedKeyChain;
|
||||
-import com.facebook.crypto.Crypto;
|
||||
-import com.facebook.crypto.CryptoConfig;
|
||||
-import com.facebook.crypto.Entity;
|
||||
-import com.facebook.crypto.keychain.KeyChain;
|
||||
-import com.facebook.react.bridge.ReactApplicationContext;
|
||||
-import com.oblador.keychain.SecurityLevel;
|
||||
-import com.oblador.keychain.exceptions.CryptoFailedException;
|
||||
-
|
||||
-import java.nio.charset.Charset;
|
||||
-
|
||||
-public class CipherStorageFacebookConceal implements CipherStorage {
|
||||
- public static final String CIPHER_STORAGE_NAME = "FacebookConceal";
|
||||
- public static final String KEYCHAIN_DATA = "RN_KEYCHAIN";
|
||||
- private final Crypto crypto;
|
||||
-
|
||||
- public CipherStorageFacebookConceal(ReactApplicationContext reactContext) {
|
||||
- KeyChain keyChain = new SharedPrefsBackedKeyChain(reactContext, CryptoConfig.KEY_256);
|
||||
- this.crypto = AndroidConceal.get().createDefaultCrypto(keyChain);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public String getCipherStorageName() {
|
||||
- return CIPHER_STORAGE_NAME;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public int getMinSupportedApiLevel() {
|
||||
- return Build.VERSION_CODES.JELLY_BEAN;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public SecurityLevel securityLevel() {
|
||||
- return SecurityLevel.ANY;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public boolean supportsSecureHardware() {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public EncryptionResult encrypt(@NonNull String service, @NonNull String username, @NonNull String password, SecurityLevel level) throws CryptoFailedException {
|
||||
-
|
||||
- if (!this.securityLevel().satisfiesSafetyThreshold(level)) {
|
||||
- throw new CryptoFailedException(String.format("Insufficient security level (wants %s; got %s)", level, this.securityLevel()));
|
||||
- }
|
||||
-
|
||||
- if (!crypto.isAvailable()) {
|
||||
- throw new CryptoFailedException("Crypto is missing");
|
||||
- }
|
||||
- Entity usernameEntity = createUsernameEntity(service);
|
||||
- Entity passwordEntity = createPasswordEntity(service);
|
||||
-
|
||||
- try {
|
||||
- byte[] encryptedUsername = crypto.encrypt(username.getBytes(Charset.forName("UTF-8")), usernameEntity);
|
||||
- byte[] encryptedPassword = crypto.encrypt(password.getBytes(Charset.forName("UTF-8")), passwordEntity);
|
||||
-
|
||||
- return new EncryptionResult(encryptedUsername, encryptedPassword, this);
|
||||
- } catch (Exception e) {
|
||||
- throw new CryptoFailedException("Encryption failed for service " + service, e);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public DecryptionResult decrypt(@NonNull String service, @NonNull byte[] username, @NonNull byte[] password) throws CryptoFailedException {
|
||||
- if (!crypto.isAvailable()) {
|
||||
- throw new CryptoFailedException("Crypto is missing");
|
||||
- }
|
||||
- Entity usernameEntity = createUsernameEntity(service);
|
||||
- Entity passwordEntity = createPasswordEntity(service);
|
||||
-
|
||||
- try {
|
||||
- byte[] decryptedUsername = crypto.decrypt(username, usernameEntity);
|
||||
- byte[] decryptedPassword = crypto.decrypt(password, passwordEntity);
|
||||
-
|
||||
- return new DecryptionResult(
|
||||
- new String(decryptedUsername, Charset.forName("UTF-8")),
|
||||
- new String(decryptedPassword, Charset.forName("UTF-8")),
|
||||
- SecurityLevel.ANY);
|
||||
- } catch (Exception e) {
|
||||
- throw new CryptoFailedException("Decryption failed for service " + service, e);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void removeKey(@NonNull String service) {
|
||||
- // Facebook Conceal stores only one key across all services, so we cannot delete the key (otherwise decryption will fail for encrypted data of other services).
|
||||
- }
|
||||
-
|
||||
- private Entity createUsernameEntity(String service) {
|
||||
- String prefix = getEntityPrefix(service);
|
||||
- return Entity.create(prefix + "user");
|
||||
- }
|
||||
-
|
||||
- private Entity createPasswordEntity(String service) {
|
||||
- String prefix = getEntityPrefix(service);
|
||||
- return Entity.create(prefix + "pass");
|
||||
- }
|
||||
-
|
||||
- private String getEntityPrefix(String service) {
|
||||
- return KEYCHAIN_DATA + ":" + service;
|
||||
- }
|
||||
-}
|
||||
@@ -1,14 +0,0 @@
|
||||
diff --git a/node_modules/react-native-mmkv-storage/android/build.gradle b/node_modules/react-native-mmkv-storage/android/build.gradle
|
||||
index abb696e..ba35baa 100644
|
||||
--- a/node_modules/react-native-mmkv-storage/android/build.gradle
|
||||
+++ b/node_modules/react-native-mmkv-storage/android/build.gradle
|
||||
@@ -98,7 +98,8 @@ android {
|
||||
cmake {
|
||||
cppFlags "-O3 -frtti -fexceptions -Wall -fstack-protector-all"
|
||||
arguments "-DANDROID_STL=c++_shared",
|
||||
- "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}"
|
||||
+ "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}",
|
||||
+ "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||
abiFilters (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,7 @@ const EXTRA_ICON_NAMES = [
|
||||
"chevron-down",
|
||||
"calendar",
|
||||
"minus-circle-outline",
|
||||
"circle-outline",
|
||||
"close-circle-outline",
|
||||
"qrcode",
|
||||
"text",
|
||||
|
||||
@@ -28,7 +28,6 @@ import RNFetchBlob from "react-native-blob-util";
|
||||
import WebView from "react-native-webview";
|
||||
import { Config } from "./store";
|
||||
import { db } from "../app/common/database";
|
||||
import { SUBSCRIPTION_STATUS } from "../app/utils/constants";
|
||||
|
||||
export const fetchHandle = createRef();
|
||||
export const HtmlLoadingWebViewAgent = React.memo(
|
||||
@@ -40,6 +39,7 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
const webview = useRef();
|
||||
const premium = useRef(false);
|
||||
const corsProxy = Config.corsProxy;
|
||||
const [isLoggedIn, setIsLoggedIn] = useState();
|
||||
|
||||
useImperativeHandle(
|
||||
fetchHandle,
|
||||
@@ -72,11 +72,8 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const user = await db.user.getUser();
|
||||
const subscriptionStatus =
|
||||
user?.subscription?.type || SUBSCRIPTION_STATUS.BASIC;
|
||||
premium.current =
|
||||
user && subscriptionStatus !== SUBSCRIPTION_STATUS.BASIC;
|
||||
|
||||
setIsLoggedIn(!!user);
|
||||
console.log("USER", !!user);
|
||||
const clipperPath =
|
||||
Platform.OS === "ios"
|
||||
? RNFetchBlob.fs.dirs.MainBundleDir +
|
||||
@@ -91,6 +88,7 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
.catch((e) => console.log(e));
|
||||
})();
|
||||
}, []);
|
||||
console.log(isLoggedIn);
|
||||
|
||||
return !source || !clipper ? null : (
|
||||
<WebView
|
||||
@@ -103,7 +101,8 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
height: 100,
|
||||
position: "absolute",
|
||||
opacity: 0,
|
||||
zIndex: -1
|
||||
zIndex: -1,
|
||||
pointerEvents: "none"
|
||||
}}
|
||||
useSharedProcessPool={false}
|
||||
pointerEvents="none"
|
||||
@@ -123,7 +122,11 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
console.log("Error handling webview message", e);
|
||||
}
|
||||
}}
|
||||
injectedJavaScriptBeforeContentLoaded={script(clipper, premium.current)}
|
||||
injectedJavaScriptBeforeContentLoaded={script(
|
||||
clipper,
|
||||
corsProxy,
|
||||
isLoggedIn
|
||||
)}
|
||||
onError={() => {
|
||||
console.log("Error loading page");
|
||||
loadHandler.current?.();
|
||||
@@ -137,9 +140,11 @@ export const HtmlLoadingWebViewAgent = React.memo(
|
||||
() => true
|
||||
);
|
||||
|
||||
const script = (clipper, pro) => `
|
||||
const script = (clipper, corsProxy, loggedIn) => `
|
||||
globalThis.module = {};
|
||||
${clipper}
|
||||
|
||||
|
||||
function postMessage(type, value) {
|
||||
if (window.ReactNativeWebView) {
|
||||
window.ReactNativeWebView.postMessage(
|
||||
@@ -158,10 +163,10 @@ function postMessage(type, value) {
|
||||
postMessage("error", globalThis.Clipper.clipPage);
|
||||
} else {
|
||||
globalThis.Clipper.clipPage(document,false, {
|
||||
images: ${pro},
|
||||
images: ${loggedIn ? "true" : "false"},
|
||||
inlineImages: false,
|
||||
styles: false,
|
||||
corsProxy: undefined
|
||||
corsProxy: ${corsProxy ? `"${corsProxy}"` : "undefined"}
|
||||
}).then(result => {
|
||||
postMessage("html", result);
|
||||
}).catch(e => {
|
||||
|
||||
@@ -19,7 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ShareExtension from "@ammarahmed/react-native-share-extension";
|
||||
import { getPreviewData } from "@flyerhq/react-native-link-preview";
|
||||
import { formatBytes } from "@notesnook/common";
|
||||
import {
|
||||
formatBytes,
|
||||
isFeatureAvailable,
|
||||
useIsFeatureAvailable
|
||||
} from "@notesnook/common";
|
||||
import { isImage } from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
@@ -119,6 +123,7 @@ const ShareView = () => {
|
||||
const noteTitle = useRef("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [loadingExtension, setLoadingExtension] = useState(true);
|
||||
const fullQualityImages = useIsFeatureAvailable("fullQualityImages");
|
||||
const [rawData, setRawData] = useState({
|
||||
type: null,
|
||||
value: null
|
||||
@@ -161,6 +166,12 @@ const ShareView = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!fullQualityImages?.isAllowed) {
|
||||
setCompress(true);
|
||||
}
|
||||
}, [fullQualityImages]);
|
||||
|
||||
const showLinkPreview = async (note, link) => {
|
||||
let _note = note;
|
||||
_note.content.data = makeHtmlFromUrl(link);
|
||||
@@ -223,14 +234,14 @@ const ShareView = () => {
|
||||
}
|
||||
} else {
|
||||
const user = await db.user.getUser();
|
||||
if (user && user.subscription.type !== 0) {
|
||||
if (
|
||||
(isImage(item.type) && item.size > IMAGE_SIZE_LIMIT) ||
|
||||
(!isImage(item.type) && item.size > FILE_SIZE_LIMIT)
|
||||
) {
|
||||
if (user) {
|
||||
const feature = await isFeatureAvailable(
|
||||
"fileSize",
|
||||
item.size || 0
|
||||
);
|
||||
if (!feature.isAllowed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
setRawFiles((files) => {
|
||||
const index = files.findIndex(
|
||||
(file) => file.name === item.name
|
||||
@@ -256,7 +267,6 @@ const ShareView = () => {
|
||||
);
|
||||
|
||||
const onLoad = useCallback(() => {
|
||||
console.log(noteContent.current, "current...");
|
||||
eSendEvent(eOnLoadNote + "shareEditor", {
|
||||
id: null,
|
||||
content: {
|
||||
@@ -491,7 +501,7 @@ const ShareView = () => {
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
flexGrow: 1,
|
||||
fontFamily: "OpenSans-SemiBold",
|
||||
fontFamily: "Inter-SemiBold",
|
||||
fontSize: AppFontSize.lg,
|
||||
paddingBottom: 0,
|
||||
paddingTop: 0
|
||||
@@ -506,7 +516,7 @@ const ShareView = () => {
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
flexGrow: 1,
|
||||
fontFamily: "OpenSans-SemiBold",
|
||||
fontFamily: "Inter-SemiBold",
|
||||
fontSize: AppFontSize.lg,
|
||||
paddingBottom: 0,
|
||||
paddingTop: 0,
|
||||
@@ -632,7 +642,9 @@ const ShareView = () => {
|
||||
marginTop: 6
|
||||
}}
|
||||
onPress={() => {
|
||||
setCompress(!compress);
|
||||
if (fullQualityImages?.isAllowed) {
|
||||
setCompress(!compress);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
@@ -643,7 +655,7 @@ const ShareView = () => {
|
||||
: "checkbox-blank-outline"
|
||||
}
|
||||
color={
|
||||
compress
|
||||
compress && fullQualityImages?.isAllowed
|
||||
? colors.primary.accent
|
||||
: colors.primary.icon
|
||||
}
|
||||
@@ -734,7 +746,7 @@ const ShareView = () => {
|
||||
</Paragraph>
|
||||
{rawData.value && isURL(rawData.value) ? (
|
||||
<Button
|
||||
type={mode === 2 ? "inverted" : "transparent"}
|
||||
type={mode === 2 ? "inverted" : "plain"}
|
||||
icon={mode === 2 ? "radiobox-marked" : "radiobox-blank"}
|
||||
onPress={() => changeMode(2)}
|
||||
title={modes[2].title}
|
||||
@@ -745,9 +757,9 @@ const ShareView = () => {
|
||||
/>
|
||||
) : null}
|
||||
<Button
|
||||
type={mode === 1 ? "inverted" : "transparent"}
|
||||
type={mode === 1 ? "inverted" : "plain"}
|
||||
icon={mode === 1 ? "radiobox-marked" : "radiobox-blank"}
|
||||
onPress={() => changeMode(2)}
|
||||
onPress={() => changeMode(1)}
|
||||
title={modes[1].title}
|
||||
height={30}
|
||||
style={{
|
||||
|
||||
@@ -68,11 +68,10 @@ export const useShareStore = create((set) => ({
|
||||
let appendNote = MMKV.getString(StorageKeys.appendNote);
|
||||
let selectedNotebooks = MMKV.getString(StorageKeys.selectedNotebooks);
|
||||
let selectedTags = MMKV.getString(StorageKeys.selectedTag);
|
||||
appendNote = JSON.parse(appendNote);
|
||||
set({
|
||||
appendNote: appendNote,
|
||||
selectedNotebooks: selectedNotebooks ? JSON.parse(selectedNotebooks) : [],
|
||||
selectedTag: selectedTags ? JSON.parse(selectedTags) : []
|
||||
selectedTags: selectedTags ? JSON.parse(selectedTags) : []
|
||||
});
|
||||
},
|
||||
selectedTags: [],
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
"@notesnook/theme": ["../../packages/theme"],
|
||||
"@types/react": ["./node_modules/@types/react"],
|
||||
"react": ["./node_modules/react"]
|
||||
},
|
||||
"incremental": true,
|
||||
"maxNodeModuleJsDepth": 5,
|
||||
"downlevelIteration": true
|
||||
}
|
||||
},
|
||||
"exclude": ["native", "e2e"]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
apps/monograph/package-lock.json
generated
1
apps/monograph/package-lock.json
generated
@@ -208,6 +208,7 @@
|
||||
"happy-dom": "16.0.1",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"nodemon": "^3.1.7",
|
||||
"prismjs": "^1.30.0",
|
||||
"prosemirror-test-builder": "^1.1.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
|
||||
2
apps/theme-builder/package-lock.json
generated
2
apps/theme-builder/package-lock.json
generated
@@ -987,7 +987,7 @@
|
||||
},
|
||||
"../web": {
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.3.0-beta.1",
|
||||
"version": "3.3.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
|
||||
1898
apps/web/package-lock.json
generated
1898
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.3.0",
|
||||
"version": "3.3.3",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
@@ -18,7 +18,7 @@
|
||||
"@lingui/react": "5.1.2",
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/react": "1.6.1",
|
||||
"@notesnook-importer/core": "^2.2.2",
|
||||
"@notesnook-importer/core": "^2.2.5",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user