refactor: 上传管理单独抽成hook

This commit is contained in:
Junhui Chen 2025-07-17 20:20:14 +08:00
parent 44ff7ce36d
commit e9079768b3
2 changed files with 97 additions and 85 deletions

View File

@ -1,14 +1,12 @@
import ChatSvg from "@/assets/icons/svg/chat.svg";
import UploaderProgress from "@/components/file-upload/upload-progress/uploader-progress";
import AskNavbar from "@/components/layout/ask";
import { endUploadSessionInDb, syncUploadSessionState } from "@/features/appState/appStateSlice";
import { triggerManualUpload } from "@/lib/background-uploader/automatic";
import { exist_pending_tasks, getUploadTasksSince, UploadTask } from "@/lib/db";
import { useUploadManager } from "@/hooks/useUploadManager";
import { fetchApi } from "@/lib/server-api-util";
import { useAppDispatch, useAppSelector } from "@/store";
import { Chat } from "@/types/ask";
import { router, useFocusEffect } from "expo-router";
import React, { useCallback, useEffect, useState } from 'react';
import { router } from "expo-router";
import React, { useEffect, useState } from 'react';
import { FlatList, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
@ -47,86 +45,7 @@ const MemoList = () => {
getHistoryList()
}, [])
const [progressInfo, setProgressInfo] = useState({ total: 0, completed: 0, image: '' });
useFocusEffect(
useCallback(() => {
let isActive = true;
let interval: any = null;
const manageUploadState = async (restore_session: boolean = false) => {
if (!isActive) {
console.log('MemoList manageUploadState is not active');
return;
}
// 首先同步Redux中的会话开始时间
const action = await dispatch(syncUploadSessionState());
const sessionStartTime = action.payload as number | null;
if (sessionStartTime) {
// 如果会话存在,则获取任务进度
const allTasks = await getUploadTasksSince(sessionStartTime);
const total = allTasks.length;
const completed = allTasks.filter((t: UploadTask) => t.status === 'success' || t.status === 'failed' || t.status === 'skipped').length;
const pending = allTasks.filter((t: UploadTask) => t.status === 'pending' || t.status === 'uploading');
if (isActive) {
setProgressInfo({ total, completed, image: allTasks[0]?.uri || '' });
}
// 如果任务完成,则结束会话并清除定时器
if (total > 0 && pending.length === 0) {
console.log('MemoList detects all tasks are complete. Ending session.');
if (interval) clearInterval(interval);
dispatch(endUploadSessionInDb());
}
} else {
// 如果没有会话,确保本地状态被重置
if (isActive) {
setProgressInfo({ total: 0, completed: 0, image: '' });
}
}
};
const initializeUploadProcess = async () => {
// First, check if a session is already active.
const action = await dispatch(syncUploadSessionState());
const existingSessionStartTime = action.payload as number | null;
const existPendingTasks = await exist_pending_tasks();
if (existingSessionStartTime && existPendingTasks) {
console.log('MemoList focused, existing session found. Monitoring progress.');
// If a session exists, just start monitoring.
manageUploadState(true); // Initial check
interval = setInterval(manageUploadState, 2000);
} else {
// If no session, then try to trigger a new upload.
console.log('MemoList focused, no existing session. Triggering foreground media upload check.');
const now = new Date();
const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
const newSessionStartTimeStr = await triggerManualUpload(oneDayAgo, now);
if (newSessionStartTimeStr) {
console.log(`New upload session started with time: ${newSessionStartTimeStr}, beginning to monitor...`);
// A new session was started, so start monitoring.
manageUploadState(); // Initial check
interval = setInterval(manageUploadState, 2000);
}
}
};
initializeUploadProcess();
return () => {
isActive = false;
if (interval) {
clearInterval(interval);
}
};
}, [dispatch])
);
const { progressInfo, uploadSessionStartTime: uploadSessionStartTimeFromHook } = useUploadManager();
const renderHeader = () => (
<>

93
hooks/useUploadManager.ts Normal file
View File

@ -0,0 +1,93 @@
import { useAppDispatch, useAppSelector } from "@/store";
import { useFocusEffect } from "expo-router";
import { useCallback, useState } from "react";
import { endUploadSessionInDb, syncUploadSessionState } from "@/features/appState/appStateSlice";
import { triggerManualUpload } from "@/lib/background-uploader/automatic";
import { exist_pending_tasks, getUploadTasksSince, UploadTask } from "@/lib/db";
export const useUploadManager = () => {
const dispatch = useAppDispatch();
const uploadSessionStartTime = useAppSelector((state) => state.appState.uploadSessionStartTime);
const [progressInfo, setProgressInfo] = useState({ total: 0, completed: 0, image: '' });
useFocusEffect(
useCallback(() => {
let isActive = true;
let interval: any = null;
const manageUploadState = async (restore_session: boolean = false) => {
if (!isActive) {
console.log('useUploadManager manageUploadState is not active');
return;
}
// 首先同步Redux中的会话开始时间
const action = await dispatch(syncUploadSessionState());
const sessionStartTime = action.payload as number | null;
if (sessionStartTime) {
// 如果会话存在,则获取任务进度
const allTasks = await getUploadTasksSince(sessionStartTime);
const total = allTasks.length;
const completed = allTasks.filter((t: UploadTask) => t.status === 'success' || t.status === 'failed' || t.status === 'skipped').length;
const pending = allTasks.filter((t: UploadTask) => t.status === 'pending' || t.status === 'uploading');
if (isActive) {
setProgressInfo({ total, completed, image: allTasks[0]?.uri || '' });
}
// 如果任务完成,则结束会话并清除定时器
if (total > 0 && pending.length === 0) {
console.log('useUploadManager detects all tasks are complete. Ending session.');
if (interval) clearInterval(interval);
dispatch(endUploadSessionInDb());
}
} else {
// 如果没有会话,确保本地状态被重置
if (isActive) {
setProgressInfo({ total: 0, completed: 0, image: '' });
}
}
};
const initializeUploadProcess = async () => {
// First, check if a session is already active.
const action = await dispatch(syncUploadSessionState());
const existingSessionStartTime = action.payload as number | null;
const existPendingTasks = await exist_pending_tasks();
if (existingSessionStartTime && existPendingTasks) {
console.log('useUploadManager focused, existing session found. Monitoring progress.');
// If a session exists, just start monitoring.
manageUploadState(true); // Initial check
interval = setInterval(manageUploadState, 2000);
} else {
// If no session, then try to trigger a new upload.
console.log('useUploadManager focused, no existing session. Triggering foreground media upload check.');
const now = new Date();
const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
const newSessionStartTimeStr = await triggerManualUpload(oneDayAgo, now);
if (newSessionStartTimeStr) {
console.log(`New upload session started with time: ${newSessionStartTimeStr}, beginning to monitor...`);
// A new session was started, so start monitoring.
manageUploadState(); // Initial check
interval = setInterval(manageUploadState, 2000);
}
}
};
initializeUploadProcess();
return () => {
isActive = false;
if (interval) {
clearInterval(interval);
}
};
}, [dispatch])
);
return { progressInfo, uploadSessionStartTime };
};