diff --git a/backend/temp_downloads/job_31743b3b-021a-4d64-aff8-e8c10f34c770/generated_video_1.mp4 b/backend/temp_downloads/job_31743b3b-021a-4d64-aff8-e8c10f34c770/generated_video_1.mp4
new file mode 100644
index 0000000..f8dac89
Binary files /dev/null and b/backend/temp_downloads/job_31743b3b-021a-4d64-aff8-e8c10f34c770/generated_video_1.mp4 differ
diff --git a/backend/temp_downloads/job_4e64eb9c-039b-4a58-a4ce-ec8ba4d120b7/generated_video_1.mp4 b/backend/temp_downloads/job_4e64eb9c-039b-4a58-a4ce-ec8ba4d120b7/generated_video_1.mp4
new file mode 100644
index 0000000..7d9d3ff
Binary files /dev/null and b/backend/temp_downloads/job_4e64eb9c-039b-4a58-a4ce-ec8ba4d120b7/generated_video_1.mp4 differ
diff --git a/backend/temp_downloads/job_95739b90-d0e7-4345-a019-0a770ef21a87/generated_video_1.mp4 b/backend/temp_downloads/job_95739b90-d0e7-4345-a019-0a770ef21a87/generated_video_1.mp4
new file mode 100644
index 0000000..02f5290
Binary files /dev/null and b/backend/temp_downloads/job_95739b90-d0e7-4345-a019-0a770ef21a87/generated_video_1.mp4 differ
diff --git a/backend/temp_downloads/job_a8d9e337-79b2-4525-b019-4bb11ba7f213/generated_video_1.mp4 b/backend/temp_downloads/job_a8d9e337-79b2-4525-b019-4bb11ba7f213/generated_video_1.mp4
new file mode 100644
index 0000000..e8cff13
Binary files /dev/null and b/backend/temp_downloads/job_a8d9e337-79b2-4525-b019-4bb11ba7f213/generated_video_1.mp4 differ
diff --git a/backend/temp_downloads/job_d4ffd8b1-bc4a-4344-949e-6ea66777b668/generated_video_1.mp4 b/backend/temp_downloads/job_d4ffd8b1-bc4a-4344-949e-6ea66777b668/generated_video_1.mp4
new file mode 100644
index 0000000..559b25b
Binary files /dev/null and b/backend/temp_downloads/job_d4ffd8b1-bc4a-4344-949e-6ea66777b668/generated_video_1.mp4 differ
diff --git a/frontend/src/components/QueueManager.jsx b/frontend/src/components/QueueManager.jsx
index a1e411b..5d5ee13 100644
--- a/frontend/src/components/QueueManager.jsx
+++ b/frontend/src/components/QueueManager.jsx
@@ -108,8 +108,8 @@ const QueueManager = ({ userEmail }) => {
return job.progress || 0;
};
- const isActiveJob = (job) => {
- const activeStatuses = [
+ const isProcessingJob = (job) => {
+ const processingStatuses = [
JOB_STATUS.STARTING,
JOB_STATUS.UPLOADING_IMAGE,
JOB_STATUS.GENERATING,
@@ -119,15 +119,32 @@ const QueueManager = ({ userEmail }) => {
'retry_2_of_3',
'retry_3_of_3'
];
- return activeStatuses.includes(job.status) || job.status.startsWith('retry_');
+ return processingStatuses.includes(job.status) || job.status.startsWith('retry_');
};
- const getMostRecentActiveJob = () => {
- return jobs.find(job => isActiveJob(job));
+ const isQueuedJob = (job) => {
+ return job.status === JOB_STATUS.QUEUED;
+ };
+
+ const isHistoricalJob = (job) => {
+ return job.status === JOB_STATUS.COMPLETED ||
+ job.status === JOB_STATUS.FAILED ||
+ job.status === JOB_STATUS.CANCELLED;
+ };
+
+ const getProcessingJobs = () => {
+ return jobs.filter(job => isProcessingJob(job))
+ .sort((a, b) => new Date(a.created_at) - new Date(b.created_at)); // FIFO order
+ };
+
+ const getQueuedJobs = () => {
+ return jobs.filter(job => isQueuedJob(job))
+ .sort((a, b) => new Date(a.created_at) - new Date(b.created_at)); // FIFO order
};
const getHistoricalJobs = () => {
- return jobs.filter(job => !isActiveJob(job));
+ return jobs.filter(job => isHistoricalJob(job))
+ .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); // Most recent first
};
const renderDownloadButtons = (job) => {
@@ -170,19 +187,28 @@ const QueueManager = ({ userEmail }) => {
return {buttons};
};
- const renderJobItem = (job, isActive = false) => {
+ const renderJobItem = (job, jobType = 'history', queuePosition = null) => {
+ const isProcessing = jobType === 'processing';
+ const isQueued = jobType === 'queued';
return (
@@ -197,9 +223,10 @@ const QueueManager = ({ userEmail }) => {
color={getStatusColor(job.status)}
size="small"
/>
- {job.status === JOB_STATUS.QUEUED && job.queue_position > 0 && (
+ {isQueued && queuePosition && (
@@ -229,26 +256,40 @@ const QueueManager = ({ userEmail }) => {
{job.message || 'Processing...'}
- {/* Enhanced Progress Bar for Active Jobs */}
+ {/* Progress Bar */}
- {isActive && (
+ {isProcessing && (
{getProgressValue(job)}% complete
)}
+ {isQueued && (
+
+ Waiting in queue...
+
+ )}
+
{/* Download Buttons */}
{renderDownloadButtons(job)}
@@ -359,47 +400,72 @@ const QueueManager = ({ userEmail }) => {
) : (
<>
- {/* Active Job Section */}
- {getMostRecentActiveJob() && (
+ {/* Processing Jobs Section */}
+ {getProcessingJobs().length > 0 && (
<>
-
- Current Video Generation
+
+
+ Currently Processing ({getProcessingJobs().length})
- {renderJobItem(getMostRecentActiveJob(), true)}
+ {getProcessingJobs().map((job, index) => (
+
+ {renderJobItem(job, 'processing')}
+ {index < getProcessingJobs().length - 1 && }
+
+ ))}
+
+ >
+ )}
+
+ {/* Queued Jobs Section */}
+ {getQueuedJobs().length > 0 && (
+ <>
+ {getProcessingJobs().length > 0 && }
+
+
+ In Queue ({getQueuedJobs().length})
+
+
+ {getQueuedJobs().map((job, index) => (
+
+ {renderJobItem(job, 'queued', index + 1)}
+ {index < getQueuedJobs().length - 1 && }
+
+ ))}
-
- {getHistoricalJobs().length > 0 && (
- <>
-
-
- Job History
-
- >
- )}
>
)}
{/* Historical Jobs Section */}
{getHistoricalJobs().length > 0 && (
-
- {getHistoricalJobs().map((job, index) => (
-
- {renderJobItem(job, false)}
- {index < getHistoricalJobs().length - 1 && }
-
- ))}
-
+ <>
+ {(getProcessingJobs().length > 0 || getQueuedJobs().length > 0) && (
+
+ )}
+
+
+ History ({getHistoricalJobs().length})
+
+
+ {getHistoricalJobs().map((job, index) => (
+
+ {renderJobItem(job, 'history')}
+ {index < getHistoricalJobs().length - 1 && }
+
+ ))}
+
+ >
)}
>
)}
diff --git a/frontend/src/components/VideoForm.jsx b/frontend/src/components/VideoForm.jsx
index 3755bf8..713b204 100644
--- a/frontend/src/components/VideoForm.jsx
+++ b/frontend/src/components/VideoForm.jsx
@@ -432,7 +432,7 @@ const VideoForm = ({ onSubmit, isGenerating, userJobs = [], queueLimit = 4 }) =>
>
{userJobs.length >= queueLimit
? 'Queue Full'
- : userJobs.some(job => ['starting', 'uploading_image', 'generating', 'processing', 'downloading'].includes(job.status))
+ : userJobs.some(job => ['starting', 'uploading_image', 'generating', 'processing', 'downloading', 'queued'].includes(job.status))
? 'Add to Queue'
: 'Generate Video'
}