Skip to content

Commit

Permalink
Use compiler-safe Reanimated get/set APIs (bluesky-social#6391)
Browse files Browse the repository at this point in the history
* Convert lightbox to get/set

* Work around software-mansion/react-native-reanimated#6613

* Use get/set in more places

* Port MainScrollProvider to get/set

* Port more to get/set

* Port composer to get/set

* Remove unnecessary thread hops in composer

* Port more things to get/set

* Convert more to get/set, remove redundant runOnJS

* Convert remaining cases to get/set
  • Loading branch information
gaearon authored Nov 17, 2024
1 parent d575a2f commit 474c4ef
Show file tree
Hide file tree
Showing 26 changed files with 351 additions and 304 deletions.
72 changes: 40 additions & 32 deletions src/Splash.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,40 +81,40 @@ export function Splash(props: React.PropsWithChildren<Props>) {
return {
transform: [
{
scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'),
scale: interpolate(intro.get(), [0, 1], [0.8, 1], 'clamp'),
},
{
scale: interpolate(
outroLogo.value,
outroLogo.get(),
[0, 0.08, 1],
[1, 0.8, 500],
'clamp',
),
},
],
opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'),
opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'),
}
})
const bottomLogoAnimation = useAnimatedStyle(() => {
return {
opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'),
opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'),
}
})
const reducedLogoAnimation = useAnimatedStyle(() => {
return {
transform: [
{
scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'),
scale: interpolate(intro.get(), [0, 1], [0.8, 1], 'clamp'),
},
],
opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'),
opacity: interpolate(intro.get(), [0, 1], [0, 1], 'clamp'),
}
})

