Skip to content

Commit

Permalink
Hide/show header and footer without re-renders, take two (#1849)
Browse files Browse the repository at this point in the history
* Remove callsites using the state value

* Remove unused code

* Change shell mode without re-renders

* Adjust "write your reply" for mode
  • Loading branch information
gaearon authored Nov 9, 2023
1 parent bd531f2 commit 82059b7
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 55 deletions.
59 changes: 30 additions & 29 deletions src/lib/hooks/useMinimalShellMode.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,61 @@
import React from 'react'
import {autorun} from 'mobx'
import {
Easing,
AnimatableValue,
interpolate,
useAnimatedStyle,
useSharedValue,
withTiming,
Easing,
} from 'react-native-reanimated'

import {useMinimalShellMode as useMinimalShellModeState} from '#/state/shell/minimal-mode'

function withShellTiming<T extends AnimatableValue>(value: T): T {
'worklet'
return withTiming(value, {
duration: 125,
easing: Easing.bezier(0.25, 0.1, 0.25, 1),
})
}

export function useMinimalShellMode() {
const minimalShellMode = useMinimalShellModeState()
const minimalShellInterp = useSharedValue(0)
const mode = useMinimalShellModeState()
const footerMinimalShellTransform = useAnimatedStyle(() => {
return {
opacity: interpolate(minimalShellInterp.value, [0, 1], [1, 0]),
pointerEvents: mode.value ? 'none' : 'auto',
opacity: withShellTiming(interpolate(mode.value ? 1 : 0, [0, 1], [1, 0])),
transform: [
{translateY: interpolate(minimalShellInterp.value, [0, 1], [0, 25])},
{
translateY: withShellTiming(
interpolate(mode.value ? 1 : 0, [0, 1], [0, 25]),
),
},
],
}
})
const headerMinimalShellTransform = useAnimatedStyle(() => {
return {
opacity: interpolate(minimalShellInterp.value, [0, 1], [1, 0]),
pointerEvents: mode.value ? 'none' : 'auto',
opacity: withShellTiming(interpolate(mode.value ? 1 : 0, [0, 1], [1, 0])),
transform: [
{translateY: interpolate(minimalShellInterp.value, [0, 1], [0, -25])},
{
translateY: withShellTiming(
interpolate(mode.value ? 1 : 0, [0, 1], [0, -25]),
),
},
],
}
})
const fabMinimalShellTransform = useAnimatedStyle(() => {
return {
transform: [
{translateY: interpolate(minimalShellInterp.value, [0, 1], [-44, 0])},
{
translateY: withShellTiming(
interpolate(mode.value ? 1 : 0, [0, 1], [-44, 0]),
),
},
],
}
})

React.useEffect(() => {
return autorun(() => {
if (minimalShellMode) {
minimalShellInterp.value = withTiming(1, {
duration: 125,
easing: Easing.bezier(0.25, 0.1, 0.25, 1),
})
} else {
minimalShellInterp.value = withTiming(0, {
duration: 125,
easing: Easing.bezier(0.25, 0.1, 0.25, 1),
})
}
})
}, [minimalShellInterp, minimalShellMode])

return {
minimalShellMode,
footerMinimalShellTransform,
headerMinimalShellTransform,
fabMinimalShellTransform,
Expand Down
7 changes: 5 additions & 2 deletions src/lib/hooks/useOnMainScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ export function useOnMainScroll(): [OnScrollCb, boolean, ResetCb] {
const dy = y - (lastY.current || 0)
lastY.current = y

if (!minimalShellMode && dy > dyLimitDown && y > Y_LIMIT) {
if (!minimalShellMode.value && dy > dyLimitDown && y > Y_LIMIT) {
setMinimalShellMode(true)
} else if (minimalShellMode && (dy < dyLimitUp * -1 || y <= Y_LIMIT)) {
} else if (
minimalShellMode.value &&
(dy < dyLimitUp * -1 || y <= Y_LIMIT)
) {
setMinimalShellMode(false)
}

Expand Down
22 changes: 17 additions & 5 deletions src/state/shell/minimal-mode.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import React from 'react'
import {useSharedValue, SharedValue} from 'react-native-reanimated'

type StateContext = boolean
type StateContext = SharedValue<boolean>
type SetContext = (v: boolean) => void

const stateContext = React.createContext<StateContext>(false)
const stateContext = React.createContext<StateContext>({
value: false,
addListener() {},
removeListener() {},
modify() {},
})
const setContext = React.createContext<SetContext>((_: boolean) => {})

export function Provider({children}: React.PropsWithChildren<{}>) {
const [state, setState] = React.useState(false)
const mode = useSharedValue(false)
const setMode = React.useCallback(
(v: boolean) => {
mode.value = v
},
[mode],
)
return (
<stateContext.Provider value={state}>
<setContext.Provider value={setState}>{children}</setContext.Provider>
<stateContext.Provider value={mode}>
<setContext.Provider value={setMode}>{children}</setContext.Provider>
</stateContext.Provider>
)
}
Expand Down
6 changes: 1 addition & 5 deletions src/view/com/pager/FeedsTabBarMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const FeedsTabBar = observer(function FeedsTabBarImpl(
const setDrawerOpen = useSetDrawerOpen()
const items = useHomeTabs(store.preferences.pinnedFeeds)
const brandBlue = useColorSchemeStyle(s.brandBlue, s.blue3)
const {minimalShellMode, headerMinimalShellTransform} = useMinimalShellMode()
const {headerMinimalShellTransform} = useMinimalShellMode()

const onPressAvi = React.useCallback(() => {
setDrawerOpen(true)
Expand All @@ -38,7 +38,6 @@ export const FeedsTabBar = observer(function FeedsTabBarImpl(
pal.border,
styles.tabBar,
headerMinimalShellTransform,
minimalShellMode && styles.disabled,
]}>
<View style={[pal.view, styles.topBar]}>
<View style={[pal.view]}>
Expand Down Expand Up @@ -110,7 +109,4 @@ const styles = StyleSheet.create({
title: {
fontSize: 21,
},
disabled: {
pointerEvents: 'none',
},
})
18 changes: 9 additions & 9 deletions src/view/screens/PostThread.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useMemo} from 'react'
import {InteractionManager, StyleSheet, View} from 'react-native'
import Animated from 'react-native-reanimated'
import {useFocusEffect} from '@react-navigation/native'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
Expand All @@ -15,15 +16,14 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {clamp} from 'lodash'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {logger} from '#/logger'
import {useMinimalShellMode, useSetMinimalShellMode} from '#/state/shell'

const SHELL_FOOTER_HEIGHT = 44
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
import {useSetMinimalShellMode} from '#/state/shell'

type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
export const PostThreadScreen = withAuthRequired(
observer(function PostThreadScreenImpl({route}: Props) {
const store = useStores()
const minimalShellMode = useMinimalShellMode()
const {fabMinimalShellTransform} = useMinimalShellMode()
const setMinimalShellMode = useSetMinimalShellMode()
const safeAreaInsets = useSafeAreaInsets()
const {name, rkey} = route.params
Expand Down Expand Up @@ -83,17 +83,17 @@ export const PostThreadScreen = withAuthRequired(
treeView={!!store.preferences.thread.lab_treeViewEnabled}
/>
</View>
{isMobile && !minimalShellMode && (
<View
{isMobile && (
<Animated.View
style={[
styles.prompt,
fabMinimalShellTransform,
{
bottom:
SHELL_FOOTER_HEIGHT + clamp(safeAreaInsets.bottom, 15, 30),
bottom: clamp(safeAreaInsets.bottom, 15, 30),
},
]}>
<ComposePrompt onPressCompose={onPressReply} />
</View>
</Animated.View>
)}
</View>
)
Expand Down
3 changes: 1 addition & 2 deletions src/view/shell/bottom-bar/BottomBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const BottomBar = observer(function BottomBarImpl({
const {isAtHome, isAtSearch, isAtFeeds, isAtNotifications, isAtMyProfile} =
useNavigationTabState()

const {minimalShellMode, footerMinimalShellTransform} = useMinimalShellMode()
const {footerMinimalShellTransform} = useMinimalShellMode()
const {notifications} = store.me

const onPressTab = React.useCallback(
Expand Down Expand Up @@ -85,7 +85,6 @@ export const BottomBar = observer(function BottomBarImpl({
pal.border,
{paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)},
footerMinimalShellTransform,
minimalShellMode && styles.disabled,
]}>
<Btn
testID="bottomBarHomeBtn"
Expand Down
3 changes: 0 additions & 3 deletions src/view/shell/bottom-bar/BottomBarStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,4 @@ export const styles = StyleSheet.create({
borderWidth: 1,
borderRadius: 100,
},
disabled: {
pointerEvents: 'none',
},
})

0 comments on commit 82059b7

Please sign in to comment.