mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-02-04 03:36:29 +08:00
- Hide live streaming tab in mobile navigation components - Hide remote input and live stream configurations in settings - Hide API configuration description text on mobile - Disable HTTP server startup on mobile devices to save resources This streamlines the mobile interface while preserving full functionality on tablet and TV platforms.
126 lines
3.4 KiB
TypeScript
126 lines
3.4 KiB
TypeScript
import React from 'react';
|
|
import { View, StyleSheet, TouchableOpacity, Text, Platform } from 'react-native';
|
|
import { useRouter, usePathname } from 'expo-router';
|
|
import { Home, Search, Heart, Settings, Tv } from 'lucide-react-native';
|
|
import { Colors } from '@/constants/Colors';
|
|
import { useResponsiveLayout } from '@/hooks/useResponsiveLayout';
|
|
import { DeviceUtils } from '@/utils/DeviceUtils';
|
|
|
|
interface TabItem {
|
|
key: string;
|
|
label: string;
|
|
icon: React.ComponentType<any>;
|
|
route: string;
|
|
}
|
|
|
|
const tabs: TabItem[] = [
|
|
{ key: 'home', label: '首页', icon: Home, route: '/' },
|
|
{ key: 'search', label: '搜索', icon: Search, route: '/search' },
|
|
{ key: 'live', label: '直播', icon: Tv, route: '/live' },
|
|
{ key: 'favorites', label: '收藏', icon: Heart, route: '/favorites' },
|
|
{ key: 'settings', label: '设置', icon: Settings, route: '/settings' },
|
|
];
|
|
|
|
const MobileBottomTabNavigator: React.FC = () => {
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
const { spacing, deviceType } = useResponsiveLayout();
|
|
|
|
// 在手机端过滤掉直播 tab
|
|
const filteredTabs = tabs.filter(tab =>
|
|
deviceType !== 'mobile' || tab.key !== 'live'
|
|
);
|
|
|
|
const handleTabPress = (route: string) => {
|
|
if (route === '/') {
|
|
router.push('/');
|
|
} else {
|
|
router.push(route as any);
|
|
}
|
|
};
|
|
|
|
const isTabActive = (route: string) => {
|
|
if (route === '/' && pathname === '/') return true;
|
|
if (route !== '/' && pathname === route) return true;
|
|
return false;
|
|
};
|
|
|
|
const dynamicStyles = createStyles(spacing);
|
|
|
|
return (
|
|
<View style={dynamicStyles.container}>
|
|
{filteredTabs.map((tab) => {
|
|
const isActive = isTabActive(tab.route);
|
|
const IconComponent = tab.icon;
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
key={tab.key}
|
|
style={[dynamicStyles.tab, isActive && dynamicStyles.activeTab]}
|
|
onPress={() => handleTabPress(tab.route)}
|
|
activeOpacity={0.7}
|
|
>
|
|
<IconComponent
|
|
size={20}
|
|
color={isActive ? Colors.dark.primary : '#888'}
|
|
strokeWidth={isActive ? 2.5 : 2}
|
|
/>
|
|
<Text style={[
|
|
dynamicStyles.tabLabel,
|
|
isActive && dynamicStyles.activeTabLabel
|
|
]}>
|
|
{tab.label}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const createStyles = (spacing: number) => {
|
|
const minTouchTarget = DeviceUtils.getMinTouchTargetSize();
|
|
|
|
return StyleSheet.create({
|
|
container: {
|
|
flexDirection: 'row',
|
|
backgroundColor: '#1c1c1e',
|
|
borderTopWidth: 1,
|
|
borderTopColor: '#333',
|
|
paddingTop: spacing / 2,
|
|
paddingBottom: Platform.OS === 'ios' ? spacing * 2 : spacing,
|
|
paddingHorizontal: spacing,
|
|
shadowColor: '#000',
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: -2,
|
|
},
|
|
shadowOpacity: 0.1,
|
|
shadowRadius: 4,
|
|
elevation: 10,
|
|
},
|
|
tab: {
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
minHeight: minTouchTarget,
|
|
paddingVertical: spacing / 2,
|
|
borderRadius: 8,
|
|
},
|
|
activeTab: {
|
|
backgroundColor: 'rgba(64, 156, 255, 0.1)',
|
|
},
|
|
tabLabel: {
|
|
fontSize: 11,
|
|
color: '#888',
|
|
marginTop: 2,
|
|
fontWeight: '500',
|
|
},
|
|
activeTabLabel: {
|
|
color: Colors.dark.primary,
|
|
fontWeight: '600',
|
|
},
|
|
});
|
|
};
|
|
|
|
export default MobileBottomTabNavigator; |