From e00642553f9ba691c174f3cacd8a84b77e111291 Mon Sep 17 00:00:00 2001 From: swpa Date: Thu, 28 May 2026 10:51:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=87=20startLockStatusPolling=20?= =?UTF-8?q?=E6=94=B9=E6=88=90=E7=89=B9=E5=8B=99=E6=A8=A1=E5=BC=8F(State=20?= =?UTF-8?q?Diffing),=20=E8=A7=A3=E6=B1=BA=E6=A8=B9=E7=8B=80=E5=9C=96?= =?UTF-8?q?=E7=80=8F=E8=A6=BD=E5=BB=B6=E9=81=B2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/app.js | 56 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/static/app.js b/static/app.js index 2bb5785..b067abe 100644 --- a/static/app.js +++ b/static/app.js @@ -102,6 +102,8 @@ window.addEventListener('beforeunload', () => { } }); +// 🌟 特務的記憶體:記錄「上一次輪詢時,處於鎖定狀態的路徑」 +let activeLockState = new Set(); let lockPollingTimer = null; function startLockStatusPolling() { @@ -114,24 +116,46 @@ function startLockStatusPolling() { try { const result = await apiGetLockStatus(connInfo.host); if (result.status === 'success') { - const activeLocks = result.data; - - document.querySelectorAll('.edit-btn').forEach(btn => { - const path = btn.getAttribute('data-path'); - if (activeLocks[path] && activeLocks[path].user_id !== SESSION_USER_ID) { - btn.style.pointerEvents = 'none'; - btn.style.opacity = '0.2'; - btn.title = `🔒 此區塊正由 [${activeLocks[path].username}] 編輯中`; - btn.innerText = "🔒"; - } else { - if (btn.innerText === "🔒") { - btn.style.pointerEvents = 'auto'; - btn.style.opacity = '0.3'; - btn.title = "鎖定並編輯此項目"; - btn.innerText = "✏️"; - } + const currentLocks = result.data; + const newLockState = new Set(); + + // 🎯 任務 1:處理「新增鎖定」或「持續鎖定」的節點 + for (const [path, lockInfo] of Object.entries(currentLocks)) { + if (lockInfo.user_id !== SESSION_USER_ID) { + newLockState.add(path); + const safePath = path.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); + const targetBtns = document.querySelectorAll(`.edit-btn[data-path="${safePath}"]`); + + targetBtns.forEach(btn => { + if (btn.innerText !== "🔒") { + btn.style.pointerEvents = 'none'; + btn.style.opacity = '0.2'; + btn.title = `🔒 此區塊正由 [${lockInfo.username}] 編輯中`; + btn.innerText = "🔒"; + } + }); + } + } + + // 🔓 任務 2:處理「解除鎖定」的節點 + activeLockState.forEach(oldPath => { + if (!newLockState.has(oldPath)) { + const safePath = oldPath.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); + const targetBtns = document.querySelectorAll(`.edit-btn[data-path="${safePath}"]`); + + targetBtns.forEach(btn => { + if (btn.innerText === "🔒") { + btn.style.pointerEvents = 'auto'; + btn.style.opacity = '0.3'; + btn.title = "鎖定並編輯此項目"; + btn.innerText = "✏️"; + } + }); } }); + + // 💾 任務 3:更新特務的記憶 + activeLockState = newLockState; } } catch (error) { console.warn("獲取鎖定狀態失敗:", error);