/* ═══════════════════════════════════════════════════════ LearnSpace — Mobile Drawer & Topbar Injected into all sidebar-layout pages ═══════════════════════════════════════════════════════ */ (function () { const MOBILE_BP = 768; function isMobile() { return window.innerWidth <= MOBILE_BP; } /* ── Inject mob-bar and backdrop ── */ function injectMobBar() { if (document.getElementById('ls-mob-bar')) return; const layout = document.querySelector('.app-layout'); if (!layout) return; /* Backdrop overlay */ const backdrop = document.createElement('div'); backdrop.className = 'sb-backdrop'; backdrop.id = 'ls-sb-backdrop'; document.body.appendChild(backdrop); /* Top bar */ const bar = document.createElement('div'); bar.className = 'mob-bar'; bar.id = 'ls-mob-bar'; bar.innerHTML = `
`; document.body.insertBefore(bar, document.body.firstChild); } /* ── Open / Close drawer ── */ function openDrawer() { const layout = document.querySelector('.app-layout'); const backdrop = document.getElementById('ls-sb-backdrop'); if (!layout) return; layout.classList.add('sb-open'); if (backdrop) backdrop.classList.add('open'); document.body.style.overflow = 'hidden'; } function closeDrawer() { const layout = document.querySelector('.app-layout'); const backdrop = document.getElementById('ls-sb-backdrop'); if (!layout) return; layout.classList.remove('sb-open'); if (backdrop) backdrop.classList.remove('open'); document.body.style.overflow = ''; } /* ── Wire up events ── */ function wireEvents() { /* Hamburger */ document.addEventListener('click', function (e) { if (e.target.closest('#mob-hamburger')) { const layout = document.querySelector('.app-layout'); if (layout && layout.classList.contains('sb-open')) { closeDrawer(); } else { openDrawer(); } return; } /* Backdrop tap */ if (e.target.id === 'ls-sb-backdrop') { closeDrawer(); return; } /* Sidebar nav link tap — close drawer */ if (isMobile() && e.target.closest('.sb-link')) { setTimeout(closeDrawer, 80); return; } /* Mob notif button — delegate to LS.notif.toggle or legacy toggleNotifDrop */ if (e.target.closest('#mob-notif-btn')) { if (typeof LS !== 'undefined' && LS.notif && LS.notif.toggle) { LS.notif.toggle(); } else if (typeof toggleNotifDrop === 'function') { toggleNotifDrop(); } return; } }); /* Escape key */ document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeDrawer(); }); /* Close drawer on resize to desktop */ window.addEventListener('resize', function () { if (!isMobile()) closeDrawer(); }); /* Close drawer on orientation change */ window.addEventListener('orientationchange', function () { setTimeout(function () { if (!isMobile()) closeDrawer(); }, 150); }); } /* ── Sync mob notif button visibility with page's notif button ── */ function syncNotifBtn() { const mobBtn = document.getElementById('mob-notif-btn'); if (!mobBtn) return; /* Look for existing notif button in sidebar */ const sbNotif = document.querySelector('.sb-link[onclick*="Notif"], .sb-link[onclick*="notif"], #notif-btn, [data-notif]'); if (sbNotif) { mobBtn.style.display = 'flex'; /* Mirror badge count */ const badge = sbNotif.querySelector('.sb-badge'); const dot = document.getElementById('mob-notif-dot'); if (badge && dot) { const observer = new MutationObserver(function () { dot.style.display = (badge.textContent.trim() !== '0' && badge.style.display !== 'none') ? 'block' : 'none'; }); observer.observe(badge, { childList: true, attributes: true, attributeFilter: ['style'] }); } } } /* ── Init ── */ function init() { if (window._lsMobileInited) return; window._lsMobileInited = true; injectMobBar(); wireEvents(); /* Defer notif sync until page JS has run */ setTimeout(syncNotifBtn, 600); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();