feat: 引导
This commit is contained in:
parent
14377edd1e
commit
301c818a66
@ -138,9 +138,11 @@ export default function AskScreen() {
|
|||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
setIsHello(true);
|
if (!sessionId) {
|
||||||
setUserMessages([])
|
setIsHello(true);
|
||||||
}, [])
|
setUserMessages([])
|
||||||
|
}
|
||||||
|
}, [sessionId])
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -180,7 +182,7 @@ export default function AskScreen() {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<AskHello />
|
<AskHello setUserMessages={setUserMessages} setConversationId={setConversationId} setIsHello={setIsHello} />
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
|
|
||||||
{/* 聊天页面 */}
|
{/* 聊天页面 */}
|
||||||
|
|||||||
@ -1,17 +1,55 @@
|
|||||||
import IP from "@/assets/icons/svg/ip.svg";
|
import IP from "@/assets/icons/svg/ip.svg";
|
||||||
import { ThemedText } from "@/components/ThemedText";
|
import { ThemedText } from "@/components/ThemedText";
|
||||||
|
import { Message } from "@/types/ask";
|
||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ScrollView, View } from 'react-native';
|
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
|
||||||
|
import { createNewConversation, getConversation } from "./utils";
|
||||||
|
|
||||||
export default function AskHello() {
|
interface AskHelloProps {
|
||||||
|
setUserMessages: Dispatch<SetStateAction<Message[]>>;
|
||||||
|
setConversationId: Dispatch<SetStateAction<string | null>>;
|
||||||
|
setIsHello: Dispatch<SetStateAction<boolean>>;
|
||||||
|
}
|
||||||
|
export default function AskHello({ setUserMessages, setConversationId, setIsHello }: AskHelloProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const handleCase = async (text: string) => {
|
||||||
|
setIsHello(false)
|
||||||
|
setUserMessages([
|
||||||
|
{
|
||||||
|
content: {
|
||||||
|
text: text
|
||||||
|
},
|
||||||
|
role: 'User',
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
content: {
|
||||||
|
text: "正在寻找,请稍等..."
|
||||||
|
},
|
||||||
|
role: 'Assistant',
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const data = await createNewConversation(text);
|
||||||
|
setConversationId(data);
|
||||||
|
const response = await getConversation({ session_id: data, user_text: text, material_ids: [] });
|
||||||
|
setUserMessages((prev: Message[]) => {
|
||||||
|
const newMessages = [...(prev || [])];
|
||||||
|
if (response) {
|
||||||
|
newMessages.push(response);
|
||||||
|
}
|
||||||
|
return newMessages.filter((item: Message) =>
|
||||||
|
item?.content?.text !== '正在寻找,请稍等...'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<View className="flex-1 bg-white w-full">
|
<View className="flex-1 bg-white w-full">
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
justifyContent: 'center',
|
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingBottom: 20
|
paddingBottom: 20
|
||||||
}}
|
}}
|
||||||
@ -24,16 +62,58 @@ export default function AskHello() {
|
|||||||
{"\n"}
|
{"\n"}
|
||||||
{t('ask.iAmMemo', { ns: 'ask' })}
|
{t('ask.iAmMemo', { ns: 'ask' })}
|
||||||
</ThemedText>
|
</ThemedText>
|
||||||
<View className="justify-center items-center my-4">
|
<View className="-mt-10">
|
||||||
<IP />
|
<IP />
|
||||||
</View>
|
</View>
|
||||||
<ThemedText className="!text-textPrimary text-center">
|
<ThemedText className="!text-textPrimary text-center -mt-20">
|
||||||
{t('ask.ready', { ns: 'ask' })}
|
{t('ask.ready', { ns: 'ask' })}
|
||||||
{"\n"}
|
{"\n"}
|
||||||
{t('ask.justAsk', { ns: 'ask' })}
|
{t('ask.justAsk', { ns: 'ask' })}
|
||||||
</ThemedText>
|
</ThemedText>
|
||||||
|
<View style={styles.caseContainer}>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
handleCase(t('ask:ask.case1'));
|
||||||
|
}}>
|
||||||
|
<ThemedText style={styles.case}>
|
||||||
|
{t('ask:ask.case1')}
|
||||||
|
</ThemedText>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
handleCase(t('ask:ask.case2'));
|
||||||
|
}}>
|
||||||
|
<ThemedText style={styles.case}>
|
||||||
|
{t('ask:ask.case2')}
|
||||||
|
</ThemedText>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity onPress={() => {
|
||||||
|
handleCase(t('ask:ask.case3'));
|
||||||
|
}}>
|
||||||
|
<ThemedText style={styles.case}>
|
||||||
|
{t('ask:ask.case3')}
|
||||||
|
</ThemedText>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
caseContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 8,
|
||||||
|
width: '100%',
|
||||||
|
marginTop: 16
|
||||||
|
},
|
||||||
|
case: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: "#FFB645",
|
||||||
|
borderRadius: 24,
|
||||||
|
paddingHorizontal: 8,
|
||||||
|
width: 'auto'
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -13,9 +13,9 @@ import {
|
|||||||
View
|
View
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import { fetchApi } from '@/lib/server-api-util';
|
|
||||||
import { Message } from '@/types/ask';
|
import { Message } from '@/types/ask';
|
||||||
import { ThemedText } from '../ThemedText';
|
import { ThemedText } from '../ThemedText';
|
||||||
|
import { createNewConversation, getConversation } from './utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
setIsHello: Dispatch<SetStateAction<boolean>>,
|
setIsHello: Dispatch<SetStateAction<boolean>>,
|
||||||
@ -31,31 +31,7 @@ export default function SendMessage(props: Props) {
|
|||||||
// 用户询问
|
// 用户询问
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
|
||||||
// 创建新对话并获取消息
|
|
||||||
const createNewConversation = useCallback(async (user_text: string) => {
|
|
||||||
const data = await fetchApi<string>("/chat/new", {
|
|
||||||
method: "POST",
|
|
||||||
});
|
|
||||||
setConversationId(data);
|
|
||||||
await getConversation({ session_id: data, user_text, material_ids: [] });
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 获取对话信息
|
|
||||||
const getConversation = useCallback(async ({ session_id, user_text, material_ids }: { session_id: string, user_text: string, material_ids: string[] }) => {
|
|
||||||
// 获取对话信息必须要有对话id
|
|
||||||
if (!session_id) return;
|
|
||||||
|
|
||||||
const response = await fetchApi<Message>(`/chat`, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify({
|
|
||||||
session_id,
|
|
||||||
user_text,
|
|
||||||
material_ids
|
|
||||||
})
|
|
||||||
});
|
|
||||||
setSelectedImages([]);
|
|
||||||
setUserMessages((prev: Message[]) => [...prev, response]?.filter((item: Message) => item.content.text !== '正在寻找,请稍等...'));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 添加一个ref来跟踪键盘状态
|
// 添加一个ref来跟踪键盘状态
|
||||||
const keyboardDidShowListener = useRef<EventSubscription | null>(null);
|
const keyboardDidShowListener = useRef<EventSubscription | null>(null);
|
||||||
@ -95,7 +71,7 @@ export default function SendMessage(props: Props) {
|
|||||||
}, [conversationId]);
|
}, [conversationId]);
|
||||||
|
|
||||||
// 发送询问
|
// 发送询问
|
||||||
const handleSubmit = useCallback(() => {
|
const handleSubmit = useCallback(async () => {
|
||||||
const text = inputValue.trim();
|
const text = inputValue.trim();
|
||||||
// 用户输入信息之后进行后续操作
|
// 用户输入信息之后进行后续操作
|
||||||
if (text) {
|
if (text) {
|
||||||
@ -117,13 +93,35 @@ export default function SendMessage(props: Props) {
|
|||||||
]));
|
]));
|
||||||
// 如果没有对话ID,创建新对话并获取消息,否则直接获取消息
|
// 如果没有对话ID,创建新对话并获取消息,否则直接获取消息
|
||||||
if (!conversationId) {
|
if (!conversationId) {
|
||||||
createNewConversation(text);
|
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 {
|
} else {
|
||||||
getConversation({
|
const response = await getConversation({
|
||||||
session_id: conversationId,
|
session_id: conversationId,
|
||||||
user_text: text,
|
user_text: text,
|
||||||
material_ids: selectedImages
|
material_ids: selectedImages
|
||||||
});
|
});
|
||||||
|
setSelectedImages([]);
|
||||||
|
setUserMessages((prev: Message[]) => {
|
||||||
|
const newMessages = [...(prev || [])];
|
||||||
|
if (response) {
|
||||||
|
newMessages.push(response);
|
||||||
|
}
|
||||||
|
return newMessages.filter((item: Message) =>
|
||||||
|
item?.content?.text !== '正在寻找,请稍等...'
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// 将输入框清空
|
// 将输入框清空
|
||||||
setInputValue('');
|
setInputValue('');
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
import { fetchApi } from "@/lib/server-api-util";
|
||||||
|
import { Message } from "@/types/ask";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
|
||||||
// 实现一个函数,从两个数组中轮流插入新数组
|
// 实现一个函数,从两个数组中轮流插入新数组
|
||||||
export const mergeArrays = (arr1: any[], arr2: any[]) => {
|
export const mergeArrays = (arr1: any[], arr2: any[]) => {
|
||||||
const result: any[] = [];
|
const result: any[] = [];
|
||||||
@ -8,3 +12,41 @@ export const mergeArrays = (arr1: any[], arr2: any[]) => {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 创建新对话并获取消息
|
||||||
|
export const createNewConversation = useCallback(async (user_text: string) => {
|
||||||
|
const data = await fetchApi<string>("/chat/new", {
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
return data
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 获取对话信息
|
||||||
|
export const getConversation = async ({
|
||||||
|
session_id,
|
||||||
|
user_text,
|
||||||
|
material_ids
|
||||||
|
}: {
|
||||||
|
session_id: string,
|
||||||
|
user_text: string,
|
||||||
|
material_ids: string[]
|
||||||
|
}): Promise<Message | undefined> => {
|
||||||
|
// 获取对话信息必须要有对话id
|
||||||
|
if (!session_id) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetchApi<Message>(`/chat`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
session_id,
|
||||||
|
user_text,
|
||||||
|
material_ids
|
||||||
|
})
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
// console.error('Error in getConversation:', error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -13,6 +13,9 @@
|
|||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
"error": "have some error",
|
"error": "have some error",
|
||||||
"issue": "have some issue"
|
"issue": "have some issue",
|
||||||
|
"case1": "Find last year's baby/pet material",
|
||||||
|
"case2": "Find last year's food",
|
||||||
|
"case3": "Find recent travel material"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,6 +13,9 @@
|
|||||||
"loading": "加载中...",
|
"loading": "加载中...",
|
||||||
"refresh": "刷新",
|
"refresh": "刷新",
|
||||||
"error": "出错了",
|
"error": "出错了",
|
||||||
"issue": "发生了一些问题"
|
"issue": "发生了一些问题",
|
||||||
|
"case1": "找去年我家宝宝/宠物的素材片段",
|
||||||
|
"case2": "找去年吃过的美食",
|
||||||
|
"case3": "找近期旅游的素材"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user