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