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>
This commit is contained in:
parent
6694a33603
commit
a3d4fb652b
18 changed files with 541 additions and 39 deletions
62
src/tours/index.tsx
Normal file
62
src/tours/index.tsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
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)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue