92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
import { Ionicons } from '@expo/vector-icons'
|
|
import { Block, Text } from '@share/components'
|
|
import { Tabs } from 'expo-router'
|
|
import { observer } from 'mobx-react-lite'
|
|
import React, { useEffect } from 'react'
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
|
|
import { Colors } from '@/constants/theme'
|
|
import { userStore } from '@/stores'
|
|
|
|
interface BottomNavProps {
|
|
currentRoute: string
|
|
onRouteChange: (route: string) => void
|
|
theme?: 'light' | 'dark'
|
|
}
|
|
|
|
const navItems = [
|
|
{ id: 'index', label: '探索', iconName: 'compass-outline' },
|
|
{ id: 'generate', label: '生成', iconName: 'image-outline' },
|
|
{ id: 'sync', label: '同步', iconName: 'refresh' },
|
|
// { id: 'explore', label: '蓝牙调试', iconName: 'person-outline' },
|
|
]
|
|
|
|
function renderNavItem(item: (typeof navItems)[0], isActive: boolean, onRouteChange: (route: string) => void) {
|
|
const { id, label, iconName } = item
|
|
return (
|
|
<Block
|
|
key={id}
|
|
className={`relative h-[48px] flex-1 flex-row items-center justify-center rounded-full ${isActive ? 'flex-[1.4]' : ''}`}
|
|
onClick={() => onRouteChange(id)}
|
|
>
|
|
{isActive && (
|
|
<Block className="absolute inset-0 rounded-full border-2 border-black bg-accent shadow-[2px_2px_0px_rgba(0,0,0,1)]" />
|
|
)}
|
|
|
|
<Block className="relative z-10 flex-row items-center justify-center gap-[4px]">
|
|
<Ionicons color={isActive ? Colors.light.text : '#9CA3AF'} name={iconName as any} size={isActive ? 20 : 24} />
|
|
{isActive && (
|
|
<Text className="text-[12px] font-[900] text-black" numberOfLines={1}>
|
|
{label}
|
|
</Text>
|
|
)}
|
|
</Block>
|
|
</Block>
|
|
)
|
|
}
|
|
|
|
export const BottomNav = ({ currentRoute, onRouteChange }: BottomNavProps) => {
|
|
const insets = useSafeAreaInsets()
|
|
return (
|
|
<Block className="absolute inset-x-[16px] z-50" style={{ bottom: 24, paddingBottom: insets.bottom }}>
|
|
<Block className="relative flex-row items-center justify-between overflow-hidden rounded-full border-[3px] border-black bg-fg p-[8px] shadow-[5px_5px_0px_rgba(0,0,0,1)]">
|
|
{navItems.map((item) => renderNavItem(item, currentRoute === item.id, onRouteChange))}
|
|
</Block>
|
|
</Block>
|
|
)
|
|
}
|
|
|
|
const CustomTabBar = observer(function CustomTabBar(props: any) {
|
|
const routes = props.state.routes
|
|
const activeIndex: number = props.state.index
|
|
const activeRouteName = routes[activeIndex]?.name || 'index'
|
|
const isAuthenticated = userStore.isAuthenticated
|
|
|
|
console.log('isAuthenticated==========', isAuthenticated)
|
|
|
|
const handleChange = (route: string) => {
|
|
if (!isAuthenticated && route !== 'index') {
|
|
props.navigation.push('auth')
|
|
return
|
|
}
|
|
props.navigation.navigate(route)
|
|
}
|
|
return <BottomNav currentRoute={activeRouteName} onRouteChange={handleChange} />
|
|
})
|
|
|
|
export default function Layout() {
|
|
useEffect(() => {
|
|
// 配置WebBrowser
|
|
// const setupWebBrowser = async () => {
|
|
// try {
|
|
// await configureWebBrowser()
|
|
// } catch (error) {
|
|
// console.warn('Failed to configure WebBrowser:', error)
|
|
// }
|
|
// }
|
|
// setupWebBrowser()
|
|
}, [])
|
|
|
|
return <Tabs screenOptions={{ headerShown: false }} tabBar={(props: any) => <CustomTabBar {...props} />}></Tabs>
|
|
}
|