diff --git a/front/Navigation.tsx b/front/Navigation.tsx index c1173c8..af4c388 100644 --- a/front/Navigation.tsx +++ b/front/Navigation.tsx @@ -35,13 +35,16 @@ import DiscoveryView from './views/V2/DiscoveryView'; import MusicView from './views/MusicView'; import Leaderboardiew from './views/LeaderboardView'; import { LinearGradient } from 'expo-linear-gradient'; +import ScaffoldMobileCC from './components/UI/ScaffoldMobileCC'; const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); const Tabs = () => { return ( - + {Object.entries(tabRoutes).map(([name, route], routeIndex) => ( ; onPress?: () => void | Promise; + onLongPress?: () => void | Promise; isDisabled?: boolean; icon?: Icon; iconVariant?: 'Bold' | 'Outline'; @@ -22,6 +23,7 @@ const ButtonBase: React.FC = ({ title, style, onPress, + onLongPress, isDisabled, icon, iconImage, @@ -123,6 +125,18 @@ const ButtonBase: React.FC = ({ } } }} + onLongPress={async () => { + if (onLongPress && !isDisabled) { + setLoading(true); + try { + await onLongPress(); + } catch (error) { + console.error(error); + } finally { + setLoading(false); + } + } + }} isDisabled={isDisabled} isOutlined={type === 'outlined'} > diff --git a/front/components/UI/InteractiveBase.tsx b/front/components/UI/InteractiveBase.tsx index 4bf7288..16d1916 100644 --- a/front/components/UI/InteractiveBase.tsx +++ b/front/components/UI/InteractiveBase.tsx @@ -5,6 +5,7 @@ import { Animated, StyleProp, ViewStyle } from 'react-native'; interface InteractiveBaseProps { children?: React.ReactNode; onPress?: () => Promise; + onLongPress?: () => Promise; isDisabled?: boolean; isOutlined?: boolean; focusable?: boolean; @@ -44,6 +45,7 @@ interface InteractiveBaseProps { const InteractiveBase: React.FC = ({ children, onPress, + onLongPress, style, styleAnimate, isDisabled = false, @@ -183,10 +185,6 @@ const InteractiveBase: React.FC = ({ useNativeDriver: false, }), ]).start(); - - if (onPress && !isDisabled) { - onPress(); - } }; // Mouse Leave const handleMouseLeave = () => { @@ -248,6 +246,8 @@ const InteractiveBase: React.FC = ({ onPressIn={handlePressIn} onPressOut={handlePressOut} onHoverOut={handleMouseLeave} + onPress={onPress} + onLongPress={onLongPress} > {children} diff --git a/front/components/UI/ScaffoldCC.tsx b/front/components/UI/ScaffoldCC.tsx index a4dc351..71f77c1 100644 --- a/front/components/UI/ScaffoldCC.tsx +++ b/front/components/UI/ScaffoldCC.tsx @@ -28,8 +28,6 @@ type ScaffoldCCProps = { const ScaffoldCC = ({ children, routeName, - withPadding = true, - enableScroll = true, }: ScaffoldCCProps) => { const userQuery = useQuery(API.getUserInfo); const screenSize = useBreakpointValue({ base: 'small', md: 'big' }); @@ -48,12 +46,8 @@ const ScaffoldCC = ({ {screenSize === 'small' ? ( {children} @@ -63,7 +57,7 @@ const ScaffoldCC = ({ logo={logo?.at(0)?.uri ?? ''} routeName={routeName} menu={menu} - widthPadding={withPadding} + widthPadding={true} > {children} diff --git a/front/components/UI/ScaffoldMobileCC.tsx b/front/components/UI/ScaffoldMobileCC.tsx index c4c1070..d286b61 100644 --- a/front/components/UI/ScaffoldMobileCC.tsx +++ b/front/components/UI/ScaffoldMobileCC.tsx @@ -1,79 +1,70 @@ -/* eslint-disable no-mixed-spaces-and-tabs */ import { View } from 'react-native'; import { Flex, useMediaQuery, useTheme } from 'native-base'; import ButtonBase from './ButtonBase'; -import { Icon } from 'iconsax-react-native'; -import { useNavigation } from '../../Navigation'; -import User from '../../models/User'; +import { Discover } from 'iconsax-react-native'; import { translate } from '../../i18n/i18n'; +import { BottomTabBarProps } from '@react-navigation/bottom-tabs'; +import { ComponentProps } from 'react'; -type ScaffoldMobileCCProps = { - children?: React.ReactNode; - user: User; - logo: string; - routeName: string; - widthPadding: boolean; - enableScroll: boolean; - menu: readonly { - type: 'main' | 'sub'; - title: - | 'menuDiscovery' - | 'menuProfile' - | 'menuMusic' - | 'menuSearch' - | 'menuLeaderBoard' - | 'menuSettings'; - icon: Icon; - link: string; - }[]; -}; - -const ScaffoldMobileCC = (props: ScaffoldMobileCCProps) => { - const navigation = useNavigation(); +const ScaffoldMobileCC = ({ state, descriptors, navigation }: BottomTabBarProps) => { const [isSmallScreen] = useMediaQuery({ maxWidth: 400 }); const { colors } = useTheme(); return ( - - + - {props.children} - - - - {props.menu.map((value) => ( + {state.routes.map((route, index) => { + const { options } = descriptors[route.key]!; + const label = options.title !== undefined ? options.title : route.name; + const isFocused = state.index === index; + + return ( navigation.navigate(value.link as never)} + isDisabled={isFocused} + iconVariant={isFocused ? 'Bold' : 'Outline'} + onPress={() => { + const event = navigation.emit({ + type: 'tabPress', + target: route.key, + canPreventDefault: true, + }); + + if (!isFocused && !event.defaultPrevented) { + navigation.navigate(route.name, route.params); + } + }} + onLongPress={() => { + navigation.emit({ + type: 'tabLongPress', + target: route.key, + }); + }} /> - ))} - - + ); + })} + ); }; -export default ScaffoldMobileCC; +// This is needed to bypass a bug in react-navigation that calls custom tabBars weirdly +const Wrapper = (props: ComponentProps) => { + return ; +} + +export default Wrapper;