major image prog bar update

This commit is contained in:
Desktop
2025-11-12 14:14:29 +05:00
parent fe57c2d321
commit 162d15357a
2 changed files with 60 additions and 77 deletions

View File

@@ -83,9 +83,9 @@ export default function ImageQueueModal({
setSmoothProgress(prev => { setSmoothProgress(prev => {
const current = prev[index] ?? currentPercent; const current = prev[index] ?? currentPercent;
// Only increment if still below 80% and status is processing or pending // Only increment if still below 80% and item is actively processing
const item = localQueue.find(item => item.index === index); const item = localQueue.find(item => item.index === index);
if (current < 80 && (item?.status === 'processing' || item?.status === 'pending')) { if (current < 80 && item?.status === 'processing') {
const newPercentage = Math.min(current + 2, 80); // 2% every 200ms const newPercentage = Math.min(current + 2, 80); // 2% every 200ms
currentPercent = newPercentage; currentPercent = newPercentage;
@@ -111,118 +111,101 @@ export default function ImageQueueModal({
progressIntervalsRef.current[index] = interval; progressIntervalsRef.current[index] = interval;
}; };
const indicesToClear: number[] = [];
localQueue.forEach((item) => { localQueue.forEach((item) => {
// Apply progress logic to all items that are processing OR pending (waiting in queue) if (item.status === 'processing') {
// This ensures all images start progress animation, not just the currently processing one
if (item.status === 'processing' || item.status === 'pending') {
// Initialize smoothProgress if not set (start at 1% for new items)
const currentProgress = smoothProgress[item.index] ?? (item.progress > 0 ? item.progress : 1); const currentProgress = smoothProgress[item.index] ?? (item.progress > 0 ? item.progress : 1);
// Phase 1: 1% → 50% at 100ms per 1% (regardless of events)
// Only start if we're below 50% and no interval is already running
if (currentProgress < 50 && !progressIntervalsRef.current[item.index]) { if (currentProgress < 50 && !progressIntervalsRef.current[item.index]) {
let currentPercent = Math.max(currentProgress, 1); // Start from 1% or current if higher let currentPercent = Math.max(currentProgress, 1);
const interval = setInterval(() => { const interval = setInterval(() => {
setSmoothProgress(prev => { setSmoothProgress(prev => {
const current = prev[item.index] ?? currentPercent; const current = prev[item.index] ?? currentPercent;
// Only increment if still below 50% and status is processing or pending if (current < 50 && item.status === 'processing') {
if (current < 50 && (item.status === 'processing' || item.status === 'pending')) { const newPercentage = Math.min(current + 1, 50);
const newPercentage = Math.min(current + 1, 50); // 1% every 100ms
currentPercent = newPercentage; currentPercent = newPercentage;
// Stop if we've reached 50%
if (newPercentage >= 50) { if (newPercentage >= 50) {
clearInterval(interval); clearInterval(interval);
delete progressIntervalsRef.current[item.index]; delete progressIntervalsRef.current[item.index];
// Start Phase 2: 2% every 200ms until 80%
if (newPercentage < 80) { if (newPercentage < 80) {
startPhase2Animation(item.index, newPercentage); startPhase2Animation(item.index, newPercentage);
} }
} }
return { return {
...prev, ...prev,
[item.index]: newPercentage [item.index]: newPercentage
}; };
} else { } else {
// Stop if status changed or reached 50%
clearInterval(interval); clearInterval(interval);
delete progressIntervalsRef.current[item.index]; delete progressIntervalsRef.current[item.index];
return prev; return prev;
} }
}); });
}, 200); // 1% every 100ms }, 200);
progressIntervalsRef.current[item.index] = interval; progressIntervalsRef.current[item.index] = interval;
} } else if (currentProgress >= 50 && currentProgress < 80 && !progressIntervalsRef.current[item.index]) {
// Phase 2: 2% every 200ms until 80%
else if (currentProgress >= 50 && currentProgress < 80 && !progressIntervalsRef.current[item.index]) {
startPhase2Animation(item.index, currentProgress); startPhase2Animation(item.index, currentProgress);
} } else if (item.imageUrl && currentProgress < 100 && !progressIntervalsRef.current[item.index]) {
// Phase 3: Event-based smooth completion to 100% (after image is downloaded and shown)
// Check if image is ready (has imageUrl) even if still processing
else if (item.imageUrl && currentProgress < 100 && !progressIntervalsRef.current[item.index]) {
// Stop any existing animation
if (progressIntervalsRef.current[item.index]) { if (progressIntervalsRef.current[item.index]) {
clearInterval(progressIntervalsRef.current[item.index]); clearInterval(progressIntervalsRef.current[item.index]);
delete progressIntervalsRef.current[item.index]; delete progressIntervalsRef.current[item.index];
} }
// Smoothly complete to 100% let animatingProgress = Math.max(currentProgress, 80);
if (!progressIntervalsRef.current[item.index]) { const startProgress = animatingProgress;
let animatingProgress = Math.max(currentProgress, 80); // Start from 80% or current if higher const endProgress = 100;
const startProgress = animatingProgress; const duration = 800;
const endProgress = 100; const startTime = Date.now();
const duration = 800; // 500ms
const startTime = Date.now(); const interval = setInterval(() => {
const elapsed = Date.now() - startTime;
const interval = setInterval(() => { const progress = Math.min(1, elapsed / duration);
const elapsed = Date.now() - startTime;
const progress = Math.min(1, elapsed / duration); const eased = 1 - Math.pow(1 - progress, 2);
animatingProgress = startProgress + ((endProgress - startProgress) * eased);
// Ease-out quadratic
const eased = 1 - Math.pow(1 - progress, 2); if (animatingProgress >= 100 || elapsed >= duration) {
animatingProgress = startProgress + ((endProgress - startProgress) * eased); animatingProgress = 100;
clearInterval(interval);
if (animatingProgress >= 100 || elapsed >= duration) { delete progressIntervalsRef.current[item.index];
animatingProgress = 100; }
clearInterval(interval);
delete progressIntervalsRef.current[item.index]; setSmoothProgress(prev => ({
} ...prev,
[item.index]: Math.round(animatingProgress)
setSmoothProgress(prev => ({ }));
...prev, }, 16);
[item.index]: Math.round(animatingProgress)
})); progressIntervalsRef.current[item.index] = interval;
}, 16);
progressIntervalsRef.current[item.index] = interval;
}
} }
} } else {
});
// Handle non-processing items
localQueue.forEach((item) => {
if (item.status !== 'processing') {
// Stop animation for completed/failed items
if (progressIntervalsRef.current[item.index]) { if (progressIntervalsRef.current[item.index]) {
clearInterval(progressIntervalsRef.current[item.index]); clearInterval(progressIntervalsRef.current[item.index]);
delete progressIntervalsRef.current[item.index]; delete progressIntervalsRef.current[item.index];
} }
// Clear smooth progress for completed/failed items
if (item.status === 'completed' || item.status === 'failed') { if (smoothProgress[item.index] !== undefined) {
setSmoothProgress(prev => { indicesToClear.push(item.index);
const next = { ...prev };
delete next[item.index];
return next;
});
} }
} }
}); });
if (indicesToClear.length > 0) {
setSmoothProgress(prev => {
const next = { ...prev };
indicesToClear.forEach(idx => {
delete next[idx];
});
return next;
});
}
// Cleanup on unmount // Cleanup on unmount
return () => { return () => {

View File

@@ -71,7 +71,7 @@ export default function Usage() {
<div className="p-6"> <div className="p-6">
<PageMeta title="Usage" description="Monitor your plan limits and usage statistics" /> <PageMeta title="Usage" description="Monitor your plan limits and usage statistics" />
<div className="mb-6"> <div className="mb-6">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Acoount Limits Usage 5</h1> <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Acoount Limits Usage 6</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">Monitor your plan limits and usage statistics</p> <p className="text-gray-600 dark:text-gray-400 mt-1">Monitor your plan limits and usage statistics</p>
</div> </div>