mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-30 18:48:27 +02:00
Compare commits
1 Commits
fix-task-i
...
fix-backup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c414d61b30 |
36
.github/workflows/desktop.publish.yml
vendored
36
.github/workflows/desktop.publish.yml
vendored
@@ -33,19 +33,11 @@ on:
|
||||
required: true
|
||||
default: true
|
||||
description: "Build for macOS?"
|
||||
release-track:
|
||||
type: choice
|
||||
required: true
|
||||
default: stable
|
||||
description: "Select the release track"
|
||||
options:
|
||||
- stable
|
||||
- beta
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -69,14 +61,9 @@ jobs:
|
||||
run: |
|
||||
echo "NX_CLOUD_ACCESS_TOKEN=${{ secrets.NX_CLOUD_ACCESS_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate desktop build (stable)
|
||||
if: ${{ inputs.release-track == 'stable' }}
|
||||
- name: Generate desktop build
|
||||
run: npx nx build:desktop @notesnook/web
|
||||
|
||||
- name: Generate desktop build (beta)
|
||||
if: ${{ inputs.release-track == 'beta' }}
|
||||
run: BETA=true npx nx build:desktop @notesnook/web
|
||||
|
||||
- name: Build desktop bundle
|
||||
working-directory: ./apps/desktop
|
||||
run: npm run bundle
|
||||
@@ -112,8 +99,7 @@ jobs:
|
||||
- name: Generate flatpak sources
|
||||
if: inputs.publish-github && inputs.build-linux
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --quiet flatpak flatpak-builder pipx
|
||||
sudo apt-get install -y flatpak flatpak-builder pipx
|
||||
git clone https://github.com/flatpak/flatpak-builder-tools.git /tmp/flatpak-builder-tools
|
||||
cd /tmp/flatpak-builder-tools/node
|
||||
pipx install .
|
||||
@@ -199,7 +185,7 @@ jobs:
|
||||
CSC_KEY_PASSWORD: ${{ secrets.mac_certs_password }}
|
||||
run: |
|
||||
npx nx run release --project @notesnook/desktop -- --variant=mas
|
||||
yarn electron-builder --config=electron-builder.config.js --mac mas --universal -p never
|
||||
yarn electron-builder --mac mas --universal -p never
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build zip and dmg
|
||||
@@ -213,9 +199,9 @@ jobs:
|
||||
run: |
|
||||
npx nx run release --project @notesnook/desktop
|
||||
if [ ${{ inputs.publish-github }} == true ]; then
|
||||
yarn electron-builder --config=electron-builder.config.js --mac zip dmg --arm64 --x64 -p always
|
||||
yarn electron-builder --mac zip dmg --arm64 --x64 -p always
|
||||
else
|
||||
yarn electron-builder --config=electron-builder.config.js --mac zip dmg --arm64 --x64 -p never
|
||||
yarn electron-builder --mac zip dmg --arm64 --x64 -p never
|
||||
fi
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
@@ -277,7 +263,7 @@ jobs:
|
||||
- name: Build snap
|
||||
if: inputs.publish-snap
|
||||
run: |
|
||||
yarn electron-builder --config=electron-builder.config.js --linux snap:x64 -p never
|
||||
yarn electron-builder --linux snap:x64 -p never
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Build AppImage
|
||||
@@ -285,9 +271,9 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
if [ ${{ inputs.publish-github }} == true ]; then
|
||||
yarn electron-builder --config=electron-builder.config.js --linux AppImage:x64 AppImage:arm64 -p always
|
||||
yarn electron-builder --linux AppImage:x64 AppImage:arm64 -p always
|
||||
else
|
||||
yarn electron-builder --config=electron-builder.config.js --linux AppImage:x64 AppImage:arm64 -p never
|
||||
yarn electron-builder --linux AppImage:x64 AppImage:arm64 -p never
|
||||
fi
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
@@ -347,8 +333,8 @@ jobs:
|
||||
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
run: |
|
||||
if ($${{ inputs.publish-github }} -eq $true) {
|
||||
yarn electron-builder --config=electron-builder.config.js --win --publish always
|
||||
yarn electron-builder --win --publish always
|
||||
} else {
|
||||
yarn electron-builder --config=electron-builder.config.js --win --publish never
|
||||
yarn electron-builder --win --publish never
|
||||
}
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
20
.github/workflows/desktop.tests.yml
vendored
20
.github/workflows/desktop.tests.yml
vendored
@@ -69,11 +69,12 @@ jobs:
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
yarn electron-builder --config=electron-builder.config.js --mac --dir --x64
|
||||
yarn electron-builder --mac --dir --x64
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Run tests x64
|
||||
run: npm run test
|
||||
run: |
|
||||
EXECUTABLE_PATH=output/mac/Notesnook.app/Contents/MacOS/Notesnook npm run test
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Upload test results
|
||||
@@ -113,11 +114,12 @@ jobs:
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
yarn electron-builder --config=electron-builder.config.js --mac --dir --arm64
|
||||
yarn electron-builder --mac --dir --arm64
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Run tests arm64
|
||||
run: npm run test
|
||||
run: |
|
||||
EXECUTABLE_PATH=output/mac-arm64/Notesnook.app/Contents/MacOS/Notesnook npm run test
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Upload test results
|
||||
@@ -163,11 +165,12 @@ jobs:
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
yarn electron-builder --config=electron-builder.config.js --linux --dir --arm64 --x64
|
||||
yarn electron-builder --linux --dir --arm64 --x64
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Run tests
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" -- npm run test
|
||||
run: |
|
||||
EXECUTABLE_PATH=output/linux-unpacked/notesnook xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" -- npm run test
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Upload test results
|
||||
@@ -213,11 +216,12 @@ jobs:
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
npx cross-env NOTESNOOK_STAGING=true yarn electron-builder --config=electron-builder.config.js --win --dir --arm64 --x64
|
||||
npx cross-env NOTESNOOK_STAGING=true yarn electron-builder --win --dir --arm64 --x64
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Run tests
|
||||
run: npm run test
|
||||
run: |
|
||||
npx cross-env EXECUTABLE_PATH=output/win-unpacked/Notesnook.exe npm run test
|
||||
working-directory: ./apps/desktop
|
||||
|
||||
- name: Upload test results
|
||||
|
||||
30
.github/workflows/web.publish.yml
vendored
30
.github/workflows/web.publish.yml
vendored
@@ -1,16 +1,6 @@
|
||||
name: Publish @notesnook/web
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-track:
|
||||
type: choice
|
||||
required: true
|
||||
default: stable
|
||||
description: "Select the release track"
|
||||
options:
|
||||
- stable
|
||||
- beta
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -34,20 +24,8 @@ jobs:
|
||||
echo "CLOUDFLARE_ACCOUNT_ID=${{ secrets.CLOUDFLARE_ACCOUNT_ID }}" >> $GITHUB_ENV
|
||||
echo "CLOUDFLARE_API_TOKEN=${{ secrets.CLOUDFLARE_API_TOKEN }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate build (stable)
|
||||
if: ${{ inputs.release-track == 'stable' }}
|
||||
- name: Generate build
|
||||
run: npm run build:web
|
||||
|
||||
- name: Publish to Cloudflare Pages (stable)
|
||||
if: ${{ inputs.release-track == 'stable' }}
|
||||
working-directory: ./apps/web
|
||||
run: npx --yes wrangler pages deploy --project-name=notesnook-app ./build/
|
||||
|
||||
- name: Generate build (beta)
|
||||
if: ${{ inputs.release-track == 'beta' }}
|
||||
run: npm run build:beta:web
|
||||
|
||||
- name: Publish to Cloudflare Pages (beta)
|
||||
if: ${{ inputs.release-track == 'beta' }}
|
||||
working-directory: ./apps/web
|
||||
run: npx --yes wrangler pages deploy --branch=beta --project-name=notesnook-app-beta ./build/
|
||||
- name: Publish to Cloudflare Pages
|
||||
run: npx --yes wrangler pages deploy --project-name=notesnook-app ./apps/web/build/
|
||||
|
||||
2
.github/workflows/web.tests.yml
vendored
2
.github/workflows/web.tests.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
||||
name: 🧪 Test (${{ matrix.shard }}/${{ strategy.job-total }})
|
||||
strategy:
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4, 5]
|
||||
shard: [1, 2, 3, 4]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,4 +11,3 @@ nx-cloud.env
|
||||
site
|
||||
node_modules.backup
|
||||
.nx
|
||||
*.patch
|
||||
|
||||
37
7421.patch
Normal file
37
7421.patch
Normal file
@@ -0,0 +1,37 @@
|
||||
From af88ee05e1620afb65c76148d347cb7efc32bded Mon Sep 17 00:00:00 2001
|
||||
From: 01zulfi <85733202+01zulfi@users.noreply.github.com>
|
||||
Date: Wed, 29 Jan 2025 12:22:32 +0500
|
||||
Subject: [PATCH] editor: fix hover styling in toolbar color buttons
|
||||
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
|
||||
|
||||
---
|
||||
packages/editor/src/toolbar/popups/color-picker.tsx | 2 +-
|
||||
packages/editor/src/toolbar/tools/colors.tsx | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/packages/editor/src/toolbar/popups/color-picker.tsx b/packages/editor/src/toolbar/popups/color-picker.tsx
|
||||
index 0abca19268..34209bd550 100644
|
||||
--- a/packages/editor/src/toolbar/popups/color-picker.tsx
|
||||
+++ b/packages/editor/src/toolbar/popups/color-picker.tsx
|
||||
@@ -284,7 +284,7 @@ function PaletteButton(props: PaletteButtonProps) {
|
||||
ml: [2, 2, 1],
|
||||
bg,
|
||||
":hover:not(:disabled):not(:active)": {
|
||||
- bg: bg?.startsWith("#") ? colord(bg).darken(5).toRgbString() : "hover"
|
||||
+ bg: bg?.startsWith("#") ? colord(bg).darken().toRgbString() : "hover"
|
||||
},
|
||||
...sx
|
||||
}}
|
||||
diff --git a/packages/editor/src/toolbar/tools/colors.tsx b/packages/editor/src/toolbar/tools/colors.tsx
|
||||
index 08c6b41d8a..77ea660e75 100644
|
||||
--- a/packages/editor/src/toolbar/tools/colors.tsx
|
||||
+++ b/packages/editor/src/toolbar/tools/colors.tsx
|
||||
@@ -137,7 +137,7 @@ export function ColorTool(props: ColorToolProps) {
|
||||
mr: 0,
|
||||
bg: activeColor || "transparent",
|
||||
":hover:not(:disabled):not(:active)": {
|
||||
- bg: tColor ? tColor.darken(5).toRgbString() : "transparent"
|
||||
+ bg: tColor ? tColor.darken().toRgbString() : "transparent"
|
||||
}
|
||||
}}
|
||||
onOpen={toggle}
|
||||
4
apps/desktop/.gitignore
vendored
4
apps/desktop/.gitignore
vendored
@@ -2,6 +2,4 @@ node_modules
|
||||
build
|
||||
output
|
||||
dist
|
||||
_catalog
|
||||
test-results
|
||||
test-artifacts
|
||||
_catalog
|
||||
@@ -58,13 +58,13 @@ This will compile and run the app in production mode but it won't generate any p
|
||||
npm run release -- --rebuild
|
||||
|
||||
# For macOS
|
||||
npx electron-builder --config=electron-builder.config.js --mac dmg --arm64 --x64 -publish never
|
||||
npx electron-builder --mac dmg --arm64 --x64 -publish never
|
||||
|
||||
# For Linux (AppImage)
|
||||
npx electron-builder --config=electron-builder.config.js --linux AppImage:x64 AppImage:arm64 -publish never
|
||||
npx electron-builder --linux AppImage:x64 AppImage:arm64 -publish never
|
||||
|
||||
# For Windows
|
||||
npx electron-builder --config=electron-builder.config.js --win --publish never
|
||||
npx electron-builder --win --publish never
|
||||
```
|
||||
|
||||
Feel free to play around with the `electron-builder` command to get the packages you need. `npx electron-builder --help` is a great resource to learn different commands & platforms supported by `electron-builder`.
|
||||
|
||||
@@ -1,246 +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 { test } from "vitest";
|
||||
import { harness } from "./utils.js";
|
||||
import { writeFile } from "fs/promises";
|
||||
import { Page } from "playwright";
|
||||
import { gt, lt } from "semver";
|
||||
|
||||
test("update starts downloading if version is outdated", async (t) => {
|
||||
await harness(
|
||||
t,
|
||||
async ({ page }) => {
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
t.expect(
|
||||
await page.getByRole("button", { name: "Create account" }).isVisible()
|
||||
).toBe(true);
|
||||
|
||||
await page
|
||||
.getByRole("button", { name: "Skip & go directly to the app" })
|
||||
.click();
|
||||
|
||||
await skipDialog(page);
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
|
||||
await page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /updating/i })
|
||||
.waitFor({ state: "attached" });
|
||||
},
|
||||
{ version: "3.0.0" }
|
||||
);
|
||||
});
|
||||
|
||||
test("update is only shown if version is outdated and auto updates are disabled", async (t) => {
|
||||
await harness(
|
||||
t,
|
||||
async (ctx) => {
|
||||
await ctx.app.close();
|
||||
await writeFile(
|
||||
ctx.configPath,
|
||||
JSON.stringify({
|
||||
automaticUpdates: false
|
||||
})
|
||||
);
|
||||
|
||||
await ctx.relaunch();
|
||||
|
||||
const { page } = ctx;
|
||||
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
t.expect(
|
||||
await page.getByRole("button", { name: "Create account" }).isVisible()
|
||||
).toBe(true);
|
||||
|
||||
await page
|
||||
.getByRole("button", { name: "Skip & go directly to the app" })
|
||||
.click();
|
||||
|
||||
await skipDialog(page);
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
|
||||
await page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /available/i })
|
||||
.waitFor({ state: "attached" });
|
||||
},
|
||||
{ version: "3.0.0" }
|
||||
);
|
||||
});
|
||||
|
||||
test("update to stable if it is newer", async (t) => {
|
||||
await harness(
|
||||
t,
|
||||
async (ctx) => {
|
||||
await ctx.app.close();
|
||||
await writeFile(
|
||||
ctx.configPath,
|
||||
JSON.stringify({
|
||||
automaticUpdates: false,
|
||||
releaseTrack: "beta"
|
||||
})
|
||||
);
|
||||
|
||||
await ctx.relaunch();
|
||||
|
||||
const { page } = ctx;
|
||||
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
t.expect(
|
||||
await page.getByRole("button", { name: "Create account" }).isVisible()
|
||||
).toBe(true);
|
||||
|
||||
await page
|
||||
.getByRole("button", { name: "Skip & go directly to the app" })
|
||||
.click();
|
||||
|
||||
await skipDialog(page);
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
|
||||
const updateButton = page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /available/i });
|
||||
await updateButton.waitFor({ state: "visible" });
|
||||
const content = await updateButton.textContent();
|
||||
const version = content?.split(" ")?.[0] || "";
|
||||
t.expect(gt(version, "3.0.0-beta.0")).toBe(true);
|
||||
},
|
||||
{ version: "3.0.0-beta.0" }
|
||||
);
|
||||
});
|
||||
|
||||
test("update is not available if it latest stable version is older", async (t) => {
|
||||
await harness(
|
||||
t,
|
||||
async (ctx) => {
|
||||
await ctx.app.close();
|
||||
await writeFile(
|
||||
ctx.configPath,
|
||||
JSON.stringify({
|
||||
automaticUpdates: false,
|
||||
releaseTrack: "beta"
|
||||
})
|
||||
);
|
||||
|
||||
await ctx.relaunch();
|
||||
|
||||
const { page } = ctx;
|
||||
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
t.expect(
|
||||
await page.getByRole("button", { name: "Create account" }).isVisible()
|
||||
).toBe(true);
|
||||
|
||||
await page
|
||||
.getByRole("button", { name: "Skip & go directly to the app" })
|
||||
.click();
|
||||
|
||||
await skipDialog(page);
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
|
||||
await page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /checking for updates/i })
|
||||
.waitFor({ state: "hidden" });
|
||||
|
||||
t.expect(
|
||||
await page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /available/i })
|
||||
.isHidden()
|
||||
).toBe(true);
|
||||
},
|
||||
{ version: "99.0.0-beta.0" }
|
||||
);
|
||||
});
|
||||
|
||||
test("downgrade to stable on switching to stable release track", async (t) => {
|
||||
await harness(
|
||||
t,
|
||||
async (ctx) => {
|
||||
await ctx.app.close();
|
||||
await writeFile(
|
||||
ctx.configPath,
|
||||
JSON.stringify({
|
||||
automaticUpdates: false,
|
||||
releaseTrack: "stable"
|
||||
})
|
||||
);
|
||||
|
||||
await ctx.relaunch();
|
||||
|
||||
const { page } = ctx;
|
||||
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
t.expect(
|
||||
await page.getByRole("button", { name: "Create account" }).isVisible()
|
||||
).toBe(true);
|
||||
|
||||
await page
|
||||
.getByRole("button", { name: "Skip & go directly to the app" })
|
||||
.click();
|
||||
|
||||
await skipDialog(page);
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
|
||||
await page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /checking for updates/i })
|
||||
.waitFor({ state: "hidden" });
|
||||
|
||||
const updateButton = page
|
||||
.locator(".theme-scope-statusBar")
|
||||
.getByRole("button", { name: /available/i });
|
||||
await updateButton.waitFor({ state: "visible" });
|
||||
const content = await updateButton.textContent();
|
||||
const version = content?.split(" ")?.[0] || "";
|
||||
t.expect(lt(version, "99.0.0-beta.0")).toBe(true);
|
||||
},
|
||||
{ version: "99.0.0-beta.0" }
|
||||
);
|
||||
});
|
||||
|
||||
async function skipDialog(page: Page) {
|
||||
await page
|
||||
.waitForSelector(".ReactModal__Content", {
|
||||
timeout: 1000
|
||||
})
|
||||
.catch(() => {})
|
||||
.then(async () => {
|
||||
const positiveButton = page.locator(
|
||||
"button[data-role='positive-button']"
|
||||
);
|
||||
const negativeButton = page.locator(
|
||||
"button[data-role='negative-button']"
|
||||
);
|
||||
if (await positiveButton.isVisible()) await positiveButton.click();
|
||||
else if (await negativeButton.isVisible()) await negativeButton.click();
|
||||
});
|
||||
}
|
||||
@@ -17,12 +17,16 @@ 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 { test } from "vitest";
|
||||
import { harness } from "./utils.js";
|
||||
import test from "node:test";
|
||||
import { launchApp } from "./utils.mjs";
|
||||
import assert from "assert";
|
||||
import slugify from "slugify";
|
||||
import path from "path";
|
||||
import { mkdir } from "fs/promises";
|
||||
|
||||
test("make sure app loads", async (t) => {
|
||||
await harness(t, async ({ page }) => {
|
||||
const { app, page } = await launchApp();
|
||||
try {
|
||||
await page.waitForSelector("#authForm");
|
||||
|
||||
assert.ok(
|
||||
@@ -34,5 +38,16 @@ test("make sure app loads", async (t) => {
|
||||
.click();
|
||||
|
||||
await page.waitForSelector(".ProseMirror");
|
||||
});
|
||||
} catch (e) {
|
||||
await mkdir("test-results", { recursive: true });
|
||||
await page.screenshot({
|
||||
path: path.join(
|
||||
"test-results",
|
||||
`${slugify(t.name)}-${process.platform}-${process.arch}-error.png`
|
||||
)
|
||||
});
|
||||
throw e;
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
@@ -17,4 +17,22 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export * from "./command-palette-dialog";
|
||||
import { _electron as electron } from "playwright";
|
||||
|
||||
const executablePath = process.env.EXECUTABLE_PATH;
|
||||
|
||||
// process.platform === "linux"
|
||||
// ? "output/linux-unpacked/Notesnook"
|
||||
// : process.platform === "darwin"
|
||||
// ? "output/mac/Notesnook.app/Contents/MacOS/Notesnook"
|
||||
// : "output/win-unpacked/Notesnook.exe";
|
||||
|
||||
export async function launchApp() {
|
||||
const app = await electron.launch({
|
||||
executablePath
|
||||
});
|
||||
|
||||
const page = await app.firstWindow();
|
||||
|
||||
return { app, page };
|
||||
}
|
||||
@@ -1,172 +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 { execSync } from "child_process";
|
||||
import { mkdir } from "fs/promises";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import path from "path";
|
||||
import { _electron as electron } from "playwright";
|
||||
import slugify from "slugify";
|
||||
import { TaskContext } from "vitest";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const IS_DEBUG = process.env.NN_DEBUG === "true" || process.env.CI === "true";
|
||||
|
||||
interface AppContext {
|
||||
app: import("playwright").ElectronApplication;
|
||||
page: import("playwright").Page;
|
||||
configPath: string;
|
||||
relaunch: () => Promise<void>;
|
||||
}
|
||||
|
||||
interface TestOptions {
|
||||
version: string;
|
||||
}
|
||||
|
||||
export async function harness(
|
||||
t: TaskContext,
|
||||
cb: (ctx: AppContext) => Promise<void>,
|
||||
options?: TestOptions
|
||||
) {
|
||||
const ctx = await buildAndLaunchApp(options);
|
||||
|
||||
t.onTestFinished(async (result) => {
|
||||
if (result.state === "fail") {
|
||||
await mkdir("test-results", { recursive: true });
|
||||
await ctx.page.screenshot({
|
||||
path: path.join(
|
||||
"test-results",
|
||||
`${slugify(t.task.name)}-${process.platform}-${
|
||||
process.arch
|
||||
}-error.png`
|
||||
)
|
||||
});
|
||||
}
|
||||
await ctx.app.close();
|
||||
});
|
||||
|
||||
await cb(ctx);
|
||||
}
|
||||
|
||||
async function buildAndLaunchApp(options?: TestOptions): Promise<AppContext> {
|
||||
const productName = makeid(10);
|
||||
const executablePath = await buildApp({ ...options, productName });
|
||||
const { app, page, configPath } = await launchApp(executablePath);
|
||||
const ctx: AppContext = {
|
||||
app,
|
||||
page,
|
||||
configPath,
|
||||
relaunch: async () => {
|
||||
const { app, page, configPath } = await launchApp(executablePath);
|
||||
ctx.app = app;
|
||||
ctx.page = page;
|
||||
ctx.configPath = configPath;
|
||||
}
|
||||
};
|
||||
return ctx;
|
||||
}
|
||||
|
||||
async function launchApp(executablePath: string) {
|
||||
const app = await electron.launch({
|
||||
executablePath,
|
||||
args: IS_DEBUG ? [] : ["--hidden"],
|
||||
env:
|
||||
process.platform === "linux"
|
||||
? {
|
||||
...(process.env as Record<string, string>),
|
||||
APPIMAGE: "true"
|
||||
}
|
||||
: (process.env as Record<string, string>)
|
||||
});
|
||||
|
||||
const page = await app.firstWindow();
|
||||
|
||||
const userDataDirectory = await app.evaluate((a) => {
|
||||
return a.app.getPath("userData");
|
||||
});
|
||||
const configPath = path.join(userDataDirectory, "config.json");
|
||||
return {
|
||||
app,
|
||||
page,
|
||||
configPath
|
||||
};
|
||||
}
|
||||
|
||||
async function buildApp({
|
||||
version,
|
||||
productName
|
||||
}: {
|
||||
version?: string;
|
||||
productName: string;
|
||||
}) {
|
||||
const buildRoot = path.join("test-artifacts", `${productName}-build`);
|
||||
const output = path.join("test-artifacts", `${productName}-output`);
|
||||
execSync(`npm run release -- --root ${buildRoot} --skip-tsc-build`, {
|
||||
stdio: IS_DEBUG ? "inherit" : "ignore"
|
||||
});
|
||||
|
||||
const args = [
|
||||
`--config electron-builder.config.js`,
|
||||
`--c.extraMetadata.productName=${productName}`,
|
||||
"--publish=never"
|
||||
];
|
||||
if (version) args.push(`--c.extraMetadata.version=${version}`);
|
||||
|
||||
execSync(`npx electron-builder --dir --${process.arch} ${args.join(" ")}`, {
|
||||
stdio: IS_DEBUG ? "inherit" : "ignore",
|
||||
env: {
|
||||
...process.env,
|
||||
NOTESNOOK_STAGING: "true",
|
||||
NN_BUILD_ROOT: buildRoot,
|
||||
NN_PRODUCT_NAME: productName,
|
||||
NN_APP_ID: `com.notesnook.test.${productName}`,
|
||||
NN_OUTPUT_DIR: output
|
||||
}
|
||||
});
|
||||
|
||||
return path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
output,
|
||||
process.platform === "linux"
|
||||
? process.arch === "arm64"
|
||||
? "linux-arm64-unpacked"
|
||||
: "linux-unpacked"
|
||||
: process.platform === "darwin"
|
||||
? process.arch === "arm64"
|
||||
? `mac-arm64/${productName}.app/Contents/MacOS/`
|
||||
: `mac/${productName}.app/Contents/MacOS/`
|
||||
: "win-unpacked",
|
||||
process.platform === "win32" ? `${productName}.exe` : productName
|
||||
);
|
||||
}
|
||||
|
||||
function makeid(length: number) {
|
||||
let result = "";
|
||||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < length) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result.toLowerCase();
|
||||
}
|
||||
Binary file not shown.
@@ -1,203 +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/>.
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
|
||||
const buildRoot = process.env.NN_BUILD_ROOT || ".";
|
||||
const buildFiles = [
|
||||
`${buildRoot}/build/`,
|
||||
`!${buildRoot}/build/screenshots\${/*}`,
|
||||
`!${buildRoot}/build/banner.jpg`,
|
||||
`!${buildRoot}/build/*.ico`,
|
||||
`!${buildRoot}/build/*.png`
|
||||
];
|
||||
|
||||
const productName = process.env.NN_PRODUCT_NAME || "Notesnook";
|
||||
const appId = process.env.NN_APP_ID || "org.streetwriters.notesnook";
|
||||
const outputDir = process.env.NN_OUTPUT_DIR || "output";
|
||||
const linuxExecutableName = process.env.NN_PRODUCT_NAME
|
||||
? process.env.NN_PRODUCT_NAME.toLowerCase().replace(/\s+/g, "-")
|
||||
: "notesnook";
|
||||
const year = new Date().getFullYear();
|
||||
const isBeta = pkg.version.includes("-beta");
|
||||
|
||||
module.exports = {
|
||||
appId: appId,
|
||||
productName: productName,
|
||||
copyright: `Copyright © ${year} Streetwriters (Private) Limited`,
|
||||
artifactName: "notesnook_${os}_${arch}.${ext}",
|
||||
generateUpdatesFilesForAllChannels: true,
|
||||
asar: false,
|
||||
files: [
|
||||
"!*.chunk.js.map",
|
||||
"!*.chunk.js.LICENSE.txt",
|
||||
...buildFiles,
|
||||
"!node_modules${/*}",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/build/Release/better_sqlite3.node",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/lib",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/package.json",
|
||||
"node_modules/file-uri-to-path",
|
||||
"node_modules/bindings",
|
||||
"node_modules/node-gyp-build",
|
||||
"node_modules/sqlite-better-trigram",
|
||||
"node_modules/sodium-native/prebuilds/${platform}-${arch}",
|
||||
{
|
||||
from: "node_modules/sqlite-better-trigram-linux-${arch}",
|
||||
to: "node_modules/sqlite-better-trigram-linux-${arch}"
|
||||
},
|
||||
{
|
||||
from: "node_modules/sqlite-better-trigram-darwin-${arch}",
|
||||
to: "node_modules/sqlite-better-trigram-darwin-${arch}"
|
||||
},
|
||||
{
|
||||
from: "node_modules/sqlite-better-trigram-windows-${arch}",
|
||||
to: "node_modules/sqlite-better-trigram-windows-${arch}"
|
||||
},
|
||||
"node_modules/sodium-native/index.js",
|
||||
"node_modules/sodium-native/package.json"
|
||||
],
|
||||
afterPack: "./scripts/removeLocales.js",
|
||||
mac: {
|
||||
bundleVersion: "240",
|
||||
minimumSystemVersion: "10.12.0",
|
||||
target: [
|
||||
{
|
||||
target: "dmg",
|
||||
arch: ["arm64", "x64"]
|
||||
},
|
||||
{
|
||||
target: "zip",
|
||||
arch: ["arm64", "x64"]
|
||||
}
|
||||
],
|
||||
category: "public.app-category.productivity",
|
||||
darkModeSupport: true,
|
||||
type: "distribution",
|
||||
hardenedRuntime: true,
|
||||
entitlements: "assets/entitlements.mac.plist",
|
||||
entitlementsInherit: "assets/entitlements.mac.plist",
|
||||
gatekeeperAssess: false,
|
||||
icon: "assets/icons/app.icns",
|
||||
notarize: true
|
||||
},
|
||||
dmg: {
|
||||
contents: [
|
||||
{
|
||||
x: 130,
|
||||
y: 220
|
||||
},
|
||||
{
|
||||
x: 410,
|
||||
y: 220,
|
||||
type: "link",
|
||||
path: "/Applications"
|
||||
}
|
||||
],
|
||||
icon: "assets/icons/app.icns",
|
||||
title: "Install Notesnook"
|
||||
},
|
||||
mas: {
|
||||
entitlements: "assets/entitlements.mas.plist",
|
||||
entitlementsInherit: "assets/entitlements.mas.inherit.plist",
|
||||
entitlementsLoginHelper: "assets/entitlements.mas.loginhelper.plist",
|
||||
hardenedRuntime: true
|
||||
},
|
||||
win: {
|
||||
target: [
|
||||
{
|
||||
target: "nsis",
|
||||
arch: ["x64", "arm64"]
|
||||
},
|
||||
{
|
||||
target: "portable",
|
||||
arch: ["x64", "arm64"]
|
||||
}
|
||||
],
|
||||
signtoolOptions: {
|
||||
signingHashAlgorithms: ["sha256"],
|
||||
sign: "./scripts/sign.js"
|
||||
},
|
||||
icon: "assets/icons/app.ico"
|
||||
},
|
||||
portable: {
|
||||
artifactName: "notesnook_${os}_${arch}_portable.${ext}"
|
||||
},
|
||||
nsis: {
|
||||
oneClick: true,
|
||||
createDesktopShortcut: "always",
|
||||
deleteAppDataOnUninstall: true
|
||||
},
|
||||
linux: {
|
||||
target: [
|
||||
{
|
||||
target: "AppImage",
|
||||
arch: ["x64", "arm64"]
|
||||
},
|
||||
{
|
||||
target: "snap",
|
||||
arch: ["x64", "arm64"]
|
||||
}
|
||||
],
|
||||
category: "Office",
|
||||
icon: "assets/icons/app.icns",
|
||||
description: "Your private note taking space",
|
||||
executableName: linuxExecutableName,
|
||||
desktop: {
|
||||
actions: [
|
||||
{
|
||||
id: "new-note",
|
||||
name: "New note",
|
||||
args: "new note"
|
||||
},
|
||||
{
|
||||
id: "new-notebook",
|
||||
name: "New notebook",
|
||||
args: "new notebook"
|
||||
},
|
||||
{
|
||||
id: "new-reminder",
|
||||
name: "New reminder",
|
||||
args: "new reminder"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
snap: {
|
||||
autoStart: false,
|
||||
confinement: "strict",
|
||||
allowNativeWayland: true
|
||||
},
|
||||
extraResources: ["app-update.yml", "./assets/**"],
|
||||
extraMetadata: {
|
||||
main: path.join(buildRoot, "build", "electron.js")
|
||||
},
|
||||
directories: {
|
||||
buildResources: "assets",
|
||||
output: outputDir
|
||||
},
|
||||
publish: [
|
||||
{
|
||||
provider: "github",
|
||||
repo: "notesnook",
|
||||
owner: "streetwriters",
|
||||
channel: isBeta ? "beta" : "latest"
|
||||
}
|
||||
]
|
||||
};
|
||||
15
apps/desktop/package-lock.json
generated
15
apps/desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -15,7 +15,7 @@
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "11.5.0",
|
||||
"electron-trpc": "0.7.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.3.4",
|
||||
"icojs": "^0.19.4",
|
||||
"sqlite-better-trigram": "0.0.2",
|
||||
@@ -38,7 +38,7 @@
|
||||
"slugify": "1.6.6",
|
||||
"tree-kill": "^1.2.2",
|
||||
"undici": "^6.19.8",
|
||||
"vitest": "^2.1.8"
|
||||
"vitest": "2.1.8"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dmg-license": "^1.0.11"
|
||||
@@ -3190,9 +3190,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-trpc": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-trpc/-/electron-trpc-0.7.1.tgz",
|
||||
"integrity": "sha512-aWjZ5pLeVhrX9A9d8O8YgR8N+q4IXXzc76CJT1PwtDijIw+y5I+c75IAAtZ4JayYLeR3ll95PNGl5RTBu2qePw==",
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-trpc/-/electron-trpc-0.6.1.tgz",
|
||||
"integrity": "sha512-Yj13UrjjjOW4+TD06YunAML2tgmtSYJMiFw6E6r1D4in/0EZ2MRwMoQc7AtMPAA6In23e+Kmq71e8h0ir+c3Jg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
@@ -6658,7 +6658,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz",
|
||||
"integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/expect": "2.1.8",
|
||||
"@vitest/mocker": "2.1.8",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/cjs/index.js",
|
||||
@@ -30,7 +30,7 @@
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "11.5.0",
|
||||
"electron-trpc": "0.7.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.3.4",
|
||||
"icojs": "^0.19.4",
|
||||
"sqlite-better-trigram": "0.0.2",
|
||||
@@ -46,14 +46,14 @@
|
||||
"electron": "^31.7.4",
|
||||
"electron-builder": "^25.1.8",
|
||||
"esbuild": "0.21.5",
|
||||
"vitest": "2.1.8",
|
||||
"node-abi": "^3.68.0",
|
||||
"node-gyp-build": "^4.8.2",
|
||||
"playwright": "^1.48.2",
|
||||
"prebuildify": "^6.0.1",
|
||||
"slugify": "1.6.6",
|
||||
"tree-kill": "^1.2.2",
|
||||
"undici": "^6.19.8",
|
||||
"vitest": "^2.1.8"
|
||||
"undici": "^6.19.8"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dmg-license": "^1.0.11"
|
||||
@@ -63,14 +63,203 @@
|
||||
"staging": "node scripts/build.mjs --run",
|
||||
"release": "node scripts/build.mjs",
|
||||
"build": "node ../../scripts/build.mjs",
|
||||
"bundle": "esbuild electron=./src/main.ts ./src/preload.ts --external:electron --external:fsevents --external:better-sqlite3-multiple-ciphers --external:sodium-native --bundle --outdir=./build --platform=node --tsconfig=tsconfig.json --define:MAC_APP_STORE=false --define:RELEASE=true",
|
||||
"bundle": "esbuild electron=./src/main.ts ./src/preload.ts --external:electron --external:fsevents --external:better-sqlite3-multiple-ciphers --external:sodium-native --minify --bundle --outdir=./build --platform=node --tsconfig=tsconfig.json --define:MAC_APP_STORE=false --define:RELEASE=true",
|
||||
"bundle:mas": "esbuild electron=./src/main.ts ./src/preload.ts --minify --external:electron --external:fsevents --bundle --outdir=./build --platform=node --tsconfig=tsconfig.json --define:MAC_APP_STORE=true --define:RELEASE=true",
|
||||
"postinstall": "patch-package",
|
||||
"test": "vitest run"
|
||||
"test": "node --test --test-timeout 30000 --test-force-exit"
|
||||
},
|
||||
"author": {
|
||||
"name": "Streetwriters (Private) Limited",
|
||||
"email": "support@streetwriters.co",
|
||||
"url": "https://streetwriters.co"
|
||||
},
|
||||
"build": {
|
||||
"appId": "org.streetwriters.notesnook",
|
||||
"productName": "Notesnook",
|
||||
"copyright": "Copyright © 2023 Streetwriters (Private) Limited",
|
||||
"artifactName": "notesnook_${os}_${arch}.${ext}",
|
||||
"generateUpdatesFilesForAllChannels": true,
|
||||
"asar": false,
|
||||
"files": [
|
||||
"!*.chunk.js.map",
|
||||
"!*.chunk.js.LICENSE.txt",
|
||||
"build/",
|
||||
"!build/screenshots${/*}",
|
||||
"!build/banner.jpg",
|
||||
"!build/*.ico",
|
||||
"!build/*.png",
|
||||
"!node_modules${/*}",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/build/Release/better_sqlite3.node",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/lib",
|
||||
"node_modules/better-sqlite3-multiple-ciphers/package.json",
|
||||
"node_modules/file-uri-to-path",
|
||||
"node_modules/bindings",
|
||||
"node_modules/node-gyp-build",
|
||||
"node_modules/sqlite-better-trigram",
|
||||
"node_modules/sodium-native/prebuilds/${platform}-${arch}",
|
||||
{
|
||||
"from": "node_modules/sqlite-better-trigram-linux-${arch}",
|
||||
"to": "node_modules/sqlite-better-trigram-linux-${arch}"
|
||||
},
|
||||
{
|
||||
"from": "node_modules/sqlite-better-trigram-darwin-${arch}",
|
||||
"to": "node_modules/sqlite-better-trigram-darwin-${arch}"
|
||||
},
|
||||
{
|
||||
"from": "node_modules/sqlite-better-trigram-windows-${arch}",
|
||||
"to": "node_modules/sqlite-better-trigram-windows-${arch}"
|
||||
},
|
||||
"node_modules/sodium-native/index.js",
|
||||
"node_modules/sodium-native/package.json"
|
||||
],
|
||||
"afterPack": "./scripts/removeLocales.js",
|
||||
"mac": {
|
||||
"bundleVersion": "240",
|
||||
"minimumSystemVersion": "10.12.0",
|
||||
"target": [
|
||||
{
|
||||
"target": "dmg",
|
||||
"arch": [
|
||||
"arm64",
|
||||
"x64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "zip",
|
||||
"arch": [
|
||||
"arm64",
|
||||
"x64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"category": "public.app-category.productivity",
|
||||
"darkModeSupport": true,
|
||||
"type": "distribution",
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "assets/entitlements.mac.plist",
|
||||
"entitlementsInherit": "assets/entitlements.mac.plist",
|
||||
"gatekeeperAssess": false,
|
||||
"icon": "assets/icons/app.icns",
|
||||
"notarize": true
|
||||
},
|
||||
"dmg": {
|
||||
"contents": [
|
||||
{
|
||||
"x": 130,
|
||||
"y": 220
|
||||
},
|
||||
{
|
||||
"x": 410,
|
||||
"y": 220,
|
||||
"type": "link",
|
||||
"path": "/Applications"
|
||||
}
|
||||
],
|
||||
"icon": "assets/icons/app.icns",
|
||||
"title": "Install Notesnook"
|
||||
},
|
||||
"mas": {
|
||||
"entitlements": "assets/entitlements.mas.plist",
|
||||
"entitlementsInherit": "assets/entitlements.mas.inherit.plist",
|
||||
"entitlementsLoginHelper": "assets/entitlements.mas.loginhelper.plist",
|
||||
"hardenedRuntime": true
|
||||
},
|
||||
"win": {
|
||||
"target": [
|
||||
{
|
||||
"target": "nsis",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "portable",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"signtoolOptions": {
|
||||
"signingHashAlgorithms": [
|
||||
"sha256"
|
||||
],
|
||||
"sign": "./scripts/sign.js"
|
||||
},
|
||||
"icon": "assets/icons/app.ico"
|
||||
},
|
||||
"portable": {
|
||||
"artifactName": "notesnook_${os}_${arch}_portable.${ext}"
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": true,
|
||||
"createDesktopShortcut": "always",
|
||||
"deleteAppDataOnUninstall": true
|
||||
},
|
||||
"linux": {
|
||||
"target": [
|
||||
{
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "snap",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"category": "Office",
|
||||
"icon": "assets/icons/app.icns",
|
||||
"description": "Your private note taking space",
|
||||
"executableName": "notesnook",
|
||||
"desktop": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "new-note",
|
||||
"name": "New note",
|
||||
"args": "new note"
|
||||
},
|
||||
{
|
||||
"id": "new-notebook",
|
||||
"name": "New notebook",
|
||||
"args": "new notebook"
|
||||
},
|
||||
{
|
||||
"id": "new-reminder",
|
||||
"name": "New reminder",
|
||||
"args": "new reminder"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"snap": {
|
||||
"autoStart": false,
|
||||
"confinement": "strict",
|
||||
"allowNativeWayland": true
|
||||
},
|
||||
"extraResources": [
|
||||
"app-update.yml",
|
||||
"./assets/**"
|
||||
],
|
||||
"extraMetadata": {
|
||||
"main": "./build/electron.js"
|
||||
},
|
||||
"directories": {
|
||||
"buildResources": "assets",
|
||||
"output": "./output/"
|
||||
},
|
||||
"publish": [
|
||||
{
|
||||
"provider": "github",
|
||||
"repo": "notesnook",
|
||||
"owner": "streetwriters"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,10 @@ import { patchBetterSQLite3 } from "./patch-better-sqlite3.mjs";
|
||||
const args = yargs(process.argv);
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const root = args.root || path.join(__dirname, "..");
|
||||
const skipTscBuild = args.skipTscBuild || false;
|
||||
|
||||
const webAppPath = path.resolve(path.join(__dirname, "..", "..", "web"));
|
||||
|
||||
await fs.rm(path.join(root, "build"), { force: true, recursive: true });
|
||||
await fs.rm("./build/", { force: true, recursive: true });
|
||||
|
||||
if (args.rebuild || !existsSync(path.join(webAppPath, "build"))) {
|
||||
await exec(
|
||||
@@ -46,25 +44,21 @@ if (args.rebuild || !existsSync(path.join(webAppPath, "build"))) {
|
||||
// temporary until there's support for prebuilt binaries for linux ARM
|
||||
if (os.platform() === "linux") await patchBetterSQLite3();
|
||||
|
||||
await fs.cp(path.join(webAppPath, "build"), path.join(root, "build"), {
|
||||
await fs.cp(path.join(webAppPath, "build"), "build", {
|
||||
recursive: true,
|
||||
force: true
|
||||
});
|
||||
|
||||
if (args.variant === "mas") {
|
||||
await exec(`yarn run bundle:mas --outdir=${path.join(root, "build")}`);
|
||||
await exec(`yarn run bundle:mas`);
|
||||
} else {
|
||||
await exec(`yarn run bundle --outdir=${path.join(root, "build")}`);
|
||||
await exec(`yarn run bundle`);
|
||||
}
|
||||
|
||||
if (!skipTscBuild) {
|
||||
await exec(`yarn run build`);
|
||||
}
|
||||
await exec(`yarn run build`);
|
||||
|
||||
if (args.run) {
|
||||
await exec(
|
||||
`yarn electron-builder --dir --${process.arch} --config=electron-builder.config.js`
|
||||
);
|
||||
await exec(`yarn electron-builder --dir --${process.arch}`);
|
||||
if (process.platform === "win32") {
|
||||
await exec(`.\\output\\win-unpacked\\Notesnook.exe`);
|
||||
} else if (process.platform === "darwin") {
|
||||
|
||||
@@ -29,7 +29,7 @@ import { dirname } from "path";
|
||||
import { resolvePath } from "../utils/resolve-path";
|
||||
import { observable } from "@trpc/server/observable";
|
||||
import { AssetManager } from "../utils/asset-manager";
|
||||
import { isFlatpak, isSnap } from "../utils";
|
||||
import { isFlatpak } from "../utils";
|
||||
import { setupDesktopIntegration } from "../utils/desktop-integration";
|
||||
import { rm } from "fs/promises";
|
||||
import { disableCustomDns, enableCustomDns } from "../utils/custom-dns";
|
||||
@@ -49,7 +49,6 @@ const NotificationOptions = z.object({
|
||||
|
||||
export const osIntegrationRouter = t.router({
|
||||
isFlatpak: t.procedure.query(() => isFlatpak()),
|
||||
isSnap: t.procedure.query(() => isSnap()),
|
||||
|
||||
zoomFactor: t.procedure.query(() => config.zoomFactor),
|
||||
setZoomFactor: t.procedure.input(z.number()).mutation(({ input: factor }) => {
|
||||
|
||||
@@ -23,7 +23,6 @@ import { CancellationToken, autoUpdater } from "electron-updater";
|
||||
import type { AppUpdaterEvents } from "electron-updater/out/AppUpdater";
|
||||
import { z } from "zod";
|
||||
import { config } from "../utils/config";
|
||||
import { app } from "electron";
|
||||
|
||||
type UpdateInfo = { version: string };
|
||||
type Progress = { percent: number };
|
||||
@@ -34,7 +33,6 @@ let downloadTimeout: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
export const updaterRouter = t.router({
|
||||
autoUpdates: t.procedure.query(() => config.automaticUpdates),
|
||||
releaseTrack: t.procedure.query(() => config.releaseTrack),
|
||||
install: t.procedure.query(() => autoUpdater.quitAndInstall()),
|
||||
download: t.procedure.query(async () => {
|
||||
if (cancellationToken) return;
|
||||
@@ -69,13 +67,7 @@ export const updaterRouter = t.router({
|
||||
.mutation(({ input: { enabled } }) => {
|
||||
config.automaticUpdates = enabled;
|
||||
}),
|
||||
changeReleaseTrack: t.procedure
|
||||
.input(z.object({ track: z.string() }))
|
||||
.mutation(({ input: { track } }) => {
|
||||
config.releaseTrack = track;
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}),
|
||||
|
||||
onChecking: createSubscription("checking-for-update"),
|
||||
onDownloaded: createSubscription<"update-downloaded", UpdateInfo>(
|
||||
"update-downloaded"
|
||||
|
||||
@@ -85,8 +85,6 @@ async function createWindow() {
|
||||
const mainWindowState = new WindowState({});
|
||||
const mainWindow = new BrowserWindow({
|
||||
show: !cliOptions.hidden,
|
||||
paintWhenInitiallyHidden: cliOptions.hidden,
|
||||
skipTaskbar: cliOptions.hidden,
|
||||
x: mainWindowState.x,
|
||||
y: mainWindowState.y,
|
||||
width: mainWindowState.width,
|
||||
@@ -103,10 +101,7 @@ async function createWindow() {
|
||||
...(config.desktopSettings.nativeTitlebar
|
||||
? {}
|
||||
: {
|
||||
titleBarStyle:
|
||||
process.platform === "win32" || process.platform === "darwin"
|
||||
? "hidden"
|
||||
: "default",
|
||||
titleBarStyle: process.platform === "win32" || process.platform === "darwin" ? "hidden" : "default",
|
||||
frame: process.platform === "win32" || process.platform === "darwin",
|
||||
titleBarOverlay: {
|
||||
height: 37,
|
||||
@@ -147,11 +142,6 @@ async function createWindow() {
|
||||
await AssetManager.loadIcons();
|
||||
setupDesktopIntegration(config.desktopSettings);
|
||||
|
||||
mainWindow.webContents.session.setPermissionRequestHandler(
|
||||
(webContents, permission, callback) => {
|
||||
callback(permission === "geolocation" ? false : true);
|
||||
}
|
||||
);
|
||||
mainWindow.webContents.session.setSpellCheckerDictionaryDownloadURL(
|
||||
"http://dictionaries.notesnook.com/"
|
||||
);
|
||||
|
||||
@@ -20,22 +20,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { autoUpdater } from "electron-updater";
|
||||
import { config } from "./config";
|
||||
|
||||
const CHANNEL = autoUpdater.currentVersion.raw.endsWith("-beta")
|
||||
? "beta"
|
||||
: "latest";
|
||||
async function configureAutoUpdater() {
|
||||
const releaseTrack =
|
||||
config.releaseTrack === "stable" ? "latest" : config.releaseTrack;
|
||||
autoUpdater.setFeedURL({
|
||||
provider: "generic",
|
||||
url: `https://notesnook.com/api/v1/releases/${process.platform}/${releaseTrack}`,
|
||||
url: `https://notesnook.com/api/v1/releases/${process.platform}/${CHANNEL}`,
|
||||
useMultipleRangeRequest: false,
|
||||
channel: releaseTrack
|
||||
channel: CHANNEL
|
||||
});
|
||||
|
||||
autoUpdater.autoDownload = config.automaticUpdates;
|
||||
autoUpdater.allowDowngrade =
|
||||
// only allow downgrade if the current version is a prerelease
|
||||
// and the user has changed the release track to stable
|
||||
config.releaseTrack === "stable" &&
|
||||
autoUpdater.currentVersion.prerelease.length > 0;
|
||||
autoUpdater.allowDowngrade = false;
|
||||
autoUpdater.allowPrerelease = false;
|
||||
autoUpdater.autoInstallOnAppQuit = true;
|
||||
autoUpdater.disableWebInstaller = true;
|
||||
|
||||
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { nativeTheme } from "electron";
|
||||
import { JSONStorage } from "./json-storage";
|
||||
import { z } from "zod";
|
||||
import { autoUpdater } from "electron-updater";
|
||||
|
||||
export const DesktopIntegration = z.object({
|
||||
autoStart: z.boolean().optional(),
|
||||
@@ -47,9 +46,6 @@ export const config = {
|
||||
automaticUpdates: true,
|
||||
proxyRules: "",
|
||||
customDns: true,
|
||||
releaseTrack: autoUpdater.currentVersion.raw.includes("-beta")
|
||||
? "beta"
|
||||
: "stable",
|
||||
|
||||
backgroundColor: nativeTheme.themeSource === "dark" ? "#0f0f0f" : "#ffffff",
|
||||
windowControlsIconColor:
|
||||
|
||||
@@ -29,7 +29,3 @@ export function isDevelopment() {
|
||||
export function isFlatpak() {
|
||||
return existsSync("/.flatpak-info");
|
||||
}
|
||||
|
||||
export function isSnap() {
|
||||
return process.env.SNAP !== undefined;
|
||||
}
|
||||
|
||||
@@ -1,40 +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 { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
testTimeout: process.env.CI ? 120 * 1000 : 120 * 1000,
|
||||
sequence: {
|
||||
concurrent: true,
|
||||
shuffle: true
|
||||
},
|
||||
dir: "./__tests__/",
|
||||
exclude: [
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/cypress/**",
|
||||
"**/.{idea,git,cache,output,temp}/**",
|
||||
"**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*",
|
||||
"**/test-results/**",
|
||||
"**/test-artifacts/**"
|
||||
]
|
||||
}
|
||||
});
|
||||
@@ -39,6 +39,7 @@ import SettingsService from "./services/settings";
|
||||
import { TipManager } from "./services/tip-manager";
|
||||
import { useThemeStore } from "./stores/use-theme-store";
|
||||
import { useUserStore } from "./stores/use-user-store";
|
||||
import { IntentService } from "./services/intent";
|
||||
|
||||
I18nManager.allowRTL(false);
|
||||
I18nManager.forceRTL(false);
|
||||
@@ -48,6 +49,7 @@ if (appLockEnabled || appLockMode !== "none") {
|
||||
useUserStore.getState().lockApp(true);
|
||||
}
|
||||
|
||||
IntentService.onLaunch();
|
||||
const App = (props: { configureMode: "note-preview" }) => {
|
||||
useAppEvents();
|
||||
//@ts-ignore
|
||||
|
||||
@@ -115,7 +115,7 @@ export const FileSizeResult = {
|
||||
Error: -1
|
||||
};
|
||||
|
||||
export async function getUploadedFileSize(hash: string, retry = 0) {
|
||||
export async function getUploadedFileSize(hash: string) {
|
||||
try {
|
||||
const url = `${hosts.API_HOST}/s3?name=${hash}`;
|
||||
const token = await db.tokenManager.getAccessToken();
|
||||
@@ -123,24 +123,8 @@ export async function getUploadedFileSize(hash: string, retry = 0) {
|
||||
method: "HEAD",
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
|
||||
if (
|
||||
!attachmentInfo.ok ||
|
||||
attachmentInfo.headers?.get("content-length") === null
|
||||
) {
|
||||
if (retry < 3) {
|
||||
DatabaseLogger.log(`Retrying file size check: ${hash}, ${retry}`);
|
||||
return getUploadedFileSize(hash, retry + 1);
|
||||
}
|
||||
throw new Error(
|
||||
`File size check failed: ${hash}, ${
|
||||
attachmentInfo.status
|
||||
}, ${attachmentInfo.headers?.get("content-length")}`
|
||||
);
|
||||
}
|
||||
|
||||
const contentLength = parseInt(
|
||||
attachmentInfo.headers?.get("content-length") as string
|
||||
attachmentInfo.headers?.get("content-length") || "0"
|
||||
);
|
||||
return isNaN(contentLength) ? FileSizeResult.Empty : contentLength;
|
||||
} catch (e) {
|
||||
|
||||
@@ -112,19 +112,14 @@ const AppLockedOverlay = () => {
|
||||
if (
|
||||
!biometricsAuthEnabled ||
|
||||
!(await BiometricService.isBiometryAvailable())
|
||||
) {
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
biometricUnlockAwaitingUserInput.current = true;
|
||||
|
||||
if (Platform.OS === "android") {
|
||||
const activityName = await NotesnookModule.getActivityName();
|
||||
if (
|
||||
activityName !== "MainActivity" &&
|
||||
activityName !== "NotePreviewConfigureActivity"
|
||||
)
|
||||
return;
|
||||
if (activityName !== "MainActivity") return;
|
||||
}
|
||||
useSettingStore.getState().setRequestBiometrics(true);
|
||||
|
||||
@@ -185,6 +180,7 @@ const AppLockedOverlay = () => {
|
||||
DatabaseLogger.info("Locking app on entering foreground");
|
||||
useUserStore.getState().lockApp(true);
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
biometricUnlockAwaitingUserInput.current ||
|
||||
|
||||
@@ -80,9 +80,8 @@ export const Dialog = ({ context = "global" }) => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
setChecked(false);
|
||||
values.current.inputValue = undefined;
|
||||
setVisible(false);
|
||||
|
||||
hide();
|
||||
};
|
||||
|
||||
const show = useCallback(
|
||||
@@ -105,14 +104,14 @@ export const Dialog = ({ context = "global" }) => {
|
||||
eUnSubscribeEvent(eOpenSimpleDialog, show);
|
||||
eUnSubscribeEvent(eCloseSimpleDialog, hide);
|
||||
};
|
||||
}, [hide, show]);
|
||||
}, [show]);
|
||||
|
||||
const hide = React.useCallback(() => {
|
||||
const hide = () => {
|
||||
setChecked(false);
|
||||
values.current.inputValue = undefined;
|
||||
setVisible(false);
|
||||
dialogInfo.onClose?.();
|
||||
}, [dialogInfo]);
|
||||
dialogInfo.onClose();
|
||||
};
|
||||
|
||||
const onNegativePress = async () => {
|
||||
if (dialogInfo.onClose) {
|
||||
|
||||
@@ -76,8 +76,7 @@ const NoteItem = ({
|
||||
}: NoteItemProps) => {
|
||||
const isEditingNote = useTabStore(
|
||||
(state) =>
|
||||
state.tabs.find((t) => t.id === state.currentTab)?.session?.noteId ===
|
||||
item.id
|
||||
state.tabs.find((t) => t.id === state.currentTab)?.noteId === item.id
|
||||
);
|
||||
const { colors } = useThemeColors();
|
||||
const compactMode = useIsCompactModeEnabled(
|
||||
|
||||
@@ -28,8 +28,7 @@ export const Filler = ({ item, color }: { item: Item; color?: string }) => {
|
||||
const { colors } = useThemeColors();
|
||||
const isEditingNote = useTabStore(
|
||||
(state) =>
|
||||
state.tabs.find((t) => t.id === state.currentTab)?.session?.noteId ===
|
||||
item.id
|
||||
state.tabs.find((t) => t.id === state.currentTab)?.noteId === item.id
|
||||
);
|
||||
|
||||
const [selected] = useIsSelected(item);
|
||||
|
||||
@@ -50,7 +50,6 @@ import { MMKV } from "../common/database/mmkv";
|
||||
import { endProgress, startProgress } from "../components/dialogs/progress";
|
||||
import Migrate from "../components/sheets/migrate";
|
||||
import NewFeature from "../components/sheets/new-feature";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { Walkthrough } from "../components/walkthroughs";
|
||||
import {
|
||||
resetTabStore,
|
||||
@@ -59,8 +58,7 @@ import {
|
||||
import {
|
||||
clearAppState,
|
||||
editorController,
|
||||
editorState,
|
||||
setAppState
|
||||
editorState
|
||||
} from "../screens/editor/tiptap/utils";
|
||||
import { useDragState } from "../screens/settings/editor/state";
|
||||
import BackupService from "../services/backup";
|
||||
@@ -71,6 +69,7 @@ import {
|
||||
eSubscribeEvent,
|
||||
presentSheet
|
||||
} from "../services/event-manager";
|
||||
import { IntentService } from "../services/intent";
|
||||
import {
|
||||
clearMessage,
|
||||
setEmailVerifyMessage,
|
||||
@@ -99,6 +98,7 @@ import {
|
||||
eLoginSessionExpired,
|
||||
eOnLoadNote,
|
||||
eOpenAnnouncementDialog,
|
||||
eUnlockNote,
|
||||
eUserLoggedIn,
|
||||
refreshNotesPage
|
||||
} from "../utils/events";
|
||||
@@ -106,6 +106,7 @@ import { getGithubVersion } from "../utils/github-version";
|
||||
import { tabBarRef } from "../utils/global-refs";
|
||||
import { NotesnookModule } from "../utils/notesnook-module";
|
||||
import { sleep } from "../utils/time";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
|
||||
const onCheckSyncStatus = async (type: SyncStatusEvent) => {
|
||||
const { disableSync, disableAutoSync } = SettingsService.get();
|
||||
@@ -161,6 +162,7 @@ const onUserSessionExpired = async () => {
|
||||
const onAppOpenedFromURL = async (event: { url: string }) => {
|
||||
const url = event.url;
|
||||
|
||||
console.log("URL", url);
|
||||
try {
|
||||
if (url.startsWith("https://app.notesnook.com/account/verified")) {
|
||||
await onUserEmailVerified();
|
||||
@@ -749,15 +751,13 @@ export const useAppEvents = () => {
|
||||
setTimeout(() => {
|
||||
sub = AppState.addEventListener("change", onAppStateChanged);
|
||||
if (
|
||||
refValues.current.initialUrl &&
|
||||
!refValues.current.initialUrl?.includes("open_note")
|
||||
refValues.current.initialUrl?.startsWith(
|
||||
"https://app.notesnook.com/account/verified"
|
||||
)
|
||||
) {
|
||||
onAppOpenedFromURL({
|
||||
url: refValues.current.initialUrl!
|
||||
});
|
||||
onUserEmailVerified();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
refValues.current.removeInternetStateListener = NetInfo.addEventListener(
|
||||
onInternetStateChanged
|
||||
);
|
||||
|
||||
@@ -17,7 +17,6 @@ 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 { strings } from "@notesnook/intl";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { NavigationContainer } from "@react-navigation/native";
|
||||
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||
@@ -45,6 +44,10 @@ import useNavigationStore from "../stores/use-navigation-store";
|
||||
import { useSelectionStore } from "../stores/use-selection-store";
|
||||
import { useSettingStore } from "../stores/use-setting-store";
|
||||
import { rootNavigatorRef } from "../utils/global-refs";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { IntentService } from "../services/intent";
|
||||
import ReminderSheet from "../components/sheets/reminder";
|
||||
import { db } from "../common/database";
|
||||
|
||||
const NativeStack = createNativeStackNavigator();
|
||||
const IntroStack = createNativeStackNavigator();
|
||||
@@ -83,6 +86,17 @@ const _Tabs = () => {
|
||||
React.useEffect(() => {
|
||||
setTimeout(async () => {
|
||||
useNavigationStore.getState().update(homepage);
|
||||
const intent = IntentService.getLaunchIntent();
|
||||
if (intent && intent["com.streetwriters.notesnook.OpenReminderId"]) {
|
||||
const reminder = await db.reminders.reminder(
|
||||
intent["com.streetwriters.notesnook.OpenReminderId"]
|
||||
);
|
||||
if (reminder) {
|
||||
ReminderSheet.present(reminder);
|
||||
}
|
||||
} else if (intent["com.streetwriters.notesnook.NewReminder"]) {
|
||||
ReminderSheet.present();
|
||||
}
|
||||
}, 1000);
|
||||
}, [homepage]);
|
||||
|
||||
|
||||
@@ -509,8 +509,7 @@ const onChangeTab = async (event) => {
|
||||
});
|
||||
} else {
|
||||
if (
|
||||
useTabStore.getState().getTab(useTabStore.getState().currentTab).session
|
||||
?.locked
|
||||
useTabStore.getState().getTab(useTabStore.getState().currentTab).locked
|
||||
) {
|
||||
eSendEvent(eUnlockNote);
|
||||
}
|
||||
@@ -524,7 +523,7 @@ const onChangeTab = async (event) => {
|
||||
|
||||
// Lock all tabs with locked notes...
|
||||
for (const tab of useTabStore.getState().tabs) {
|
||||
const noteId = useTabStore.getState().getTab(tab.id)?.session?.noteId;
|
||||
const noteId = useTabStore.getState().getTab(tab.id)?.noteId;
|
||||
if (!noteId) continue;
|
||||
const note = await db.notes.note(noteId);
|
||||
const locked = note && (await db.vaults.itemExists(note));
|
||||
|
||||
@@ -248,13 +248,14 @@ const useLockedNoteHandler = () => {
|
||||
);
|
||||
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note,
|
||||
refresh: true
|
||||
item: note
|
||||
});
|
||||
|
||||
useTabStore.getState().updateTab(tabRef.current.id, {
|
||||
session: {
|
||||
locked: false
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (tabRef.current && tabRef.current.session?.locked) {
|
||||
editorController.current?.commands.focusPassInput();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@@ -309,8 +310,12 @@ const useLockedNoteHandler = () => {
|
||||
}
|
||||
}
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note,
|
||||
refresh: true
|
||||
item: note
|
||||
});
|
||||
useTabStore.getState().updateTab(tabRef.current.id, {
|
||||
session: {
|
||||
locked: false
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
ToastManager.show({
|
||||
|
||||
@@ -90,14 +90,8 @@ class Commands {
|
||||
|
||||
const locked = useTabStore.getState().getTab(tabId)?.session?.locked;
|
||||
if (Platform.OS === "android") {
|
||||
//this.ref.current?.requestFocus();
|
||||
setTimeout(async () => {
|
||||
if (
|
||||
locked &&
|
||||
useTabStore.getState().biometryAvailable &&
|
||||
useTabStore.getState().biometryEnrolled
|
||||
)
|
||||
return;
|
||||
|
||||
if (!this.ref) return;
|
||||
textInput.current?.focus();
|
||||
await this.sendCommand("focus", tabId, locked);
|
||||
@@ -176,13 +170,13 @@ class Commands {
|
||||
await this.sendCommand("clearTags", tabId);
|
||||
};
|
||||
|
||||
insertAttachment = async (attachment: Attachment, tabId: string) => {
|
||||
insertAttachment = async (attachment: Attachment, tabId: number) => {
|
||||
await this.sendCommand("insertAttachment", attachment, tabId);
|
||||
};
|
||||
|
||||
setAttachmentProgress = async (
|
||||
attachmentProgress: Partial<Attachment>,
|
||||
tabId: string
|
||||
tabId: number
|
||||
) => {
|
||||
await this.sendCommand("setAttachmentProgress", attachmentProgress, tabId);
|
||||
};
|
||||
@@ -191,7 +185,7 @@ class Commands {
|
||||
image: Omit<ImageAttributes, "bloburl"> & {
|
||||
dataurl: string;
|
||||
},
|
||||
tabId: string
|
||||
tabId: number
|
||||
) => {
|
||||
await this.sendCommand("insertImage", image, tabId);
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ const santizeUri = (uri: string) => {
|
||||
|
||||
type PickerOptions = {
|
||||
noteId?: string;
|
||||
tabId?: string;
|
||||
tabId?: number;
|
||||
type: "image" | "camera" | "file";
|
||||
reupload: boolean;
|
||||
hash?: string;
|
||||
|
||||
@@ -613,7 +613,7 @@ export const useEditorEvents = (
|
||||
}
|
||||
case EditorEvents.tabFocused: {
|
||||
eSendEvent(eEditorTabFocused, editorMessage.tabId);
|
||||
if (!editor.state.current.initialLoadCalled) break;
|
||||
|
||||
if (editorMessage.noteId) {
|
||||
if (!useSettingStore.getState().isAppLoading) {
|
||||
const note = await db.notes.note(editorMessage.noteId);
|
||||
|
||||
@@ -77,7 +77,6 @@ import {
|
||||
isEditorLoaded,
|
||||
post
|
||||
} from "./utils";
|
||||
import { Linking } from "react-native";
|
||||
|
||||
const loadNoteMutex = new Mutex();
|
||||
|
||||
@@ -127,8 +126,15 @@ class LocalTabState {
|
||||
tabSession?.readonly !== readonly ||
|
||||
!noteId
|
||||
) {
|
||||
console.log("tab is refreshing...");
|
||||
return true;
|
||||
}
|
||||
console.log(
|
||||
"Tab refreshing...",
|
||||
state.editedAt < this.noteEditedTime[noteId]
|
||||
);
|
||||
|
||||
console.log(state.editedAt, this.noteEditedTime[noteId]);
|
||||
|
||||
return !state.editedAt || state.editedAt < this.noteEditedTime[noteId];
|
||||
}
|
||||
@@ -494,7 +500,6 @@ export const useEditor = (
|
||||
blockId?: string;
|
||||
session?: TabSessionItem;
|
||||
newTab?: boolean;
|
||||
refresh?: boolean;
|
||||
}) => {
|
||||
loadNoteMutex.runExclusive(async () => {
|
||||
if (!event) return;
|
||||
@@ -515,12 +520,7 @@ export const useEditor = (
|
||||
}
|
||||
if (event.newNote && !currentLoadingNoteId.current) {
|
||||
let tabId;
|
||||
|
||||
const currentTab = useTabStore
|
||||
.getState()
|
||||
.getTab(useTabStore.getState().currentTab as string);
|
||||
|
||||
if (useTabStore.getState().tabs.length === 0 || currentTab?.pinned) {
|
||||
if (useTabStore.getState().tabs.length === 0) {
|
||||
tabId = useTabStore.getState().newTab();
|
||||
} else {
|
||||
tabId = useTabStore.getState().currentTab;
|
||||
@@ -545,14 +545,14 @@ export const useEditor = (
|
||||
|
||||
const item = event.item;
|
||||
|
||||
const currentTab = useTabStore
|
||||
.getState()
|
||||
.getTab(useTabStore.getState().currentTab as string);
|
||||
|
||||
// If note is already open in a tab, focus that tab.
|
||||
if (useTabStore.getState().hasTabForNote(item.id) && !event.newTab) {
|
||||
const tabId = useTabStore.getState().getTabForNote(item.id);
|
||||
|
||||
const currentTab = useTabStore
|
||||
.getState()
|
||||
.getTab(useTabStore.getState().currentTab as string);
|
||||
|
||||
if (
|
||||
currentTab?.session?.noteId !== item.id &&
|
||||
tabId !== useTabStore.getState().currentTab
|
||||
@@ -573,10 +573,11 @@ export const useEditor = (
|
||||
? event.tabId
|
||||
: useTabStore.getState().currentTab;
|
||||
|
||||
console.log(tabId === useTabStore.getState().currentTab);
|
||||
|
||||
// Check if tab needs to be refreshed.
|
||||
if (!event.newTab) {
|
||||
if (
|
||||
!event.refresh &&
|
||||
tabId &&
|
||||
event.item.id === useTabStore.getState().getNoteIdForTab(tabId) &&
|
||||
!localTabState.current?.needsRefresh(
|
||||
@@ -622,16 +623,10 @@ export const useEditor = (
|
||||
|
||||
const tab = useTabStore.getState().getTab(tabId!);
|
||||
|
||||
if (
|
||||
useTabStore.getState().tabs.length === 0 ||
|
||||
event.newTab ||
|
||||
(currentTab?.pinned &&
|
||||
event.item.id !== currentTab?.session?.noteId)
|
||||
) {
|
||||
if (useTabStore.getState().tabs.length === 0 || event.newTab) {
|
||||
useTabStore.getState().newTab({
|
||||
session: session
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// A new session is created if the note is changed.
|
||||
// If the note is already opened, the session is updated.
|
||||
@@ -1044,17 +1039,6 @@ export const useEditor = (
|
||||
}, [isDefaultEditor, restoreEditorState]);
|
||||
|
||||
const onLoad = useCallback(async () => {
|
||||
const isAppLoading = useSettingStore.getState().isAppLoading;
|
||||
if (isAppLoading) {
|
||||
const sub = useSettingStore.subscribe((state) => {
|
||||
if (!state.isAppLoading) {
|
||||
sub();
|
||||
onLoad();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
postMessage(NativeEvents.theme, theme);
|
||||
});
|
||||
@@ -1071,34 +1055,32 @@ export const useEditor = (
|
||||
state.current.ready = true;
|
||||
}
|
||||
|
||||
if (!state.current?.initialLoadCalled) {
|
||||
const url = await Linking.getInitialURL();
|
||||
let noteId = url && new URL(url).searchParams.get("id");
|
||||
if (noteId) {
|
||||
const note = await db.notes?.note(noteId);
|
||||
const appState = getAppState();
|
||||
if (appState?.noteId) {
|
||||
const note = await db.notes?.note(appState.noteId);
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const noteId = useTabStore.getState().getCurrentNoteId();
|
||||
if (!noteId) {
|
||||
loadNote({ newNote: true });
|
||||
if (tabBarRef.current?.page() === 1) {
|
||||
state.current.currentlyEditing = false;
|
||||
}
|
||||
} else if (state.current?.initialLoadCalled) {
|
||||
const note = currentNotes.current[noteId];
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
tabBarRef.current?.goToPage(1);
|
||||
} else {
|
||||
noteId = useTabStore.getState().getCurrentNoteId() || null;
|
||||
if (!noteId) {
|
||||
loadNote({ newNote: true });
|
||||
if (tabBarRef.current?.page() === 1) {
|
||||
state.current.currentlyEditing = false;
|
||||
}
|
||||
} else {
|
||||
const note = await db.notes.note(noteId);
|
||||
if (note) {
|
||||
loadNote({
|
||||
item: note
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
state.current.initialLoadCalled = true;
|
||||
if (!state.current?.initialLoadCalled) {
|
||||
state.current.initialLoadCalled = true;
|
||||
}
|
||||
overlay(false);
|
||||
}
|
||||
}, [
|
||||
|
||||
@@ -97,12 +97,10 @@ class TabSessionStorage {
|
||||
static storage: typeof TabSessionStorageKV = TabSessionStorageKV;
|
||||
|
||||
static get(id: string): TabSessionItem | null {
|
||||
if (!id) return null;
|
||||
return TabSessionStorage.storage.getMap(id);
|
||||
}
|
||||
|
||||
static set(id: string, session: TabSessionItem): void {
|
||||
if (!id) return;
|
||||
TabSessionStorage.storage.setMap(id, session);
|
||||
}
|
||||
|
||||
@@ -110,16 +108,13 @@ class TabSessionStorage {
|
||||
const currentSession = TabSessionStorage.get(id);
|
||||
const newSession = {
|
||||
...currentSession,
|
||||
...session,
|
||||
id: currentSession?.id || session.id || id
|
||||
...session
|
||||
};
|
||||
|
||||
TabSessionStorage.set(id, newSession as TabSessionItem);
|
||||
return newSession;
|
||||
}
|
||||
|
||||
static remove(id: string) {
|
||||
if (!id) return;
|
||||
TabSessionStorageKV.removeItem(id);
|
||||
}
|
||||
}
|
||||
@@ -169,7 +164,7 @@ const history = new TabHistory();
|
||||
|
||||
export type TabStore = {
|
||||
tabs: TabItem[];
|
||||
currentTab: string;
|
||||
currentTab?: string;
|
||||
updateTab: (id: string, options: Omit<Partial<TabItem>, "id">) => void;
|
||||
focusPreviewTab: (
|
||||
noteId: string,
|
||||
@@ -269,7 +264,6 @@ export const useTabStore = create<TabStore>(
|
||||
TabSessionStorage.set(sessionId, session as TabSessionItem);
|
||||
} else {
|
||||
session = {
|
||||
id: sessionId,
|
||||
...TabSessionStorage.get(oldSessionId),
|
||||
...options
|
||||
};
|
||||
@@ -295,7 +289,6 @@ export const useTabStore = create<TabStore>(
|
||||
const tabs = [...get().tabs];
|
||||
const sessionId =
|
||||
options.session?.id || (tabs[index].session?.id as string);
|
||||
|
||||
const updatedSession = !options.session
|
||||
? tabs[index].session
|
||||
: TabSessionStorage.update(sessionId, options.session);
|
||||
@@ -320,15 +313,13 @@ export const useTabStore = create<TabStore>(
|
||||
const sessionLoaded = await get().loadSession(id);
|
||||
|
||||
if (!sessionLoaded) {
|
||||
const canGoBack = tabSessionHistory.canGoBack(currentTab);
|
||||
if (!canGoBack) {
|
||||
tabSessionHistory.remove(currentTab, id);
|
||||
TabSessionStorage.remove(id);
|
||||
if (!tabSessionHistory.canGoBack(currentTab)) {
|
||||
tabSessionHistory.forward(currentTab);
|
||||
syncTabs();
|
||||
} else {
|
||||
get().goBack();
|
||||
tabSessionHistory.remove(currentTab, id);
|
||||
TabSessionStorage.remove(id);
|
||||
return;
|
||||
return get().goBack();
|
||||
}
|
||||
} else {
|
||||
syncTabs();
|
||||
@@ -341,15 +332,13 @@ export const useTabStore = create<TabStore>(
|
||||
if (!tabSessionHistory.canGoForward(currentTab)) return;
|
||||
const id = tabSessionHistory.forward(currentTab) as string;
|
||||
if (!(await get().loadSession(id))) {
|
||||
const canGoForward = tabSessionHistory.canGoForward(currentTab);
|
||||
if (!canGoForward) {
|
||||
tabSessionHistory.remove(currentTab, id);
|
||||
TabSessionStorage.remove(id);
|
||||
if (!tabSessionHistory.canGoForward(currentTab)) {
|
||||
tabSessionHistory.back(currentTab);
|
||||
syncTabs();
|
||||
} else {
|
||||
get().goForward();
|
||||
tabSessionHistory.remove(currentTab, id);
|
||||
TabSessionStorage.remove(id);
|
||||
return;
|
||||
return get().goForward();
|
||||
}
|
||||
} else {
|
||||
syncTabs();
|
||||
@@ -365,8 +354,8 @@ export const useTabStore = create<TabStore>(
|
||||
|
||||
if (note) {
|
||||
const isLocked = await db.vaults.itemExists(note);
|
||||
session.noteLocked = isLocked;
|
||||
session.locked = isLocked;
|
||||
session.noteLocked = isLocked && !session?.noteLocked;
|
||||
|
||||
session.readonly = note.readonly;
|
||||
} else if (session.noteId) {
|
||||
@@ -406,7 +395,7 @@ export const useTabStore = create<TabStore>(
|
||||
set({
|
||||
tabs: [{ id: id }]
|
||||
});
|
||||
get().newTabSession(id);
|
||||
get().newTabSession(id, {});
|
||||
get().focusTab(id);
|
||||
} else {
|
||||
set({
|
||||
@@ -485,7 +474,7 @@ export const useTabStore = create<TabStore>(
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "tabs-storage-v5",
|
||||
name: "tabs-storage-v3",
|
||||
getStorage: () => MMKV as unknown as StateStorage,
|
||||
onRehydrateStorage: () => {
|
||||
return (state) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
StackActions,
|
||||
useNavigation
|
||||
} from "@react-navigation/native";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { ActivityIndicator, TextInput, View } from "react-native";
|
||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||
import ToggleSwitch from "toggle-switch-react-native";
|
||||
@@ -41,10 +41,7 @@ import { RouteParams, SettingSection } from "./types";
|
||||
|
||||
const _SectionItem = ({ item }: { item: SettingSection }) => {
|
||||
const { colors } = useThemeColors();
|
||||
const [settings, itemProperty] = useSettingStore((state) => [
|
||||
state.settings,
|
||||
item.property ? state.settings[item.property] : null
|
||||
]);
|
||||
const settings = useSettingStore((state) => state.settings);
|
||||
const navigation = useNavigation<NavigationProp<RouteParams>>();
|
||||
const current = item.useHook && item.useHook(item);
|
||||
const [isHidden, setIsHidden] = useState(
|
||||
@@ -106,11 +103,6 @@ const _SectionItem = ({ item }: { item: SettingSection }) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setIsHidden(item.hidden && item.hidden(item.property || current));
|
||||
setIsDisabled(item.disabled && item.disabled(item.property || current));
|
||||
}, [current, item, itemProperty]);
|
||||
|
||||
return isHidden ? null : (
|
||||
<Pressable
|
||||
disabled={item.type === "component" || isDisabled}
|
||||
|
||||
@@ -451,7 +451,7 @@ export const settingsGroups: SettingSection[] = [
|
||||
"local",
|
||||
"partial"
|
||||
);
|
||||
if (result?.error) throw result.error as Error;
|
||||
if (result.error) throw result.error as Error;
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e);
|
||||
const error = e;
|
||||
|
||||
@@ -169,11 +169,7 @@ async function run(
|
||||
progress = false,
|
||||
context?: string,
|
||||
backupType: "full" | "partial" = "partial"
|
||||
): Promise<{
|
||||
path?: string;
|
||||
error?: Error;
|
||||
report?: boolean;
|
||||
}> {
|
||||
) {
|
||||
if (backupRunning) {
|
||||
if (progress) {
|
||||
startProgress({
|
||||
@@ -183,7 +179,7 @@ async function run(
|
||||
canHideProgress: true
|
||||
});
|
||||
}
|
||||
return {};
|
||||
return;
|
||||
}
|
||||
backupRunning = true;
|
||||
const androidBackupDirectory = (await checkBackupDirExists(
|
||||
@@ -347,7 +343,7 @@ async function run(
|
||||
endProgress();
|
||||
}
|
||||
return {
|
||||
error: e as Error,
|
||||
error: e,
|
||||
report: true
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,17 +45,7 @@ function resetSettings() {
|
||||
...defaultSettings,
|
||||
introCompleted: true,
|
||||
serverUrls: get().serverUrls,
|
||||
backupDirectoryAndroid: get().backupDirectoryAndroid,
|
||||
darkTheme: get().darkTheme,
|
||||
lighTheme: get().lighTheme,
|
||||
useSystemTheme: get().useSystemTheme,
|
||||
colorScheme: get().colorScheme,
|
||||
defaultSnoozeTime: get().defaultSnoozeTime,
|
||||
defaultFontFamily: get().defaultFontFamily,
|
||||
defaultFontSize: get().defaultFontSize,
|
||||
privacyScreen: get().privacyScreen,
|
||||
corsProxy: get().corsProxy,
|
||||
showBackupCompleteSheet: get().showBackupCompleteSheet
|
||||
backupDirectoryAndroid: undefined
|
||||
};
|
||||
|
||||
MMKV.setString("appSettings", JSON.stringify(settings));
|
||||
|
||||
@@ -116,7 +116,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3042
|
||||
versionCode 3038
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
- Small bug fixes and improvements
|
||||
- New and improved editor tabs with history
|
||||
- Fixed homescreen widget bugs
|
||||
- Many small bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -1063,7 +1063,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1137,7 +1137,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1168,7 +1168,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1242,7 +1242,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1401,7 +1401,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1413,7 +1413,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1444,7 +1444,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1457,7 +1457,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1487,7 +1487,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1561,7 +1561,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1592,7 +1592,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2129;
|
||||
CURRENT_PROJECT_VERSION = 2125;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1667,7 +1667,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.0.32;
|
||||
MARKETING_VERSION = 3.0.28;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
@@ -1820,7 +1820,7 @@ SPEC CHECKSUMS:
|
||||
Base64: cecfb41a004124895a7bcee567a89bae5a89d49b
|
||||
BEMCheckBox: 5ba6e37ade3d3657b36caecc35c8b75c6c2b1a4e
|
||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||
callstack-repack: 721b034d0662f47388719bf26c00f838da6880d5
|
||||
callstack-repack: 2db7cbeced7cd5da360d01965e0b983f6dacfd54
|
||||
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
|
||||
FBLazyVector: ac12dc084d1c8ec4cc4d7b3cf1b0ebda6dab85af
|
||||
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
|
||||
@@ -1837,103 +1837,103 @@ SPEC CHECKSUMS:
|
||||
RCTTypeSafety: f5ecbc86c5c5fa163c05acb7a1c5012e15b5f994
|
||||
React: fc9fa7258eff606f44d58c5b233a82dc9cf09018
|
||||
React-callinvoker: e3fab14d69607fb7e8e3a57e5a415aed863d3599
|
||||
React-Codegen: ff6c425afab9288a1573337111741d30363bf962
|
||||
React-Core: c3f589f104983dec3c3eeec5e70d61aa811bc236
|
||||
React-CoreModules: 864932ddae3ead5af5bfb05f9bbc2cedcb958b39
|
||||
React-cxxreact: bd9146108c44e6dbb99bba4568ce7af0304a2419
|
||||
React-Codegen: 49efb5917c904b5b01ef708311a2f1773f4fe73e
|
||||
React-Core: 3a5fd9e781cecf87803e5b091496a606a3df774a
|
||||
React-CoreModules: cbf4707dafab8f9f826ac0c63a07d0bf5d01e256
|
||||
React-cxxreact: 7b188556271e3c7fdf22a04819f6a6225045b9dd
|
||||
React-debug: d30893c49ae1bce4037ea5cd8bb2511d2a38d057
|
||||
React-Fabric: a171830e52baf8ec2b175c6a3791e01bbb92f1fb
|
||||
React-FabricImage: ad154af0067f4b5dc5a41f607e48ee343641e903
|
||||
React-Fabric: 826729dd2304fda9b89ff0a579f60ba2a470bc26
|
||||
React-FabricImage: 2ad1fb8ffa5778eda9ed204a7b3cdd70bc333ce7
|
||||
React-featureflags: 4ae83e72d9a92452793601ac9ac7d2280e486089
|
||||
React-graphics: ed7d57965140168de86835946e8f1210c72c65dc
|
||||
React-hermes: 177b1efdf3b8f10f4ca12b624b83fb4d4ccb2884
|
||||
React-ImageManager: 3a50d0ee0bf81b1a6f23a0c5b30388293bcd6004
|
||||
React-jserrorhandler: dcd62f5ca1c724c19637595ef7f45b78018e758f
|
||||
React-jsi: 0abe1b0881b67caf8d8df6a57778dd0d3bb9d9a5
|
||||
React-jsiexecutor: f6ca8c04f19f6a3acaa9610f7fb728f39d6e3248
|
||||
React-jsinspector: db98771eae84e6f86f0ca5d9dcc572baadbfefc0
|
||||
React-jsitracing: f8367edacc50bb3f9f056a5aeafb8cee5849fafb
|
||||
React-logger: 780b9ee9cec7d44eabc4093de90107c379078cb6
|
||||
React-Mapbuffer: f544f00b98dbdd8cbae96dd2bdb8b47f719976e0
|
||||
react-native-actions-shortcuts: 65fb9cb4a58c71af7382663c1822dda061dbf1b0
|
||||
react-native-background-actions: 40e09df6ea8c7d2753f6c1d75f6f1eee4a9bc35f
|
||||
react-native-begin-background-task: 2191f2a84b0328932a3d44db4361e666fee781bb
|
||||
react-native-blob-util: 4be49d669870f01645b63d33342718e95d0d48b1
|
||||
react-native-config: 136f9755ccc991cc6438053a44363259ad4c7813
|
||||
react-native-date-picker: bbf77c50dce9da2beb11e2f67f3300195ba27d81
|
||||
react-native-document-picker: f4ccd6f6f369da1409e609788181eac66cc1a2d8
|
||||
react-native-fingerprint-scanner: 562585260768cad51ae48e4b505d28c8731aecfa
|
||||
react-native-get-random-values: 419569b6ed3d15bfb9b6781b2f2e058f8e8d2698
|
||||
react-native-gzip: 8d602277c2564591f04dd1cec4043acc8350dcc3
|
||||
react-native-html-to-pdf-lite: d606d3b72d9696c7a6d1e5f5b7536783faacef14
|
||||
react-native-image-resizer: ff3c9ab0ce235c4c00f49d0a373043cb4b8781be
|
||||
react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400
|
||||
react-native-keep-awake: bda639e941ce138506c18f1b999dcbf16d4c77b8
|
||||
react-native-mmkv-storage: 8dddc9d16248bc9a4d9566ac5c97c318692d299c
|
||||
react-native-netinfo: 66c9ac0d0ae92a57a9ed99ab8a75429740700c73
|
||||
react-native-notification-sounds: ce106d58df0dd384bccbd2e84fb53accab7cc068
|
||||
react-native-orientation: db2655b95b4123f17e75dcb04ee8b8b1294ce7ee
|
||||
react-native-pdf: da10473ae54555c373c62af671da8fe0eef846e2
|
||||
react-native-quick-sqlite: 80b5b3405bfc92e97b6041d2c2a446800bea6ad7
|
||||
react-native-safe-area-context: b72c4611af2e86d80a59ac76279043d8f75f454c
|
||||
react-native-screenguard: 82437eeb0086a90b5e5d7e54130bb04fb406373e
|
||||
react-native-share-extension: 7528322fe621b683e6b48ab3418207ed45a70983
|
||||
react-native-sodium: ed020d5f50ab1886f7bf23e32732d0d10e9373ac
|
||||
react-native-theme-switch-animation: 64f2688c2e3489ababc7b35f436fd3b5ed7c0a98
|
||||
react-native-webview: a71525b1ab760230fbf37303d8371fbe72051c7d
|
||||
React-graphics: 61a026e1c1e7e20d20ac9fec6f6de631732b233d
|
||||
React-hermes: a7054fbcbda3957e3c5eaad06ef9bf79998d535a
|
||||
React-ImageManager: 2bbd6eb2e696bc680f76f84563e4b87d241614e1
|
||||
React-jserrorhandler: 56fa04d49bfbe54ddfece7916673a73ebfea286b
|
||||
React-jsi: f3ce1dd2e950b6ad12b65ea3ef89168f1b94c584
|
||||
React-jsiexecutor: b4df3a27973d82f9abf3c4bd0f88e042cda25f16
|
||||
React-jsinspector: 97ea746c023687de7313ee289817d6991d596c7d
|
||||
React-jsitracing: 3b6060bbf5317663667e1dd93560c7943ab86ccc
|
||||
React-logger: 257858bd55f3a4e1bc0cf07ddc8fb9faba6f8c7c
|
||||
React-Mapbuffer: 6c1cacdbf40b531f549eba249e531a7d0bfd8e7f
|
||||
react-native-actions-shortcuts: 5d9cf0c9c308333dfcc1e05c3f9afa8c428e2533
|
||||
react-native-background-actions: 2c251c986f23347f9c1722f05fd296938f60edb1
|
||||
react-native-begin-background-task: 3b889e07458afc5822a7277cf9cbc7cd077e39ee
|
||||
react-native-blob-util: 2d36383bb52c15c5451be81cb7ddf22bc34a12a6
|
||||
react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8
|
||||
react-native-date-picker: 93e43b3084cea595b4d68b1405d6d99849663bd6
|
||||
react-native-document-picker: ec07866a30707f23660c0f3ae591d669d3e89096
|
||||
react-native-fingerprint-scanner: be63e626b31fb951780a5fac5328b065a61a3d6e
|
||||
react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
|
||||
react-native-gzip: c5e87ee9e359f02350e3a2ee52eb35eddc398868
|
||||
react-native-html-to-pdf-lite: 21bfb169bf4cbcd7bec9f736975ee1b3f5292d4a
|
||||
react-native-image-resizer: 00ceb0e05586c7aadf061eea676957a6c2ec60fa
|
||||
react-native-in-app-review: db8bb167a5f238e7ceca5c242d6b36ce8c4404a4
|
||||
react-native-keep-awake: caee3ff89eaa21dfe29010f0d143566874a04441
|
||||
react-native-mmkv-storage: 3892853c11ab8a0c3a3f9ef3b0657aa9a5f616c9
|
||||
react-native-netinfo: ccbe1085dffd16592791d550189772e13bf479e2
|
||||
react-native-notification-sounds: da78c828fe1bcbb92d8b505d5261890ed315ff39
|
||||
react-native-orientation: f1caf84d65f1a4fd4511a18f2b924e634ad7a628
|
||||
react-native-pdf: 33c622cbdf776a649929e8b9d1ce2d313347c4fa
|
||||
react-native-quick-sqlite: 18e1367c34faac90e37f6eb3e78c196e9b674b5d
|
||||
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
|
||||
react-native-screenguard: 8b36a3df84c76cd2b82c477f71c26fa1c8cc14a0
|
||||
react-native-share-extension: 01b25fc15faf2510cc2529e98ca444f64e46238d
|
||||
react-native-sodium: 4cb76086943a7f60c42b40ebca866695b360a196
|
||||
react-native-theme-switch-animation: d3eb50365a3829ce5572628888fa514752703f61
|
||||
react-native-webview: 553abd09f58e340fdc7746c9e2ae096839e99911
|
||||
React-nativeconfig: ba9a2e54e2f0882cf7882698825052793ed4c851
|
||||
React-NativeModulesApple: 84aaad2b0e546d7b839837ca537f6e72804a4cad
|
||||
React-NativeModulesApple: 8d11ff8955181540585c944cf48e9e7236952697
|
||||
React-perflogger: ed4e0c65781521e0424f2e5e40b40cc7879d737e
|
||||
React-RCTActionSheet: 49d53ff03bb5688ca4606c55859053a0cd129ea5
|
||||
React-RCTAnimation: 3075449f26cb98a52bcbf51cccd0c7954e2a71db
|
||||
React-RCTAppDelegate: 9a419c4dda9dd039ad851411546dd297b930c454
|
||||
React-RCTBlob: e81ab773a8fc1e9dceed953e889f936a7b7b3aa6
|
||||
React-RCTFabric: 47a87a3e3fa751674f7e64d0bcd58976b8c57db9
|
||||
React-RCTImage: d570531201c6dce7b5b63878fa8ecec0cc311c4c
|
||||
React-RCTLinking: af888972b925d2811633d47853c479e88c35eb4d
|
||||
React-RCTNetwork: 5728a06ff595003eca628f43f112a804f4a9a970
|
||||
React-RCTSettings: ba3665b0569714a8aaceee5c7d23b943e333fa55
|
||||
React-RCTText: b733fa984f0336b072e47512898ba91214f66ddb
|
||||
React-RCTVibration: 0cbcbbd8781b6f6123671bae9ee5dd20d621af6c
|
||||
React-rendererdebug: 9fc8f7d0bd19f2a3fe3791982af550b5e1535ff7
|
||||
React-RCTAnimation: 07b4923885c52c397c4ec103924bf6e53b42c73e
|
||||
React-RCTAppDelegate: 316e295076734baf9bdf1bfac7d92ab647aed930
|
||||
React-RCTBlob: 85c57b0d5e667ff8a472163ba3af0628171a64bb
|
||||
React-RCTFabric: 97c1465ded4dc92841f5376a39e43e1b2c455f40
|
||||
React-RCTImage: b965c85bec820e2a9c154b1fb00a2ecdd59a9c92
|
||||
React-RCTLinking: 75f04a5f27c26c4e73a39c50df470820d219df79
|
||||
React-RCTNetwork: c1a9143f4d5778efc92da40d83969d03912ccc24
|
||||
React-RCTSettings: c6800f91c0ecd48868cd5db754b0b0a7f5ffe039
|
||||
React-RCTText: b923e24f9b7250bc4f7ab154c4168ad9f8d8fc9d
|
||||
React-RCTVibration: 08c4f0c917c435b3619386c25a94ee5d64c250f0
|
||||
React-rendererdebug: 3cda04217d9df67b94397ee0ead8ef3d8b7e427b
|
||||
React-rncore: 4013508a2f3fcf46c961919bbbd4bfdda198977e
|
||||
React-RuntimeApple: a852a6e06ab20711658873f39cb10b0033bea19d
|
||||
React-RuntimeCore: 12e5e176c0cb09926f3e6f37403a84d2e0f203a7
|
||||
React-RuntimeApple: 447844a2bdb0a03ffd24e5b4a4b96cfc50325b88
|
||||
React-RuntimeCore: 9b5bffdaccee9b707b1c2694c9044e13ff0bb087
|
||||
React-runtimeexecutor: 0e688aefc14c6bc8601f4968d8d01c3fb6446844
|
||||
React-RuntimeHermes: 80c03a5215520c9733764ba11cbe535053c9746d
|
||||
React-runtimescheduler: 2cbd0f3625b30bba08e8768776107f6f0203159b
|
||||
React-utils: 9fa4e5d0b5e6c6c85c958f19d6ef854337886417
|
||||
ReactCommon: 9f285823dbe955099978d9bff65a7653ca029256
|
||||
RNBackgroundFetch: 0c49d5892a0e2f9c139e24ba498985cf0bf070c6
|
||||
RNBootSplash: 3bc12ecb62f69c5af6e6ddf0e6bef88f572ccdb5
|
||||
RNCCheckbox: df88c1c78a17869da84bb031c9d8185d417398a6
|
||||
RNCClipboard: efe1b27ad1ea378c60c8c8aabfd130961bbeb474
|
||||
RNCMaskedView: 4b5b12efdee55966f1d68f32d4b3401c2acf05c2
|
||||
RNDateTimePicker: 818460dc31b0dc5ec58289003e27dd8d022fb79c
|
||||
RNDeviceInfo: d3e91ffb33ee97a7982108476edb68cb3672efa6
|
||||
RNExitApp: 890cce29b4e01372c84b3b775f9a63f90d77de19
|
||||
RNFileViewer: 4b5d83358214347e4ab2d4ca8d5c1c90d869e251
|
||||
RNFlashList: fe872a2d1b4c859c64a7d7421628a1308ebb9e4f
|
||||
RNGestureHandler: 61302deb50c92cba160f5a11f00f69da48116724
|
||||
RNIap: aa38c2cc8a2a75ba8112d161ca084a0b611955df
|
||||
RNImageCropPicker: 30d770b383d84e1067d82ea7b5ed4fff851bbbb2
|
||||
RNKeychain: ffd0513e676445c637410b47249460cbf56bc9cb
|
||||
RNNotifee: b98fb71f678f6644fa48ec6d515ec6fcfc5214ba
|
||||
RNPrivacySnapshot: ccad3a548338c2f526bb7b1789af3fb0618b7d1d
|
||||
RNReanimated: bee9626cf4920f2910bf7c4f8a3dc569161a9475
|
||||
RNScreens: d0db5e9f28afd284a5193474d6be949f4cba888e
|
||||
RNSecureRandom: b64d263529492a6897e236a22a2c4249aa1b53dc
|
||||
RNShare: 5d7762ded21e1fff97dda6d41e963e22dce2d025
|
||||
RNSVG: d7cb8bd34550cf4c4fc7edd7ac627905e2b71f3f
|
||||
RNTooltips: 50ff94bd2bff84ef74279c9532d008f5fdcddb95
|
||||
RNZipArchive: 71befbdc20e7fbd4b64552a0b324ad0e8d0efefb
|
||||
React-RuntimeHermes: 4d6ef6bb0f2b0b40d59143317f6b99c82764c959
|
||||
React-runtimescheduler: cfbe85c3510c541ec6dc815c7729b41304b67961
|
||||
React-utils: f242eb7e7889419d979ca0e1c02ccc0ea6e43b29
|
||||
ReactCommon: f7da14a8827b72704169a48c929bcde802698361
|
||||
RNBackgroundFetch: 35c7183f6eeff69396d42c4b206e1ae2a21e9327
|
||||
RNBootSplash: de2c568373a9c79a66e9918b8929eb6c9a35246f
|
||||
RNCCheckbox: 43bcc6493611468af0e19f19f029dab3da8561c4
|
||||
RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc
|
||||
RNCMaskedView: 949696f25ec596bfc697fc88e6f95cf0c79669b6
|
||||
RNDateTimePicker: 40ffda97d071a98a10fdca4fa97e3977102ccd14
|
||||
RNDeviceInfo: aad3c663b25752a52bf8fce93f2354001dd185aa
|
||||
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
|
||||
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
|
||||
RNFlashList: e9b57a5553639f9b528cc50ab53f25831722ed62
|
||||
RNGestureHandler: 4fd316f1bdb8d7f6a54efc58da5923cb83014b19
|
||||
RNIap: 17583f958d35788a87948e94072ff6edd3580497
|
||||
RNImageCropPicker: d9616a0cb9b72e8551ff94a7a5021fbd29050aa5
|
||||
RNKeychain: 840f8e6f13be0576202aefcdffd26a4f54bfe7b5
|
||||
RNNotifee: 1448fd16c2a6f3e8abbc219801bf5be2435183e5
|
||||
RNPrivacySnapshot: 8eaf571478a353f2e5184f5c803164f22428b023
|
||||
RNReanimated: 7212582b487bceed64b2dbc6c15777b97922be21
|
||||
RNScreens: d2a12528d1abe4922e7ee5c9a00dd40c827c2ab5
|
||||
RNSecureRandom: 07efbdf2cd99efe13497433668e54acd7df49fef
|
||||
RNShare: 22717e910836a66cb7255b3b8c4ab06cbe346e27
|
||||
RNSVG: d7d7bc8229af3842c9cfc3a723c815a52cdd1105
|
||||
RNTooltips: 5424d4bf0b3d441104127943b1115cc7f0616b1f
|
||||
RNZipArchive: 9d90367b1573903b5561a8c0b911e5cc12626e74
|
||||
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
|
||||
SexyTooltip: 5c9b4dec52bfb317938cb0488efd9da3717bb6fd
|
||||
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
toolbar-android: c426ed5bd3dcccfed20fd79533efc0d1ae0ef018
|
||||
toolbar-android: 2a73856e98b750d7e71ce4644d3f41cc98211719
|
||||
Yoga: 950bbfd7e6f04790fdb51149ed51df41f329fcc8
|
||||
|
||||
PODFILE CHECKSUM: aa07aca16c1d92394d8ce12f2c5fcaa8a3ae4997
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"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"
|
||||
"@ammarahmed/react-native-share-extension": "^2.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"detox": "^20.27.6",
|
||||
|
||||
163
apps/mobile/package-lock.json
generated
163
apps/mobile/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.31",
|
||||
"version": "3.0.27",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.31",
|
||||
"version": "3.0.27",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -14,7 +14,6 @@
|
||||
"app/"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ammarahmed/react-native-share-extension": "^2.9.0",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/core": "file:../../packages/core",
|
||||
"@notesnook/crypto": "file:../../packages/crypto",
|
||||
@@ -7743,7 +7742,7 @@
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/@types/prop-types": {
|
||||
"version": "15.7.11",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/@types/q": {
|
||||
@@ -7763,7 +7762,7 @@
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/@types/react": {
|
||||
"version": "18.2.39",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
@@ -7794,7 +7793,7 @@
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/@types/semver": {
|
||||
@@ -12619,7 +12618,7 @@
|
||||
},
|
||||
"../../packages/editor-mobile/node_modules/immer": {
|
||||
"version": "9.0.21",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -23091,6 +23090,7 @@
|
||||
},
|
||||
"../../packages/editor/node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"../../packages/editor/node_modules/jsesc": {
|
||||
@@ -23141,6 +23141,7 @@
|
||||
},
|
||||
"../../packages/editor/node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
@@ -23652,6 +23653,7 @@
|
||||
},
|
||||
"../../packages/editor/node_modules/react": {
|
||||
"version": "18.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
@@ -23670,6 +23672,7 @@
|
||||
},
|
||||
"../../packages/editor/node_modules/react-dom": {
|
||||
"version": "18.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
@@ -23808,6 +23811,7 @@
|
||||
},
|
||||
"../../packages/editor/node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
@@ -28315,6 +28319,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.8.0",
|
||||
"@ammarahmed/react-native-sodium": "^1.6.1",
|
||||
"@bam.tech/react-native-image-resizer": "3.0.5",
|
||||
"@callstack/repack": "^4.1.1",
|
||||
@@ -28452,10 +28457,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==",
|
||||
"license": "MIT",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.8.0.tgz",
|
||||
"integrity": "sha512-eDFVKiJJxjnIORveMUKVJGIhKfRNjqJWIoKS+JM88q8I8e3jHys9moyJAr9QM5oW/tZx4yyItl08yRXGnr7Grg==",
|
||||
"dependencies": {
|
||||
"react-native": "^0.63.1"
|
||||
}
|
||||
@@ -28590,6 +28594,7 @@
|
||||
},
|
||||
"node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.5"
|
||||
@@ -28709,6 +28714,7 @@
|
||||
},
|
||||
"node_modules/@babel/helper-hoist-variables": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.5"
|
||||
@@ -28968,6 +28974,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
|
||||
"integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
},
|
||||
@@ -28982,6 +28989,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz",
|
||||
"integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
|
||||
@@ -29130,6 +29138,7 @@
|
||||
"version": "7.21.0-placeholder-for-preset-env.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
|
||||
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
@@ -29142,6 +29151,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
|
||||
"integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
|
||||
"deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
|
||||
"@babel/helper-plugin-utils": "^7.18.6"
|
||||
@@ -29176,6 +29186,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-syntax-class-properties": {
|
||||
"version": "7.12.13",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.12.13"
|
||||
@@ -29188,6 +29199,7 @@
|
||||
"version": "7.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
|
||||
"integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.14.5"
|
||||
},
|
||||
@@ -29225,6 +29237,7 @@
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
|
||||
"integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.8.3"
|
||||
},
|
||||
@@ -29249,6 +29262,7 @@
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz",
|
||||
"integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -29263,6 +29277,7 @@
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz",
|
||||
"integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -29277,6 +29292,7 @@
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
|
||||
"integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.10.4"
|
||||
},
|
||||
@@ -29288,6 +29304,7 @@
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
|
||||
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.8.0"
|
||||
},
|
||||
@@ -29387,6 +29404,7 @@
|
||||
"version": "7.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
|
||||
"integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.14.5"
|
||||
},
|
||||
@@ -29414,6 +29432,7 @@
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
|
||||
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
|
||||
"@babel/helper-plugin-utils": "^7.18.6"
|
||||
@@ -29442,6 +29461,7 @@
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz",
|
||||
"integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-environment-visitor": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
@@ -29472,6 +29492,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoped-functions": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29500,6 +29521,7 @@
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
|
||||
"integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29515,6 +29537,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz",
|
||||
"integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
@@ -29579,6 +29602,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz",
|
||||
"integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29594,6 +29618,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz",
|
||||
"integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -29608,6 +29633,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
|
||||
"integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
},
|
||||
@@ -29620,6 +29646,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-exponentiation-operator": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
|
||||
@@ -29636,6 +29663,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz",
|
||||
"integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/plugin-syntax-export-namespace-from": "^7.8.3"
|
||||
@@ -29663,6 +29691,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-for-of": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29693,6 +29722,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz",
|
||||
"integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/plugin-syntax-json-strings": "^7.8.3"
|
||||
@@ -29721,6 +29751,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz",
|
||||
"integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
|
||||
@@ -29734,6 +29765,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-member-expression-literals": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29749,6 +29781,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz",
|
||||
"integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29779,6 +29812,7 @@
|
||||
"version": "7.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz",
|
||||
"integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-module-transforms": "^7.22.5",
|
||||
@@ -29796,6 +29830,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz",
|
||||
"integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -29825,6 +29860,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz",
|
||||
"integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -29854,6 +29890,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz",
|
||||
"integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/plugin-syntax-numeric-separator": "^7.10.4"
|
||||
@@ -29869,6 +29906,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz",
|
||||
"integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.22.5",
|
||||
"@babel/helper-compilation-targets": "^7.22.5",
|
||||
@@ -29885,6 +29923,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-super": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
@@ -29901,6 +29940,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz",
|
||||
"integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
|
||||
@@ -29974,6 +30014,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-property-literals": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -30043,6 +30084,7 @@
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.22.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
@@ -30059,6 +30101,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz",
|
||||
"integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -30151,6 +30194,7 @@
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz",
|
||||
"integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -30181,6 +30225,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz",
|
||||
"integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
},
|
||||
@@ -30195,6 +30240,7 @@
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz",
|
||||
"integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -30224,6 +30270,7 @@
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
|
||||
"integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.22.5"
|
||||
@@ -30239,6 +30286,7 @@
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz",
|
||||
"integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.22.5",
|
||||
"@babel/helper-compilation-targets": "^7.22.5",
|
||||
@@ -30332,6 +30380,7 @@
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz",
|
||||
"integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.0.0",
|
||||
"@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
|
||||
@@ -30347,6 +30396,7 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
@@ -33650,7 +33700,8 @@
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/graceful-fs": {
|
||||
"version": "4.1.6",
|
||||
@@ -33756,14 +33807,14 @@
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.5",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.3.18",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz",
|
||||
"integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
@@ -34119,6 +34170,7 @@
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
|
||||
"integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/helper-numbers": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6"
|
||||
@@ -34127,22 +34179,26 @@
|
||||
"node_modules/@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
|
||||
"integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw=="
|
||||
"integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-api-error": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
|
||||
"integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="
|
||||
"integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-buffer": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
|
||||
"integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw=="
|
||||
"integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-numbers": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
|
||||
"integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.11.6",
|
||||
"@webassemblyjs/helper-api-error": "1.11.6",
|
||||
@@ -34152,12 +34208,14 @@
|
||||
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
|
||||
"integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="
|
||||
"integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
|
||||
"integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
@@ -34169,6 +34227,7 @@
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
|
||||
"integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
@@ -34177,6 +34236,7 @@
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
|
||||
"integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
@@ -34184,12 +34244,14 @@
|
||||
"node_modules/@webassemblyjs/utf8": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
|
||||
"integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="
|
||||
"integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/wasm-edit": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
|
||||
"integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
@@ -34205,6 +34267,7 @@
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
|
||||
"integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
|
||||
@@ -34217,6 +34280,7 @@
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
|
||||
"integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-buffer": "1.11.6",
|
||||
@@ -34228,6 +34292,7 @@
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
|
||||
"integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@webassemblyjs/helper-api-error": "1.11.6",
|
||||
@@ -34241,6 +34306,7 @@
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
|
||||
"integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "1.11.6",
|
||||
"@xtuc/long": "4.2.2"
|
||||
@@ -34298,12 +34364,14 @@
|
||||
"node_modules/@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
|
||||
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@xtuc/long": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@yarnpkg/lockfile": {
|
||||
"version": "1.1.0",
|
||||
@@ -35302,6 +35370,7 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
|
||||
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
}
|
||||
@@ -35732,7 +35801,7 @@
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.2",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
@@ -36332,6 +36401,7 @@
|
||||
"version": "5.17.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
@@ -36451,7 +36521,8 @@
|
||||
"node_modules/es-module-lexer": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
|
||||
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw=="
|
||||
"integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.0.0",
|
||||
@@ -36796,6 +36867,7 @@
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^4.1.1"
|
||||
@@ -36808,6 +36880,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
|
||||
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
@@ -36971,6 +37044,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
@@ -36982,6 +37056,7 @@
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
}
|
||||
@@ -36990,6 +37065,7 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -37749,7 +37825,8 @@
|
||||
"node_modules/glob-to-regexp": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/global": {
|
||||
"version": "4.4.0",
|
||||
@@ -39838,7 +39915,8 @@
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
|
||||
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-schema-ref-resolver": {
|
||||
"version": "1.0.1",
|
||||
@@ -40314,6 +40392,7 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
|
||||
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.11.5"
|
||||
}
|
||||
@@ -42543,6 +42622,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
@@ -42564,30 +42644,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.23.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom/node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-freeze": {
|
||||
"version": "1.0.3",
|
||||
"license": "MIT",
|
||||
@@ -43507,6 +43563,7 @@
|
||||
},
|
||||
"node_modules/regenerator-transform": {
|
||||
"version": "0.15.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4"
|
||||
@@ -43859,6 +43916,7 @@
|
||||
},
|
||||
"node_modules/serialize-javascript": {
|
||||
"version": "6.0.1",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"randombytes": "^2.1.0"
|
||||
@@ -44516,6 +44574,7 @@
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.2.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -44593,6 +44652,7 @@
|
||||
"version": "5.3.10",
|
||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
|
||||
"integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.17",
|
||||
"jest-worker": "^27.4.5",
|
||||
@@ -44626,6 +44686,7 @@
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
@@ -44639,6 +44700,7 @@
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
@@ -45215,6 +45277,7 @@
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
|
||||
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"graceful-fs": "^4.1.2"
|
||||
@@ -45238,6 +45301,7 @@
|
||||
"version": "5.94.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
"@types/estree": "^1.0.0",
|
||||
@@ -45353,6 +45417,7 @@
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.0.32",
|
||||
"version": "3.0.28",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
@@ -54,4 +54,4 @@
|
||||
"react": "18.2.0",
|
||||
"react-native": "0.74.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,7 +546,7 @@ const ShareView = () => {
|
||||
</Paragraph>
|
||||
<ScrollView horizontal>
|
||||
{rawFiles.map((item) =>
|
||||
isImage(item.type) || item.value?.endsWith(".png") ? (
|
||||
isImage(item.type) ? (
|
||||
<TouchableOpacity
|
||||
onPress={() => onRemoveFile(item)}
|
||||
key={item.name}
|
||||
@@ -604,8 +604,7 @@ const ShareView = () => {
|
||||
paddingRight: 8
|
||||
}}
|
||||
>
|
||||
{item.name || item.value.split("/").pop()}
|
||||
{item.size ? `(${formatBytes(item.size)})` : ""}
|
||||
{item.name} ({formatBytes(item.size)})
|
||||
</Paragraph>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
FROM oven/bun:1.2.2-alpine
|
||||
FROM --platform=$BUILDPLATFORM oven/bun:1.1.36-alpine
|
||||
|
||||
RUN mkdir -p /home/bun/app && chown -R bun:bun /home/bun/app
|
||||
|
||||
@@ -11,4 +11,4 @@ COPY --chown=bun:bun output .
|
||||
|
||||
RUN bun install
|
||||
|
||||
CMD [ "bun", "run", "start" ]
|
||||
CMD [ "bun", "run", "start" ]
|
||||
@@ -62,42 +62,8 @@ export default function handleRequest(
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html; charset=utf-8");
|
||||
|
||||
const nonce =
|
||||
remixContext.staticHandlerContext?.loaderData?.root?.cspScriptNonce;
|
||||
if (nonce)
|
||||
responseHeaders.set(
|
||||
"Content-Security-Policy",
|
||||
getContentSecurityPolicy(nonce)
|
||||
);
|
||||
|
||||
return new Response(html, {
|
||||
status: responseStatusCode,
|
||||
headers: responseHeaders
|
||||
});
|
||||
}
|
||||
|
||||
function getContentSecurityPolicy(nonce?: string) {
|
||||
let script_src: string;
|
||||
if (typeof nonce === "string") {
|
||||
script_src = `'self' 'report-sample' 'nonce-${nonce}'`;
|
||||
} else if (process.env.NODE_ENV === "development") {
|
||||
// Allow the <LiveReload /> component to load without a nonce in the error pages
|
||||
script_src = "'self' 'report-sample'";
|
||||
} else {
|
||||
script_src = "'self' 'report-sample'";
|
||||
}
|
||||
|
||||
const connect_src =
|
||||
process.env.NODE_ENV === "development"
|
||||
? "'self' ws://localhost:*"
|
||||
: "'self'";
|
||||
|
||||
return (
|
||||
`script-src ${script_src} 'strict-dynamic'; ` +
|
||||
`connect-src ${connect_src}; ` +
|
||||
"form-action 'self'; " +
|
||||
"object-src 'none'; " +
|
||||
"block-all-mixed-content; " +
|
||||
"base-uri 'self'; manifest-src 'self'"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,22 +22,14 @@ import {
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
useLoaderData
|
||||
ScrollRestoration
|
||||
} from "@remix-run/react";
|
||||
import { BaseThemeProvider } from "./components/theme-provider";
|
||||
import { Buffer } from "buffer";
|
||||
import { ThemeDark, themeToCSS } from "@notesnook/theme";
|
||||
import { LoaderFunction } from "@remix-run/node";
|
||||
|
||||
globalThis.Buffer = Buffer;
|
||||
|
||||
type RootLoaderData = { cspScriptNonce: string };
|
||||
export const loader: LoaderFunction = async () => {
|
||||
const crypto = await import("node:crypto");
|
||||
return { cspScriptNonce: crypto.randomBytes(16).toString("hex") };
|
||||
};
|
||||
|
||||
export function Head() {
|
||||
return (
|
||||
<>
|
||||
@@ -48,17 +40,13 @@ export function Head() {
|
||||
<Links />
|
||||
<style
|
||||
id="theme-colors"
|
||||
dangerouslySetInnerHTML={{ __html: themeToCSS(ThemeDark) }}
|
||||
dangerouslySetInnerHTML={{ __html: colorsToCSS() }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const data = useLoaderData<RootLoaderData>();
|
||||
const cspScriptNonce =
|
||||
typeof document === "undefined" ? data.cspScriptNonce : "";
|
||||
|
||||
return (
|
||||
<>
|
||||
<BaseThemeProvider
|
||||
@@ -68,8 +56,29 @@ export default function App() {
|
||||
>
|
||||
<Outlet />
|
||||
</BaseThemeProvider>
|
||||
<ScrollRestoration nonce={cspScriptNonce} />
|
||||
<Scripts nonce={cspScriptNonce} />
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function colorsToCSS() {
|
||||
// const colorScheme = JSON.parse(
|
||||
// window.localStorage.getItem("colorScheme") || '"light"'
|
||||
// );
|
||||
// const root = document.querySelector("html");
|
||||
// if (root) root.setAttribute("data-theme", colorScheme);
|
||||
|
||||
// const theme =
|
||||
// colorScheme === "dark"
|
||||
// ? JSON.parse(window.localStorage.getItem("theme:dark") || "false") ||
|
||||
// ThemeDark
|
||||
// : JSON.parse(window.localStorage.getItem("theme:light") || "false") ||
|
||||
// ThemeLight;
|
||||
// const stylesheet = document.getElementById("theme-colors");
|
||||
// if (theme) {
|
||||
// const css = ;
|
||||
// if (stylesheet) stylesheet.innerHTML = css;
|
||||
// } else stylesheet?.remove();
|
||||
return themeToCSS(ThemeDark);
|
||||
}
|
||||
|
||||
45
apps/monograph/package-lock.json
generated
45
apps/monograph/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/monograph",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/monograph",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.2",
|
||||
"dependencies": {
|
||||
"@emotion/cache": "11.11.0",
|
||||
"@emotion/react": "11.11.1",
|
||||
@@ -60,6 +60,9 @@
|
||||
"vite-plugin-static-copy": "^2.1.0",
|
||||
"vite-tsconfig-paths": "^5.0.1",
|
||||
"wrangler": "3.78.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"../../packages/core": {
|
||||
@@ -2942,22 +2945,6 @@
|
||||
"@styled-system/css": "^5.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/color-modes": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.16.2.tgz",
|
||||
"integrity": "sha512-jWEWx53lxNgWCT38i/kwLV2rsvJz8lVZgi5oImnVwYba9VejXD23q1ckbNFJHosQ8KKXY87ht0KPC6BQFIiHtQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/core": "^0.16.2",
|
||||
"@theme-ui/css": "^0.16.2",
|
||||
"deepmerge": "^4.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/components": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/components/-/components-0.16.2.tgz",
|
||||
@@ -3003,22 +2990,6 @@
|
||||
"@emotion/react": "^11.11.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@theme-ui/theme-provider": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.16.2.tgz",
|
||||
"integrity": "sha512-LRnVevODcGqO0JyLJ3wht+PV3ZoZcJ7XXLJAJWDoGeII4vZcPQKwVy4Lpz/juHsZppQxKcB3U+sQDGBnP25irQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@theme-ui/color-modes": "^0.16.2",
|
||||
"@theme-ui/core": "^0.16.2",
|
||||
"@theme-ui/css": "^0.16.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"react": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/acorn": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz",
|
||||
@@ -3148,14 +3119,14 @@
|
||||
"version": "15.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
|
||||
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.3.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz",
|
||||
"integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
@@ -12241,7 +12212,7 @@
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/monograph",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.2",
|
||||
"private": true,
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
@@ -64,5 +64,8 @@
|
||||
"vite-plugin-static-copy": "^2.1.0",
|
||||
"vite-tsconfig-paths": "^5.0.1",
|
||||
"wrangler": "3.78.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
3481
apps/theme-builder/package-lock.json
generated
3481
apps/theme-builder/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/theme-builder",
|
||||
"description": "Your private note taking space",
|
||||
"version": "1.3.0",
|
||||
"version": "1.2.0",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
@@ -12,25 +12,35 @@
|
||||
"@mdi/js": "^7.2.96",
|
||||
"@mdi/react": "^1.6.1",
|
||||
"@notesnook/common": "file:../../packages/common",
|
||||
"@notesnook/intl": "file:../../packages/intl",
|
||||
"@notesnook/theme": "file:../../packages/theme",
|
||||
"@notesnook/web": "file:../web",
|
||||
"@streetwriters/kysely": "^0.27.4",
|
||||
"@theme-ui/components": "^0.14.7",
|
||||
"@theme-ui/core": "^0.14.7",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"clipboard-polyfill": "^4.0.0",
|
||||
"dayjs": "1.11.13",
|
||||
"file-saver": "^2.0.5",
|
||||
"katex": "^0.16.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-modal": "3.16.3",
|
||||
"@lingui/core": "5.1.2"
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "5.4.11"
|
||||
"@babel/core": "^7.22.5",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/file-saver": "^2.0.5",
|
||||
"@types/react": "^18.2.39",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"buffer": "^6.0.3",
|
||||
"chalk": "^4.1.0",
|
||||
"happy-dom": "^8.9.0",
|
||||
"rollup": "^3.27.0",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"swc-plugin-react-remove-properties": "^0.1.4",
|
||||
"vite": "^4.3.9",
|
||||
"vite-plugin-env-compatible": "^1.1.1",
|
||||
"vite-plugin-svgr": "^3.2.0",
|
||||
"vitest": "^0.32.0"
|
||||
},
|
||||
"overrides": {
|
||||
"@theme-ui/components@>0": "0.14.7",
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#root > .theme-scope-base {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#app {
|
||||
flex: 1;
|
||||
height: unset;
|
||||
}
|
||||
|
||||
#root > .theme-scope-base > :first-child:not(#menu-wrapper) {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -17,44 +17,60 @@ 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 "./index.css";
|
||||
import "@notesnook/web/src/polyfills";
|
||||
import "@notesnook/web/src/app.css";
|
||||
import { ThemeDark, ThemeLight, themeToCSS } from "@notesnook/theme";
|
||||
import Config from "@notesnook/web/src/utils/config";
|
||||
import { setI18nGlobal, Messages } from "@notesnook/intl";
|
||||
import { i18n } from "@lingui/core";
|
||||
import { init } from "@notesnook/web/src/bootstrap";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import {
|
||||
ErrorBoundary,
|
||||
ErrorComponent
|
||||
} from "@notesnook/web/src/components/error-boundary";
|
||||
import { BaseThemeProvider } from "@notesnook/web/src/components/theme-provider";
|
||||
import { App } from "./app";
|
||||
|
||||
const colorScheme = JSON.parse(
|
||||
window.localStorage.getItem("colorScheme") || '"light"'
|
||||
);
|
||||
const root = document.querySelector("html");
|
||||
if (root) root.setAttribute("data-theme", colorScheme);
|
||||
renderApp();
|
||||
|
||||
const theme =
|
||||
colorScheme === "dark"
|
||||
? Config.get("theme:dark", ThemeDark)
|
||||
: Config.get("theme:light", ThemeLight);
|
||||
const stylesheet = document.getElementById("theme-colors");
|
||||
if (theme) {
|
||||
const css = themeToCSS(theme);
|
||||
if (stylesheet) stylesheet.innerHTML = css;
|
||||
} else stylesheet?.remove();
|
||||
async function renderApp() {
|
||||
const rootElement = document.getElementById("root");
|
||||
if (!rootElement) return;
|
||||
const root = createRoot(rootElement);
|
||||
try {
|
||||
const { component, props } = await init();
|
||||
|
||||
const locale = import.meta.env.DEV
|
||||
? import("@notesnook/intl/locales/$pseudo-LOCALE.json")
|
||||
: import("@notesnook/intl/locales/$en.json");
|
||||
locale.then(({ default: locale }) => {
|
||||
i18n.load({
|
||||
en: locale.messages as unknown as Messages
|
||||
});
|
||||
i18n.activate("en");
|
||||
const { useKeyStore } = await import(
|
||||
"@notesnook/web/src/interfaces/key-store"
|
||||
);
|
||||
await useKeyStore.getState().init();
|
||||
|
||||
performance.mark("import:root");
|
||||
import("@notesnook/web/src/root.js").then(({ startApp }) => {
|
||||
performance.mark("start:app");
|
||||
startApp(<App />);
|
||||
});
|
||||
});
|
||||
setI18nGlobal(i18n);
|
||||
const { default: Component } = await component();
|
||||
const { default: AppLock } = await import(
|
||||
"@notesnook/web/src/views/app-lock"
|
||||
);
|
||||
|
||||
root.render(
|
||||
<ErrorBoundary>
|
||||
<BaseThemeProvider
|
||||
onRender={() => document.getElementById("splash")?.remove()}
|
||||
sx={{
|
||||
display: "flex",
|
||||
"#app": { flex: 1, height: "unset" },
|
||||
"& > :first-child:not(#menu-wrapper)": { flex: 1 },
|
||||
height: "100%"
|
||||
}}
|
||||
>
|
||||
<AppLock>
|
||||
<Component route={props?.route || "login:email"} />
|
||||
</AppLock>
|
||||
<App />
|
||||
</BaseThemeProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
} catch (e) {
|
||||
root.render(
|
||||
<>
|
||||
<ErrorComponent
|
||||
error={e}
|
||||
resetErrorBoundary={() => window.location.reload()}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type ErrorsListProps = {
|
||||
export function ErrorsList(props: ErrorsListProps) {
|
||||
return (
|
||||
<Accordion
|
||||
title={`${props.errors.length} errors occurred`}
|
||||
title={`${props.errors.length} errors occured`}
|
||||
sx={{ bg: "errorBg", borderRadius: "default", mt: 2 }}
|
||||
color="#E53935"
|
||||
>
|
||||
|
||||
3
apps/web/.gitignore
vendored
3
apps/web/.gitignore
vendored
@@ -30,5 +30,4 @@ dist
|
||||
public/workbox
|
||||
scripts/secrets
|
||||
test-results
|
||||
.swc
|
||||
.wrangler
|
||||
.swc
|
||||
@@ -40,12 +40,10 @@ test("remove color", async ({ page }) => {
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await note?.contextMenu.newColor({ title: "red", color: "#ff0000" });
|
||||
await app.navigation.waitForItem("red");
|
||||
const colorItem = await app.navigation.findItem("red");
|
||||
|
||||
await colorItem?.removeColor();
|
||||
|
||||
await expect(colorItem!.locator).toBeHidden();
|
||||
expect(await app.navigation.findItem("red")).toBeUndefined();
|
||||
expect(await note?.contextMenu.isColored("red")).toBe(false);
|
||||
});
|
||||
@@ -56,7 +54,6 @@ test("rename color", async ({ page }) => {
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await note?.contextMenu.newColor({ title: "red", color: "#ff0000" });
|
||||
await app.navigation.waitForItem("red");
|
||||
const colorItem = await app.navigation.findItem("red");
|
||||
|
||||
await colorItem?.renameColor("priority-33");
|
||||
|
||||
@@ -20,12 +20,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { AppModel } from "./models/app.model";
|
||||
import { NotesViewModel } from "./models/notes-view.model";
|
||||
import { getTestId } from "./utils";
|
||||
|
||||
for (const item of [
|
||||
{ id: "notebooks", title: "Notebooks" },
|
||||
{ id: "tags", title: "Tags" }
|
||||
]) {
|
||||
test.skip(`drag & hover over ${item.id} should navigate inside`, () => {});
|
||||
test(`drag & hover over ${item.id} should navigate inside`, async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: `Test note`
|
||||
});
|
||||
const navigationItem = await app.navigation.findItem(item.title);
|
||||
|
||||
await note?.locator.hover();
|
||||
await page.mouse.down();
|
||||
await navigationItem?.locator.hover();
|
||||
await navigationItem?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(app.routeHeader).toHaveText(item.title);
|
||||
});
|
||||
}
|
||||
|
||||
test(`drag & drop note over Favorites should make the note favorite`, async ({
|
||||
@@ -66,20 +85,24 @@ test(`drag & drop note over a notebook should get assigned to the notebook`, asy
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook({ title: "Test notebook" });
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: `Test note`
|
||||
});
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook({ title: "Test notebook" });
|
||||
const navigationItem = await app.navigation.findItem("Notebooks");
|
||||
|
||||
await note?.locator.hover();
|
||||
await page.mouse.down();
|
||||
await navigationItem?.locator.hover();
|
||||
await navigationItem?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await notebook?.locator.hover();
|
||||
await notebook?.locator.hover();
|
||||
await page.mouse.up();
|
||||
|
||||
const notebookNotes = await notebook?.openNotebook();
|
||||
const { notes: notebookNotes } = (await notebook?.openNotebook()) || {};
|
||||
expect(await notebookNotes?.findNote({ title: "Test note" })).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -88,15 +111,19 @@ test(`drag & drop note over a tag should get assigned to the tag`, async ({
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const tags = await app.goToTags();
|
||||
const tag = await tags.createItem({ title: "Tag" });
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: `Test note`
|
||||
});
|
||||
const tags = await app.goToTags();
|
||||
const tag = await tags.createItem({ title: "Tag" });
|
||||
const navigationItem = await app.navigation.findItem("Tags");
|
||||
|
||||
await note?.locator.hover();
|
||||
await page.mouse.down();
|
||||
await navigationItem?.locator.hover();
|
||||
await navigationItem?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await tag?.locator.hover();
|
||||
await tag?.locator.hover();
|
||||
await page.mouse.up();
|
||||
@@ -158,20 +185,25 @@ test(`drag & drop note over a nested notebook should get assigned to the noteboo
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook({
|
||||
title: "Test notebook",
|
||||
subNotebooks: [{ title: "Nested notebook" }]
|
||||
});
|
||||
const nestedNotebook = await (
|
||||
await notebook?.openNotebook()
|
||||
)?.subNotebooks.createNotebook({ title: "Nested notebook" });
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: `Test note`
|
||||
});
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook({
|
||||
title: "Test notebook"
|
||||
});
|
||||
const nestedNotebook = await notebook?.createSubnotebook({
|
||||
title: "Nested notebook"
|
||||
});
|
||||
const navigationItem = await app.navigation.findItem("Notebooks");
|
||||
|
||||
await note?.locator.hover();
|
||||
await page.mouse.down();
|
||||
await navigationItem?.locator.hover();
|
||||
await navigationItem?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await nestedNotebook?.locator.hover();
|
||||
await nestedNotebook?.locator.hover();
|
||||
await page.mouse.up();
|
||||
@@ -180,3 +212,46 @@ test(`drag & drop note over a nested notebook should get assigned to the noteboo
|
||||
const notebookNotes = new NotesViewModel(page, "notebook", "notes");
|
||||
expect(await notebookNotes?.findNote({ title: "Test note" })).toBeDefined();
|
||||
});
|
||||
|
||||
test(`drag & hover over a nested notebook should navigate inside`, async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook({
|
||||
title: "Test notebook",
|
||||
subNotebooks: [{ title: "Nested notebook" }]
|
||||
});
|
||||
const nestedNotebook = await (
|
||||
await notebook?.openNotebook()
|
||||
)?.subNotebooks.createNotebook({ title: "Nested notebook" });
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: `Test note`
|
||||
});
|
||||
const navigationItem = await app.navigation.findItem("Notebooks");
|
||||
await navigationItem?.click();
|
||||
await navigationItem?.click();
|
||||
await app.goToNotes();
|
||||
|
||||
await note?.locator.hover();
|
||||
await page.mouse.down();
|
||||
await navigationItem?.locator.hover();
|
||||
await navigationItem?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await notebook?.locator.hover();
|
||||
await notebook?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await nestedNotebook?.locator.hover();
|
||||
await nestedNotebook?.locator.hover();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.keyboard.press("Escape");
|
||||
|
||||
expect(
|
||||
await page
|
||||
.locator(getTestId("notebook-header"))
|
||||
.locator(getTestId("notebook-title"))
|
||||
.textContent()
|
||||
).toBe("Nested notebook");
|
||||
});
|
||||
|
||||
@@ -258,21 +258,6 @@ test("creating a new note and toggling read-only mode should not empty editor co
|
||||
expect(await notes.editor.getContent("text")).toBe(NOTE.content);
|
||||
});
|
||||
|
||||
test("toggling read-only should hide undo & redo buttons", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
|
||||
await notes.editor.undoButton.waitFor({ state: "visible" });
|
||||
await notes.editor.redoButton.waitFor({ state: "visible" });
|
||||
await note?.properties.readonly();
|
||||
|
||||
expect(await note?.properties.isReadonly()).toBeTruthy();
|
||||
expect(notes.editor.undoButton).not.toBeVisible();
|
||||
expect(notes.editor.redoButton).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("#1468 count words separated by newlines", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
@@ -362,7 +347,7 @@ test("when autosave is disabled, creating a new note should save the note", asyn
|
||||
await notes.newNote();
|
||||
|
||||
await note?.openNote();
|
||||
// await expect(notes.editor.savedIcon).toBeVisible();
|
||||
await expect(notes.editor.savedIcon).toBeVisible();
|
||||
expect(await notes.editor.getContent("text")).toBe(content.trim());
|
||||
});
|
||||
|
||||
@@ -400,7 +385,7 @@ test("control + alt + right arrow should go to next note", async ({ page }) => {
|
||||
});
|
||||
|
||||
await note1?.openNote();
|
||||
await note2?.openNote(true);
|
||||
await note2?.openNote();
|
||||
await page.keyboard.press("Control+Alt+ArrowRight");
|
||||
|
||||
expect(await notes.editor.getTitle()).toBe("Note 1");
|
||||
@@ -428,7 +413,7 @@ test("control + alt + left arrow should go to previous note", async ({
|
||||
});
|
||||
|
||||
await note1?.openNote();
|
||||
await note2?.openNote(true);
|
||||
await note2?.openNote();
|
||||
await page.keyboard.press("Control+Alt+ArrowLeft");
|
||||
|
||||
expect(await notes.editor.getTitle()).toBe("Note 1");
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 79 KiB |
@@ -1 +1 @@
|
||||
An edit I madeThis is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1
|
||||
This is Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1Test 1An edit I made
|
||||
@@ -30,7 +30,6 @@ import { SearchViewModel } from "./search-view-model";
|
||||
import { SettingsViewModel } from "./settings-view.model";
|
||||
import { ToastsModel } from "./toasts.model";
|
||||
import { TrashViewModel } from "./trash-view.model";
|
||||
import { ContextMenuModel } from "./context-menu.model";
|
||||
|
||||
export class AppModel {
|
||||
readonly page: Page;
|
||||
@@ -39,7 +38,6 @@ export class AppModel {
|
||||
readonly auth: AuthModel;
|
||||
readonly checkout: CheckoutModel;
|
||||
readonly routeHeader: Locator;
|
||||
private readonly profileDropdown: ContextMenuModel;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
@@ -48,72 +46,56 @@ export class AppModel {
|
||||
this.auth = new AuthModel(page);
|
||||
this.checkout = new CheckoutModel(page);
|
||||
this.routeHeader = this.page.locator(getTestId("routeHeader"));
|
||||
this.profileDropdown = new ContextMenuModel(this.page);
|
||||
}
|
||||
|
||||
async goto(isLoggedIn = false) {
|
||||
await this.page.goto("/");
|
||||
await this.routeHeader.waitFor({ state: "visible" });
|
||||
if (!isLoggedIn)
|
||||
await this.page
|
||||
.locator(getTestId("logged-in"))
|
||||
.waitFor({ state: "hidden" });
|
||||
if (!isLoggedIn) await this.navigation.waitForItem("Login");
|
||||
}
|
||||
|
||||
goBack() {
|
||||
const goBackButton = this.page.locator(getTestId("route-go-back"));
|
||||
return goBackButton.click();
|
||||
}
|
||||
|
||||
async goToNotes() {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo("Notes");
|
||||
return new NotesViewModel(this.page, "home", "home");
|
||||
}
|
||||
|
||||
async goToNotebooks() {
|
||||
await this.page.locator(getTestId("tab-notebooks")).click();
|
||||
const model = new NotebooksViewModel(this.page);
|
||||
await model.waitForList();
|
||||
return model;
|
||||
await this.navigateTo("Notebooks");
|
||||
return new NotebooksViewModel(this.page);
|
||||
}
|
||||
|
||||
async goToFavorites() {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo("Favorites");
|
||||
return new NotesViewModel(this.page, "notes", "favorites");
|
||||
}
|
||||
|
||||
async goToReminders() {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo("Reminders");
|
||||
return new RemindersViewModel(this.page);
|
||||
}
|
||||
|
||||
async goToTags() {
|
||||
await this.page.locator(getTestId("tab-tags")).click();
|
||||
const model = new ItemsViewModel(this.page);
|
||||
await model.waitForList();
|
||||
return model;
|
||||
}
|
||||
|
||||
async goToHome() {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo("Tags");
|
||||
return new ItemsViewModel(this.page);
|
||||
}
|
||||
|
||||
async goToColor(color: string) {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo(color);
|
||||
return new NotesViewModel(this.page, "notes", "notes");
|
||||
}
|
||||
|
||||
async goToTrash() {
|
||||
await this.page.locator(getTestId("tab-home")).click();
|
||||
await this.navigateTo("Trash");
|
||||
return new TrashViewModel(this.page);
|
||||
}
|
||||
|
||||
async goToSettings() {
|
||||
await this.profileDropdown.open(
|
||||
this.page.locator(getTestId("profile-dropdown")),
|
||||
"left"
|
||||
);
|
||||
await this.profileDropdown.clickOnItem("settings");
|
||||
await this.navigateTo("Settings");
|
||||
return new SettingsViewModel(this.page);
|
||||
}
|
||||
|
||||
@@ -129,7 +111,7 @@ export class AppModel {
|
||||
async getRouteHeader() {
|
||||
if (!(await this.routeHeader.isVisible())) return;
|
||||
|
||||
return await this.routeHeader.getAttribute("data-header");
|
||||
return await this.routeHeader.innerText();
|
||||
}
|
||||
|
||||
async isSynced() {
|
||||
|
||||
@@ -51,11 +51,7 @@ export class BaseViewModel {
|
||||
.locator(getTestId("group-header"));
|
||||
|
||||
for await (const item of iterateList(locator)) {
|
||||
if (
|
||||
(
|
||||
await item.locator(getTestId("title")).textContent()
|
||||
)?.toLowerCase() === groupName.toLowerCase()
|
||||
)
|
||||
if ((await item.locator(getTestId("title")).textContent()) === groupName)
|
||||
return item;
|
||||
}
|
||||
return undefined;
|
||||
@@ -99,9 +95,7 @@ export class BaseViewModel {
|
||||
// }
|
||||
|
||||
async press(key: string) {
|
||||
const itemList = this.list.locator(
|
||||
getTestId(`virtuoso-item-list`, "data-testid")
|
||||
);
|
||||
const itemList = this.list.locator(getTestId(`virtuoso-item-list`, "data-testid"));
|
||||
await itemList.press(key);
|
||||
await this.page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ export class EditorModel {
|
||||
private readonly newTabButton: Locator;
|
||||
readonly savedIcon: Locator;
|
||||
readonly notSavedIcon: Locator;
|
||||
readonly undoButton: Locator;
|
||||
readonly redoButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
@@ -67,8 +65,6 @@ export class EditorModel {
|
||||
this.goBackButton = page.locator(getTestId("go-back"));
|
||||
this.goForwardButton = page.locator(getTestId("go-forward"));
|
||||
this.newTabButton = page.locator(getTestId("New tab"));
|
||||
this.undoButton = page.locator(getTestId("Undo"));
|
||||
this.redoButton = page.locator(getTestId("Redo"));
|
||||
}
|
||||
|
||||
async waitForLoading(title?: string, content?: string) {
|
||||
@@ -93,6 +89,7 @@ export class EditorModel {
|
||||
}
|
||||
|
||||
async waitForUnloading() {
|
||||
await this.page.waitForURL(/#\/notes\/?.+\/create/gm);
|
||||
await this.searchButton.isDisabled();
|
||||
await this.page
|
||||
.locator(".active")
|
||||
@@ -104,6 +101,7 @@ export class EditorModel {
|
||||
}
|
||||
|
||||
async waitForSaving() {
|
||||
await this.page.waitForURL(/#\/notes\/?.+\/edit/gm);
|
||||
await this.page.locator(".active").locator(getTestId("tags")).waitFor();
|
||||
await this.searchButton.waitFor();
|
||||
await this.wordCountText.waitFor();
|
||||
@@ -126,8 +124,7 @@ export class EditorModel {
|
||||
async typeTitle(text: string, delay = 0) {
|
||||
await this.editAndWait(async () => {
|
||||
await this.title.focus();
|
||||
await this.title.selectText();
|
||||
await this.title.press("ArrowRight");
|
||||
await this.title.press("End");
|
||||
await this.title.type(text, { delay });
|
||||
});
|
||||
}
|
||||
@@ -199,16 +196,6 @@ export class EditorModel {
|
||||
return tags;
|
||||
}
|
||||
|
||||
async removeTags(tags: string[]) {
|
||||
for (const tag of tags) {
|
||||
const item = this.tags
|
||||
.filter({ hasText: tag })
|
||||
.getByTitle("Remove")
|
||||
.first();
|
||||
await item.click();
|
||||
}
|
||||
}
|
||||
|
||||
async getTitle() {
|
||||
return this.title.inputValue();
|
||||
}
|
||||
|
||||
@@ -28,22 +28,25 @@ export class ItemsViewModel extends BaseViewModel {
|
||||
private readonly createButton: Locator;
|
||||
constructor(page: Page) {
|
||||
super(page, "tags", "tags");
|
||||
this.createButton = page.locator(getTestId(`create-tag-button`));
|
||||
this.createButton = page.locator(getTestId(`tags-action-button`));
|
||||
}
|
||||
|
||||
async createItem(item: Item) {
|
||||
const titleToCompare = `#${item.title}`;
|
||||
|
||||
await this.createButton.first().click();
|
||||
await fillItemDialog(this.page, item);
|
||||
|
||||
await this.waitForItem(item.title);
|
||||
await this.waitForItem(titleToCompare);
|
||||
return await this.findItem(item);
|
||||
}
|
||||
|
||||
async findItem(item: Item) {
|
||||
const titleToCompare = `#${item.title}`;
|
||||
for await (const _item of this.iterateItems()) {
|
||||
const itemModel = new ItemModel(_item, "tag");
|
||||
const title = await itemModel.getTitle();
|
||||
if (title === item.title) return itemModel;
|
||||
if (title === titleToCompare) return itemModel;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -134,14 +134,14 @@ abstract class BaseProperties {
|
||||
|
||||
export class NotePropertiesModel extends BaseProperties {
|
||||
private readonly propertiesButton: Locator;
|
||||
private readonly generalSection: Locator;
|
||||
private readonly propertiesCloseButton: Locator;
|
||||
private readonly readonlyToggle: ToggleModel;
|
||||
private readonly sessionItems: Locator;
|
||||
|
||||
constructor(page: Page, noteLocator: Locator) {
|
||||
super(page, noteLocator, "properties");
|
||||
this.propertiesButton = page.locator(getTestId("Properties"));
|
||||
this.generalSection = page.locator(getTestId("general-section"));
|
||||
this.propertiesCloseButton = page.locator(getTestId("properties-close"));
|
||||
this.readonlyToggle = new ToggleModel(page, `properties-readonly`);
|
||||
this.sessionItems = page.locator(getTestId("session-item"));
|
||||
}
|
||||
@@ -183,11 +183,12 @@ export class NotePropertiesModel extends BaseProperties {
|
||||
|
||||
async open() {
|
||||
await this.propertiesButton.click();
|
||||
await this.generalSection.waitFor();
|
||||
await this.propertiesCloseButton.waitFor();
|
||||
await this.page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
async close() {
|
||||
await this.propertiesButton.click();
|
||||
await this.propertiesCloseButton.click();
|
||||
}
|
||||
|
||||
async getSessionHistory() {
|
||||
|
||||
@@ -25,21 +25,21 @@ import { Notebook } from "./types";
|
||||
import { confirmDialog, fillNotebookDialog } from "./utils";
|
||||
import { NotesViewModel } from "./notes-view.model";
|
||||
import { getTestId } from "../utils";
|
||||
import { NotebooksViewModel } from "./notebooks-view.model";
|
||||
import { SubnotebooksViewModel } from "./subnotebooks-view.model";
|
||||
|
||||
export class NotebookItemModel extends BaseItemModel {
|
||||
private readonly contextMenu: ContextMenuModel;
|
||||
constructor(
|
||||
locator: Locator,
|
||||
private readonly notebooks: NotebooksViewModel
|
||||
) {
|
||||
constructor(locator: Locator) {
|
||||
super(locator);
|
||||
this.contextMenu = new ContextMenuModel(this.page);
|
||||
}
|
||||
|
||||
async openNotebook() {
|
||||
await this.locator.click();
|
||||
return new NotesViewModel(this.page, "notebook", "notes");
|
||||
return {
|
||||
subNotebooks: new SubnotebooksViewModel(this.page),
|
||||
notes: new NotesViewModel(this.page, "notebook", "notes")
|
||||
};
|
||||
}
|
||||
|
||||
async editNotebook(notebook: Notebook) {
|
||||
@@ -49,16 +49,6 @@ export class NotebookItemModel extends BaseItemModel {
|
||||
await fillNotebookDialog(this.page, notebook);
|
||||
}
|
||||
|
||||
async createSubnotebook(notebook: Notebook) {
|
||||
await this.contextMenu.open(this.locator);
|
||||
await this.contextMenu.clickOnItem("add");
|
||||
|
||||
await fillNotebookDialog(this.page, notebook);
|
||||
|
||||
await this.notebooks.waitForItem(notebook.title);
|
||||
return await this.notebooks.findNotebook(notebook);
|
||||
}
|
||||
|
||||
async moveToTrash(deleteContainedNotes = false) {
|
||||
await this.contextMenu.open(this.locator);
|
||||
await this.contextMenu.clickOnItem("movetotrash");
|
||||
|
||||
@@ -30,7 +30,7 @@ export class NotebooksViewModel extends BaseViewModel {
|
||||
constructor(page: Page) {
|
||||
super(page, "notebooks", "notebooks");
|
||||
this.createButton = page
|
||||
.locator(getTestId("create-notebook-button"))
|
||||
.locator(getTestId("notebooks-action-button"))
|
||||
.first();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export class NotebooksViewModel extends BaseViewModel {
|
||||
|
||||
async findNotebook(notebook: Partial<Notebook>) {
|
||||
for await (const item of this.iterateItems()) {
|
||||
const notebookModel = new NotebookItemModel(item, this);
|
||||
const notebookModel = new NotebookItemModel(item);
|
||||
if ((await notebookModel.getTitle()) === notebook.title)
|
||||
return notebookModel;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,10 @@ export class NotesViewModel extends BaseViewModel {
|
||||
listType: string
|
||||
) {
|
||||
super(page, pageId, listType);
|
||||
this.createButton = page.locator(getTestId(`create-new-note`));
|
||||
this.createButton = page.locator(
|
||||
// TODO:
|
||||
getTestId(`notes-action-button`)
|
||||
);
|
||||
this.editor = new EditorModel(page);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export class RemindersViewModel extends BaseViewModel {
|
||||
constructor(page: Page) {
|
||||
super(page, "reminders", "reminders");
|
||||
this.createButton = page
|
||||
.locator(getTestId("create-reminder-button"))
|
||||
.locator(getTestId("reminders-action-button"))
|
||||
.first();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ export class SettingsViewModel {
|
||||
await confirmDialog(this.page.locator(getTestId("confirm-dialog")));
|
||||
|
||||
await this.page
|
||||
.locator(getTestId("logged-in"))
|
||||
.waitFor({ state: "hidden" });
|
||||
.locator(getTestId("not-logged-in"))
|
||||
.waitFor({ state: "visible" });
|
||||
}
|
||||
|
||||
async getRecoveryKey(password: string) {
|
||||
|
||||
@@ -19,17 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Locator, Page } from "@playwright/test";
|
||||
import { getTestId } from "../utils";
|
||||
import { ContextMenuModel } from "./context-menu.model";
|
||||
|
||||
export class TabItemModel {
|
||||
private readonly closeButton: Locator;
|
||||
readonly contextMenu: TabContextMenuModel;
|
||||
readonly titleElement: Locator;
|
||||
|
||||
constructor(readonly locator: Locator, page: Page) {
|
||||
constructor(private readonly locator: Locator, page: Page) {
|
||||
this.closeButton = locator.locator(getTestId("tab-close-button"));
|
||||
this.contextMenu = new TabContextMenuModel(page, locator);
|
||||
this.titleElement = locator.locator(getTestId("tab-title"));
|
||||
}
|
||||
|
||||
async getId() {
|
||||
@@ -42,7 +36,7 @@ export class TabItemModel {
|
||||
}
|
||||
|
||||
async title() {
|
||||
return this.titleElement.textContent();
|
||||
return this.locator.locator(getTestId("tab-title")).textContent();
|
||||
}
|
||||
|
||||
async isActive() {
|
||||
@@ -54,19 +48,3 @@ export class TabItemModel {
|
||||
return this.closeButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
class TabContextMenuModel {
|
||||
private readonly menu: ContextMenuModel;
|
||||
constructor(page: Page, private readonly tabLocator: Locator) {
|
||||
this.menu = new ContextMenuModel(page);
|
||||
}
|
||||
|
||||
async pin() {
|
||||
await this.open();
|
||||
await this.menu.clickOnItem("pin");
|
||||
}
|
||||
|
||||
async open() {
|
||||
await this.menu.open(this.tabLocator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ function createRoute(key: string, header: string) {
|
||||
|
||||
const routes = [
|
||||
createRoute("notes", "Notes"),
|
||||
createRoute("notebooks", "Notebooks"),
|
||||
createRoute("favorites", "Favorites"),
|
||||
createRoute("monographs", "Monographs"),
|
||||
createRoute("reminders", "Reminders"),
|
||||
createRoute("tags", "Tags"),
|
||||
createRoute("trash", "Trash")
|
||||
];
|
||||
|
||||
|
||||
@@ -43,8 +43,7 @@ test("create a note inside a notebook", async ({ page }) => {
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook(NOTEBOOK);
|
||||
const notes = await notebook?.openNotebook();
|
||||
await notes?.waitForList();
|
||||
const { notes } = (await notebook?.openNotebook()) || {};
|
||||
|
||||
const note = await notes?.createNote(NOTE);
|
||||
|
||||
@@ -56,10 +55,11 @@ test("create a note inside a subnotebook", async ({ page }) => {
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook(NOTEBOOK);
|
||||
const subNotebook = await notebook?.createSubnotebook({
|
||||
const { subNotebooks } = (await notebook?.openNotebook()) || {};
|
||||
const subNotebook = await subNotebooks?.createNotebook({
|
||||
title: "Subnotebook 1"
|
||||
});
|
||||
const notes = await subNotebook?.openNotebook();
|
||||
const { notes } = (await subNotebook?.openNotebook()) || {};
|
||||
|
||||
const note = await notes?.createNote(NOTE);
|
||||
|
||||
@@ -80,6 +80,7 @@ test("edit a notebook", async ({ page }) => {
|
||||
|
||||
const editedNotebook = await notebooks.findNotebook(item);
|
||||
expect(editedNotebook).toBeDefined();
|
||||
expect(await editedNotebook?.getDescription()).toBe(item.description);
|
||||
});
|
||||
|
||||
test("delete a notebook", async ({ page }) => {
|
||||
@@ -128,6 +129,29 @@ test("permanently delete a notebook", async ({ page }) => {
|
||||
await expect(trashItem.locator).toBeHidden();
|
||||
});
|
||||
|
||||
test("pin a notebook", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook(NOTEBOOK);
|
||||
|
||||
await notebook?.pin();
|
||||
|
||||
expect(await notebook?.isPinned()).toBe(true);
|
||||
});
|
||||
|
||||
test("unpin a notebook", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook(NOTEBOOK);
|
||||
await notebook?.pin();
|
||||
|
||||
await notebook?.unpin();
|
||||
|
||||
expect(await notebook?.isPinned()).toBe(false);
|
||||
});
|
||||
|
||||
test("create shortcut of a notebook", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
@@ -137,8 +161,8 @@ test("create shortcut of a notebook", async ({ page }) => {
|
||||
await notebook?.createShortcut();
|
||||
|
||||
expect(await notebook?.isShortcut()).toBe(true);
|
||||
await app.goToHome();
|
||||
expect(await app.navigation.findItem(NOTEBOOK.title)).toBeDefined();
|
||||
const allShortcuts = await app.navigation.getShortcuts();
|
||||
expect(allShortcuts.includes(NOTEBOOK.title)).toBeTruthy();
|
||||
});
|
||||
|
||||
test("remove shortcut of a notebook", async ({ page }) => {
|
||||
@@ -160,13 +184,14 @@ test("delete all notes within a notebook", async ({ page }) => {
|
||||
await app.goto();
|
||||
const notebooks = await app.goToNotebooks();
|
||||
const notebook = await notebooks.createNotebook(NOTEBOOK);
|
||||
let notes = await notebook?.openNotebook();
|
||||
let { notes } = (await notebook?.openNotebook()) || {};
|
||||
for (let i = 0; i < 2; ++i) {
|
||||
await notes?.createNote({
|
||||
title: `Note ${i}`,
|
||||
content: NOTE.content
|
||||
});
|
||||
}
|
||||
await app.goBack();
|
||||
|
||||
await notebook?.moveToTrash(true);
|
||||
|
||||
@@ -229,17 +254,20 @@ test(`sort notebooks`, async ({ page }, info) => {
|
||||
await notebooks.createNotebook(NOTEBOOK);
|
||||
}
|
||||
|
||||
for (const sortBy of sortByOptions) {
|
||||
for (const orderBy of orderByOptions) {
|
||||
await test.step(`sort by ${sortBy}, order by ${orderBy}`, async () => {
|
||||
const sortResult = await notebooks?.sort({
|
||||
orderBy,
|
||||
sortBy
|
||||
});
|
||||
if (!sortResult) return;
|
||||
for (const groupBy of groupByOptions) {
|
||||
for (const sortBy of sortByOptions) {
|
||||
for (const orderBy of orderByOptions) {
|
||||
await test.step(`group by ${groupBy}, sort by ${sortBy}, order by ${orderBy}`, async () => {
|
||||
const sortResult = await notebooks?.sort({
|
||||
groupBy,
|
||||
orderBy,
|
||||
sortBy
|
||||
});
|
||||
if (!sortResult) return;
|
||||
|
||||
await expect(notebooks.items).toHaveCount(titles.length);
|
||||
});
|
||||
await expect(notebooks.items).toHaveCount(titles.length);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { AppModel } from "./models/app.model";
|
||||
import { createHistorySession, NOTE } from "./utils";
|
||||
import { createHistorySession } from "./utils";
|
||||
|
||||
test("notes should open in the same tab", async ({ page }) => {
|
||||
const app = new AppModel(page);
|
||||
@@ -63,7 +63,7 @@ test("open note in new tab (using context menu)", async ({ page }) => {
|
||||
|
||||
const tabs = await notes.editor.getTabs();
|
||||
expect(tabs.length).toBe(2);
|
||||
await expect(tabs[1].titleElement).toHaveText("Note 2");
|
||||
expect(await tabs[1].title()).toBe("Note 2");
|
||||
});
|
||||
|
||||
test("open note in new tab (using middle click)", async ({ page }) => {
|
||||
@@ -80,7 +80,7 @@ test("open note in new tab (using middle click)", async ({ page }) => {
|
||||
|
||||
const tabs = await notes.editor.getTabs();
|
||||
expect(tabs.length).toBe(2);
|
||||
await expect(tabs[1].titleElement).toHaveText("Note 2");
|
||||
expect(await tabs[1].title()).toBe("Note 2");
|
||||
});
|
||||
|
||||
test("go back should open previous note", async ({ page }) => {
|
||||
@@ -93,9 +93,9 @@ test("go back should open previous note", async ({ page }) => {
|
||||
await notes.createNote({ title: "Note 3" });
|
||||
|
||||
await notes.editor.goBack();
|
||||
await expect(tabs[0].titleElement).toHaveText("Note 2");
|
||||
expect(await tabs[0].title()).toBe("Note 2");
|
||||
await notes.editor.goBack();
|
||||
await expect(tabs[0].titleElement).toHaveText("Note 1");
|
||||
expect(await tabs[0].title()).toBe("Note 1");
|
||||
});
|
||||
|
||||
test("go forward should open next note", async ({ page }) => {
|
||||
@@ -110,9 +110,9 @@ test("go forward should open next note", async ({ page }) => {
|
||||
await notes.editor.goBack();
|
||||
await notes.editor.goBack();
|
||||
await notes.editor.goForward();
|
||||
await expect(tabs[0].titleElement).toHaveText("Note 2");
|
||||
expect(await tabs[0].title()).toBe("Note 2");
|
||||
await notes.editor.goForward();
|
||||
await expect(tabs[0].titleElement).toHaveText("Note 3");
|
||||
expect(await tabs[0].title()).toBe("Note 3");
|
||||
});
|
||||
|
||||
test("new tab button should open a new tab", async ({ page }) => {
|
||||
@@ -124,11 +124,11 @@ test("new tab button should open a new tab", async ({ page }) => {
|
||||
await notes.editor.newTab();
|
||||
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await expect(tabs[0].titleElement).toHaveText("Note 1");
|
||||
await expect(tabs[1].titleElement).toHaveText("Untitled");
|
||||
expect(await tabs[0].title()).toBe("Note 1");
|
||||
expect(await tabs[1].title()).toBe("Untitled");
|
||||
});
|
||||
|
||||
test("content changes in a note opened in multiple tabs should sync", async ({
|
||||
test("changes in a note opened in multiple tabs should sync", async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
@@ -173,7 +173,6 @@ test("reloading with a note diff open in a tab", async ({ page }) => {
|
||||
const history = await note?.properties.getSessionHistory();
|
||||
const preview = await history?.[0].open();
|
||||
await preview!.firstEditor.waitFor({ state: "visible" });
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.reload();
|
||||
await preview!.firstEditor.waitFor({ state: "visible" });
|
||||
@@ -228,7 +227,7 @@ test("clicking on a note that's already opened in another tab should focus the t
|
||||
await note?.openNote();
|
||||
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await expect(tabs[0].locator).toHaveClass(/active/);
|
||||
expect(await tabs[0].isActive()).toBe(true);
|
||||
});
|
||||
|
||||
test("open a note in 2 tabs then open another note and navigate back", async ({
|
||||
@@ -249,134 +248,8 @@ test("open a note in 2 tabs then open another note and navigate back", async ({
|
||||
await notes.editor.goBack();
|
||||
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await expect(tabs[1].locator).toHaveClass(/active/);
|
||||
await expect(tabs[1].titleElement).toHaveText("Note 1");
|
||||
});
|
||||
|
||||
test("shouldn't be possible to open a note in a pinned tab", async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote({
|
||||
title: "Note 1"
|
||||
});
|
||||
await notes.createNote({
|
||||
title: "Note 2"
|
||||
});
|
||||
let tabs = await notes.editor.getTabs();
|
||||
await tabs[0].contextMenu.pin();
|
||||
|
||||
await note?.click();
|
||||
await notes.editor.waitForLoading();
|
||||
|
||||
tabs = await notes.editor.getTabs();
|
||||
expect(tabs.length).toBe(2);
|
||||
await expect(tabs[1].locator).toHaveClass(/active/);
|
||||
await expect(tabs[1].titleElement).toHaveText("Note 1");
|
||||
});
|
||||
|
||||
test("shouldn't be possible to create a new note in a pinned tab", async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
await notes.createNote({
|
||||
title: "Note 1"
|
||||
});
|
||||
let tabs = await notes.editor.getTabs();
|
||||
await tabs[0].contextMenu.pin();
|
||||
|
||||
await notes.newNote();
|
||||
|
||||
tabs = await notes.editor.getTabs();
|
||||
expect(tabs.length).toBe(2);
|
||||
await expect(tabs[1].locator).toHaveClass(/active/);
|
||||
});
|
||||
|
||||
test("notes open in multiple tabs should sync tags when tags are added", async ({
|
||||
page
|
||||
}) => {
|
||||
const tags = ["toAdd", "todo"];
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await note?.contextMenu.openInNewTab();
|
||||
|
||||
await notes.editor.setTags(tags);
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await tabs[0].click();
|
||||
|
||||
const noteTags = await notes.editor.getTags();
|
||||
expect(noteTags).toHaveLength(tags.length);
|
||||
expect(noteTags.every((t, i) => t === tags[i])).toBe(true);
|
||||
});
|
||||
|
||||
test("notes open in multiple tabs should sync tags when tags are removed", async ({
|
||||
page
|
||||
}) => {
|
||||
const tags = ["removeme", "dontremoveme", "removemex2", "todo"];
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await notes.editor.setTags(tags);
|
||||
await note?.contextMenu.openInNewTab();
|
||||
|
||||
await notes.editor.removeTags(["removeme", "removemex2"]);
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await tabs[0].click();
|
||||
|
||||
const noteTags = await notes.editor.getTags();
|
||||
expect(noteTags).toHaveLength(2);
|
||||
expect(noteTags.every((t, i) => t === ["dontremoveme", "todo"][i])).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
test("notes open in multiple tabs should sync color in note properties when color is changed", async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await note?.contextMenu.newColor({ title: "red", color: "#ff0000" });
|
||||
await note?.contextMenu.newColor({ title: "blue", color: "#0000ff" });
|
||||
await note?.contextMenu.openInNewTab();
|
||||
|
||||
await notes.editor.waitForLoading();
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await tabs[0].click();
|
||||
|
||||
expect(await note?.properties.isColored("blue")).toBe(true);
|
||||
|
||||
await note?.properties.color("red");
|
||||
await tabs[1].click();
|
||||
|
||||
expect(await note?.properties.isColored("red")).toBe(true);
|
||||
});
|
||||
|
||||
test("notes open in multiple tabs should sync title when title is changed", async ({
|
||||
page
|
||||
}) => {
|
||||
const app = new AppModel(page);
|
||||
await app.goto();
|
||||
const notes = await app.goToNotes();
|
||||
const note = await notes.createNote(NOTE);
|
||||
await notes.editor.setTitle("Todo");
|
||||
await note?.contextMenu.openInNewTab();
|
||||
|
||||
expect(await notes.editor.getTitle()).toBe("Todo");
|
||||
|
||||
await notes.editor.setTitle("Todo - Today");
|
||||
const tabs = await notes.editor.getTabs();
|
||||
await tabs[0].click();
|
||||
|
||||
expect(await notes.editor.getTitle()).toBe("Todo - Today");
|
||||
expect(await tabs[1].isActive()).toBe(true);
|
||||
expect(await tabs[1].title()).toBe("Note 1");
|
||||
});
|
||||
|
||||
test.skip("TODO: open a locked note, switch to another note and navigate back", () => {});
|
||||
|
||||
@@ -99,8 +99,8 @@ test("create shortcut of a tag", async ({ page }) => {
|
||||
await tag?.createShortcut();
|
||||
|
||||
expect(await tag?.isShortcut()).toBe(true);
|
||||
await app.goToHome();
|
||||
expect(await app.navigation.findItem("hello-world")).toBeDefined();
|
||||
const allShortcuts = await app.navigation.getShortcuts();
|
||||
expect(allShortcuts.includes("hello-world")).toBeTruthy();
|
||||
});
|
||||
|
||||
test("remove shortcut of a tag", async ({ page }) => {
|
||||
@@ -204,17 +204,20 @@ test(`sort tags`, async ({ page }, info) => {
|
||||
if (!tag) continue;
|
||||
}
|
||||
|
||||
for (const sortBy of sortByOptions) {
|
||||
for (const orderBy of orderByOptions) {
|
||||
await test.step(`sort by ${sortBy}, order by ${orderBy}`, async () => {
|
||||
const sortResult = await tags?.sort({
|
||||
orderBy,
|
||||
sortBy
|
||||
});
|
||||
if (!sortResult) return;
|
||||
for (const groupBy of groupByOptions) {
|
||||
for (const sortBy of sortByOptions) {
|
||||
for (const orderBy of orderByOptions) {
|
||||
await test.step(`group by ${groupBy}, sort by ${sortBy}, order by ${orderBy}`, async () => {
|
||||
const sortResult = await tags?.sort({
|
||||
groupBy,
|
||||
orderBy,
|
||||
sortBy
|
||||
});
|
||||
if (!sortResult) return;
|
||||
|
||||
await expect(tags.items).toHaveCount(titles.length);
|
||||
});
|
||||
await expect(tags.items).toHaveCount(titles.length);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ The flow will be as follows:
|
||||
5. Use the database password to init the db & keep the user's encryption key in memory. (we have 2 choices here: either keep the encryption key in memory or keep the pin in memory)
|
||||
6. If not enabled, we will ask the keystore to give us the database password + user's encryption key
|
||||
|
||||
We should store both the database password and the user's encryption key in a keychain. If user sets a pin, we can just double encrypt these values. This will keep things simple and seamless.
|
||||
We should store both the database password and the user's encryption key in a keychain. If user sets a pin, we can just double encrypt these values. This will keep things simple and seemless.
|
||||
|
||||
Q: How to find out if app lock is enabled?
|
||||
|
||||
|
||||
@@ -1,57 +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/>.
|
||||
*/
|
||||
|
||||
function isBeta(cookie: string) {
|
||||
console.log("Checking cookie:", cookie);
|
||||
const releaseTrack = cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("release-track="))
|
||||
?.split("=")[1];
|
||||
return releaseTrack === "beta";
|
||||
}
|
||||
|
||||
interface Env {
|
||||
BETA_BASE_URL: string;
|
||||
}
|
||||
|
||||
export const onRequest: PagesFunction<Env> = async ({ request, env, next }) => {
|
||||
try {
|
||||
const url = new URL(request.url);
|
||||
const response = await (async () => {
|
||||
if (isBeta(request.headers.get("Cookie") || "") && env.BETA_BASE_URL) {
|
||||
const betaUrl = new URL(env.BETA_BASE_URL);
|
||||
betaUrl.pathname = url.pathname;
|
||||
betaUrl.search = url.search;
|
||||
console.log("Fetching asset from beta URL:", betaUrl.toString());
|
||||
const asset = await fetch(betaUrl, {
|
||||
headers: request.headers,
|
||||
method: request.method,
|
||||
body: request.body
|
||||
});
|
||||
return new Response(asset.body, asset);
|
||||
} else {
|
||||
return await next();
|
||||
}
|
||||
})();
|
||||
return response;
|
||||
} catch (thrown) {
|
||||
console.error("Error occurred:", thrown);
|
||||
return new Response(thrown);
|
||||
}
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "CommonJS",
|
||||
"lib": ["ES2020"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
21
apps/web/package-lock.json
generated
21
apps/web/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/web",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -77,7 +77,7 @@
|
||||
"react-modal": "3.16.3",
|
||||
"react-qrcode-logo": "^2.9.0",
|
||||
"react-scroll-sync": "^0.11.2",
|
||||
"react-virtuoso": "^4.12.3",
|
||||
"react-virtuoso": "^4.6.2",
|
||||
"snarkdown": "^2.0.0",
|
||||
"timeago.js": "4.0.2",
|
||||
"w3c-keyname": "^2.2.6",
|
||||
@@ -87,7 +87,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@cloudflare/workers-types": "^4.20250224.0",
|
||||
"@playwright/test": "1.48.2",
|
||||
"@swc/plugin-react-remove-properties": "^6.0.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
@@ -296,7 +295,6 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@notesnook-importer/core": "^2.1.1",
|
||||
"@notesnook/common": "file:../common",
|
||||
"@notesnook/intl": "file:../intl",
|
||||
"@notesnook/theme": "file:../theme",
|
||||
@@ -499,7 +497,7 @@
|
||||
},
|
||||
"../desktop": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.0.29",
|
||||
"version": "3.0.24",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -508,7 +506,7 @@
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "11.5.0",
|
||||
"electron-trpc": "0.7.1",
|
||||
"electron-trpc": "0.6.1",
|
||||
"electron-updater": "^6.3.4",
|
||||
"icojs": "^0.19.4",
|
||||
"sqlite-better-trigram": "0.0.2",
|
||||
@@ -531,7 +529,7 @@
|
||||
"slugify": "1.6.6",
|
||||
"tree-kill": "^1.2.2",
|
||||
"undici": "^6.19.8",
|
||||
"vitest": "^2.1.8"
|
||||
"vitest": "2.1.8"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dmg-license": "^1.0.11"
|
||||
@@ -2134,13 +2132,6 @@
|
||||
"pnpm": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@cloudflare/workers-types": {
|
||||
"version": "4.20250224.0",
|
||||
"resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250224.0.tgz",
|
||||
"integrity": "sha512-j6ZwQ5G2moQRaEtGI2u5TBQhVXv/XwOS5jfBAheZHcpCM07zm8j0i8jZHHLq/6VA8e6VRjKohOyj5j6tZ1KHLQ==",
|
||||
"dev": true,
|
||||
"license": "MIT OR Apache-2.0"
|
||||
},
|
||||
"node_modules/@dnd-kit/accessibility": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.1.0-beta.1",
|
||||
"version": "3.0.25",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
@@ -75,7 +75,7 @@
|
||||
"react-modal": "3.16.3",
|
||||
"react-qrcode-logo": "^2.9.0",
|
||||
"react-scroll-sync": "^0.11.2",
|
||||
"react-virtuoso": "^4.12.3",
|
||||
"react-virtuoso": "^4.6.2",
|
||||
"snarkdown": "^2.0.0",
|
||||
"timeago.js": "4.0.2",
|
||||
"w3c-keyname": "^2.2.6",
|
||||
@@ -85,7 +85,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@cloudflare/workers-types": "^4.20250224.0",
|
||||
"@playwright/test": "1.48.2",
|
||||
"@swc/plugin-react-remove-properties": "^6.0.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
@@ -132,7 +131,6 @@
|
||||
"start:test": "serve -s build/ -p 3000",
|
||||
"build": "cross-env PLATFORM=web vite build",
|
||||
"build:test": "cross-env PLATFORM=web TEST=true vite build",
|
||||
"build:beta": "cross-env PLATFORM=web BETA=true vite build",
|
||||
"build:desktop": "cross-env PLATFORM=desktop vite build",
|
||||
"analyze": "cross-env ANALYZING=true PLATFORM=web vite build",
|
||||
"test": "playwright test -u",
|
||||
|
||||
@@ -48,9 +48,11 @@ import { AnnouncementDialog } from "./dialogs/announcement-dialog";
|
||||
import { logger } from "./utils/logger";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export default function AppEffects() {
|
||||
type AppEffectsProps = {
|
||||
setShow: (show: boolean) => void;
|
||||
};
|
||||
export default function AppEffects({ setShow }: AppEffectsProps) {
|
||||
const refreshNavItems = useStore((store) => store.refreshNavItems);
|
||||
const toggleListPane = useStore((store) => store.toggleListPane);
|
||||
const updateLastSynced = useStore((store) => store.updateLastSynced);
|
||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||
const initUser = useUserStore((store) => store.init);
|
||||
@@ -232,7 +234,7 @@ export default function AppEffects() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
toggleListPane(!isFocusMode);
|
||||
setShow(!isFocusMode);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isFocusMode]);
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
:root {
|
||||
--sash-size: 10px;
|
||||
--sash-hover-size: 4px;
|
||||
}
|
||||
|
||||
.tabsScroll,
|
||||
.titlebarLogo,
|
||||
.theme-scope-titleBar,
|
||||
@@ -13,77 +18,101 @@
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* open-sans-regular - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: local(""), url("./assets/fonts/Inter-Regular.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-Regular.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 600;
|
||||
src: local(""), url("./assets/fonts/Inter-SemiBold.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-SemiBold.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 700;
|
||||
src: local(""), url("./assets/fonts/Inter-Bold.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-Bold.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 500;
|
||||
src: local(""), url("./assets/fonts/Inter-Medium.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-Medium.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: local(""), url("./assets/fonts/Inter-Italic.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-Italic.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 600;
|
||||
src: local(""),
|
||||
url("./assets/fonts/Inter-SemiBoldItalic.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-SemiBoldItalic.ttf") format("truetype");
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-regular.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
|
||||
/* open-sans-600 - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local(""),
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
/* open-sans-700 - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local(""), url("./assets/fonts/Inter-BoldItalic.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-BoldItalic.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 500;
|
||||
src: local(""), url("./assets/fonts/Inter-MediumItalic.woff2") format("woff2"),
|
||||
url("./assets/fonts/Inter-MediumItalic.ttf") format("truetype");
|
||||
src: local(""),
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
/* open-sans-italic - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local(""),
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-italic.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
/* open-sans-600italic - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local(""),
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600italic.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600italic.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-600italic.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
/* open-sans-700italic - vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local(""),
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff2")
|
||||
format("woff2"),
|
||||
/* Super Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */
|
||||
url("./assets/fonts/open-sans-v34-vietnamese_latin-ext_latin_hebrew_greek-ext_greek_cyrillic-ext_cyrillic-700italic.ttf")
|
||||
format("truetype");
|
||||
}
|
||||
|
||||
.rpv-core__text-layer,
|
||||
@@ -220,26 +249,3 @@ textarea,
|
||||
background-color: color-mix(in srgb, var(--accent) 5%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
kbd {
|
||||
background: var(--background);
|
||||
border-radius: 3px;
|
||||
padding: 2px 5px;
|
||||
color: var(--paragraph-secondary);
|
||||
}
|
||||
|
||||
.ping {
|
||||
animation: ping 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes ping {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ import { AppEventManager, AppEvents } from "./common/app-events";
|
||||
import { TITLE_BAR_HEIGHT } from "./components/title-bar";
|
||||
import { getFontSizes } from "@notesnook/theme/theme/font/fontsize.js";
|
||||
import { useWindowControls } from "./hooks/use-window-controls";
|
||||
import { STATUS_BAR_HEIGHT } from "./common/constants";
|
||||
|
||||
new WebExtensionRelay();
|
||||
|
||||
function App() {
|
||||
const isMobile = useMobile();
|
||||
const [show, setShow] = useState(true);
|
||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||
const { isFocused } = useWindowFocus();
|
||||
const { isFullscreen } = useWindowControls();
|
||||
@@ -64,8 +64,11 @@ function App() {
|
||||
{isFocused ? null : (
|
||||
<Global
|
||||
styles={`
|
||||
.nav-pane {
|
||||
opacity: 0.7;
|
||||
body {
|
||||
filter: brightness(0.95) grayscale(1);
|
||||
}
|
||||
.titlebar {
|
||||
background: var(--background-secondary) !important;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
@@ -74,9 +77,15 @@ function App() {
|
||||
<Global
|
||||
// These styles to make sure the app content doesn't overlap with the traffic lights.
|
||||
styles={`
|
||||
.nav-pane .theme-scope-navigationMenu,
|
||||
.mobile-nav-pane .theme-scope-navigationMenu {
|
||||
padding-top: env(titlebar-area-height) !important;
|
||||
.nav-pane,
|
||||
.mobile-nav-pane {
|
||||
margin-top: env(titlebar-area-height) !important;
|
||||
height: calc(100% - env(titlebar-area-height)) !important;
|
||||
}
|
||||
.nav-pane.collapsed + .list-pane .route-container-header,
|
||||
.nav-pane.collapsed + .list-pane.collapsed + .editor-pane .editor-action-bar,
|
||||
.nav-pane.collapsed + .editor-pane .editor-action-bar {
|
||||
padding-left: 25px;
|
||||
}
|
||||
.editor-pane:first-of-type .editor-action-bar,
|
||||
.mobile-editor-pane.pane-active .editor-action-bar,
|
||||
@@ -92,9 +101,9 @@ function App() {
|
||||
.route-container-header .routeHeader {
|
||||
font-size: ${getFontSizes().title};
|
||||
}
|
||||
// .global-split-pane .react-split__sash {
|
||||
// height: calc(100% - ${TITLE_BAR_HEIGHT}px);
|
||||
// }
|
||||
.global-split-pane .react-split__sash {
|
||||
height: calc(100% - ${TITLE_BAR_HEIGHT}px);
|
||||
}
|
||||
`}
|
||||
/>
|
||||
) : null}
|
||||
@@ -104,7 +113,7 @@ function App() {
|
||||
<GlobalMenuWrapper />
|
||||
</div>
|
||||
</Suspense>
|
||||
<AppEffects />
|
||||
<AppEffects setShow={setShow} />
|
||||
|
||||
<Flex
|
||||
id="app"
|
||||
@@ -116,11 +125,12 @@ function App() {
|
||||
height: "100%"
|
||||
}}
|
||||
>
|
||||
{isMobile ? <MobileAppContents /> : <DesktopAppContents />}
|
||||
<Toaster
|
||||
containerClassName="toasts-container"
|
||||
containerStyle={{ bottom: STATUS_BAR_HEIGHT + 10 }}
|
||||
/>
|
||||
{isMobile ? (
|
||||
<MobileAppContents />
|
||||
) : (
|
||||
<DesktopAppContents setShow={setShow} show={show} />
|
||||
)}
|
||||
<Toaster containerClassName="toasts-container" />
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
@@ -128,18 +138,35 @@ function App() {
|
||||
|
||||
export default App;
|
||||
|
||||
function DesktopAppContents() {
|
||||
type DesktopAppContentsProps = {
|
||||
show: boolean;
|
||||
setShow: (show: boolean) => void;
|
||||
};
|
||||
function DesktopAppContents({ show, setShow }: DesktopAppContentsProps) {
|
||||
const isFocusMode = useStore((store) => store.isFocusMode);
|
||||
const isListPaneVisible = useStore((store) => store.isListPaneVisible);
|
||||
const isTablet = useTablet();
|
||||
// const [isNarrow, setIsNarrow] = useState(isTablet || false);
|
||||
const [isNarrow, setIsNarrow] = useState(isTablet || false);
|
||||
const navPane = useRef<SplitPaneImperativeHandle>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTablet) navPane.current?.collapse(0);
|
||||
else if (navPane.current?.isCollapsed(0)) navPane.current?.expand(0);
|
||||
else navPane.current?.expand(0);
|
||||
}, [isTablet]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (show) middlePane.current?.expand();
|
||||
// else middlePane.current?.collapse();
|
||||
// }, [show]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (isFocusMode) {
|
||||
// const middlePaneSize = middlePane.current?.getSize() || 20;
|
||||
// navPane.current?.collapse();
|
||||
// // the middle pane has to be resized because collapsing the nav
|
||||
// // pane increases the middle pane's size every time.
|
||||
// middlePane.current?.resize(middlePaneSize);
|
||||
// } else navPane.current?.expand();
|
||||
// }, [isFocusMode]);
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
@@ -154,26 +181,27 @@ function DesktopAppContents() {
|
||||
autoSaveId="global-panel-group"
|
||||
direction="vertical"
|
||||
onChange={(sizes) => {
|
||||
useStore.setState({ isNavPaneCollapsed: sizes[0] <= 70 });
|
||||
setIsNarrow(sizes[0] <= 70);
|
||||
}}
|
||||
>
|
||||
{isFocusMode ? null : (
|
||||
<Pane
|
||||
id="nav-pane"
|
||||
initialSize={isTablet ? 0 : 250}
|
||||
initialSize={180}
|
||||
className={`nav-pane`}
|
||||
snapSize={160}
|
||||
minSize={50}
|
||||
maxSize={isTablet ? 0 : 500}
|
||||
style={{
|
||||
overflow: "initial",
|
||||
zIndex: 3
|
||||
}}
|
||||
snapSize={120}
|
||||
maxSize={300}
|
||||
>
|
||||
<NavigationMenu onExpand={() => navPane.current?.reset(0)} />
|
||||
<NavigationMenu
|
||||
toggleNavigationContainer={(state) => {
|
||||
setShow(state || !show);
|
||||
}}
|
||||
isTablet={isNarrow}
|
||||
/>
|
||||
</Pane>
|
||||
)}
|
||||
{!isFocusMode && isListPaneVisible ? (
|
||||
{!isFocusMode && show ? (
|
||||
<Pane
|
||||
id="list-pane"
|
||||
initialSize={380}
|
||||
@@ -283,7 +311,7 @@ function MobileAppContents() {
|
||||
flexShrink: 0
|
||||
}}
|
||||
>
|
||||
<NavigationMenu />
|
||||
<NavigationMenu toggleNavigationContainer={() => {}} isTablet={false} />
|
||||
</Flex>
|
||||
<Flex
|
||||
className="mobile-list-pane"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user