diff --git a/packages/mobile/src/components/now-playing-drawer/NowPlayingDrawer.tsx b/packages/mobile/src/components/now-playing-drawer/NowPlayingDrawer.tsx index 25472f28643..4f8c1b04275 100644 --- a/packages/mobile/src/components/now-playing-drawer/NowPlayingDrawer.tsx +++ b/packages/mobile/src/components/now-playing-drawer/NowPlayingDrawer.tsx @@ -17,7 +17,15 @@ import type { GestureResponderEvent, PanResponderGestureState } from 'react-native' -import { Keyboard, Platform, View, StatusBar, Pressable } from 'react-native' +import { + Keyboard, + Platform, + View, + StatusBar, + Pressable, + StyleSheet +} from 'react-native' +import Reanimated, { useAnimatedStyle } from 'react-native-reanimated' import { useSafeAreaInsets } from 'react-native-safe-area-context' import TrackPlayer from 'react-native-track-player' import { useDispatch, useSelector } from 'react-redux' @@ -33,6 +41,7 @@ import { useDrawer } from 'app/hooks/useDrawer' import { useNavigation } from 'app/hooks/useNavigation' import { AppDrawerContext } from 'app/screens/app-drawer-screen' import { AppTabNavigationContext } from 'app/screens/app-screen' +import { useTabBarHiddenProgress } from 'app/screens/app-screen/TabBarAutoHideContext' import { makeStyles } from 'app/styles' import { zIndex } from 'app/utils/zIndex' @@ -110,6 +119,7 @@ export const NowPlayingDrawer = memo(function NowPlayingDrawer( const styles = useStyles() const { isOpen, onOpen, onClose } = useDrawer('NowPlaying') + const tabBarHidden = useTabBarHiddenProgress() // Defer to the comments bottom-sheet while it's presented: its swipe-to-dismiss // gesture would otherwise leak through and also close this drawer underneath. const { isOpen: isCommentDrawerOpen } = useCommentDrawer() @@ -170,6 +180,31 @@ export const NowPlayingDrawer = memo(function NowPlayingDrawer( isOpen && isDrawerFullyOpen ? staticTopInset.current : insets.top const effectiveBottomInset = isOpen && isDrawerFullyOpen ? 0 : insets.bottom + // Travel with the bottom tab bar so the bottom chrome moves as one unit. + // The collapsed drawer rests `BOTTOM_BAR_HEIGHT + PLAY_BAR_HEIGHT` off the + // bottom, so once the tab bar floats away the play bar would otherwise hang + // there with an empty band beneath it. + // + // This moves the whole drawer rather than just the play bar inside it: the + // white surface behind the play bar belongs to the drawer root, so + // translating only its contents slides the bar off a background that stays + // put, leaving an empty white block. Pinned to 0 while open, since the same + // drawer is the full-screen player and translating that would drag the + // expanded player off screen with it. + const chromeHideStyle = useAnimatedStyle( + () => ({ + transform: [ + { + translateY: isOpen + ? 0 + : (PLAY_BAR_HEIGHT + BOTTOM_BAR_HEIGHT + insets.bottom) * + tabBarHidden.value + } + ] + }), + [isOpen, insets.bottom] + ) + useEffect(() => { if ( Platform.OS === 'ios' && @@ -281,79 +316,94 @@ export const NowPlayingDrawer = memo(function NowPlayingDrawer( }, [onClose, navigation, trackId]) return ( - - - - - - - - - - - - - - - - - - - - - + ]} + > + + + + + + + + + + + + + + + + + + + + - - + + ) })