memowake-front/app/(tabs)/user-message.tsx
2025-07-17 15:45:41 +08:00

125 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Choice from '@/components/user-message.tsx/choice';
import Done from '@/components/user-message.tsx/done';
import Look from '@/components/user-message.tsx/look';
import UserName from '@/components/user-message.tsx/userName';
import { checkAuthStatus } from '@/lib/auth';
import { getUploadTasks, UploadTask } from '@/lib/db';
import { fetchApi } from '@/lib/server-api-util';
import { FileUploadItem } from '@/types/upload';
import { User } from '@/types/user';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useEffect, useState } from 'react';
import { KeyboardAvoidingView, Platform, ScrollView, StatusBar, Text, View } from 'react-native';
export type Steps = "userName" | "look" | "choice" | "done";
export default function UserMessage() {
const router = useRouter();
// 步骤
const [steps, setSteps] = useState<Steps>("userName")
const [username, setUsername] = useState('')
const [avatar, setAvatar] = useState('')
const [fileData, setFileData] = useState<FileUploadItem[]>([])
const [isLoading, setIsLoading] = useState(false);
const [userInfo, setUserInfo] = useState<User | null>(null);
const [uploadTasks, setUploadTasks] = useState<UploadTask[]>([]); // 新增上传任务状态
const statusBarHeight = StatusBar?.currentHeight ?? 0;
// 获取路由参数
const params = useLocalSearchParams();
const { username: usernameParam } = params;
useEffect(() => {
checkAuthStatus(router);
// 设置定时器,每秒查询一次上传进度
const intervalId = setInterval(async () => {
const tasks = await getUploadTasks();
setUploadTasks(tasks);
}, 1000);
return () => clearInterval(intervalId); // 清理定时器
}, []);
// 获取用户信息
const getUserInfo = async () => {
const res = await fetchApi<User>("/iam/user-info");
setUserInfo(res);
setUsername(res?.nickname || '');
setAvatar(res?.avatar_file_url || '');
}
const handleUser = () => {
setIsLoading(true);
fetchApi("/iam/user/info", {
method: "POST",
body: JSON.stringify({
username,
avatar_file_id: fileData?.[0]?.originalFile?.file_id
})
}).then(() => {
setIsLoading(false);
setSteps('done');
}).catch(() => {
setIsLoading(false);
});
};
useEffect(() => {
getUserInfo();
setSteps("userName")
}, [usernameParam]);
return (
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : -statusBarHeight}
>
<ScrollView
contentContainerStyle={{
flexGrow: 1,
}}
keyboardShouldPersistTaps="handled"
bounces={false}
>
{/* 上传进度展示区域 */}
{uploadTasks.length > 0 && (
<View style={{ padding: 10, backgroundColor: '#f0f0f0', borderBottomWidth: 1, borderBottomColor: '#ccc' }}>
<Text style={{ fontWeight: 'bold', marginBottom: 5 }}></Text>
{uploadTasks.map((task) => (
<Text key={task.uri}>
{task.filename}: {task.status} ({task.progress}%)
</Text>
))}
</View>
)}
<View className="h-full" key={steps}>
{(() => {
const components = {
userName: (
<UserName
setSteps={setSteps}
username={username}
setUsername={setUsername}
/>
),
look: (
<Look
setSteps={setSteps}
fileData={fileData}
setFileData={setFileData}
isLoading={isLoading}
handleUser={handleUser}
avatar={avatar}
/>
),
choice: <Choice setSteps={setSteps} />,
done: <Done />
};
return components[steps as keyof typeof components] || null;
})()}
</View>
</ScrollView>
</KeyboardAvoidingView>
);
}