## 核心功能 ### 1. 全局认证架构 - 新增 AuthProvider:全局认证上下文,管理登录状态和Modal - 新增 useAuthGuard Hook:提供 requireAuth 认证拦截功能 - 新增 AuthGuard 组件:包装需要认证的组件 - 新增 AuthPrompt 组件:多种样式的登录引导组件 ### 2. 登录体验优化 - LoginModal 已优化为底部抽屉式设计 - 登录成功后自动关闭Modal并恢复用户操作 - 支持队列机制,多个认证检查依次执行 ### 3. 页面架构调整 - 根布局集成 AuthProvider - 移除 Tabs 布局的重定向逻辑 - Explore 页面添加认证保护,显示登录提示 ### 4. API安全增强 - 新增 TokenManager:完整的Token生命周期管理 - 新增 SecureClient:安全API客户端,自动处理认证 - 更新 API 客户端:支持认证头和自动Token刷新 ### 5. 文档完善 - AUTH_SYSTEM.md:完整的认证系统使用指南 - AUTH_UPGRADE_SUMMARY.md:升级总结文档 ## 技术亮点 ✅ TypeScript 完整支持,编译时类型检查 ✅ React 最佳实践,合理使用 Hooks 和 Context ✅ 优雅的错误处理,友好的用户提示 ✅ 流畅的动画效果,原生级用户体验 ## 核心优势 - 流畅:无需页面跳转,Modal即用即走 - 智能:自动检测登录需求,无需手动判断 - 安全:完整Token管理和自动刷新机制 - 灵活:多种认证组件满足不同场景 - 易用:详细文档和示例,快速上手 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
206 lines
5.6 KiB
TypeScript
206 lines
5.6 KiB
TypeScript
import { useMemo, useState } from 'react';
|
|
import { ScrollView, StyleSheet, View, TouchableOpacity, Text } from 'react-native';
|
|
|
|
import {
|
|
CategoryTabs,
|
|
CommunityGrid,
|
|
FeatureCarousel,
|
|
Header,
|
|
PageLayout,
|
|
SectionHeader,
|
|
StatusBarSpacer,
|
|
type CommunityItem,
|
|
type FeatureItem,
|
|
} from '@/components/bestai';
|
|
import { useAuth } from '@/hooks/use-auth';
|
|
import { useAuthGuard } from '@/hooks/use-auth-guard';
|
|
|
|
const categories = [
|
|
{ id: 'visual-effects', label: 'Visual Effects' },
|
|
{ id: 'higgsfield-soul', label: 'Higgsfield Soul' },
|
|
{ id: 'higgsfield-apps', label: 'Higgsfield Apps' },
|
|
{ id: 'king', label: 'King' },
|
|
];
|
|
|
|
const baseFeatureItems: FeatureItem[] = [
|
|
{
|
|
id: 'sketch-video',
|
|
title: 'UNLIMITED SKETCH TO VIDEO',
|
|
subtitle: 'Bring your imagination to life with Sora 2',
|
|
image: 'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=800&q=80',
|
|
},
|
|
{
|
|
id: 'portrait-video',
|
|
title: 'UNLIMITED PORTRAIT TO VIDEO',
|
|
subtitle: 'Transform portraits into motion-driven stories',
|
|
image: 'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=800&q=80',
|
|
},
|
|
{
|
|
id: 'water-simulation',
|
|
title: 'FLUID SIMULATION PACK',
|
|
subtitle: 'Realistic water physics for cinematic scenes',
|
|
image: 'https://images.unsplash.com/photo-1505744386214-51dba16a26fc?auto=format&fit=crop&w=800&q=80',
|
|
},
|
|
];
|
|
|
|
const baseCommunityItems: CommunityItem[] = [
|
|
{
|
|
id: 'community-1',
|
|
chip: '64/10',
|
|
title: 'OBJECTS AROUND',
|
|
image: 'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=800&q=80',
|
|
actionLabel: 'Generate',
|
|
},
|
|
{
|
|
id: 'community-2',
|
|
chip: '64/10',
|
|
title: 'OBJECTS AROUND',
|
|
image: 'https://images.unsplash.com/photo-1544723795-3fb6469f5b39?auto=format&fit=crop&w=800&q=80',
|
|
actionLabel: 'Generate',
|
|
},
|
|
{
|
|
id: 'community-3',
|
|
chip: '64/10',
|
|
title: 'OBJECTS AROUND',
|
|
image: 'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=800&q=80',
|
|
actionLabel: 'Generate',
|
|
},
|
|
{
|
|
id: 'community-4',
|
|
chip: '64/10',
|
|
title: 'OBJECTS AROUND',
|
|
image: 'https://images.unsplash.com/photo-1531259683007-016a7b628fc4?auto=format&fit=crop&w=800&q=80',
|
|
actionLabel: 'Generate',
|
|
},
|
|
];
|
|
|
|
export default function ExploreScreen() {
|
|
const { isAuthenticated } = useAuth();
|
|
const { requireAuth } = useAuthGuard();
|
|
const [activeCategory, setActiveCategory] = useState(categories[0]?.id ?? 'visual-effects');
|
|
|
|
const featureItems = useMemo(() => {
|
|
return baseFeatureItems.map((item, index) => ({
|
|
...item,
|
|
id: `${activeCategory}-${index}`,
|
|
}));
|
|
}, [activeCategory]);
|
|
|
|
const communityItems = useMemo(() => {
|
|
return baseCommunityItems.map((item, index) => ({
|
|
...item,
|
|
id: `${activeCategory}-${index}`,
|
|
}));
|
|
}, [activeCategory]);
|
|
|
|
const handleGeneratePress = () => {
|
|
requireAuth(() => {
|
|
console.log('用户已登录,执行生成操作');
|
|
});
|
|
};
|
|
|
|
if (!isAuthenticated) {
|
|
return (
|
|
<PageLayout backgroundColor="#050505">
|
|
<ScrollView
|
|
style={styles.scroll}
|
|
contentContainerStyle={styles.contentContainer}
|
|
showsVerticalScrollIndicator={false}
|
|
>
|
|
<StatusBarSpacer />
|
|
<Header />
|
|
<View style={styles.loginPrompt}>
|
|
<View style={styles.lockIconContainer}>
|
|
<Text style={styles.lockIcon}>🔒</Text>
|
|
</View>
|
|
<Text style={styles.loginTitle}>需要登录</Text>
|
|
<Text style={styles.loginSubtitle}>
|
|
登录后即可浏览和使用所有功能
|
|
</Text>
|
|
<TouchableOpacity
|
|
style={styles.loginButton}
|
|
onPress={() => requireAuth()}
|
|
activeOpacity={0.8}
|
|
>
|
|
<Text style={styles.loginButtonText}>立即登录</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<View style={styles.bottomSpacer} />
|
|
</ScrollView>
|
|
</PageLayout>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<PageLayout backgroundColor="#050505">
|
|
<ScrollView
|
|
style={styles.scroll}
|
|
contentContainerStyle={styles.contentContainer}
|
|
showsVerticalScrollIndicator={false}
|
|
>
|
|
<StatusBarSpacer />
|
|
<Header />
|
|
<CategoryTabs categories={categories} activeId={activeCategory} onChange={setActiveCategory} />
|
|
<FeatureCarousel items={featureItems} />
|
|
<SectionHeader title="WAN 2.5 COMMUNITY" />
|
|
<CommunityGrid items={communityItems} />
|
|
<View style={styles.bottomSpacer} />
|
|
</ScrollView>
|
|
</PageLayout>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
scroll: {
|
|
flex: 1,
|
|
},
|
|
contentContainer: {
|
|
paddingTop: 16,
|
|
paddingBottom: 48,
|
|
},
|
|
bottomSpacer: {
|
|
height: 32,
|
|
},
|
|
loginPrompt: {
|
|
alignItems: 'center',
|
|
paddingVertical: 60,
|
|
paddingHorizontal: 32,
|
|
},
|
|
lockIconContainer: {
|
|
width: 80,
|
|
height: 80,
|
|
borderRadius: 40,
|
|
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
marginBottom: 24,
|
|
},
|
|
lockIcon: {
|
|
fontSize: 40,
|
|
},
|
|
loginTitle: {
|
|
fontSize: 24,
|
|
fontWeight: '700',
|
|
color: '#ffffff',
|
|
marginBottom: 12,
|
|
},
|
|
loginSubtitle: {
|
|
fontSize: 16,
|
|
color: 'rgba(255, 255, 255, 0.6)',
|
|
textAlign: 'center',
|
|
lineHeight: 24,
|
|
marginBottom: 32,
|
|
},
|
|
loginButton: {
|
|
backgroundColor: '#d7ff1f',
|
|
paddingHorizontal: 32,
|
|
paddingVertical: 16,
|
|
borderRadius: 12,
|
|
},
|
|
loginButtonText: {
|
|
color: '#050505',
|
|
fontSize: 16,
|
|
fontWeight: '700',
|
|
},
|
|
});
|