From b1580ee47367005cf26b84e54216248c45e261c3 Mon Sep 17 00:00:00 2001 From: "Andrew Rosiclair (via MelvinBot)" Date: Thu, 21 May 2026 15:16:18 +0000 Subject: [PATCH 1/4] Add Learn more link to Device Management page Restore the "Learn more" link in the Device Management RHP description that was previously removed. The link now points to the published help doc at help.expensify.com. Updated all 10 language files with localized link text, and switched DeviceManagementPage from plain Text to RenderHTML to render the anchor tag. Co-authored-by: Andrew Rosiclair --- src/languages/de.ts | 3 ++- src/languages/en.ts | 3 ++- src/languages/es.ts | 3 ++- src/languages/fr.ts | 3 ++- src/languages/it.ts | 2 +- src/languages/ja.ts | 3 ++- src/languages/nl.ts | 3 ++- src/languages/pl.ts | 3 ++- src/languages/pt-BR.ts | 3 ++- src/languages/zh-hans.ts | 2 +- src/pages/settings/Security/DeviceManagementPage.tsx | 5 ++++- 11 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index c77a6ba1bd60..26d6fab657b1 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -2214,7 +2214,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Geräteverwaltung', - description: 'Verwalten Sie alle Geräte, auf denen Sie sich mit Ihrem Expensify-Konto angemeldet haben.', + description: + 'Verwalten Sie alle Geräte, auf denen Sie sich mit Ihrem Expensify-Konto angemeldet haben. Weitere Informationen', revoke: 'Widerrufen', unknownDevice: 'Unbekanntes Gerät', }, diff --git a/src/languages/en.ts b/src/languages/en.ts index 23d4be8a5b88..cec7781a93dc 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2285,7 +2285,8 @@ const translations = { }, deviceManagementPage: { title: 'Device management', - description: 'Manage all the devices that you have logged into with your Expensify Account.', + description: + 'Manage all the devices that you have logged into with your Expensify Account. Learn more', revoke: 'Revoke', unknownDevice: 'Unknown Device', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index cfcfe238925c..181984cb5e8c 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2101,7 +2101,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Gestión de dispositivos', - description: 'Gestiona todos los dispositivos en los que has iniciado sesión con tu cuenta de Expensify.', + description: + 'Gestiona todos los dispositivos en los que has iniciado sesión con tu cuenta de Expensify. Más información', revoke: 'Revocar', unknownDevice: 'Dispositivo Desconocido', }, diff --git a/src/languages/fr.ts b/src/languages/fr.ts index f217296b269d..2caddaf37e11 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -2219,7 +2219,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Gestion des appareils', - description: 'Gérez tous les appareils sur lesquels vous vous êtes connecté avec votre compte Expensify.', + description: + 'Gérez tous les appareils sur lesquels vous vous êtes connecté avec votre compte Expensify. En savoir plus', revoke: 'Révoquer', unknownDevice: 'Appareil Inconnu', }, diff --git a/src/languages/it.ts b/src/languages/it.ts index 04714349e740..51da362c7bb4 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -2213,7 +2213,7 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Gestione dei dispositivi', - description: `Gestisci tutti i dispositivi su cui hai effettuato l'accesso con il tuo account Expensify.`, + description: `Gestisci tutti i dispositivi su cui hai effettuato l'accesso con il tuo account Expensify. Scopri di più`, revoke: 'Revoca', unknownDevice: 'Dispositivo Sconosciuto', }, diff --git a/src/languages/ja.ts b/src/languages/ja.ts index c6ee83df7138..d2a8ec8a40e8 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -2192,7 +2192,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'デバイス管理', - description: 'Expensifyアカウントでログインしたすべてのデバイスを管理します。', + description: + 'Expensifyアカウントでログインしたすべてのデバイスを管理します。詳細はこちら', revoke: '取り消す', unknownDevice: '不明なデバイス', }, diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 891386fd47b8..55a85a0891cb 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -2208,7 +2208,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Apparaatbeheer', - description: 'Beheer alle apparaten waarop u bent ingelogd met uw Expensify-account.', + description: + 'Beheer alle apparaten waarop u bent ingelogd met uw Expensify-account. Meer informatie', revoke: 'Intrekken', unknownDevice: 'Onbekend Apparaat', }, diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 91459e089731..b7c83b68eecd 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -2208,7 +2208,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Zarządzanie urządzeniami', - description: 'Zarządzaj wszystkimi urządzeniami, na których zalogowałeś się za pomocą swojego konta Expensify.', + description: + 'Zarządzaj wszystkimi urządzeniami, na których zalogowałeś się za pomocą swojego konta Expensify. Dowiedz się więcej', revoke: 'Cofnąć', unknownDevice: 'Nieznane Urządzenie', }, diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 535659f23f58..bfbf9613df7d 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -2205,7 +2205,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Gerenciamento de dispositivos', - description: 'Gerencie todos os dispositivos nos quais você fez login com sua conta do Expensify.', + description: + 'Gerencie todos os dispositivos nos quais você fez login com sua conta do Expensify. Saiba mais', revoke: 'Revogar', unknownDevice: 'Dispositivo Desconhecido', }, diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 3c9e8607e50e..1e95fd6224d7 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -2150,7 +2150,7 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: '设备管理', - description: '管理您使用 Expensify 账户登录过的所有设备。', + description: '管理您使用 Expensify 账户登录过的所有设备。了解更多', revoke: '撤销', unknownDevice: '未知设备', }, diff --git a/src/pages/settings/Security/DeviceManagementPage.tsx b/src/pages/settings/Security/DeviceManagementPage.tsx index 3f4b2c263f08..2e9349aefaf1 100644 --- a/src/pages/settings/Security/DeviceManagementPage.tsx +++ b/src/pages/settings/Security/DeviceManagementPage.tsx @@ -6,6 +6,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import RenderHTML from '@components/RenderHTML'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; @@ -61,7 +62,9 @@ function DeviceManagementPage() { title={translate('deviceManagementPage.title')} onBackButtonPress={Navigation.goBack} /> - {translate('deviceManagementPage.description')} + + + Date: Thu, 21 May 2026 16:10:58 +0000 Subject: [PATCH 2/4] Update translations for deviceManagementPage description Co-authored-by: Andrew Rosiclair --- src/languages/de.ts | 2 +- src/languages/it.ts | 3 ++- src/languages/ja.ts | 2 +- src/languages/nl.ts | 2 +- src/languages/pl.ts | 2 +- src/languages/pt-BR.ts | 2 +- src/languages/zh-hans.ts | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 26d6fab657b1..a9283bc58ecb 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -2215,7 +2215,7 @@ const translations: TranslationDeepObject = { deviceManagementPage: { title: 'Geräteverwaltung', description: - 'Verwalten Sie alle Geräte, auf denen Sie sich mit Ihrem Expensify-Konto angemeldet haben. Weitere Informationen', + 'Verwalten Sie alle Geräte, bei denen Sie sich mit Ihrem Expensify Konto angemeldet haben. Erfahren Sie mehr', revoke: 'Widerrufen', unknownDevice: 'Unbekanntes Gerät', }, diff --git a/src/languages/it.ts b/src/languages/it.ts index 51da362c7bb4..8b11e289fbe5 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -2213,7 +2213,8 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: 'Gestione dei dispositivi', - description: `Gestisci tutti i dispositivi su cui hai effettuato l'accesso con il tuo account Expensify. Scopri di più`, + description: + 'Gestisci tutti i dispositivi su cui hai effettuato l\'accesso con il tuo account Expensify. Scopri di più', revoke: 'Revoca', unknownDevice: 'Dispositivo Sconosciuto', }, diff --git a/src/languages/ja.ts b/src/languages/ja.ts index d2a8ec8a40e8..b0d9262e2288 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -2193,7 +2193,7 @@ const translations: TranslationDeepObject = { deviceManagementPage: { title: 'デバイス管理', description: - 'Expensifyアカウントでログインしたすべてのデバイスを管理します。詳細はこちら', + 'Expensify アカウントでログインしているすべてのデバイスを管理できます。詳しくはこちら', revoke: '取り消す', unknownDevice: '不明なデバイス', }, diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 55a85a0891cb..de528bc2605c 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -2209,7 +2209,7 @@ const translations: TranslationDeepObject = { deviceManagementPage: { title: 'Apparaatbeheer', description: - 'Beheer alle apparaten waarop u bent ingelogd met uw Expensify-account. Meer informatie', + 'Beheer alle apparaten waarop je bent ingelogd met je Expensify-account. Meer informatie', revoke: 'Intrekken', unknownDevice: 'Onbekend Apparaat', }, diff --git a/src/languages/pl.ts b/src/languages/pl.ts index b7c83b68eecd..671e125a74bf 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -2209,7 +2209,7 @@ const translations: TranslationDeepObject = { deviceManagementPage: { title: 'Zarządzanie urządzeniami', description: - 'Zarządzaj wszystkimi urządzeniami, na których zalogowałeś się za pomocą swojego konta Expensify. Dowiedz się więcej', + 'Zarządzaj wszystkimi urządzeniami, na które zalogowałeś(-aś) się za pomocą konta Expensify. Dowiedz się więcej', revoke: 'Cofnąć', unknownDevice: 'Nieznane Urządzenie', }, diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index bfbf9613df7d..349af7964e71 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -2206,7 +2206,7 @@ const translations: TranslationDeepObject = { deviceManagementPage: { title: 'Gerenciamento de dispositivos', description: - 'Gerencie todos os dispositivos nos quais você fez login com sua conta do Expensify. Saiba mais', + 'Gerencie todos os dispositivos nos quais você fez login com sua conta Expensify. Saiba mais', revoke: 'Revogar', unknownDevice: 'Dispositivo Desconhecido', }, diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 1e95fd6224d7..a6368929d929 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -2150,7 +2150,7 @@ const translations: TranslationDeepObject = { }, deviceManagementPage: { title: '设备管理', - description: '管理您使用 Expensify 账户登录过的所有设备。了解更多', + description: '管理所有已使用你的 Expensify 账户登录的设备。了解详情', revoke: '撤销', unknownDevice: '未知设备', }, From bcd9a40c4c978bf138b34f85be4071e5d43ec479 Mon Sep 17 00:00:00 2001 From: "Andrew Rosiclair (via MelvinBot)" Date: Thu, 21 May 2026 17:06:04 +0000 Subject: [PATCH 3/4] Move description into ListHeaderComponent to fix Android display The description text was rendered as a sibling View to FlashList, which caused it to be overlapped by FlashList's internal absolute positioning on Android. Moving it into ListHeaderComponent ensures it renders inside the FlashList scroll content. Co-authored-by: Andrew Rosiclair --- .../settings/Security/DeviceManagementPage.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pages/settings/Security/DeviceManagementPage.tsx b/src/pages/settings/Security/DeviceManagementPage.tsx index 2e9349aefaf1..526f96069172 100644 --- a/src/pages/settings/Security/DeviceManagementPage.tsx +++ b/src/pages/settings/Security/DeviceManagementPage.tsx @@ -1,6 +1,6 @@ import {FlashList} from '@shopify/flash-list'; import type {ListRenderItemInfo} from '@shopify/flash-list'; -import React from 'react'; +import React, {useMemo} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; @@ -30,6 +30,15 @@ function DeviceManagementPage() { const [logins] = useOnyx(ONYXKEYS.LOGINS, {selector: getDeviceLogins}); const [autoGeneratedLogin] = useOnyx(ONYXKEYS.CREDENTIALS, {selector: autoGeneratedLoginSelector}); + const listHeader = useMemo( + () => ( + + + + ), + [styles.pv3, translate], + ); + const renderItem = ({item}: ListRenderItemInfo) => { const {deviceName, deviceVersion, os, osVersion} = item.additionalData ?? {}; return ( @@ -62,15 +71,13 @@ function DeviceManagementPage() { title={translate('deviceManagementPage.title')} onBackButtonPress={Navigation.goBack} /> - - - ); From 91bfc2e38cb4393638fe47026c97c6d50ed2ac46 Mon Sep 17 00:00:00 2001 From: "Andrew Rosiclair (via MelvinBot)" Date: Thu, 21 May 2026 18:06:49 +0000 Subject: [PATCH 4/4] Remove redundant useMemo from listHeader React Compiler handles memoization automatically, making the manual useMemo wrapper unnecessary. Co-authored-by: Andrew Rosiclair --- .../settings/Security/DeviceManagementPage.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/pages/settings/Security/DeviceManagementPage.tsx b/src/pages/settings/Security/DeviceManagementPage.tsx index 526f96069172..f7b73da7b1fe 100644 --- a/src/pages/settings/Security/DeviceManagementPage.tsx +++ b/src/pages/settings/Security/DeviceManagementPage.tsx @@ -1,6 +1,6 @@ import {FlashList} from '@shopify/flash-list'; import type {ListRenderItemInfo} from '@shopify/flash-list'; -import React, {useMemo} from 'react'; +import React from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Button from '@components/Button'; @@ -30,13 +30,10 @@ function DeviceManagementPage() { const [logins] = useOnyx(ONYXKEYS.LOGINS, {selector: getDeviceLogins}); const [autoGeneratedLogin] = useOnyx(ONYXKEYS.CREDENTIALS, {selector: autoGeneratedLoginSelector}); - const listHeader = useMemo( - () => ( - - - - ), - [styles.pv3, translate], + const listHeader = ( + + + ); const renderItem = ({item}: ListRenderItemInfo) => {