Speed up global prompt Apply → scene text sync

Update timeline and preview optimistically from the parse response,
save immediately instead of waiting on the autosave debounce, refresh
preview without delay after commit, and force an inspector rebuild
even when the global prompt field still has focus.
This commit is contained in:
digital-garbage
2026-06-10 16:44:46 +03:00
parent aca161da05
commit e514c8f178
2 changed files with 48 additions and 15 deletions
+12 -4
View File
@@ -529,10 +529,18 @@
apply.title = "Split this prompt into anchor, scenes and transitions on the timeline (overwrites it)";
apply.disabled = !val.trim(); // clickable whenever there's a prompt to (re)split — not only after edits
apply.onclick = async () => {
apply.disabled = true; apply.textContent = "Applying…";
await S.applyGlobalPrompt(gpDraft != null ? gpDraft : live);
gpDraft = null;
S.set({}); // re-render so the field returns to its live view
_editing = false;
ta.blur();
apply.disabled = true;
apply.textContent = "Applying…";
try {
const ok = await S.applyGlobalPrompt(gpDraft != null ? gpDraft : live);
if (ok) gpDraft = null;
} finally {
apply.disabled = false;
apply.textContent = "Apply →";
render(S.get());
}
};
head.append(apply);
sec.append(head);
+36 -11
View File
@@ -167,7 +167,7 @@
_pruneSelection();
notify();
refreshProjectList();
refreshPreview();
refreshPreview(true);
} catch (e) {
state.saving = false; notify();
console.error("save failed", e);
@@ -544,15 +544,15 @@
// anchor + one scene per parsed segment + transitions matched from the library.
// Existing per-scene source / length settings are carried over by index.
async function applyGlobalPrompt(text) {
if (!state.project) return;
if (!state.project) return false;
state.project.global_prompt = text;
let res;
try { res = await API.parsePrompt(state.project.id, text); }
catch (e) { alert("Could not parse the global prompt: " + e.message); return; }
catch (e) { alert("Could not parse the global prompt: " + e.message); return false; }
// The verbatim split is authoritative: correct (shortcut-aware) boundaries, scene
// text kept exactly as typed, anchor + scenes reproduce the global prompt.
const v = res.parsed_verbatim || res.parsed_raw || res.parsed || {};
if (!(v.scenes || []).length) { alert("Nothing parsed — no scenes detected."); return; }
if (!(v.scenes || []).length) { alert("Nothing parsed — no scenes detected."); return false; }
state.project.anchor = v.anchor || "";
const old = state.project.scenes || [];
@@ -565,10 +565,32 @@
_applyDetectedTransitions(next, v.transitions);
state.project.scenes = next;
state.sceneGhosts = []; // scene ids changed — old ghosts no longer anchor correctly
state.selectedSceneId = null; // show project view so the result is visible
state.selectedSceneIds = [];
_selectionAnchorId = null;
notify(); scheduleSave();
const firstId = next[0]?.id || null;
state.selectedSceneId = firstId;
state.selectedSceneIds = firstId ? [firstId] : [];
_selectionAnchorId = firstId;
// Refresh the inspector immediately — don't wait for save debounce + preview round-trip.
state.preview = {
...(state.preview || {}),
combined_prompt: text,
display_prompt: text,
parsed: res.parsed,
parsed_raw: res.parsed_raw,
parsed_verbatim: res.parsed_verbatim,
for_generation: false,
};
notify();
clearTimeout(saveTimer);
saveTimer = null;
state.saving = true;
notify();
try {
await commit();
} catch (e) {
console.error("save after apply failed", e);
return false;
}
return true;
}
// Map detected transitions (visual_effect) onto scene seams via the library (display
@@ -585,14 +607,17 @@
// ── preview ──────────────────────────────────────────────────────────────────
let previewTimer = null;
function refreshPreview() {
function refreshPreview(immediate = false) {
clearTimeout(previewTimer);
previewTimer = setTimeout(async () => {
previewTimer = null;
const run = async () => {
if (!state.project) return;
try { state.preview = await API.preview(state.project.id, false, true); }
catch (e) { state.preview = { parse_error: e.message }; }
notify();
}, 250);
};
if (immediate) return run();
previewTimer = setTimeout(run, 250);
}
// ── generation ───────────────────────────────────────────────────────────────