with open("frontend/src/App.tsx", "r", encoding="utf-8") as f: content = f.read() old_export_progress = """ {(job?.kind === "split" || job?.kind === "split_all") && job.status !== "completed" && ( {job.message || `Status: ${job.status}`} {job.details && ( )} )}""" new_export_progress = """ {(job?.kind === "split" || job?.kind === "split_all") && job.status !== "completed" && ( {job.kind === "split_all" ? "Bulk Export Progress" : "Export Progress"} {job.kind === "split_all" && job.details?.label && (() => { const match = /^(\d+)\\/(\d+) (.+)$/.exec(job.details.label); if (match) { const index = Number(match[1]); const total = Number(match[2]); const filename = match[3]; const videoProgress = Math.max(0, Math.min(100, (job.progress - (index - 1) / total) * total * 100)); return ( Overall Bulk Progress ({index}/{total} videos) Current Video: {filename} Current Stage: {job.details.stage || "working"} ); } return null; })()} {job.kind === "split" && ( Video Progress Current Stage: {job.details?.stage || "working"} )} {job.details?.stage_eta && } {job.details?.total_eta && } {job.kind === "split_all" && ( Queue Queue {videoList.map((v, i) => { const match = job.details?.label ? /^(\d+)\\/(\d+) (.+)$/.exec(job.details.label) : null; const currentIndex = match ? Number(match[1]) - 1 : -1; const status = i < currentIndex ? "completed" : i === currentIndex ? "running" : "pending"; return ( {status === "completed" ? "✓ " : status === "running" ? "▶ " : "• "} {v.filename} ); })} )} )}""" content = content.replace(old_export_progress, new_export_progress) with open("frontend/src/App.tsx", "w", encoding="utf-8") as f: f.write(content) print("App.tsx export UI patched")