From 6d708d726ddb7dfa74477bd0d67959514b028c41 Mon Sep 17 00:00:00 2001 From: Andrii Vitiv Date: Fri, 30 Aug 2024 14:46:42 +0300 Subject: [PATCH 1/3] Replace `withOnyx` with `useOnyx` --- src/Expensify.tsx | 76 +++++++---------------------------------------- 1 file changed, 11 insertions(+), 65 deletions(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index 10389f69a44c..788928b3b788 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -2,8 +2,7 @@ import {Audio} from 'expo-av'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {NativeEventSubscription} from 'react-native'; import {AppState, Linking, NativeModules, Platform} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; +import Onyx, {useOnyx} from 'react-native-onyx'; import ConfirmModal from './components/ConfirmModal'; import DeeplinkWrapper from './components/DeeplinkWrapper'; import EmojiPicker from './components/EmojiPicker/EmojiPicker'; @@ -42,7 +41,6 @@ import PopoverReportActionContextMenu from './pages/home/report/ContextMenu/Popo import * as ReportActionContextMenu from './pages/home/report/ContextMenu/ReportActionContextMenu'; import type {Route} from './ROUTES'; import ROUTES from './ROUTES'; -import type {ScreenShareRequest} from './types/onyx'; Onyx.registerLogger(({level, message}) => { if (level === 'alert') { @@ -55,31 +53,6 @@ Onyx.registerLogger(({level, message}) => { } }); -type ExpensifyOnyxProps = { - /** Whether the app is waiting for the server's response to determine if a room is public */ - isCheckingPublicRoom: OnyxEntry; - - /** Whether a new update is available and ready to install. */ - updateAvailable: OnyxEntry; - - /** Tells us if the sidebar has rendered */ - isSidebarLoaded: OnyxEntry; - - /** Information about a screen share call requested by a GuidesPlus agent */ - screenShareRequest: OnyxEntry; - - /** True when the user must update to the latest minimum version of the app */ - updateRequired: OnyxEntry; - - /** Whether we should display the notification alerting the user that focus mode has been auto-enabled */ - focusModeNotification: OnyxEntry; - - /** Last visited path in the app */ - lastVisitedPath: OnyxEntry; -}; - -type ExpensifyProps = ExpensifyOnyxProps; - // HybridApp needs access to SetStateAction in order to properly hide SplashScreen when React Native was booted before. type SplashScreenHiddenContextType = {isSplashHidden?: boolean; setIsSplashHidden: React.Dispatch>}; @@ -87,15 +60,7 @@ const SplashScreenHiddenContext = React.createContext {}, }); -function Expensify({ - isCheckingPublicRoom = true, - updateAvailable, - isSidebarLoaded = false, - screenShareRequest, - updateRequired = false, - focusModeNotification = false, - lastVisitedPath, -}: ExpensifyProps) { +function Expensify() { const appStateChangeListener = useRef(null); const [isNavigationReady, setIsNavigationReady] = useState(false); const [isOnyxMigrated, setIsOnyxMigrated] = useState(false); @@ -106,6 +71,13 @@ function Expensify({ const [session] = useOnyx(ONYXKEYS.SESSION); const [lastRoute] = useOnyx(ONYXKEYS.LAST_ROUTE); const [shouldShowRequire2FAModal, setShouldShowRequire2FAModal] = useState(false); + const [isCheckingPublicRoom] = useOnyx(ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, {initWithStoredValues: false, initialValue: true}); + const [updateAvailable] = useOnyx(ONYXKEYS.UPDATE_AVAILABLE, {initWithStoredValues: false}); + const [updateRequired] = useOnyx(ONYXKEYS.UPDATE_REQUIRED, {initWithStoredValues: false, initialValue: false}); + const [isSidebarLoaded] = useOnyx(ONYXKEYS.IS_SIDEBAR_LOADED, {initialValue: false}); + const [screenShareRequest] = useOnyx(ONYXKEYS.SCREEN_SHARE_REQUEST); + const [focusModeNotification] = useOnyx(ONYXKEYS.FOCUS_MODE_NOTIFICATION, {initWithStoredValues: false, initialValue: false}); + const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH); useEffect(() => { if (!account?.needsTwoFactorAuthSetup || account.requiresTwoFactorAuth) { @@ -182,7 +154,7 @@ function Expensify({ Log.info('[BootSplash] splash screen status', false, {appState, status}); if (status === 'visible') { - const propsToLog: Omit = { + const propsToLog = { isCheckingPublicRoom, updateRequired, updateAvailable, @@ -322,32 +294,6 @@ function Expensify({ Expensify.displayName = 'Expensify'; -export default withOnyx({ - isCheckingPublicRoom: { - key: ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, - initWithStoredValues: false, - }, - updateAvailable: { - key: ONYXKEYS.UPDATE_AVAILABLE, - initWithStoredValues: false, - }, - updateRequired: { - key: ONYXKEYS.UPDATE_REQUIRED, - initWithStoredValues: false, - }, - isSidebarLoaded: { - key: ONYXKEYS.IS_SIDEBAR_LOADED, - }, - screenShareRequest: { - key: ONYXKEYS.SCREEN_SHARE_REQUEST, - }, - focusModeNotification: { - key: ONYXKEYS.FOCUS_MODE_NOTIFICATION, - initWithStoredValues: false, - }, - lastVisitedPath: { - key: ONYXKEYS.LAST_VISITED_PATH, - }, -})(Expensify); +export default Expensify; export {SplashScreenHiddenContext}; From 60ecde92f38c704d694f2e0ea070c5559756b321 Mon Sep 17 00:00:00 2001 From: Andrii Vitiv Date: Fri, 30 Aug 2024 14:48:54 +0300 Subject: [PATCH 2/3] Fix crash when report is not yet loaded --- src/pages/home/ReportScreen.tsx | 4 ++-- src/pages/home/report/ReportActionItem.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 56b9cf970d54..9e8c46692bbd 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -121,7 +121,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {allowStaleData: true, initialValue: {}}); const [betas] = useOnyx(ONYXKEYS.BETAS); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const [parentReportAction] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportOnyx?.parentReportID || 0}`, { + const [parentReportAction] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportOnyx?.parentReportID || -1}`, { canEvict: false, selector: (parentReportActions) => getParentReportAction(parentReportActions, reportOnyx?.parentReportActionID ?? ''), }); @@ -132,7 +132,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const isDeletedParentAction = ReportActionsUtils.isDeletedParentAction(parentReportAction); const prevIsDeletedParentAction = usePrevious(isDeletedParentAction); - const isLoadingReportOnyx = isLoadingOnyxValue(reportResult); + const isLoadingReportOnyx = !reportOnyx || Object.keys(reportOnyx).length === 0 || isLoadingOnyxValue(reportResult); const permissions = useDeepCompareRef(reportOnyx?.permissions); useEffect(() => { diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index bd19dff42038..db1af55b59f7 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -188,7 +188,7 @@ function ReportActionItem({ }); const theme = useTheme(); const styles = useThemeStyles(); - const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID ?? -1}`); + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID || -1}`); const StyleUtils = useStyleUtils(); const personalDetails = usePersonalDetails() || CONST.EMPTY_OBJECT; const [isContextMenuActive, setIsContextMenuActive] = useState(() => ReportActionContextMenu.isActiveReportAction(action.reportActionID)); From 8ad5ece1e44b3657f0d3ecb8383a5ef5d4897c12 Mon Sep 17 00:00:00 2001 From: Andrii Vitiv Date: Fri, 6 Sep 2024 16:49:38 +0300 Subject: [PATCH 3/3] Revert "Replace `withOnyx` with `useOnyx`" --- src/Expensify.tsx | 76 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index eba4f9e2007a..62e7839b21f0 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -2,7 +2,8 @@ import {Audio} from 'expo-av'; import React, {useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {NativeEventSubscription} from 'react-native'; import {AppState, Linking, NativeModules, Platform} from 'react-native'; -import Onyx, {useOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import Onyx, {useOnyx, withOnyx} from 'react-native-onyx'; import ConfirmModal from './components/ConfirmModal'; import DeeplinkWrapper from './components/DeeplinkWrapper'; import EmojiPicker from './components/EmojiPicker/EmojiPicker'; @@ -42,6 +43,7 @@ import * as ReportActionContextMenu from './pages/home/report/ContextMenu/Report import type {Route} from './ROUTES'; import ROUTES from './ROUTES'; import SplashScreenStateContext from './SplashScreenStateContext'; +import type {ScreenShareRequest} from './types/onyx'; Onyx.registerLogger(({level, message}) => { if (level === 'alert') { @@ -54,7 +56,40 @@ Onyx.registerLogger(({level, message}) => { } }); -function Expensify() { +type ExpensifyOnyxProps = { + /** Whether the app is waiting for the server's response to determine if a room is public */ + isCheckingPublicRoom: OnyxEntry; + + /** Whether a new update is available and ready to install. */ + updateAvailable: OnyxEntry; + + /** Tells us if the sidebar has rendered */ + isSidebarLoaded: OnyxEntry; + + /** Information about a screen share call requested by a GuidesPlus agent */ + screenShareRequest: OnyxEntry; + + /** True when the user must update to the latest minimum version of the app */ + updateRequired: OnyxEntry; + + /** Whether we should display the notification alerting the user that focus mode has been auto-enabled */ + focusModeNotification: OnyxEntry; + + /** Last visited path in the app */ + lastVisitedPath: OnyxEntry; +}; + +type ExpensifyProps = ExpensifyOnyxProps; + +function Expensify({ + isCheckingPublicRoom = true, + updateAvailable, + isSidebarLoaded = false, + screenShareRequest, + updateRequired = false, + focusModeNotification = false, + lastVisitedPath, +}: ExpensifyProps) { const appStateChangeListener = useRef(null); const [isNavigationReady, setIsNavigationReady] = useState(false); const [isOnyxMigrated, setIsOnyxMigrated] = useState(false); @@ -66,13 +101,6 @@ function Expensify() { const [lastRoute] = useOnyx(ONYXKEYS.LAST_ROUTE); const [tryNewDotData] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT); const [shouldShowRequire2FAModal, setShouldShowRequire2FAModal] = useState(false); - const [isCheckingPublicRoom] = useOnyx(ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, {initWithStoredValues: false, initialValue: true}); - const [updateAvailable] = useOnyx(ONYXKEYS.UPDATE_AVAILABLE, {initWithStoredValues: false}); - const [updateRequired] = useOnyx(ONYXKEYS.UPDATE_REQUIRED, {initWithStoredValues: false, initialValue: false}); - const [isSidebarLoaded] = useOnyx(ONYXKEYS.IS_SIDEBAR_LOADED, {initialValue: false}); - const [screenShareRequest] = useOnyx(ONYXKEYS.SCREEN_SHARE_REQUEST); - const [focusModeNotification] = useOnyx(ONYXKEYS.FOCUS_MODE_NOTIFICATION, {initWithStoredValues: false, initialValue: false}); - const [lastVisitedPath] = useOnyx(ONYXKEYS.LAST_VISITED_PATH); useEffect(() => { if (!account?.needsTwoFactorAuthSetup || account.requiresTwoFactorAuth) { @@ -150,7 +178,7 @@ function Expensify() { Log.info('[BootSplash] splash screen status', false, {appState, splashScreenState}); if (splashScreenState === CONST.BOOT_SPLASH_STATE.VISIBLE) { - const propsToLog = { + const propsToLog: Omit = { isCheckingPublicRoom, updateRequired, updateAvailable, @@ -286,4 +314,30 @@ function Expensify() { Expensify.displayName = 'Expensify'; -export default Expensify; +export default withOnyx({ + isCheckingPublicRoom: { + key: ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, + initWithStoredValues: false, + }, + updateAvailable: { + key: ONYXKEYS.UPDATE_AVAILABLE, + initWithStoredValues: false, + }, + updateRequired: { + key: ONYXKEYS.UPDATE_REQUIRED, + initWithStoredValues: false, + }, + isSidebarLoaded: { + key: ONYXKEYS.IS_SIDEBAR_LOADED, + }, + screenShareRequest: { + key: ONYXKEYS.SCREEN_SHARE_REQUEST, + }, + focusModeNotification: { + key: ONYXKEYS.FOCUS_MODE_NOTIFICATION, + initWithStoredValues: false, + }, + lastVisitedPath: { + key: ONYXKEYS.LAST_VISITED_PATH, + }, +})(Expensify);