Compare commits

...

25 Commits

Author SHA1 Message Date
Matt Walsh
8a25881d5b 5.9.6 2023-01-05 14:19:43 -06:00
Matt Walsh
0743b9e2bb filter current conditions for missing icon or current conditions 2023-01-05 14:19:33 -06:00
Matt Walsh
784c074e32 capture dist 2022-12-22 14:48:05 -06:00
Matt Walsh
4840909098 5.9.5 2022-12-22 14:47:08 -06:00
Matt Walsh
03dfbc462b better latest observation get data routine 2022-12-22 14:46:58 -06:00
Matt Walsh
25291efff5 capture dist 2022-12-21 16:20:54 -06:00
Matt Walsh
dc77ba835c 5.9.4 2022-12-21 16:20:37 -06:00
Matt Walsh
a440990696 update top form html and css 2022-12-21 16:20:31 -06:00
Matt Walsh
fc4cbc1415 fix time zones close #21 2022-12-21 15:17:50 -06:00
Matt Walsh
20ba3ddaac capture dist 2022-12-21 14:52:03 -06:00
Matt Walsh
4205155f96 5.9.3 2022-12-21 14:51:04 -06:00
Matt Walsh
f4101f06cc fix hazards failed to load auto play issue 2022-12-21 14:50:56 -06:00
Matt Walsh
4c3fcfc358 correct hazard scroll time 2022-12-21 14:44:36 -06:00
Matt Walsh
366f527aee auto play when hazard is present 2022-12-21 14:05:14 -06:00
Matt Walsh
797b4d32fa capture dist 2022-12-19 15:24:34 -06:00
Matt Walsh
5092076050 5.9.2 2022-12-19 15:24:12 -06:00
Matt Walsh
5d891fb38f switch to 2x image sizes 2022-12-19 15:21:38 -06:00
Matt Walsh
97e0fda709 key navigation 2022-12-19 11:48:59 -06:00
Matt Walsh
7cf9dd6466 almanac delivers data when disabled 2022-12-19 11:27:02 -06:00
Matt Walsh
a44bd866ed regional forecast icon blizzard 2022-12-19 11:17:30 -06:00
Matt Walsh
21ef7f476a auto refresh fix 2022-12-19 11:15:48 -06:00
Matt Walsh
c5b715d631 checkbox label colors 2022-12-19 10:17:12 -06:00
Matt Walsh
dfd9facc79 Merge branch 'main' of github.com:netbymatt/ws4kp 2022-12-19 10:14:37 -06:00
Matt Walsh
5b926a358e no hazards, blizzard 2022-12-19 10:14:33 -06:00
Matt Walsh
ba1fbd7088 capture dist 2022-12-14 21:49:07 -06:00
23 changed files with 623 additions and 260 deletions

2
dist/index.html vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

