'use client'; import SendSvg from '@/assets/icons/svg/send.svg'; 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 { Keyboard, ScrollView, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native'; import { Message } from '@/types/ask'; import { useTranslation } from 'react-i18next'; import { ThemedText } from '../ThemedText'; import { createNewConversation, getConversation } from './utils'; interface Props { setIsHello: Dispatch>, conversationId: string | null, setUserMessages: Dispatch>; setConversationId: (conversationId: string) => void, selectedImages: string[]; setSelectedImages: Dispatch>; } export default function SendMessage(props: Props) { const { setIsHello, conversationId, setUserMessages, setConversationId, selectedImages, setSelectedImages } = props; const { t } = useTranslation() // 用户询问 const [inputValue, setInputValue] = useState(''); // 添加一个ref来跟踪键盘状态 const isKeyboardVisible = useRef(false); useEffect(() => { // 使用keyboardWillShow而不是keyboardDidShow,这样可以在键盘完全显示前更新UI const showSubscription = Keyboard.addListener('keyboardWillShow', () => { isKeyboardVisible.current = true; if (!conversationId) { // 确保在下一个事件循环中更新状态,避免可能的渲染问题 requestAnimationFrame(() => { setIsHello(false); setUserMessages([ { content: { text: t("ask:ask.introduction1") }, role: 'Assistant', timestamp: new Date().toISOString() } ]) }); } }); const hideSubscription = Keyboard.addListener('keyboardWillHide', () => { isKeyboardVisible.current = false; }); return () => { showSubscription.remove(); hideSubscription.remove(); }; }, [conversationId]); // 发送询问 const handleSubmit = useCallback(async () => { const text = inputValue.trim(); // 用户输入信息之后进行后续操作 if (text) { // 将用户输入信息添加到消息列表中 setUserMessages(pre => ([...pre, { content: { text: text }, role: 'User', timestamp: new Date().toISOString() }, { content: { text: "正在寻找,请稍等..." }, role: 'Assistant', timestamp: new Date().toISOString() } ])); // 如果没有对话ID,创建新对话并获取消息,否则直接获取消息 if (!conversationId) { const data = await createNewConversation(text); setConversationId(data); const response = await getConversation({ session_id: data, user_text: text, material_ids: [] }); setSelectedImages([]); setUserMessages((prev: Message[]) => { const newMessages = [...(prev || [])]; if (response) { newMessages.push(response); } return newMessages.filter((item: Message) => item?.content?.text !== '正在寻找,请稍等...' ); }); } else { const response = await getConversation({ session_id: conversationId, user_text: text, material_ids: selectedImages }); setSelectedImages([]); setUserMessages((prev: Message[]) => { const newMessages = [...(prev || [])]; if (response) { newMessages.push(response); } return newMessages.filter((item: Message) => item?.content?.text !== '正在寻找,请稍等...' ); }); } // 将输入框清空 setInputValue(''); // 只有在键盘可见时才关闭键盘 if (isKeyboardVisible.current) { Keyboard.dismiss(); } } }, [inputValue, conversationId, selectedImages, createNewConversation, getConversation]); const handleQuitly = (type: string) => { setIsHello(false) setUserMessages(pre => ([ ...pre, { content: { text: type === "search" ? t("ask:ask.introduction2") : t("ask:ask.introduction3") }, role: 'Assistant', timestamp: new Date().toISOString() } ])) }; return ( handleQuitly('search')}> {t("ask:ask.search")} handleQuitly('video')}> {t("ask:ask.video")} { setInputValue(text); }} onSubmitEditing={handleSubmit} // 调起的键盘类型 returnKeyType="send" /> ); } 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', }, input: { borderColor: '#FF9500', borderWidth: 1, borderRadius: 25, paddingHorizontal: 20, paddingVertical: 13, fontSize: 16, width: '100%', // 确保输入框宽度撑满 paddingRight: 50 }, voiceButton: { padding: 8, borderRadius: 20, backgroundColor: '#FF9500', justifyContent: 'center', alignItems: 'center', position: 'absolute', transform: [{ translateY: -12 }], }, });