mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-08-30 18:48:27 +02:00
Compare commits
10 Commits
3.2.1-andr
...
fix-input-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10b495cdbe | ||
|
|
d456132dd6 | ||
|
|
4ac7941b6c | ||
|
|
e7f5463917 | ||
|
|
6e41ce459d | ||
|
|
f5095fa643 | ||
|
|
e6a5b85011 | ||
|
|
409c5a2517 | ||
|
|
35cd6b101d | ||
|
|
2440e28168 |
12
apps/desktop/package-lock.json
generated
12
apps/desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/desktop",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
@@ -15,7 +15,7 @@
|
||||
"@notesnook/ui": "file:../../packages/ui",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "11.3.0",
|
||||
"better-sqlite3-multiple-ciphers": "^11.10.0",
|
||||
"electron-trpc": "0.7.1",
|
||||
"electron-updater": "^6.6.2",
|
||||
"icojs": "^0.19.5",
|
||||
@@ -2282,9 +2282,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/better-sqlite3-multiple-ciphers": {
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3-multiple-ciphers/-/better-sqlite3-multiple-ciphers-11.3.0.tgz",
|
||||
"integrity": "sha512-F0+gYaT8drCyHpujgMjS4RRAElVdAtif0uH/v4rA5cLTR5v25zDXTkj2/ie8A26Www+vT60pCF0MD+MGzIcUzw==",
|
||||
"version": "11.10.0",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3-multiple-ciphers/-/better-sqlite3-multiple-ciphers-11.10.0.tgz",
|
||||
"integrity": "sha512-/dKO3lKuJFbmuzh80uN2cmMsz8iyTskGB2l/fd9X6rt1P3EPIOvRUIxD7Qim8gLygUPB/u+db8byZGumOOdp3g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@notesnook/desktop",
|
||||
"productName": "Notesnook",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"appAppleId": "1544027013",
|
||||
"private": true,
|
||||
"main": "./dist/cjs/index.js",
|
||||
@@ -30,7 +30,7 @@
|
||||
"@notesnook/ui": "file:../../packages/ui",
|
||||
"@trpc/client": "10.45.2",
|
||||
"@trpc/server": "10.45.2",
|
||||
"better-sqlite3-multiple-ciphers": "11.3.0",
|
||||
"better-sqlite3-multiple-ciphers": "^11.10.0",
|
||||
"electron-trpc": "0.7.1",
|
||||
"electron-updater": "^6.6.2",
|
||||
"icojs": "^0.19.5",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/better-sqlite3-multiple-ciphers/deps/defines.gypi b/node_modules/better-sqlite3-multiple-ciphers/deps/defines.gypi
|
||||
index 1a14ecd..dabcce2 100644
|
||||
index 1a14ecd..ff938f1 100644
|
||||
--- a/node_modules/better-sqlite3-multiple-ciphers/deps/defines.gypi
|
||||
+++ b/node_modules/better-sqlite3-multiple-ciphers/deps/defines.gypi
|
||||
@@ -38,5 +38,6 @@
|
||||
@@ -33,6 +33,8 @@ export class SQLite {
|
||||
initialized = false;
|
||||
preparedStatements: Map<string, Statement<unknown[]>> = new Map();
|
||||
retryCounter: Record<string, number> = {};
|
||||
extensionsLoaded = false;
|
||||
|
||||
constructor() {
|
||||
console.log("new sqlite worker");
|
||||
}
|
||||
@@ -46,10 +48,6 @@ export class SQLite {
|
||||
this.sqlite = require("better-sqlite3-multiple-ciphers")(
|
||||
filePath
|
||||
).unsafeMode(true);
|
||||
const betterTrigram = require("sqlite-better-trigram");
|
||||
const fts5Html = require("sqlite3-fts5-html");
|
||||
betterTrigram.load(this.sqlite);
|
||||
fts5Html.load(this.sqlite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,6 +115,20 @@ export class SQLite {
|
||||
} catch (e) {
|
||||
if (e instanceof Error) e.message += ` (query: ${sql})`;
|
||||
throw e;
|
||||
} finally {
|
||||
// Since SQLite 3.48.0 (SQLite3MC v2.0.2) it's not possible to load fts5
|
||||
// extensions before database has been decrypting. This is because
|
||||
// executing a `SELECT` now accesses the underlying databases resulting in
|
||||
// an error. Since FTS5 extensions depend on `SELECT fts5` to load the
|
||||
// fts5 API, we must wait decrypt the database before we can load
|
||||
// the extensions.
|
||||
if (!this.extensionsLoaded && (await this.isDatabaseReady())) {
|
||||
const betterTrigram = require("sqlite-better-trigram");
|
||||
const fts5Html = require("sqlite3-fts5-html");
|
||||
betterTrigram.load(this.sqlite);
|
||||
fts5Html.load(this.sqlite);
|
||||
this.extensionsLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,4 +156,22 @@ export class SQLite {
|
||||
retryDelay: 500
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This just executes `SELECT 1` on the database to make sure its ready.
|
||||
* On an encrypted database, this will fail until `PRAGMA key` has been
|
||||
* called.
|
||||
*/
|
||||
private async isDatabaseReady() {
|
||||
// return this.exec(`SELECT 1;`)
|
||||
// .then(() => true)
|
||||
// .catch(() => false);
|
||||
if (!this.sqlite) return false;
|
||||
try {
|
||||
this.sqlite.prepare(`SELECT 1;`).run();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,26 +17,20 @@ 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 React, { useRef, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { db } from "../../common/database";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
ToastManager
|
||||
} from "../../services/event-manager";
|
||||
import BackupService from "../../services/backup";
|
||||
import { eSendEvent, ToastManager } from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { eCloseSheet, eOpenRecoveryKeyDialog } from "../../utils/events";
|
||||
import DialogHeader from "../dialog/dialog-header";
|
||||
import { eOpenRecoveryKeyDialog } from "../../utils/events";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { Dialog } from "../dialog";
|
||||
import { Button } from "../ui/button";
|
||||
import Input from "../ui/input";
|
||||
import { Notice } from "../ui/notice";
|
||||
import Seperator from "../ui/seperator";
|
||||
import { Dialog } from "../dialog";
|
||||
import BackupService from "../../services/backup";
|
||||
import { sleep } from "../../utils/time";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
|
||||
export const ChangePassword = () => {
|
||||
const passwordInputRef = useRef();
|
||||
@@ -85,8 +79,7 @@ export const ChangePassword = () => {
|
||||
context: "global"
|
||||
});
|
||||
setLoading(false);
|
||||
eSendEvent(eCloseSheet);
|
||||
await sleep(300);
|
||||
Navigation.goBack();
|
||||
eSendEvent(eOpenRecoveryKeyDialog);
|
||||
} catch (e) {
|
||||
setLoading(false);
|
||||
@@ -108,9 +101,6 @@ export const ChangePassword = () => {
|
||||
}}
|
||||
>
|
||||
<Dialog context="change-password-dialog" />
|
||||
<DialogHeader title={strings.changePassword()} />
|
||||
<Seperator />
|
||||
|
||||
<Input
|
||||
fwdRef={oldPasswordInputRef}
|
||||
onChangeText={(value) => {
|
||||
@@ -160,9 +150,3 @@ export const ChangePassword = () => {
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
ChangePassword.present = () => {
|
||||
presentSheet({
|
||||
component: <ChangePassword />
|
||||
});
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ import { hideAuth } from "./common";
|
||||
import { ForgotPassword } from "./forgot-password";
|
||||
import { useLogin } from "./use-login";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { Dialog } from "../dialog";
|
||||
|
||||
const LoginSteps = {
|
||||
emailAuth: 1,
|
||||
@@ -89,7 +90,7 @@ export const Login = ({ changeMode }) => {
|
||||
return (
|
||||
<>
|
||||
<ForgotPassword />
|
||||
<SheetProvider context="two_factor_verify" />
|
||||
<Dialog context="two_factor_verify" />
|
||||
<View
|
||||
style={{
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
|
||||
@@ -24,12 +24,8 @@ import { View } from "react-native";
|
||||
import { ScrollView } from "react-native-actions-sheet";
|
||||
import { db } from "../../common/database/index";
|
||||
import useTimer from "../../hooks/use-timer";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
ToastManager
|
||||
} from "../../services/event-manager";
|
||||
import { eCloseSheet } from "../../utils/events";
|
||||
import { eSendEvent, ToastManager } from "../../services/event-manager";
|
||||
import { eCloseSimpleDialog } from "../../utils/events";
|
||||
import { AppFontSize } from "../../utils/size";
|
||||
import { Button } from "../ui/button";
|
||||
import { IconButton } from "../ui/icon-button";
|
||||
@@ -38,6 +34,7 @@ import { Pressable } from "../ui/pressable";
|
||||
import Heading from "../ui/typography/heading";
|
||||
import Paragraph from "../ui/typography/paragraph";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { presentDialog } from "../dialog/functions";
|
||||
|
||||
const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -46,7 +43,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
method: mfaInfo?.primaryMethod,
|
||||
isPrimary: true
|
||||
});
|
||||
const { seconds, start } = useTimer(currentMethod.method);
|
||||
const { seconds, start, reset } = useTimer(currentMethod.method);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const inputRef = useRef();
|
||||
const [sending, setSending] = useState(false);
|
||||
@@ -62,7 +59,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
},
|
||||
(result) => {
|
||||
if (result) {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -133,6 +130,12 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
<ScrollView
|
||||
keyboardShouldPersistTaps="handled"
|
||||
keyboardDismissMode="interactive"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor: colors.primary.background,
|
||||
paddingTop: 60
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
@@ -236,7 +239,10 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
<Button
|
||||
title={strings.cancel()}
|
||||
type="secondaryAccented"
|
||||
onPress={onCancel}
|
||||
onPress={() => {
|
||||
reset();
|
||||
onCancel();
|
||||
}}
|
||||
width={250}
|
||||
/>
|
||||
|
||||
@@ -297,7 +303,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo, onCancel }) => {
|
||||
};
|
||||
|
||||
TwoFactorVerification.present = (onMfaLogin, data, onCancel, context) => {
|
||||
presentSheet({
|
||||
presentDialog({
|
||||
component: () => (
|
||||
<TwoFactorVerification
|
||||
onMfaLogin={onMfaLogin}
|
||||
@@ -306,7 +312,9 @@ TwoFactorVerification.present = (onMfaLogin, data, onCancel, context) => {
|
||||
/>
|
||||
),
|
||||
context: context || "two_factor_verify",
|
||||
disableClosing: true
|
||||
disableClosing: true,
|
||||
transparent: false,
|
||||
statusBarTranslucent: true
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { clearMessage } from "../../services/message";
|
||||
import PremiumService from "../../services/premium";
|
||||
import SettingsService from "../../services/settings";
|
||||
import { useUserStore } from "../../stores/use-user-store";
|
||||
import { eCloseSheet } from "../../utils/events";
|
||||
import { eCloseSimpleDialog } from "../../utils/events";
|
||||
import TwoFactorVerification from "./two-factor";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
@@ -92,7 +92,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
} catch (e) {
|
||||
callback && callback(false);
|
||||
if (e.message === "invalid_grant") {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ export const useLogin = (onFinishLogin, sessionExpired = false) => {
|
||||
},
|
||||
mfaInfo,
|
||||
() => {
|
||||
eSendEvent(eCloseSheet, "two_factor_verify");
|
||||
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
|
||||
setLoading(false);
|
||||
setStep(LoginSteps.emailAuth);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ export type DialogInfo = {
|
||||
paragraph?: string;
|
||||
positiveText: string;
|
||||
negativeText: string;
|
||||
background?: string;
|
||||
transparent?: boolean;
|
||||
statusBarTranslucent?: boolean;
|
||||
positivePress?: (...args: any[]) => Promise<any>;
|
||||
onClose?: () => void;
|
||||
positiveType?:
|
||||
|
||||
@@ -130,9 +130,17 @@ export const Dialog = ({ context = "global" }: { context?: string }) => {
|
||||
|
||||
return visible && dialogInfo ? (
|
||||
<BaseDialog
|
||||
statusBarTranslucent={false}
|
||||
statusBarTranslucent={
|
||||
dialogInfo.statusBarTranslucent === undefined
|
||||
? false
|
||||
: dialogInfo.statusBarTranslucent
|
||||
}
|
||||
bounce={!dialogInfo.input}
|
||||
closeOnTouch={!dialogInfo.disableBackdropClosing}
|
||||
background={dialogInfo.background}
|
||||
transparent={
|
||||
dialogInfo.transparent === undefined ? true : dialogInfo.transparent
|
||||
}
|
||||
onShow={async () => {
|
||||
if (dialogInfo.input) {
|
||||
inputRef.current?.setNativeProps({
|
||||
|
||||
@@ -52,7 +52,14 @@ const useTimer = (initialId?: string) => {
|
||||
};
|
||||
}, [seconds, id]);
|
||||
|
||||
return { seconds, setId, start };
|
||||
const reset = () => {
|
||||
if (id) {
|
||||
timers[id] = 0;
|
||||
setSeconds(0);
|
||||
}
|
||||
};
|
||||
|
||||
return { seconds, setId, start, reset };
|
||||
};
|
||||
|
||||
export default useTimer;
|
||||
|
||||
@@ -16,35 +16,22 @@ 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 React, { RefObject, useRef, useState } from "react";
|
||||
import React, { useRef, useState } from "react";
|
||||
import { TextInput, View } from "react-native";
|
||||
import { ActionSheetRef } from "react-native-actions-sheet";
|
||||
import { db } from "../../../common/database";
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
PresentSheetOptions,
|
||||
ToastManager
|
||||
} from "../../../services/event-manager";
|
||||
import DialogHeader from "../../dialog/dialog-header";
|
||||
import { Button } from "../../ui/button";
|
||||
import Input from "../../ui/input";
|
||||
import { eSendEvent, ToastManager } from "../../../services/event-manager";
|
||||
import { eUserLoggedIn } from "../../../utils/events";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
|
||||
type ChangeEmailProps = {
|
||||
actionSheetRef: RefObject<ActionSheetRef>;
|
||||
close?: () => void;
|
||||
update?: (options: PresentSheetOptions) => void;
|
||||
};
|
||||
import Input from "../../../components/ui/input";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
|
||||
enum EmailChangeSteps {
|
||||
verify,
|
||||
changeEmail
|
||||
}
|
||||
|
||||
export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
export const ChangeEmail = () => {
|
||||
const [step, setStep] = useState(EmailChangeSteps.verify);
|
||||
const emailChangeData = useRef<{
|
||||
email?: string;
|
||||
@@ -103,10 +90,6 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
|
||||
return (
|
||||
<View style={{ paddingHorizontal: DefaultAppStyles.GAP }}>
|
||||
<DialogHeader
|
||||
title={strings.changeEmail()}
|
||||
paragraph={strings.changeEmailDesc()}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
@@ -156,23 +139,12 @@ export const ChangeEmail = ({ close }: ChangeEmailProps) => {
|
||||
: strings.changeEmail()
|
||||
}
|
||||
type="accent"
|
||||
width={250}
|
||||
style={{
|
||||
width: "100%"
|
||||
}}
|
||||
loading={loading}
|
||||
onPress={onSubmit}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
height: 45,
|
||||
marginTop: 2
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
ChangeEmail.present = () => {
|
||||
presentSheet({
|
||||
component: (ref, close, update) => (
|
||||
<ChangeEmail actionSheetRef={ref} close={close} update={update} />
|
||||
)
|
||||
});
|
||||
};
|
||||
@@ -43,6 +43,8 @@ import ThemeSelector from "./theme-selector";
|
||||
import { TitleFormat } from "./title-format";
|
||||
import { View } from "react-native";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { ChangePassword } from "../../components/auth/change-password";
|
||||
import { ChangeEmail } from "./change-email";
|
||||
|
||||
export const components: { [name: string]: ReactElement } = {
|
||||
colorpicker: <AccentColorPicker />,
|
||||
@@ -69,5 +71,7 @@ export const components: { [name: string]: ReactElement } = {
|
||||
<AttachmentGroupProgress groupId="offline-mode" />
|
||||
</View>
|
||||
),
|
||||
"sidebar-tab-selector": <SidebarTabPicker />
|
||||
"sidebar-tab-selector": <SidebarTabPicker />,
|
||||
"change-password": <ChangePassword />,
|
||||
"change-email": <ChangeEmail />
|
||||
};
|
||||
|
||||
@@ -32,11 +32,9 @@ import { enabled } from "react-native-privacy-snapshot";
|
||||
import ScreenGuardModule from "react-native-screenguard";
|
||||
import { db } from "../../common/database";
|
||||
import filesystem from "../../common/filesystem";
|
||||
import { ChangePassword } from "../../components/auth/change-password";
|
||||
import { presentDialog } from "../../components/dialog/functions";
|
||||
import { AppLockPassword } from "../../components/dialogs/applock-password";
|
||||
import { endProgress, startProgress } from "../../components/dialogs/progress";
|
||||
import { ChangeEmail } from "../../components/sheets/change-email";
|
||||
import ExportNotesSheet from "../../components/sheets/export-notes";
|
||||
import { Issue } from "../../components/sheets/github/issue";
|
||||
import { Progress } from "../../components/sheets/progress";
|
||||
@@ -243,17 +241,15 @@ export const settingsGroups: SettingSection[] = [
|
||||
{
|
||||
id: "change-password",
|
||||
name: strings.changePassword(),
|
||||
modifer: async () => {
|
||||
ChangePassword.present();
|
||||
},
|
||||
description: strings.changePasswordDesc()
|
||||
type: "screen",
|
||||
description: strings.changePasswordDesc(),
|
||||
component: "change-password"
|
||||
},
|
||||
{
|
||||
id: "change-email",
|
||||
name: strings.changeEmail(),
|
||||
modifer: async () => {
|
||||
ChangeEmail.present();
|
||||
},
|
||||
type: "screen",
|
||||
component: "change-email",
|
||||
description: strings.changeEmailDesc()
|
||||
},
|
||||
{
|
||||
|
||||
@@ -124,7 +124,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
multiDexEnabled true
|
||||
versionCode 3057
|
||||
versionCode 3058
|
||||
versionName getNpmVersion()
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -1091,7 +1091,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1165,7 +1165,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -1196,7 +1196,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1270,7 +1270,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -1429,7 +1429,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1441,7 +1441,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
@@ -1472,7 +1472,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1485,7 +1485,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -1515,7 +1515,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
@@ -1589,7 +1589,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
@@ -1620,7 +1620,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 2135;
|
||||
CURRENT_PROJECT_VERSION = 2136;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
|
||||
@@ -1695,7 +1695,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 3.2.1;
|
||||
MARKETING_VERSION = 3.2.2;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
||||
4
apps/mobile/package-lock.json
generated
4
apps/mobile/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@notesnook/mobile",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"workspaces": [
|
||||
|
||||
1375
apps/web/package-lock.json
generated
1375
apps/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@notesnook/web",
|
||||
"description": "Your private note taking space",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"private": true,
|
||||
"main": "./src/app.js",
|
||||
"homepage": "https://notesnook.com/",
|
||||
|
||||
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { store as noteStore } from "../stores/note-store";
|
||||
import { store as trashStore } from "../stores/trash-store";
|
||||
import { store as notebookStore } from "../stores/notebook-store";
|
||||
import { store as attachmentStore } from "../stores/attachment-store";
|
||||
import { store as reminderStore } from "../stores/reminder-store";
|
||||
@@ -27,7 +28,11 @@ import { db } from "./db";
|
||||
import { showToast } from "../utils/toast";
|
||||
import Vault from "./vault";
|
||||
import { TaskManager } from "./task-manager";
|
||||
import { ConfirmDialog, showMultiDeleteConfirmation } from "../dialogs/confirm";
|
||||
import {
|
||||
ConfirmDialog,
|
||||
showMultiDeleteConfirmation,
|
||||
showMultiPermanentDeleteConfirmation
|
||||
} from "../dialogs/confirm";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
async function moveNotesToTrash(ids: string[], confirm = true) {
|
||||
@@ -77,14 +82,7 @@ async function moveNotebooksToTrash(ids: string[]) {
|
||||
if (!result) return;
|
||||
|
||||
if (result.deleteContainingNotes) {
|
||||
await Multiselect.moveNotesToTrash(
|
||||
Array.from(
|
||||
new Set(
|
||||
(await Promise.all(ids.map((id) => db.notebooks.notes(id)))).flat()
|
||||
)
|
||||
),
|
||||
false
|
||||
);
|
||||
await Multiselect.moveNotesToTrash(await db.notebooks.notes(...ids), false);
|
||||
}
|
||||
|
||||
await TaskManager.startTask({
|
||||
@@ -182,10 +180,50 @@ async function deleteTags(ids: string[]) {
|
||||
showToast("success", strings.actions.deleted.tag(ids.length));
|
||||
}
|
||||
|
||||
async function restoreItemsFromTrash(ids: string[]) {
|
||||
if (!ids.length) return;
|
||||
|
||||
await TaskManager.startTask({
|
||||
type: "status",
|
||||
id: "restoreItems",
|
||||
title: strings.inProgressActions.restoring.item(ids.length),
|
||||
action: async (report) => {
|
||||
report({
|
||||
text: strings.inProgressActions.restoring.item(ids.length)
|
||||
});
|
||||
await trashStore.restore(...ids);
|
||||
}
|
||||
});
|
||||
|
||||
showToast("success", strings.actions.restored.item(ids.length));
|
||||
}
|
||||
|
||||
async function deleteItemsFromTrash(ids: string[]) {
|
||||
if (!ids.length) return;
|
||||
|
||||
if (!(await showMultiPermanentDeleteConfirmation(ids.length))) return;
|
||||
|
||||
await TaskManager.startTask({
|
||||
type: "status",
|
||||
id: "restoreItems",
|
||||
title: strings.inProgressActions.permanentlyDeleting.item(ids.length),
|
||||
action: async (report) => {
|
||||
report({
|
||||
text: strings.inProgressActions.permanentlyDeleting.item(ids.length)
|
||||
});
|
||||
await trashStore.delete(...ids);
|
||||
}
|
||||
});
|
||||
|
||||
showToast("success", strings.actions.permanentlyDeleted.item(ids.length));
|
||||
}
|
||||
|
||||
export const Multiselect = {
|
||||
moveRemindersToTrash,
|
||||
moveNotebooksToTrash,
|
||||
moveNotesToTrash,
|
||||
deleteAttachments,
|
||||
deleteTags
|
||||
deleteTags,
|
||||
restoreItemsFromTrash,
|
||||
deleteItemsFromTrash
|
||||
};
|
||||
|
||||
@@ -561,11 +561,16 @@ export function Factory(Module) {
|
||||
databases.add(db);
|
||||
Module._sqlite3_free(zVfs);
|
||||
|
||||
check(fname, result);
|
||||
return db;
|
||||
};
|
||||
})();
|
||||
|
||||
sqlite3.register_extensions = (function () {
|
||||
return async function (db) {
|
||||
Module.ccall("RegisterExtensionFunctions", "void", ["number"], [db]);
|
||||
Module.ccall("sqlite3Fts5BetterTrigramInit", "void", ["number"], [db]);
|
||||
Module.ccall("sqlite3Fts5HtmlInit", "void", ["number"], [db]);
|
||||
check(fname, result);
|
||||
return db;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
@@ -724,6 +724,12 @@ export interface SQLiteAPI {
|
||||
*/
|
||||
open_v2(zFilename: string, iFlags?: number, zVfs?: string): Promise<number>;
|
||||
|
||||
/**
|
||||
* Register and init extensions.
|
||||
* @param db database pointer
|
||||
*/
|
||||
register_extensions(db: number): Promise<void>;
|
||||
|
||||
/**
|
||||
* Compile an SQL statement
|
||||
*
|
||||
|
||||
@@ -227,6 +227,9 @@ class _SQLiteWorker {
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
if (typeof this.db === "number")
|
||||
await this.sqlite.register_extensions(this.db);
|
||||
|
||||
self.dispatchEvent(
|
||||
new MessageEvent("message", {
|
||||
data: { type: "databaseInitialized", dbName: this.name }
|
||||
|
||||
@@ -142,12 +142,12 @@ a._sqlite3_table_column_metadata=function(){return(a._sqlite3_table_column_metad
|
||||
a._sqlite3_test_control=function(){return(a._sqlite3_test_control=a.asm.Oe).apply(null,arguments)};a._sqlite3_create_filename=function(){return(a._sqlite3_create_filename=a.asm.Pe).apply(null,arguments)};a._sqlite3_free_filename=function(){return(a._sqlite3_free_filename=a.asm.Qe).apply(null,arguments)};a._sqlite3_uri_parameter=function(){return(a._sqlite3_uri_parameter=a.asm.Re).apply(null,arguments)};a._sqlite3_uri_key=function(){return(a._sqlite3_uri_key=a.asm.Se).apply(null,arguments)};
|
||||
a._sqlite3_uri_boolean=function(){return(a._sqlite3_uri_boolean=a.asm.Te).apply(null,arguments)};a._sqlite3_uri_int64=function(){return(a._sqlite3_uri_int64=a.asm.Ue).apply(null,arguments)};a._sqlite3_filename_database=function(){return(a._sqlite3_filename_database=a.asm.Ve).apply(null,arguments)};a._sqlite3_filename_journal=function(){return(a._sqlite3_filename_journal=a.asm.We).apply(null,arguments)};a._sqlite3_filename_wal=function(){return(a._sqlite3_filename_wal=a.asm.Xe).apply(null,arguments)};
|
||||
a._sqlite3_db_name=function(){return(a._sqlite3_db_name=a.asm.Ye).apply(null,arguments)};a._sqlite3_db_filename=function(){return(a._sqlite3_db_filename=a.asm.Ze).apply(null,arguments)};a._sqlite3_db_readonly=function(){return(a._sqlite3_db_readonly=a.asm._e).apply(null,arguments)};a._sqlite3_compileoption_used=function(){return(a._sqlite3_compileoption_used=a.asm.$e).apply(null,arguments)};a._sqlite3_compileoption_get=function(){return(a._sqlite3_compileoption_get=a.asm.af).apply(null,arguments)};
|
||||
a._sqlite3_sourceid=function(){return(a._sqlite3_sourceid=a.asm.bf).apply(null,arguments)};a._sqlite3mc_config=function(){return(a._sqlite3mc_config=a.asm.cf).apply(null,arguments)};a._sqlite3mc_cipher_count=function(){return(a._sqlite3mc_cipher_count=a.asm.df).apply(null,arguments)};a._sqlite3mc_cipher_index=function(){return(a._sqlite3mc_cipher_index=a.asm.ef).apply(null,arguments)};a._sqlite3mc_cipher_name=function(){return(a._sqlite3mc_cipher_name=a.asm.ff).apply(null,arguments)};
|
||||
a._sqlite3mc_config_cipher=function(){return(a._sqlite3mc_config_cipher=a.asm.gf).apply(null,arguments)};a._sqlite3mc_codec_data=function(){return(a._sqlite3mc_codec_data=a.asm.hf).apply(null,arguments)};a._sqlite3_key=function(){return(a._sqlite3_key=a.asm.jf).apply(null,arguments)};a._sqlite3_key_v2=function(){return(a._sqlite3_key_v2=a.asm.kf).apply(null,arguments)};a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.lf).apply(null,arguments)};
|
||||
a._sqlite3_rekey=function(){return(a._sqlite3_rekey=a.asm.mf).apply(null,arguments)};a._sqlite3_regexp_init=function(){return(a._sqlite3_regexp_init=a.asm.nf).apply(null,arguments)};a._sqlite3mc_register_cipher=function(){return(a._sqlite3mc_register_cipher=a.asm.of).apply(null,arguments)};
|
||||
var kd=a.___errno_location=function(){return(kd=a.___errno_location=a.asm.pf).apply(null,arguments)},Rb=a._malloc=function(){return(Rb=a._malloc=a.asm.qf).apply(null,arguments)},$c=a._free=function(){return($c=a._free=a.asm.rf).apply(null,arguments)};a._RegisterExtensionFunctions=function(){return(a._RegisterExtensionFunctions=a.asm.sf).apply(null,arguments)};a._sqlite3Fts5BetterTrigramInit=function(){return(a._sqlite3Fts5BetterTrigramInit=a.asm.tf).apply(null,arguments)};
|
||||
a._sqlite3Fts5HtmlInit=function(){return(a._sqlite3Fts5HtmlInit=a.asm.uf).apply(null,arguments)};a._set_authorizer=function(){return(a._set_authorizer=a.asm.vf).apply(null,arguments)};a._create_function=function(){return(a._create_function=a.asm.wf).apply(null,arguments)};a._create_module=function(){return(a._create_module=a.asm.xf).apply(null,arguments)};a._progress_handler=function(){return(a._progress_handler=a.asm.yf).apply(null,arguments)};
|
||||
a._register_vfs=function(){return(a._register_vfs=a.asm.zf).apply(null,arguments)};a._getSqliteFree=function(){return(a._getSqliteFree=a.asm.Af).apply(null,arguments)};a._main=function(){return(a._main=a.asm.Bf).apply(null,arguments)};
|
||||
a._sqlite3_sourceid=function(){return(a._sqlite3_sourceid=a.asm.bf).apply(null,arguments)};var kd=a.___errno_location=function(){return(kd=a.___errno_location=a.asm.cf).apply(null,arguments)};a._sqlite3mc_config=function(){return(a._sqlite3mc_config=a.asm.df).apply(null,arguments)};a._sqlite3mc_cipher_count=function(){return(a._sqlite3mc_cipher_count=a.asm.ef).apply(null,arguments)};a._sqlite3mc_cipher_index=function(){return(a._sqlite3mc_cipher_index=a.asm.ff).apply(null,arguments)};
|
||||
a._sqlite3mc_cipher_name=function(){return(a._sqlite3mc_cipher_name=a.asm.gf).apply(null,arguments)};a._sqlite3mc_config_cipher=function(){return(a._sqlite3mc_config_cipher=a.asm.hf).apply(null,arguments)};a._sqlite3mc_codec_data=function(){return(a._sqlite3mc_codec_data=a.asm.jf).apply(null,arguments)};a._sqlite3_key=function(){return(a._sqlite3_key=a.asm.kf).apply(null,arguments)};a._sqlite3_key_v2=function(){return(a._sqlite3_key_v2=a.asm.lf).apply(null,arguments)};
|
||||
a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.mf).apply(null,arguments)};a._sqlite3_rekey=function(){return(a._sqlite3_rekey=a.asm.nf).apply(null,arguments)};a._sqlite3_regexp_init=function(){return(a._sqlite3_regexp_init=a.asm.of).apply(null,arguments)};a._sqlite3mc_register_cipher=function(){return(a._sqlite3mc_register_cipher=a.asm.pf).apply(null,arguments)};
|
||||
var Rb=a._malloc=function(){return(Rb=a._malloc=a.asm.qf).apply(null,arguments)},$c=a._free=function(){return($c=a._free=a.asm.rf).apply(null,arguments)};a._RegisterExtensionFunctions=function(){return(a._RegisterExtensionFunctions=a.asm.sf).apply(null,arguments)};a._sqlite3Fts5BetterTrigramInit=function(){return(a._sqlite3Fts5BetterTrigramInit=a.asm.tf).apply(null,arguments)};a._sqlite3Fts5HtmlInit=function(){return(a._sqlite3Fts5HtmlInit=a.asm.uf).apply(null,arguments)};
|
||||
a._set_authorizer=function(){return(a._set_authorizer=a.asm.vf).apply(null,arguments)};a._create_function=function(){return(a._create_function=a.asm.wf).apply(null,arguments)};a._create_module=function(){return(a._create_module=a.asm.xf).apply(null,arguments)};a._progress_handler=function(){return(a._progress_handler=a.asm.yf).apply(null,arguments)};a._register_vfs=function(){return(a._register_vfs=a.asm.zf).apply(null,arguments)};
|
||||
a._getSqliteFree=function(){return(a._getSqliteFree=a.asm.Af).apply(null,arguments)};a._main=function(){return(a._main=a.asm.Bf).apply(null,arguments)};
|
||||
var ab=a._emscripten_builtin_memalign=function(){return(ab=a._emscripten_builtin_memalign=a.asm.Cf).apply(null,arguments)},md=a.getTempRet0=function(){return(md=a.getTempRet0=a.asm.Ef).apply(null,arguments)},hd=a.stackSave=function(){return(hd=a.stackSave=a.asm.Ff).apply(null,arguments)},fd=a.stackRestore=function(){return(fd=a.stackRestore=a.asm.Gf).apply(null,arguments)},gd=a.stackAlloc=function(){return(gd=a.stackAlloc=a.asm.Hf).apply(null,arguments)},Yc=a._asyncify_start_unwind=function(){return(Yc=
|
||||
a._asyncify_start_unwind=a.asm.If).apply(null,arguments)},Mc=a._asyncify_stop_unwind=function(){return(Mc=a._asyncify_stop_unwind=a.asm.Jf).apply(null,arguments)},Wc=a._asyncify_start_rewind=function(){return(Wc=a._asyncify_start_rewind=a.asm.Kf).apply(null,arguments)},Zc=a._asyncify_stop_rewind=function(){return(Zc=a._asyncify_stop_rewind=a.asm.Lf).apply(null,arguments)};a._sqlite3_version=3232;a.UTF8ToString=x;a.stringToUTF8=qa;a.lengthBytesUTF8=ra;a.getTempRet0=md;a.ccall=Z;
|
||||
a.cwrap=function(b,c,d,e){d=d||[];var f=d.every(g=>"number"===g||"boolean"===g);return"string"!==c&&f&&!e?a["_"+b]:function(){return Z(b,c,d,arguments,e)}};
|
||||
|
||||
Binary file not shown.
@@ -137,9 +137,9 @@ a._sqlite3_table_column_metadata=function(){return(a._sqlite3_table_column_metad
|
||||
a._sqlite3_test_control=function(){return(a._sqlite3_test_control=a.asm.Oe).apply(null,arguments)};a._sqlite3_create_filename=function(){return(a._sqlite3_create_filename=a.asm.Pe).apply(null,arguments)};a._sqlite3_free_filename=function(){return(a._sqlite3_free_filename=a.asm.Qe).apply(null,arguments)};a._sqlite3_uri_parameter=function(){return(a._sqlite3_uri_parameter=a.asm.Re).apply(null,arguments)};a._sqlite3_uri_key=function(){return(a._sqlite3_uri_key=a.asm.Se).apply(null,arguments)};
|
||||
a._sqlite3_uri_boolean=function(){return(a._sqlite3_uri_boolean=a.asm.Te).apply(null,arguments)};a._sqlite3_uri_int64=function(){return(a._sqlite3_uri_int64=a.asm.Ue).apply(null,arguments)};a._sqlite3_filename_database=function(){return(a._sqlite3_filename_database=a.asm.Ve).apply(null,arguments)};a._sqlite3_filename_journal=function(){return(a._sqlite3_filename_journal=a.asm.We).apply(null,arguments)};a._sqlite3_filename_wal=function(){return(a._sqlite3_filename_wal=a.asm.Xe).apply(null,arguments)};
|
||||
a._sqlite3_db_name=function(){return(a._sqlite3_db_name=a.asm.Ye).apply(null,arguments)};a._sqlite3_db_filename=function(){return(a._sqlite3_db_filename=a.asm.Ze).apply(null,arguments)};a._sqlite3_db_readonly=function(){return(a._sqlite3_db_readonly=a.asm._e).apply(null,arguments)};a._sqlite3_compileoption_used=function(){return(a._sqlite3_compileoption_used=a.asm.$e).apply(null,arguments)};a._sqlite3_compileoption_get=function(){return(a._sqlite3_compileoption_get=a.asm.af).apply(null,arguments)};
|
||||
a._sqlite3_sourceid=function(){return(a._sqlite3_sourceid=a.asm.bf).apply(null,arguments)};a._sqlite3mc_config=function(){return(a._sqlite3mc_config=a.asm.cf).apply(null,arguments)};a._sqlite3mc_cipher_count=function(){return(a._sqlite3mc_cipher_count=a.asm.df).apply(null,arguments)};a._sqlite3mc_cipher_index=function(){return(a._sqlite3mc_cipher_index=a.asm.ef).apply(null,arguments)};a._sqlite3mc_cipher_name=function(){return(a._sqlite3mc_cipher_name=a.asm.ff).apply(null,arguments)};
|
||||
a._sqlite3mc_config_cipher=function(){return(a._sqlite3mc_config_cipher=a.asm.gf).apply(null,arguments)};a._sqlite3mc_codec_data=function(){return(a._sqlite3mc_codec_data=a.asm.hf).apply(null,arguments)};a._sqlite3_key=function(){return(a._sqlite3_key=a.asm.jf).apply(null,arguments)};a._sqlite3_key_v2=function(){return(a._sqlite3_key_v2=a.asm.kf).apply(null,arguments)};a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.lf).apply(null,arguments)};
|
||||
a._sqlite3_rekey=function(){return(a._sqlite3_rekey=a.asm.mf).apply(null,arguments)};a._sqlite3_regexp_init=function(){return(a._sqlite3_regexp_init=a.asm.nf).apply(null,arguments)};a._sqlite3mc_register_cipher=function(){return(a._sqlite3mc_register_cipher=a.asm.of).apply(null,arguments)};var Nc=a.___errno_location=function(){return(Nc=a.___errno_location=a.asm.pf).apply(null,arguments)},Pb=a._malloc=function(){return(Pb=a._malloc=a.asm.qf).apply(null,arguments)};
|
||||
a._sqlite3_sourceid=function(){return(a._sqlite3_sourceid=a.asm.bf).apply(null,arguments)};var Nc=a.___errno_location=function(){return(Nc=a.___errno_location=a.asm.cf).apply(null,arguments)};a._sqlite3mc_config=function(){return(a._sqlite3mc_config=a.asm.df).apply(null,arguments)};a._sqlite3mc_cipher_count=function(){return(a._sqlite3mc_cipher_count=a.asm.ef).apply(null,arguments)};a._sqlite3mc_cipher_index=function(){return(a._sqlite3mc_cipher_index=a.asm.ff).apply(null,arguments)};
|
||||
a._sqlite3mc_cipher_name=function(){return(a._sqlite3mc_cipher_name=a.asm.gf).apply(null,arguments)};a._sqlite3mc_config_cipher=function(){return(a._sqlite3mc_config_cipher=a.asm.hf).apply(null,arguments)};a._sqlite3mc_codec_data=function(){return(a._sqlite3mc_codec_data=a.asm.jf).apply(null,arguments)};a._sqlite3_key=function(){return(a._sqlite3_key=a.asm.kf).apply(null,arguments)};a._sqlite3_key_v2=function(){return(a._sqlite3_key_v2=a.asm.lf).apply(null,arguments)};
|
||||
a._sqlite3_rekey_v2=function(){return(a._sqlite3_rekey_v2=a.asm.mf).apply(null,arguments)};a._sqlite3_rekey=function(){return(a._sqlite3_rekey=a.asm.nf).apply(null,arguments)};a._sqlite3_regexp_init=function(){return(a._sqlite3_regexp_init=a.asm.of).apply(null,arguments)};a._sqlite3mc_register_cipher=function(){return(a._sqlite3mc_register_cipher=a.asm.pf).apply(null,arguments)};var Pb=a._malloc=function(){return(Pb=a._malloc=a.asm.qf).apply(null,arguments)};
|
||||
a._free=function(){return(a._free=a.asm.rf).apply(null,arguments)};a._RegisterExtensionFunctions=function(){return(a._RegisterExtensionFunctions=a.asm.sf).apply(null,arguments)};a._sqlite3Fts5BetterTrigramInit=function(){return(a._sqlite3Fts5BetterTrigramInit=a.asm.tf).apply(null,arguments)};a._sqlite3Fts5HtmlInit=function(){return(a._sqlite3Fts5HtmlInit=a.asm.uf).apply(null,arguments)};a._set_authorizer=function(){return(a._set_authorizer=a.asm.vf).apply(null,arguments)};
|
||||
a._create_function=function(){return(a._create_function=a.asm.wf).apply(null,arguments)};a._create_module=function(){return(a._create_module=a.asm.xf).apply(null,arguments)};a._progress_handler=function(){return(a._progress_handler=a.asm.yf).apply(null,arguments)};a._register_vfs=function(){return(a._register_vfs=a.asm.zf).apply(null,arguments)};a._getSqliteFree=function(){return(a._getSqliteFree=a.asm.Af).apply(null,arguments)};a._main=function(){return(a._main=a.asm.Bf).apply(null,arguments)};
|
||||
var Za=a._emscripten_builtin_memalign=function(){return(Za=a._emscripten_builtin_memalign=a.asm.Cf).apply(null,arguments)},Pc=a.getTempRet0=function(){return(Pc=a.getTempRet0=a.asm.Ef).apply(null,arguments)},Kc=a.stackSave=function(){return(Kc=a.stackSave=a.asm.Ff).apply(null,arguments)},Lc=a.stackRestore=function(){return(Lc=a.stackRestore=a.asm.Gf).apply(null,arguments)},Jc=a.stackAlloc=function(){return(Jc=a.stackAlloc=a.asm.Hf).apply(null,arguments)};a._sqlite3_version=3232;a.UTF8ToString=v;
|
||||
|
||||
Binary file not shown.
@@ -19,17 +19,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ListItem from "../list-item";
|
||||
import { Restore, DeleteForver } from "../icons";
|
||||
import { store } from "../../stores/trash-store";
|
||||
import { Flex, Text } from "@theme-ui/components";
|
||||
import TimeAgo from "../time-ago";
|
||||
import { pluralize, toTitleCase } from "@notesnook/common";
|
||||
import { showToast } from "../../utils/toast";
|
||||
import { toTitleCase } from "@notesnook/common";
|
||||
import { MenuItem } from "@notesnook/ui";
|
||||
import { TrashItem as TrashItemType } from "@notesnook/core";
|
||||
import { useEditorStore } from "../../stores/editor-store";
|
||||
import { showMultiPermanentDeleteConfirmation } from "../../dialogs/confirm";
|
||||
import { useStore as useSelectionStore } from "../../stores/selection-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { Multiselect } from "../../common/multi-select";
|
||||
|
||||
type TrashItemProps = { item: TrashItemType; date: number };
|
||||
function TrashItem(props: TrashItemProps) {
|
||||
@@ -44,7 +42,9 @@ function TrashItem(props: TrashItemProps) {
|
||||
body={item.itemType === "note" ? item.headline : item.description}
|
||||
onKeyPress={async (e) => {
|
||||
if (e.key === "Delete") {
|
||||
await deleteTrash(useSelectionStore.getState().selectedItems);
|
||||
await Multiselect.deleteItemsFromTrash(
|
||||
useSelectionStore.getState().selectedItems
|
||||
);
|
||||
}
|
||||
}}
|
||||
footer={
|
||||
@@ -81,9 +81,7 @@ export const trashMenuItems: (
|
||||
key: "restore",
|
||||
title: strings.restore(),
|
||||
icon: Restore.path,
|
||||
onClick: async () => {
|
||||
await store.restore(...ids);
|
||||
},
|
||||
onClick: () => Multiselect.restoreItemsFromTrash(ids),
|
||||
multiSelect: true
|
||||
},
|
||||
{
|
||||
@@ -92,16 +90,8 @@ export const trashMenuItems: (
|
||||
title: strings.delete(),
|
||||
icon: DeleteForver.path,
|
||||
variant: "dangerous",
|
||||
onClick: async () => {
|
||||
await deleteTrash(ids);
|
||||
},
|
||||
onClick: () => Multiselect.deleteItemsFromTrash(ids),
|
||||
multiSelect: true
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
export async function deleteTrash(ids: string[]) {
|
||||
if (!(await showMultiPermanentDeleteConfirmation(ids.length))) return;
|
||||
await store.delete(...ids);
|
||||
showToast("success", `${pluralize(ids.length, "item")} permanently deleted`);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- You can now share multiple files to Notesnook
|
||||
- Fix file and image sharing not working
|
||||
- Many other bug fixes and small improvements
|
||||
- New and improved search with highlighting
|
||||
- Fixed app crashing on android 16 devices
|
||||
- Many bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
5
fastlane/metadata/android/en-US/changelogs/15294.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/15294.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
- New and improved search with highlighting
|
||||
- Fixed app crashing on android 16 devices
|
||||
- Many bug fixes and improvements
|
||||
|
||||
Thank you for using Notesnook!
|
||||
@@ -48,11 +48,12 @@ export async function resolveItems(ids: string[], items: Item[]) {
|
||||
const { type } = items[0];
|
||||
if (type === "note") return resolveNotes(ids);
|
||||
else if (type === "notebook") {
|
||||
return Promise.all(ids.map((id) => db.notebooks.totalNotes(id)));
|
||||
return await db.notebooks.totalNotes(...ids);
|
||||
} else if (type === "tag") {
|
||||
return Promise.all(
|
||||
ids.map((id) => db.relations.from({ id, type: "tag" }, "note").count())
|
||||
);
|
||||
const relations = await db.relations
|
||||
.from({ type: "tag", ids }, "note")
|
||||
.get();
|
||||
return ids.map((id) => relations.filter((r) => r.fromId === id).length);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ test("delete note", () =>
|
||||
await db.notes.moveToTrash(id);
|
||||
|
||||
expect(await db.notes.note(id)).toBeUndefined();
|
||||
expect(await db.notebooks.totalNotes(notebookId)).toBe(0);
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toBe(0);
|
||||
expect(await db.notebooks.totalNotes(notebookId)).toStrictEqual([0]);
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toStrictEqual([0]);
|
||||
}));
|
||||
|
||||
test("get all notes", () =>
|
||||
@@ -323,8 +323,8 @@ test("add note to subnotebook", () =>
|
||||
.from({ type: "notebook", id: notebookId }, "notebook")
|
||||
.count()
|
||||
).toBe(1);
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toBe(1);
|
||||
expect(await db.notebooks.totalNotes(notebookId)).toBe(1);
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toStrictEqual([1]);
|
||||
expect(await db.notebooks.totalNotes(notebookId)).toStrictEqual([1]);
|
||||
}));
|
||||
|
||||
test("duplicate note to topic should not be added", () =>
|
||||
@@ -333,7 +333,7 @@ test("duplicate note to topic should not be added", () =>
|
||||
notebookTitle: "Hello",
|
||||
subNotebookTitle: "Home"
|
||||
});
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toBe(1);
|
||||
expect(await db.notebooks.totalNotes(subNotebookId)).toStrictEqual([1]);
|
||||
}));
|
||||
|
||||
test("add the same note to 2 notebooks", () =>
|
||||
|
||||
@@ -22,8 +22,8 @@ import Database from "../api/index.js";
|
||||
import { Notebook, TrashOrItem, isTrashItem } from "../types.js";
|
||||
import { ICollection } from "./collection.js";
|
||||
import { SQLCollection } from "../database/sql-collection.js";
|
||||
import { isFalse } from "../database/index.js";
|
||||
import { sql } from "@streetwriters/kysely";
|
||||
import { DatabaseSchema, isFalse } from "../database/index.js";
|
||||
import { Kysely, sql, Transaction } from "@streetwriters/kysely";
|
||||
import { deleteItems } from "../utils/array.js";
|
||||
import {
|
||||
CHECK_IDS,
|
||||
@@ -125,65 +125,45 @@ export class Notebooks implements ICollection {
|
||||
await this.collection.update(ids, { pinned: state });
|
||||
}
|
||||
|
||||
async totalNotes(id: string) {
|
||||
const result = await this.db
|
||||
.sql()
|
||||
.withRecursive(`subNotebooks(id)`, (eb) =>
|
||||
eb
|
||||
.selectNoFrom((eb) => eb.val(id).as("id"))
|
||||
.unionAll((eb) =>
|
||||
eb
|
||||
.selectFrom(["relations", "subNotebooks"])
|
||||
.select("relations.toId as id")
|
||||
.where("toType", "==", "notebook")
|
||||
.where("fromType", "==", "notebook")
|
||||
.whereRef("fromId", "==", "subNotebooks.id")
|
||||
.where("toId", "not in", this.db.trash.cache.notebooks)
|
||||
.$narrowType<{ id: string }>()
|
||||
)
|
||||
)
|
||||
async totalNotes(...ids: string[]) {
|
||||
const result = await withSubNotebooks(
|
||||
this.db.sql(),
|
||||
ids,
|
||||
this.db.trash.cache.notebooks
|
||||
)
|
||||
.selectFrom("relations")
|
||||
.innerJoin("subNotebooks", "subNotebooks.id", "relations.fromId")
|
||||
.where("toType", "==", "note")
|
||||
.where("fromType", "==", "notebook")
|
||||
.where("fromId", "in", (eb) =>
|
||||
eb.selectFrom("subNotebooks").select("subNotebooks.id")
|
||||
)
|
||||
.where("toId", "not in", this.db.trash.cache.notes)
|
||||
.select((eb) => eb.fn.count<number>("relations.toId").as("totalNotes"))
|
||||
.executeTakeFirst();
|
||||
|
||||
if (!result) return 0;
|
||||
return result.totalNotes;
|
||||
}
|
||||
|
||||
async notes(id: string) {
|
||||
const result = await this.db
|
||||
.sql()
|
||||
.withRecursive(`subNotebooks(id)`, (eb) =>
|
||||
eb
|
||||
.selectNoFrom((eb) => eb.val(id).as("id"))
|
||||
.unionAll((eb) =>
|
||||
eb
|
||||
.selectFrom(["relations", "subNotebooks"])
|
||||
.select("relations.toId as id")
|
||||
.where("toType", "==", "notebook")
|
||||
.where("fromType", "==", "notebook")
|
||||
.whereRef("fromId", "==", "subNotebooks.id")
|
||||
.where("toId", "not in", this.db.trash.cache.notebooks)
|
||||
.$narrowType<{ id: string }>()
|
||||
)
|
||||
)
|
||||
.selectFrom("relations")
|
||||
.where("toType", "==", "note")
|
||||
.where("fromType", "==", "notebook")
|
||||
.where("fromId", "in", (eb) =>
|
||||
eb.selectFrom("subNotebooks").select("subNotebooks.id")
|
||||
)
|
||||
.where("toId", "not in", this.db.trash.cache.notes)
|
||||
.select("relations.toId as id")
|
||||
.$narrowType<{ id: string }>()
|
||||
.select((eb) => [
|
||||
"subNotebooks.rootId as id",
|
||||
eb.fn.count<number>("relations.toId").distinct().as("totalNotes")
|
||||
])
|
||||
.groupBy("subNotebooks.rootId")
|
||||
.execute();
|
||||
|
||||
return ids.map((id) => {
|
||||
const item = result.find((i) => i.id === id);
|
||||
return item ? item.totalNotes : 0;
|
||||
});
|
||||
}
|
||||
|
||||
async notes(...ids: string[]) {
|
||||
const result = await withSubNotebooks(
|
||||
this.db.sql(),
|
||||
ids,
|
||||
this.db.trash.cache.notebooks
|
||||
)
|
||||
.selectFrom("relations")
|
||||
.innerJoin("subNotebooks", "subNotebooks.id", "relations.fromId")
|
||||
.where("toType", "==", "note")
|
||||
.where("fromType", "==", "notebook")
|
||||
.where("toId", "not in", this.db.trash.cache.notes)
|
||||
.select("relations.toId as id")
|
||||
.distinct()
|
||||
.$narrowType<{ id: string }>()
|
||||
.execute();
|
||||
return result.map((i) => i.id);
|
||||
}
|
||||
|
||||
@@ -254,26 +234,7 @@ export class Notebooks implements ICollection {
|
||||
|
||||
async moveToTrash(...ids: string[]) {
|
||||
await this.db.transaction(async (tr) => {
|
||||
const query = tr
|
||||
.withRecursive(`subNotebooks(id)`, (eb) =>
|
||||
eb
|
||||
.selectFrom(() =>
|
||||
sql<{ id: string }>`(VALUES ${sql.join(
|
||||
ids.map((id) => sql.raw(`('${id}')`))
|
||||
)})`.as("roots")
|
||||
)
|
||||
.selectAll()
|
||||
.unionAll((eb) =>
|
||||
eb
|
||||
.selectFrom(["relations", "subNotebooks"])
|
||||
.select("relations.toId as id")
|
||||
.where("toType", "==", "notebook")
|
||||
.where("fromType", "==", "notebook")
|
||||
.whereRef("fromId", "==", "subNotebooks.id")
|
||||
.where("toId", "not in", this.db.trash.cache.notebooks)
|
||||
.$narrowType<{ id: string }>()
|
||||
)
|
||||
)
|
||||
const query = withSubNotebooks(tr, ids, this.db.trash.cache.notebooks)
|
||||
.selectFrom("subNotebooks")
|
||||
.select("id");
|
||||
|
||||
@@ -305,3 +266,45 @@ export class Notebooks implements ICollection {
|
||||
return relation[0]?.fromId;
|
||||
}
|
||||
}
|
||||
|
||||
export function withSubNotebooks(
|
||||
db: Kysely<DatabaseSchema> | Transaction<DatabaseSchema>,
|
||||
ids: string[],
|
||||
excluded: string[]
|
||||
) {
|
||||
return db.withRecursive(`subNotebooks(id, path, rootId)`, (eb) =>
|
||||
eb
|
||||
.selectFrom(() =>
|
||||
sql<{
|
||||
id: string;
|
||||
path: string;
|
||||
rootId: string;
|
||||
}>`(VALUES ${sql.join(
|
||||
ids.map((id) => sql.raw(`('${id}', '${id}', '${id}')`))
|
||||
)})`.as("roots")
|
||||
)
|
||||
.selectAll()
|
||||
.unionAll((eb) =>
|
||||
eb
|
||||
.selectFrom(["relations", "subNotebooks"])
|
||||
.select([
|
||||
"relations.toId as id",
|
||||
// Concatenate parent path with current id
|
||||
sql<string>`subNotebooks.path || '/' || relations.toId`.as("path"),
|
||||
// Preserve original root
|
||||
"subNotebooks.rootId as rootId"
|
||||
])
|
||||
.where("toType", "==", "notebook")
|
||||
.where("fromType", "==", "notebook")
|
||||
.whereRef("fromId", "==", "subNotebooks.id")
|
||||
.where("toId", "not in", excluded)
|
||||
// Use path to prevent cycles
|
||||
.where(
|
||||
"subNotebooks.path",
|
||||
"not like",
|
||||
sql`'%' || relations.toId || '%'`
|
||||
)
|
||||
.$narrowType<{ id: string; path: string; rootId: string }>()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
checkIsUserPremium,
|
||||
FREE_NOTEBOOKS_LIMIT
|
||||
} from "../common.js";
|
||||
import { withSubNotebooks } from "./notebooks.js";
|
||||
|
||||
export default class Trash {
|
||||
collections = ["notes", "notebooks"] as const;
|
||||
@@ -324,27 +325,11 @@ export default class Trash {
|
||||
}
|
||||
|
||||
private async subNotebooks(notebookIds: string[]) {
|
||||
const ids = await this.db
|
||||
.sql()
|
||||
.withRecursive(`subNotebooks(id)`, (eb) =>
|
||||
eb
|
||||
.selectFrom((eb) =>
|
||||
sql<{ id: string }>`(VALUES ${sql.join(
|
||||
notebookIds.map((id) => eb.parens(sql`${id}`))
|
||||
)})`.as("notebookIds")
|
||||
)
|
||||
.selectAll()
|
||||
.unionAll((eb) =>
|
||||
eb
|
||||
.selectFrom(["relations", "subNotebooks"])
|
||||
.select("relations.toId as id")
|
||||
.where("toType", "==", "notebook")
|
||||
.where("fromType", "==", "notebook")
|
||||
.whereRef("fromId", "==", "subNotebooks.id")
|
||||
.where("toId", "not in", this.userDeletedCache.notebooks)
|
||||
.$narrowType<{ id: string }>()
|
||||
)
|
||||
)
|
||||
const ids = await withSubNotebooks(
|
||||
this.db.sql(),
|
||||
notebookIds,
|
||||
this.userDeletedCache.notebooks
|
||||
)
|
||||
.selectFrom("subNotebooks")
|
||||
.select("id")
|
||||
.where("id", "not in", notebookIds)
|
||||
|
||||
@@ -44,10 +44,12 @@ export default function TiptapEditorWrapper(props: {
|
||||
display: props.settings.noToolbar ? "none" : "flex",
|
||||
overflowY: "hidden",
|
||||
minHeight: "50px",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
...(globalThis.__PLATFORM__ === "ios" && {
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
})
|
||||
}}
|
||||
editor={editor}
|
||||
location="bottom"
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-06-05 11:43+0500\n"
|
||||
"POT-Creation-Date: 2025-06-21 11:05+0500\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: en\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/strings.ts:2410
|
||||
msgid " \"Notebook > Notes\""
|
||||
@@ -157,7 +151,7 @@ msgstr "{count, plural, one {Attachment deleted} other {# attachments deleted}}"
|
||||
msgid "{count, plural, one {Attachment downloaded at {path}} other {#/{total} attachments downloaded as a zip file at {path}}}"
|
||||
msgstr "{count, plural, one {Attachment downloaded at {path}} other {#/{total} attachments downloaded as a zip file at {path}}}"
|
||||
|
||||
#: generated/actions.ts:210
|
||||
#: generated/actions.ts:216
|
||||
msgid "{count, plural, one {Color renamed} other {# colors renamed}}"
|
||||
msgstr "{count, plural, one {Color renamed} other {# colors renamed}}"
|
||||
|
||||
@@ -250,7 +244,7 @@ msgstr "{count, plural, one {Item could not be published} other {# items could n
|
||||
msgid "{count, plural, one {Item could not be unpublished} other {# items could not be unpublished}}"
|
||||
msgstr "{count, plural, one {Item could not be unpublished} other {# items could not be unpublished}}"
|
||||
|
||||
#: generated/actions.ts:202
|
||||
#: generated/actions.ts:208
|
||||
msgid "{count, plural, one {Item created} other {# items created}}"
|
||||
msgstr "{count, plural, one {Item created} other {# items created}}"
|
||||
|
||||
@@ -258,7 +252,7 @@ msgstr "{count, plural, one {Item created} other {# items created}}"
|
||||
msgid "{count, plural, one {Item deleted} other {# items deleted}}"
|
||||
msgstr "{count, plural, one {Item deleted} other {# items deleted}}"
|
||||
|
||||
#: generated/actions.ts:173
|
||||
#: generated/actions.ts:179
|
||||
msgid "{count, plural, one {Item edited} other {# items edited}}"
|
||||
msgstr "{count, plural, one {Item edited} other {# items edited}}"
|
||||
|
||||
@@ -266,24 +260,25 @@ msgstr "{count, plural, one {Item edited} other {# items edited}}"
|
||||
msgid "{count, plural, one {Item moved to trash} other {# items moved to trash}}"
|
||||
msgstr "{count, plural, one {Item moved to trash} other {# items moved to trash}}"
|
||||
|
||||
#: generated/actions.ts:87
|
||||
#: generated/actions.ts:80
|
||||
#: generated/actions.ts:93
|
||||
msgid "{count, plural, one {Item permanently deleted} other {# items permanently deleted}}"
|
||||
msgstr "{count, plural, one {Item permanently deleted} other {# items permanently deleted}}"
|
||||
|
||||
#: generated/actions.ts:104
|
||||
#: generated/actions.ts:110
|
||||
msgid "{count, plural, one {Item published} other {# items published}}"
|
||||
msgstr "{count, plural, one {Item published} other {# items published}}"
|
||||
|
||||
#: generated/actions.ts:219
|
||||
#: generated/actions.ts:225
|
||||
msgid "{count, plural, one {Item renamed} other {# items renamed}}"
|
||||
msgstr "{count, plural, one {Item renamed} other {# items renamed}}"
|
||||
|
||||
#: generated/actions.ts:137
|
||||
#: generated/actions.ts:150
|
||||
#: generated/actions.ts:143
|
||||
#: generated/actions.ts:156
|
||||
msgid "{count, plural, one {Item restored} other {# items restored}}"
|
||||
msgstr "{count, plural, one {Item restored} other {# items restored}}"
|
||||
|
||||
#: generated/actions.ts:121
|
||||
#: generated/actions.ts:127
|
||||
msgid "{count, plural, one {Item unpublished} other {# items unpublished}}"
|
||||
msgstr "{count, plural, one {Item unpublished} other {# items unpublished}}"
|
||||
|
||||
@@ -323,15 +318,15 @@ msgstr "{count, plural, one {Note moved to trash} other {# notes moved to trash}
|
||||
msgid "{count, plural, one {Note permanently deleted} other {# notes permanently deleted}}"
|
||||
msgstr "{count, plural, one {Note permanently deleted} other {# notes permanently deleted}}"
|
||||
|
||||
#: generated/actions.ts:95
|
||||
#: generated/actions.ts:101
|
||||
msgid "{count, plural, one {Note published} other {# notes published}}"
|
||||
msgstr "{count, plural, one {Note published} other {# notes published}}"
|
||||
|
||||
#: generated/actions.ts:129
|
||||
#: generated/actions.ts:135
|
||||
msgid "{count, plural, one {Note restored} other {# notes restored}}"
|
||||
msgstr "{count, plural, one {Note restored} other {# notes restored}}"
|
||||
|
||||
#: generated/actions.ts:112
|
||||
#: generated/actions.ts:118
|
||||
msgid "{count, plural, one {Note unpublished} other {# notes unpublished}}"
|
||||
msgstr "{count, plural, one {Note unpublished} other {# notes unpublished}}"
|
||||
|
||||
@@ -339,7 +334,7 @@ msgstr "{count, plural, one {Note unpublished} other {# notes unpublished}}"
|
||||
msgid "{count, plural, one {Note will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?} other {# notes will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?}}"
|
||||
msgstr "{count, plural, one {Note will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?} other {# notes will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?}}"
|
||||
|
||||
#: generated/actions.ts:181
|
||||
#: generated/actions.ts:187
|
||||
msgid "{count, plural, one {Notebook created} other {# notebooks created}}"
|
||||
msgstr "{count, plural, one {Notebook created} other {# notebooks created}}"
|
||||
|
||||
@@ -347,7 +342,7 @@ msgstr "{count, plural, one {Notebook created} other {# notebooks created}}"
|
||||
msgid "{count, plural, one {Notebook deleted} other {# notebooks deleted}}"
|
||||
msgstr "{count, plural, one {Notebook deleted} other {# notebooks deleted}}"
|
||||
|
||||
#: generated/actions.ts:162
|
||||
#: generated/actions.ts:168
|
||||
msgid "{count, plural, one {Notebook edited} other {# notebooks edited}}"
|
||||
msgstr "{count, plural, one {Notebook edited} other {# notebooks edited}}"
|
||||
|
||||
@@ -359,7 +354,7 @@ msgstr "{count, plural, one {Notebook moved to trash} other {# notebooks moved t
|
||||
msgid "{count, plural, one {Notebook permanently deleted} other {# notebooks permanently deleted}}"
|
||||
msgstr "{count, plural, one {Notebook permanently deleted} other {# notebooks permanently deleted}}"
|
||||
|
||||
#: generated/actions.ts:133
|
||||
#: generated/actions.ts:139
|
||||
msgid "{count, plural, one {Notebook restored} other {# notebooks restored}}"
|
||||
msgstr "{count, plural, one {Notebook restored} other {# notebooks restored}}"
|
||||
|
||||
@@ -372,6 +367,11 @@ msgstr "{count, plural, one {Permanently delete attachment} other {Permanently d
|
||||
msgid "{count, plural, one {Permanently delete item} other {Permanently delete # items}}"
|
||||
msgstr "{count, plural, one {Permanently delete item} other {Permanently delete # items}}"
|
||||
|
||||
#: generated/in-progress-actions.ts:66
|
||||
#: generated/in-progress-actions.ts:75
|
||||
msgid "{count, plural, one {permanently deleting item...} other {permanently deleting # items...}}"
|
||||
msgstr "{count, plural, one {permanently deleting item...} other {permanently deleting # items...}}"
|
||||
|
||||
#: generated/do-actions.ts:99
|
||||
msgid "{count, plural, one {Pin item} other {Pin # items}}"
|
||||
msgstr "{count, plural, one {Pin item} other {Pin # items}}"
|
||||
@@ -444,11 +444,16 @@ msgstr "{count, plural, one {Restore note} other {Restore # notes}}"
|
||||
msgid "{count, plural, one {Restore notebook} other {Restore # notebooks}}"
|
||||
msgstr "{count, plural, one {Restore notebook} other {Restore # notebooks}}"
|
||||
|
||||
#: generated/actions.ts:189
|
||||
#: generated/in-progress-actions.ts:49
|
||||
#: generated/in-progress-actions.ts:58
|
||||
msgid "{count, plural, one {Restoring item...} other {Restoring # items...}}"
|
||||
msgstr "{count, plural, one {Restoring item...} other {Restoring # items...}}"
|
||||
|
||||
#: generated/actions.ts:195
|
||||
msgid "{count, plural, one {Shortcut created} other {# shortcuts created}}"
|
||||
msgstr "{count, plural, one {Shortcut created} other {# shortcuts created}}"
|
||||
|
||||
#: generated/actions.ts:185
|
||||
#: generated/actions.ts:191
|
||||
msgid "{count, plural, one {Tag created} other {# tags created}}"
|
||||
msgstr "{count, plural, one {Tag created} other {# tags created}}"
|
||||
|
||||
@@ -456,7 +461,7 @@ msgstr "{count, plural, one {Tag created} other {# tags created}}"
|
||||
msgid "{count, plural, one {Tag deleted} other {# tags deleted}}"
|
||||
msgstr "{count, plural, one {Tag deleted} other {# tags deleted}}"
|
||||
|
||||
#: generated/actions.ts:158
|
||||
#: generated/actions.ts:164
|
||||
msgid "{count, plural, one {Tag edited} other {# tags edited}}"
|
||||
msgstr "{count, plural, one {Tag edited} other {# tags edited}}"
|
||||
|
||||
@@ -613,8 +618,8 @@ msgid "A to Z"
|
||||
msgstr "A to Z"
|
||||
|
||||
#: src/strings.ts:447
|
||||
msgid "A vault stores your notes in a encrypted storage."
|
||||
msgstr "A vault stores your notes in a encrypted storage."
|
||||
msgid "A vault stores your notes in an encrypted storage."
|
||||
msgstr "A vault stores your notes in an encrypted storage."
|
||||
|
||||
#: src/strings.ts:661
|
||||
msgid "Abc"
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-06-05 11:43+0500\n"
|
||||
"POT-Creation-Date: 2025-06-21 11:05+0500\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: pseudo-LOCALE\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/strings.ts:2410
|
||||
msgid " \"Notebook > Notes\""
|
||||
@@ -157,7 +151,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Attachment downloaded at {path}} other {#/{total} attachments downloaded as a zip file at {path}}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:210
|
||||
#: generated/actions.ts:216
|
||||
msgid "{count, plural, one {Color renamed} other {# colors renamed}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -250,7 +244,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Item could not be unpublished} other {# items could not be unpublished}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:202
|
||||
#: generated/actions.ts:208
|
||||
msgid "{count, plural, one {Item created} other {# items created}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -258,7 +252,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Item deleted} other {# items deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:173
|
||||
#: generated/actions.ts:179
|
||||
msgid "{count, plural, one {Item edited} other {# items edited}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -266,24 +260,25 @@ msgstr ""
|
||||
msgid "{count, plural, one {Item moved to trash} other {# items moved to trash}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:87
|
||||
#: generated/actions.ts:80
|
||||
#: generated/actions.ts:93
|
||||
msgid "{count, plural, one {Item permanently deleted} other {# items permanently deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:104
|
||||
#: generated/actions.ts:110
|
||||
msgid "{count, plural, one {Item published} other {# items published}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:219
|
||||
#: generated/actions.ts:225
|
||||
msgid "{count, plural, one {Item renamed} other {# items renamed}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:137
|
||||
#: generated/actions.ts:150
|
||||
#: generated/actions.ts:143
|
||||
#: generated/actions.ts:156
|
||||
msgid "{count, plural, one {Item restored} other {# items restored}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:121
|
||||
#: generated/actions.ts:127
|
||||
msgid "{count, plural, one {Item unpublished} other {# items unpublished}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -323,15 +318,15 @@ msgstr ""
|
||||
msgid "{count, plural, one {Note permanently deleted} other {# notes permanently deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:95
|
||||
#: generated/actions.ts:101
|
||||
msgid "{count, plural, one {Note published} other {# notes published}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:129
|
||||
#: generated/actions.ts:135
|
||||
msgid "{count, plural, one {Note restored} other {# notes restored}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:112
|
||||
#: generated/actions.ts:118
|
||||
msgid "{count, plural, one {Note unpublished} other {# notes unpublished}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -339,7 +334,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Note will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?} other {# notes will be automatically deleted from all other devices & any future changes won't get synced. Are you sure you want to continue?}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:181
|
||||
#: generated/actions.ts:187
|
||||
msgid "{count, plural, one {Notebook created} other {# notebooks created}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -347,7 +342,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Notebook deleted} other {# notebooks deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:162
|
||||
#: generated/actions.ts:168
|
||||
msgid "{count, plural, one {Notebook edited} other {# notebooks edited}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -359,7 +354,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Notebook permanently deleted} other {# notebooks permanently deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:133
|
||||
#: generated/actions.ts:139
|
||||
msgid "{count, plural, one {Notebook restored} other {# notebooks restored}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -372,6 +367,11 @@ msgstr ""
|
||||
msgid "{count, plural, one {Permanently delete item} other {Permanently delete # items}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/in-progress-actions.ts:66
|
||||
#: generated/in-progress-actions.ts:75
|
||||
msgid "{count, plural, one {permanently deleting item...} other {permanently deleting # items...}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/do-actions.ts:99
|
||||
msgid "{count, plural, one {Pin item} other {Pin # items}}"
|
||||
msgstr ""
|
||||
@@ -444,11 +444,16 @@ msgstr ""
|
||||
msgid "{count, plural, one {Restore notebook} other {Restore # notebooks}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:189
|
||||
#: generated/in-progress-actions.ts:49
|
||||
#: generated/in-progress-actions.ts:58
|
||||
msgid "{count, plural, one {Restoring item...} other {Restoring # items...}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:195
|
||||
msgid "{count, plural, one {Shortcut created} other {# shortcuts created}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:185
|
||||
#: generated/actions.ts:191
|
||||
msgid "{count, plural, one {Tag created} other {# tags created}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -456,7 +461,7 @@ msgstr ""
|
||||
msgid "{count, plural, one {Tag deleted} other {# tags deleted}}"
|
||||
msgstr ""
|
||||
|
||||
#: generated/actions.ts:158
|
||||
#: generated/actions.ts:164
|
||||
msgid "{count, plural, one {Tag edited} other {# tags edited}}"
|
||||
msgstr ""
|
||||
|
||||
@@ -613,7 +618,7 @@ msgid "A to Z"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:447
|
||||
msgid "A vault stores your notes in a encrypted storage."
|
||||
msgid "A vault stores your notes in an encrypted storage."
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:661
|
||||
|
||||
@@ -83,7 +83,7 @@ const ACTIONS = [
|
||||
{
|
||||
action: "permanentlyDeleted",
|
||||
label: "permanently deleted",
|
||||
dataTypes: ["note", "notebook"]
|
||||
dataTypes: ["note", "notebook", "item"]
|
||||
},
|
||||
{ action: "published", label: "published", dataTypes: ["note"] },
|
||||
{ action: "unpublished", label: "unpublished", dataTypes: ["note"] },
|
||||
@@ -121,7 +121,7 @@ const ACTION_CONFIRMATIONS = [
|
||||
"tag",
|
||||
"color",
|
||||
"attachment"
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
action: "permanentlyDelete",
|
||||
@@ -148,6 +148,16 @@ const IN_PROGRESS_ACTIONS = [
|
||||
action: "deleting",
|
||||
label: "Deleting",
|
||||
dataTypes: ["note", "notebook", "attachment", "tag", "reminder"]
|
||||
},
|
||||
{
|
||||
action: "restoring",
|
||||
label: "Restoring",
|
||||
dataTypes: ["item"]
|
||||
},
|
||||
{
|
||||
action: "permanentlyDeleting",
|
||||
label: "permanently deleting",
|
||||
dataTypes: ["item"]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user