Skip to content

Commit 72d4cc3

Browse files
fix(studio): a host can claim its writes under the key Studio's edit history uses (#5064)
* fix(studio): a host can claim its writes under the key Studio's edit history uses * fix(studio): drop the claimKey comment, the comment share may not rise
1 parent 6791ea5 commit 72d4cc3

2 files changed

Lines changed: 29 additions & 3 deletions

File tree

‎packages/studio/src/hooks/usePersistentEditHistory.test.ts‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ async function studio({ withHistory = true } = {}) {
6262
const file = () => readFileSync(join(dir, "index.html"), "utf8");
6363
const save = (content: string) => writeFileSync(join(dir, "index.html"), content);
6464
const readFile = async (path: string) => readFileSync(join(dir, path), "utf8");
65-
return { dir, hook: () => hook, file, save, readFile };
65+
return { dir, history, hook: () => hook, file, save, readFile };
6666
}
6767

6868
it("an edit Studio saved is undone and redone by the project's history, with the preview's before and after", async () => {
@@ -411,6 +411,30 @@ it("a key one page holds does not join another page's edit under the same key",
411411
expect(file()).toBe("B");
412412
});
413413

414+
it("a host's write claimed under claimKey joins Studio's save under the same key: one undo takes back both", async () => {
415+
const { dir, history, hook, file, save, readFile } = await studio();
416+
const key = "drop:1";
417+
writeFileSync(join(dir, "clip.mp4"), "media");
418+
await history.claim({ kind: "person", name: "You" }, "Dropped on timeline", ["clip.mp4"], {
419+
coalesceKey: hook().claimKey(key),
420+
idleMs: Infinity,
421+
});
422+
save("B");
423+
await act(() =>
424+
hook().recordEdit({
425+
label: "Dropped on timeline",
426+
coalesceKey: key,
427+
coalesceMs: Infinity,
428+
files: { "index.html": { before: "A", after: "B" } },
429+
}),
430+
);
431+
432+
await act(() => hook().undo({ readFile }));
433+
434+
expect(file()).toBe("A");
435+
expect(existsSync(join(dir, "clip.mp4"))).toBe(false);
436+
});
437+
414438
it("an undo before the history view shows a drag's held claim still waits on the files it wrote", async () => {
415439
const { hook, save, readFile } = await studio();
416440
const server = globalThis.fetch;

‎packages/studio/src/hooks/usePersistentEditHistory.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export function usePersistentEditHistory({ projectId }: UsePersistentEditHistory
209209
projectIdRef.current = projectId;
210210
const [own] = useState(createOwnHistory);
211211
const [pageKeyScope] = useState(generateId);
212+
const claimKey = useCallback((key: string) => `${pageKeyScope}:${key}`, [pageKeyScope]);
212213

213214
const refresh = useCallback(async () => {
214215
if (!projectId) return;
@@ -246,7 +247,7 @@ export function usePersistentEditHistory({ projectId }: UsePersistentEditHistory
246247
paths,
247248
overwrote: await overwroteVersions(files),
248249
...(coalesceKey && {
249-
coalesceKey: `${pageKeyScope}:${coalesceKey}`,
250+
coalesceKey: claimKey(coalesceKey),
250251
idleMs: coalesceMs ?? DEFAULT_COALESCE_MS,
251252
}),
252253
});
@@ -258,7 +259,7 @@ export function usePersistentEditHistory({ projectId }: UsePersistentEditHistory
258259
heldClaimRef.current = claimed && coalesceKey ? { paths, at: Date.now() } : null;
259260
await refresh();
260261
},
261-
[projectId, refresh, own, pageKeyScope],
262+
[projectId, refresh, own, claimKey],
262263
);
263264

264265
const step = useCallback(
@@ -341,6 +342,7 @@ export function usePersistentEditHistory({ projectId }: UsePersistentEditHistory
341342
redoPaths: view.forward?.paths ?? [],
342343
state,
343344
recordEdit,
345+
claimKey,
344346
undo,
345347
redo,
346348
predict: own.predict,

0 commit comments

Comments
 (0)