{(() => {
const percentage = getProgressPercentage(job.progress);
+ const eta = calculateETA(job);
+ const hasProcessedTotal = typeof job.progress?.processed === "number" && typeof job.progress?.total === "number";
+ const stageProgress = job.progress?.stage ? getStageProgress(job.progress.stage) : null;
+ const timeRange = job.progress?.timeRange as { start: string; end: string } | undefined;
+ const sequenceInfo = job.progress?.sequence as { current: number; total: number } | undefined;
+ const chunkCount = job.progress?.chunkCount as number | undefined;
+ const audioDuration = job.progress?.duration as number | undefined;
+ const otherFields = typeof job.progress === "object"
+ ? Object.entries(job.progress).filter(([k]) =>
+ !["processed", "total", "stage", "sequenceId", "timeRange", "sequence", "chunkCount", "duration", "audioSize"].includes(k)
+ )
+ : [];
+
return (
<>
- {percentage !== null && (
-
+ {percentage !== null ? (
+
+
+
+ {Math.round(percentage)}%
+
+
+ ) : stageProgress && (
+
+
+
+ {stageProgress.current}/{stageProgress.total}
+
+
+ )}
+ {sequenceInfo && (
+
+ Loop {sequenceInfo.current} of {sequenceInfo.total}
+
+ )}
+ {timeRange && (
+
+ Range:{" "}
+ {format(new Date(timeRange.start), "MMM d HH:mm:ss")} → {format(new Date(timeRange.end), "HH:mm:ss")}
+
)}
-
- {typeof job.progress === "object" ? (
- Object.entries(job.progress)
- .slice(0, 3)
- .map(([k, v]) => (
+ {stageProgress && (
+
+ {stageProgress.label}
+
+ )}
+ {hasProcessedTotal && !sequenceInfo && (
+
+ {job.progress.processed} / {job.progress.total}
+
+ )}
+ {(chunkCount || audioDuration) && (
+
+ {chunkCount && {chunkCount} chunks}
+ {audioDuration && (
+
+ {Math.floor(audioDuration / 60)}m {Math.round(audioDuration % 60)}s audio
+
+ )}
+
+ )}
+ {eta && (
+
+ ETA: {eta}
+
+ )}
+ {otherFields.length > 0 && (
+
+ {otherFields.slice(0, 2).map(([k, v]) => {
+ let displayValue = String(v);
+ // Format duration/audioSize as readable values
+ if (k === "duration" && typeof v === "number") {
+ const mins = Math.floor(v / 60);
+ const secs = Math.round(v % 60);
+ displayValue = `${mins}m ${secs}s`;
+ } else if (k === "audioSize" && typeof v === "number") {
+ displayValue = `${(v / 1024 / 1024).toFixed(1)} MB`;
+ }
+ return (
- {k}:{" "}
- {String(v)}
+ {k}: {displayValue}
- ))
- ) : (
-
{String(job.progress)}
- )}
-
+ );
+ })}
+
+ )}
>
);
})()}