memowake-front/hooks/useUploadManager.ts

94 lines
4.4 KiB
TypeScript
Raw Permalink 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 { 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 };
};