const logoWrapperAnimation = useAnimatedStyle(() => {
return {
opacity: interpolate(
outroAppOpacity.value,
outroAppOpacity.get(),
[0, 0.1, 0.2, 1],
[1, 1, 0, 0],
'clamp',
Expand All @@ -126,11 +126,11 @@ export function Splash(props: React.PropsWithChildren<Props>) {
return {
transform: [
{
scale: interpolate(outroApp.value, [0, 1], [1.1, 1], 'clamp'),
scale: interpolate(outroApp.get(), [0, 1], [1.1, 1], 'clamp'),
},
],
opacity: interpolate(
outroAppOpacity.value,
outroAppOpacity.get(),
[0, 0.1, 0.2, 1],
[0, 0, 1, 1],
'clamp',
Expand All @@ -146,29 +146,37 @@ export function Splash(props: React.PropsWithChildren<Props>) {
if (isReady) {
SplashScreen.hideAsync()
.then(() => {
intro.value = withTiming(
1,
{duration: 400, easing: Easing.out(Easing.cubic)},
async () => {
// set these values to check animation at specific point
// outroLogo.value = 0.1
// outroApp.value = 0.1
outroLogo.value = withTiming(
1,
{duration: 1200, easing: Easing.in(Easing.cubic)},
() => {
runOnJS(onFinish)()
},
)
outroApp.value = withTiming(1, {
duration: 1200,
easing: Easing.inOut(Easing.cubic),
})
outroAppOpacity.value = withTiming(1, {
duration: 1200,
easing: Easing.in(Easing.cubic),
})
},
intro.set(() =>
withTiming(
1,
{duration: 400, easing: Easing.out(Easing.cubic)},
async () => {
// set these values to check animation at specific point
// outroLogo.set(0.1)
// outroApp.set(0.1)
outroLogo.set(() =>
withTiming(
1,
{duration: 1200, easing: Easing.in(Easing.cubic)},
() => {
runOnJS(onFinish)()
},
),
)
outroApp.set(() =>
withTiming(1, {
duration: 1200,
easing: Easing.inOut(Easing.cubic),
}),
)
outroAppOpacity.set(() =>
withTiming(1, {
duration: 1200,
easing: Easing.in(Easing.cubic),
}),
)
},
),
)
})
.catch(() => {})
Expand Down
7 changes: 3 additions & 4 deletions src/components/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ export function Loader(props: Props) {
const rotation = useSharedValue(0)

const animatedStyles = useAnimatedStyle(() => ({
transform: [{rotate: rotation.value + 'deg'}],
transform: [{rotate: rotation.get() + 'deg'}],
}))

React.useEffect(() => {
rotation.value = withRepeat(
withTiming(360, {duration: 500, easing: Easing.linear}),
-1,
rotation.set(() =>
withRepeat(withTiming(360, {duration: 500, easing: Easing.linear}), -1),
)
}, [rotation])

Expand Down
48 changes: 27 additions & 21 deletions src/components/ProgressGuide/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ export const ProgressGuideToast = React.forwardRef<

// animate the opacity then set isOpen to false when done
const setIsntOpen = () => setIsOpen(false)
opacity.value = withTiming(
0,
{
duration: 400,
easing: Easing.out(Easing.cubic),
},
() => runOnJS(setIsntOpen)(),
opacity.set(() =>
withTiming(
0,
{
duration: 400,
easing: Easing.out(Easing.cubic),
},
() => runOnJS(setIsntOpen)(),
),
)
}, [setIsOpen, opacity])

Expand All @@ -71,20 +73,24 @@ export const ProgressGuideToast = React.forwardRef<

// animate the vertical translation, the opacity, and the checkmark
const playCheckmark = () => animatedCheckRef.current?.play()
opacity.value = 0
opacity.value = withTiming(
1,
{
duration: 100,
opacity.set(0)
opacity.set(() =>
withTiming(
1,
{
duration: 100,
easing: Easing.out(Easing.cubic),
},
() => runOnJS(playCheckmark)(),
),
)
translateY.set(0)
translateY.set(() =>
withTiming(insets.top + 10, {
duration: 500,
easing: Easing.out(Easing.cubic),
},
() => runOnJS(playCheckmark)(),
}),
)
translateY.value = 0
translateY.value = withTiming(insets.top + 10, {
duration: 500,
easing: Easing.out(Easing.cubic),
})

// start the countdown timer to autoclose
timeoutRef.current = setTimeout(close, visibleDuration || 5e3)
Expand Down Expand Up @@ -114,8 +120,8 @@ export const ProgressGuideToast = React.forwardRef<
}, [winDim.width])

const animatedStyle = useAnimatedStyle(() => ({
transform: [{translateY: translateY.value}],
opacity: opacity.value,
transform: [{translateY: translateY.get()}],
opacity: opacity.get(),
}))

return (
Expand Down
20 changes: 12 additions & 8 deletions src/components/anim/AnimatedCheck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,25 @@ export const AnimatedCheck = React.forwardRef<
const checkAnim = useSharedValue(0)

const circleAnimatedProps = useAnimatedProps(() => ({
strokeDashoffset: 166 - circleAnim.value * 166,
strokeDashoffset: 166 - circleAnim.get() * 166,
}))
const checkAnimatedProps = useAnimatedProps(() => ({
strokeDashoffset: 48 - 48 * checkAnim.value,
strokeDashoffset: 48 - 48 * checkAnim.get(),
}))

const play = React.useCallback(
(cb?: () => void) => {
circleAnim.value = 0
checkAnim.value = 0
circleAnim.set(0)
checkAnim.set(0)

circleAnim.value = withTiming(1, {duration: 500, easing: Easing.linear})
checkAnim.value = withDelay(
500,
withTiming(1, {duration: 300, easing: Easing.linear}, cb),
circleAnim.set(() =>
withTiming(1, {duration: 500, easing: Easing.linear}),
)
checkAnim.set(() =>
withDelay(
500,
withTiming(1, {duration: 300, easing: Easing.linear}, cb),
),
)
},
[circleAnim, checkAnim],
Expand Down
16 changes: 9 additions & 7 deletions src/components/dms/ActionsWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function ActionsWrapper({
const scale = useSharedValue(1)

const animatedStyle = useAnimatedStyle(() => ({
transform: [{scale: scale.value}],
transform: [{scale: scale.get()}],
}))

const open = React.useCallback(() => {
Expand All @@ -46,7 +46,7 @@ export function ActionsWrapper({
const shrink = React.useCallback(() => {
'worklet'
cancelAnimation(scale)
scale.value = withTiming(1, {duration: 200})
scale.set(() => withTiming(1, {duration: 200}))
}, [scale])

const doubleTapGesture = Gesture.Tap()
Expand All @@ -58,11 +58,13 @@ export function ActionsWrapper({
const pressAndHoldGesture = Gesture.LongPress()
.onStart(() => {
'worklet'
scale.value = withTiming(1.05, {duration: 200}, finished => {
if (!finished) return
runOnJS(open)()
shrink()
})
scale.set(() =>
withTiming(1.05, {duration: 200}, finished => {
if (!finished) return
runOnJS(open)()
shrink()
}),
)
})
.onTouchesUp(shrink)
.onTouchesMove(shrink)
Expand Down
6 changes: 3 additions & 3 deletions src/components/dms/ChatEmptyPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ export function ChatEmptyPill() {

const onPressIn = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1.075, {duration: 100})
scale.set(() => withTiming(1.075, {duration: 100}))
}, [scale])

const onPressOut = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1, {duration: 100})
scale.set(() => withTiming(1, {duration: 100}))
}, [scale])

const onPress = React.useCallback(() => {
Expand All @@ -61,7 +61,7 @@ export function ChatEmptyPill() {
}, [playHaptic, prompts.length])

const animatedStyle = useAnimatedStyle(() => ({
transform: [{scale: scale.value}],
transform: [{scale: scale.get()}],
}))

return (
Expand Down
6 changes: 3 additions & 3 deletions src/components/dms/NewMessagesPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ export function NewMessagesPill({

const onPressIn = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1.075, {duration: 100})
scale.set(() => withTiming(1.075, {duration: 100}))
}, [scale])

const onPressOut = React.useCallback(() => {
if (isWeb) return
scale.value = withTiming(1, {duration: 100})
scale.set(() => withTiming(1, {duration: 100}))
}, [scale])

const onPress = React.useCallback(() => {
Expand All @@ -49,7 +49,7 @@ export function NewMessagesPill({
}, [onPressInner, playHaptic])

const animatedStyle = useAnimatedStyle(() => ({
transform: [{scale: scale.value}],
transform: [{scale: scale.get()}],
}))

return (
Expand Down
Loading

0 comments on commit 474c4ef

Please sign in to comment.