From e9079768b3417f44a77d611eb342203bcc2cf942 Mon Sep 17 00:00:00 2001 From: Junhui Chen Date: Thu, 17 Jul 2025 20:20:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=B8=8A=E4=BC=A0=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=8D=95=E7=8B=AC=E6=8A=BD=E6=88=90hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/memo-list.tsx | 89 ++----------------------------------- hooks/useUploadManager.ts | 93 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 85 deletions(-) create mode 100644 hooks/useUploadManager.ts diff --git a/app/(tabs)/memo-list.tsx b/app/(tabs)/memo-list.tsx index 83d2e82..9ab35d2 100644 --- a/app/(tabs)/memo-list.tsx +++ b/app/(tabs)/memo-list.tsx @@ -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 = () => ( <> diff --git a/hooks/useUploadManager.ts b/hooks/useUploadManager.ts new file mode 100644 index 0000000..b19ff11 --- /dev/null +++ b/hooks/useUploadManager.ts @@ -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 }; +};