From be41d66de9356d9e31a90dff36339b6a4075fb54 Mon Sep 17 00:00:00 2001 From: Eddy G Date: Tue, 24 Jun 2025 22:30:16 -0400 Subject: [PATCH] Improve kiosk mode startup experience - Pass query parameters to EJS template for kiosk mode detection - Add kiosk class to body when enabled via query parameter - Simplify kiosk mode CSS to hide all elements except main weather display - Add null checks for progress object to prevent errors in kiosk mode - Prevent navigation errors when no suitable displays are available --- gulp/publish-frontend.mjs | 1 + index.mjs | 1 + server/scripts/modules/navigation.mjs | 114 +++++++++++++++----------- server/styles/scss/_page.scss | 22 ++--- views/index.ejs | 4 +- 5 files changed, 83 insertions(+), 59 deletions(-) diff --git a/gulp/publish-frontend.mjs b/gulp/publish-frontend.mjs index 5bd2b07..bdb418b 100644 --- a/gulp/publish-frontend.mjs +++ b/gulp/publish-frontend.mjs @@ -138,6 +138,7 @@ const compressHtml = async () => { production: version, version, OVERRIDES, + query: {}, })) .pipe(rename({ extname: '.html' })) .pipe(htmlmin({ collapseWhitespace: true })) diff --git a/index.mjs b/index.mjs index 39cb2b6..58be321 100644 --- a/index.mjs +++ b/index.mjs @@ -54,6 +54,7 @@ const index = (req, res) => { production: false, version, OVERRIDES, + query: req.query, }); }; diff --git a/server/scripts/modules/navigation.mjs b/server/scripts/modules/navigation.mjs index f252b5d..40e110e 100644 --- a/server/scripts/modules/navigation.mjs +++ b/server/scripts/modules/navigation.mjs @@ -36,57 +36,66 @@ const getWeather = async (latLon, haveDataCallback) => { if (typeof haveDataCallback === 'function') haveDataCallback(point); + try { // get stations const stations = await json(point.properties.observationStations); - const StationId = stations.features[0].properties.stationIdentifier; + const StationId = stations.features[0].properties.stationIdentifier; - let { city } = point.properties.relativeLocation.properties; - const { state } = point.properties.relativeLocation.properties; + let { city } = point.properties.relativeLocation.properties; + const { state } = point.properties.relativeLocation.properties; - if (StationId in StationInfo) { - city = StationInfo[StationId].city; - [city] = city.split('/'); - city = city.replace(/\s+$/, ''); + if (StationId in StationInfo) { + city = StationInfo[StationId].city; + [city] = city.split('/'); + city = city.replace(/\s+$/, ''); + } + + // populate the weather parameters + weatherParameters.latitude = latLon.lat; + weatherParameters.longitude = latLon.lon; + weatherParameters.zoneId = point.properties.forecastZone.substr(-6); + weatherParameters.radarId = point.properties.radarStation.substr(-3); + weatherParameters.stationId = StationId; + weatherParameters.weatherOffice = point.properties.cwa; + weatherParameters.city = city; + weatherParameters.state = state; + weatherParameters.timeZone = point.properties.timeZone; + weatherParameters.forecast = point.properties.forecast; + weatherParameters.forecastGridData = point.properties.forecastGridData; + weatherParameters.stations = stations.features; + + // update the main process for display purposes + populateWeatherParameters(weatherParameters); + + // reset the scroll + postMessage({ type: 'current-weather-scroll', method: 'reload' }); + + // draw the progress canvas and hide others + hideAllCanvases(); + if (!settings?.kiosk?.value) { + // In normal mode, hide loading screen and show progress + // (In kiosk mode, keep the loading screen visible until autoplay starts) + document.querySelector('#loading').style.display = 'none'; + if (progress) { + await progress.drawCanvas(); + progress.showCanvas(); + } + } + + // call for new data on each display + displays.forEach((display) => display.getData(weatherParameters)); + } catch (error) { + console.error(`Failed to get weather data: ${error.message}`); } - - // populate the weather parameters - weatherParameters.latitude = latLon.lat; - weatherParameters.longitude = latLon.lon; - weatherParameters.zoneId = point.properties.forecastZone.substr(-6); - weatherParameters.radarId = point.properties.radarStation.substr(-3); - weatherParameters.stationId = StationId; - weatherParameters.weatherOffice = point.properties.cwa; - weatherParameters.city = city; - weatherParameters.state = state; - weatherParameters.timeZone = point.properties.timeZone; - weatherParameters.forecast = point.properties.forecast; - weatherParameters.forecastGridData = point.properties.forecastGridData; - weatherParameters.stations = stations.features; - - // update the main process for display purposes - populateWeatherParameters(weatherParameters); - - // reset the scroll - postMessage({ type: 'current-weather-scroll', method: 'reload' }); - - // draw the progress canvas and hide others - hideAllCanvases(); - document.querySelector('#loading').style.display = 'none'; - if (progress) { - await progress.drawCanvas(); - progress.showCanvas(); - } - - // call for new data on each display - displays.forEach((display) => display.getData(weatherParameters)); }; // receive a status update from a module {id, value} const updateStatus = (value) => { if (value.id < 0) return; - if (!progress) return; - progress.drawCanvas(displays, countLoadedDisplays()); + if (!progress && !settings?.kiosk?.value) return; + + if (progress) progress.drawCanvas(displays, countLoadedDisplays()); // first display is hazards and it must load before evaluating the first display if (displays[0].status === STATUS.loading) return; @@ -153,7 +162,7 @@ const displayNavMessage = (myMessage) => { const navTo = (direction) => { // test for a current display const current = currentDisplay(); - progress.hideCanvas(); + if (progress) progress.hideCanvas(); if (!current) { // special case for no active displays (typically on progress screen) // find the first ready display @@ -166,6 +175,11 @@ const navTo = (direction) => { if (!firstDisplay) return; + // In kiosk mode, hide the loading screen when we start showing the first display + if (settings?.kiosk?.value) { + document.querySelector('#loading').style.display = 'none'; + } + firstDisplay.navNext(msg.command.firstFrame); firstDisplay.showCanvas(); return; @@ -183,7 +197,7 @@ const loadDisplay = (direction) => { // convert form simple 0-10 to start at current display index +/-1 and wrap idx = wrap(curIdx + (i + 1) * direction, totalDisplays); if (displays[idx].status === STATUS.loaded && displays[idx].timing.totalScreens > 0) break; - } + } const newDisplay = displays[idx]; // hide all displays hideAllCanvases(); @@ -210,9 +224,12 @@ const setPlaying = (newValue) => { playButton.title = 'Play'; playButton.src = 'images/nav/ic_play_arrow_white_24dp_2x.png'; } - // if we're playing and on the progress screen jump to the next screen - if (!progress) return; - if (playing && !currentDisplay()) navTo(msg.command.firstFrame); + // if we're playing and on the progress screen (or in kiosk mode), jump to the next screen + if (playing && !currentDisplay()) { + if (progress || settings?.kiosk?.value) { + navTo(msg.command.firstFrame); + } + } }; // handle all navigation buttons @@ -237,7 +254,12 @@ const handleNavButton = (button) => { break; case 'menu': setPlaying(false); - progress.showCanvas(); + if (progress) { + progress.showCanvas(); + } else if (settings?.kiosk?.value) { + // In kiosk mode without progress, show the loading screen + document.querySelector('#loading').style.display = 'flex'; + } hideAllCanvases(); break; default: diff --git a/server/styles/scss/_page.scss b/server/styles/scss/_page.scss index f6bf8af..806b171 100644 --- a/server/styles/scss/_page.scss +++ b/server/styles/scss/_page.scss @@ -1,5 +1,5 @@ -@use 'shared/_utils'as u; -@use 'shared/_colors'as c; +@use 'shared/_utils' as u; +@use 'shared/_colors' as c; @font-face { font-family: "Star4000"; @@ -768,15 +768,15 @@ body { display: none; } +// Hide instructions in kiosk mode (higher specificity than the show rule) +body.kiosk #loading .instructions { + display: none !important; +} + .kiosk { - #divQuery, - >.info, - >.related-links, - >.heading, - #enabledDisplays, - #settings, - #divInfo { - display: none; + // In kiosk mode, hide everything except the main weather display + >*:not(#divTwc) { + display: none !important; } -} \ No newline at end of file +} diff --git a/views/index.ejs b/views/index.ejs index 85f8f49..7fbc6f7 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -63,7 +63,7 @@ - + class="kiosk"<% } %>>
@@ -192,4 +192,4 @@ - \ No newline at end of file +