diff --git a/apps/mobile/src/hooks/useEnableDrawer.ts b/apps/mobile/src/hooks/useEnableDrawer.ts new file mode 100644 index 000000000..64079a4d9 --- /dev/null +++ b/apps/mobile/src/hooks/useEnableDrawer.ts @@ -0,0 +1,27 @@ +import { useNavigation } from '@react-navigation/native'; +import { useEffect } from 'react'; + +/** + * This hook enables the drawer swipe gesture when the screen is focused and disables it when the screen is blurred. + */ + +export function useEnableDrawer(): void { + const navigation = useNavigation(); + useEffect(() => { + const tabNavigator = navigation.getParent(); // This is the TabNavigator + const drawerNavigator = tabNavigator?.getParent(); // This is the DrawerNavigator + + const unsubscribeFocus = navigation.addListener('focus', () => { + drawerNavigator?.setOptions({ swipeEnabled: true }); + }); + + const unsubscribeBlur = navigation.addListener('blur', () => { + drawerNavigator?.setOptions({ swipeEnabled: false }); + }); + + return () => { + unsubscribeFocus(); + unsubscribeBlur(); + }; + }, [navigation]); +} diff --git a/apps/mobile/src/navigation/DrawerNavigator.tsx b/apps/mobile/src/navigation/DrawerNavigator.tsx index a72b4b867..211eeb4fc 100644 --- a/apps/mobile/src/navigation/DrawerNavigator.tsx +++ b/apps/mobile/src/navigation/DrawerNavigator.tsx @@ -16,6 +16,7 @@ export default function DrawerNavigator() { initialRouteName="Home" screenOptions={{ headerShown: false, + swipeEnabled: false, drawerStyle: { backgroundColor: tw.color('app-darkBox'), width: '70%', diff --git a/apps/mobile/src/navigation/SearchStack.tsx b/apps/mobile/src/navigation/SearchStack.tsx index 0f0e4388e..ef4edb250 100644 --- a/apps/mobile/src/navigation/SearchStack.tsx +++ b/apps/mobile/src/navigation/SearchStack.tsx @@ -10,7 +10,12 @@ const Stack = createNativeStackNavigator(); export default function SearchStack() { return ( - + - {TabScreens.map((screen, index) => ( - ({ - tabBarLabel: screen.label, - tabBarLabelStyle: screen.labelStyle, - /** - * TouchableWithoutFeedback is used to prevent Android ripple effect - * State is being used to control the animation and make Rive work - * Tab.Screen listeners are needed because if a user taps on the tab text only, the animation won't play - * This may be revisited in the future to update accordingly - */ - tabBarIcon: () => ( - { - navigation.navigate(screen.name); - setActiveIndex(index); - }} - > - {screen.icon} - - ), - tabBarTestID: screen.testID - })} - listeners={() => ({ - focus: () => { - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); - setActiveIndex(index); - } - })} - /> - ))} + {TabScreens.map((screen, index) => { + return ( + ({ + tabBarLabel: screen.label, + tabBarLabelStyle: screen.labelStyle, + /** + * TouchableWithoutFeedback is used to prevent Android ripple effect + * State is being used to control the animation and make Rive work + * Tab.Screen listeners are needed because if a user taps on the tab text only, the animation won't play + * This may be revisited in the future to update accordingly + */ + tabBarIcon: () => ( + { + navigation.navigate(screen.name); + setActiveIndex(index); + }} + > + {screen.icon} + + ), + tabBarTestID: screen.testID + })} + listeners={() => ({ + focus: () => { + Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); + setActiveIndex(index); + } + })} + /> + ); + })} ); } diff --git a/apps/mobile/src/navigation/tabs/BrowseStack.tsx b/apps/mobile/src/navigation/tabs/BrowseStack.tsx index e7ce71588..5f38af1e1 100644 --- a/apps/mobile/src/navigation/tabs/BrowseStack.tsx +++ b/apps/mobile/src/navigation/tabs/BrowseStack.tsx @@ -16,7 +16,12 @@ const Stack = createNativeStackNavigator(); export default function BrowseStack() { return ( - + (); export default function OverviewStack() { return ( - + + {/* */} diff --git a/apps/mobile/src/screens/browse/Locations.tsx b/apps/mobile/src/screens/browse/Locations.tsx index e482baa9b..e951c2d62 100644 --- a/apps/mobile/src/screens/browse/Locations.tsx +++ b/apps/mobile/src/screens/browse/Locations.tsx @@ -16,9 +16,10 @@ import { useSearchStore } from '~/stores/searchStore'; interface Props { viewStyle?: 'grid' | 'list'; + navToSettings?: boolean; // on press, navigate to settings } -export default function LocationsScreen({ viewStyle }: Props) { +export default function LocationsScreen({ viewStyle, navToSettings }: Props) { const locationsQuery = useLibraryQuery(['locations.list']); const locations = locationsQuery.data; const { search } = useSearchStore(); @@ -67,12 +68,18 @@ export default function LocationsScreen({ viewStyle }: Props) { numColumns={viewStyle === 'grid' ? 3 : 1} renderItem={({ item }) => ( + onPress={() => { + if (navToSettings) { + return navigation.navigate('SettingsStack', { + screen: 'EditLocationSettings', + params: { id: item.id } + }); + } navigation.navigate('BrowseStack', { screen: 'Location', params: { id: item.id } - }) - } + }); + }} editLocation={() => navigation.navigate('SettingsStack', { screen: 'EditLocationSettings', diff --git a/apps/mobile/src/screens/network/Network.tsx b/apps/mobile/src/screens/network/Network.tsx index 92e7ed22c..1725a8dd4 100644 --- a/apps/mobile/src/screens/network/Network.tsx +++ b/apps/mobile/src/screens/network/Network.tsx @@ -1,10 +1,12 @@ import { Text } from 'react-native'; import { Icon } from '~/components/icons/Icon'; import ScreenContainer from '~/components/layout/ScreenContainer'; +import { useEnableDrawer } from '~/hooks/useEnableDrawer'; import { tw } from '~/lib/tailwind'; import { NetworkStackScreenProps } from '~/navigation/tabs/NetworkStack'; export default function NetworkScreen({ navigation }: NetworkStackScreenProps<'Network'>) { + useEnableDrawer(); return ( diff --git a/apps/mobile/src/screens/overview/Overview.tsx b/apps/mobile/src/screens/overview/Overview.tsx index 7cc71c35f..c4f19fe9e 100644 --- a/apps/mobile/src/screens/overview/Overview.tsx +++ b/apps/mobile/src/screens/overview/Overview.tsx @@ -5,6 +5,7 @@ import Cloud from '~/components/overview/Cloud'; import Devices from '~/components/overview/Devices'; import Locations from '~/components/overview/Locations'; import OverviewStats from '~/components/overview/OverviewStats'; +import { useEnableDrawer } from '~/hooks/useEnableDrawer'; const EMPTY_STATISTICS = { id: 0, @@ -26,6 +27,7 @@ export default function OverviewScreen() { // Running the query here so the data is already available for settings screen useLibraryQuery(['sync.enabled']); + useEnableDrawer(); return ( diff --git a/apps/mobile/src/screens/settings/Settings.tsx b/apps/mobile/src/screens/settings/Settings.tsx index 1259c4216..df3f93666 100644 --- a/apps/mobile/src/screens/settings/Settings.tsx +++ b/apps/mobile/src/screens/settings/Settings.tsx @@ -20,6 +20,7 @@ import { Platform, SectionList, Text, TouchableWithoutFeedback, View } from 'rea import { DebugState, useDebugState, useDebugStateEnabler, useLibraryQuery } from '@sd/client'; import ScreenContainer from '~/components/layout/ScreenContainer'; import { SettingsItem } from '~/components/settings/SettingsItem'; +import { useEnableDrawer } from '~/hooks/useEnableDrawer'; import { tw, twStyle } from '~/lib/tailwind'; import { SettingsStackParamList, @@ -200,6 +201,8 @@ export default function SettingsScreen({ navigation }: SettingsStackScreenProps< // eslint-disable-next-line react-hooks/exhaustive-deps }, [navigation]); + useEnableDrawer(); + return ( { - return ; + return ; }; export default LocationSettingsScreen; diff --git a/interface/app/$libraryId/Explorer/ContextMenu/SharedItems.tsx b/interface/app/$libraryId/Explorer/ContextMenu/SharedItems.tsx index f8115633f..1c79d03ac 100644 --- a/interface/app/$libraryId/Explorer/ContextMenu/SharedItems.tsx +++ b/interface/app/$libraryId/Explorer/ContextMenu/SharedItems.tsx @@ -63,7 +63,7 @@ export const OpenQuickView = () => { return ( (getQuickPreviewStore().open = true)} /> diff --git a/interface/app/$libraryId/Explorer/Inspector/index.tsx b/interface/app/$libraryId/Explorer/Inspector/index.tsx index dcdfff4b9..08b3255d0 100644 --- a/interface/app/$libraryId/Explorer/Inspector/index.tsx +++ b/interface/app/$libraryId/Explorer/Inspector/index.tsx @@ -395,6 +395,7 @@ export const SingleItemMetadata = ({ item }: { item: ExplorerItem }) => { {t('add_tag')}} side="left" + className="z-[101]" sideOffset={5} alignOffset={-10} > diff --git a/interface/components/ColorPicker.tsx b/interface/components/ColorPicker.tsx index 0c3d8a92f..68ad2186e 100644 --- a/interface/components/ColorPicker.tsx +++ b/interface/components/ColorPicker.tsx @@ -19,7 +19,7 @@ export const ColorPicker = ({ className, ...props }: Prop style={{ backgroundColor: field.value }} /> } - className="p-3" + className="relative z-[110] p-3" sideOffset={5} > diff --git a/packages/ui/src/Dialog.tsx b/packages/ui/src/Dialog.tsx index 49810c1ec..6efbfeb3b 100644 --- a/packages/ui/src/Dialog.tsx +++ b/packages/ui/src/Dialog.tsx @@ -261,14 +261,14 @@ export function Dialog({ show ? ( props.ignoreClickOutside && e.preventDefault()