fix: hover preview flashing — skip grid/sidebar re-render while preview active
Poll cycle rebuilds innerHTML every ~2s, destroying the hovered tile's DOM element and tile--previewing class. Fix: renderGrid() and renderSidebar() early-return when _previewPopover is non-null. On hidePreview(), a catch-up render fires so no data is stale.
This commit is contained in:
@@ -353,6 +353,7 @@ function buildSidebarHTML(session, currentSession) {
|
|||||||
*/
|
*/
|
||||||
function renderSidebar(sessions, currentSession) {
|
function renderSidebar(sessions, currentSession) {
|
||||||
if (_viewMode !== 'fullscreen') return;
|
if (_viewMode !== 'fullscreen') return;
|
||||||
|
if (_previewPopover) return; // skip re-render while hover preview is active
|
||||||
|
|
||||||
const list = $('sidebar-list');
|
const list = $('sidebar-list');
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
@@ -482,6 +483,8 @@ function bindSidebarClickAway() {
|
|||||||
* @param {object[]} sessions
|
* @param {object[]} sessions
|
||||||
*/
|
*/
|
||||||
function renderGrid(sessions) {
|
function renderGrid(sessions) {
|
||||||
|
if (_previewPopover) return; // skip re-render while hover preview is active
|
||||||
|
|
||||||
const grid = $('session-grid');
|
const grid = $('session-grid');
|
||||||
const emptyState = $('empty-state');
|
const emptyState = $('empty-state');
|
||||||
|
|
||||||
@@ -612,6 +615,11 @@ function hidePreview() {
|
|||||||
_previewEl.classList.remove('tile--previewing', 'item--previewing');
|
_previewEl.classList.remove('tile--previewing', 'item--previewing');
|
||||||
_previewEl = null;
|
_previewEl = null;
|
||||||
}
|
}
|
||||||
|
// Catch-up render after preview is dismissed — apply any data missed while paused
|
||||||
|
if (_currentSessions) {
|
||||||
|
renderGrid(_currentSessions);
|
||||||
|
renderSidebar(_currentSessions, _viewingSession);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Notification permission ────────────────────────────────────────────────
|
// ─── Notification permission ────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -2091,4 +2091,22 @@ test('hover preview delay is 1500ms (not 350ms)', () => {
|
|||||||
assert.ok(!source.includes(', 350)'), 'old 350ms delay must be removed');
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user