diff --git a/apps/mobile/app/components/app-lock-overlay/index.tsx b/apps/mobile/app/components/app-lock-overlay/index.tsx index f84d00d01..eab792b61 100644 --- a/apps/mobile/app/components/app-lock-overlay/index.tsx +++ b/apps/mobile/app/components/app-lock-overlay/index.tsx @@ -47,6 +47,9 @@ const AppLockedOverlay = () => { const password = useRef(); const appState = useAppState(); const biometricUnlockAwaitingUserInput = useRef(false); + const keyboardType = useSettingStore( + (state) => state.settings.applockKeyboardType + ); const appLockHasPasswordSecurity = useSettingStore( (state) => state.settings.appLockHasPasswordSecurity ); @@ -186,11 +189,13 @@ const AppLockedOverlay = () => { fwdRef={passwordInputRef} secureTextEntry keyboardType={ - appLockHasPasswordSecurity ? "number-pad" : "default" + appLockHasPasswordSecurity ? keyboardType : "default" } placeholder={`Enter ${ appLockHasPasswordSecurity - ? `app lock pin` + ? `app lock ${ + keyboardType === "numeric" ? "pin" : "password" + }` : "account password" }`} onChangeText={(v) => (password.current = v)} diff --git a/apps/mobile/app/components/dialogs/applock-password/index.tsx b/apps/mobile/app/components/dialogs/applock-password/index.tsx index 2f44b1399..3c72feec3 100644 --- a/apps/mobile/app/components/dialogs/applock-password/index.tsx +++ b/apps/mobile/app/components/dialogs/applock-password/index.tsx @@ -31,22 +31,30 @@ import { eSubscribeEvent } from "../../../services/event-manager"; import SettingsService from "../../../services/settings"; +import { useSettingStore } from "../../../stores/use-setting-store"; import { getElevationStyle } from "../../../utils/elevation"; import { eCloseAppLocKPasswordDailog, eOpenAppLockPasswordDialog } from "../../../utils/events"; +import { SIZE } from "../../../utils/size"; import { sleep } from "../../../utils/time"; import BaseDialog from "../../dialog/base-dialog"; import DialogButtons from "../../dialog/dialog-buttons"; import DialogHeader from "../../dialog/dialog-header"; import { Toast } from "../../toast"; +import { IconButton } from "../../ui/icon-button"; import Input from "../../ui/input"; import Seperator from "../../ui/seperator"; export const AppLockPassword = () => { const { colors } = useThemeColors(); const [mode, setMode] = useState<"create" | "change" | "remove">("create"); + const [keyboardType, setKeyboardType] = useState<"pin" | "password">( + useSettingStore.getState().settings.applockKeyboardType === "default" + ? "password" + : "pin" + ); const [visible, setVisible] = useState(false); const currentPasswordInputRef = useRef(null); const passwordInputRef = useRef(null); @@ -56,6 +64,7 @@ export const AppLockPassword = () => { password?: string; confirmPassword?: string; }>({}); + const [secureTextEntry, setSecureTextEntry] = useState(true); useEffect(() => { const subs = [ @@ -72,7 +81,7 @@ export const AppLockPassword = () => { }) ]; return () => { - subs.forEach((sub) => sub.unsubscribe()); + subs.forEach((sub) => sub?.unsubscribe()); }; }, []); @@ -85,7 +94,11 @@ export const AppLockPassword = () => { { await sleep(100); - passwordInputRef.current?.focus(); + if (mode !== "change") { + passwordInputRef.current?.focus(); + } else { + currentPasswordInputRef.current?.focus(); + } }} statusBarTranslucent={false} onRequestClose={close} @@ -103,17 +116,17 @@ export const AppLockPassword = () => { { onSubmit={() => { passwordInputRef.current?.focus(); }} + defaultValue={values.current.currentPassword} autoComplete="password" returnKeyLabel="Next" - keyboardType="number-pad" + keyboardType={keyboardType === "pin" ? "number-pad" : "default"} returnKeyType="next" - secureTextEntry - placeholder={"Current pin"} + secureTextEntry={secureTextEntry} + placeholder={`Current ${keyboardType}`} /> ) : null} @@ -153,12 +167,37 @@ export const AppLockPassword = () => { onSubmit={() => { confirmPasswordInputRef.current?.focus(); }} - keyboardType="number-pad" + defaultValue={values.current.password} + keyboardType={keyboardType === "pin" ? "number-pad" : "default"} autoComplete="password" returnKeyLabel={mode !== "remove" ? "Next" : "Remove"} returnKeyType={mode !== "remove" ? "next" : "done"} - secureTextEntry - placeholder={mode === "change" ? "New pin" : "Pin"} + secureTextEntry={secureTextEntry} + buttonLeft={ + { + setKeyboardType( + keyboardType === "password" ? "pin" : "password" + ); + setSecureTextEntry(false); + setImmediate(() => { + setSecureTextEntry(true); + }); + }} + customStyle={{ + width: 25, + height: 25, + marginRight: 5 + }} + size={SIZE.lg} + /> + } + placeholder={ + mode === "change" + ? `New ${keyboardType}` + : `${keyboardType === "pin" ? "Pin" : "Password"}` + } /> {mode !== "remove" ? ( @@ -171,14 +210,15 @@ export const AppLockPassword = () => { onSubmit={() => { confirmPasswordInputRef.current?.focus(); }} - keyboardType="number-pad" + defaultValue={values.current.confirmPassword} + keyboardType={keyboardType === "pin" ? "number-pad" : "default"} customValidator={() => values.current.password || ""} validationType="confirmPassword" autoComplete="password" returnKeyLabel="Done" returnKeyType="done" - secureTextEntry - placeholder={"Confirm pin"} + secureTextEntry={secureTextEntry} + placeholder={`Confirm ${keyboardType}`} /> ) : null} @@ -198,7 +238,11 @@ export const AppLockPassword = () => { if (values.current.password !== values.current.confirmPassword) { ToastManager.error( - new Error("Pin does not match"), + new Error( + `${ + keyboardType === "pin" ? "Pin" : "Password" + } does not match` + ), undefined, "local" ); @@ -222,7 +266,11 @@ export const AppLockPassword = () => { if (values.current.password !== values.current.confirmPassword) { ToastManager.error( - new Error("Pin does not match"), + new Error( + `${ + keyboardType === "pin" ? "Pin" : "Password" + } does not match` + ), undefined, "local" ); @@ -235,7 +283,9 @@ export const AppLockPassword = () => { if (!isCurrentPasswordCorrect) { ToastManager.error( - new Error("Pin incorrect"), + new Error( + `${keyboardType === "pin" ? "Pin" : "Password"} incorrect` + ), undefined, "local" ); @@ -259,13 +309,23 @@ export const AppLockPassword = () => { ); if (!isCurrentPasswordCorrect) { - ToastManager.error(new Error("Pin incorrect"), "local"); + ToastManager.error( + new Error( + `${keyboardType === "pin" ? "Pin" : "Password"} incorrect` + ), + "local" + ); return; } clearAppLockVerificationCipher(); SettingsService.setProperty("appLockHasPasswordSecurity", false); } + SettingsService.setProperty( + "applockKeyboardType", + keyboardType === "password" ? "default" : "numeric" + ); + close(); }} positiveTitle="Save" diff --git a/apps/mobile/app/components/sheets/migrate/index.tsx b/apps/mobile/app/components/sheets/migrate/index.tsx index a9d6d4a3f..bffdf2b88 100644 --- a/apps/mobile/app/components/sheets/migrate/index.tsx +++ b/apps/mobile/app/components/sheets/migrate/index.tsx @@ -18,18 +18,18 @@ along with this program. If not, see . */ import { EVENTS } from "@notesnook/core/dist/common"; +import { useThemeColors } from "@notesnook/theme"; import React, { useCallback, useEffect, useState } from "react"; import { Platform, View } from "react-native"; import { db } from "../../../common/database"; import { MMKV } from "../../../common/database/mmkv"; import BackupService from "../../../services/backup"; import { + ToastManager, eSendEvent, - presentSheet, - ToastManager + presentSheet } from "../../../services/event-manager"; import SettingsService from "../../../services/settings"; -import { useThemeColors } from "@notesnook/theme"; import { eCloseSheet } from "../../../utils/events"; import { sleep } from "../../../utils/time"; import { Dialog } from "../../dialog"; @@ -122,10 +122,13 @@ export default function Migrate() { - {!loading ? ( + {!loading && !error ? ( - - - Updating {progress ? progress?.collection : null} + Migrating database{progress ? `(${progress?.collection})` : null} {progress ? `(${progress.current}/${progress.total}) ` : null}... please wait + + + + ) : error ? ( @@ -198,6 +207,7 @@ export default function Migrate() { width={250} onPress={async () => { MMKV.clearStore(); + await db.reset(); setReset(true); }} style={{ diff --git a/apps/mobile/app/components/ui/sheet/index.js b/apps/mobile/app/components/ui/sheet/index.js index 67b4a66dc..3c8e01ab5 100644 --- a/apps/mobile/app/components/ui/sheet/index.js +++ b/apps/mobile/app/components/ui/sheet/index.js @@ -120,7 +120,8 @@ const SheetWrapper = ({ width: 100, backgroundColor: colors.secondary.background }} - drawUnderStatusBar={false} + statusBarTranslucent + drawUnderStatusBar={true} containerStyle={style} gestureEnabled={gestureEnabled} initialOffsetFromBottom={1} diff --git a/apps/mobile/app/screens/settings/section-item.tsx b/apps/mobile/app/screens/settings/section-item.tsx index 664b175e4..191316d0f 100644 --- a/apps/mobile/app/screens/settings/section-item.tsx +++ b/apps/mobile/app/screens/settings/section-item.tsx @@ -57,10 +57,11 @@ const _SectionItem = ({ item }: { item: SettingSection }) => { return; } if (!item.property) return; - item.onChange?.(!settings[item.property]); + const nextValue = !settings[item.property]; SettingsService.set({ - [item.property]: !settings[item.property] + [item.property]: nextValue }); + setImmediate(() => item.onChange?.(nextValue)); }; const styles = diff --git a/apps/mobile/app/screens/settings/settings-data.tsx b/apps/mobile/app/screens/settings/settings-data.tsx index bf5b8f2d4..06809a64e 100644 --- a/apps/mobile/app/screens/settings/settings-data.tsx +++ b/apps/mobile/app/screens/settings/settings-data.tsx @@ -799,19 +799,25 @@ export const settingsGroups: SettingSection[] = [ property: "appLockEnabled", onChange: async () => { if (!SettingsService.getProperty("appLockEnabled")) { + const keyboardType = SettingsService.getProperty( + "applockKeyboardType" + ); if (SettingsService.getProperty("appLockHasPasswordSecurity")) { presentDialog({ title: "Verify it's you", input: true, - inputPlaceholder: "Enter app lock pin", - paragraph: - "Please enter your app lock pin to disable app lock", + inputPlaceholder: `Enter app lock ${ + keyboardType === "numeric" ? "pin" : "password" + }`, + paragraph: `Please enter your app lock ${ + keyboardType === "numeric" ? "pin" : "password" + } to disable app lock`, positiveText: "Disable", secureTextEntry: true, negativeText: "Cancel", positivePress: async (value) => { try { - let verified = await validateAppLockPassword(value); + const verified = await validateAppLockPassword(value); if (!verified) { SettingsService.setProperty("appLockEnabled", true); return false; @@ -892,8 +898,8 @@ export const settingsGroups: SettingSection[] = [ }, { id: "app-lock-pin", - name: "Setup app lock pin", - description: "Set up a new pin for app lock", + name: "Setup app lock password", + description: "Setup a new app lock password for app lock", hidden: () => { return !!SettingsService.getProperty( "appLockHasPasswordSecurity" diff --git a/apps/mobile/app/stores/use-setting-store.ts b/apps/mobile/app/stores/use-setting-store.ts index b85276398..6d9348477 100644 --- a/apps/mobile/app/stores/use-setting-store.ts +++ b/apps/mobile/app/stores/use-setting-store.ts @@ -80,6 +80,7 @@ export type Settings = { appLockHasPasswordSecurity?: boolean; biometricsAuthEnabled?: boolean; backgroundSync?: boolean; + applockKeyboardType: "numeric" | "default"; }; type DimensionsType = { @@ -122,6 +123,7 @@ export interface SettingStore extends State { const { width, height } = Dimensions.get("window"); export const defaultSettings: SettingStore["settings"] = { + applockKeyboardType: "numeric", appLockTimer: 0, showToolbarOnTop: false, showKeyboardOnOpen: false, diff --git a/apps/mobile/native/android/gradle.properties b/apps/mobile/native/android/gradle.properties index dd5532e59..769aa2e62 100644 --- a/apps/mobile/native/android/gradle.properties +++ b/apps/mobile/native/android/gradle.properties @@ -48,5 +48,6 @@ hermesEnabled=true # fdroid fdroidBuild=false +org.gradle.java.home=/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home # -DSQLITE_USER_AUTHENTICATION=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 quickSqliteFlags=-DSQLITE3MC_OMIT_AES_HARDWARE_SUPPORT -DHAVE_CIPHER_AES_128_CBC=0 -DHAVE_CIPHER_AES_256_CBC=0 -DHAVE_CIPHER_SQLCIPHER=0 -DHAVE_CIPHER_RC4=0 -DHAVE_CIPHER_CHACHA20=1 -DSQLITE_ENABLE_FTS5 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 -DSQLITE_DQS=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_USE_ALLOCA=1 \ No newline at end of file diff --git a/apps/mobile/native/fonts/MaterialCommunityIcons.ttf b/apps/mobile/native/fonts/MaterialCommunityIcons.ttf index 4bc96924e..cb039d578 100644 Binary files a/apps/mobile/native/fonts/MaterialCommunityIcons.ttf and b/apps/mobile/native/fonts/MaterialCommunityIcons.ttf differ diff --git a/apps/mobile/scripts/optimize-fonts.mjs b/apps/mobile/scripts/optimize-fonts.mjs index 6befe67bf..e7a048d5b 100644 --- a/apps/mobile/scripts/optimize-fonts.mjs +++ b/apps/mobile/scripts/optimize-fonts.mjs @@ -72,7 +72,9 @@ const EXTRA_ICON_NAMES = [ "qrcode", "text", "cloud", - "restore" + "restore", + "keyboard", + "numeric" ]; const __filename = fileURLToPath(import.meta.url);