// Track when the time estimate was last updated to calculate live remaining time const [estimateSnapshot, setEstimateSnapshot] = useState<{ remainingSeconds: number; capturedAt: number; }>(() => ({ remainingSeconds:timeEstimate.estimatedRemainingSeconds, capturedAt:Date.now(), }));
// Calculate live remaining time that decreases as actual time passes const [liveRemainingSeconds, setLiveRemainingSeconds] = useState<number>( () =>timeEstimate.estimatedRemainingSeconds, );
// Update elapsed time and live remaining time every second when matching is active useEffect(() => { if (!timeEstimate.startTime || progress.current <= 0) { setElapsedSeconds(0); setLiveRemainingSeconds(0); return; }
// Calculate how much time has actually passed since the estimate was captured constsecondsSinceEstimate = Math.floor( (now - estimateSnapshot.capturedAt) / 1000, ); // Subtract elapsed time from the snapshot to get live remaining time constcalculatedRemaining = Math.max( 0, estimateSnapshot.remainingSeconds - secondsSinceEstimate, ); setLiveRemainingSeconds(calculatedRemaining); };
updateTimes();
// Update every second while matching is active constintervalId = setInterval(updateTimes, 1000);
Displays the progress of the manga matching process, including progress bar, status, and time estimate.
Source
Example