312 lines
9.0 KiB
TypeScript
312 lines
9.0 KiB
TypeScript
import ChatSvg from "@/assets/icons/svg/chat.svg";
|
||
import AutoUploadScreen from "@/components/file-upload/autoUploadScreen";
|
||
import AskNavbar from "@/components/layout/ask";
|
||
import { getUploadTasks, UploadTask } from "@/lib/db";
|
||
import { fetchApi } from "@/lib/server-api-util";
|
||
import { Chat } from "@/types/ask";
|
||
import { router, useFocusEffect } from "expo-router";
|
||
import React, { useCallback, useEffect, useState } from 'react';
|
||
import { FlatList, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||
const MemoList = () => {
|
||
const insets = useSafeAreaInsets();
|
||
const [uploadTasks, setUploadTasks] = useState<UploadTask[]>([]); // 新增上传任务状态
|
||
// 历史消息
|
||
const [historyList, setHistoryList] = React.useState<Chat[]>([]);
|
||
|
||
// 获取历史消息
|
||
const getHistoryList = async () => {
|
||
await fetchApi<Chat[]>(`/chats`).then((res) => {
|
||
setHistoryList(res)
|
||
})
|
||
}
|
||
|
||
// 获取对话历史消息
|
||
const getChatHistory = async (id: string) => {
|
||
// 跳转到聊天页面,并携带参数
|
||
router.push({
|
||
pathname: '/ask',
|
||
params: {
|
||
sessionId: id,
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
const handleMemoPress = (item: Chat) => {
|
||
getChatHistory(item.session_id)
|
||
}
|
||
|
||
useEffect(() => {
|
||
getHistoryList()
|
||
}, [])
|
||
|
||
|
||
useFocusEffect(
|
||
useCallback(() => {
|
||
// 设置定时器,每秒查询一次上传进度
|
||
const intervalId = setInterval(async () => {
|
||
const tasks = await getUploadTasks();
|
||
setUploadTasks(tasks);
|
||
}, 1000);
|
||
|
||
return () => clearInterval(intervalId); // 清理定时器
|
||
}, [])
|
||
);
|
||
|
||
return (
|
||
<View style={[styles.container, { paddingTop: insets.top }]}>
|
||
{/* 上传进度展示区域 */}
|
||
|
||
<View className="w-full h-80">
|
||
{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>
|
||
)}
|
||
<AutoUploadScreen />
|
||
</View>
|
||
|
||
{/* 顶部标题和上传按钮 */}
|
||
<View style={styles.header}>
|
||
<Text style={styles.title}>Memo List</Text>
|
||
</View>
|
||
|
||
{/* 历史对话 */}
|
||
<FlatList
|
||
data={historyList}
|
||
keyExtractor={(item) => item.session_id}
|
||
ItemSeparatorComponent={() => (
|
||
<View style={styles.separator} />
|
||
)}
|
||
renderItem={({ item }) => (
|
||
<TouchableOpacity
|
||
style={styles.memoItem}
|
||
onPress={() => handleMemoPress(item)}
|
||
>
|
||
<View className="w-[3rem] h-[3rem] z-1">
|
||
<ChatSvg
|
||
width="100%"
|
||
height="100%"
|
||
preserveAspectRatio="xMidYMid meet"
|
||
/>
|
||
</View>
|
||
<View style={styles.memoContent}>
|
||
<Text
|
||
style={styles.memoTitle}
|
||
numberOfLines={1}
|
||
ellipsizeMode="tail"
|
||
>
|
||
{item.title || 'memo list 历史消息'}
|
||
</Text>
|
||
<Text
|
||
style={styles.memoTitle}
|
||
numberOfLines={1}
|
||
ellipsizeMode="tail"
|
||
>
|
||
{item.latest_message?.content?.text || 'memo list 历史消息'}
|
||
</Text>
|
||
</View>
|
||
</TouchableOpacity>
|
||
)}
|
||
/>
|
||
{/* 底部导航栏 */}
|
||
<AskNavbar />
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
separator: {
|
||
height: 1,
|
||
backgroundColor: '#f0f0f0',
|
||
marginLeft: 60, // 与头像对齐
|
||
},
|
||
container: {
|
||
flex: 1,
|
||
backgroundColor: 'white',
|
||
},
|
||
header: {
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: 16,
|
||
},
|
||
title: {
|
||
fontSize: 24,
|
||
fontWeight: 'bold',
|
||
color: '#4C320C',
|
||
},
|
||
uploadButton: {
|
||
padding: 8,
|
||
},
|
||
searchContainer: {
|
||
flexDirection: 'row',
|
||
alignItems: 'center',
|
||
backgroundColor: '#FFF',
|
||
borderRadius: 20,
|
||
marginHorizontal: 16,
|
||
paddingHorizontal: 16,
|
||
height: 48,
|
||
shadowColor: '#000',
|
||
shadowOffset: { width: 0, height: 2 },
|
||
shadowOpacity: 0.1,
|
||
shadowRadius: 4,
|
||
elevation: 2,
|
||
},
|
||
searchIcon: {
|
||
marginRight: 8,
|
||
},
|
||
memoItem: {
|
||
flexDirection: 'row',
|
||
borderRadius: 0, // 移除圆角
|
||
padding: 16,
|
||
marginBottom: 0, // 移除底部边距
|
||
alignItems: 'center',
|
||
gap: 16,
|
||
backgroundColor: 'white',
|
||
},
|
||
avatar: {
|
||
width: 60,
|
||
height: 60,
|
||
borderRadius: 30,
|
||
marginRight: 16,
|
||
},
|
||
memoContent: {
|
||
flex: 1,
|
||
marginLeft: 12,
|
||
gap: 6,
|
||
justifyContent: 'center',
|
||
minWidth: 0, // 这行很重要,确保文本容器可以收缩到比内容更小
|
||
},
|
||
memoTitle: {
|
||
fontSize: 16,
|
||
fontWeight: '500',
|
||
color: '#333',
|
||
flex: 1, // 或者 flexShrink: 1
|
||
marginLeft: 12,
|
||
},
|
||
memoSubtitle: {
|
||
fontSize: 14,
|
||
color: '#666',
|
||
},
|
||
tabBar: {
|
||
flexDirection: 'row',
|
||
justifyContent: 'space-around',
|
||
alignItems: 'center',
|
||
backgroundColor: '#FFF',
|
||
borderTopWidth: 1,
|
||
borderTopColor: '#EEE',
|
||
paddingVertical: 12,
|
||
},
|
||
tabBarSvg: {
|
||
color: 'red',
|
||
},
|
||
tabItem: {
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
},
|
||
tabCenter: {
|
||
width: 60,
|
||
height: 60,
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
},
|
||
centerTabIcon: {
|
||
width: 50,
|
||
height: 50,
|
||
borderRadius: 25,
|
||
backgroundColor: '#FF9500',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
marginTop: -30,
|
||
},
|
||
centerTabImage: {
|
||
width: 40,
|
||
height: 40,
|
||
borderRadius: 20,
|
||
},
|
||
// 在 tabBarContainer 样式中添加
|
||
tabBarContainer: {
|
||
position: 'relative',
|
||
paddingBottom: 0,
|
||
overflow: 'visible',
|
||
marginTop: 10, // 添加一些上边距
|
||
},
|
||
tabBarContent: {
|
||
flexDirection: 'row',
|
||
justifyContent: 'space-around',
|
||
alignItems: 'center',
|
||
height: 60,
|
||
position: 'relative',
|
||
backgroundColor: 'rgba(255, 255, 255, 0.7)', // 半透明白色背景
|
||
borderRadius: 30, // 圆角
|
||
marginHorizontal: 16, // 左右边距
|
||
// 添加边框效果
|
||
borderWidth: 1,
|
||
borderColor: 'rgba(255, 255, 255, 0.8)',
|
||
// 添加阴影
|
||
...Platform.select({
|
||
ios: {
|
||
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||
shadowOffset: { width: 0, height: 2 },
|
||
shadowOpacity: 0.8,
|
||
shadowRadius: 4,
|
||
},
|
||
android: {
|
||
elevation: 8,
|
||
},
|
||
}),
|
||
},
|
||
// 移除之前的 tabBarBackground 样式
|
||
// 修改 centerTabShadow 样式
|
||
centerTabShadow: {
|
||
position: 'absolute',
|
||
bottom: 15,
|
||
width: 60,
|
||
height: 60,
|
||
borderRadius: 30,
|
||
backgroundColor: 'white',
|
||
...Platform.select({
|
||
ios: {
|
||
shadowColor: 'rgba(0, 0, 0, 0.2)',
|
||
shadowOffset: { width: 0, height: 4 },
|
||
shadowOpacity: 0.3,
|
||
shadowRadius: 6,
|
||
},
|
||
android: {
|
||
elevation: 10,
|
||
},
|
||
}),
|
||
},
|
||
centerTabContainer: {
|
||
flex: 1,
|
||
alignItems: 'center',
|
||
position: 'relative',
|
||
height: '100%',
|
||
},
|
||
centerTabButton: {
|
||
width: '100%',
|
||
height: '100%',
|
||
borderRadius: 30,
|
||
backgroundColor: '#FF9500',
|
||
justifyContent: 'center',
|
||
alignItems: 'center',
|
||
},
|
||
notificationDot: {
|
||
position: 'absolute',
|
||
top: -2,
|
||
right: -4,
|
||
width: 10,
|
||
height: 10,
|
||
borderRadius: 5,
|
||
backgroundColor: '#FF3B30',
|
||
},
|
||
});
|
||
|
||
export default MemoList; |