From 6f7a55c31659e848552d17277a281dc6607458ea Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Thu, 16 Jul 2026 16:25:28 +0500 Subject: [PATCH] mobile: settings module ui fixes --- .../app/components/auth/change-password.tsx | 17 +- .../mobile/app/components/dialog/functions.ts | 2 +- apps/mobile/app/components/dialog/index.tsx | 5 +- .../app/components/dialogs/vault/index.tsx | 21 +- .../components/sheets/export-notes/index.tsx | 30 +- .../components/sheets/force-sync/index.tsx | 7 +- apps/mobile/app/components/toast/index.tsx | 8 +- apps/mobile/app/components/ui/checkbox.tsx | 3 - .../app/components/ui/input/form-input.tsx | 5 + apps/mobile/app/hooks/use-vault-status.ts | 1 + .../settings/components/notesnook-circle.tsx | 4 + .../settings/components/picker/index.tsx | 13 +- .../settings/components/picker/pickers.tsx | 2 +- .../settings/components/theme-selector.tsx | 12 +- .../app/screens/settings/groups/about.tsx | 1 + .../screens/settings/groups/account-local.ts | 1 + .../app/screens/settings/groups/account.ts | 21 +- .../screens/settings/groups/back-restore.ts | 8 +- .../app/screens/settings/groups/customize.ts | 15 +- .../screens/settings/groups/help-support.tsx | 3 +- .../settings/groups/privacy-security.ts | 11 + .../screens/settings/groups/productivity.ts | 2 + .../screens/settings/restore-backup/index.tsx | 154 ++++--- .../app/screens/settings/section-item.tsx | 385 ++++++++++-------- apps/mobile/app/screens/settings/types.ts | 15 + apps/mobile/app/services/exporter.ts | 16 +- .../fonts/notesnook-icons.glyphmap.json | 2 +- apps/mobile/fonts/notesnook-icons.ttf | Bin 37136 -> 37364 bytes .../ios/nanoicons-fonts/notesnook-icons.ttf | Bin 37136 -> 37364 bytes apps/mobile/react-native.config.js | 2 +- packages/icons/svgs/folder-lock.svg | 3 + packages/intl/locale/en.po | 8 + packages/intl/locale/pseudo-LOCALE.po | 8 + packages/intl/src/strings.ts | 4 +- 34 files changed, 510 insertions(+), 279 deletions(-) create mode 100644 packages/icons/svgs/folder-lock.svg diff --git a/apps/mobile/app/components/auth/change-password.tsx b/apps/mobile/app/components/auth/change-password.tsx index 80f24a8c7..862529fc9 100644 --- a/apps/mobile/app/components/auth/change-password.tsx +++ b/apps/mobile/app/components/auth/change-password.tsx @@ -21,7 +21,10 @@ import { strings } from "@notesnook/intl"; import { useThemeColors } from "@notesnook/theme"; import React, { useRef, useState } from "react"; import { View } from "react-native"; +import { TextInput } from "react-native-gesture-handler"; +import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import { db } from "../../common/database"; +import { Spacing } from "../../common/design/spacing"; import BackupService from "../../services/backup"; import { ToastManager } from "../../services/event-manager"; import Navigation from "../../services/navigation"; @@ -29,14 +32,12 @@ import { useUserStore } from "../../stores/use-user-store"; import { AppFontSize } from "../../utils/size"; import { DefaultAppStyles } from "../../utils/styles"; import { Dialog } from "../dialog"; +import RecoveryKeySheet from "../sheets/recovery-key"; import AppIcon from "../ui/AppIcon"; import { Button } from "../ui/button"; import FormInput, { createFormRef, validators } from "../ui/input/form-input"; import { Notice } from "../ui/notice"; import Paragraph from "../ui/typography/paragraph"; -import { TextInput } from "react-native-gesture-handler"; -import { Spacing } from "../../common/design/spacing"; -import RecoveryKeySheet from "../sheets/recovery-key"; export const ChangePassword = () => { const { colors } = useThemeColors(); @@ -107,13 +108,17 @@ export const ChangePassword = () => { }; return ( - { /> {strings.yourSecurityIsPriority()} - + ); }; diff --git a/apps/mobile/app/components/dialog/functions.ts b/apps/mobile/app/components/dialog/functions.ts index 813761764..f2644a5e0 100644 --- a/apps/mobile/app/components/dialog/functions.ts +++ b/apps/mobile/app/components/dialog/functions.ts @@ -60,7 +60,7 @@ export type DialogInfo = { ref: RefObject; inputProps?: TextInputProps; }[]; - onFormSubmit?: (form: FormRef) => Promise; + onFormSubmit?: (form: FormRef, checked?: boolean) => Promise; }; input: boolean; inputLabel?: string; diff --git a/apps/mobile/app/components/dialog/index.tsx b/apps/mobile/app/components/dialog/index.tsx index fbeedd057..dfb9d3ec1 100644 --- a/apps/mobile/app/components/dialog/index.tsx +++ b/apps/mobile/app/components/dialog/index.tsx @@ -74,7 +74,10 @@ export const Dialog = ({ context = "global" }: { context?: string }) => { } if (dialogInfo.form.onFormSubmit) { setLoading(true); - const result = await dialogInfo.form.onFormSubmit(formRef.current); + const result = await dialogInfo.form.onFormSubmit( + formRef.current, + checked + ); if (result === false) { setLoading(false); return; diff --git a/apps/mobile/app/components/dialogs/vault/index.tsx b/apps/mobile/app/components/dialogs/vault/index.tsx index 93fb4bba4..b49f7c68e 100644 --- a/apps/mobile/app/components/dialogs/vault/index.tsx +++ b/apps/mobile/app/components/dialogs/vault/index.tsx @@ -188,7 +188,6 @@ export const VaultDialog: React.FC = () => { } await db.vault.delete(deleteAll); await BiometricService.resetCredentials(); - if (deleteAll) { noteIds.forEach((id) => { eSendEvent( @@ -753,9 +752,13 @@ export const VaultDialog: React.FC = () => { name="password" formRef={formRef} label={ - isChangePassword - ? strings.currentPassword() - : strings.password() + isDeleteVault + ? strings.enterAccountPassword() + : isClearVault + ? strings.enterVaultPassword() + : isChangePassword + ? strings.currentPassword() + : strings.password() } fwdRef={passInputRef} editable={!loading} @@ -809,11 +812,17 @@ export const VaultDialog: React.FC = () => { width="100%" style={{ justifyContent: "flex-start", - paddingHorizontal: 0 + paddingHorizontal: 0, + paddingVertical: 0, + marginTop: Spacing.LEVEL_1 }} title={strings.deleteAllNotes()} type="transparent" - iconColor={colors.error.accent} + iconColor={ + deleteAll + ? [colors.error.accent, colors.error.accentForeground] + : colors.error.accent + } textStyle={{ color: colors.error.accent }} diff --git a/apps/mobile/app/components/sheets/export-notes/index.tsx b/apps/mobile/app/components/sheets/export-notes/index.tsx index 391da494f..2a505cccd 100644 --- a/apps/mobile/app/components/sheets/export-notes/index.tsx +++ b/apps/mobile/app/components/sheets/export-notes/index.tsx @@ -19,7 +19,7 @@ along with this program. If not, see . import { strings } from "@notesnook/intl"; import { useThemeColors } from "@notesnook/theme"; -import React, { useState } from "react"; +import React, { useRef, useState } from "react"; import { ActivityIndicator, Linking, Platform, View } from "react-native"; import FileViewer from "react-native-file-viewer"; import Share from "react-native-share"; @@ -65,11 +65,14 @@ const ExportNotesSheet = ({ | undefined >(); const [status, setStatus] = useState(); + const abortController = useRef(undefined); const exportNoteAs = async ( type: "pdf" | "txt" | "md" | "html" | "md-frontmatter" ) => { if (exporting) return; + const controller = new AbortController(); + abortController.current = controller; setExporting(true); update?.({ disableClosing: true } as PresentSheetOptions); setComplete(false); @@ -78,7 +81,8 @@ const ExportNotesSheet = ({ result = await Exporter.bulkExport( db.notes.all.where((eb) => eb("id", "in", ids)), type, - setStatus + setStatus, + controller.signal ); } else { const note = await db.notes.note(ids[0]); @@ -86,10 +90,15 @@ const ExportNotesSheet = ({ setExporting(false); return; } - result = await Exporter.exportNote(note, type, setStatus); + result = await Exporter.exportNote( + note, + type, + setStatus, + controller.signal + ); await sleep(1000); } - if (!result) { + if (!result || controller.signal.aborted) { update?.({ disableClosing: false } as PresentSheetOptions); return setExporting(false); } @@ -100,6 +109,13 @@ const ExportNotesSheet = ({ requestInAppReview(); }; + const cancelExport = () => { + abortController.current?.abort(); + update?.({ disableClosing: false } as PresentSheetOptions); + setExporting(false); + setStatus(undefined); + }; + const actions = [ { title: "PDF", @@ -276,6 +292,12 @@ const ExportNotesSheet = ({ " " + strings.pleaseWait()} +