mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-07-09 20:09:36 +02:00
Merge branch 'master' into beta
This commit is contained in:
@@ -66,12 +66,17 @@ import {
|
||||
VAULT_ERRORS
|
||||
} from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { useUserStore } from "../../../stores/use-user-store";
|
||||
import { AppFontSize } from "../../../utils/size";
|
||||
import { Pressable } from "../../ui/pressable";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
|
||||
export const VaultDialog: React.FC = () => {
|
||||
const { colors } = useThemeColors();
|
||||
|
||||
// UI State
|
||||
const [visible, setVisible] = useState(false);
|
||||
const isUserLoggedIn = useUserStore((state) => !!state.user);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [deleteAll, setDeleteAll] = useState(false);
|
||||
const [biometricUnlock, setBiometricUnlock] = useState(false);
|
||||
@@ -196,9 +201,12 @@ export const VaultDialog: React.FC = () => {
|
||||
}
|
||||
eSendEvent("vaultUpdated");
|
||||
setLoading(false);
|
||||
setTimeout(() => {
|
||||
close();
|
||||
}, 100);
|
||||
close();
|
||||
ToastManager.show({
|
||||
message: strings.vaultDeleted(),
|
||||
type: "success",
|
||||
context: "global"
|
||||
});
|
||||
} else {
|
||||
setLoading(false);
|
||||
formRef.current.setError("password", strings.passwordIncorrect());
|
||||
@@ -489,6 +497,13 @@ export const VaultDialog: React.FC = () => {
|
||||
|
||||
const { password, newPassword } = formRef.current.getValues();
|
||||
|
||||
if (requestType === VaultRequestType.DeleteVault && !isUserLoggedIn) {
|
||||
setLoading(true);
|
||||
await deleteVault();
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestType === VaultRequestType.CreateVault) {
|
||||
createVault();
|
||||
} else if (requestType === VaultRequestType.ChangePassword) {
|
||||
@@ -629,16 +644,22 @@ export const VaultDialog: React.FC = () => {
|
||||
// Auto-unlock with fingerprint if applicable
|
||||
const canAutoUnlock =
|
||||
fingerprint &&
|
||||
available &&
|
||||
data.requestType !== VaultRequestType.EnableFingerprint &&
|
||||
data.requestType !== VaultRequestType.RevokeFingerprint &&
|
||||
data.requestType !== VaultRequestType.ChangePassword &&
|
||||
data.requestType !== VaultRequestType.ClearVault &&
|
||||
data.requestType !== VaultRequestType.DeleteVault &&
|
||||
data.requestType !== VaultRequestType.CustomAction &&
|
||||
data.requestType !== VaultRequestType.PermanentUnlock;
|
||||
data.requestType !== VaultRequestType.PermanentUnlock &&
|
||||
data.requestType !== VaultRequestType.CreateVault;
|
||||
|
||||
if (canAutoUnlock) {
|
||||
await onPressFingerprintAuth(data.title, data.description);
|
||||
if (canAutoUnlock && available) {
|
||||
try {
|
||||
await onPressFingerprintAuth(data.title, data.description);
|
||||
} catch (e) {
|
||||
setVisible(true);
|
||||
}
|
||||
} else {
|
||||
setVisible(true);
|
||||
}
|
||||
@@ -700,7 +721,6 @@ export const VaultDialog: React.FC = () => {
|
||||
icon="shield"
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator half />
|
||||
|
||||
<View
|
||||
style={{
|
||||
@@ -709,8 +729,7 @@ export const VaultDialog: React.FC = () => {
|
||||
>
|
||||
{(isChangePassword ||
|
||||
isClearVault ||
|
||||
!isCreateVault ||
|
||||
isDeleteVault ||
|
||||
(isDeleteVault && isUserLoggedIn) ||
|
||||
isCustomAction) &&
|
||||
!isRevokeFingerprint ? (
|
||||
<>
|
||||
@@ -772,20 +791,32 @@ export const VaultDialog: React.FC = () => {
|
||||
) : null}
|
||||
|
||||
{isDeleteVault && (
|
||||
<Button
|
||||
<Pressable
|
||||
onPress={() => setDeleteAll(!deleteAll)}
|
||||
icon={
|
||||
deleteAll
|
||||
? "check-circle-outline"
|
||||
: "checkbox-blank-circle-outline"
|
||||
}
|
||||
style={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
paddingVertical: 0,
|
||||
flexDirection: "row",
|
||||
gap: DefaultAppStyles.GAP_SMALL,
|
||||
marginTop: isUserLoggedIn
|
||||
? DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||
: 0,
|
||||
justifyContent: "flex-start"
|
||||
}}
|
||||
width="100%"
|
||||
title={strings.deleteAllNotes()}
|
||||
type="errorShade"
|
||||
/>
|
||||
>
|
||||
<AppIcon
|
||||
name={
|
||||
deleteAll
|
||||
? "check-circle-outline"
|
||||
: "checkbox-blank-circle-outline"
|
||||
}
|
||||
color={colors.error.accent}
|
||||
size={AppFontSize.md}
|
||||
/>
|
||||
|
||||
<Paragraph color={colors.error.accent} size={AppFontSize.sm}>
|
||||
{strings.deleteAllNotes()}
|
||||
</Paragraph>
|
||||
</Pressable>
|
||||
)}
|
||||
|
||||
{isChangePassword ? (
|
||||
|
||||
@@ -384,10 +384,14 @@ function MonographLockscreen({
|
||||
}) {
|
||||
const [error, setError] = useState<string>();
|
||||
const [loading, setLoading] = useState<boolean>();
|
||||
const password = useRef<string>();
|
||||
const password = useRef<string>("");
|
||||
|
||||
const unlock = useCallback(async () => {
|
||||
if (!password.current) return;
|
||||
if (!password.current) {
|
||||
setError("Password is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
try {
|
||||
@@ -467,7 +471,9 @@ function MonographLockscreen({
|
||||
}}
|
||||
autoFocus={true}
|
||||
autofillBackgroundColor="background-secondary"
|
||||
onChange={(event) => (password.current = event.target.value)}
|
||||
onChange={(event) => {
|
||||
password.current = event.target.value;
|
||||
}}
|
||||
onKeyUp={(e) => (e.key === "Enter" ? unlock() : null)}
|
||||
type="password"
|
||||
placeholder="Enter password to continue"
|
||||
@@ -477,6 +483,7 @@ function MonographLockscreen({
|
||||
title="Unlock"
|
||||
sx={{ borderRadius: 100, px: 50, mt: 1 }}
|
||||
onClick={() => unlock()}
|
||||
disabled={loading}
|
||||
>
|
||||
Unlock
|
||||
</Button>
|
||||
|
||||
@@ -23,6 +23,7 @@ import { showToast } from "../utils/toast";
|
||||
import { VAULT_ERRORS } from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useStore as useAppStore } from "../stores/app-store";
|
||||
import { useStore as useUserStore } from "../stores/user-store";
|
||||
|
||||
class Vault {
|
||||
static async createVault() {
|
||||
@@ -63,29 +64,47 @@ class Vault {
|
||||
|
||||
static async deleteVault() {
|
||||
if (!(await db.vault.exists())) return false;
|
||||
const result = await showPasswordDialog({
|
||||
title: strings.deleteVault(),
|
||||
subtitle: strings.deleteVaultDesc(),
|
||||
inputs: {
|
||||
password: {
|
||||
label: strings.accountPassword(),
|
||||
autoComplete: "current-password"
|
||||
}
|
||||
},
|
||||
checks: {
|
||||
deleteAllLockedNotes: {
|
||||
text: strings.deleteAllNotes(),
|
||||
default: false
|
||||
}
|
||||
},
|
||||
validate: ({ password }) => {
|
||||
return db.user.verifyPassword(password);
|
||||
}
|
||||
});
|
||||
|
||||
const result = await (useUserStore.getState().isLoggedIn
|
||||
? showPasswordDialog({
|
||||
title: strings.deleteVault(),
|
||||
subtitle: strings.deleteVaultDesc(),
|
||||
inputs: {
|
||||
password: {
|
||||
label: strings.accountPassword(),
|
||||
autoComplete: "current-password"
|
||||
}
|
||||
},
|
||||
checks: {
|
||||
deleteAllLockedNotes: {
|
||||
text: strings.deleteAllNotes(),
|
||||
default: false
|
||||
}
|
||||
},
|
||||
validate: ({ password }) => {
|
||||
return db.user.verifyPassword(password);
|
||||
}
|
||||
})
|
||||
: showPasswordDialog({
|
||||
title: strings.deleteVault(),
|
||||
subtitle: strings.deleteVaultDesc(),
|
||||
inputs: {},
|
||||
checks: {
|
||||
deleteAllLockedNotes: {
|
||||
text: strings.deleteAllNotes(),
|
||||
default: false
|
||||
}
|
||||
},
|
||||
validate: () => {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}));
|
||||
|
||||
if (result) {
|
||||
await db.vault.delete(result.deleteAllLockedNotes);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
async up(db) {
|
||||
await db.schema
|
||||
.createTable("kv")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.addColumn("key", "text", (c) => c.primaryKey().unique().notNull())
|
||||
.addColumn("value", "text")
|
||||
@@ -46,6 +47,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("notes")
|
||||
.ifNotExists()
|
||||
// .modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.$call(addTrashColumns)
|
||||
@@ -68,6 +70,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("content")
|
||||
.ifNotExists()
|
||||
// .modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("noteId", "text")
|
||||
@@ -88,6 +91,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("notehistory")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("noteId", "text")
|
||||
@@ -98,6 +102,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("sessioncontent")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("data", "text")
|
||||
@@ -109,6 +114,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("notebooks")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.$call(addTrashColumns)
|
||||
@@ -120,6 +126,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("tags")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("title", "text", COLLATE_NOCASE)
|
||||
@@ -127,6 +134,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("colors")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("title", "text", COLLATE_NOCASE)
|
||||
@@ -135,6 +143,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("vaults")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("title", "text", COLLATE_NOCASE)
|
||||
@@ -143,6 +152,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("relations")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("fromType", "text")
|
||||
@@ -153,6 +163,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("shortcuts")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("sortIndex", "integer")
|
||||
@@ -162,6 +173,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("reminders")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("title", "text", COLLATE_NOCASE)
|
||||
@@ -178,6 +190,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("attachments")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("iv", "text")
|
||||
@@ -197,6 +210,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createTable("settings")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("key", "text", (c) => c.unique())
|
||||
@@ -205,12 +219,14 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createIndex("notehistory_noteid")
|
||||
.ifNotExists()
|
||||
.on("notehistory")
|
||||
.column("noteId")
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("relation_from_general")
|
||||
.ifNotExists()
|
||||
.on("relations")
|
||||
.columns(["fromType", "toType", "fromId"])
|
||||
.where("toType", "!=", "note")
|
||||
@@ -219,6 +235,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createIndex("relation_to_general")
|
||||
.ifNotExists()
|
||||
.on("relations")
|
||||
.columns(["fromType", "toType", "toId"])
|
||||
.where("fromType", "!=", "note")
|
||||
@@ -227,6 +244,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createIndex("relation_from_note_notebook")
|
||||
.ifNotExists()
|
||||
.on("relations")
|
||||
.columns(["fromType", "toType", "fromId", "toId"])
|
||||
.where((eb) =>
|
||||
@@ -239,6 +257,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createIndex("relation_to_note_notebook")
|
||||
.ifNotExists()
|
||||
.on("relations")
|
||||
.columns(["fromType", "toType", "toId", "fromId"])
|
||||
.where((eb) =>
|
||||
@@ -251,36 +270,42 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
|
||||
await db.schema
|
||||
.createIndex("note_type")
|
||||
.ifNotExists()
|
||||
.on("notes")
|
||||
.columns(["type"])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("note_deleted")
|
||||
.ifNotExists()
|
||||
.on("notes")
|
||||
.columns(["deleted"])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("note_date_deleted")
|
||||
.ifNotExists()
|
||||
.on("notes")
|
||||
.columns(["dateDeleted"])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("notebook_type")
|
||||
.ifNotExists()
|
||||
.on("notebooks")
|
||||
.columns(["type"])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("attachment_hash")
|
||||
.ifNotExists()
|
||||
.on("attachments")
|
||||
.column("hash")
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex("content_noteId")
|
||||
.ifNotExists()
|
||||
.on("content")
|
||||
.columns(["noteId"])
|
||||
.execute();
|
||||
@@ -316,6 +341,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
async up(db) {
|
||||
await db.schema
|
||||
.createTable("config")
|
||||
.ifNotExists()
|
||||
.modifyEnd(sql`without rowid`)
|
||||
.addColumn("name", "text", (c) => c.primaryKey().unique().notNull())
|
||||
.addColumn("value", "text")
|
||||
@@ -397,6 +423,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
async up(db) {
|
||||
await db.schema
|
||||
.createTable("monographs")
|
||||
.ifNotExists()
|
||||
.$call(addBaseColumns)
|
||||
.addColumn("datePublished", "integer")
|
||||
.addColumn("title", "text", COLLATE_NOCASE)
|
||||
@@ -413,6 +440,7 @@ export class NNMigrationProvider implements MigrationProvider {
|
||||
.execute();
|
||||
await db.schema
|
||||
.createIndex("note_expiry_date")
|
||||
.ifNotExists()
|
||||
.on("notes")
|
||||
.expression(sql`expiryDate ->> '$.value'`)
|
||||
.execute();
|
||||
@@ -514,7 +542,9 @@ function createFTS5Table(
|
||||
sql.join(_options.map((o) => sql.raw(o)))
|
||||
]);
|
||||
|
||||
return sql`CREATE VIRTUAL TABLE ${sql.raw(name)} USING fts5(${args})`;
|
||||
return sql`CREATE VIRTUAL TABLE IF NOT EXISTS ${sql.raw(
|
||||
name
|
||||
)} USING fts5(${args})`;
|
||||
}
|
||||
|
||||
async function runFTSTablesMigrations(db: Kysely<any>) {
|
||||
|
||||
@@ -2310,8 +2310,8 @@ msgid "Delete mode"
|
||||
msgstr "Delete mode"
|
||||
|
||||
#: src/strings.ts:562
|
||||
msgid "Delete notes in this vault"
|
||||
msgstr "Delete notes in this vault"
|
||||
msgid "Delete notes in this vault permanently"
|
||||
msgstr "Delete notes in this vault permanently"
|
||||
|
||||
#: src/strings.ts:569
|
||||
msgid "Delete permanently"
|
||||
|
||||
@@ -2299,7 +2299,7 @@ msgid "Delete mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:562
|
||||
msgid "Delete notes in this vault"
|
||||
msgid "Delete notes in this vault permanently"
|
||||
msgstr ""
|
||||
|
||||
#: src/strings.ts:569
|
||||
|
||||
@@ -559,7 +559,7 @@ $day$: Current day (eg. Monday)`,
|
||||
couldNotUnlock: () => t`Could not unlock`,
|
||||
unlockNoteDesc: () =>
|
||||
t`Your note will be unencrypted and removed from the vault.`,
|
||||
deleteAllNotes: () => t`Delete notes in this vault`,
|
||||
deleteAllNotes: () => t`Delete notes in this vault permanently`,
|
||||
getStarted: () => t`Get started`,
|
||||
saveACopy: () => t`Save a copy`,
|
||||
discard: () => t`Discard`,
|
||||
|
||||
Reference in New Issue
Block a user