Phase 16E.2 - Runtime Update Reliability and Responsiveness
This commit is contained in:
parent
18f204460f
commit
0fc21041fc
@ -198,7 +198,8 @@
|
||||
let selectionRefreshTimer = null;
|
||||
let runtimeSelectionDirty = false;
|
||||
let runtimeLastActivityAt = 0;
|
||||
const runtimeIdleDelayMs = 1800;
|
||||
let runtimeUpdatePending = false;
|
||||
const runtimeIdleDelayMs = 1200;
|
||||
let selectionHandlerRegistered = false;
|
||||
let isAutoRefreshingScene = false;
|
||||
let sceneWordCountSyncTimer = null;
|
||||
@ -4063,18 +4064,27 @@
|
||||
|
||||
const refreshCurrentSceneFromSelection = async () => {
|
||||
selectionRefreshTimer = null;
|
||||
if (isAutoRefreshingScene || !isAuthenticated || !selectedBook()) {
|
||||
if (isAutoRefreshingScene) {
|
||||
runtimeUpdatePending = true;
|
||||
runtimeDebug("Runtime update deferred; update already running.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAuthenticated || !selectedBook()) {
|
||||
runtimeSelectionDirty = false;
|
||||
runtimeDebug("Runtime update skipped.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!officeReady || !wordHostAvailable || !window.Word || typeof window.Word.run !== "function") {
|
||||
runtimeSelectionDirty = false;
|
||||
setSceneTrackingState("Manual");
|
||||
setDocumentMessage("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!documentStructureCache) {
|
||||
runtimeSelectionDirty = false;
|
||||
setSceneTrackingState("Manual");
|
||||
setDocumentMessage("Document structure is not cached yet. Use Refresh Current Scene.");
|
||||
return;
|
||||
@ -4089,17 +4099,19 @@
|
||||
|
||||
isAutoRefreshingScene = true;
|
||||
runtimeSelectionDirty = false;
|
||||
setSceneTrackingState("Live");
|
||||
runtimeUpdatePending = false;
|
||||
setSceneTrackingState("Updating...");
|
||||
runtimeDebug("Runtime update executed.");
|
||||
|
||||
try {
|
||||
const selectionParagraphs = await window.Word.run(async (context) => await readSelectionParagraphs(context));
|
||||
const selectedIndex = findSelectedParagraphIndex(documentStructureCache, selectionParagraphs);
|
||||
const changed = applyRuntimeSelection(selectedIndex);
|
||||
await recountCachedCurrentScene();
|
||||
|
||||
if (!changed) {
|
||||
setSceneContextStale(false);
|
||||
setSceneTrackingState("Live");
|
||||
setSceneTrackingState("Current scene updated");
|
||||
scheduleSceneWordCountSync();
|
||||
return;
|
||||
}
|
||||
@ -4110,8 +4122,8 @@
|
||||
await refreshPlotDirectorScene();
|
||||
}
|
||||
setSceneContextStale(false);
|
||||
setSceneTrackingState("Live");
|
||||
setDocumentMessage("");
|
||||
setSceneTrackingState("Current scene updated");
|
||||
setDocumentMessage("Current scene updated.");
|
||||
scheduleSceneWordCountSync();
|
||||
} catch (error) {
|
||||
console.error("Unable to refresh current scene from Word selection.", error);
|
||||
@ -4119,6 +4131,10 @@
|
||||
setSceneContextStale(true, "The Word cursor is now in a different scene. Refresh Current Scene before saving.");
|
||||
} finally {
|
||||
isAutoRefreshingScene = false;
|
||||
if (runtimeUpdatePending || runtimeSelectionDirty) {
|
||||
runtimeUpdatePending = false;
|
||||
scheduleSelectionRefresh(runtimeIdleDelayMs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -4127,15 +4143,36 @@
|
||||
window.clearTimeout(selectionRefreshTimer);
|
||||
}
|
||||
selectionRefreshTimer = window.setTimeout(refreshCurrentSceneFromSelection, Math.max(0, delayMs));
|
||||
setSceneTrackingState("Waiting for typing to pause");
|
||||
runtimeDebug("Runtime update scheduled.");
|
||||
};
|
||||
|
||||
const handleDocumentSelectionChanged = () => {
|
||||
const markRuntimeDirty = (reason = "selection", delayMs = runtimeIdleDelayMs) => {
|
||||
runtimeSelectionDirty = true;
|
||||
runtimeLastActivityAt = Date.now();
|
||||
clearPendingSceneWordCountSync();
|
||||
runtimeDebug("Selection changed.");
|
||||
scheduleSelectionRefresh();
|
||||
runtimeDebug(`${reason} changed.`);
|
||||
|
||||
if (isAutoRefreshingScene) {
|
||||
runtimeUpdatePending = true;
|
||||
setSceneTrackingState("Waiting for typing to pause");
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleSelectionRefresh(delayMs);
|
||||
};
|
||||
|
||||
const cancelPendingRuntimeUpdate = () => {
|
||||
if (selectionRefreshTimer) {
|
||||
window.clearTimeout(selectionRefreshTimer);
|
||||
selectionRefreshTimer = null;
|
||||
}
|
||||
runtimeSelectionDirty = false;
|
||||
runtimeUpdatePending = false;
|
||||
};
|
||||
|
||||
const handleDocumentSelectionChanged = () => {
|
||||
markRuntimeDirty("Selection");
|
||||
};
|
||||
|
||||
const removeSelectionTracking = () => {
|
||||
@ -4199,7 +4236,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
cancelPendingRuntimeUpdate();
|
||||
setRefreshCurrentSceneBusy(true);
|
||||
setSceneTrackingState("Updating...");
|
||||
try {
|
||||
const scanned = await refreshDocumentStructure();
|
||||
if (!scanned) {
|
||||
@ -4209,10 +4248,12 @@
|
||||
|
||||
if (!detectedSceneTitle) {
|
||||
await refreshPlotDirectorChapter();
|
||||
setSceneTrackingState("Current scene updated");
|
||||
return;
|
||||
}
|
||||
|
||||
await refreshPlotDirectorScene();
|
||||
setSceneTrackingState("Current scene updated");
|
||||
} finally {
|
||||
setRefreshCurrentSceneBusy(false);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user