* Split minimal shell mode into headerMode and footerMode For now, we'll always write them in sync. When we read them, we'll use headerMode as source of truth. This will let us keep footerMode independent in a future commit. * Remove fixed_bottom_bar special cases during calculation This isn't the right time to determine special behavior. Instead we'll adjust footerMode itself conditionally on the gate. * Copy-paste setMode into MainScrollProvider This lets us fork the implementation later just for this case. * Gate footer adjustment in MainScrollProvider This is the final piece. Normal calls to setMode() keep setting both header and footer, but MainScrollProvider adjusts the footer conditionally.
69 lines
1.6 KiB
TypeScript
69 lines
1.6 KiB
TypeScript
import React from 'react'
|
|
import {
|
|
cancelAnimation,
|
|
SharedValue,
|
|
useSharedValue,
|
|
withSpring,
|
|
} from 'react-native-reanimated'
|
|
|
|
type StateContext = {
|
|
headerMode: SharedValue<number>
|
|
footerMode: SharedValue<number>
|
|
}
|
|
type SetContext = (v: boolean) => void
|
|
|
|
const stateContext = React.createContext<StateContext>({
|
|
headerMode: {
|
|
value: 0,
|
|
addListener() {},
|
|
removeListener() {},
|
|
modify() {},
|
|
},
|
|
footerMode: {
|
|
value: 0,
|
|
addListener() {},
|
|
removeListener() {},
|
|
modify() {},
|
|
},
|
|
})
|
|
const setContext = React.createContext<SetContext>((_: boolean) => {})
|
|
|
|
export function Provider({children}: React.PropsWithChildren<{}>) {
|
|
const headerMode = useSharedValue(0)
|
|
const footerMode = useSharedValue(0)
|
|
const setMode = React.useCallback(
|
|
(v: boolean) => {
|
|
'worklet'
|
|
// Cancel any existing animation
|
|
cancelAnimation(headerMode)
|
|
headerMode.value = withSpring(v ? 1 : 0, {
|
|
overshootClamping: true,
|
|
})
|
|
cancelAnimation(footerMode)
|
|
footerMode.value = withSpring(v ? 1 : 0, {
|
|
overshootClamping: true,
|
|
})
|
|
},
|
|
[headerMode, footerMode],
|
|
)
|
|
const value = React.useMemo(
|
|
() => ({
|
|
headerMode,
|
|
footerMode,
|
|
}),
|
|
[headerMode, footerMode],
|
|
)
|
|
return (
|
|
<stateContext.Provider value={value}>
|
|
<setContext.Provider value={setMode}>{children}</setContext.Provider>
|
|
</stateContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useMinimalShellMode() {
|
|
return React.useContext(stateContext)
|
|
}
|
|
|
|
export function useSetMinimalShellMode() {
|
|
return React.useContext(setContext)
|
|
}
|