diff --git a/native/components/nux-handler.react.js b/native/components/nux-handler.react.js --- a/native/components/nux-handler.react.js +++ b/native/components/nux-handler.react.js @@ -6,10 +6,21 @@ import { isLoggedIn } from 'lib/selectors/user-selectors.js'; -import { NUXTipsContext } from './nux-tips-context.react.js'; +import { + type NUXTip, + NUXTipsContext, + nuxTip, +} from './nux-tips-context.react.js'; import { useSelector } from '../redux/redux-utils.js'; import { useOnFirstLaunchEffect } from '../utils/hooks.js'; +const orderedTips: $ReadOnlyArray = [ + nuxTip.INTRO, + nuxTip.COMMUNITY_DRAWER, + nuxTip.HOME, + nuxTip.MUTED, +]; + function NUXHandler(): React.Node { const nuxTipsContext = React.useContext(NUXTipsContext); invariant(nuxTipsContext, 'nuxTipsContext should be defined'); @@ -30,6 +41,9 @@ const effect = React.useCallback(() => { navigation.navigate<'NUXTipOverlayBackdrop'>({ name: 'NUXTipOverlayBackdrop', + params: { + orderedTips, + }, }); }, [navigation]); diff --git a/native/components/nux-tips-context.react.js b/native/components/nux-tips-context.react.js --- a/native/components/nux-tips-context.react.js +++ b/native/components/nux-tips-context.react.js @@ -24,7 +24,6 @@ export type NUXTip = $Values; type NUXTipParams = { - +nextTip: ?NUXTip, +tooltipLocation: 'below' | 'above' | 'absolute', +routeName: NUXTipRouteNames, +exitingCallback?: ( @@ -36,22 +35,18 @@ const nuxTipParams: { +[NUXTip]: NUXTipParams } = { [nuxTip.INTRO]: { - nextTip: nuxTip.COMMUNITY_DRAWER, tooltipLocation: 'absolute', routeName: IntroTipRouteName, }, [nuxTip.COMMUNITY_DRAWER]: { - nextTip: nuxTip.HOME, tooltipLocation: 'below', routeName: CommunityDrawerTipRouteName, }, [nuxTip.HOME]: { - nextTip: nuxTip.MUTED, tooltipLocation: 'below', routeName: HomeTabTipRouteName, }, [nuxTip.MUTED]: { - nextTip: undefined, routeName: MutedTabTipRouteName, tooltipLocation: 'below', exitingCallback: navigation => navigation.goBack(), diff --git a/native/navigation/nux-tip-overlay-backdrop.react.js b/native/navigation/nux-tip-overlay-backdrop.react.js --- a/native/navigation/nux-tip-overlay-backdrop.react.js +++ b/native/navigation/nux-tip-overlay-backdrop.react.js @@ -7,10 +7,7 @@ import type { AppNavigationProp } from './app-navigator.react.js'; import { OverlayContext } from './overlay-context.js'; import type { NUXTipRouteNames, NavigationRoute } from './route-names'; -import { - firstNUXTipKey, - getNUXTipParams, -} from '../components/nux-tips-context.react.js'; +import { getNUXTipParams } from '../components/nux-tips-context.react.js'; import { useStyles } from '../themes/colors.js'; import { animationDuration } from '../tooltip/nux-tips-overlay.react.js'; import { AnimatedView } from '../types/styles.js'; @@ -44,12 +41,21 @@ } function NUXTipOverlayBackdropInner(props: Props): React.Node { + const { navigation, route } = props; + const overlayContext = React.useContext(OverlayContext); invariant(overlayContext, 'NUXTipsOverlay should have OverlayContext'); const { onExitFinish } = overlayContext; const styles = useStyles(unboundStyles); + const orderedTips = route.params?.orderedTips; + invariant( + orderedTips && orderedTips.length > 0, + 'orderedTips is required and should not be empty.', + ); + const firstTip = orderedTips[0]; + const opacityExitingAnimation = React.useCallback(() => { 'worklet'; @@ -64,16 +70,18 @@ }; }, [onExitFinish]); - const { routeName } = getNUXTipParams(firstNUXTipKey); + const { routeName } = getNUXTipParams(firstTip); React.useEffect( - () => - props.navigation.navigate({ + () => { + navigation.navigate({ name: routeName, params: { - tipKey: firstNUXTipKey, + orderedTips, + orderedTipsIndex: 0, }, - }), + }); + }, // We want this effect to run exactly once, when this component is mounted // eslint-disable-next-line react-hooks/exhaustive-deps [], diff --git a/native/tooltip/nux-tips-overlay.react.js b/native/tooltip/nux-tips-overlay.react.js --- a/native/tooltip/nux-tips-overlay.react.js +++ b/native/tooltip/nux-tips-overlay.react.js @@ -100,7 +100,8 @@ }; export type NUXTipsOverlayParams = { - +tipKey: NUXTip, + +orderedTips: $ReadOnlyArray, + +orderedTipsIndex: number, }; export type NUXTipsOverlayProps = { @@ -144,7 +145,9 @@ }); return; } - const measure = nuxTipContext?.tipsProps?.[route.params.tipKey]; + const currentTipKey = + route.params.orderedTips[route.params.orderedTipsIndex]; + const measure = nuxTipContext?.tipsProps?.[currentTipKey]; invariant(measure, 'button should be registered with nuxTipContext'); measure((x, y, width, height, pageX, pageY) => @@ -153,7 +156,12 @@ verticalBounds: { height, y: pageY }, }), ); - }, [dimensions, nuxTipContext?.tipsProps, route.params.tipKey]); + }, [ + dimensions, + nuxTipContext?.tipsProps, + route.params.orderedTips, + route.params.orderedTipsIndex, + ]); const overlayContext = React.useContext(OverlayContext); invariant(overlayContext, 'NUXTipsOverlay should have OverlayContext'); @@ -218,7 +226,9 @@ [coordinates, dimensions.width, tipHorizontalOffset], ); - const tipParams = getNUXTipParams(route.params.tipKey); + const currentTipKey = + route.params.orderedTips[route.params.orderedTipsIndex]; + const tipParams = getNUXTipParams(currentTipKey); const { tooltipLocation } = tipParams; const baseTipContainerStyle = React.useMemo(() => { @@ -415,25 +425,30 @@ } const onPressOk = React.useCallback(() => { - const { nextTip, exitingCallback } = tipParams; + const { orderedTips, orderedTipsIndex } = route.params; + const { exitingCallback } = tipParams; goBackOnce(); if (exitingCallback) { exitingCallback?.(navigation); } - if (!nextTip) { + const nextOrderedTipsIndex = orderedTipsIndex + 1; + if (nextOrderedTipsIndex >= orderedTips.length) { return; } + + const nextTip = orderedTips[nextOrderedTipsIndex]; const { routeName } = getNUXTipParams(nextTip); navigation.navigate({ name: routeName, params: { - tipKey: nextTip, + orderedTips, + orderedTipsIndex: nextOrderedTipsIndex, }, }); - }, [goBackOnce, navigation, tipParams]); + }, [goBackOnce, navigation, route.params, tipParams]); const button = React.useMemo( () =>