From eda362c6a1f48eed062cf1b68a52fc595cdd6612 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Wed, 14 Jan 2026 17:46:36 +0100 Subject: [PATCH 1/6] Add warning for ongoing trip before signing out - GPS --- src/languages/de.ts | 5 + src/languages/en.ts | 5 + src/languages/es.ts | 5 + src/languages/fr.ts | 5 + src/languages/it.ts | 5 + src/languages/ja.ts | 5 + src/languages/nl.ts | 5 + src/languages/pl.ts | 5 + src/languages/pt-BR.ts | 5 + src/languages/zh-hans.ts | 5 + src/pages/settings/InitialSettingsPage.tsx | 468 ++++++++++----------- 11 files changed, 273 insertions(+), 245 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index ae25f3d1b9f53..ade7c8fc17b02 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7990,6 +7990,11 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`, button: 'App herunterladen', }, notification: {title: 'GPS-Tracking läuft', body: 'Wechsel zur App, um abzuschließen'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/en.ts b/src/languages/en.ts index fa82fab9c8ec1..4d25a2d51cd1c 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -7080,6 +7080,11 @@ const translations = { title: 'GPS tracking in progress', body: 'Go to the app to finish', }, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, reportCardLostOrDamaged: { screenTitle: 'Report card lost or damaged', diff --git a/src/languages/es.ts b/src/languages/es.ts index 72da0a21314e8..dc4e20cb2ae5f 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -8079,6 +8079,11 @@ ${amount} para ${merchant} - ${date}`, title: 'Seguimiento GPS en curso', body: 'Ve a la app para finalizar', }, + signOutWarningTripInProgress: { + title: 'Seguimiento por GPS en curso', + prompt: '¿Seguro que quieres descartar el viaje y cerrar sesión?', + confirm: 'Descartar y cerrar sesión', + }, }, }; diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 644dc0765184a..d05bb6e93b11d 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -7995,6 +7995,11 @@ Voici un *reçu test* pour vous montrer comment cela fonctionne :`, button: 'Télécharger l’application', }, notification: {title: 'Suivi GPS en cours', body: 'Allez dans l’application pour terminer'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/it.ts b/src/languages/it.ts index ba43c1ed57200..2b59f62825aac 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -7972,6 +7972,11 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`, button: 'Scarica l’app', }, notification: {title: 'Tracciamento GPS in corso', body: "Vai all'app per completare"}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/ja.ts b/src/languages/ja.ts index d1d830cabedb2..a72e931de4010 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7891,6 +7891,11 @@ Expensify の使い方をお見せするための*テストレシート*がこ preciseLocationRequiredModal: {title: '正確な位置情報が必要です', prompt: 'GPS距離の追跡を開始するには、デバイスの設定で「正確な位置情報」を有効にしてください。'}, desktop: {title: 'スマートフォンで距離を記録する', subtitle: 'GPS で自動的にマイルまたはキロメートルを記録し、移動をすぐに経費に変換します。', button: 'アプリをダウンロード'}, notification: {title: 'GPS追跡を実行中', body: '完了するにはアプリに移動'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 3e670a6f34c4c..e08180c979653 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -7954,6 +7954,11 @@ Hier is een *testbon* om je te laten zien hoe het werkt:`, preciseLocationRequiredModal: {title: 'Precieze locatie vereist', prompt: 'Schakel "precieze locatie" in de instellingen van je apparaat in om GPS-afstandsregistratie te starten.'}, desktop: {title: 'Volg afstand op je telefoon', subtitle: 'Leg kilometers of mijlen automatisch vast met GPS en zet ritten direct om in uitgaven.', button: 'Download de app'}, notification: {title: 'GPS-tracking bezig', body: 'Ga naar de app om af te ronden'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/pl.ts b/src/languages/pl.ts index ea469d0a8c9b8..15e00013bcc2f 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7936,6 +7936,11 @@ Oto *paragon testowy*, który pokazuje, jak to działa:`, button: 'Pobierz aplikację', }, notification: {title: 'Śledzenie GPS w toku', body: 'Przejdź do aplikacji, aby zakończyć'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 6ed504b6715e8..dec148300686d 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -7948,6 +7948,11 @@ Aqui está um *recibo de teste* para mostrar como funciona:`, button: 'Baixar o app', }, notification: {title: 'Rastreamento de GPS em andamento', body: 'Vá para o app para finalizar'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index a4c9dafa67ebc..055cf9118c064 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -7742,6 +7742,11 @@ ${reportName} preciseLocationRequiredModal: {title: '需要精确位置', prompt: '请在设备设置中启用“精确位置”以开始 GPS 距离跟踪。'}, desktop: {title: '在手机上跟踪距离', subtitle: '使用 GPS 自动记录英里或公里,并将行程即时转换为报销费用。', button: '下载应用程序'}, notification: {title: '正在进行 GPS 跟踪', body: '前往应用完成'}, + signOutWarningTripInProgress: { + title: 'GPS tracking in progress', + prompt: 'Are you sure you want to discard the trip and sign out?', + confirm: 'Discard and sign out', + }, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index d3be766079bf6..6108cb1ed62cb 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -1,5 +1,6 @@ import {findFocusedRoute, useNavigationState, useRoute} from '@react-navigation/native'; import {differenceInDays} from 'date-fns'; +import {stopLocationUpdatesAsync} from 'expo-location'; import React, {useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; // eslint-disable-next-line no-restricted-imports import type {GestureResponderEvent, ScrollView as RNScrollView, ScrollViewProps, StyleProp, ViewStyle} from 'react-native'; @@ -32,6 +33,7 @@ import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {resetExitSurveyForm} from '@libs/actions/ExitSurvey'; +import {resetGPSDraftDetails} from '@libs/actions/GPSDraftDetails'; import {closeReactNativeApp} from '@libs/actions/HybridApp'; import {hasPartiallySetupBankAccount} from '@libs/BankAccountUtils'; import {checkIfFeedConnectionIsBroken, filterPersonalCards, hasPendingExpensifyCardAction} from '@libs/CardUtils'; @@ -42,6 +44,7 @@ import {getFreeTrialText, hasSubscriptionRedDotError} from '@libs/SubscriptionUt import {getProfilePageBrickRoadIndicator} from '@libs/UserUtils'; import type SETTINGS_TO_RHP from '@navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP'; import {showContextMenu} from '@pages/home/report/ContextMenu/ReportActionContextMenu'; +import {BACKGROUND_LOCATION_TRACKING_TASK_NAME} from '@pages/iou/request/step/IOURequestStepDistanceGPS/const'; import variables from '@styles/variables'; import {confirmReadyToOpenApp} from '@userActions/App'; import {openExternalLink, openOldDotLink} from '@userActions/Link'; @@ -131,6 +134,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr const isScreenFocused = useIsSidebarRouteActive(NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR, shouldUseNarrowLayout); const hasActivatedWallet = ([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM] as string[]).includes(userWallet?.tierName ?? ''); const [firstDayFreeTrial] = useOnyx(ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL, {canBeMissing: true}); + const [gpsDraftDetails] = useOnyx(ONYXKEYS.GPS_DRAFT_DETAILS, {canBeMissing: true}); const [lastDayFreeTrial] = useOnyx(ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL, {canBeMissing: true}); const [unsharedBankAccount] = useOnyx(ONYXKEYS.UNSHARE_BANK_ACCOUNT, {canBeMissing: true}); const privateSubscription = usePrivateSubscription(); @@ -189,276 +193,240 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr setShouldShowSignoutConfirmModal(value); }; - const signOut = useCallback( - (shouldForceSignout = false) => { - if (!network.isOffline || shouldForceSignout) { - return signOutAndRedirectToSignIn(); - } + const signOut = (shouldForceSignout = false) => { + if ((!network.isOffline && !gpsDraftDetails?.isTracking) || shouldForceSignout) { + return signOutAndRedirectToSignIn(); + } - // When offline, warn the user that any actions they took while offline will be lost if they sign out - toggleSignoutConfirmModal(true); - }, - [network.isOffline], - ); + // When offline, warn the user that any actions they took while offline will be lost if they sign out + toggleSignoutConfirmModal(true); + }; - const surveyCompletedWithinLastMonth = useMemo(() => { + const isSurveyCompletedWithinLastMonth = () => { const surveyThresholdInDays = 30; if (!tryNewDot?.classicRedirect?.timestamp || !tryNewDot?.classicRedirect?.dismissed) { return false; } const daysSinceLastSurvey = differenceInDays(new Date(), new Date(tryNewDot.classicRedirect.timestamp)); return daysSinceLastSurvey < surveyThresholdInDays; - }, [tryNewDot?.classicRedirect?.timestamp, tryNewDot?.classicRedirect?.dismissed]); + }; + + const surveyCompletedWithinLastMonth = isSurveyCompletedWithinLastMonth(); + + const profileBrickRoadIndicator = getProfilePageBrickRoadIndicator(loginList, privatePersonalDetails, vacationDelegate, session?.email); + + const accountMenuItemsDataItems: MenuData[] = [ + { + translationKey: 'common.profile', + icon: icons.Profile, + screenName: SCREENS.SETTINGS.PROFILE.ROOT, + brickRoadIndicator: profileBrickRoadIndicator, + action: () => Navigation.navigate(ROUTES.SETTINGS_PROFILE.getRoute()), + }, + { + translationKey: 'common.wallet', + icon: icons.Wallet, + screenName: SCREENS.SETTINGS.WALLET.ROOT, + brickRoadIndicator: walletBrickRoadIndicator, + action: () => Navigation.navigate(ROUTES.SETTINGS_WALLET), + badgeText: hasActivatedWallet ? convertToDisplayString(userWallet?.currentBalance) : undefined, + }, + { + translationKey: 'common.preferences', + icon: icons.Gear, + screenName: SCREENS.SETTINGS.PREFERENCES.ROOT, + action: () => Navigation.navigate(ROUTES.SETTINGS_PREFERENCES), + }, + { + translationKey: 'initialSettingsPage.security', + icon: icons.Lock, + screenName: SCREENS.SETTINGS.SECURITY, + action: () => Navigation.navigate(ROUTES.SETTINGS_SECURITY), + }, + ]; + + const subscriptionPlanItem: MenuData = { + translationKey: 'allSettingsScreen.subscription', + icon: icons.CreditCard, + screenName: SCREENS.SETTINGS.SUBSCRIPTION.ROOT, + brickRoadIndicator: + !!privateSubscription?.errors || hasSubscriptionRedDotError(stripeCustomerId, retryBillingSuccessful, billingDisputePending, retryBillingFailed, fundList, billingStatus) + ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR + : undefined, + badgeText: freeTrialText, + badgeStyle: freeTrialText ? styles.badgeSuccess : undefined, + action: () => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION.route), + }; /** - * Return a list of menu items data for account section - * @returns object with translationKey, style and items for the account section + * Object with translationKey, style and items for the account section */ - const accountMenuItemsData: Menu = useMemo(() => { - const profileBrickRoadIndicator = getProfilePageBrickRoadIndicator(loginList, privatePersonalDetails, vacationDelegate, session?.email); - const items: MenuData[] = [ - { - translationKey: 'common.profile', - icon: icons.Profile, - screenName: SCREENS.SETTINGS.PROFILE.ROOT, - brickRoadIndicator: profileBrickRoadIndicator, - action: () => Navigation.navigate(ROUTES.SETTINGS_PROFILE.getRoute()), - }, - { - translationKey: 'common.wallet', - icon: icons.Wallet, - screenName: SCREENS.SETTINGS.WALLET.ROOT, - brickRoadIndicator: walletBrickRoadIndicator, - action: () => Navigation.navigate(ROUTES.SETTINGS_WALLET), - badgeText: hasActivatedWallet ? convertToDisplayString(userWallet?.currentBalance) : undefined, + const accountMenuItemsData: Menu = { + sectionStyle: styles.accountSettingsSectionContainer, + sectionTranslationKey: 'initialSettingsPage.account', + items: subscriptionPlan ? [accountMenuItemsDataItems.at(0), subscriptionPlanItem, ...accountMenuItemsDataItems.slice(1)].filter((value) => !!value) : accountMenuItemsDataItems, + }; + + const classicRedirectMenuItem: MenuData | null = tryNewDot?.classicRedirect?.isLockedToNewDot + ? null + : { + translationKey: 'exitSurvey.goToExpensifyClassic', + icon: icons.ExpensifyLogoNew, + ...(CONFIG.IS_HYBRID_APP + ? { + action: () => closeReactNativeApp({shouldSetNVP: true}), + } + : { + action() { + if (surveyCompletedWithinLastMonth) { + openOldDotLink(CONST.OLDDOT_URLS.INBOX, true); + return; + } + + const shouldOpenSurveyReasonPage = tryNewDot?.classicRedirect?.dismissed === false; + + resetExitSurveyForm(() => { + if (shouldOpenSurveyReasonPage) { + Navigation.navigate(ROUTES.SETTINGS_EXIT_SURVEY_REASON); + return; + } + Navigation.navigate(ROUTES.SETTINGS_EXIT_SURVEY_CONFIRM.route); + }); + }, + }), + }; + + const signOutTranslationKey = isSupportAuthToken() && hasStashedSession() ? 'initialSettingsPage.restoreStashed' : 'initialSettingsPage.signOut'; + + const generalMenuItemsDataItems: MenuData[] = [ + ...(classicRedirectMenuItem && tryNewDot?.nudgeMigration ? [classicRedirectMenuItem] : []), + { + translationKey: 'initialSettingsPage.help', + icon: icons.QuestionMark, + iconRight: icons.NewWindow, + shouldShowRightIcon: true, + link: CONST.NEWHELP_URL, + action: () => { + openExternalLink(CONST.NEWHELP_URL); }, - { - translationKey: 'common.preferences', - icon: icons.Gear, - screenName: SCREENS.SETTINGS.PREFERENCES.ROOT, - action: () => Navigation.navigate(ROUTES.SETTINGS_PREFERENCES), + }, + { + translationKey: 'initialSettingsPage.whatIsNew', + icon: icons.TreasureChest, + iconRight: icons.NewWindow, + shouldShowRightIcon: true, + link: CONST.WHATS_NEW_URL, + action: () => { + openExternalLink(CONST.WHATS_NEW_URL); }, - { - translationKey: 'initialSettingsPage.security', - icon: icons.Lock, - screenName: SCREENS.SETTINGS.SECURITY, - action: () => Navigation.navigate(ROUTES.SETTINGS_SECURITY), + }, + { + translationKey: 'initialSettingsPage.about', + icon: icons.Info, + screenName: SCREENS.SETTINGS.ABOUT, + action: () => Navigation.navigate(ROUTES.SETTINGS_ABOUT), + }, + { + translationKey: 'initialSettingsPage.aboutPage.troubleshoot', + icon: icons.Lightbulb, + screenName: SCREENS.SETTINGS.TROUBLESHOOT, + action: () => Navigation.navigate(ROUTES.SETTINGS_TROUBLESHOOT), + }, + { + translationKey: 'sidebarScreen.saveTheWorld', + icon: icons.Heart, + screenName: SCREENS.SETTINGS.SAVE_THE_WORLD, + action: () => Navigation.navigate(ROUTES.SETTINGS_SAVE_THE_WORLD), + }, + { + translationKey: signOutTranslationKey, + icon: icons.Exit, + action: () => { + signOut(false); }, - ]; - - if (subscriptionPlan) { - items.splice(1, 0, { - translationKey: 'allSettingsScreen.subscription', - icon: icons.CreditCard, - screenName: SCREENS.SETTINGS.SUBSCRIPTION.ROOT, - brickRoadIndicator: - !!privateSubscription?.errors || hasSubscriptionRedDotError(stripeCustomerId, retryBillingSuccessful, billingDisputePending, retryBillingFailed, fundList, billingStatus) - ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR - : undefined, - badgeText: freeTrialText, - badgeStyle: freeTrialText ? styles.badgeSuccess : undefined, - action: () => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION.route), - }); - } - - return { - sectionStyle: styles.accountSettingsSectionContainer, - sectionTranslationKey: 'initialSettingsPage.account', - items, - }; - }, [ - loginList, - privatePersonalDetails, - vacationDelegate, - session?.email, - icons.Profile, - icons.Gear, - icons.Lock, - icons.Wallet, - icons.CreditCard, - walletBrickRoadIndicator, - hasActivatedWallet, - userWallet?.currentBalance, - subscriptionPlan, - styles.accountSettingsSectionContainer, - styles.badgeSuccess, - privateSubscription?.errors, - stripeCustomerId, - retryBillingSuccessful, - billingDisputePending, - retryBillingFailed, - fundList, - freeTrialText, - billingStatus, - ]); - - const classicRedirectMenuItem: MenuData | null = useMemo(() => { - if (tryNewDot?.classicRedirect?.isLockedToNewDot) { - return null; - } - - const shouldOpenSurveyReasonPage = tryNewDot?.classicRedirect?.dismissed === false; - - return { - translationKey: 'exitSurvey.goToExpensifyClassic', - icon: icons.ExpensifyLogoNew, - ...(CONFIG.IS_HYBRID_APP - ? { - action: () => closeReactNativeApp({shouldSetNVP: true}), - } - : { - action() { - if (surveyCompletedWithinLastMonth) { - openOldDotLink(CONST.OLDDOT_URLS.INBOX, true); - return; - } - - resetExitSurveyForm(() => { - if (shouldOpenSurveyReasonPage) { - Navigation.navigate(ROUTES.SETTINGS_EXIT_SURVEY_REASON); - return; - } - Navigation.navigate(ROUTES.SETTINGS_EXIT_SURVEY_CONFIRM.route); - }); - }, - }), - }; - }, [tryNewDot?.classicRedirect?.isLockedToNewDot, tryNewDot?.classicRedirect?.dismissed, icons.ExpensifyLogoNew, surveyCompletedWithinLastMonth]); + }, + ]; /** - * Return a list of menu items data for general section - * @returns object with translationKey, style and items for the general section + * Object with translationKey, style and items for the general section */ - const generalMenuItemsData: Menu = useMemo(() => { - const signOutTranslationKey = isSupportAuthToken() && hasStashedSession() ? 'initialSettingsPage.restoreStashed' : 'initialSettingsPage.signOut'; - return { - sectionStyle: { - ...styles.pt4, - }, - sectionTranslationKey: 'initialSettingsPage.general', - items: [ - ...(classicRedirectMenuItem && tryNewDot?.nudgeMigration ? [classicRedirectMenuItem] : []), - { - translationKey: 'initialSettingsPage.help', - icon: icons.QuestionMark, - iconRight: icons.NewWindow, - shouldShowRightIcon: true, - link: CONST.NEWHELP_URL, - action: () => { - openExternalLink(CONST.NEWHELP_URL); - }, - }, - { - translationKey: 'initialSettingsPage.whatIsNew', - icon: icons.TreasureChest, - iconRight: icons.NewWindow, - shouldShowRightIcon: true, - link: CONST.WHATS_NEW_URL, - action: () => { - openExternalLink(CONST.WHATS_NEW_URL); - }, - }, - { - translationKey: 'initialSettingsPage.about', - icon: icons.Info, - screenName: SCREENS.SETTINGS.ABOUT, - action: () => Navigation.navigate(ROUTES.SETTINGS_ABOUT), - }, - { - translationKey: 'initialSettingsPage.aboutPage.troubleshoot', - icon: icons.Lightbulb, - screenName: SCREENS.SETTINGS.TROUBLESHOOT, - action: () => Navigation.navigate(ROUTES.SETTINGS_TROUBLESHOOT), - }, - { - translationKey: 'sidebarScreen.saveTheWorld', - icon: icons.Heart, - screenName: SCREENS.SETTINGS.SAVE_THE_WORLD, - action: () => Navigation.navigate(ROUTES.SETTINGS_SAVE_THE_WORLD), - }, - { - translationKey: signOutTranslationKey, - icon: icons.Exit, - action: () => { - signOut(false); - }, - }, - ], - }; - }, [icons, styles.pt4, classicRedirectMenuItem, tryNewDot?.nudgeMigration, signOut]); + const generalMenuItemsData: Menu = { + sectionStyle: { + ...styles.pt4, + }, + sectionTranslationKey: 'initialSettingsPage.general', + items: generalMenuItemsDataItems, + }; /** * Return JSX.Element with menu items * @param menuItemsData list with menu items data * @returns the menu items for passed data */ - const getMenuItemsSection = useCallback( - (menuItemsData: Menu) => { - const openPopover = (link: string | (() => Promise) | undefined, event: GestureResponderEvent | MouseEvent) => { - if (!isScreenFocused) { - return; - } - - if (typeof link === 'function') { - link?.()?.then((url) => - showContextMenu({ - type: CONST.CONTEXT_MENU_TYPES.LINK, - event, - selection: url, - contextMenuAnchor: popoverAnchor.current, - }), - ); - } else if (link) { + const getMenuItemsSection = (menuItemsData: Menu) => { + const openPopover = (link: string | (() => Promise) | undefined, event: GestureResponderEvent | MouseEvent) => { + if (!isScreenFocused) { + return; + } + + if (typeof link === 'function') { + link?.()?.then((url) => showContextMenu({ type: CONST.CONTEXT_MENU_TYPES.LINK, event, - selection: link, + selection: url, contextMenuAnchor: popoverAnchor.current, - }); - } - }; - - return ( - - {translate(menuItemsData.sectionTranslationKey)} - {menuItemsData.items.map((item) => { - const keyTitle = item.translationKey ? translate(item.translationKey) : item.title; - const isFocused = focusedRouteName ? focusedRouteName === item.screenName : false; - - return ( - openPopover(item.link, event) : undefined} - focused={isFocused} - isPaneMenu - iconRight={item.iconRight} - shouldShowRightIcon={item.shouldShowRightIcon} - shouldIconUseAutoWidthStyle - /> - ); - })} - - ); - }, - [styles.pb4, styles.mh3, styles.sectionTitle, styles.sectionMenuItem, translate, isScreenFocused, focusedRouteName, isExecuting, singleExecution], - ); + }), + ); + } else if (link) { + showContextMenu({ + type: CONST.CONTEXT_MENU_TYPES.LINK, + event, + selection: link, + contextMenuAnchor: popoverAnchor.current, + }); + } + }; - const accountMenuItems = useMemo(() => getMenuItemsSection(accountMenuItemsData), [accountMenuItemsData, getMenuItemsSection]); - const generalMenuItems = useMemo(() => getMenuItemsSection(generalMenuItemsData), [generalMenuItemsData, getMenuItemsSection]); + return ( + + {translate(menuItemsData.sectionTranslationKey)} + {menuItemsData.items.map((item) => { + const keyTitle = item.translationKey ? translate(item.translationKey) : item.title; + const isFocused = focusedRouteName ? focusedRouteName === item.screenName : false; + + return ( + openPopover(item.link, event) : undefined} + focused={isFocused} + isPaneMenu + iconRight={item.iconRight} + shouldShowRightIcon={item.shouldShowRightIcon} + shouldIconUseAutoWidthStyle + /> + ); + })} + + ); + }; + + const accountMenuItems = getMenuItemsSection(accountMenuItemsData); + const generalMenuItems = getMenuItemsSection(generalMenuItemsData); const headerContent = ( @@ -517,6 +485,10 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr scrollViewRef.current.scrollTo({y: scrollOffset, animated: false}); }, [getScrollOffset, route]); + const confirmModalTitle = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.title') : translate('common.areYouSure'); + const confirmModalPrompt = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.prompt') : translate('initialSettingsPage.signOutConfirmationText'); + const confirmModalConfirmText = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.confirm') : translate('initialSettingsPage.signOut'); + return ( { + if (gpsDraftDetails?.isTracking) { + stopLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKING_TASK_NAME).catch((error) => + console.error('[GPS distance request] Failed to stop location tracking', error), + ); + resetGPSDraftDetails(); + } toggleSignoutConfirmModal(false); shouldLogout.current = true; }} From 8e363909ec78562abd533d46459c970b7f51fea1 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Thu, 15 Jan 2026 11:22:23 +0100 Subject: [PATCH 2/6] Translations --- src/languages/de.ts | 8 ++------ src/languages/fr.ts | 8 ++------ src/languages/it.ts | 10 +++------- src/languages/ja.ts | 8 ++------ src/languages/nl.ts | 10 +++------- src/languages/pl.ts | 8 ++------ src/languages/pt-BR.ts | 10 +++------- src/languages/zh-hans.ts | 10 +++------- 8 files changed, 20 insertions(+), 52 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index ade7c8fc17b02..2e6deecc55311 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -7989,12 +7989,8 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`, subtitle: 'Protokolliere Meilen oder Kilometer automatisch mit GPS und verwandle Fahrten sofort in Ausgaben.', button: 'App herunterladen', }, - notification: {title: 'GPS-Tracking läuft', body: 'Wechsel zur App, um abzuschließen'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'GPS-Tracking läuft', body: 'Zur App gehen, um abzuschließen'}, + signOutWarningTripInProgress: {title: 'GPS-Tracking läuft', prompt: 'Sind Sie sicher, dass Sie die Reise verwerfen und sich abmelden möchten?', confirm: 'Verwerfen und abmelden'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/fr.ts b/src/languages/fr.ts index d05bb6e93b11d..e24bb84a6ac6b 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -1194,7 +1194,7 @@ const translations: TranslationDeepObject = { other: 'Voulez-vous vraiment supprimer ces dépenses ?', }), deleteReport: 'Supprimer le rapport', - deleteReportConfirmation: 'Voulez-vous vraiment supprimer ce rapport ?', + deleteReportConfirmation: 'Voulez-vous vraiment supprimer ce rapport ?', settledExpensify: 'Payé', done: 'Terminé', settledElsewhere: 'Payé ailleurs', @@ -7995,11 +7995,7 @@ Voici un *reçu test* pour vous montrer comment cela fonctionne :`, button: 'Télécharger l’application', }, notification: {title: 'Suivi GPS en cours', body: 'Allez dans l’application pour terminer'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + signOutWarningTripInProgress: {title: 'Suivi GPS en cours', prompt: 'Voulez-vous vraiment abandonner le déplacement et vous déconnecter ?', confirm: 'Ignorer et se déconnecter'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/it.ts b/src/languages/it.ts index 2b59f62825aac..3500157bc1ffc 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -1189,7 +1189,7 @@ const translations: TranslationDeepObject = { one: 'Sei sicuro di voler eliminare questa spesa?', other: 'Sei sicuro di voler eliminare queste spese?', }), - deleteReport: 'Elimina resoconto', + deleteReport: 'Elimina report', deleteReportConfirmation: 'Sei sicuro di voler eliminare questo report?', settledExpensify: 'Pagato', done: 'Fatto', @@ -7971,12 +7971,8 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`, subtitle: 'Registra automaticamente miglia o chilometri con il GPS e trasforma i viaggi in spese all’istante.', button: 'Scarica l’app', }, - notification: {title: 'Tracciamento GPS in corso', body: "Vai all'app per completare"}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'Tracciamento GPS in corso', body: "Vai all'app per terminare"}, + signOutWarningTripInProgress: {title: 'Tracciamento GPS in corso', prompt: 'Sei sicuro di voler annullare il viaggio e disconnetterti?', confirm: 'Annulla e disconnettiti'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/ja.ts b/src/languages/ja.ts index a72e931de4010..f02fcd5a2676a 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -7890,12 +7890,8 @@ Expensify の使い方をお見せするための*テストレシート*がこ }, preciseLocationRequiredModal: {title: '正確な位置情報が必要です', prompt: 'GPS距離の追跡を開始するには、デバイスの設定で「正確な位置情報」を有効にしてください。'}, desktop: {title: 'スマートフォンで距離を記録する', subtitle: 'GPS で自動的にマイルまたはキロメートルを記録し、移動をすぐに経費に変換します。', button: 'アプリをダウンロード'}, - notification: {title: 'GPS追跡を実行中', body: '完了するにはアプリに移動'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'GPS追跡を実行中', body: '完了するにはアプリに移動してください'}, + signOutWarningTripInProgress: {title: 'GPS追跡を実行中', prompt: 'この出張を破棄してサインアウトしてもよろしいですか?', confirm: '破棄してサインアウト'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/nl.ts b/src/languages/nl.ts index e08180c979653..43304bd44af5c 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -1190,7 +1190,7 @@ const translations: TranslationDeepObject = { other: 'Weet je zeker dat je deze uitgaven wilt verwijderen?', }), deleteReport: 'Rapport verwijderen', - deleteReportConfirmation: 'Weet u zeker dat u dit rapport wilt verwijderen?', + deleteReportConfirmation: 'Weet je zeker dat je dit rapport wilt verwijderen?', settledExpensify: 'Betaald', done: 'Gereed', settledElsewhere: 'Elders betaald', @@ -7953,12 +7953,8 @@ Hier is een *testbon* om je te laten zien hoe het werkt:`, }, preciseLocationRequiredModal: {title: 'Precieze locatie vereist', prompt: 'Schakel "precieze locatie" in de instellingen van je apparaat in om GPS-afstandsregistratie te starten.'}, desktop: {title: 'Volg afstand op je telefoon', subtitle: 'Leg kilometers of mijlen automatisch vast met GPS en zet ritten direct om in uitgaven.', button: 'Download de app'}, - notification: {title: 'GPS-tracking bezig', body: 'Ga naar de app om af te ronden'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'GPS-tracking bezig', body: 'Ga naar de app om te voltooien'}, + signOutWarningTripInProgress: {title: 'GPS-tracking bezig', prompt: 'Weet je zeker dat je de reis wilt weggooien en uitloggen?', confirm: 'Verwerpen en afmelden'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 15e00013bcc2f..27d82d0742e72 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -7935,12 +7935,8 @@ Oto *paragon testowy*, który pokazuje, jak to działa:`, subtitle: 'Automatycznie rejestruj mile lub kilometry za pomocą GPS i natychmiast zamieniaj podróże w wydatki.', button: 'Pobierz aplikację', }, - notification: {title: 'Śledzenie GPS w toku', body: 'Przejdź do aplikacji, aby zakończyć'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'Śledzenie GPS w toku', body: 'Przejdź do aplikacji, aby dokończyć'}, + signOutWarningTripInProgress: {title: 'Śledzenie GPS w toku', prompt: 'Czy na pewno chcesz porzucić podróż i się wylogować?', confirm: 'Odrzuć i wyloguj się'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index dec148300686d..433501641794a 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -1189,7 +1189,7 @@ const translations: TranslationDeepObject = { other: 'Tem certeza de que deseja excluir estas despesas?', }), deleteReport: 'Excluir relatório', - deleteReportConfirmation: 'Você tem certeza de que deseja excluir este relatório?', + deleteReportConfirmation: 'Tem certeza de que deseja excluir este relatório?', settledExpensify: 'Pago', done: 'Concluído', settledElsewhere: 'Pago em outro lugar', @@ -7947,12 +7947,8 @@ Aqui está um *recibo de teste* para mostrar como funciona:`, subtitle: 'Registre milhas ou quilômetros automaticamente com o GPS e transforme viagens em despesas instantaneamente.', button: 'Baixar o app', }, - notification: {title: 'Rastreamento de GPS em andamento', body: 'Vá para o app para finalizar'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'Rastreamento por GPS em andamento', body: 'Vá para o app para finalizar'}, + signOutWarningTripInProgress: {title: 'Rastreamento por GPS em andamento', prompt: 'Tem certeza de que deseja descartar a viagem e sair?', confirm: 'Descartar e sair'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 055cf9118c064..a9b4be126be1a 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -1172,7 +1172,7 @@ const translations: TranslationDeepObject = { other: '您确定要删除这些报销吗?', }), deleteReport: '删除报表', - deleteReportConfirmation: '您确定要删除此报表吗?', + deleteReportConfirmation: '您确定要删除此报告吗?', settledExpensify: '已支付', done: '完成', settledElsewhere: '在其他地方已支付', @@ -7741,12 +7741,8 @@ ${reportName} androidBackgroundLocationRequiredModal: {title: '需要后台位置访问权限', prompt: '请在设备设置中允许应用使用“始终允许”位置访问权限,以开始 GPS 距离跟踪。'}, preciseLocationRequiredModal: {title: '需要精确位置', prompt: '请在设备设置中启用“精确位置”以开始 GPS 距离跟踪。'}, desktop: {title: '在手机上跟踪距离', subtitle: '使用 GPS 自动记录英里或公里,并将行程即时转换为报销费用。', button: '下载应用程序'}, - notification: {title: '正在进行 GPS 跟踪', body: '前往应用完成'}, - signOutWarningTripInProgress: { - title: 'GPS tracking in progress', - prompt: 'Are you sure you want to discard the trip and sign out?', - confirm: 'Discard and sign out', - }, + notification: {title: 'GPS 跟踪进行中', body: '前往应用完成'}, + signOutWarningTripInProgress: {title: 'GPS 跟踪进行中', prompt: '您确定要放弃此行程并登出吗?', confirm: '放弃并退出'}, }, }; // IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts, From fcabd02c61861e30bb5965e90bf1056a652c1a8e Mon Sep 17 00:00:00 2001 From: GCyganek Date: Tue, 20 Jan 2026 14:52:35 +0100 Subject: [PATCH 3/6] Revert comments changes --- src/pages/settings/InitialSettingsPage.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index c3073cf258204..f3d1694a2382d 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -203,7 +203,8 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr } /** - * Object with translationKey, style and items for the account section + * Return a list of menu items data for account section + * @returns object with translationKey, style and items for the account section */ const profileBrickRoadIndicator = getProfilePageBrickRoadIndicator(loginList, privatePersonalDetails, vacationDelegate, session?.email); const accountItems: MenuData[] = [ @@ -288,7 +289,8 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr } /** - * Object with translationKey, style and items for the general section + * Return a list of menu items data for account section + * @returns object with translationKey, style and items for the account section */ const signOutTranslationKey = isSupportAuthToken() && hasStashedSession() ? 'initialSettingsPage.restoreStashed' : 'initialSettingsPage.signOut'; const generalMenuItemsData: Menu = { From 106da88cd390a275d56b3e5056f4fe84379cf8b3 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Tue, 20 Jan 2026 16:37:13 +0100 Subject: [PATCH 4/6] Revert comments changes --- src/pages/settings/InitialSettingsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index f3d1694a2382d..b8f3a3d06ea96 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -289,8 +289,8 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr } /** - * Return a list of menu items data for account section - * @returns object with translationKey, style and items for the account section + * Return a list of menu items data for general section + * @returns object with translationKey, style and items for the general section */ const signOutTranslationKey = isSupportAuthToken() && hasStashedSession() ? 'initialSettingsPage.restoreStashed' : 'initialSettingsPage.signOut'; const generalMenuItemsData: Menu = { From 7b7e180f3a10276f0b4901700938e4c7a3f377cc Mon Sep 17 00:00:00 2001 From: GCyganek Date: Tue, 20 Jan 2026 17:23:07 +0100 Subject: [PATCH 5/6] Add isTracking selector and await stopLocationUpdates before reseting gps draft details --- src/pages/settings/InitialSettingsPage.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index b8f3a3d06ea96..9003f1d316b1d 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -58,6 +58,7 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; +import type {GpsDraftDetails} from '@src/types/onyx'; import type {Icon as TIcon} from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; @@ -88,6 +89,8 @@ type MenuData = { type Menu = {sectionStyle: StyleProp; sectionTranslationKey: TranslationPaths; items: MenuData[]}; +const isTrackingSelector = (gpsDraftDetails?: GpsDraftDetails) => gpsDraftDetails?.isTracking; + function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPageProps) { const icons = useMemoizedLazyExpensifyIcons([ 'Gear', @@ -134,7 +137,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr const isScreenFocused = useIsSidebarRouteActive(NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR, shouldUseNarrowLayout); const hasActivatedWallet = ([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM] as string[]).includes(userWallet?.tierName ?? ''); const [firstDayFreeTrial] = useOnyx(ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL, {canBeMissing: true}); - const [gpsDraftDetails] = useOnyx(ONYXKEYS.GPS_DRAFT_DETAILS, {canBeMissing: true}); + const [isTrackingGPS] = useOnyx(ONYXKEYS.GPS_DRAFT_DETAILS, {canBeMissing: true, selector: isTrackingSelector}); const [lastDayFreeTrial] = useOnyx(ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL, {canBeMissing: true}); const [unsharedBankAccount] = useOnyx(ONYXKEYS.UNSHARE_BANK_ACCOUNT, {canBeMissing: true}); const privateSubscription = usePrivateSubscription(); @@ -187,7 +190,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr }; const signOut = (shouldForceSignout = false) => { - if ((!network.isOffline && !gpsDraftDetails?.isTracking) || shouldForceSignout) { + if ((!network.isOffline && isTrackingGPS) || shouldForceSignout) { return signOutAndRedirectToSignIn(); } @@ -472,9 +475,9 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr scrollViewRef.current.scrollTo({y: scrollOffset, animated: false}); }, [getScrollOffset, route]); - const confirmModalTitle = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.title') : translate('common.areYouSure'); - const confirmModalPrompt = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.prompt') : translate('initialSettingsPage.signOutConfirmationText'); - const confirmModalConfirmText = gpsDraftDetails?.isTracking ? translate('gps.signOutWarningTripInProgress.confirm') : translate('initialSettingsPage.signOut'); + const confirmModalTitle = isTrackingGPS ? translate('gps.signOutWarningTripInProgress.title') : translate('common.areYouSure'); + const confirmModalPrompt = isTrackingGPS ? translate('gps.signOutWarningTripInProgress.prompt') : translate('initialSettingsPage.signOutConfirmationText'); + const confirmModalConfirmText = isTrackingGPS ? translate('gps.signOutWarningTripInProgress.confirm') : translate('initialSettingsPage.signOut'); return ( { - if (gpsDraftDetails?.isTracking) { - stopLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKING_TASK_NAME).catch((error) => - console.error('[GPS distance request] Failed to stop location tracking', error), - ); - resetGPSDraftDetails(); + if (isTrackingGPS) { + stopLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKING_TASK_NAME) + .catch((error) => console.error('[GPS distance request] Failed to stop location tracking', error)) + .then(resetGPSDraftDetails); } toggleSignoutConfirmModal(false); shouldLogout.current = true; From 677dfac7bae6eccc65b30aae26b223d51fee8661 Mon Sep 17 00:00:00 2001 From: GCyganek Date: Wed, 21 Jan 2026 09:26:18 +0100 Subject: [PATCH 6/6] Changes according to feedback --- src/pages/settings/InitialSettingsPage.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index 9003f1d316b1d..0f506deaa8743 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -33,7 +33,6 @@ import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {resetExitSurveyForm} from '@libs/actions/ExitSurvey'; -import {resetGPSDraftDetails} from '@libs/actions/GPSDraftDetails'; import {closeReactNativeApp} from '@libs/actions/HybridApp'; import {hasPartiallySetupBankAccount} from '@libs/BankAccountUtils'; import {checkIfFeedConnectionIsBroken, filterPersonalCards, hasPendingExpensifyCardAction} from '@libs/CardUtils'; @@ -190,7 +189,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr }; const signOut = (shouldForceSignout = false) => { - if ((!network.isOffline && isTrackingGPS) || shouldForceSignout) { + if ((!network.isOffline && !isTrackingGPS) || shouldForceSignout) { return signOutAndRedirectToSignIn(); } @@ -506,9 +505,9 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr isVisible={shouldShowSignoutConfirmModal} onConfirm={() => { if (isTrackingGPS) { - stopLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKING_TASK_NAME) - .catch((error) => console.error('[GPS distance request] Failed to stop location tracking', error)) - .then(resetGPSDraftDetails); + stopLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKING_TASK_NAME).catch((error) => + console.error('[GPS distance request] Failed to stop location tracking', error), + ); } toggleSignoutConfirmModal(false); shouldLogout.current = true;