bsky-app/src/tours/index.tsx
Paul Frazee a3d4fb652b
Guided tour for new users (#4690)
* Add home guided tour (WIP)

* Add web handling of the tour

* Switch to our fork of rn-tourguide

* Bump guided-tour

* Fix alignment on android

* Implement home page tour trigger after account creation

* Add new_user_guided_tour gate

* Add a title line to the tour tooltips

* A11y improvements: proper labels, focus capture, scroll capture

* Silence type error

* Native a11y

* Use FocusScope

* Switch to useWebBodyScrollLock()

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2024-07-02 21:25:19 -07:00

62 lines
1.8 KiB
TypeScript

import React from 'react'
import {InteractionManager} from 'react-native'
import {TourGuideProvider, useTourGuideController} from 'rn-tourguide'
import {useGate} from '#/lib/statsig/statsig'
import {useColorModeTheme} from '#/alf/util/useColorModeTheme'
import {HomeTour} from './HomeTour'
import {TooltipComponent} from './Tooltip'
export enum TOURS {
HOME = 'home',
}
type StateContext = TOURS | null
type SetContext = (v: TOURS | null) => void
const stateContext = React.createContext<StateContext>(null)
const setContext = React.createContext<SetContext>((_: TOURS | null) => {})
export function Provider({children}: React.PropsWithChildren<{}>) {
const theme = useColorModeTheme()
const [state, setState] = React.useState<TOURS | null>(() => null)
return (
<TourGuideProvider
androidStatusBarVisible
tooltipComponent={TooltipComponent}
backdropColor={
theme === 'light' ? 'rgba(0, 0, 0, 0.15)' : 'rgba(0, 0, 0, 0.8)'
}
preventOutsideInteraction>
<stateContext.Provider value={state}>
<setContext.Provider value={setState}>
<HomeTour />
{children}
</setContext.Provider>
</stateContext.Provider>
</TourGuideProvider>
)
}
export function useTriggerTourIfQueued(tour: TOURS) {
const {start} = useTourGuideController(tour)
const setQueuedTour = React.useContext(setContext)
const queuedTour = React.useContext(stateContext)
const gate = useGate()
return React.useCallback(() => {
if (queuedTour === tour) {
setQueuedTour(null)
InteractionManager.runAfterInteractions(() => {
if (gate('new_user_guided_tour')) {
start()
}
})
}
}, [tour, queuedTour, setQueuedTour, start, gate])
}
export function useSetQueuedTour() {
return React.useContext(setContext)
}