fix(forge): ne plus ecraser une completion acceptee au Tab (BUG-055)
This commit is contained in:
+26
-6
@@ -653,17 +653,22 @@ function _invalidateActiveTabCache(vault, path) {
|
||||
* pre-write content, and — worse — an open editor holds the old text in memory
|
||||
* and its 2s autosave would overwrite the assistant's change with it.
|
||||
*/
|
||||
async function reloadExternalWrite(vault, path) {
|
||||
async function reloadExternalWrite(vault, path, force = false) {
|
||||
if (!vault || !path) return;
|
||||
const isEdited = state.editorVault === vault && state.editorPath === path;
|
||||
if (isEdited) {
|
||||
// Forge hosts its own buffer inside an iframe: ask it to reload from disk.
|
||||
var forgeFrame = document.getElementById("forge-iframe");
|
||||
if (forgeFrame && forgeFrame.contentWindow) {
|
||||
forgeFrame.contentWindow.postMessage({ type: 'parent-reload' }, '*');
|
||||
forgeFrame.contentWindow.postMessage({ type: 'parent-reload', force: !!force }, '*');
|
||||
return;
|
||||
}
|
||||
if (!state.editorView) return;
|
||||
// BUG-055 — a non-forced reload (SSE `index_updated`) is often caused by the
|
||||
// editor's own autosave: reloading then would clobber edits made after the
|
||||
// save. Skip while the save dot reports unsaved local changes.
|
||||
var dirtyDot = document.getElementById("editor-save-dot");
|
||||
if (!force && dirtyDot && dirtyDot.classList.contains("dirty")) return;
|
||||
try {
|
||||
const rawUrl = `/api/file/${encodeURIComponent(vault)}/raw?path=${encodeURIComponent(path)}`;
|
||||
const rawData = await api(rawUrl);
|
||||
@@ -757,9 +762,23 @@ async function saveFile(silent = false) {
|
||||
throw new Error(error.detail || "Erreur de sauvegarde");
|
||||
}
|
||||
|
||||
// Update save dot to saved state
|
||||
if (saveDot) { saveDot.className = 'editor-save-dot ok'; }
|
||||
if (saveLabel) saveLabel.textContent = 'Saved';
|
||||
// BUG-055 — only mark clean when nothing changed while saving; otherwise
|
||||
// keep the unsaved state and schedule another autosave (an SSE reload of
|
||||
// the file must not drop edits typed during the request).
|
||||
const currentContent = state.editorView
|
||||
? state.editorView.state.doc.toString()
|
||||
: state.fallbackEditorEl
|
||||
? state.fallbackEditorEl.value
|
||||
: content;
|
||||
if (silent && currentContent !== content) {
|
||||
if (saveDot) { saveDot.className = 'editor-save-dot dirty'; }
|
||||
if (saveLabel) saveLabel.textContent = 'Unsaved';
|
||||
clearTimeout(window._obsigateAutoSaveTimer);
|
||||
window._obsigateAutoSaveTimer = setTimeout(() => saveFile(true), 2000);
|
||||
} else {
|
||||
if (saveDot) { saveDot.className = 'editor-save-dot ok'; }
|
||||
if (saveLabel) saveLabel.textContent = 'Saved';
|
||||
}
|
||||
|
||||
if (silent) {
|
||||
// Auto-save: brief green flash on save button
|
||||
@@ -921,7 +940,8 @@ function initEditor() {
|
||||
// visible right away and never overwritten by the editor's autosave.
|
||||
window.addEventListener("obsigate:file-written", (e) => {
|
||||
const detail = (e && e.detail) || {};
|
||||
reloadExternalWrite(detail.vault, detail.path);
|
||||
// force: the assistant's write must win over the stale local buffer.
|
||||
reloadExternalWrite(detail.vault, detail.path, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user