fix: tour -- Sync scenes from preview could reach a real save, and a demo text mismatch
Adversarial review of ee2c0d5 (the parsed.scenes crash fix) found the crash
fix's own side effect: stopping the crash meant "Sync scenes from preview"
became clickable for the first time during the tour. That button calls
syncFromPreview() -> scheduleSave() -> a 5s-debounced closure-scoped
commit() -> a real PUT /funpack/api/projects/<id>. patchStore() already
blocks "commit", but only as the exported Store.commit property --
scheduleSave()'s internal setTimeout calls the closure-scoped commit
function directly, bypassing that patch entirely. This directly
contradicts the tour's own welcome copy ("nothing here touches your real
files"). Fixed by blocking syncFromPreview itself, the same way every
other mutating entry point (generate/save/delete/import/...) is already
blocked -- consistent with the existing pattern rather than trying to
patch scheduleSave's internals.
Also fixed a cosmetic mismatch the review caught: the demo preview's
middle scene had prose text while its actual timeline clip (tour-s2, a
video clip) has none -- now both agree.
Verified live: clicked "Sync scenes from preview" mid-tour, confirmed the
block toast fires and no PUT request is made (watched network across the
full 5s+ debounce window), then re-ran the full tour sequence to
completion with zero thrown errors.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
ee2c0d55ea
commit
c020ee8ca8
+12
-2
@@ -269,9 +269,11 @@
|
||||
// that panel renders (pre-existing in v4's tour.js too, found while
|
||||
// verifying this port live).
|
||||
parsed: {
|
||||
// Matches demoProject()'s own three scenes verbatim -- tour-s2 is
|
||||
// a video clip with no prompt text, same as its timeline entry.
|
||||
scenes: [
|
||||
{ text: "Wide establishing shot of the city at dawn, soft haze." },
|
||||
{ text: "B-roll alley clip." },
|
||||
{ text: "" },
|
||||
{ text: "Close-up reaction, emotional beat, shallow depth of field." },
|
||||
],
|
||||
transitions: [],
|
||||
@@ -342,7 +344,7 @@
|
||||
"generate", "generateMontage", "generateSelected", "renderFinal", "exportSelected",
|
||||
"saveSelectedToMediaBin", "commit", "newProject", "loadProject", "deleteProject",
|
||||
"importProject", "downloadProject", "uploadMedia", "deleteMedia", "deleteMediaMany",
|
||||
"interrupt", "resetStudioSession",
|
||||
"interrupt", "resetStudioSession", "syncFromPreview",
|
||||
];
|
||||
const labels = {
|
||||
generate: "Generate",
|
||||
@@ -359,6 +361,14 @@
|
||||
downloadProject: "Download project",
|
||||
uploadMedia: "Upload media",
|
||||
resetStudioSession: "Reset Studio session",
|
||||
// Blocking "commit" only stops external callers of Store.commit -- the
|
||||
// property gets reassigned below, but scheduleSave()'s own setTimeout
|
||||
// calls the closure-scoped `commit` function directly, bypassing this
|
||||
// patch. syncFromPreview() is the one UI entry point that reaches
|
||||
// scheduleSave() (and, through it, a real API.saveProject network
|
||||
// call) without going through anything else already on this list, so
|
||||
// it needs its own block rather than relying on "commit" to cover it.
|
||||
syncFromPreview: "Sync scenes from preview",
|
||||
};
|
||||
blocked.forEach((name) => {
|
||||
if (typeof Store[name] !== "function") return;
|
||||
|
||||
Reference in New Issue
Block a user