fix: bug
This commit is contained in:
@@ -1,27 +1,40 @@
|
||||
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import { Image } from 'expo-image';
|
||||
import { Video, ResizeMode } from 'expo-av';
|
||||
import { VideoPlayer } from '@/components/video/video-player';
|
||||
import { FullscreenMediaModal } from '@/components/media/fullscreen-media-modal';
|
||||
import { useThemeColor } from '@/hooks/use-theme-color';
|
||||
import { Template } from '@/lib/types/template';
|
||||
import { ResizeMode } from 'expo-av';
|
||||
import { Image } from 'expo-image';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Platform, StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||
import { ThemedText } from '../themed-text';
|
||||
import { ThemedView } from '../themed-view';
|
||||
import { Template } from '@/lib/types/template';
|
||||
import { useThemeColor } from '@/hooks/use-theme-color';
|
||||
import { useMemo } from 'react';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { isVideoTemplate, canLoadMedia } from '@/utils/media-utils';
|
||||
|
||||
interface TemplateCardProps {
|
||||
template: Template;
|
||||
onPress?: (template: Template) => void;
|
||||
allTemplates?: Template[];
|
||||
currentIndex?: number;
|
||||
onVideoChange?: (template: Template, index: number) => void;
|
||||
}
|
||||
|
||||
export function TemplateCard({ template, onPress }: TemplateCardProps) {
|
||||
export function TemplateCard({
|
||||
template,
|
||||
onPress,
|
||||
allTemplates = [],
|
||||
currentIndex = 0,
|
||||
onVideoChange
|
||||
}: TemplateCardProps) {
|
||||
const router = useRouter();
|
||||
const cardColor = useThemeColor({}, 'card');
|
||||
const imagePlaceholderColor = useThemeColor({}, 'imagePlaceholder');
|
||||
const [isMediaFullscreenVisible, setIsMediaFullscreenVisible] = useState(false);
|
||||
const [currentMediaIndex, setCurrentMediaIndex] = useState(currentIndex);
|
||||
|
||||
const isVideo = useMemo(() => {
|
||||
return /\.(mp4|webm|ogg|mov|avi|mkv|flv)$/i.test(template.previewUrl || '');
|
||||
}, [template.previewUrl]);
|
||||
return isVideoTemplate(template);
|
||||
}, [template]);
|
||||
|
||||
const getImageHeight = () => {
|
||||
if (template.aspectRatio) {
|
||||
@@ -39,23 +52,36 @@ export function TemplateCard({ template, onPress }: TemplateCardProps) {
|
||||
router.push(`/template/${template.id}/run`);
|
||||
};
|
||||
|
||||
const handleCardPress = () => {
|
||||
if (onPress) {
|
||||
onPress(template);
|
||||
} else {
|
||||
// 默认行为:跳转到运行页面
|
||||
handleUseTemplate();
|
||||
}
|
||||
const handleFullscreenMedia = () => {
|
||||
setIsMediaFullscreenVisible(true);
|
||||
};
|
||||
|
||||
const handleMediaIndexChanged = (newIndex: number) => {
|
||||
setCurrentMediaIndex(newIndex);
|
||||
const newTemplate = allTemplates[newIndex];
|
||||
onVideoChange?.(newTemplate, newIndex);
|
||||
};
|
||||
|
||||
const handleCardPress = () => {
|
||||
// 统一处理:打开媒体全屏预览
|
||||
handleFullscreenMedia();
|
||||
};
|
||||
|
||||
// 获取当前媒体模板
|
||||
const getCurrentMediaTemplate = () => {
|
||||
return allTemplates[currentMediaIndex] || template;
|
||||
};
|
||||
|
||||
const currentTemplate = getCurrentMediaTemplate();
|
||||
|
||||
return (
|
||||
<View style={[styles.card, { backgroundColor: cardColor }]}>
|
||||
<View style={styles.mediaContainer}>
|
||||
<ThemedView style={[styles.mediaContent, { height: mediaHeight }]}>
|
||||
{isVideo ? (
|
||||
<VideoPlayer
|
||||
source={{ uri: template.previewUrl }}
|
||||
poster={template.coverImageUrl}
|
||||
source={{ uri: currentTemplate.previewUrl }}
|
||||
poster={currentTemplate.coverImageUrl}
|
||||
style={[styles.videoPlayer, styles.videoCover]}
|
||||
resizeMode={ResizeMode.COVER}
|
||||
shouldPlay={true}
|
||||
@@ -120,6 +146,15 @@ export function TemplateCard({ template, onPress }: TemplateCardProps) {
|
||||
<ThemedText style={styles.useButtonText}>立即使用</ThemedText>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* 统一全屏媒体模态框 */}
|
||||
<FullscreenMediaModal
|
||||
visible={isMediaFullscreenVisible}
|
||||
onClose={() => setIsMediaFullscreenVisible(false)}
|
||||
currentIndex={currentMediaIndex}
|
||||
templates={allTemplates}
|
||||
onIndexChanged={handleMediaIndexChanged}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -158,6 +193,11 @@ const styles = StyleSheet.create({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
// React Native中object-fit对应contentFit属性,但在VideoPlayer中已经处理了
|
||||
...Platform.select({
|
||||
web: {
|
||||
objectFit: 'cover',
|
||||
},
|
||||
}),
|
||||
},
|
||||
imageContainer: {
|
||||
width: '100%',
|
||||
@@ -181,6 +221,7 @@ const styles = StyleSheet.create({
|
||||
color: 'rgba(255, 255, 255, 0.85)',
|
||||
fontSize: 10,
|
||||
fontWeight: '400',
|
||||
lineHeight: 6
|
||||
},
|
||||
tagOverlay: {
|
||||
position: 'absolute',
|
||||
@@ -205,6 +246,7 @@ const styles = StyleSheet.create({
|
||||
color: '#fff',
|
||||
fontSize: 11,
|
||||
fontWeight: '500',
|
||||
lineHeight: 4
|
||||
},
|
||||
actionArea: {
|
||||
padding: 12,
|
||||
|
||||
Reference in New Issue
Block a user