feat: 完整应用重构 - 优化界面架构与用户体验

主要变更:
- 重构应用界面:优化首页、登录、认证流程
- 新增用户档案模块:包含完整的档案管理组件
- 优化路由结构:重新组织页面布局和导航
- 改进API集成:新增活动、内容分类等API模块
- 删除冗余组件:清理不必要的文件和依赖

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
imeepos
2025-11-03 12:44:12 +08:00
parent b9399bf4cf
commit af64049c69
52 changed files with 2832 additions and 2007 deletions

View File

@@ -1,5 +1,5 @@
import { ThemedText } from '@/components/themed-text';
import { AVPlaybackStatus, ResizeMode, Video } from 'expo-av';
import { type VideoReadyForDisplayEvent, ResizeMode, Video } from 'expo-av';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
ActivityIndicator,
@@ -59,12 +59,10 @@ export function FullscreenVideoModal({
}, [visible, autoPlay]);
// 处理视频加载完成
const handleVideoReady = (status: AVPlaybackStatus) => {
if (status.isLoaded) {
setIsLoading(false);
if (autoPlay) {
videoRef.current?.playAsync();
}
const handleVideoReady = (_event: VideoReadyForDisplayEvent) => {
setIsLoading(false);
if (autoPlay) {
videoRef.current?.playAsync();
}
};

View File

@@ -10,6 +10,7 @@ import {
import { Video, ResizeMode, AVPlaybackStatus } from 'expo-av';
import { Image } from 'expo-image';
import { ThemedView } from '@/components/themed-view';
import { ThemedText } from '@/components/themed-text';
import { useThemeColor } from '@/hooks/use-theme-color';
import {
extractVideoMetadata,
@@ -59,7 +60,8 @@ export function VideoPlayer({
onPress,
fullscreenMode = false, // 新增:默认非全屏模式
}: VideoPlayerProps) {
const videoRef = useRef<Video>(null);
const nativeVideoRef = useRef<Video | null>(null);
const webVideoRef = useRef<HTMLVideoElement | null>(null);
const [videoStatus, setVideoStatus] = useState<AVPlaybackStatus>();
const [videoMetadata, setVideoMetadata] = useState<any>(null);
const [isLoading, setIsLoading] = useState(true);
@@ -185,15 +187,29 @@ export function VideoPlayer({
}
// 如果视频已加载但未播放,开始播放
if (Platform.OS === 'web') {
webVideoRef.current?.play().catch(() => {});
return;
}
if (videoStatus?.isLoaded && !videoStatus.isPlaying && !useNativeControls) {
videoRef.current?.playAsync();
nativeVideoRef.current?.playAsync().catch(() => {});
}
};
// 自动播放逻辑
useEffect(() => {
if (autoPlay && videoRef.current && videoStatus?.isLoaded) {
videoRef.current.playAsync();
if (!autoPlay) {
return;
}
if (Platform.OS === 'web') {
webVideoRef.current?.play().catch(() => {});
return;
}
if (videoStatus?.isLoaded) {
nativeVideoRef.current?.playAsync().catch(() => {});
}
}, [autoPlay, videoStatus]);
@@ -260,7 +276,7 @@ export function VideoPlayer({
<>
{Platform.OS === 'web' ? (
<video
ref={videoRef}
ref={webVideoRef}
src={source.uri}
style={{
position: 'absolute',
@@ -291,7 +307,7 @@ export function VideoPlayer({
/>
) : (
<Video
ref={videoRef}
ref={nativeVideoRef}
source={source}
style={styles.video}
resizeMode={resizeMode}
@@ -339,9 +355,9 @@ export function VideoPlayer({
{!useNativeControls && isVideoLoaded && !isVideoPlaying && !isLoading && !hasVideoError && !fullscreenMode && (
<View style={styles.playButtonOverlay}>
<View style={styles.playButton}>
<ThemedView style={styles.playIcon}>
<ThemedText style={styles.playIcon}>
{'▶️'}
</ThemedView>
</ThemedText>
</View>
</View>
)}
@@ -349,9 +365,9 @@ export function VideoPlayer({
{/* 错误状态 - 只在非 Web 平台显示 */}
{!isLoading && !isVideoLoaded && hasVideoError && Platform.OS !== 'web' && !shouldShowAsImage && (
<View style={styles.errorOverlay}>
<ThemedView style={styles.errorMessage}>
<ThemedText style={styles.errorMessage}>
{'❌'}
</ThemedView>
</ThemedText>
</View>
)}
</ThemedView>
@@ -439,4 +455,4 @@ const styles = StyleSheet.create({
},
});
export default VideoPlayer;
export default VideoPlayer;