feat: 兼容
This commit is contained in:
parent
39b768f2cc
commit
436b44a107
@ -1,3 +1,4 @@
|
||||
import IP from '@/assets/icons/svg/ip.svg';
|
||||
import * as MediaLibrary from 'expo-media-library';
|
||||
import { useRouter } from 'expo-router';
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
@ -96,7 +97,7 @@ export default function HomeScreen() {
|
||||
isLoggedIn ? <MemoList /> :
|
||||
<View className="flex-1 bg-bgPrimary px-[1rem] h-screen overflow-auto py-[2rem] " style={{ paddingTop: insets.top + 48 }}>
|
||||
{/* 标题区域 */}
|
||||
<View className="items-center mb-10 w-full px-5">
|
||||
<View className="mb-10 w-full px-5">
|
||||
<Text className="text-white text-3xl font-bold mb-3 text-left">
|
||||
{t('auth.welcomeAwaken.awaken', { ns: 'login' })}
|
||||
{"\n"}
|
||||
@ -110,9 +111,9 @@ export default function HomeScreen() {
|
||||
</View>
|
||||
|
||||
{/* Memo 形象区域 */}
|
||||
{/* <View className="items-center">
|
||||
<View className="items-center">
|
||||
<IP />
|
||||
</View> */}
|
||||
</View>
|
||||
|
||||
{/* 介绍文本 */}
|
||||
<Text className="text-white text-base text-center mb-[1rem] leading-6 opacity-90 px-10 -mt-[4rem]">
|
||||
|
||||
45
components/ask/VideoPlayer.tsx
Normal file
45
components/ask/VideoPlayer.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import { useVideoPlayer, VideoView } from 'expo-video';
|
||||
import {
|
||||
Pressable,
|
||||
StyleProp,
|
||||
ViewStyle
|
||||
} from 'react-native';
|
||||
|
||||
const VideoPlayer = ({
|
||||
videoUrl,
|
||||
style,
|
||||
onPress
|
||||
}: {
|
||||
videoUrl: string;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
onPress?: () => void;
|
||||
}) => {
|
||||
const player = useVideoPlayer(videoUrl, (player) => {
|
||||
player.loop = true;
|
||||
player.play();
|
||||
});
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={[{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}, style]}
|
||||
onPress={onPress}
|
||||
>
|
||||
<VideoView
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: '#000', // 添加背景色
|
||||
}}
|
||||
player={player}
|
||||
allowsFullscreen
|
||||
allowsPictureInPicture
|
||||
/>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoPlayer
|
||||
@ -5,24 +5,22 @@ import ReturnArrow from "@/assets/icons/svg/returnArrow.svg";
|
||||
import YesSvg from "@/assets/icons/svg/yes.svg";
|
||||
import { Message, Video } from "@/types/ask";
|
||||
import { MaterialItem } from "@/types/personal-info";
|
||||
import { useVideoPlayer, VideoView } from 'expo-video';
|
||||
import { TFunction } from "i18next";
|
||||
import React from 'react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
FlatList,
|
||||
Image,
|
||||
Modal,
|
||||
Pressable,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
ViewStyle
|
||||
View
|
||||
} from 'react-native';
|
||||
import { ThemedText } from "../ThemedText";
|
||||
import TypewriterText from "./typewriterText";
|
||||
import { mergeArrays } from "./utils";
|
||||
import VideoPlayer from "./VideoPlayer";
|
||||
|
||||
interface RenderMessageProps {
|
||||
insets: { top: number };
|
||||
@ -34,51 +32,14 @@ interface RenderMessageProps {
|
||||
modalDetailsVisible: boolean;
|
||||
setSelectedImages: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
selectedImages: string[];
|
||||
t: TFunction;
|
||||
}
|
||||
|
||||
const renderMessage = ({ insets, item, sessionId, setModalVisible, modalVisible, setModalDetailsVisible, modalDetailsVisible, setSelectedImages, selectedImages }: RenderMessageProps) => {
|
||||
const MessageItem = ({ t, insets, item, sessionId, setModalVisible, modalVisible, setModalDetailsVisible, modalDetailsVisible, setSelectedImages, selectedImages }: RenderMessageProps) => {
|
||||
const isUser = item.role === 'User';
|
||||
const isVideo = (data: Video | MaterialItem): data is Video => {
|
||||
return 'video' in data;
|
||||
};
|
||||
const { t } = useTranslation();
|
||||
// 创建一个新的 VideoPlayer 组件
|
||||
const VideoPlayer = ({
|
||||
videoUrl,
|
||||
style,
|
||||
onPress
|
||||
}: {
|
||||
videoUrl: string;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
onPress?: () => void;
|
||||
}) => {
|
||||
const player = useVideoPlayer(videoUrl, (player) => {
|
||||
player.loop = true;
|
||||
player.play();
|
||||
});
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={[{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}, style]}
|
||||
onPress={onPress}
|
||||
>
|
||||
<VideoView
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: '#000', // 添加背景色
|
||||
}}
|
||||
player={player}
|
||||
allowsFullscreen
|
||||
allowsPictureInPicture
|
||||
/>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View className={`flex-row items-start gap-2 w-full ${isUser ? 'justify-end' : 'justify-start'}`}>
|
||||
@ -304,7 +265,7 @@ const renderMessage = ({ insets, item, sessionId, setModalVisible, modalVisible,
|
||||
);
|
||||
};
|
||||
|
||||
export default renderMessage;
|
||||
export default MessageItem;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
imageGridContainer: {
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { Message, Video } from '@/types/ask';
|
||||
import { MaterialItem } from '@/types/personal-info';
|
||||
import React, { Dispatch, memo, SetStateAction, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FlatList,
|
||||
SafeAreaView
|
||||
} from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import renderMessage from "./aiChat";
|
||||
import MessageItem from './aiChat';
|
||||
|
||||
interface ChatProps {
|
||||
userMessages: Message[];
|
||||
@ -19,7 +20,7 @@ function ChatComponent({ userMessages, sessionId, setSelectedImages, selectedIma
|
||||
const flatListRef = useRef<FlatList>(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const [modalVisible, setModalVisible] = React.useState({ visible: false, data: {} as Video | MaterialItem });
|
||||
|
||||
const { t } = useTranslation();
|
||||
// 使用 useCallback 缓存 keyExtractor 函数
|
||||
const keyExtractor = useCallback((item: Message) => `${item.role}-${item.timestamp}`, []);
|
||||
|
||||
@ -51,7 +52,7 @@ function ChatComponent({ userMessages, sessionId, setSelectedImages, selectedIma
|
||||
updateCellsBatchingPeriod={50}
|
||||
initialNumToRender={10}
|
||||
windowSize={11}
|
||||
renderItem={({ item }) => renderMessage({ setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })}
|
||||
renderItem={({ item }) => MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user