diff --git a/solixauto/monitor.py b/solixauto/monitor.py index f77fd00..2073411 100644 --- a/solixauto/monitor.py +++ b/solixauto/monitor.py @@ -795,6 +795,37 @@ PAGE = """ .theme button:focus-visible { outline: 2px solid var(--solar); outline-offset: 1px; } + .fit-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 26px; + height: 26px; + margin-left: 14px; + padding: 0; + font-size: 14px; + line-height: 1; + border: 1px solid var(--rule); + background: transparent; + color: var(--ink-soft); + cursor: pointer; + vertical-align: middle; + } + + .fit-btn:hover { color: var(--ink); } + + .fit-btn[aria-pressed="true"] { + background: var(--ink); + color: var(--panel-raised); + } + + [data-theme="dark"] .fit-btn[aria-pressed="true"] { + background: var(--solar); + color: var(--panel); + } + + .fit-btn:focus-visible { outline: 2px solid var(--solar); outline-offset: 1px; } + table { width: 100%; border-collapse: collapse; } th { @@ -1039,6 +1070,8 @@ PAGE = """ + @@ -1727,6 +1760,7 @@ function togglePanel(key) { if (!collapsed[key] && key === 'history') { drawChart(currentHistory.points, currentHistory.serial); } + refitIfEnabled(); } function setCount(key, text) { @@ -1749,6 +1783,34 @@ function applyTheme(mode) { renderGridUsage(currentHistory.grid); } +let fitToScreen = false; + +function computeFitScale() { + const previousZoom = document.documentElement.style.zoom; + document.documentElement.style.zoom = ''; + const naturalHeight = document.documentElement.scrollHeight; + document.documentElement.style.zoom = previousZoom; + if (!naturalHeight) return 1; + return Math.min(1, window.innerHeight / naturalHeight); +} + +function refitIfEnabled() { + if (!fitToScreen) return; + document.documentElement.style.zoom = computeFitScale(); +} + +function applyFitToScreen(enabled) { + fitToScreen = enabled; + const btn = document.getElementById('fitBtn'); + if (btn) btn.setAttribute('aria-pressed', enabled ? 'true' : 'false'); + try { localStorage.setItem('solixauto-fit', enabled ? '1' : '0'); } catch (e) {} + if (enabled) { + refitIfEnabled(); + } else { + document.documentElement.style.zoom = ''; + } +} + function applyClockFormat(is12Hour) { use12Hour = is12Hour; document.getElementById('clock12Btn').setAttribute('aria-pressed', is12Hour); @@ -1758,6 +1820,7 @@ function applyClockFormat(is12Hour) { renderEvents(latest.events, latest.multi); } if (!collapsed.history) drawChart(currentHistory.points, currentHistory.serial); + refitIfEnabled(); } const stored = (() => { @@ -1773,10 +1836,17 @@ const storedClock12 = (() => { applyClockFormat(storedClock12 === '1'); +const storedFit = (() => { + try { return localStorage.getItem('solixauto-fit'); } catch (e) { return null; } +})(); + +applyFitToScreen(storedFit === '1'); + document.getElementById('lightBtn').addEventListener('click', () => applyTheme('light')); document.getElementById('darkBtn').addEventListener('click', () => applyTheme('dark')); document.getElementById('clock12Btn').addEventListener('click', () => applyClockFormat(true)); document.getElementById('clock24Btn').addEventListener('click', () => applyClockFormat(false)); +document.getElementById('fitBtn').addEventListener('click', () => applyFitToScreen(!fitToScreen)); let failures = 0; @@ -1805,6 +1875,7 @@ async function refresh() { ? data.shelly.length + ', ' + on + ' on' : 'none'); setCount('actions', (data.events || []).length ? (data.events || []).length + ' logged' : 'none yet'); + refitIfEnabled(); } catch (err) { failures++; document.getElementById('dot').className = 'dot stale'; @@ -1874,6 +1945,7 @@ async function loadHistory(win) { drawChart(currentHistory.points, currentHistory.serial); } renderGridUsage(currentHistory.grid); + refitIfEnabled(); } document.getElementById('window1d').addEventListener('click', () => loadHistory('1d'));