change .value = to .set()

This commit is contained in:
Samuel Newman
2024-11-12 20:41:17 +00:00
parent 427f3a8bd7
commit b29f7b64ac
19 changed files with 153 additions and 125 deletions
+2 -3
View File
@@ -21,9 +21,8 @@ export function Loader(props: Props) {
})) }))
React.useEffect(() => { React.useEffect(() => {
rotation.value = withRepeat( rotation.set(
withTiming(360, {duration: 500, easing: Easing.linear}), withRepeat(withTiming(360, {duration: 500, easing: Easing.linear}), -1),
-1,
) )
}, [rotation]) }, [rotation])
+32 -21
View File
@@ -3,6 +3,7 @@ import {Pressable, useWindowDimensions, View} from 'react-native'
import Animated, { import Animated, {
Easing, Easing,
runOnJS, runOnJS,
runOnUI,
useAnimatedStyle, useAnimatedStyle,
useSharedValue, useSharedValue,
withTiming, withTiming,
@@ -55,13 +56,15 @@ export const ProgressGuideToast = React.forwardRef<
// animate the opacity then set isOpen to false when done // animate the opacity then set isOpen to false when done
const setIsntOpen = () => setIsOpen(false) const setIsntOpen = () => setIsOpen(false)
opacity.value = withTiming( opacity.set(
0, withTiming(
{ 0,
duration: 400, {
easing: Easing.out(Easing.cubic), duration: 400,
}, easing: Easing.out(Easing.cubic),
() => runOnJS(setIsntOpen)(), },
() => runOnJS(setIsntOpen)(),
),
) )
}, [setIsOpen, opacity]) }, [setIsOpen, opacity])
@@ -71,20 +74,28 @@ export const ProgressGuideToast = React.forwardRef<
// animate the vertical translation, the opacity, and the checkmark // animate the vertical translation, the opacity, and the checkmark
const playCheckmark = () => animatedCheckRef.current?.play() const playCheckmark = () => animatedCheckRef.current?.play()
opacity.value = 0
opacity.value = withTiming( runOnUI(() => {
1, 'worklet'
{ opacity.set(0)
duration: 100, opacity.set(
easing: Easing.out(Easing.cubic), withTiming(
}, 1,
() => runOnJS(playCheckmark)(), {
) duration: 100,
translateY.value = 0 easing: Easing.out(Easing.cubic),
translateY.value = withTiming(insets.top + 10, { },
duration: 500, () => runOnJS(playCheckmark)(),
easing: Easing.out(Easing.cubic), ),
}) )
translateY.set(0)
translateY.set(
withTiming(insets.top + 10, {
duration: 500,
easing: Easing.out(Easing.cubic),
}),
)
})()
// start the countdown timer to autoclose // start the countdown timer to autoclose
timeoutRef.current = setTimeout(close, visibleDuration || 5e3) timeoutRef.current = setTimeout(close, visibleDuration || 5e3)
+13 -7
View File
@@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import Animated, { import Animated, {
Easing, Easing,
runOnUI,
useAnimatedProps, useAnimatedProps,
useSharedValue, useSharedValue,
withDelay, withDelay,
@@ -40,14 +41,19 @@ export const AnimatedCheck = React.forwardRef<
const play = React.useCallback( const play = React.useCallback(
(cb?: () => void) => { (cb?: () => void) => {
circleAnim.value = 0 runOnUI(() => {
checkAnim.value = 0 'worklet'
circleAnim.set(0)
checkAnim.set(0)
circleAnim.value = withTiming(1, {duration: 500, easing: Easing.linear}) circleAnim.set(withTiming(1, {duration: 500, easing: Easing.linear}))
checkAnim.value = withDelay( checkAnim.set(
500, withDelay(
withTiming(1, {duration: 300, easing: Easing.linear}, cb), 500,
) withTiming(1, {duration: 300, easing: Easing.linear}, cb),
),
)
})()
}, },
[circleAnim, checkAnim], [circleAnim, checkAnim],
) )
+8 -6
View File
@@ -46,7 +46,7 @@ export function ActionsWrapper({
const shrink = React.useCallback(() => { const shrink = React.useCallback(() => {
'worklet' 'worklet'
cancelAnimation(scale) cancelAnimation(scale)
scale.value = withTiming(1, {duration: 200}) scale.set(withTiming(1, {duration: 200}))
}, [scale]) }, [scale])
const doubleTapGesture = Gesture.Tap() const doubleTapGesture = Gesture.Tap()
@@ -58,11 +58,13 @@ export function ActionsWrapper({
const pressAndHoldGesture = Gesture.LongPress() const pressAndHoldGesture = Gesture.LongPress()
.onStart(() => { .onStart(() => {
'worklet' 'worklet'
scale.value = withTiming(1.05, {duration: 200}, finished => { scale.set(
if (!finished) return withTiming(1.05, {duration: 200}, finished => {
runOnJS(open)() if (!finished) return
shrink() runOnJS(open)()
}) shrink()
}),
)
}) })
.onTouchesUp(shrink) .onTouchesUp(shrink)
.onTouchesMove(shrink) .onTouchesMove(shrink)
+2 -2
View File
@@ -42,12 +42,12 @@ export function ChatEmptyPill() {
const onPressIn = React.useCallback(() => { const onPressIn = React.useCallback(() => {
if (isWeb) return if (isWeb) return
scale.value = withTiming(1.075, {duration: 100}) scale.set(withTiming(1.075, {duration: 100}))
}, [scale]) }, [scale])
const onPressOut = React.useCallback(() => { const onPressOut = React.useCallback(() => {
if (isWeb) return if (isWeb) return
scale.value = withTiming(1, {duration: 100}) scale.set(withTiming(1, {duration: 100}))
}, [scale]) }, [scale])
const onPress = React.useCallback(() => { const onPress = React.useCallback(() => {
+2 -2
View File
@@ -35,12 +35,12 @@ export function NewMessagesPill({
const onPressIn = React.useCallback(() => { const onPressIn = React.useCallback(() => {
if (isWeb) return if (isWeb) return
scale.value = withTiming(1.075, {duration: 100}) scale.set(withTiming(1.075, {duration: 100}))
}, [scale]) }, [scale])
const onPressOut = React.useCallback(() => { const onPressOut = React.useCallback(() => {
if (isWeb) return if (isWeb) return
scale.value = withTiming(1, {duration: 100}) scale.set(withTiming(1, {duration: 100}))
}, [scale]) }, [scale])
const onPress = React.useCallback(() => { const onPress = React.useCallback(() => {
+19 -17
View File
@@ -75,9 +75,11 @@ export function GestureActionView({
return return
} }
iconScale.value = withSequence( iconScale.set(
withTiming(1.2, {duration: 175}), withSequence(
withTiming(1, {duration: 100}), withTiming(1.2, {duration: 175}),
withTiming(1, {duration: 100}),
),
) )
} }
@@ -119,11 +121,11 @@ export function GestureActionView({
.activeOffsetY([-200, 200]) .activeOffsetY([-200, 200])
.onStart(() => { .onStart(() => {
'worklet' 'worklet'
isActive.value = true isActive.set(true)
}) })
.onChange(e => { .onChange(e => {
'worklet' 'worklet'
transX.value = e.translationX transX.set(e.translationX)
if (e.translationX < 0) { if (e.translationX < 0) {
// Left side // Left side
@@ -134,13 +136,13 @@ export function GestureActionView({
) { ) {
runPopAnimation() runPopAnimation()
runOnJS(haptic)() runOnJS(haptic)()
hitSecond.value = true hitSecond.set(true)
} else if ( } else if (
hitSecond.value && hitSecond.value &&
e.translationX > -actions.leftSecond.threshold e.translationX > -actions.leftSecond.threshold
) { ) {
runPopAnimation() runPopAnimation()
hitSecond.value = false hitSecond.set(false)
} }
} }
@@ -151,12 +153,12 @@ export function GestureActionView({
) { ) {
runPopAnimation() runPopAnimation()
runOnJS(haptic)() runOnJS(haptic)()
hitFirst.value = true hitFirst.set(true)
} else if ( } else if (
hitFirst.value && hitFirst.value &&
e.translationX > -actions.leftFirst.threshold e.translationX > -actions.leftFirst.threshold
) { ) {
hitFirst.value = false hitFirst.set(false)
} }
} }
} else if (e.translationX > 0) { } else if (e.translationX > 0) {
@@ -168,13 +170,13 @@ export function GestureActionView({
) { ) {
runPopAnimation() runPopAnimation()
runOnJS(haptic)() runOnJS(haptic)()
hitSecond.value = true hitSecond.set(true)
} else if ( } else if (
hitSecond.value && hitSecond.value &&
e.translationX < actions.rightSecond.threshold e.translationX < actions.rightSecond.threshold
) { ) {
runPopAnimation() runPopAnimation()
hitSecond.value = false hitSecond.set(false)
} }
} }
@@ -185,12 +187,12 @@ export function GestureActionView({
) { ) {
runPopAnimation() runPopAnimation()
runOnJS(haptic)() runOnJS(haptic)()
hitFirst.value = true hitFirst.set(true)
} else if ( } else if (
hitFirst.value && hitFirst.value &&
e.translationX < actions.rightFirst.threshold e.translationX < actions.rightFirst.threshold
) { ) {
hitFirst.value = false hitFirst.set(false)
} }
} }
} }
@@ -210,10 +212,10 @@ export function GestureActionView({
runOnJS(actions.rightFirst.action)() runOnJS(actions.rightFirst.action)()
} }
} }
transX.value = withTiming(0, {duration: 200}) transX.set(withTiming(0, {duration: 200}))
hitFirst.value = false hitFirst.set(false)
hitSecond.value = false hitSecond.set(false)
isActive.value = false isActive.set(false)
}) })
const composedGesture = Gesture.Simultaneous(panGesture) const composedGesture = Gesture.Simultaneous(panGesture)
@@ -111,8 +111,8 @@ export function MessageInput({
const max = windowHeight - -keyboardHeight.value - topInset - 150 const max = windowHeight - -keyboardHeight.value - topInset - 150
const availableSpace = max - measurement.height const availableSpace = max - measurement.height
maxHeight.value = max maxHeight.set(max)
isInputScrollable.value = availableSpace < 30 isInputScrollable.set(availableSpace < 30)
}, },
}, },
[windowHeight, topInset], [windowHeight, topInset],
@@ -217,13 +217,13 @@ export function MessagesList({
const onScroll = React.useCallback( const onScroll = React.useCallback(
(e: ReanimatedScrollEvent) => { (e: ReanimatedScrollEvent) => {
'worklet' 'worklet'
layoutHeight.value = e.layoutMeasurement.height layoutHeight.value.set(e.layoutMeasurement.height)
const bottomOffset = e.contentOffset.y + e.layoutMeasurement.height const bottomOffset = e.contentOffset.y + e.layoutMeasurement.height
// Most apps have a little bit of space the user can scroll past while still automatically scrolling ot the bottom // Most apps have a little bit of space the user can scroll past while still automatically scrolling ot the bottom
// when a new message is added, hence the 100 pixel offset // when a new message is added, hence the 100 pixel offset
isAtBottom.value = e.contentSize.height - 100 < bottomOffset isAtBottom.set(e.contentSize.height - 100 < bottomOffset)
isAtTop.value = e.contentOffset.y <= 1 isAtTop.set(e.contentOffset.y <= 1)
if ( if (
newMessagesPill.show && newMessagesPill.show &&
@@ -256,22 +256,22 @@ export function MessagesList({
// Immediate updates - like opening the emoji picker - will have a duration of zero. In those cases, we should // Immediate updates - like opening the emoji picker - will have a duration of zero. In those cases, we should
// just update the height here instead of having the `onMove` event do it (that event will not fire!) // just update the height here instead of having the `onMove` event do it (that event will not fire!)
if (e.duration === 0) { if (e.duration === 0) {
layoutScrollWithoutAnimation.value = true layoutScrollWithoutAnimation.set(true)
keyboardHeight.value = e.height keyboardHeight.set(e.height)
} else { } else {
keyboardIsOpening.value = true keyboardIsOpening.set(true)
} }
}, },
onMove: e => { onMove: e => {
'worklet' 'worklet'
keyboardHeight.value = e.height keyboardHeight.set(e.height)
if (e.height > bottomOffset) { if (e.height > bottomOffset) {
scrollTo(flatListRef, 0, 1e7, false) scrollTo(flatListRef, 0, 1e7, false)
} }
}, },
onEnd: () => { onEnd: () => {
'worklet' 'worklet'
keyboardIsOpening.value = false keyboardIsOpening.set(false)
}, },
}) })
@@ -363,13 +363,13 @@ export function MessagesList({
// -- List layout changes (opening emoji keyboard, etc.) // -- List layout changes (opening emoji keyboard, etc.)
const onListLayout = React.useCallback( const onListLayout = React.useCallback(
(e: LayoutChangeEvent) => { (e: LayoutChangeEvent) => {
layoutHeight.value = e.nativeEvent.layout.height layoutHeight.set(e.nativeEvent.layout.height)
if (isWeb || !keyboardIsOpening.value) { if (isWeb || !keyboardIsOpening.value) {
flatListRef.current?.scrollToEnd({ flatListRef.current?.scrollToEnd({
animated: !layoutScrollWithoutAnimation.value, animated: !layoutScrollWithoutAnimation.value,
}) })
layoutScrollWithoutAnimation.value = false layoutScrollWithoutAnimation.set(false)
} }
}, },
[ [
+10 -6
View File
@@ -44,13 +44,17 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
'worklet' 'worklet'
// Cancel any existing animation // Cancel any existing animation
cancelAnimation(headerMode) cancelAnimation(headerMode)
headerMode.value = withSpring(v ? 1 : 0, { headerMode.set(
overshootClamping: true, withSpring(v ? 1 : 0, {
}) overshootClamping: true,
}),
)
cancelAnimation(footerMode) cancelAnimation(footerMode)
footerMode.value = withSpring(v ? 1 : 0, { footerMode.set(
overshootClamping: true, withSpring(v ? 1 : 0, {
}) overshootClamping: true,
}),
)
}, },
[headerMode, footerMode], [headerMode, footerMode],
) )
+3 -3
View File
@@ -1288,11 +1288,11 @@ function useScrollTracker({
}) => { }) => {
'worklet' 'worklet'
if (typeof newContentHeight === 'number') if (typeof newContentHeight === 'number')
contentHeight.value = Math.floor(newContentHeight) contentHeight.value.set(Math.floor(newContentHeight))
if (typeof newContentOffset === 'number') if (typeof newContentOffset === 'number')
contentOffset.value = Math.floor(newContentOffset) contentOffset.value.set(Math.floor(newContentOffset))
if (typeof newScrollViewHeight === 'number') if (typeof newScrollViewHeight === 'number')
scrollViewHeight.value = Math.floor(newScrollViewHeight) scrollViewHeight.set(Math.floor(newScrollViewHeight))
}, },
[contentHeight, contentOffset, scrollViewHeight], [contentHeight, contentOffset, scrollViewHeight],
) )
+1 -1
View File
@@ -93,7 +93,7 @@ function HomeHeaderLayoutDesktopAndTablet({
{tabBarAnchor} {tabBarAnchor}
<Animated.View <Animated.View
onLayout={e => { onLayout={e => {
headerHeight.value = e.nativeEvent.layout.height headerHeight.set(e.nativeEvent.layout.height)
}} }}
style={[ style={[
t.atoms.bg, t.atoms.bg,
+1 -1
View File
@@ -43,7 +43,7 @@ export function HomeHeaderLayoutMobile({
<Animated.View <Animated.View
style={[pal.view, pal.border, styles.tabBar, headerMinimalShellTransform]} style={[pal.view, pal.border, styles.tabBar, headerMinimalShellTransform]}
onLayout={e => { onLayout={e => {
headerHeight.value = e.nativeEvent.layout.height headerHeight.set(e.nativeEvent.layout.height)
}}> }}>
<View style={[pal.view, styles.topBar]}> <View style={[pal.view, styles.topBar]}>
<View style={[pal.view, {width: 100}]}> <View style={[pal.view, {width: 100}]}>
@@ -147,10 +147,10 @@ const ImageItem = ({
.onStart(e => { .onStart(e => {
'worklet' 'worklet'
const screenSize = measureSafeArea() const screenSize = measureSafeArea()
pinchOrigin.value = { pinchOrigin.set({
x: e.focalX - screenSize.width / 2, x: e.focalX - screenSize.width / 2,
y: e.focalY - screenSize.height / 2, y: e.focalY - screenSize.height / 2,
} })
}) })
.onChange(e => { .onChange(e => {
'worklet' 'worklet'
@@ -171,7 +171,7 @@ const ImageItem = ({
Math.max(minPinchScale, e.scale), Math.max(minPinchScale, e.scale),
maxPinchScale, maxPinchScale,
) )
pinchScale.value = nextPinchScale pinchScale.set(nextPinchScale)
// Zooming out close to the corner could push us out of bounds, which we don't want on Android. // Zooming out close to the corner could push us out of bounds, which we don't want on Android.
// Calculate where we'll end up so we know how much to translate back to stay in bounds. // Calculate where we'll end up so we know how much to translate back to stay in bounds.
@@ -181,10 +181,10 @@ const ImageItem = ({
prependTransform(t, committedTransform.value) prependTransform(t, committedTransform.value)
const [dx, dy] = getExtraTranslationToStayInBounds(t, screenSize) const [dx, dy] = getExtraTranslationToStayInBounds(t, screenSize)
if (dx !== 0 || dy !== 0) { if (dx !== 0 || dy !== 0) {
pinchTranslation.value = { pinchTranslation.set({
x: pinchTranslation.value.x + dx, x: pinchTranslation.value.x + dx,
y: pinchTranslation.value.y + dy, y: pinchTranslation.value.y + dy,
} })
} }
}) })
.onEnd(() => { .onEnd(() => {
@@ -199,12 +199,12 @@ const ImageItem = ({
) )
prependTransform(t, committedTransform.value) prependTransform(t, committedTransform.value)
applyRounding(t) applyRounding(t)
committedTransform.value = t committedTransform.set(t)
// Reset just the pinch. // Reset just the pinch.
pinchScale.value = 1 pinchScale.set(1)
pinchOrigin.value = {x: 0, y: 0} pinchOrigin.set({x: 0, y: 0})
pinchTranslation.value = {x: 0, y: 0} pinchTranslation.set({x: 0, y: 0})
}) })
const pan = Gesture.Pan() const pan = Gesture.Pan()
@@ -233,7 +233,7 @@ const ImageItem = ({
const [dx, dy] = getExtraTranslationToStayInBounds(t, screenSize) const [dx, dy] = getExtraTranslationToStayInBounds(t, screenSize)
nextPanTranslation.x += dx nextPanTranslation.x += dx
nextPanTranslation.y += dy nextPanTranslation.y += dy
panTranslation.value = nextPanTranslation panTranslation.set(nextPanTranslation)
}) })
.onEnd(() => { .onEnd(() => {
'worklet' 'worklet'
@@ -242,10 +242,10 @@ const ImageItem = ({
prependPan(t, panTranslation.value) prependPan(t, panTranslation.value)
prependTransform(t, committedTransform.value) prependTransform(t, committedTransform.value)
applyRounding(t) applyRounding(t)
committedTransform.value = t committedTransform.set(t)
// Reset just the pan. // Reset just the pan.
panTranslation.value = {x: 0, y: 0} panTranslation.set({x: 0, y: 0})
}) })
const singleTap = Gesture.Tap().onEnd(() => { const singleTap = Gesture.Tap().onEnd(() => {
@@ -265,7 +265,7 @@ const ImageItem = ({
if (committedScale !== 1) { if (committedScale !== 1) {
// Go back to 1:1 using the identity vector. // Go back to 1:1 using the identity vector.
let t = createTransform() let t = createTransform()
committedTransform.value = withClampedSpring(t) committedTransform.set(withClampedSpring(t))
return return
} }
@@ -299,7 +299,7 @@ const ImageItem = ({
) )
const finalTransform = createTransform() const finalTransform = createTransform()
prependPinch(finalTransform, scale, origin, {x: dx, y: dy}) prependPinch(finalTransform, scale, origin, {x: dx, y: dy})
committedTransform.value = withClampedSpring(finalTransform) committedTransform.set(withClampedSpring(finalTransform))
}) })
const composedGesture = isScrollViewBeingDragged const composedGesture = isScrollViewBeingDragged
+19 -15
View File
@@ -98,12 +98,12 @@ export default function ImageViewRoot({
// https://github.com/software-mansion/react-native-reanimated/issues/6677 // https://github.com/software-mansion/react-native-reanimated/issues/6677
requestAnimationFrame(() => { requestAnimationFrame(() => {
openProgress.value = canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1 openProgress.set(canAnimate ? withClampedSpring(1, SLOW_SPRING) : 1)
}) })
return () => { return () => {
// https://github.com/software-mansion/react-native-reanimated/issues/6677 // https://github.com/software-mansion/react-native-reanimated/issues/6677
requestAnimationFrame(() => { requestAnimationFrame(() => {
openProgress.value = canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0 openProgress.set(canAnimate ? withClampedSpring(0, SLOW_SPRING) : 0)
}) })
} }
}, [nextLightbox, openProgress]) }, [nextLightbox, openProgress])
@@ -119,7 +119,7 @@ export default function ImageViewRoot({
const onFlyAway = React.useCallback(() => { const onFlyAway = React.useCallback(() => {
'worklet' 'worklet'
openProgress.value = 0 openProgress.set(0)
runOnJS(onRequestClose)() runOnJS(onRequestClose)()
}, [onRequestClose, openProgress]) }, [onRequestClose, openProgress])
@@ -426,7 +426,7 @@ function LightboxImage({
if (openProgress.value !== 1 || isFlyingAway.value) { if (openProgress.value !== 1 || isFlyingAway.value) {
return return
} }
dismissSwipeTranslateY.value = e.translationY dismissSwipeTranslateY.set(e.translationY)
}) })
.onEnd(e => { .onEnd(e => {
'worklet' 'worklet'
@@ -434,22 +434,26 @@ function LightboxImage({
return return
} }
if (Math.abs(e.velocityY) > 1000) { if (Math.abs(e.velocityY) > 1000) {
isFlyingAway.value = true isFlyingAway.set(true)
if (dismissSwipeTranslateY.value === 0) { if (dismissSwipeTranslateY.value === 0) {
// HACK: If the initial value is 0, withDecay() animation doesn't start. // HACK: If the initial value is 0, withDecay() animation doesn't start.
// This is a bug in Reanimated, but for now we'll work around it like this. // This is a bug in Reanimated, but for now we'll work around it like this.
dismissSwipeTranslateY.value = 1 dismissSwipeTranslateY.set(1)
} }
dismissSwipeTranslateY.value = withDecay({ dismissSwipeTranslateY.set(
velocity: e.velocityY, withDecay({
velocityFactor: Math.max(3000 / Math.abs(e.velocityY), 1), // Speed up if it's too slow. velocity: e.velocityY,
deceleration: 1, // Danger! This relies on the reaction below stopping it. velocityFactor: Math.max(3000 / Math.abs(e.velocityY), 1), // Speed up if it's too slow.
}) deceleration: 1, // Danger! This relies on the reaction below stopping it.
}),
)
} else { } else {
dismissSwipeTranslateY.value = withSpring(0, { dismissSwipeTranslateY.set(
stiffness: 700, withSpring(0, {
damping: 50, stiffness: 700,
}) damping: 50,
}),
)
} }
}) })
+2 -2
View File
@@ -134,7 +134,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
const currentScrollY = scrollY.value const currentScrollY = scrollY.value
const forcedScrollY = Math.min(currentScrollY, headerOnlyHeight) const forcedScrollY = Math.min(currentScrollY, headerOnlyHeight)
if (lastForcedScrollY.value !== forcedScrollY) { if (lastForcedScrollY.value !== forcedScrollY) {
lastForcedScrollY.value = forcedScrollY lastForcedScrollY.set(forcedScrollY)
const refs = scrollRefs.value const refs = scrollRefs.value
for (let i = 0; i < refs.length; i++) { for (let i = 0; i < refs.length; i++) {
const scollRef = refs[i] const scollRef = refs[i]
@@ -167,7 +167,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
const isPossiblyInvalid = const isPossiblyInvalid =
headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight
if (!isPossiblyInvalid) { if (!isPossiblyInvalid) {
scrollY.value = nextScrollY scrollY.set(nextScrollY)
runOnJS(queueThrottledOnScroll)() runOnJS(queueThrottledOnScroll)()
} }
}, },
+1 -1
View File
@@ -78,7 +78,7 @@ function ListImpl<ItemT>(
const didScrollDown = e.contentOffset.y > SCROLLED_DOWN_LIMIT const didScrollDown = e.contentOffset.y > SCROLLED_DOWN_LIMIT
if (isScrolledDown.value !== didScrollDown) { if (isScrolledDown.value !== didScrollDown) {
isScrolledDown.value = didScrollDown isScrolledDown.set(didScrollDown)
if (onScrolledDownChange != null) { if (onScrolledDownChange != null) {
runOnJS(handleScrolledDownChange)(didScrollDown) runOnJS(handleScrolledDownChange)(didScrollDown)
} }
+11 -11
View File
@@ -44,7 +44,7 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
(v: boolean) => { (v: boolean) => {
'worklet' 'worklet'
cancelAnimation(headerMode) cancelAnimation(headerMode)
headerMode.value = v ? V1.value : V0.value headerMode.set(v ? V1.value : V0.value)
}, },
[headerMode], [headerMode],
) )
@@ -52,9 +52,9 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
useEffect(() => { useEffect(() => {
if (isWeb) { if (isWeb) {
return listenToForcedWindowScroll(() => { return listenToForcedWindowScroll(() => {
startDragOffset.value = null startDragOffset.set(null)
startMode.value = null startMode.set(null)
didJustRestoreScroll.value = true didJustRestoreScroll.set(true)
}) })
} }
}) })
@@ -67,8 +67,8 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
return return
} }
const didScrollDown = e.contentOffset.y > startDragOffset.value const didScrollDown = e.contentOffset.y > startDragOffset.value
startDragOffset.value = null startDragOffset.set(null)
startMode.value = null startMode.set(null)
if (e.contentOffset.y < headerHeight.value) { if (e.contentOffset.y < headerHeight.value) {
// If we're close to the top, show the shell. // If we're close to the top, show the shell.
setMode(false) setMode(false)
@@ -88,8 +88,8 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
(e: NativeScrollEvent) => { (e: NativeScrollEvent) => {
'worklet' 'worklet'
if (isNative) { if (isNative) {
startDragOffset.value = e.contentOffset.y startDragOffset.set(e.contentOffset.y)
startMode.value = headerMode.value startMode.set(headerMode.value)
} }
}, },
[headerMode, startDragOffset, startMode], [headerMode, startDragOffset, startMode],
@@ -148,18 +148,18 @@ export function MainScrollProvider({children}: {children: React.ReactNode}) {
// Manually adjust the value. This won't be (and shouldn't be) animated. // Manually adjust the value. This won't be (and shouldn't be) animated.
// Cancel any any existing animation // Cancel any any existing animation
cancelAnimation(headerMode) cancelAnimation(headerMode)
headerMode.value = newValue headerMode.set(newValue)
} }
} else { } else {
if (didJustRestoreScroll.value) { if (didJustRestoreScroll.value) {
didJustRestoreScroll.value = false didJustRestoreScroll.set(false)
// Don't hide/show navbar based on scroll restoratoin. // Don't hide/show navbar based on scroll restoratoin.
return return
} }
// On the web, we don't try to follow the drag because we don't know when it ends. // On the web, we don't try to follow the drag because we don't know when it ends.
// Instead, show/hide immediately based on whether we're scrolling up or down. // Instead, show/hide immediately based on whether we're scrolling up or down.
const dy = e.contentOffset.y - (startDragOffset.value ?? 0) const dy = e.contentOffset.y - (startDragOffset.value ?? 0)
startDragOffset.value = e.contentOffset.y startDragOffset.set(e.contentOffset.y)
if (dy < 0 || e.contentOffset.y < WEB_HIDE_SHELL_THRESHOLD) { if (dy < 0 || e.contentOffset.y < WEB_HIDE_SHELL_THRESHOLD) {
setMode(false) setMode(false)
+1 -1
View File
@@ -134,7 +134,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
footerMinimalShellTransform, footerMinimalShellTransform,
]} ]}
onLayout={e => { onLayout={e => {
footerHeight.value = e.nativeEvent.layout.height footerHeight.set(e.nativeEvent.layout.height)
}}> }}>
{hasSession ? ( {hasSession ? (
<> <>