From 260c69aa70ec23f53f04b4a5c6296a57d7524fa0 Mon Sep 17 00:00:00 2001 From: eliran goshen Date: Tue, 14 Apr 2026 16:43:55 +0200 Subject: [PATCH 1/2] deferreing onyx calls --- .../ProductTrainingContext/index.tsx | 27 ++++++++++++++++--- .../ProductTrainingContextProvider.tsx | 2 +- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/components/ProductTrainingContext/index.tsx b/src/components/ProductTrainingContext/index.tsx index 100eb568e8dd..0d2a35fc0c63 100644 --- a/src/components/ProductTrainingContext/index.tsx +++ b/src/components/ProductTrainingContext/index.tsx @@ -47,11 +47,13 @@ type ProductTrainingContextConfig = { onShown?: () => void; }; -const ProductTrainingContext = createContext({ +const defaultProductTrainingContext: ProductTrainingContextType = { shouldRenderTooltip: () => false, registerTooltip: () => {}, unregisterTooltip: () => {}, -}); +}; + +const ProductTrainingContext = createContext(defaultProductTrainingContext); function ProductTrainingContextProvider({children}: ChildrenProps) { const [isLoadingApp = true] = useOnyx(ONYXKEYS.IS_LOADING_APP); @@ -369,4 +371,23 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou }; }; -export {ProductTrainingContextProvider, useProductTrainingContext}; +/** + * Deferred wrapper that skips the heavy Onyx subscriptions and policy iteration + * on the first render. Tooltips are never visible during the splash screen, so + * providing the default no-op context for the first frame is safe. + */ +function DeferredProductTrainingContextProvider({children}: ChildrenProps) { + const [isReady, setIsReady] = useState(false); + + useEffect(() => { + requestAnimationFrame(() => setIsReady(true)); + }, []); + + if (isReady) { + return {children}; + } + + return {children}; +} + +export {DeferredProductTrainingContextProvider as ProductTrainingContextProvider, ProductTrainingContextProvider as ImmediateProductTrainingContextProvider, useProductTrainingContext}; diff --git a/tests/ui/components/ProductTrainingContextProvider.tsx b/tests/ui/components/ProductTrainingContextProvider.tsx index 81791f0dc121..5aa3b5609ea5 100644 --- a/tests/ui/components/ProductTrainingContextProvider.tsx +++ b/tests/ui/components/ProductTrainingContextProvider.tsx @@ -2,7 +2,7 @@ import {render, renderHook} from '@testing-library/react-native'; import {createRef, useImperativeHandle} from 'react'; import type {Ref} from 'react'; import Onyx from 'react-native-onyx'; -import {ProductTrainingContextProvider, useProductTrainingContext} from '@components/ProductTrainingContext'; +import {ImmediateProductTrainingContextProvider as ProductTrainingContextProvider, useProductTrainingContext} from '@components/ProductTrainingContext'; import type {ProductTrainingTooltipName} from '@components/ProductTrainingContext/TOOLTIPS'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import DateUtils from '@libs/DateUtils'; From f9186cb994f6c59739835adb13d34565ac1312b5 Mon Sep 17 00:00:00 2001 From: eliran goshen Date: Tue, 14 Apr 2026 18:39:13 +0200 Subject: [PATCH 2/2] pr fix --- src/App.tsx | 2 -- .../ProductTrainingContext/index.tsx | 21 +------------------ .../Navigation/AppNavigator/AuthScreens.tsx | 2 ++ .../ProductTrainingContextProvider.tsx | 2 +- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8ef6d1a55f19..c5a82b0c582c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -28,7 +28,6 @@ import {ModalProvider} from './components/Modal/Global/ModalContext'; import NavigationBar from './components/NavigationBar'; import OnyxListItemProvider from './components/OnyxListItemProvider'; import PopoverContextProvider from './components/PopoverProvider'; -import {ProductTrainingContextProvider} from './components/ProductTrainingContext'; import SafeArea from './components/SafeArea'; import ScrollOffsetContextProvider from './components/ScrollOffsetContextProvider'; import {SearchRouterContextProvider} from './components/Search/SearchRouter/SearchRouterContext'; @@ -125,7 +124,6 @@ function App() { KeyboardStateProvider, KeyboardDismissibleFlatListContextProvider, SearchRouterContextProvider, - ProductTrainingContextProvider, InputBlurContextProvider, FullScreenBlockingViewContextProvider, FullScreenLoaderContextProvider, diff --git a/src/components/ProductTrainingContext/index.tsx b/src/components/ProductTrainingContext/index.tsx index 0d2a35fc0c63..6499d3481827 100644 --- a/src/components/ProductTrainingContext/index.tsx +++ b/src/components/ProductTrainingContext/index.tsx @@ -371,23 +371,4 @@ const useProductTrainingContext = (tooltipName: ProductTrainingTooltipName, shou }; }; -/** - * Deferred wrapper that skips the heavy Onyx subscriptions and policy iteration - * on the first render. Tooltips are never visible during the splash screen, so - * providing the default no-op context for the first frame is safe. - */ -function DeferredProductTrainingContextProvider({children}: ChildrenProps) { - const [isReady, setIsReady] = useState(false); - - useEffect(() => { - requestAnimationFrame(() => setIsReady(true)); - }, []); - - if (isReady) { - return {children}; - } - - return {children}; -} - -export {DeferredProductTrainingContextProvider as ProductTrainingContextProvider, ProductTrainingContextProvider as ImmediateProductTrainingContextProvider, useProductTrainingContext}; +export {ProductTrainingContextProvider, useProductTrainingContext}; diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 96b635b29085..7728bb3395ce 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -11,6 +11,7 @@ import LockedAccountModalProvider from '@components/LockedAccountModalProvider'; import OpenAppFailureModal from '@components/OpenAppFailureModal'; import OptionsListContextProvider from '@components/OptionListContextProvider'; import PriorityModeController from '@components/PriorityModeController'; +import {ProductTrainingContextProvider} from '@components/ProductTrainingContext'; import {SearchContextProvider} from '@components/Search/SearchContext'; import SearchRouterModal from '@components/Search/SearchRouter/SearchRouterModal'; import SupportalPermissionDeniedModalProvider from '@components/SupportalPermissionDeniedModalProvider'; @@ -157,6 +158,7 @@ function AuthScreens() { OptionsListContextProvider, SidebarOrderedReportsContextProvider, SearchContextProvider, + ProductTrainingContextProvider, LockedAccountModalProvider, DelegateNoAccessModalProvider, SupportalPermissionDeniedModalProvider, diff --git a/tests/ui/components/ProductTrainingContextProvider.tsx b/tests/ui/components/ProductTrainingContextProvider.tsx index 5aa3b5609ea5..81791f0dc121 100644 --- a/tests/ui/components/ProductTrainingContextProvider.tsx +++ b/tests/ui/components/ProductTrainingContextProvider.tsx @@ -2,7 +2,7 @@ import {render, renderHook} from '@testing-library/react-native'; import {createRef, useImperativeHandle} from 'react'; import type {Ref} from 'react'; import Onyx from 'react-native-onyx'; -import {ImmediateProductTrainingContextProvider as ProductTrainingContextProvider, useProductTrainingContext} from '@components/ProductTrainingContext'; +import {ProductTrainingContextProvider, useProductTrainingContext} from '@components/ProductTrainingContext'; import type {ProductTrainingTooltipName} from '@components/ProductTrainingContext/TOOLTIPS'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import DateUtils from '@libs/DateUtils';