diff --git a/app/static/css/style.css b/app/static/css/style.css index a792efb..6f8f53d 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -130,14 +130,12 @@ main { flex-shrink: 0; } -/* Show sidebar and hide dropdown on wide screens */ -@media (min-width: 992px) { - .channel-sidebar { - display: flex; - } - #channelSelectorWrapper { - display: none !important; - } +/* Show sidebar and hide dropdown on wide screens (toggled by JS via .layout-wide on ) */ +.layout-wide .channel-sidebar { + display: flex; +} +.layout-wide #channelSelectorWrapper { + display: none !important; } /* Channel Selector Dropdown (base.html navbar, narrow screens) */ @@ -266,17 +264,15 @@ main { flex-shrink: 0; } -/* Show DM sidebar and hide mobile selector on wide screens */ -@media (min-width: 992px) { - .dm-sidebar { - display: flex; - } - .dm-mobile-selector { - display: none !important; - } - .dm-desktop-header { - display: block !important; - } +/* Show DM sidebar and hide mobile selector on wide screens (toggled by JS via .layout-wide on ) */ +.layout-wide .dm-sidebar { + display: flex; +} +.layout-wide .dm-mobile-selector { + display: none !important; +} +.layout-wide .dm-desktop-header { + display: block !important; } .dm-desktop-header { diff --git a/app/static/js/app.js b/app/static/js/app.js index 7c1e14b..1c1df54 100644 --- a/app/static/js/app.js +++ b/app/static/js/app.js @@ -558,6 +558,10 @@ document.addEventListener('DOMContentLoaded', async function() { applyItemPlacements(); initializeItemPlacementSettings(); + // Sidebar breakpoint: re-apply (covers no-localStorage case) and wire up settings UI + resize listener + applySidebarBreakpoint(); + initializeSidebarBreakpointSettings(); + // Initialize FAB toggle initializeFabToggle(); @@ -5382,6 +5386,70 @@ function initializeFabToggle() { }); } +// ============================================================================= +// Sidebar breakpoint (channel/DM list as sidebar vs. dropdown) +// ============================================================================= + +const SIDEBAR_BREAKPOINT_DEFAULT = 992; +const SIDEBAR_BREAKPOINT_MIN = 600; +const SIDEBAR_BREAKPOINT_MAX = 2000; +const SIDEBAR_BREAKPOINT_KEY = 'mc-webui-sidebar-breakpoint'; + +function readSidebarBreakpoint() { + const stored = parseInt(localStorage.getItem(SIDEBAR_BREAKPOINT_KEY), 10); + if (isNaN(stored) || stored < SIDEBAR_BREAKPOINT_MIN || stored > SIDEBAR_BREAKPOINT_MAX) { + return SIDEBAR_BREAKPOINT_DEFAULT; + } + return stored; +} + +function applySidebarBreakpoint() { + const bp = readSidebarBreakpoint(); + document.documentElement.classList.toggle('layout-wide', window.innerWidth >= bp); +} + +let _sidebarBreakpointRaf = null; +function onSidebarBreakpointResize() { + if (_sidebarBreakpointRaf) return; + _sidebarBreakpointRaf = requestAnimationFrame(() => { + _sidebarBreakpointRaf = null; + applySidebarBreakpoint(); + }); +} + +function syncSidebarBreakpointUI() { + const input = document.getElementById('settSidebarBreakpoint'); + if (input) input.value = readSidebarBreakpoint(); +} + +function initializeSidebarBreakpointSettings() { + window.addEventListener('resize', onSidebarBreakpointResize); + + const input = document.getElementById('settSidebarBreakpoint'); + if (input) { + input.addEventListener('input', () => { + const val = parseInt(input.value, 10); + if (isNaN(val) || val < SIDEBAR_BREAKPOINT_MIN || val > SIDEBAR_BREAKPOINT_MAX) return; + localStorage.setItem(SIDEBAR_BREAKPOINT_KEY, String(val)); + applySidebarBreakpoint(); + }); + } + + const resetBtn = document.getElementById('settSidebarBreakpointReset'); + if (resetBtn) { + resetBtn.addEventListener('click', () => { + localStorage.removeItem(SIDEBAR_BREAKPOINT_KEY); + if (input) input.value = SIDEBAR_BREAKPOINT_DEFAULT; + applySidebarBreakpoint(); + }); + } + + const settingsModal = document.getElementById('settingsModal'); + if (settingsModal) { + settingsModal.addEventListener('show.bs.modal', syncSidebarBreakpointUI); + } +} + // ============================================================================= // Chat Filter Functionality // ============================================================================= diff --git a/app/templates/base.html b/app/templates/base.html index 20da22a..4a540b1 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -21,6 +21,19 @@ })(); + + + @@ -666,6 +679,22 @@
Window width above which the channel/contact list is shown as a sidebar. Below this width it collapses to a dropdown at the top of the screen. Saved per device (browser).
+| Sidebar breakpoint (px) | +
+
+
+
+
+ |
+