diff --git a/internal/glance/static/css/site.css b/internal/glance/static/css/site.css index fbf3c8ad..f34b1c67 100644 --- a/internal/glance/static/css/site.css +++ b/internal/glance/static/css/site.css @@ -316,17 +316,38 @@ kbd:active { color: var(--color-text-highlight); } -.logout-button { +.logout-button, .refresh-icon svg, .auto-refresh-toggle svg { width: 2rem; height: 2rem; stroke: var(--color-text-subdue); transition: stroke .2s; + cursor: pointer; } -.logout-button:hover, .logout-button:focus { +.logout-button:hover, .logout-button:focus, +.refresh-icon:hover svg, .refresh-icon:focus svg, +.auto-refresh-toggle:hover svg, .auto-refresh-toggle:focus svg { stroke: var(--color-text-highlight); } + .auto-refresh-toggle { + display: flex; + align-items: center; + gap: 0.5rem; + } + +.refresh-button { + stroke: var(--color-text-subdue); + transition: stroke .2s; +} + +.refresh-panel { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; +} + .theme-choices { --presets-per-row: 2; display: grid; @@ -393,6 +414,7 @@ kbd:active { transition: opacity .3s; } -.theme-picker.popover-active .current-theme-preview, .theme-picker:hover { +.theme-picker.popover-active .current-theme-preview, .theme-picker:hover, +.refresh-container, .refresh-container:hover, .refresh-container.popover-active { opacity: 1; } diff --git a/internal/glance/static/css/utils.css b/internal/glance/static/css/utils.css index 3bbb48cd..92b7a011 100644 --- a/internal/glance/static/css/utils.css +++ b/internal/glance/static/css/utils.css @@ -565,6 +565,7 @@ details[open] .summary::after { .inline-block { display: inline-block; } .overflow-hidden { overflow: hidden; } .relative { position: relative; } +.display-none { display: none !important; } .flex { display: flex; } .flex-1 { flex: 1; } .flex-wrap { flex-wrap: wrap; } diff --git a/internal/glance/static/js/page.js b/internal/glance/static/js/page.js index 0212a4fa..ea66c6ff 100644 --- a/internal/glance/static/js/page.js +++ b/internal/glance/static/js/page.js @@ -743,8 +743,71 @@ function initThemePicker() { }) } +function initRefreshControls() { + const refreshButton = find(".refresh-button"); + if (!refreshButton) return; + + refreshButton.addEventListener("click", () => { + setupPage(); + }); + + const autoRefreshToggleOn = find(".refresh-button-on"); + const autoRefreshToggleOff = find(".refresh-button-off"); + + const localStorageKey = "auto-refresh-interval-id"; + + const loadOrSaveIntervalId = (intervalId) => { + if(intervalId) window.localStorage.setItem(localStorageKey, intervalId); + else return window.localStorage.getItem(localStorageKey); + } + + const toggleAutoRefreshUI = (autoRefreshOn) => { + if (autoRefreshOn) { + autoRefreshToggleOn.classList.remove("display-none"); + autoRefreshToggleOff.classList.add("display-none"); + } else { + autoRefreshToggleOn.classList.add("display-none"); + autoRefreshToggleOff.classList.remove("display-none"); + } + } + + const startAutoRefresh = () => { + //Remove any previous interval + stopAutoRefresh(); + + toggleAutoRefreshUI(true); + + const intervalId = setInterval(() => { + setupPage(); + }, 1000 * 60 * 3); + loadOrSaveIntervalId(intervalId); + }; + + const stopAutoRefresh = () => { + toggleAutoRefreshUI(false); + + const intervalId = loadOrSaveIntervalId(); + + if (intervalId) { + clearInterval(intervalId); + window.localStorage.removeItem(localStorageKey); + } + }; + + autoRefreshToggleOn.addEventListener("click", () => { + stopAutoRefresh(); + }); + + autoRefreshToggleOff.addEventListener("click", () => { + startAutoRefresh(); + }); + + toggleAutoRefreshUI(!!loadOrSaveIntervalId()); +} + async function setupPage() { initThemePicker(); + initRefreshControls(); const pageElement = document.getElementById("page"); const pageContentElement = document.getElementById("page-content"); diff --git a/internal/glance/templates/page.html b/internal/glance/templates/page.html index 0f831830..ce18a79a 100644 --- a/internal/glance/templates/page.html +++ b/internal/glance/templates/page.html @@ -43,6 +43,28 @@ {{ end }} +
+
+ + + +
+
+ +
+
{{- if .App.RequiresAuth }}