feat: 引导

This commit is contained in:
jinyaqiu 2025-07-30 14:21:44 +08:00
parent 14377edd1e
commit 301c818a66
6 changed files with 168 additions and 40 deletions

View File

@ -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>
{/* 聊天页面 */} {/* 聊天页面 */}

View File

@ -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'
}
})

View File

@ -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('');

View File

@ -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;
}
};

View File

@ -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"
} }
} }

View File

@ -13,6 +13,9 @@
"loading": "加载中...", "loading": "加载中...",
"refresh": "刷新", "refresh": "刷新",
"error": "出错了", "error": "出错了",
"issue": "发生了一些问题" "issue": "发生了一些问题",
"case1": "找去年我家宝宝/宠物的素材片段",
"case2": "找去年吃过的美食",
"case3": "找近期旅游的素材"
} }
} }