diff --git a/app/(tabs)/ask.tsx b/app/(tabs)/ask.tsx index eac825b..510296f 100644 --- a/app/(tabs)/ask.tsx +++ b/app/(tabs)/ask.tsx @@ -5,8 +5,8 @@ import SendMessage from "@/components/ask/send"; import { ThemedText } from "@/components/ThemedText"; import { fetchApi } from "@/lib/server-api-util"; import { Message } from "@/types/ask"; -import { router, useLocalSearchParams } from "expo-router"; -import { default as React, default as React, useCallback, useEffect, useRef, useState } from 'react'; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import { useCallback, useEffect, useRef, useState } from 'react'; import { Animated, FlatList, @@ -116,7 +116,6 @@ export default function AskScreen() { Animated.timing(fadeAnimChat, { toValue: 1, duration: 300, - duration: 300, useNativeDriver: true, }) ]).start(() => { @@ -131,31 +130,17 @@ export default function AskScreen() { useEffect(() => { if (!isHello) { - const timer = setTimeout(() => { - scrollToEnd(false); - }, 300); - return () => clearTimeout(timer); + // 不再自动关闭键盘,让用户手动控制 + // 这里可以添加其他需要在隐藏hello界面时执行的逻辑 + scrollToEnd(false); } }, [isHello]); - useEffect(() => { - const timer = setTimeout(() => { - if (!isHello) { - try { - if (TextInput.State?.currentlyFocusedInput) { - const input = TextInput.State.currentlyFocusedInput(); - if (input) input.blur(); - } - } catch (error) { - console.log('失去焦点失败:', error); - } - - scrollToEnd(false); - } - }, 200); - - return () => clearTimeout(timer); - }, [isHello]); + useFocusEffect( + useCallback(() => { + setIsHello(true); + }, []) + ); return ( @@ -299,7 +284,7 @@ const styles = StyleSheet.create({ padding: 16, paddingBottom: 24, backgroundColor: 'white', - borderTopWidth: 1, - borderTopColor: '#f0f0f0', + // borderTopWidth: 1, + // borderTopColor: '#f0f0f0', }, }); \ No newline at end of file diff --git a/assets/icons/svg/sun.svg b/assets/icons/svg/sun.svg new file mode 100644 index 0000000..ad68ee6 --- /dev/null +++ b/assets/icons/svg/sun.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/svg/video.svg b/assets/icons/svg/video.svg new file mode 100644 index 0000000..e5a979c --- /dev/null +++ b/assets/icons/svg/video.svg @@ -0,0 +1,3 @@ + + + diff --git a/components/ask/chat.tsx b/components/ask/chat.tsx index 9a65dc5..e5f5fea 100644 --- a/components/ask/chat.tsx +++ b/components/ask/chat.tsx @@ -5,7 +5,8 @@ import { useTranslation } from 'react-i18next'; import { FlatList, FlatListProps, - SafeAreaView + SafeAreaView, + View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import MessageItem from './aiChat'; @@ -27,7 +28,11 @@ function ChatComponent( const { t } = useTranslation(); const keyExtractor = useCallback((item: Message) => `${item.role}-${item.timestamp}`, []); - const contentContainerStyle = useMemo(() => ({ padding: 16, flexGrow: 1 }), []); + const contentContainerStyle = useMemo(() => ({ + padding: 16, + flexGrow: 1, + paddingTop: 0, + }), []); const [modalDetailsVisible, setModalDetailsVisible] = useState(false); @@ -37,7 +42,14 @@ function ChatComponent( ref={ref} data={userMessages} keyExtractor={keyExtractor} - renderItem={({ item }) => MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })} + renderItem={({ item, index }) => { + const itemStyle = index === 0 ? { marginTop: 16 } : {}; + return ( + + {MessageItem({ t, setSelectedImages, selectedImages, insets, item, sessionId, modalVisible, setModalVisible, setModalDetailsVisible, modalDetailsVisible })} + + ); + }} contentContainerStyle={contentContainerStyle} keyboardDismissMode="interactive" keyboardShouldPersistTaps="handled" diff --git a/components/ask/send.tsx b/components/ask/send.tsx index ab9793e..45b7f91 100644 --- a/components/ask/send.tsx +++ b/components/ask/send.tsx @@ -1,8 +1,12 @@ 'use client'; import SendSvg from '@/assets/icons/svg/send.svg'; -import React, { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; +import SunSvg from '@/assets/icons/svg/sun.svg'; +import VideoSvg from '@/assets/icons/svg/video.svg'; +import React, { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'; import { + EventSubscription, Keyboard, + ScrollView, StyleSheet, TextInput, TouchableOpacity, @@ -11,6 +15,7 @@ import { import { fetchApi } from '@/lib/server-api-util'; import { Message } from '@/types/ask'; +import { ThemedText } from '../ThemedText'; interface Props { setIsHello: Dispatch>, @@ -52,9 +57,36 @@ export default function SendMessage(props: Props) { setUserMessages((prev: Message[]) => [...prev, response]?.filter((item: Message) => item.content.text !== '正在寻找,请稍等...')); }, []); + // 添加一个ref来跟踪键盘状态 + const keyboardDidShowListener = useRef(null); + const keyboardDidHideListener = useRef(null); + const isKeyboardVisible = useRef(false); + + useEffect(() => { + // 使用keyboardWillShow而不是keyboardDidShow,这样可以在键盘完全显示前更新UI + const showSubscription = Keyboard.addListener('keyboardWillShow', () => { + isKeyboardVisible.current = true; + if (!conversationId) { + // 确保在下一个事件循环中更新状态,避免可能的渲染问题 + requestAnimationFrame(() => { + setIsHello(false); + }); + } + }); + + const hideSubscription = Keyboard.addListener('keyboardWillHide', () => { + isKeyboardVisible.current = false; + }); + + return () => { + showSubscription.remove(); + hideSubscription.remove(); + }; + }, [conversationId]); + // 发送询问 - const handleSubmit = () => { - const text = inputValue; + const handleSubmit = useCallback(() => { + const text = inputValue.trim(); // 用户输入信息之后进行后续操作 if (text) { // 将用户输入信息添加到消息列表中 @@ -85,38 +117,25 @@ export default function SendMessage(props: Props) { } // 将输入框清空 setInputValue(''); - // 关闭键盘 - Keyboard.dismiss(); - } - } - useEffect(() => { - const keyboardWillShowListener = Keyboard.addListener( - 'keyboardWillShow', - () => { - if (!conversationId) { - console.log('Keyboard will show'); - setIsHello(false); - setUserMessages([{ - content: { - text: "快来寻找你的记忆吧。。。" - }, - role: 'Assistant', - timestamp: new Date().toISOString() - }]) - } else { - - } + // 只有在键盘可见时才关闭键盘 + if (isKeyboardVisible.current) { + Keyboard.dismiss(); } - ); - - return () => { - keyboardWillShowListener.remove(); - }; - }, [conversationId]); + } + }, [inputValue, conversationId, selectedImages, createNewConversation, getConversation]); return ( + + + + 检索素材 + + + 创作视频 + + @@ -144,6 +163,17 @@ export default function SendMessage(props: Props) { } const styles = StyleSheet.create({ + button: { + paddingHorizontal: 8, + paddingVertical: 4, + margin: 5, + borderRadius: 25, + alignItems: 'center', + borderWidth: 2, + display: 'flex', + flexDirection: 'row', + gap: 5 + }, container: { justifyContent: 'center', backgroundColor: '#transparent',