diff options
-rw-r--r-- | src/view/shell/mobile/TabsSelector.tsx | 50 | ||||
-rw-r--r-- | src/view/shell/mobile/index.tsx | 64 |
2 files changed, 60 insertions, 54 deletions
diff --git a/src/view/shell/mobile/TabsSelector.tsx b/src/view/shell/mobile/TabsSelector.tsx index be54cfc5b..28f488f01 100644 --- a/src/view/shell/mobile/TabsSelector.tsx +++ b/src/view/shell/mobile/TabsSelector.tsx @@ -1,6 +1,7 @@ -import React, {createRef, useRef, useMemo, useEffect, useState} from 'react' +import React, {createRef, useRef, useMemo, useState} from 'react' import {observer} from 'mobx-react-lite' import { + Animated, ScrollView, Share, StyleSheet, @@ -9,20 +10,13 @@ import { View, } from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import Animated, { - interpolate, - SharedValue, - useSharedValue, - useAnimatedStyle, - withTiming, - runOnJS, -} from 'react-native-reanimated' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import Swipeable from 'react-native-gesture-handler/Swipeable' import {useStores} from '../../../state' import {s, colors} from '../../lib/styles' import {toShareUrl} from '../../../lib/strings' import {match} from '../../routes' +import {useAnimatedValue} from '../../lib/useAnimatedValue' const TAB_HEIGHT = 42 @@ -33,7 +27,7 @@ export const TabsSelector = observer( onClose, }: { active: boolean - tabMenuInterp: SharedValue<number> + tabMenuInterp: Animated.Value onClose: () => void }) => { const store = useStores() @@ -41,7 +35,7 @@ export const TabsSelector = observer( const [closingTabIndex, setClosingTabIndex] = useState<number | undefined>( undefined, ) - const closeInterp = useSharedValue<number>(0) + const closeInterp = useAnimatedValue(0) const tabsRef = useRef<ScrollView>(null) const tabRefs = useMemo( () => @@ -51,11 +45,16 @@ export const TabsSelector = observer( [store.nav.tabs.length], ) - const wrapperAnimStyle = useAnimatedStyle(() => ({ + const wrapperAnimStyle = { transform: [ - {translateY: interpolate(tabMenuInterp.value, [0, 1.0], [320, 0])}, + { + translateY: tabMenuInterp.interpolate({ + inputRange: [0, 1.0], + outputRange: [320, 0], + }), + }, ], - })) + } // events // = @@ -76,13 +75,16 @@ export const TabsSelector = observer( store.nav.setActiveTab(tabIndex) onClose() } - const doCloseTab = (index: number) => store.nav.closeTab(index) const onCloseTab = (tabIndex: number) => { setClosingTabIndex(tabIndex) - closeInterp.value = 0 - closeInterp.value = withTiming(1, {duration: 300}, () => { - runOnJS(setClosingTabIndex)(undefined) - runOnJS(doCloseTab)(tabIndex) + closeInterp.setValue(0) + Animated.timing(closeInterp, { + toValue: 1, + duration: 300, + useNativeDriver: false, + }).start(() => { + setClosingTabIndex(undefined) + store.nav.closeTab(tabIndex) }) } const onLayout = () => { @@ -107,11 +109,11 @@ export const TabsSelector = observer( } const currentTabIndex = store.nav.tabIndex - const closingTabAnimStyle = useAnimatedStyle(() => ({ - height: TAB_HEIGHT * (1 - closeInterp.value), - opacity: 1 - closeInterp.value, - marginBottom: 4 * (1 - closeInterp.value), - })) + const closingTabAnimStyle = { + height: Animated.multiply(TAB_HEIGHT, Animated.subtract(1, closeInterp)), + opacity: Animated.subtract(1, closeInterp), + marginBottom: Animated.multiply(4, Animated.subtract(1, closeInterp)), + } if (!active) { return <View /> diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx index 894d4db58..2c1023632 100644 --- a/src/view/shell/mobile/index.tsx +++ b/src/view/shell/mobile/index.tsx @@ -1,7 +1,8 @@ import React, {useState, useEffect, useRef} from 'react' import {observer} from 'mobx-react-lite' import { - Animated as RNAnimated, + Animated, + Easing, FlatList, GestureResponderEvent, SafeAreaView, @@ -16,13 +17,6 @@ import { import {ScreenContainer, Screen} from 'react-native-screens' import LinearGradient from 'react-native-linear-gradient' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import { - Easing, - useSharedValue, - useAnimatedStyle, - withTiming, - runOnJS, -} from 'react-native-reanimated' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {TABS_ENABLED} from '../../../build-flags' @@ -119,8 +113,8 @@ export const MobileShell: React.FC = observer(() => { const scrollElRef = useRef<FlatList | undefined>() const winDim = useWindowDimensions() const swipeGestureInterp = useAnimatedValue(0) - const tabMenuInterp = useSharedValue<number>(0) - const newTabInterp = useSharedValue<number>(0) + const tabMenuInterp = useAnimatedValue(0) + const newTabInterp = useAnimatedValue(0) const [isRunningNewTabAnim, setIsRunningNewTabAnim] = useState(false) const colorScheme = useColorScheme() const safeAreaInsets = useSafeAreaInsets() @@ -139,22 +133,29 @@ export const MobileShell: React.FC = observer(() => { // tab selector animation // = - const closeTabsSelector = () => setTabsSelectorActive(false) const toggleTabsMenu = (active: boolean) => { if (active) { // will trigger the animation below setTabsSelectorActive(true) } else { - tabMenuInterp.value = withTiming(0, {duration: 100}, () => { + Animated.timing(tabMenuInterp, { + toValue: 0, + duration: 100, + useNativeDriver: false, + }).start(() => { // hide once the animation has finished - runOnJS(closeTabsSelector)() + setTabsSelectorActive(false) }) } } useEffect(() => { if (isTabsSelectorActive) { // trigger the animation once the tabs selector is rendering - tabMenuInterp.value = withTiming(1, {duration: 100}) + Animated.timing(tabMenuInterp, { + toValue: 1, + duration: 100, + useNativeDriver: false, + }).start() } }, [isTabsSelectorActive]) @@ -171,13 +172,16 @@ export const MobileShell: React.FC = observer(() => { store.nav.tab.setIsNewTab(false) setIsRunningNewTabAnim(false) } - newTabInterp.value = withTiming( - 1, - {duration: 250, easing: Easing.out(Easing.exp)}, - () => runOnJS(reset)(), - ) + Animated.timing(newTabInterp, { + toValue: 1, + duration: 250, + easing: Easing.out(Easing.exp), + useNativeDriver: false, + }).start(() => { + reset() + }) } else { - newTabInterp.value = 0 + newTabInterp.setValue(0) } }, [isRunningNewTabAnim]) @@ -190,7 +194,7 @@ export const MobileShell: React.FC = observer(() => { } const swipeTransform = { transform: [ - {translateX: RNAnimated.multiply(swipeGestureInterp, winDim.width * -1)}, + {translateX: Animated.multiply(swipeGestureInterp, winDim.width * -1)}, ], } const swipeOpacity = { @@ -199,12 +203,12 @@ export const MobileShell: React.FC = observer(() => { outputRange: [0, 0.6, 0], }), } - const tabMenuTransform = useAnimatedStyle(() => ({ - transform: [{translateY: tabMenuInterp.value * -320}], - })) - const newTabTransform = useAnimatedStyle(() => ({ - transform: [{scale: newTabInterp.value}], - })) + const tabMenuTransform = { + transform: [{translateY: Animated.multiply(tabMenuInterp.value, -320)}], + } + const newTabTransform = { + transform: [{scale: newTabInterp}], + } if (!store.session.hasSession) { return ( @@ -250,12 +254,12 @@ export const MobileShell: React.FC = observer(() => { key={key} style={[StyleSheet.absoluteFill]} activityState={current ? 2 : previous ? 1 : 0}> - <RNAnimated.View + <Animated.View style={ current ? [styles.screenMask, swipeOpacity] : undefined } /> - <RNAnimated.View + <Animated.View style={[ s.flex1, styles.screen, @@ -273,7 +277,7 @@ export const MobileShell: React.FC = observer(() => { visible={current} scrollElRef={current ? scrollElRef : undefined} /> - </RNAnimated.View> + </Animated.View> </Screen> ) }, |