diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js index b79e3a8..9f81116 100644 --- a/muxplex/frontend/app.js +++ b/muxplex/frontend/app.js @@ -353,6 +353,7 @@ function buildSidebarHTML(session, currentSession) { */ function renderSidebar(sessions, currentSession) { if (_viewMode !== 'fullscreen') return; + if (_previewPopover) return; // skip re-render while hover preview is active const list = $('sidebar-list'); if (!list) return; @@ -482,6 +483,8 @@ function bindSidebarClickAway() { * @param {object[]} sessions */ function renderGrid(sessions) { + if (_previewPopover) return; // skip re-render while hover preview is active + const grid = $('session-grid'); const emptyState = $('empty-state'); @@ -612,6 +615,11 @@ function hidePreview() { _previewEl.classList.remove('tile--previewing', 'item--previewing'); _previewEl = null; } + // Catch-up render after preview is dismissed — apply any data missed while paused + if (_currentSessions) { + renderGrid(_currentSessions); + renderSidebar(_currentSessions, _viewingSession); + } } // ─── Notification permission ──────────────────────────────────────────────── diff --git a/muxplex/frontend/tests/test_app.mjs b/muxplex/frontend/tests/test_app.mjs index d4b1c0c..6ef63c9 100644 --- a/muxplex/frontend/tests/test_app.mjs +++ b/muxplex/frontend/tests/test_app.mjs @@ -2091,4 +2091,22 @@ test('hover preview delay is 1500ms (not 350ms)', () => { assert.ok(!source.includes(', 350)'), 'old 350ms delay must be removed'); }); +test('renderGrid and renderSidebar skip re-render while preview is active', () => { + const source = fs.readFileSync( + new URL('../app.js', import.meta.url), 'utf8' + ); + + // Find renderGrid function body + const gridFnStart = source.indexOf('function renderGrid'); + const gridFnBody = source.substring(gridFnStart, gridFnStart + 500); + assert.ok(gridFnBody.includes('_previewPopover'), + 'renderGrid must check _previewPopover and skip while active'); + + // Find renderSidebar function body + const sidebarFnStart = source.indexOf('function renderSidebar'); + const sidebarFnBody = source.substring(sidebarFnStart, sidebarFnStart + 500); + assert.ok(sidebarFnBody.includes('_previewPopover'), + 'renderSidebar must check _previewPopover and skip while active'); +}); +