diff --git a/apps/mobile/app/components/auth/change-password.tsx b/apps/mobile/app/components/auth/change-password.tsx index a3ca00938..d10ae1341 100644 --- a/apps/mobile/app/components/auth/change-password.tsx +++ b/apps/mobile/app/components/auth/change-password.tsx @@ -18,6 +18,7 @@ along with this program. If not, see . */ import { strings } from "@notesnook/intl"; +import { useThemeColors } from "@notesnook/theme"; import React, { useRef, useState } from "react"; import { View } from "react-native"; import { db } from "../../common/database"; @@ -26,42 +27,44 @@ import { eSendEvent, ToastManager } from "../../services/event-manager"; import Navigation from "../../services/navigation"; import { useUserStore } from "../../stores/use-user-store"; import { eOpenRecoveryKeyDialog } from "../../utils/events"; +import { AppFontSize } from "../../utils/size"; import { DefaultAppStyles } from "../../utils/styles"; import { Dialog } from "../dialog"; +import AppIcon from "../ui/AppIcon"; import { Button } from "../ui/button"; -import Input from "../ui/input"; +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"; export const ChangePassword = () => { - const passwordInputRef = useRef(null); - const password = useRef(undefined); + const { colors } = useThemeColors(); + const formRef = useRef( + createFormRef({ + oldPassword: "", + password: "" + }) + ); const oldPasswordInputRef = useRef(null); - const oldPassword = useRef(undefined); - - const [error, setError] = useState(false); + const passwordInputRef = useRef(null); const [loading, setLoading] = useState(false); + const [error, setError] = useState(); const user = useUserStore((state) => state.user); const changePassword = async () => { + setError(undefined); + formRef.current.clearErrors(); + if (!user?.isEmailConfirmed) { - ToastManager.show({ - heading: strings.emailNotConfirmed(), - message: strings.emailNotConfirmedDesc(), - type: "error", - context: "local" - }); + setError(strings.emailNotConfirmedDesc()); return; } - if (error || !oldPassword.current || !password.current) { - ToastManager.show({ - heading: strings.allFieldsRequired(), - message: strings.allFieldsRequiredDesc(), - type: "error", - context: "local" - }); + if (!formRef.current.validate()) { return; } + + const values = formRef.current.getValues(); + setLoading(true); try { const result = await BackupService.run( @@ -74,8 +77,8 @@ export const ChangePassword = () => { } const passwordChanged = await db.user.changePassword( - oldPassword.current, - password.current + values.oldPassword, + values.password ); if (!passwordChanged) { @@ -91,15 +94,15 @@ export const ChangePassword = () => { Navigation.goBack(); eSendEvent(eOpenRecoveryKeyDialog); } catch (e) { + const message = (e as Error).message; setLoading(false); - ToastManager.show({ - heading: strings.passwordChangeFailed(), - message: (e as Error).message, - type: "error", - context: "local" - }); + + if (/old password/i.test(message)) { + formRef.current.setError("oldPassword", message); + } else { + setError(message); + } } - setLoading(false); }; return ( @@ -110,36 +113,61 @@ export const ChangePassword = () => { }} > - { - oldPassword.current = value; - }} + loading={loading} + validators={[validators.required(strings.currentPasswordRequired())]} returnKeyLabel="Next" returnKeyType="next" secureTextEntry autoComplete="password" autoCapitalize="none" autoCorrect={false} - placeholder={strings.oldPassword()} + placeholder={strings.currentPassword()} + onSubmitEditing={() => { + passwordInputRef.current?.focus(); + }} /> - { - password.current = value; - }} - onErrorCheck={(e) => setError(e)} + loading={loading} + validators={[validators.required(strings.passwordRequired())]} returnKeyLabel={strings.next()} returnKeyType="next" secureTextEntry - validationType="password" autoComplete="password" autoCapitalize="none" autoCorrect={false} placeholder={strings.newPassword()} + onSubmitEditing={() => { + changePassword(); + }} /> + {error ? ( + {}} + color={colors.error.accent} + style={{ + textAlign: "center", + marginTop: DefaultAppStyles.GAP_VERTICAL + }} + > + {" "} + {error} + + ) : null} + diff --git a/packages/intl/locale/en.po b/packages/intl/locale/en.po index 534e7e949..3bc3c0f7e 100644 --- a/packages/intl/locale/en.po +++ b/packages/intl/locale/en.po @@ -6,6 +6,12 @@ msgstr "" "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:2421 msgid " \"Notebook > Notes\"" @@ -1962,10 +1968,15 @@ msgstr "Curate the toolbar that fits your needs and matches your personality." msgid "Current note" msgstr "Current note" +#: src/strings.ts:1479 #: src/strings.ts:1485 msgid "Current password" msgstr "Current password" +#: src/strings.ts:2670 +msgid "Current password required" +msgstr "Current password required" + #: src/strings.ts:1229 msgid "Current path: {path}" msgstr "Current path: {path}" @@ -4401,10 +4412,6 @@ msgstr "Okay" msgid "Old - new" msgstr "Old - new" -#: src/strings.ts:1479 -msgid "Old password" -msgstr "Old password" - #: src/strings.ts:1835 msgid "Older version" msgstr "Older version" diff --git a/packages/intl/locale/pseudo-LOCALE.po b/packages/intl/locale/pseudo-LOCALE.po index 0ad2efe05..0ca7eae41 100644 --- a/packages/intl/locale/pseudo-LOCALE.po +++ b/packages/intl/locale/pseudo-LOCALE.po @@ -6,6 +6,12 @@ msgstr "" "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:2421 msgid " \"Notebook > Notes\"" @@ -1951,10 +1957,15 @@ msgstr "" msgid "Current note" msgstr "" +#: src/strings.ts:1479 #: src/strings.ts:1485 msgid "Current password" msgstr "" +#: src/strings.ts:2670 +msgid "Current password required" +msgstr "" + #: src/strings.ts:1229 msgid "Current path: {path}" msgstr "" @@ -4375,10 +4386,6 @@ msgstr "" msgid "Old - new" msgstr "" -#: src/strings.ts:1479 -msgid "Old password" -msgstr "" - #: src/strings.ts:1835 msgid "Older version" msgstr "" diff --git a/packages/intl/src/strings.ts b/packages/intl/src/strings.ts index 6bfe069ec..92e750d0c 100644 --- a/packages/intl/src/strings.ts +++ b/packages/intl/src/strings.ts @@ -1476,7 +1476,7 @@ $day$: Current day (eg. Monday)`, someNotesPublished: () => t`Some notes are published`, unpublishToDelete: () => t`Unpublish notes to delete them`, filterAttachments: () => t`Filter attachments by filename, type or hash`, - oldPassword: () => t`Old password`, + oldPassword: () => t`Current password`, newPassword: () => t`New password`, email: () => t`Email`, emailInvalid: () => t`Invalid email`, @@ -2666,5 +2666,6 @@ Use this if changes from other devices are not appearing on this device. This wi t`Are you sure you want to delete this attachment?`, attachmentDeleted: () => t`Attachment deleted`, titleIsRequired: () => t`Title is required`, - nameIsRequired: () => t`Name is required.` + nameIsRequired: () => t`Name is required.`, + currentPasswordRequired: () => t`Current password required` };