🐛 修复视频播放器无限循环渲染问题
## 主要修复 - 修复 FullscreenMediaModal 和 FullscreenVideoModal 中的 useEffect 循环依赖 - 重构 VideoPlayer 组件的视频属性管理逻辑 - 优化 useVideoPlayer 的初始化回调机制 ## 新增功能 - 新增标签 API 支持 (lib/api/tags.ts) - 新增内容骨架屏组件 (components/profile/content-skeleton.tsx) - 新增返回按钮组件 (components/ui/back-button.tsx) ## 改进优化 - 优化视频播放器的性能,避免重复初始化 - 修复 useEffect 依赖项导致的无限循环更新 - 完善类型定义和 API 接口 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
import { Feather } from '@expo/vector-icons';
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
import { Stack, useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import { UploadCloud } from 'lucide-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
@@ -11,12 +15,13 @@ import {
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import { ArrowLeft, UploadCloud } from 'lucide-react';
|
||||
import { Feather } from '@expo/vector-icons';
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
|
||||
export const unstable_settings = {
|
||||
headerShown: false,
|
||||
};
|
||||
|
||||
import { DynamicForm } from '@/components/forms/dynamic-form';
|
||||
import { BackButton } from '@/components/ui/back-button';
|
||||
import { getTemplateById } from '@/lib/api/templates';
|
||||
import { Template } from '@/lib/types/template';
|
||||
import { RunFormSchema, RunTemplateData } from '@/lib/types/template-run';
|
||||
@@ -28,7 +33,7 @@ interface Step1FormData {
|
||||
script: string;
|
||||
}
|
||||
|
||||
interface Step2FormData extends RunTemplateData {}
|
||||
interface Step2FormData extends RunTemplateData { }
|
||||
|
||||
interface FormData {
|
||||
step1: Step1FormData;
|
||||
@@ -250,13 +255,7 @@ export default function TemplateFormScreen() {
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<View style={styles.topBar}>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.85}
|
||||
onPress={() => router.back()}
|
||||
style={styles.backButton}
|
||||
>
|
||||
<ArrowLeft size={22} color="#FFFFFF" strokeWidth={2.4} />
|
||||
</TouchableOpacity>
|
||||
<BackButton onPress={() => router.back()} />
|
||||
</View>
|
||||
|
||||
<Text style={styles.heroTitle}>
|
||||
@@ -329,13 +328,7 @@ export default function TemplateFormScreen() {
|
||||
const renderStep2 = () => (
|
||||
<View style={styles.step2Wrapper}>
|
||||
<View style={styles.topBar}>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.85}
|
||||
onPress={handleStep2Prev}
|
||||
style={styles.backButton}
|
||||
>
|
||||
<ArrowLeft size={22} color="#FFFFFF" strokeWidth={2.4} />
|
||||
</TouchableOpacity>
|
||||
<BackButton onPress={handleStep2Prev} />
|
||||
<Text style={styles.stepIndicator}>STEP 2 OF 2</Text>
|
||||
</View>
|
||||
|
||||
@@ -406,24 +399,32 @@ export default function TemplateFormScreen() {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<View style={styles.loadingCanvas}>
|
||||
<SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color="#D1FF00" />
|
||||
<Text style={styles.loadingText}>Loading...</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
<>
|
||||
<Stack.Screen options={{ headerShown: false }} />
|
||||
|
||||
<View style={styles.loadingCanvas}>
|
||||
<SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color="#D1FF00" />
|
||||
<Text style={styles.loadingText}>Loading...</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.canvas}>
|
||||
<SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
|
||||
{currentStep === 1 ? renderStep1() : renderStep2()}
|
||||
</SafeAreaView>
|
||||
{renderBottomActions()}
|
||||
</View>
|
||||
<>
|
||||
<Stack.Screen options={{ headerShown: false }} />
|
||||
|
||||
<View style={styles.canvas}>
|
||||
<SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
|
||||
{currentStep === 1 ? renderStep1() : renderStep2()}
|
||||
</SafeAreaView>
|
||||
{renderBottomActions()}
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -461,17 +462,10 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 28,
|
||||
},
|
||||
backButton: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 18,
|
||||
borderWidth: 1,
|
||||
borderColor: 'rgba(255, 255, 255, 0.1)',
|
||||
backgroundColor: 'rgba(18, 18, 18, 0.78)',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: 0,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
gap: 12,
|
||||
},
|
||||
stepIndicator: {
|
||||
flex: 1,
|
||||
@@ -512,9 +506,6 @@ const styles = StyleSheet.create({
|
||||
width: 74,
|
||||
height: 74,
|
||||
borderRadius: 24,
|
||||
borderWidth: 2,
|
||||
borderColor: '#050505',
|
||||
backgroundColor: '#050505',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
previewInsetImage: {
|
||||
|
||||
Reference in New Issue
Block a user