From 654a221cd2fd39d181be9d2125fadb49f107c31d Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Fri, 24 Jul 2026 12:10:59 +0500 Subject: [PATCH] mobile: ui updates --- .../components/sheets/export-notes/index.tsx | 7 + .../app/components/ui/input/form-input.tsx | 2 +- .../settings/components/change-email.tsx | 186 +- .../settings/components/components.tsx | 4 +- .../settings/components/edit-profile.tsx | 204 ++ .../settings/components/sound-picker.tsx | 93 +- .../app/screens/settings/groups/account.ts | 174 +- .../app/screens/settings/groups/customize.ts | 5 +- .../screens/settings/groups/productivity.ts | 3 +- .../fonts/notesnook-icons.glyphmap.json | 2 +- apps/mobile/fonts/notesnook-icons.ttf | Bin 42268 -> 42348 bytes .../ios/nanoicons-fonts/notesnook-icons.ttf | Bin 42268 -> 42348 bytes packages/icons/svgs/format-font-size.svg | 3 + packages/intl/locale/en.po | 2254 +++++++-------- packages/intl/locale/pseudo-LOCALE.po | 2478 +++++++++-------- packages/intl/src/strings.ts | 8 +- 16 files changed, 2814 insertions(+), 2609 deletions(-) create mode 100644 apps/mobile/app/screens/settings/components/edit-profile.tsx create mode 100644 packages/icons/svgs/format-font-size.svg diff --git a/apps/mobile/app/components/sheets/export-notes/index.tsx b/apps/mobile/app/components/sheets/export-notes/index.tsx index 2a505cccd..486328f49 100644 --- a/apps/mobile/app/components/sheets/export-notes/index.tsx +++ b/apps/mobile/app/components/sheets/export-notes/index.tsx @@ -382,6 +382,13 @@ const ExportNotesSheet = ({ ExportNotesSheet.present = async (ids?: string[], allNotes?: boolean) => { const exportNoteIds = allNotes ? await db.notes.all?.ids() : ids || []; + if (!exportNoteIds.length) { + ToastManager.show({ + message: strings.noNotesToExport(), + type: "info" + }); + return; + } presentSheet({ component: (ref, close, update) => ( diff --git a/apps/mobile/app/components/ui/input/form-input.tsx b/apps/mobile/app/components/ui/input/form-input.tsx index 0fb3753d8..495aaa256 100644 --- a/apps/mobile/app/components/ui/input/form-input.tsx +++ b/apps/mobile/app/components/ui/input/form-input.tsx @@ -320,7 +320,7 @@ export function FormInput({ onPress && loading ? colors.primary.accent : colors.primary.paragraph, paddingTop: Spacing.LEVEL_3, paddingBottom: Spacing.LEVEL_3, - lineHeight: fontSize + fontSize * 0.3, + lineHeight: fontSize + fontSize * 0.2, flexGrow: 1, flexShrink: 1, fontFamily: "Inter-Regular", diff --git a/apps/mobile/app/screens/settings/components/change-email.tsx b/apps/mobile/app/screens/settings/components/change-email.tsx index 24e908bbf..7d2c46012 100644 --- a/apps/mobile/app/screens/settings/components/change-email.tsx +++ b/apps/mobile/app/screens/settings/components/change-email.tsx @@ -18,26 +18,28 @@ along with this program. If not, see . */ import { strings } from "@notesnook/intl"; import { useThemeColors } from "@notesnook/theme"; -import React, { useRef, useState } from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; import { TextInput, View } from "react-native"; import { db } from "../../../common/database"; +import { Spacing } from "../../../common/design/spacing"; import { Button } from "../../../components/ui/button"; import FormInput, { createFormRef, validators } from "../../../components/ui/input/form-input"; +import Heading from "../../../components/ui/typography/heading"; +import Paragraph from "../../../components/ui/typography/paragraph"; import { eSendEvent, ToastManager } from "../../../services/event-manager"; import Navigation from "../../../services/navigation"; import { eUserLoggedIn } from "../../../utils/events"; -import { DefaultAppStyles } from "../../../utils/styles"; -import { Spacing } from "../../../common/design/spacing"; -import { PASSWORD_PLACEHOLDER } from "../../../utils/constants"; enum EmailChangeSteps { verify, changeEmail } +const RESEND_TIMEOUT = 30; + export const ChangeEmail = () => { const { colors } = useThemeColors(); const [step, setStep] = useState(EmailChangeSteps.verify); @@ -49,10 +51,30 @@ export const ChangeEmail = () => { }) ); const [loading, setLoading] = useState(false); + const [resendSeconds, setResendSeconds] = useState(RESEND_TIMEOUT); const emailInputRef = useRef(null); const passInputRef = useRef(null); const codeInputRef = useRef(null); + useEffect(() => { + if (step !== EmailChangeSteps.changeEmail || resendSeconds <= 0) return; + const timer = setTimeout(() => { + setResendSeconds((seconds) => seconds - 1); + }, 1000); + return () => clearTimeout(timer); + }, [step, resendSeconds]); + + const onResend = useCallback(async () => { + if (resendSeconds > 0) return; + try { + const { email } = formRef.current.getValues(); + await db.user?.sendVerificationEmail(email); + setResendSeconds(RESEND_TIMEOUT); + } catch (e) { + formRef.current.setError("code", (e as Error).message); + } + }, [resendSeconds]); + const onSubmit = async () => { try { if (step === EmailChangeSteps.verify) { @@ -67,6 +89,7 @@ export const ChangeEmail = () => { if (!verified) throw new Error(strings.passwordIncorrect()); await db.user?.sendVerificationEmail(email); setStep(EmailChangeSteps.changeEmail); + setResendSeconds(RESEND_TIMEOUT); formRef.current.clearErrors(); formRef.current.setValue("code", ""); setLoading(false); @@ -113,67 +136,98 @@ export const ChangeEmail = () => { gap: Spacing.LEVEL_4 }} > - - {step === EmailChangeSteps.verify ? ( - <> - { - passInputRef.current?.focus(); - }} - /> - - - ) : ( - <> - - /^\d{6}$/.test(value.trim()) - ? undefined - : strings.enterSixDigitCode() - ]} - onSubmitEditing={onSubmit} - /> - - )} - + {step === EmailChangeSteps.verify ? ( + + { + passInputRef.current?.focus(); + }} + /> + + + ) : ( + + + + {strings.verifyCurrentEmail()} + + + {strings.verifyCurrentEmailDesc()} + + + + /^\d{6}$/.test(value.trim()) + ? undefined + : strings.enterSixDigitCode() + ]} + onSubmitEditing={onSubmit} + /> + 0 + ? colors.secondary.paragraph + : colors.primary.accent + } + > + {resendSeconds > 0 + ? strings.resend2faCode(`${resendSeconds}`) + : strings.resendCode()} + + + )}