更新ios
This commit is contained in:
413
MeAgent/navigation/Menu.js
Normal file
413
MeAgent/navigation/Menu.js
Normal file
@@ -0,0 +1,413 @@
|
||||
import React from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
Image,
|
||||
TouchableOpacity,
|
||||
Linking,
|
||||
} from "react-native";
|
||||
import { Block, Text, theme } from "galio-framework";
|
||||
import { useSafeArea } from "react-native-safe-area-context";
|
||||
import { Box, HStack, VStack, Icon, Pressable, Spinner } from "native-base";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { LinearGradient } from "expo-linear-gradient";
|
||||
import Images from "../constants/Images";
|
||||
import { DrawerItem as DrawerCustomItem } from "../components/index";
|
||||
import { useAuth } from "../src/contexts/AuthContext";
|
||||
|
||||
const { width } = Dimensions.get("screen");
|
||||
|
||||
// 金色主题色
|
||||
const GOLD_PRIMARY = '#D4AF37';
|
||||
|
||||
// 用户卡片组件
|
||||
const UserCard = ({ navigation }) => {
|
||||
const { user, isLoggedIn, isLoading, subscription, logout } = useAuth();
|
||||
|
||||
const handleLoginPress = () => {
|
||||
navigation.closeDrawer();
|
||||
// 使用 getParent 获取根导航器来导航到 Login
|
||||
navigation.getParent()?.navigate("Login");
|
||||
};
|
||||
|
||||
const handleLogoutPress = async () => {
|
||||
await logout();
|
||||
};
|
||||
|
||||
// 获取订阅显示文本
|
||||
const getSubscriptionText = () => {
|
||||
if (!subscription || !subscription.is_active) {
|
||||
return "免费用户";
|
||||
}
|
||||
const typeMap = { pro: "Pro 会员", max: "Max 会员" };
|
||||
return typeMap[subscription.type] || "免费用户";
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box px={4} py={4} mb={2}>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Spinner size="sm" color="primary.500" />
|
||||
<Text color="#8898AA" style={{ fontFamily: "open-sans-regular" }}>
|
||||
加载中...
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<Pressable onPress={handleLoginPress}>
|
||||
<Box
|
||||
mx={3}
|
||||
mb={3}
|
||||
p={4}
|
||||
bg="rgba(124, 58, 237, 0.1)"
|
||||
borderWidth={1}
|
||||
borderColor="rgba(124, 58, 237, 0.3)"
|
||||
borderRadius={12}
|
||||
>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={10}
|
||||
h={10}
|
||||
bg="rgba(124, 58, 237, 0.2)"
|
||||
borderRadius={20}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Icon as={Ionicons} name="person-outline" size="md" color="#7C3AED" />
|
||||
</Box>
|
||||
<VStack flex={1}>
|
||||
<Text
|
||||
color="#333"
|
||||
style={{ fontFamily: "open-sans-bold", fontSize: 14 }}
|
||||
>
|
||||
登录/注册
|
||||
</Text>
|
||||
<Text
|
||||
color="#8898AA"
|
||||
style={{ fontFamily: "open-sans-regular", fontSize: 12 }}
|
||||
>
|
||||
登录解锁更多功能
|
||||
</Text>
|
||||
</VStack>
|
||||
<Icon as={Ionicons} name="chevron-forward" size="sm" color="#8898AA" />
|
||||
</HStack>
|
||||
</Box>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
// 已登录状态
|
||||
return (
|
||||
<Box mx={3} mb={3} p={4} bg="#F8F9FE" borderRadius={12}>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={10}
|
||||
h={10}
|
||||
bg="#7C3AED"
|
||||
borderRadius={20}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Text style={{ color: "white", fontFamily: "open-sans-bold", fontSize: 16 }}>
|
||||
{(user?.username || user?.nickname || "U").charAt(0).toUpperCase()}
|
||||
</Text>
|
||||
</Box>
|
||||
<VStack flex={1}>
|
||||
<Text
|
||||
color="#333"
|
||||
style={{ fontFamily: "open-sans-bold", fontSize: 14 }}
|
||||
>
|
||||
{user?.nickname || user?.username || "用户"}
|
||||
</Text>
|
||||
<HStack alignItems="center" space={1}>
|
||||
<Box
|
||||
px={1.5}
|
||||
py={0.5}
|
||||
bg={subscription?.is_active ? "rgba(16, 185, 129, 0.1)" : "rgba(100, 116, 139, 0.1)"}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: "open-sans-regular",
|
||||
fontSize: 10,
|
||||
color: subscription?.is_active ? "#10B981" : "#64748B",
|
||||
}}
|
||||
>
|
||||
{getSubscriptionText()}
|
||||
</Text>
|
||||
</Box>
|
||||
</HStack>
|
||||
</VStack>
|
||||
<Pressable onPress={handleLogoutPress}>
|
||||
<Icon as={Ionicons} name="log-out-outline" size="sm" color="#F43F5E" />
|
||||
</Pressable>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
function CustomDrawerContent({
|
||||
drawerPosition,
|
||||
navigation,
|
||||
profile,
|
||||
focused,
|
||||
state,
|
||||
...rest
|
||||
}) {
|
||||
const insets = useSafeArea();
|
||||
// 菜单项配置
|
||||
const screens = [
|
||||
{ title: "事件中心", navigateTo: "EventsDrawer", icon: "flash", gradient: ["#7C3AED", "#A78BFA"] },
|
||||
{ title: "市场热点", navigateTo: "MarketDrawer", icon: "flame", gradient: ["#F59E0B", "#FBBF24"] },
|
||||
{ title: "概念中心", navigateTo: "ConceptsDrawer", icon: "bulb", gradient: ["#06B6D4", "#22D3EE"] },
|
||||
{ title: "我的自选", navigateTo: "WatchlistDrawer", icon: "star", gradient: ["#EC4899", "#F472B6"] },
|
||||
{ title: "个人中心", navigateTo: "ProfileDrawerNew", icon: "person", gradient: ["#8B5CF6", "#A78BFA"] },
|
||||
];
|
||||
return (
|
||||
<Box flex={1} bg="#0F172A">
|
||||
{/* 品牌头部 - 黑金主题 */}
|
||||
<Box px={4} py={5} style={{ paddingTop: insets.top + 16 }}>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Image
|
||||
source={Images.Logo}
|
||||
style={{ width: 40, height: 40, borderRadius: 10 }}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
<VStack>
|
||||
<Text style={{ color: GOLD_PRIMARY, fontFamily: "open-sans-bold", fontSize: 18 }}>
|
||||
价值前沿
|
||||
</Text>
|
||||
<Text style={{ color: "rgba(212, 175, 55, 0.6)", fontFamily: "open-sans-regular", fontSize: 11 }}>
|
||||
VALUE FRONTIER
|
||||
</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
|
||||
<ScrollView style={{ flex: 1 }} showsVerticalScrollIndicator={false}>
|
||||
{/* 用户卡片 - 深色版本 */}
|
||||
<Box mx={4} mb={4}>
|
||||
<UserCardDark navigation={navigation} />
|
||||
</Box>
|
||||
|
||||
{/* 导航菜单 */}
|
||||
<Box px={4}>
|
||||
{screens.map((item, index) => {
|
||||
const isFocused = state.index === index;
|
||||
return (
|
||||
<Pressable
|
||||
key={index}
|
||||
onPress={() => navigation.navigate(item.navigateTo)}
|
||||
mb={2}
|
||||
>
|
||||
{isFocused ? (
|
||||
<LinearGradient
|
||||
colors={item.gradient}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 0 }}
|
||||
style={{
|
||||
borderRadius: 12,
|
||||
padding: 14,
|
||||
}}
|
||||
>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={8}
|
||||
h={8}
|
||||
bg="rgba(255, 255, 255, 0.25)"
|
||||
borderRadius={8}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Icon as={Ionicons} name={item.icon} size="sm" color="white" />
|
||||
</Box>
|
||||
<Text style={{ fontFamily: "open-sans-bold", fontSize: 15, color: "white" }}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</HStack>
|
||||
</LinearGradient>
|
||||
) : (
|
||||
<Box
|
||||
px={3.5}
|
||||
py={3.5}
|
||||
bg="rgba(255, 255, 255, 0.05)"
|
||||
borderRadius={12}
|
||||
borderWidth={1}
|
||||
borderColor="rgba(255, 255, 255, 0.08)"
|
||||
>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={8}
|
||||
h={8}
|
||||
bg={`${item.gradient[0]}20`}
|
||||
borderRadius={8}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Icon as={Ionicons} name={item.icon} size="sm" color={item.gradient[0]} />
|
||||
</Box>
|
||||
<Text style={{ fontFamily: "open-sans-regular", fontSize: 15, color: "rgba(255, 255, 255, 0.8)" }}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</HStack>
|
||||
</Box>
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
|
||||
{/* 底部版本信息 */}
|
||||
<Box mt={8} px={4} mb={4}>
|
||||
<Box
|
||||
borderTopWidth={1}
|
||||
borderTopColor="rgba(255, 255, 255, 0.08)"
|
||||
pt={4}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: "open-sans-regular",
|
||||
fontSize: 11,
|
||||
color: "rgba(255, 255, 255, 0.4)",
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
价值前沿 v1.0.0
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</ScrollView>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// 深色主题用户卡片
|
||||
const UserCardDark = ({ navigation }) => {
|
||||
const { user, isLoggedIn, isLoading, subscription, logout } = useAuth();
|
||||
|
||||
const handleLoginPress = () => {
|
||||
navigation.closeDrawer();
|
||||
navigation.getParent()?.navigate("Login");
|
||||
};
|
||||
|
||||
const handleLogoutPress = async () => {
|
||||
await logout();
|
||||
};
|
||||
|
||||
const getSubscriptionText = () => {
|
||||
if (!subscription || !subscription.is_active) return "免费用户";
|
||||
const typeMap = { pro: "Pro 会员", max: "Max 会员" };
|
||||
return typeMap[subscription.type] || "免费用户";
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<HStack alignItems="center" space={3} py={2}>
|
||||
<Spinner size="sm" color="primary.500" />
|
||||
<Text style={{ color: "rgba(255,255,255,0.6)", fontFamily: "open-sans-regular" }}>
|
||||
加载中...
|
||||
</Text>
|
||||
</HStack>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<Pressable onPress={handleLoginPress}>
|
||||
<Box
|
||||
p={4}
|
||||
bg="rgba(124, 58, 237, 0.15)"
|
||||
borderWidth={1}
|
||||
borderColor="rgba(124, 58, 237, 0.3)"
|
||||
borderRadius={12}
|
||||
>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={10}
|
||||
h={10}
|
||||
bg="rgba(124, 58, 237, 0.3)"
|
||||
borderRadius={20}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Icon as={Ionicons} name="person-outline" size="md" color="#A78BFA" />
|
||||
</Box>
|
||||
<VStack flex={1}>
|
||||
<Text style={{ fontFamily: "open-sans-bold", fontSize: 14, color: "white" }}>
|
||||
登录/注册
|
||||
</Text>
|
||||
<Text style={{ fontFamily: "open-sans-regular", fontSize: 12, color: "rgba(255,255,255,0.5)" }}>
|
||||
登录解锁更多功能
|
||||
</Text>
|
||||
</VStack>
|
||||
<Icon as={Ionicons} name="chevron-forward" size="sm" color="rgba(255,255,255,0.5)" />
|
||||
</HStack>
|
||||
</Box>
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box p={4} bg="rgba(255, 255, 255, 0.08)" borderRadius={12}>
|
||||
<HStack alignItems="center" space={3}>
|
||||
<Box
|
||||
w={10}
|
||||
h={10}
|
||||
bg="#7C3AED"
|
||||
borderRadius={20}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<Text style={{ color: "white", fontFamily: "open-sans-bold", fontSize: 16 }}>
|
||||
{(user?.username || user?.nickname || "U").charAt(0).toUpperCase()}
|
||||
</Text>
|
||||
</Box>
|
||||
<VStack flex={1}>
|
||||
<Text style={{ fontFamily: "open-sans-bold", fontSize: 14, color: "white" }}>
|
||||
{user?.nickname || user?.username || "用户"}
|
||||
</Text>
|
||||
<Box
|
||||
alignSelf="flex-start"
|
||||
px={1.5}
|
||||
py={0.5}
|
||||
bg={subscription?.is_active ? "rgba(16, 185, 129, 0.2)" : "rgba(100, 116, 139, 0.2)"}
|
||||
borderRadius={4}
|
||||
mt={0.5}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: "open-sans-regular",
|
||||
fontSize: 10,
|
||||
color: subscription?.is_active ? "#10B981" : "#94A3B8",
|
||||
}}
|
||||
>
|
||||
{getSubscriptionText()}
|
||||
</Text>
|
||||
</Box>
|
||||
</VStack>
|
||||
<Pressable onPress={handleLogoutPress}>
|
||||
<Icon as={Ionicons} name="log-out-outline" size="sm" color="#F43F5E" />
|
||||
</Pressable>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
paddingHorizontal: 28,
|
||||
paddingBottom: theme.SIZES.BASE,
|
||||
paddingTop: theme.SIZES.BASE * 3,
|
||||
justifyContent: "center",
|
||||
},
|
||||
});
|
||||
|
||||
export default CustomDrawerContent;
|
||||
Reference in New Issue
Block a user