From f778010261f66f8a4705671f5a0114341b79825e Mon Sep 17 00:00:00 2001 From: wiiiii123 Date: Fri, 22 May 2026 22:55:21 +0700 Subject: [PATCH] refactor(editor): extract export progress state --- src/components/video-editor/VideoEditor.tsx | 13 +--- .../video-editor/exportProgressState.test.ts | 67 +++++++++++++++++++ .../video-editor/exportProgressState.ts | 15 +++++ 3 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 src/components/video-editor/exportProgressState.test.ts create mode 100644 src/components/video-editor/exportProgressState.ts diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index 0b8b3ca9..9ce15228 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -88,6 +88,7 @@ import { } from "@/utils/aspectRatioUtils"; import { ExtensionIcon } from "./ExtensionIcon"; import { calculateMp4ExportDimensions, calculateMp4SourceDimensions } from "./exportDimensions"; +import { resolveSavingExportProgress } from "./exportProgressState"; import { resolveExportStartSettings } from "./exportStartSettings"; import { resolveExportStatusModel } from "./exportStatusModel"; import { resolveMp4ExportRouting } from "./mp4ExportRouting"; @@ -1213,17 +1214,7 @@ export default function VideoEditor() { ]); const markExportAsSaving = useCallback(() => { - setExportProgress((previous) => ({ - currentFrame: previous?.totalFrames ?? previous?.currentFrame ?? 1, - totalFrames: previous?.totalFrames ?? previous?.currentFrame ?? 1, - percentage: 100, - estimatedTimeRemaining: 0, - renderFps: previous?.renderFps, - renderBackend: previous?.renderBackend, - encodeBackend: previous?.encodeBackend, - encoderName: previous?.encoderName, - phase: "saving", - })); + setExportProgress(resolveSavingExportProgress); }, []); const handleShowCursorChange = useCallback((nextShowCursor: boolean) => { diff --git a/src/components/video-editor/exportProgressState.test.ts b/src/components/video-editor/exportProgressState.test.ts new file mode 100644 index 00000000..a17f2f3f --- /dev/null +++ b/src/components/video-editor/exportProgressState.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, it } from "vitest"; +import type { ExportProgress } from "@/lib/exporter"; +import { resolveSavingExportProgress } from "./exportProgressState"; + +function progress(overrides: Partial = {}): ExportProgress { + return { + currentFrame: 24, + totalFrames: 120, + percentage: 20, + estimatedTimeRemaining: 12, + ...overrides, + }; +} + +describe("resolveSavingExportProgress", () => { + it("marks progress as saving while preserving runtime diagnostics", () => { + expect( + resolveSavingExportProgress( + progress({ + renderFps: 144.25, + renderBackend: "webgpu", + encodeBackend: "ffmpeg", + encoderName: "h264_nvenc", + }), + ), + ).toEqual({ + currentFrame: 120, + totalFrames: 120, + percentage: 100, + estimatedTimeRemaining: 0, + renderFps: 144.25, + renderBackend: "webgpu", + encodeBackend: "ffmpeg", + encoderName: "h264_nvenc", + phase: "saving", + }); + }); + + it("preserves the existing zero-total-frame behavior", () => { + expect( + resolveSavingExportProgress( + progress({ + currentFrame: 36, + totalFrames: 0, + }), + ), + ).toMatchObject({ + currentFrame: 0, + totalFrames: 0, + phase: "saving", + }); + }); + + it("uses a minimal fallback when there is no previous progress", () => { + expect(resolveSavingExportProgress(null)).toEqual({ + currentFrame: 1, + totalFrames: 1, + percentage: 100, + estimatedTimeRemaining: 0, + renderFps: undefined, + renderBackend: undefined, + encodeBackend: undefined, + encoderName: undefined, + phase: "saving", + }); + }); +}); diff --git a/src/components/video-editor/exportProgressState.ts b/src/components/video-editor/exportProgressState.ts new file mode 100644 index 00000000..a928fdb0 --- /dev/null +++ b/src/components/video-editor/exportProgressState.ts @@ -0,0 +1,15 @@ +import type { ExportProgress } from "@/lib/exporter"; + +export function resolveSavingExportProgress(previous: ExportProgress | null): ExportProgress { + return { + currentFrame: previous?.totalFrames ?? previous?.currentFrame ?? 1, + totalFrames: previous?.totalFrames ?? previous?.currentFrame ?? 1, + percentage: 100, + estimatedTimeRemaining: 0, + renderFps: previous?.renderFps, + renderBackend: previous?.renderBackend, + encodeBackend: previous?.encodeBackend, + encoderName: previous?.encoderName, + phase: "saving", + }; +}