498
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "ws4kp",
"version": "5.9.1",
"version": "5.9.6",
"description": "Welcome to the WeatherStar 4000+ project page!",
"main": "index.js",
"scripts": {

View File

@@ -44,10 +44,13 @@ const init = () => {
if (document.fullscreenElement) updateFullScreenNavigate();
});
document.getElementById('txtAddress').addEventListener('keydown', (key) => { if (key.code === 'Enter') formSubmit(); });
document.getElementById('btnGetLatLng').addEventListener('click', () => formSubmit());
document.addEventListener('keydown', documentKeydown);
document.addEventListener('touchmove', (e) => { if (fullScreenOverride) e.preventDefault(); });
$('#frmGetLatLng #txtAddress').devbridgeAutocomplete({
$('#txtAddress').devbridgeAutocomplete({
serviceUrl: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest',
deferRequestBy: 300,
paramName: 'text',
@@ -71,11 +74,11 @@ const init = () => {
width: 490,
});
$('#frmGetLatLng').on('submit', () => {
const ac = $('#frmGetLatLng #txtAddress').devbridgeAutocomplete();
const formSubmit = () => {
const ac = $('#txtAddress').devbridgeAutocomplete();
if (ac.suggestions[0]) $(ac.suggestionsContainer.children[0]).trigger('click');
return false;
});
};
// Auto load the previous query
const query = localStorage.getItem('latLonQuery');
@@ -187,7 +190,7 @@ const enterFullScreen = () => {
// change hover text and image
const img = document.getElementById('ToggleFullScreen');
img.src = 'images/nav/ic_fullscreen_exit_white_24dp_1x.png';
img.src = 'images/nav/ic_fullscreen_exit_white_24dp_2x.png';
img.title = 'Exit fullscreen';
};
@@ -211,7 +214,7 @@ const exitFullscreen = () => {
resize();
// change hover text and image
const img = document.getElementById('ToggleFullScreen');
img.src = 'images/nav/ic_fullscreen_white_24dp_1x.png';
img.src = 'images/nav/ic_fullscreen_white_24dp_2x.png';
img.title = 'Enter fullscreen';
};
@@ -290,37 +293,41 @@ const updateFullScreenNavigate = () => {
};
const documentKeydown = (e) => {
const code = (e.keyCode || e.which);
// 200ms repeat
if ((Date.now() - documentKeydown.lastButton ?? 0) < 200) return false;
documentKeydown.lastButton = Date.now();
const { key } = e;
if (document.fullscreenElement || document.activeElement === document.body) {
switch (code) {
case 32: // Space
switch (key) {
case ' ': // Space
// don't scroll
e.preventDefault();
btnNavigatePlayClick();
return false;
case 39: // Right Arrow
case 34: // Page Down
case 'ArrowRight':
case 'PageDown':
// don't scroll
e.preventDefault();
btnNavigateNextClick();
return false;
case 37: // Left Arrow
case 33: // Page Up
case 'ArrowLeft':
case 'PageUp':
// don't scroll
e.preventDefault();
btnNavigatePreviousClick();
return false;
case 36: // Home
case 'ArrowUp': // Home
e.preventDefault();
btnNavigateMenuClick();
return false;
case 48: // Restart
case '0': // "O" Restart
btnNavigateRefreshClick();
return false;
case 70: // F
case 'F':
case 'f':
btnFullScreenClick();
return false;
@@ -368,7 +375,6 @@ const btnGetGpsClick = async () => {
txtAddress.value = `${round2(latitude, 4)}, ${round2(longitude, 4)}`;
doRedirectToGeometry({ y: latitude, x: longitude }, (point) => {
console.log(point);
const location = point.properties.relativeLocation.properties;
// Save the query
const query = `${location.city}, ${location.state}`;

View File

@@ -22,7 +22,7 @@ class Almanac extends WeatherDisplay {
}
async getData(_weatherParameters) {
if (!super.getData(_weatherParameters)) return;
const superResponse = super.getData(_weatherParameters);
const weatherParameters = _weatherParameters ?? this.weatherParameters;
// get sun/moon data
@@ -33,11 +33,13 @@ class Almanac extends WeatherDisplay {
sun,
moon,
};
// update status
this.setStatus(STATUS.loaded);
// share data
this.getDataCallback();
if (!superResponse) return;
// update status
this.setStatus(STATUS.loaded);
}
calcSunMoonData(weatherParameters) {

View File

@@ -53,7 +53,9 @@ class CurrentWeather extends WeatherDisplay {
// test data quality
if (observations.features[0].properties.temperature.value === null
|| observations.features[0].properties.windSpeed.value === null
|| observations.features[0].properties.textDescription === null) {
|| observations.features[0].properties.textDescription === null
|| observations.features[0].properties.textDescription === ''
|| observations.features[0].properties.icon === null) {
observations = undefined;
throw new Error(`Unable to get observations: ${station.properties.stationIdentifier}, trying next station`);
}

View File

@@ -43,7 +43,7 @@ const incrementInterval = () => {
const drawScreen = async () => {
// get the conditions
const data = await getCurrentWeather(() => this.stillWaiting());
const data = await getCurrentWeather();
// nothing to do if there's no data yet
if (!data) return;

View File

@@ -51,7 +51,10 @@ class Hazards extends WeatherDisplay {
this.getDataCallback();
if (!superResult) return;
if (!superResult) {
this.setStatus(STATUS.loaded);
return;
}
this.drawLongCanvas();
}
@@ -72,6 +75,7 @@ class Hazards extends WeatherDisplay {
// no alerts, skip this display by setting timing to zero
if (lines.length === 0) {
this.setStatus(STATUS.loaded);
this.timing.totalScreens = 0;
this.setStatus(STATUS.loaded);
return;
@@ -81,13 +85,13 @@ class Hazards extends WeatherDisplay {
// set up the timing
this.timing.baseDelay = 20;
// 24 hours = 6 pages
const pages = Math.ceil(list.scrollHeight / 390); // first page is already displayed, last page doesn't happen
const timingStep = 75 * 4;
const pages = Math.max(Math.ceil(list.scrollHeight / 400) - 3, 1);
const timingStep = 400;
this.timing.delay = [150 + timingStep];
// add additional pages
for (let i = 0; i < pages; i += 1) this.timing.delay.push(timingStep);
// add the final 3 second delay
this.timing.delay.push(150);
this.timing.delay.push(250);
this.calcNavTiming();
this.setStatus(STATUS.loaded);
}

View File

@@ -87,6 +87,7 @@ const getWeatherRegionalIconFromIconLink = (link, _isNightTime) => {
return addPath('Light-Snow.gif');
case 'rain_snow':
case 'rain_snow-n':
return addPath('Rain-Snow-1992.gif');
case 'snow_fzra':
@@ -133,6 +134,7 @@ const getWeatherRegionalIconFromIconLink = (link, _isNightTime) => {
return addPath('Clear-Wind-1994.gif');
case 'blizzard':
case 'blizzard-n':
return addPath('Blowing Snow.gif');
case 'cold':
@@ -268,6 +270,7 @@ const getWeatherIconFromIconLink = (link, _isNightTime) => {
return addPath('CC_Windy.gif');
case 'blizzard':
case 'blizzard-n':
return addPath('Blowing-Snow.gif');
default:

View File

@@ -32,26 +32,20 @@ class LatestObservations extends WeatherDisplay {
const regionalStations = sortedStations.slice(0, 30);
// get data for regional stations
const allConditions = await Promise.all(regionalStations.map(async (station) => {
try {
const data = await json(`https://api.weather.gov/stations/${station.id}/observations/latest`, { retryCount: 3, stillWaiting: () => this.stillWaiting() });
// test for temperature, weather and wind values present
if (data.properties.temperature.value === null
|| data.properties.textDescription === ''
|| data.properties.windSpeed.value === null) return false;
// format the return values
return {
...data.properties,
StationId: station.id,
city: station.city,
};
} catch (e) {
console.log(`Unable to get latest observations for ${station.id}`);
return false;
}
}));
// remove and stations that did not return data
const actualConditions = allConditions.filter((condition) => condition);
// get first 7 stations
const actualConditions = [];
let lastStation = Math.min(regionalStations.length, 7);
let firstStation = 0;
while (actualConditions.length < 7 && (lastStation) <= regionalStations.length) {
// eslint-disable-next-line no-await-in-loop
const someStations = await getStations(regionalStations.slice(firstStation, lastStation));
actualConditions.push(...someStations);
// update counters
firstStation += lastStation;
lastStation = Math.min(regionalStations.length + 1, firstStation + 7 - actualConditions.length);
}
// cut down to the maximum of 7
this.data = actualConditions.slice(0, this.MaximumRegionalStations);
@@ -119,5 +113,28 @@ const shortenCurrentConditions = (_condition) => {
condition = condition.replace(/ with /, '/');
return condition;
};
const getStations = async (stations) => {
const stationData = await Promise.all(stations.map(async (station) => {
try {
const data = await json(`https://api.weather.gov/stations/${station.id}/observations/latest`, { retryCount: 1, stillWaiting: () => this.stillWaiting() });
// test for temperature, weather and wind values present
if (data.properties.temperature.value === null
|| data.properties.textDescription === ''
|| data.properties.windSpeed.value === null) return false;
// format the return values
return {
...data.properties,
StationId: station.id,
city: station.city,
};
} catch (e) {
console.log(`Unable to get latest observations for ${station.id}`);
return false;
}
}));
// filter false (no data or other error)
return stationData.filter((d) => d);
};
// register display
registerDisplay(new LatestObservations(2, 'latest-observations'));

View File

@@ -77,7 +77,7 @@ const getWeather = async (latLon, haveDataCallback) => {
weatherParameters.weatherOffice = point.properties.cwa;
weatherParameters.city = city;
weatherParameters.state = point.properties.relativeLocation.properties.state;
weatherParameters.timeZone = point.properties.relativeLocation.properties.timeZone;
weatherParameters.timeZone = point.properties.timeZone;
weatherParameters.forecast = point.properties.forecast;
weatherParameters.forecastGridData = point.properties.forecastGridData;
weatherParameters.stations = stations.features;
@@ -109,6 +109,13 @@ const updateStatus = (value) => {
// calculate first enabled display
const firstDisplayIndex = displays.findIndex((display) => display.enabled && display.timing.totalScreens > 0);
// value.id = 0 is hazards, if they fail to load hot-wire a new value.id to the current display to see if it needs to be loaded
// typically this plays out as current conditions loads, then hazards fails.
if (value.id === 0 && (value.status === STATUS.failed || value.status === STATUS.retrying)) {
value.id = firstDisplayIndex;
value.status = displays[firstDisplayIndex].status;
}
// if this is the first display and we're playing, load it up so it starts playing
if (isPlaying() && value.id === firstDisplayIndex && value.status === STATUS.loaded) {
navTo(msg.command.firstFrame);
@@ -175,6 +182,7 @@ const navTo = (direction) => {
if (!firstDisplay) return;
firstDisplay.navNext(msg.command.firstFrame);
firstDisplay.showCanvas();
return;
}
if (direction === msg.command.nextFrame) currentDisplay().navNext();
@@ -218,11 +226,11 @@ const setPlaying = (newValue) => {
if (playing) {
noSleep(true);
playButton.title = 'Pause';
playButton.src = 'images/nav/ic_pause_white_24dp_1x.png';
playButton.src = 'images/nav/ic_pause_white_24dp_2x.png';
} else {
noSleep(false);
playButton.title = 'Play';
playButton.src = 'images/nav/ic_play_arrow_white_24dp_1x.png';
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;
@@ -377,7 +385,7 @@ const stopAutoRefreshTimer = () => {
const refreshCheck = () => {
// Time has elapsed.
if (AutoRefreshCountMs >= AUTO_REFRESH_TIME_MS) {
if (AutoRefreshCountMs >= AUTO_REFRESH_TIME_MS && isPlaying()) {
loadTwcData();
return true;
}
@@ -392,6 +400,8 @@ const registerRefreshData = (callback) => {
loadTwcData.callback = callback;
};
const timeZone = () => weatherParameters.timeZone;
export {
updateStatus,
displayNavMessage,
@@ -407,4 +417,5 @@ export {
latLonReceived,
stopAutoRefreshTimer,
registerRefreshData,
timeZone,
};

View File

@@ -5,7 +5,7 @@ import { loadImg } from './utils/image.mjs';
import { text } from './utils/fetch.mjs';
import { rewriteUrl } from './utils/cors.mjs';
import WeatherDisplay from './weatherdisplay.mjs';
import { registerDisplay } from './navigation.mjs';
import { registerDisplay, timeZone } from './navigation.mjs';
import * as utils from './radar-utils.mjs';
class Radar extends WeatherDisplay {
@@ -159,7 +159,7 @@ class Radar extends WeatherDisplay {
zone: 'UTC',
}).setZone();
} else {
time = DateTime.fromHTTP(response.headers.get('last-modified')).setZone();
time = DateTime.fromHTTP(response.headers.get('last-modified')).setZone(timeZone());
}
// assign to an html image element

View File

@@ -23,7 +23,9 @@ const getRegionalObservation = async (point, city) => {
const observation = await json(`${station}/observations/latest`);
// preload the image
if (!observation.properties.icon) return false;
preloadImg(getWeatherRegionalIconFromIconLink(observation.properties.icon, !observation.properties.daytime));
const icon = getWeatherRegionalIconFromIconLink(observation.properties.icon, !observation.properties.daytime);
if (!icon) return false;
preloadImg(icon);
// return the observation
return observation.properties;
} catch (e) {

View File

@@ -87,6 +87,9 @@ class RegionalForecast extends WeatherDisplay {
// wait for the regional observation if it's not done yet
const observation = await observationPromise;
if (!observation) return false;
// format the observation the same as the forecast
const regionalObservation = {
daytime: !!observation.icon.match(/\/day\//),

View File

@@ -2,9 +2,8 @@
import STATUS, { calcStatusClass, statusClasses } from './status.mjs';
import { DateTime } from '../vendor/auto/luxon.mjs';
import { elemForEach } from './utils/elem.mjs';
import {
msg, displayNavMessage, isPlaying, updateStatus,
msg, displayNavMessage, isPlaying, updateStatus, timeZone,
} from './navigation.mjs';
class WeatherDisplay {
@@ -173,20 +172,22 @@ class WeatherDisplay {
// only draw if canvas is active to conserve battery
if (!this.active) return;
// Get the current date and time.
const now = DateTime.local();
const now = DateTime.local().setZone(timeZone());
// time = "11:35:08 PM";
const time = now.toLocaleString(DateTime.TIME_WITH_SECONDS).padStart(11, ' ');
const date = now.toFormat(' ccc LLL ') + now.day.toString().padStart(2, ' ');
if (this.lastTime !== time) {
elemForEach('.date-time.time', (elem) => { elem.innerHTML = time.toUpperCase(); });
const dateElem = this.elem.querySelector('.date-time.date');
const timeElem = this.elem.querySelector('.date-time.time');
if (timeElem && this.lastTime !== time) {
timeElem.innerHTML = time.toUpperCase();
}
this.lastTime = time;
const date = now.toFormat(' ccc LLL ') + now.day.toString().padStart(2, ' ');
if (this.lastDate !== date) {
elemForEach('.date-time.date', (elem) => { elem.innerHTML = date.toUpperCase(); });
if (dateElem && this.lastDate !== date) {
dateElem.innerHTML = date.toUpperCase();
}
this.lastDate = date;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -20,72 +20,83 @@ body {
}
}
input,
button {
font-family: "Star4000";
}
#divQuery {
max-width: 640px;
#imgGetGps {
height: 13px;
vertical-align: middle;
}
.buttons {
display: inline-block;
width: 150px;
text-align: right;
#txtAddress {
width: 490px;
font-size: 16pt;
max-width: calc(100% - 8px);
@media (prefers-color-scheme: dark) {
background-color: #000000;
color: white;
border: 1px solid darkgray;
}
}
#btnGetGps,
#btnGetLatLng,
#btnClearQuery {
font-size: 16pt;
@media (prefers-color-scheme: dark) {
background-color: #000000;
color: white;
}
border: 1px solid darkgray;
}
#btnGetGps {
img {
&.dark {
display: none;
@media (prefers-color-scheme: dark) {
display: inline-block;
}
#imgGetGps {
height: 13px;
vertical-align: middle;
}
&.light {
button {
font-size: 16pt;
@media (prefers-color-scheme: dark) {
display: none;
background-color: #000000;
color: white;
}
border: 1px solid darkgray;
}
#btnGetGps {
img {
&.dark {
display: none;
@media (prefers-color-scheme: dark) {
display: inline-block;
}
}
&.light {
@media (prefers-color-scheme: dark) {
display: none;
}
}
}
&.active {
background-color: black;
@media (prefers-color-scheme: dark) {
background-color: white;
}
img {
filter: invert(1);
}
}
}
}
&.active {
background-color: black;
input,
button {
font-family: "Star4000";
}
#txtAddress {
width: calc(100% - 170px);
max-width: 490px;
font-size: 16pt;
min-width: 200px;
display: inline-block;
@media (prefers-color-scheme: dark) {
background-color: white;
}
img {
filter: invert(1);
background-color: #000000;
color: white;
border: 1px solid darkgray;
}
}
}
}
.autocomplete-suggestions {
background-color: #ffffff;
border: 1px solid #000000;
@@ -93,19 +104,19 @@ button {
@media (prefers-color-scheme: dark) {
background-color: #000000;
}
}
.autocomplete-suggestion {
/*padding: 2px 5px;*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16pt;
}
.autocomplete-suggestion {
/*padding: 2px 5px;*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16pt;
}
.autocomplete-selected {
background-color: #0000ff;
color: #ffffff;
.autocomplete-selected {
background-color: #0000ff;
color: #ffffff;
}
}
#divTwc {
@@ -213,8 +224,7 @@ button {
text-align: right;
}
#imgPause1x,
#imgPause2x {
#imgPause1x {
visibility: hidden;
position: absolute;
}
@@ -318,6 +328,10 @@ button {
margin-bottom: 15px;
@include u.status-colors();
.press-here {
color: white;
}
@media (prefers-color-scheme: light) {
.loading,
@@ -326,7 +340,7 @@ button {
}
.press-here {
color: hsl(120, 100%, 30%);
color: black;
cursor: pointer;
}
@@ -343,10 +357,6 @@ button {
}
}
.press-here {
color: black;
}
label {
display: block;
max-width: 300px;
@@ -363,7 +373,7 @@ button {
}
#divTwcBottom img {
zoom: 150%;
zoom: 75%;
}
#divTwc:fullscreen {

View File

@@ -60,19 +60,15 @@
<div id="divQuery">
<form id="frmGetLatLng">
<input id="txtAddress" type="text" value="" placeholder="Zip or City, State" /><button id="btnGetGps" type="button" title="Get GPS Location"><img src="images/nav/ic_gps_fixed_black_18dp_1x.png" class="light"/><img src="images/nav/ic_gps_fixed_white_18dp_1x.png" class="dark"/></button>
<input id="btnGetLatLng" type="submit" value="GO" />
<input id="btnClearQuery" type="reset" value="Reset" />
</form>
<div id="divLat"></div>
<div id="divLng"></div>
<input id="txtAddress" type="text" value="" placeholder="Zip or City, State" />
<div class="buttons">
<button id="btnGetGps" type="button" title="Get GPS Location"><img src="images/nav/ic_gps_fixed_black_18dp_1x.png" class="light"/>
<img src="images/nav/ic_gps_fixed_white_18dp_1x.png" class="dark"/>
</button>
<button id="btnGetLatLng" type="submit">GO</button>
<button id="btnClearQuery" type="reset">Reset</button>
</div>
</div>
<br />
<img id="imgPause1x" src="images/nav/ic_pause_white_24dp_1x.png" />
<img id="imgPause2x" src="images/nav/ic_pause_white_24dp_2x.png" />
<div id="version" style="display:none">
<%- version %>
</div>
@@ -125,16 +121,16 @@
</div>
<div id="divTwcBottom">
<div id="divTwcBottomLeft">
<img id="NavigateMenu" class="navButton" src="images/nav/ic_menu_white_24dp_1x.png" title="Menu" />
<img id="NavigatePrevious" class="navButton" src="images/nav/ic_skip_previous_white_24dp_1x.png" title="Previous" />
<img id="NavigateNext" class="navButton" src="images/nav/ic_skip_next_white_24dp_1x.png" title="Next" />
<img id="NavigatePlay" class="navButton" src="images/nav/ic_play_arrow_white_24dp_1x.png" title="Play" />
<img id="NavigateMenu" class="navButton" src="images/nav/ic_menu_white_24dp_2x.png" title="Menu" />
<img id="NavigatePrevious" class="navButton" src="images/nav/ic_skip_previous_white_24dp_2x.png" title="Previous" />
<img id="NavigateNext" class="navButton" src="images/nav/ic_skip_next_white_24dp_2x.png" title="Next" />
<img id="NavigatePlay" class="navButton" src="images/nav/ic_play_arrow_white_24dp_2x.png" title="Play" />
</div>
<div id="divTwcBottomMiddle">
<img id="NavigateRefresh" class="navButton" src="images/nav/ic_refresh_white_24dp_1x.png" title="Refresh" />
<img id="NavigateRefresh" class="navButton" src="images/nav/ic_refresh_white_24dp_2x.png" title="Refresh" />
</div>
<div id="divTwcBottomRight">
<img id="ToggleFullScreen" class="navButton" src="images/nav/ic_fullscreen_white_24dp_1x.png" title="Enter Fullscreen" />
<img id="ToggleFullScreen" class="navButton" src="images/nav/ic_fullscreen_white_24dp_2x.png" title="Enter Fullscreen" />
</div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
<%- include('header.ejs', {titleDual:{ top: 'Current' , bottom: 'Conditions' }, noaaLogo: true}) %>
<%- include('header.ejs', {titleDual:{ top: 'Current' , bottom: 'Conditions' }, noaaLogo: true, hasTime: true}) %>
<div class="main has-scroll has-box current-weather">
<div class="weather template">
<div class="left col">

View File

@@ -1,4 +1,4 @@
<%- include('header.ejs', {titleDual:{ top: 'Latest' , bottom: 'Observations' }, noaaLogo: true }) %>
<%- include('header.ejs', {titleDual:{ top: 'Latest' , bottom: 'Observations' }, noaaLogo: true, hasTime: true }) %>
<div class="main has-scroll latest-observations has-box">
<div class="container">
<div class="column-headers">