125 lines
4.8 KiB
TypeScript
125 lines
4.8 KiB
TypeScript
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>
|
||
);
|
||
}
|