fix(editor): preserve completed imports and reset export state

This commit is contained in:
webadderall
2026-09-21 08:50:23 +10:00
parent 3933531fd9
commit 0514303685
4 changed files with 54 additions and 6 deletions
@@ -47,6 +47,7 @@ export function useExportDialogActions({
session.setShowExportDropdown(true);
session.setExportProgress(null);
session.setExportError(null);
session.setExportedFilePath(undefined);
}, [videoPath, session]);
const resolveCurrentSettings = useCallback(
@@ -120,10 +120,15 @@ export function useRecordingLibrary(
let insertAt = Math.min(before.length, Math.max(0, index ?? before.length));
const addedZooms: ZoomRegion[] = [];
let id = "";
let completed = 0;
for (const path of [...new Set(typeof paths === "string" ? [paths] : paths)]) {
if (cancelled.current) return;
if (cancelled.current) break;
const result = await window.electronAPI.importRecording(sourcePath, path, webcam);
if (!result.success) throw new Error(result.error);
if (!result.success) {
if (cancelled.current) break;
throw new Error(result.error);
}
completed++;
if (current.current.project.videoSourcePath !== source)
throw new Error(
"The project changed while importing. Add the recordings again.",
@@ -174,7 +179,7 @@ export function useRecordingLibrary(
);
}
}
if (!media || cancelled.current) return;
if (!media) return;
const { project, timeline, ui, appearance } = current.current;
if (project.videoSourcePath !== source)
throw new Error("The project changed while importing. Add the recordings again.");
@@ -202,9 +207,9 @@ export function useRecordingLibrary(
ui.setIsPreviewReady(false);
ui.setPreviewVersion((version) => version + 1);
toast.success(
typeof paths === "string"
completed === 1
? "Video added to timeline"
: `${paths.length} videos added to timeline`,
: `${completed} videos added to timeline`,
);
} catch (error) {
if (!cancelled.current) toast.error(`Could not add video: ${String(error)}`);
@@ -121,9 +121,10 @@ export function useProjectOpenActions({
}
const sourcePath = fromFileUrl(result.path);
await window.electronAPI.setCurrentVideoPath(sourcePath, {
const setPathResult = await window.electronAPI.setCurrentVideoPath(sourcePath, {
preserveProjectPath: false,
});
if (!setPathResult.success) throw new Error("Could not load media");
const sourceVideoUrl = await resolveVideoUrl(sourcePath);
try {
videoPlaybackRef.current?.pause();
+41
View File
@@ -359,3 +359,44 @@ for (const enabled of [true, false]) {
}
});
}
test("cancelling a batch keeps completed clips and stops the remaining import", async ({
page,
}) => {
await setup(page);
await page.evaluate(() => {
let count = 0;
let finish: ((result: { success: false; error: string }) => void) | undefined;
window.electronAPI.importRecording = async () => {
count++;
if (count === 1)
return {
success: true,
value: {
path: "/sequence-first.mp4",
url: `${location.origin}/tests/ui/fixtures/filmstrip.mp4`,
sourceStartMs: 6000,
durationMs: 1000,
totalDurationMs: 7000,
},
};
document.documentElement.dataset.pendingImport = "true";
return new Promise((resolve) => {
finish = resolve;
});
};
window.electronAPI.cancelRecordingImport = async () => {
finish?.({ success: false, error: "Cancelled" });
return { success: true };
};
});
const panel = page.getByRole("complementary", { name: "Videos" });
await panel.locator('[data-slot="checkbox-control"]').first().click();
await panel
.locator('[data-recording-path="/recordings/second.mp4"]')
.dragTo(page.locator('[data-variant="clip"]'), { targetPosition: { x: 5, y: 15 } });
await expect(page.locator("html")).toHaveAttribute("data-pending-import", "true");
await page.getByRole("button", { name: "Cancel", exact: true }).click();
await expect(page.getByText("Adding video…")).toHaveCount(0);
await expect(page.locator('[data-variant="clip"]')).toHaveCount(2);
});