From 2ff7cbd75195345eb719d75536a49d33f0dc9279 Mon Sep 17 00:00:00 2001 From: Sepehr Date: Fri, 24 Apr 2026 17:05:00 -0400 Subject: [PATCH] fix: use matchMedia for mobile nav to fix background restore bug window.innerWidth can briefly report the desktop viewport width when the page is restored from a long Android background session, causing openChat() to skip adding chat-open even though chatIsOpen is true. Replace all window.innerWidth checks with mobileQuery.matches so the JS breakpoint always agrees with CSS. Also swap the resize listener for mobileQuery.addEventListener('change') which only fires when the breakpoint actually crosses, and add a visibilitychange handler to re-apply chat-open when the app returns to the foreground. --- internal/web/static/index.html | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/internal/web/static/index.html b/internal/web/static/index.html index 9cee8ff..e015af3 100644 --- a/internal/web/static/index.html +++ b/internal/web/static/index.html @@ -2397,10 +2397,11 @@ var refreshingChannels = {}; // tracks channels with an in-flight refresh // ===== MOBILE NAV ===== + var mobileQuery = window.matchMedia('(max-width: 768px)'); var chatIsOpen = false; function openChat() { chatIsOpen = true; - if (window.innerWidth <= 768) { + if (mobileQuery.matches) { document.getElementById('app').classList.add('chat-open'); history.pushState({ view: 'chat' }, ''); } @@ -2410,10 +2411,15 @@ document.getElementById('app').classList.remove('chat-open'); } window.addEventListener('popstate', function () { - if (window.innerWidth <= 768 && document.getElementById('app').classList.contains('chat-open')) { + if (mobileQuery.matches && document.getElementById('app').classList.contains('chat-open')) { openSidebar(); } }); + document.addEventListener('visibilitychange', function () { + if (!document.hidden && mobileQuery.matches && chatIsOpen) { + document.getElementById('app').classList.add('chat-open'); + } + }); function filterChannels() { var q = document.getElementById('channelSearch').value.toLowerCase(); document.querySelectorAll('.ch-item').forEach(function (el) { el.style.display = el.dataset.name.toLowerCase().includes(q) ? 'flex' : 'none' }); @@ -3593,7 +3599,7 @@ document.getElementById('progressPanel').innerHTML = ''; var p = document.getElementById('progressPanel'); p.innerHTML = '
' + t('loading') + '
'; - if (window.innerWidth <= 768) { openChat(); openLog(); } + if (mobileQuery.matches) { openChat(); openLog(); } } function startAutoRefresh() { if (autoRefreshTimer) return; autoRefreshTimer = setInterval(function () { if (selectedChannel > 0) doRefresh(true) }, 600000) } function updateNextFetchDisplay() { @@ -4471,9 +4477,9 @@ if (e.key === 'Enter' && document.activeElement === document.getElementById('msgSearchInput')) { e.preventDefault(); msgSearchNext() } if (e.key === 'Escape') { closeSettings(); closeProfiles(); closeProfileEditor(); closeScanner(); closeMsgSearch(); closeExportModal(); closeResolversModal() } }); - window.addEventListener('resize', function () { + mobileQuery.addEventListener('change', function () { var app = document.getElementById('app'); - if (window.innerWidth > 768) { + if (!mobileQuery.matches) { app.classList.remove('chat-open'); } else if (chatIsOpen) { app.classList.add('chat-open');