From 9e5940f0abbd428506aab475aa487336dc577f68 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Fri, 9 Dec 2022 11:46:49 -0600 Subject: [PATCH] Improve aesthetic of main menu swipeout (use screen mask) --- src/view/com/util/gestures/HorzSwipe.tsx | 12 +++++++++- src/view/shell/mobile/index.tsx | 28 ++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/view/com/util/gestures/HorzSwipe.tsx b/src/view/com/util/gestures/HorzSwipe.tsx index 0176bd4c..82b230bf 100644 --- a/src/view/com/util/gestures/HorzSwipe.tsx +++ b/src/view/com/util/gestures/HorzSwipe.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useState} from 'react' import { Animated, GestureResponderEvent, @@ -19,6 +19,7 @@ interface Props { distThresholdDivisor?: number useNativeDriver?: boolean onSwipeStart?: () => void + onSwipeStartDirection?: (dx: number) => void onSwipeEnd?: (dx: number) => void children: React.ReactNode } @@ -32,10 +33,12 @@ export function HorzSwipe({ distThresholdDivisor = 1.75, useNativeDriver = false, onSwipeStart, + onSwipeStartDirection, onSwipeEnd, children, }: Props) { const winDim = useWindowDimensions() + const [dir, setDir] = useState(0) const swipeVelocityThreshold = 35 const swipeDistanceThreshold = winDim.width / distThresholdDivisor @@ -66,6 +69,7 @@ export function HorzSwipe({ } const startGesture = () => { + setDir(0) onSwipeStart?.() // TODO @@ -94,6 +98,12 @@ export function HorzSwipe({ } panX.setValue(clamp(diffX / swipeDistanceThreshold, -1, 1) * -1) + + const newDir = diffX > 0 ? -1 : diffX < 0 ? 1 : 0 + if (newDir !== dir) { + setDir(newDir) + onSwipeStartDirection?.(newDir) + } } const finishGesture = ( diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx index 04c4c469..1506b52e 100644 --- a/src/view/shell/mobile/index.tsx +++ b/src/view/shell/mobile/index.tsx @@ -113,6 +113,7 @@ export const MobileShell: React.FC = observer(() => { const [isTabsSelectorActive, setTabsSelectorActive] = useState(false) const scrollElRef = useRef() const winDim = useWindowDimensions() + const [menuSwipingDirection, setMenuSwipingDirection] = useState(0) const swipeGestureInterp = useAnimatedValue(0) const tabMenuInterp = useAnimatedValue(0) const newTabInterp = useAnimatedValue(0) @@ -213,6 +214,15 @@ export const MobileShell: React.FC = observer(() => { const isMenuActive = store.shell.isMainMenuOpen const canSwipeLeft = store.nav.tab.canGoBack || !isMenuActive const canSwipeRight = isMenuActive + const onNavSwipeStartDirection = (dx: number) => { + if (dx < 0 && !store.nav.tab.canGoBack) { + setMenuSwipingDirection(dx) + } else if (dx > 0 && isMenuActive) { + setMenuSwipingDirection(dx) + } else { + setMenuSwipingDirection(0) + } + } const onNavSwipeEnd = (dx: number) => { if (dx < 0) { if (store.nav.tab.canGoBack) { @@ -225,6 +235,7 @@ export const MobileShell: React.FC = observer(() => { store.shell.setMainMenuOpen(false) } } + setMenuSwipingDirection(0) } const swipeTranslateX = Animated.multiply( swipeGestureInterp, @@ -256,6 +267,15 @@ export const MobileShell: React.FC = observer(() => { outputRange: [0, 0.6, 0], }), } + const menuSwipeOpacity = + menuSwipingDirection !== 0 + ? { + opacity: swipeGestureInterp.interpolate({ + inputRange: menuSwipingDirection > 0 ? [0, 1] : [-1, 0], + outputRange: [0.6, 0], + }), + } + : undefined // TODO // const tabMenuTransform = { // transform: [{translateY: Animated.multiply(tabMenuInterp, -320)}], @@ -301,6 +321,7 @@ export const MobileShell: React.FC = observer(() => { swipeEnabled canSwipeLeft={canSwipeLeft} canSwipeRight={canSwipeRight} + onSwipeStartDirection={onNavSwipeStartDirection} onSwipeEnd={onNavSwipeEnd}> {screenRenderDesc.screens.map( @@ -348,6 +369,9 @@ export const MobileShell: React.FC = observer(() => { }, )} + {menuSwipingDirection !== 0 ? ( + + ) : undefined}