Implement CopyCodesPage changes from Design Document#91254
Conversation
prop to PressableWithDelayToggle
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/de.ts b/src/languages/de.ts
index c77a6ba1..f5ebc5a3 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2229,11 +2229,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'Die Zwei-Faktor-Authentifizierung ist jetzt deaktiviert',
noAuthenticatorApp: 'Sie benötigen keine Authentifizierungs-App mehr, um sich bei Expensify anzumelden.',
stepCodes: 'Wiederherstellungscodes',
- keepCodesSafe: 'Bewahre diese Wiederherstellungscodes sicher auf!',
+ keepCodesSafe: 'Bewahren Sie diese Codes sicher auf!',
codesLoseAccess: dedent(`
- Wenn du den Zugriff auf deine Authentifizierungs-App verlierst und diese Codes nicht hast, verlierst du den Zugriff auf dein Konto.
+ Wenn Sie den Zugriff auf Ihre Authentifizierungs-App verlieren und diese Codes nicht haben, verlieren Sie den Zugriff auf Ihr Konto.
- Hinweis: Das Einrichten der Zwei-Faktor-Authentifizierung meldet dich von allen anderen aktiven Sitzungen ab.
+ <strong>Hinweis</strong>: Das Einrichten der Zwei-Faktor-Authentifizierung meldet Sie von allen anderen aktiven Sitzungen ab.
`),
errorStepCodes: 'Bitte kopiere oder lade die Codes herunter, bevor du fortfährst',
stepVerify: 'Bestätigen',
@@ -2262,6 +2262,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Geben Sie den sechsstelligen Code aus Ihrer aktuellen Authentifizierungs-App ein, um zu bestätigen, dass Sie Zugriff darauf haben.',
verifyNewDeviceTitle: 'Neues Gerät einrichten',
verifyNewDeviceDescription: 'Scannen Sie den QR-Code mit Ihrem neuen Gerät und geben Sie dann den Code ein, um die Einrichtung abzuschließen.',
+ downloadCodes: 'Codes herunterladen',
+ screenshotTip: 'Tipp: Machen Sie einen Screenshot, um ihn in Ihrer Fotomediathek zu speichern',
+ copyCodes: 'Codes kopieren',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/es.ts b/src/languages/es.ts
index cfcfe238..4ca52229 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -2116,9 +2116,12 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'La autenticación de dos factores está ahora deshabilitada',
noAuthenticatorApp: 'Ya no necesitarás una aplicación de autenticación para iniciar sesión en Expensify.',
stepCodes: 'Códigos de recuperación',
- keepCodesSafe: '¡Guarda los códigos de recuperación en un lugar seguro!',
- codesLoseAccess:
- 'Si pierdes el acceso a tu aplicación de autenticación y no tienes estos códigos, perderás el acceso a tu cuenta. \n\nNota: Configurar la autenticación de dos factores cerrará la sesión de todas las demás sesiones activas.',
+ keepCodesSafe: '¡Guarda estos códigos en un lugar seguro!',
+ codesLoseAccess: dedent(`
+ Si pierdes el acceso a tu aplicación de autenticación y no tienes estos códigos, perderás el acceso a tu cuenta.
+
+ <strong>Nota</strong>: Configurar la autenticación de dos factores cerrará la sesión en todas las demás sesiones activas.
+ `),
errorStepCodes: 'Copia o descarga los códigos antes de continuar',
stepVerify: 'Verificar',
scanCode: 'Escanea el código QR usando tu',
@@ -2146,6 +2149,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Introduce el código de seis dígitos de tu aplicación de autenticación actual para confirmar que tienes acceso a ella.',
verifyNewDeviceTitle: 'Configurar nuevo dispositivo',
verifyNewDeviceDescription: 'Escanea el código QR con tu nuevo dispositivo y luego introduce el código para completar la configuración.',
+ downloadCodes: 'Descargar códigos',
+ screenshotTip: 'Consejo: haz una captura de pantalla para guardarla en tu galería de fotos',
+ copyCodes: 'Copiar códigos',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index f217296b..2a7eb27f 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2234,11 +2234,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'L’authentification à deux facteurs est maintenant désactivée',
noAuthenticatorApp: 'Vous n’aurez plus besoin d’une application d’authentification pour vous connecter à Expensify.',
stepCodes: 'Codes de récupération',
- keepCodesSafe: 'Conservez ces codes de récupération en lieu sûr !',
+ keepCodesSafe: 'Conservez ces codes en lieu sûr !',
codesLoseAccess: dedent(`
Si vous perdez l’accès à votre application d’authentification et que vous n’avez pas ces codes, vous perdrez l’accès à votre compte.
- Remarque : la configuration de l’authentification à deux facteurs vous déconnectera de toutes les autres sessions actives.
+ <strong>Remarque</strong> : La configuration de l’authentification à deux facteurs vous déconnectera de toutes les autres sessions actives.
`),
errorStepCodes: 'Veuillez copier ou télécharger les codes avant de continuer',
stepVerify: 'Vérifier',
@@ -2267,6 +2267,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Saisissez le code à six chiffres de votre application d’authentification actuelle pour confirmer que vous y avez accès.',
verifyNewDeviceTitle: 'Configurer un nouvel appareil',
verifyNewDeviceDescription: 'Scannez le code QR avec votre nouvel appareil, puis saisissez le code pour terminer la configuration.',
+ downloadCodes: 'Télécharger les codes',
+ screenshotTip: 'Astuce : faites une capture d’écran pour l’enregistrer dans votre photothèque',
+ copyCodes: 'Copier les codes',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 04714349..cdab019f 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2228,11 +2228,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: "L'autenticazione a due fattori è ora disattivata",
noAuthenticatorApp: 'Non sarà più necessaria un’app di autenticazione per accedere a Expensify.',
stepCodes: 'Codici di recupero',
- keepCodesSafe: 'Conserva questi codici di recupero in un luogo sicuro!',
+ keepCodesSafe: 'Conserva questi codici al sicuro!',
codesLoseAccess: dedent(`
Se perdi l'accesso alla tua app di autenticazione e non hai questi codici, perderai l'accesso al tuo account.
- Nota: Configurare l'autenticazione a due fattori ti disconnetterà da tutte le altre sessioni attive.
+ <strong>Nota</strong>: configurare l'autenticazione a due fattori ti disconnetterà da tutte le altre sessioni attive.
`),
errorStepCodes: 'Copia o scarica i codici prima di continuare',
stepVerify: 'Verifica',
@@ -2261,6 +2261,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Inserisci il codice a sei cifre dalla tua attuale app di autenticazione per confermare che hai accesso ad essa.',
verifyNewDeviceTitle: 'Configura nuovo dispositivo',
verifyNewDeviceDescription: 'Scansiona il codice QR con il tuo nuovo dispositivo, poi inserisci il codice per completare la configurazione.',
+ downloadCodes: 'Scarica codici',
+ screenshotTip: 'Suggerimento: fai uno screenshot per salvarlo nel rullino fotografico',
+ copyCodes: 'Copia codici',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index c6ee83df..027218c8 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2206,11 +2206,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: '二要素認証は現在無効になっています',
noAuthenticatorApp: '今後、Expensify にログインする際に認証アプリは不要になります。',
stepCodes: 'リカバリーコード',
- keepCodesSafe: 'これらのリカバリーコードを安全に保管してください!',
+ keepCodesSafe: 'これらのコードを安全に保管してください。',
codesLoseAccess: dedent(`
- 認証アプリへのアクセスを失い、これらのコードも持っていない場合は、アカウントにアクセスできなくなります。
+ 認証アプリへのアクセスを失い、これらのコードも持っていない場合は、お客さまのアカウントへのアクセスもできなくなります。
- 注: 二要素認証を設定すると、他のすべてのアクティブなセッションからログアウトされます。
+ <strong>注意</strong>:二要素認証を設定すると、他のすべてのアクティブなセッションからログアウトされます。
`),
errorStepCodes: '続行する前にコードをコピーまたはダウンロードしてください',
stepVerify: '確認',
@@ -2239,6 +2239,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: '現在使用している認証アプリに表示されている6桁のコードを入力して、アクセスできることを確認してください。',
verifyNewDeviceTitle: '新しいデバイスを設定',
verifyNewDeviceDescription: '新しいデバイスでQRコードをスキャンし、表示されたコードを入力して設定を完了してください。',
+ downloadCodes: 'コードをダウンロード',
+ screenshotTip: 'ヒント:スクリーンショットを撮ってフォトライブラリに保存しましょう',
+ copyCodes: 'コードをコピー',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 891386fd..8e86542b 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2223,11 +2223,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'Tweeledige verificatie is nu uitgeschakeld',
noAuthenticatorApp: 'Je hebt geen authenticator-app meer nodig om in te loggen bij Expensify.',
stepCodes: 'Herstelcodes',
- keepCodesSafe: 'Bewaar deze herstercodes goed!',
+ keepCodesSafe: 'Bewaar deze codes goed!',
codesLoseAccess: dedent(`
- Als je de toegang tot je authenticator-app kwijtraakt en deze codes niet hebt, verlies je de toegang tot je account.
+ Als je de toegang tot je authenticator-app verliest en deze codes niet hebt, verlies je de toegang tot je account.
- Let op: het instellen van tweeledige verificatie zal je uitloggen bij alle andere actieve sessies.
+ <strong>Let op</strong>: Het instellen van twee-factor-authenticatie zal je bij alle andere actieve sessies afmelden.
`),
errorStepCodes: 'Kopieer of download de codes voordat je verdergaat',
stepVerify: 'Verifiëren',
@@ -2256,6 +2256,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Voer de zescijferige code uit je huidige authenticator-app in om te bevestigen dat je daar toegang toe hebt.',
verifyNewDeviceTitle: 'Nieuw apparaat instellen',
verifyNewDeviceDescription: 'Scan de QR-code met je nieuwe apparaat en voer daarna de code in om de installatie te voltooien.',
+ downloadCodes: 'Codes downloaden',
+ screenshotTip: 'Tip: maak een screenshot om dit op te slaan in je fotobibliotheek',
+ copyCodes: 'Codes kopiëren',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 91459e08..9db21262 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2223,11 +2223,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'Uwierzytelnianie dwuskładnikowe jest teraz wyłączone',
noAuthenticatorApp: 'Nie będziesz już potrzebować aplikacji uwierzytelniającej, aby logować się do Expensify.',
stepCodes: 'Kody odzyskiwania',
- keepCodesSafe: 'Zachowaj te kody odzyskiwania w bezpiecznym miejscu!',
+ keepCodesSafe: 'Zachowaj te kody w bezpiecznym miejscu!',
codesLoseAccess: dedent(`
- Jeśli utracisz dostęp do aplikacji uwierzytelniającej i nie będziesz mieć tych kodów, stracisz dostęp do swojego konta.
+ Jeśli stracisz dostęp do swojej aplikacji uwierzytelniającej i nie masz tych kodów, stracisz dostęp do swojego konta.
- Uwaga: Włączenie uwierzytelniania dwuskładnikowego spowoduje wylogowanie Cię ze wszystkich innych aktywnych sesji.
+ <strong>Uwaga</strong>: Włączenie uwierzytelniania dwuskładnikowego wyloguje cię ze wszystkich innych aktywnych sesji.
`),
errorStepCodes: 'Skopiuj lub pobierz kody przed kontynuowaniem',
stepVerify: 'Zweryfikuj',
@@ -2256,6 +2256,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Wpisz sześciocyfrowy kod z bieżącej aplikacji uwierzytelniającej, żeby potwierdzić, że masz do niej dostęp.',
verifyNewDeviceTitle: 'Skonfiguruj nowe urządzenie',
verifyNewDeviceDescription: 'Zeskanuj kod QR nowym urządzeniem, a następnie wpisz ten kod, aby zakończyć konfigurację.',
+ downloadCodes: 'Pobierz kody',
+ screenshotTip: 'Wskazówka: Zrób zrzut ekranu, żeby zapisać to w swojej galerii zdjęć',
+ copyCodes: 'Skopiuj kody',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 535659f2..fc3d310c 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2220,11 +2220,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: 'A autenticação em duas etapas está desativada agora',
noAuthenticatorApp: 'Você não vai mais precisar de um app autenticador para entrar no Expensify.',
stepCodes: 'Códigos de recuperação',
- keepCodesSafe: 'Mantenha estes códigos de recuperação em segurança!',
+ keepCodesSafe: 'Mantenha estes códigos em segurança!',
codesLoseAccess: dedent(`
Se você perder o acesso ao seu app autenticador e não tiver esses códigos, perderá o acesso à sua conta.
- Observação: Configurar a autenticação em duas etapas desconectará você de todas as outras sessões ativas.
+ <strong>Observação</strong>: Configurar a autenticação em duas etapas vai desconectar você de todas as outras sessões ativas.
`),
errorStepCodes: 'Copie ou faça o download dos códigos antes de continuar',
stepVerify: 'Verificar',
@@ -2253,6 +2253,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: 'Digite o código de seis dígitos do seu aplicativo autenticador atual para confirmar que você tem acesso a ele.',
verifyNewDeviceTitle: 'Configurar novo dispositivo',
verifyNewDeviceDescription: 'Escaneie o código QR com seu novo dispositivo e depois insira o código para concluir a configuração.',
+ downloadCodes: 'Baixar códigos',
+ screenshotTip: 'Dica: faça uma captura de tela para salvar na sua galeria de fotos',
+ copyCodes: 'Copiar códigos',
},
recoveryCodeForm: {
error: {
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 3c9e8607..7445f6ee 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2164,11 +2164,11 @@ const translations: TranslationDeepObject<typeof en> = {
disabled: '已关闭双重身份验证',
noAuthenticatorApp: '你今后登录 Expensify 时将不再需要验证器应用程序。',
stepCodes: '恢复代码',
- keepCodesSafe: '请妥善保管这些恢复代码!',
+ keepCodesSafe: '妥善保管这些验证码!',
codesLoseAccess: dedent(`
- 如果你无法访问身份验证应用并且没有这些代码,你将无法访问你的帐户。
+ 如果你无法使用身份验证应用且没有这些代码,你将无法访问你的账户。
- 注意:设置双重身份验证会将你从所有其他活动会话中登出。
+ <strong>注意</strong>:设置双重身份验证后,你将在所有其他活跃会话中退出登录。
`),
errorStepCodes: '请在继续之前复制或下载这些代码',
stepVerify: '验证',
@@ -2197,6 +2197,9 @@ const translations: TranslationDeepObject<typeof en> = {
verifyOldDeviceDescription: '请输入您当前身份验证器应用中的六位数验证码,以确认您仍可访问该应用。',
verifyNewDeviceTitle: '设置新设备',
verifyNewDeviceDescription: '使用新设备扫描二维码,然后输入代码完成设置。',
+ downloadCodes: '下载代码',
+ screenshotTip: '提示:截屏此页面以将其保存到你的相册',
+ copyCodes: '复制代码',
},
recoveryCodeForm: {
error: {
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
@ChavdaSachin Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
Videos seem good to me 👍 |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-05-22.at.4.00.17.PM.movAndroid: mWeb ChromeiOS: HybridAppScreen.Recording.2026-05-22.at.3.56.24.PM.moviOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-05-22.at.3.50.00.PM.mov |
There was a problem hiding this comment.
just a small cleanup - #91254 (comment)
other than that, LGTM! ✅
cc. @chuckdries
|
🚧 @MariaHCD has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/MariaHCD in version: 9.3.82-0 🚀
Bundle Size Analysis (Sentry): |
|
Yes, help site changes are required. The PR changes the 2FA recovery codes page flow:
I've created a draft PR with the necessary docs updates: #91655 Files updated:
@chuckdries, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR |
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.3.82-3 🚀
|
Explanation of Change
wrapperStylesprop toPressableWithDelayToggleso I can make it the full width as shown in the mockupwrapperStylespropFixed Issues
$ #91253
PROPOSAL:
Tests
Offline tests
N/A - Offline pattern D
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
2fa.changes.android.mp4
Android: mWeb Chrome
2fa.changes.android.chrome.mp4
iOS: Native
2fa.changes.ios.mp4
iOS: mWeb Safari
2fa.changes.iOS.safari.mp4
MacOS: Chrome / Safari
2fa.changes.chrome.mp4