From ba1b5bb96582f028d0b634fc87d74220e771e1c1 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 9 Mar 2026 22:54:47 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20Fix=20for=20showing=20accurate?= =?UTF-8?q?=20import=20counts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Import/RealTimeImportStats.tsx | 71 +++++++++++++++---- src/client/hooks/useImportSessionStatus.ts | 4 +- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/client/components/Import/RealTimeImportStats.tsx b/src/client/components/Import/RealTimeImportStats.tsx index 089103c..1ca6df9 100644 --- a/src/client/components/Import/RealTimeImportStats.tsx +++ b/src/client/components/Import/RealTimeImportStats.tsx @@ -18,6 +18,12 @@ import { useImportSessionStatus } from "../../hooks/useImportSessionStatus"; export const RealTimeImportStats = (): ReactElement => { const [importError, setImportError] = useState(null); const [detectedFile, setDetectedFile] = useState(null); + const [socketImport, setSocketImport] = useState<{ + active: boolean; + completed: number; + total: number; + failed: number; + } | null>(null); const queryClient = useQueryClient(); const { getSocket, disconnectSocket, importJobQueue } = useStore( @@ -100,14 +106,53 @@ export const RealTimeImportStats = (): ReactElement => { setTimeout(() => setDetectedFile(null), 5000); }; + const handleImportStarted = () => { + setSocketImport({ active: true, completed: 0, total: 0, failed: 0 }); + }; + + const handleCoverExtracted = (payload: { + completedJobCount: number; + totalJobCount: number; + importResult: unknown; + }) => { + setSocketImport((prev) => ({ + active: true, + completed: payload.completedJobCount, + total: payload.totalJobCount, + failed: prev?.failed ?? 0, + })); + }; + + const handleCoverExtractionFailed = (payload: { + failedJobCount: number; + importResult: unknown; + }) => { + setSocketImport((prev) => + prev ? { ...prev, failed: payload.failedJobCount } : null, + ); + }; + + const handleQueueDrained = () => { + setSocketImport((prev) => (prev ? { ...prev, active: false } : null)); + handleStatsChange(); + }; + socket.on("LS_LIBRARY_STATS", handleStatsChange); socket.on("LS_FILES_MISSING", handleStatsChange); socket.on("LS_FILE_DETECTED", handleFileDetected); + socket.on("LS_INCREMENTAL_IMPORT_STARTED", handleImportStarted); + socket.on("LS_COVER_EXTRACTED", handleCoverExtracted); + socket.on("LS_COVER_EXTRACTION_FAILED", handleCoverExtractionFailed); + socket.on("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained); return () => { socket.off("LS_LIBRARY_STATS", handleStatsChange); socket.off("LS_FILES_MISSING", handleStatsChange); socket.off("LS_FILE_DETECTED", handleFileDetected); + socket.off("LS_INCREMENTAL_IMPORT_STARTED", handleImportStarted); + socket.off("LS_COVER_EXTRACTED", handleCoverExtracted); + socket.off("LS_COVER_EXTRACTION_FAILED", handleCoverExtractionFailed); + socket.off("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained); }; }, [getSocket, queryClient]); @@ -151,12 +196,14 @@ export const RealTimeImportStats = (): ReactElement => { const hasSessionStats = importSession.isActive && sessionStats !== null; const totalFiles = stats.totalLocalFiles; - const importedCount = hasSessionStats - ? sessionStats!.filesSucceeded - : stats.alreadyImported; + const importedCount = stats.alreadyImported; const failedCount = hasSessionStats ? sessionStats!.filesFailed : 0; - const showProgressBar = importSession.isActive; + const showProgressBar = socketImport !== null; + const socketProgressPct = + socketImport && socketImport.total > 0 + ? Math.round((socketImport.completed / socketImport.total) * 100) + : 0; const showFailedCard = hasSessionStats && failedCount > 0; const showMissingCard = missingCount > 0; @@ -214,20 +261,20 @@ export const RealTimeImportStats = (): ReactElement => {
- {importSession.isActive - ? `Importing ${sessionStats?.filesSucceeded ?? 0} / ${sessionStats?.filesQueued ?? 0}` - : `${sessionStats?.filesSucceeded ?? 0} / ${sessionStats?.filesQueued ?? 0} imported`} + {socketImport!.active + ? `Importing ${socketImport!.completed} / ${socketImport!.total}` + : `${socketImport!.completed} / ${socketImport!.total} imported`} - {Math.round(importSession.progress)}% complete + {socketProgressPct}% complete
- {importSession.isActive && ( + {socketImport!.active && (
)}
@@ -243,7 +290,7 @@ export const RealTimeImportStats = (): ReactElement => { style={{ backgroundColor: "#6b7280" }} >
{totalFiles}
-
total files
+
in import folder
{/* Imported */} @@ -255,7 +302,7 @@ export const RealTimeImportStats = (): ReactElement => { {importedCount}
- {importSession.isActive ? "imported so far" : "imported"} + {importSession.isActive ? "imported so far" : "imported in database"}
diff --git a/src/client/hooks/useImportSessionStatus.ts b/src/client/hooks/useImportSessionStatus.ts index 56dd7a5..64e10b7 100644 --- a/src/client/hooks/useImportSessionStatus.ts +++ b/src/client/hooks/useImportSessionStatus.ts @@ -258,7 +258,7 @@ export const useImportSessionStatus = (): ImportSessionState => { }; const handleSessionStarted = () => { - console.log("[useImportSessionStatus] IMPORT_SESSION_STARTED event received"); + console.log("[useImportSessionStatus] IMPORT_SESSION_STARTED / LS_INCREMENTAL_IMPORT_STARTED event received"); // Reset completion flags when new session starts completionEventReceived.current = false; queueDrainedEventReceived.current = false; @@ -275,12 +275,14 @@ export const useImportSessionStatus = (): ImportSessionState => { socket.on("IMPORT_SESSION_COMPLETED", handleSessionCompleted); socket.on("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained); socket.on("IMPORT_SESSION_STARTED", handleSessionStarted); + socket.on("LS_INCREMENTAL_IMPORT_STARTED", handleSessionStarted); socket.on("IMPORT_SESSION_UPDATED", handleSessionUpdated); return () => { socket.off("IMPORT_SESSION_COMPLETED", handleSessionCompleted); socket.off("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained); socket.off("IMPORT_SESSION_STARTED", handleSessionStarted); + socket.off("LS_INCREMENTAL_IMPORT_STARTED", handleSessionStarted); socket.off("IMPORT_SESSION_UPDATED", handleSessionUpdated); }; }, [getSocket, refetch]);