additional eslint rules
This commit is contained in:
parent
b890b4e53d
commit
3743c45de6
27
.eslintrc.js
27
.eslintrc.js
|
@ -6,7 +6,10 @@ module.exports = {
|
|||
node: true,
|
||||
jquery: true,
|
||||
},
|
||||
extends: 'airbnb-base',
|
||||
extends: [
|
||||
'airbnb-base',
|
||||
'plugin:sonarjs/recommended',
|
||||
],
|
||||
globals: {
|
||||
Atomics: 'readonly',
|
||||
SharedArrayBuffer: 'readonly',
|
||||
|
@ -21,6 +24,10 @@ module.exports = {
|
|||
parserOptions: {
|
||||
ecmaVersion: 2021,
|
||||
},
|
||||
plugins: [
|
||||
'unicorn',
|
||||
'sonarjs',
|
||||
],
|
||||
rules: {
|
||||
indent: [
|
||||
'error',
|
||||
|
@ -60,6 +67,24 @@ module.exports = {
|
|||
json: 'always',
|
||||
},
|
||||
],
|
||||
// unicorn
|
||||
'unicorn/numeric-separators-style': 'error',
|
||||
'unicorn/prefer-query-selector': 'error',
|
||||
'unicorn/catch-error-name': 'error',
|
||||
'unicorn/no-negated-condition': 'error',
|
||||
'unicorn/better-regex': 'error',
|
||||
'unicorn/consistent-function-scoping': 'error',
|
||||
'unicorn/prefer-array-flat-map': 'error',
|
||||
'unicorn/prefer-array-find': 'error',
|
||||
'unicorn/prefer-regexp-test': 'error',
|
||||
'unicorn/consistent-destructuring': 'error',
|
||||
'unicorn/prefer-date-now': 'error',
|
||||
'unicorn/prefer-ternary': 'error',
|
||||
'unicorn/prefer-dom-node-append': 'error',
|
||||
'unicorn/explicit-length-check': 'error',
|
||||
'unicorn/prefer-at': 'error',
|
||||
// sonarjs
|
||||
'sonarjs/cognitive-complexity': 0,
|
||||
},
|
||||
ignorePatterns: [
|
||||
'*.min.js',
|
||||
|
|
14
.vscode/tasks.json
vendored
Normal file
14
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "lint",
|
||||
"problemMatcher": [
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"label": "npm: lint",
|
||||
"detail": "eslint ./server/scripts/**"
|
||||
}
|
||||
]
|
||||
}
|
867
package-lock.json
generated
867
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -22,7 +22,11 @@
|
|||
"devDependencies": {
|
||||
"del": "^6.0.0",
|
||||
"ejs": "^3.1.5",
|
||||
"eslint": "^8.21.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-sonarjs": "^0.17.0",
|
||||
"eslint-plugin-unicorn": "^45.0.2",
|
||||
"express": "^4.17.1",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
|
@ -40,9 +44,6 @@
|
|||
"suncalc": "^1.8.0",
|
||||
"swiped-events": "^1.1.4",
|
||||
"terser-webpack-plugin": "^5.3.6",
|
||||
"webpack-stream": "^7.0.0",
|
||||
"eslint": "^8.21.0",
|
||||
"eslint-plugin-import": "^2.26.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
"webpack-stream": "^7.0.0"
|
||||
}
|
||||
}
|
||||
|
|
6
server/scripts/data/.eslintrc.js
Normal file
6
server/scripts/data/.eslintrc.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
rules: {
|
||||
// unicorn
|
||||
'unicorn/numeric-separators-style': 0,
|
||||
},
|
||||
};
|
|
@ -22,35 +22,38 @@ const categories = [
|
|||
'Postal', 'Populated Place',
|
||||
];
|
||||
const category = categories.join(',');
|
||||
const TXT_ADDRESS_SELECTOR = '#txtAddress';
|
||||
const TOGGLE_FULL_SCREEN_SELECTOR = '#ToggleFullScreen';
|
||||
const BNT_GET_GPS_SELECTOR = '#btnGetGps';
|
||||
|
||||
const init = () => {
|
||||
document.getElementById('txtAddress').addEventListener('focus', (e) => {
|
||||
document.querySelector(TXT_ADDRESS_SELECTOR).addEventListener('focus', (e) => {
|
||||
e.target.select();
|
||||
});
|
||||
|
||||
registerRefreshData(loadData);
|
||||
|
||||
document.getElementById('NavigateMenu').addEventListener('click', btnNavigateMenuClick);
|
||||
document.getElementById('NavigateRefresh').addEventListener('click', btnNavigateRefreshClick);
|
||||
document.getElementById('NavigateNext').addEventListener('click', btnNavigateNextClick);
|
||||
document.getElementById('NavigatePrevious').addEventListener('click', btnNavigatePreviousClick);
|
||||
document.getElementById('NavigatePlay').addEventListener('click', btnNavigatePlayClick);
|
||||
document.getElementById('ToggleFullScreen').addEventListener('click', btnFullScreenClick);
|
||||
const btnGetGps = document.getElementById('btnGetGps');
|
||||
document.querySelector('#NavigateMenu').addEventListener('click', btnNavigateMenuClick);
|
||||
document.querySelector('#NavigateRefresh').addEventListener('click', btnNavigateRefreshClick);
|
||||
document.querySelector('#NavigateNext').addEventListener('click', btnNavigateNextClick);
|
||||
document.querySelector('#NavigatePrevious').addEventListener('click', btnNavigatePreviousClick);
|
||||
document.querySelector('#NavigatePlay').addEventListener('click', btnNavigatePlayClick);
|
||||
document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR).addEventListener('click', btnFullScreenClick);
|
||||
const btnGetGps = document.querySelector(BNT_GET_GPS_SELECTOR);
|
||||
btnGetGps.addEventListener('click', btnGetGpsClick);
|
||||
if (!navigator.geolocation) btnGetGps.style.display = 'none';
|
||||
|
||||
document.getElementById('divTwc').addEventListener('click', () => {
|
||||
document.querySelector('#divTwc').addEventListener('click', () => {
|
||||
if (document.fullscreenElement) updateFullScreenNavigate();
|
||||
});
|
||||
|
||||
document.getElementById('txtAddress').addEventListener('keydown', (key) => { if (key.code === 'Enter') formSubmit(); });
|
||||
document.getElementById('btnGetLatLng').addEventListener('click', () => formSubmit());
|
||||
document.querySelector(TXT_ADDRESS_SELECTOR).addEventListener('keydown', (key) => { if (key.code === 'Enter') formSubmit(); });
|
||||
document.querySelector('#btnGetLatLng').addEventListener('click', () => formSubmit());
|
||||
|
||||
document.addEventListener('keydown', documentKeydown);
|
||||
document.addEventListener('touchmove', (e) => { if (fullScreenOverride) e.preventDefault(); });
|
||||
|
||||
$('#txtAddress').devbridgeAutocomplete({
|
||||
$(TXT_ADDRESS_SELECTOR).devbridgeAutocomplete({
|
||||
serviceUrl: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest',
|
||||
deferRequestBy: 300,
|
||||
paramName: 'text',
|
||||
|
@ -75,7 +78,7 @@ const init = () => {
|
|||
});
|
||||
|
||||
const formSubmit = () => {
|
||||
const ac = $('#txtAddress').devbridgeAutocomplete();
|
||||
const ac = $(TXT_ADDRESS_SELECTOR).devbridgeAutocomplete();
|
||||
if (ac.suggestions[0]) $(ac.suggestionsContainer.children[0]).trigger('click');
|
||||
return false;
|
||||
};
|
||||
|
@ -85,7 +88,7 @@ const init = () => {
|
|||
const latLon = localStorage.getItem('latLon');
|
||||
const fromGPS = localStorage.getItem('latLonFromGPS');
|
||||
if (query && latLon && !fromGPS) {
|
||||
const txtAddress = document.getElementById('txtAddress');
|
||||
const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR);
|
||||
txtAddress.value = query;
|
||||
loadData(JSON.parse(latLon));
|
||||
}
|
||||
|
@ -96,14 +99,14 @@ const init = () => {
|
|||
const play = localStorage.getItem('play');
|
||||
if (play === null || play === 'true') postMessage('navButton', 'play');
|
||||
|
||||
document.getElementById('btnClearQuery').addEventListener('click', () => {
|
||||
document.getElementById('spanCity').innerHTML = '';
|
||||
document.getElementById('spanState').innerHTML = '';
|
||||
document.getElementById('spanStationId').innerHTML = '';
|
||||
document.getElementById('spanRadarId').innerHTML = '';
|
||||
document.getElementById('spanZoneId').innerHTML = '';
|
||||
document.querySelector('#btnClearQuery').addEventListener('click', () => {
|
||||
document.querySelector('#spanCity').innerHTML = '';
|
||||
document.querySelector('#spanState').innerHTML = '';
|
||||
document.querySelector('#spanStationId').innerHTML = '';
|
||||
document.querySelector('#spanRadarId').innerHTML = '';
|
||||
document.querySelector('#spanZoneId').innerHTML = '';
|
||||
|
||||
document.getElementById('chkAutoRefresh').checked = true;
|
||||
document.querySelector('#chkAutoRefresh').checked = true;
|
||||
localStorage.removeItem('autoRefresh');
|
||||
|
||||
localStorage.removeItem('play');
|
||||
|
@ -112,12 +115,12 @@ const init = () => {
|
|||
localStorage.removeItem('latLonQuery');
|
||||
localStorage.removeItem('latLon');
|
||||
localStorage.removeItem('latLonFromGPS');
|
||||
document.getElementById('btnGetGps').classList.remove('active');
|
||||
document.querySelector(BNT_GET_GPS_SELECTOR).classList.remove('active');
|
||||
});
|
||||
|
||||
// swipe functionality
|
||||
document.getElementById('container').addEventListener('swiped-left', () => swipeCallBack('left'));
|
||||
document.getElementById('container').addEventListener('swiped-right', () => swipeCallBack('right'));
|
||||
document.querySelector('#container').addEventListener('swiped-left', () => swipeCallBack('left'));
|
||||
document.querySelector('#container').addEventListener('swiped-right', () => swipeCallBack('right'));
|
||||
};
|
||||
|
||||
const autocompleteOnSelect = async (suggestion, elem) => {
|
||||
|
@ -135,7 +138,7 @@ const autocompleteOnSelect = async (suggestion, elem) => {
|
|||
const loc = data.locations[0];
|
||||
if (loc) {
|
||||
localStorage.removeItem('latLonFromGPS');
|
||||
document.getElementById('btnGetGps').classList.remove('active');
|
||||
document.querySelector(BNT_GET_GPS_SELECTOR).classList.remove('active');
|
||||
doRedirectToGeometry(loc.feature.geometry);
|
||||
} else {
|
||||
console.error('An unexpected error occurred. Please try a different search string.');
|
||||
|
@ -145,7 +148,7 @@ const autocompleteOnSelect = async (suggestion, elem) => {
|
|||
const doRedirectToGeometry = (geom, haveDataCallback) => {
|
||||
const latLon = { lat: round2(geom.y, 4), lon: round2(geom.x, 4) };
|
||||
// Save the query
|
||||
localStorage.setItem('latLonQuery', document.getElementById('txtAddress').value);
|
||||
localStorage.setItem('latLonQuery', document.querySelector(TXT_ADDRESS_SELECTOR).value);
|
||||
localStorage.setItem('latLon', JSON.stringify(latLon));
|
||||
|
||||
// get the data
|
||||
|
@ -153,10 +156,10 @@ const doRedirectToGeometry = (geom, haveDataCallback) => {
|
|||
};
|
||||
|
||||
const btnFullScreenClick = () => {
|
||||
if (!document.fullscreenElement) {
|
||||
enterFullScreen();
|
||||
} else {
|
||||
if (document.fullscreenElement) {
|
||||
exitFullscreen();
|
||||
} else {
|
||||
enterFullScreen();
|
||||
}
|
||||
|
||||
if (isPlaying()) {
|
||||
|
@ -171,7 +174,7 @@ const btnFullScreenClick = () => {
|
|||
};
|
||||
|
||||
const enterFullScreen = () => {
|
||||
const element = document.getElementById('divTwc');
|
||||
const element = document.querySelector('#divTwc');
|
||||
|
||||
// Supports most browsers and their versions.
|
||||
const requestMethod = element.requestFullScreen || element.webkitRequestFullScreen
|
||||
|
@ -189,7 +192,7 @@ const enterFullScreen = () => {
|
|||
updateFullScreenNavigate();
|
||||
|
||||
// change hover text and image
|
||||
const img = document.getElementById('ToggleFullScreen');
|
||||
const img = document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR);
|
||||
img.src = 'images/nav/ic_fullscreen_exit_white_24dp_2x.png';
|
||||
img.title = 'Exit fullscreen';
|
||||
};
|
||||
|
@ -213,7 +216,7 @@ const exitFullscreen = () => {
|
|||
}
|
||||
resize();
|
||||
// change hover text and image
|
||||
const img = document.getElementById('ToggleFullScreen');
|
||||
const img = document.querySelector(TOGGLE_FULL_SCREEN_SELECTOR);
|
||||
img.src = 'images/nav/ic_fullscreen_white_24dp_2x.png';
|
||||
img.title = 'Enter fullscreen';
|
||||
};
|
||||
|
@ -232,7 +235,7 @@ const loadData = (_latLon, haveDataCallback) => {
|
|||
// if there's no data stop
|
||||
if (!latLon) return;
|
||||
|
||||
document.getElementById('txtAddress').blur();
|
||||
document.querySelector(TXT_ADDRESS_SELECTOR).blur();
|
||||
stopAutoRefreshTimer();
|
||||
latLonReceived(latLon, haveDataCallback);
|
||||
};
|
||||
|
@ -276,8 +279,9 @@ let navigateFadeIntervalId = null;
|
|||
|
||||
const updateFullScreenNavigate = () => {
|
||||
document.activeElement.blur();
|
||||
document.getElementById('divTwcBottom').classList.remove('hidden');
|
||||
document.getElementById('divTwcBottom').classList.add('visible');
|
||||
const divTwcBottom = document.querySelector('#divTwcBottom');
|
||||
divTwcBottom.classList.remove('hidden');
|
||||
divTwcBottom.classList.add('visible');
|
||||
|
||||
if (navigateFadeIntervalId) {
|
||||
clearTimeout(navigateFadeIntervalId);
|
||||
|
@ -286,8 +290,8 @@ const updateFullScreenNavigate = () => {
|
|||
|
||||
navigateFadeIntervalId = setTimeout(() => {
|
||||
if (document.fullscreenElement) {
|
||||
document.getElementById('divTwcBottom').classList.remove('visible');
|
||||
document.getElementById('divTwcBottom').classList.add('hidden');
|
||||
divTwcBottom.classList.remove('visible');
|
||||
divTwcBottom.classList.add('hidden');
|
||||
}
|
||||
}, 2000);
|
||||
};
|
||||
|
@ -355,7 +359,7 @@ const getPosition = async () => new Promise((resolve) => {
|
|||
|
||||
const btnGetGpsClick = async () => {
|
||||
if (!navigator.geolocation) return;
|
||||
const btn = document.getElementById('btnGetGps');
|
||||
const btn = document.querySelector(BNT_GET_GPS_SELECTOR);
|
||||
|
||||
// toggle first
|
||||
if (btn.classList.contains('active')) {
|
||||
|
@ -371,7 +375,7 @@ const btnGetGpsClick = async () => {
|
|||
const position = await getPosition();
|
||||
const { latitude, longitude } = position.coords;
|
||||
|
||||
const txtAddress = document.getElementById('txtAddress');
|
||||
const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR);
|
||||
txtAddress.value = `${round2(latitude, 4)}, ${round2(longitude, 4)}`;
|
||||
|
||||
doRedirectToGeometry({ y: latitude, x: longitude }, (point) => {
|
||||
|
|
|
@ -59,8 +59,8 @@ class CurrentWeather extends WeatherDisplay {
|
|||
observations = undefined;
|
||||
throw new Error(`Unable to get observations: ${station.properties.stationIdentifier}, trying next station`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
// test for data received
|
||||
|
|
|
@ -75,12 +75,10 @@ const screens = [
|
|||
|
||||
// wind
|
||||
(data) => {
|
||||
let text = '';
|
||||
if (data.WindSpeed > 0) {
|
||||
text = `Wind: ${data.WindDirection} ${data.WindSpeed} ${data.WindUnit}`;
|
||||
} else {
|
||||
text = 'Wind: Calm';
|
||||
}
|
||||
let text = data.WindSpeed > 0
|
||||
? `Wind: ${data.WindDirection} ${data.WindSpeed} ${data.WindUnit}`
|
||||
: 'Wind: Calm';
|
||||
|
||||
if (data.WindGust > 0) {
|
||||
text += ` Gusts to ${data.WindGust}`;
|
||||
}
|
||||
|
@ -88,7 +86,10 @@ const screens = [
|
|||
},
|
||||
|
||||
// visibility
|
||||
(data) => `Visib: ${data.Visibility} ${data.VisibilityUnit} Ceiling: ${data.Ceiling === 0 ? 'Unlimited' : `${data.Ceiling} ${data.CeilingUnit}`}`,
|
||||
(data) => {
|
||||
const distance = `${data.Ceiling} ${data.CeilingUnit}`;
|
||||
return `Visib: ${data.Visibility} ${data.VisibilityUnit} Ceiling: ${data.Ceiling === 0 ? 'Unlimited' : distance}`;
|
||||
},
|
||||
];
|
||||
|
||||
// internal draw function with preset parameters
|
||||
|
|
|
@ -31,9 +31,9 @@ class ExtendedForecast extends WeatherDisplay {
|
|||
retryCount: 3,
|
||||
stillWaiting: () => this.stillWaiting(),
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.error('Unable to get extended forecast');
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
this.setStatus(STATUS.failed);
|
||||
return;
|
||||
}
|
||||
|
@ -52,7 +52,10 @@ class ExtendedForecast extends WeatherDisplay {
|
|||
|
||||
// create each day template
|
||||
const days = forecast.map((Day) => {
|
||||
const fill = {};
|
||||
const fill = {
|
||||
icon: { type: 'img', src: Day.icon },
|
||||
condition: Day.text,
|
||||
};
|
||||
fill.date = Day.dayName;
|
||||
|
||||
const { low } = Day;
|
||||
|
@ -61,10 +64,6 @@ class ExtendedForecast extends WeatherDisplay {
|
|||
}
|
||||
const { high } = Day;
|
||||
fill['value-hi'] = Math.round(high);
|
||||
fill.condition = Day.text;
|
||||
|
||||
// draw the icon
|
||||
fill.icon = { type: 'img', src: Day.icon };
|
||||
|
||||
// return the filled template
|
||||
return this.fillTemplate('day', fill);
|
||||
|
@ -123,13 +122,13 @@ const parse = (fullForecast) => {
|
|||
|
||||
const shortenExtendedForecastText = (long) => {
|
||||
const regexList = [
|
||||
[/ and /ig, ' '],
|
||||
[/Slight /ig, ''],
|
||||
[/Chance /ig, ''],
|
||||
[/Very /ig, ''],
|
||||
[/Patchy /ig, ''],
|
||||
[/Areas /ig, ''],
|
||||
[/Dense /ig, ''],
|
||||
[/ and /gi, ' '],
|
||||
[/slight /gi, ''],
|
||||
[/chance /gi, ''],
|
||||
[/very /gi, ''],
|
||||
[/patchy /gi, ''],
|
||||
[/areas /gi, ''],
|
||||
[/dense /gi, ''],
|
||||
[/Thunderstorm/g, 'T\'Storm'],
|
||||
];
|
||||
// run all regexes
|
||||
|
@ -144,10 +143,10 @@ const shortenExtendedForecastText = (long) => {
|
|||
let short1 = conditions[0].substr(0, 10);
|
||||
let short2 = '';
|
||||
if (conditions[1]) {
|
||||
if (!short1.endsWith('.')) {
|
||||
short2 = conditions[1].substr(0, 10);
|
||||
} else {
|
||||
if (short1.endsWith('.')) {
|
||||
short1 = short1.replace(/\./, '');
|
||||
} else {
|
||||
short2 = conditions[1].substr(0, 10);
|
||||
}
|
||||
|
||||
if (short2 === 'Blowing') {
|
||||
|
|
|
@ -40,9 +40,9 @@ class Hazards extends WeatherDisplay {
|
|||
|
||||
// show alert indicator
|
||||
if (this.data.length > 0) alert.classList.add('show');
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.error('Get hourly forecast failed');
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
if (this.isEnabled) this.setStatus(STATUS.failed);
|
||||
// return undefined to other subscribers
|
||||
this.getDataCallback(undefined);
|
||||
|
|
|
@ -34,9 +34,9 @@ class Hourly extends WeatherDisplay {
|
|||
try {
|
||||
// get the forecast
|
||||
forecast = await json(weatherParameters.forecastGridData, { retryCount: 3, stillWaiting: () => this.stillWaiting() });
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.error('Get hourly forecast failed');
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
if (this.isEnabled) this.setStatus(STATUS.failed);
|
||||
// return undefined to other subscribers
|
||||
this.getDataCallback(undefined);
|
||||
|
@ -183,7 +183,7 @@ const expand = (data) => {
|
|||
result.push(item.value); // push data array
|
||||
} // timestamp is after now
|
||||
// increment start time by 1 hour
|
||||
startTime += 3600000;
|
||||
startTime += 3_600_000;
|
||||
} while (startTime < endTime && result.length < 24);
|
||||
}); // for each value
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable unicorn/consistent-function-scoping */
|
||||
/* spell-checker: disable */
|
||||
|
||||
const getWeatherRegionalIconFromIconLink = (link, _isNightTime) => {
|
||||
|
@ -8,7 +9,7 @@ const getWeatherRegionalIconFromIconLink = (link, _isNightTime) => {
|
|||
|
||||
// grab everything after the last slash ending at any of these: ?&,
|
||||
const afterLastSlash = link.toLowerCase().match(/[^/]+$/)[0];
|
||||
let conditionName = afterLastSlash.match(/(.*?)[,?&.]/)[1];
|
||||
let conditionName = afterLastSlash.match(/(.*?)[&,.?]/)[1];
|
||||
// using probability as a crude heavy/light indication where possible
|
||||
const value = +(link.match(/,(\d{2,3})/) ?? [0, 100])[1];
|
||||
|
||||
|
@ -156,7 +157,7 @@ const getWeatherIconFromIconLink = (link, _isNightTime) => {
|
|||
|
||||
// grab everything after the last slash ending at any of these: ?&,
|
||||
const afterLastSlash = link.toLowerCase().match(/[^/]+$/)[0];
|
||||
let conditionName = afterLastSlash.match(/(.*?)[,?&.]/)[1];
|
||||
let conditionName = afterLastSlash.match(/(.*?)[&,.?]/)[1];
|
||||
// using probability as a crude heavy/light indication where possible
|
||||
const value = +(link.match(/,(\d{2,3})/) ?? [0, 100])[1];
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class LatestObservations extends WeatherDisplay {
|
|||
this.data = actualConditions.slice(0, this.MaximumRegionalStations);
|
||||
|
||||
// test for at least one station
|
||||
if (this.data.length < 1) {
|
||||
if (this.data.length === 0) {
|
||||
this.setStatus(STATUS.noData);
|
||||
return;
|
||||
}
|
||||
|
@ -73,10 +73,12 @@ class LatestObservations extends WeatherDisplay {
|
|||
const Temperature = Math.round(celsiusToFahrenheit(condition.temperature.value));
|
||||
const WindSpeed = Math.round(kphToMph(condition.windSpeed.value));
|
||||
|
||||
const fill = {};
|
||||
fill.location = locationCleanup(condition.city).substr(0, 14);
|
||||
fill.temp = Temperature;
|
||||
fill.weather = shortenCurrentConditions(condition.textDescription).substr(0, 9);
|
||||
const fill = {
|
||||
location: locationCleanup(condition.city).substr(0, 14),
|
||||
temp: Temperature,
|
||||
weather: shortenCurrentConditions(condition.textDescription).substr(0, 9),
|
||||
};
|
||||
|
||||
if (WindSpeed > 0) {
|
||||
fill.wind = windDirection + (Array(6 - windDirection.length - WindSpeed.toString().length).join(' ')) + WindSpeed.toString();
|
||||
} else if (WindSpeed === 'NA') {
|
||||
|
@ -128,7 +130,7 @@ const getStations = async (stations) => {
|
|||
StationId: station.id,
|
||||
city: station.city,
|
||||
};
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.log(`Unable to get latest observations for ${station.id}`);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -66,9 +66,9 @@ class LocalForecast extends WeatherDisplay {
|
|||
retryCount: 3,
|
||||
stillWaiting: () => this.stillWaiting(),
|
||||
});
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.error(`GetWeatherForecast failed: ${weatherParameters.forecast}`);
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
this.setStatus(STATUS.failed);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ const weatherParameters = {};
|
|||
|
||||
// auto refresh
|
||||
const AUTO_REFRESH_INTERVAL_MS = 500;
|
||||
const AUTO_REFRESH_TIME_MS = 600000; // 10 min.
|
||||
const AUTO_REFRESH_TIME_MS = 600_000; // 10 min.
|
||||
const CHK_AUTO_REFRESH_SELECTOR = '#chkAutoRefresh';
|
||||
let AutoRefreshIntervalId = null;
|
||||
let AutoRefreshCountMs = 0;
|
||||
|
||||
|
@ -28,25 +29,19 @@ const init = async () => {
|
|||
// auto refresh
|
||||
const autoRefresh = localStorage.getItem('autoRefresh');
|
||||
if (!autoRefresh || autoRefresh === 'true') {
|
||||
document.getElementById('chkAutoRefresh').checked = true;
|
||||
document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked = true;
|
||||
} else {
|
||||
document.getElementById('chkAutoRefresh').checked = false;
|
||||
document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked = false;
|
||||
}
|
||||
document.getElementById('chkAutoRefresh').addEventListener('change', autoRefreshChange);
|
||||
document.querySelector(CHK_AUTO_REFRESH_SELECTOR).addEventListener('change', autoRefreshChange);
|
||||
generateCheckboxes();
|
||||
};
|
||||
|
||||
const message = (data) => {
|
||||
// dispatch event
|
||||
if (!data.type) return;
|
||||
switch (data.type) {
|
||||
case 'navButton':
|
||||
handleNavButton(data.message);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error(`Unknown event ${data.type}`);
|
||||
}
|
||||
if (!data.type) return false;
|
||||
if (data.type === 'navButton') return handleNavButton(data.message);
|
||||
return console.error(`Unknown event ${data.type}`);
|
||||
};
|
||||
|
||||
const getWeather = async (latLon, haveDataCallback) => {
|
||||
|
@ -61,6 +56,7 @@ const getWeather = async (latLon, haveDataCallback) => {
|
|||
const StationId = stations.features[0].properties.stationIdentifier;
|
||||
|
||||
let { city } = point.properties.relativeLocation.properties;
|
||||
const { state } = point.properties.relativeLocation.properties;
|
||||
|
||||
if (StationId in StationInfo) {
|
||||
city = StationInfo[StationId].city;
|
||||
|
@ -76,7 +72,7 @@ const getWeather = async (latLon, haveDataCallback) => {
|
|||
weatherParameters.stationId = StationId;
|
||||
weatherParameters.weatherOffice = point.properties.cwa;
|
||||
weatherParameters.city = city;
|
||||
weatherParameters.state = point.properties.relativeLocation.properties.state;
|
||||
weatherParameters.state = state;
|
||||
weatherParameters.timeZone = point.properties.timeZone;
|
||||
weatherParameters.forecast = point.properties.forecast;
|
||||
weatherParameters.forecastGridData = point.properties.forecastGridData;
|
||||
|
@ -87,7 +83,7 @@ const getWeather = async (latLon, haveDataCallback) => {
|
|||
|
||||
// draw the progress canvas and hide others
|
||||
hideAllCanvases();
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
document.querySelector('#loading').style.display = 'none';
|
||||
if (progress) {
|
||||
await progress.drawCanvas();
|
||||
progress.showCanvas();
|
||||
|
@ -200,9 +196,7 @@ const loadDisplay = (direction) => {
|
|||
if (displays[idx].status === STATUS.loaded && displays[idx].timing.totalScreens > 0) break;
|
||||
}
|
||||
// if new display index is less than current display a wrap occurred, test for reload timeout
|
||||
if (idx <= curIdx) {
|
||||
if (refreshCheck()) return;
|
||||
}
|
||||
if (idx <= curIdx && refreshCheck()) return;
|
||||
const newDisplay = displays[idx];
|
||||
// hide all displays
|
||||
hideAllCanvases();
|
||||
|
@ -212,15 +206,12 @@ const loadDisplay = (direction) => {
|
|||
};
|
||||
|
||||
// get the current display index or value
|
||||
const currentDisplayIndex = () => {
|
||||
const index = displays.findIndex((display) => display.active);
|
||||
return index;
|
||||
};
|
||||
const currentDisplayIndex = () => displays.findIndex((display) => display.active);
|
||||
const currentDisplay = () => displays[currentDisplayIndex()];
|
||||
|
||||
const setPlaying = (newValue) => {
|
||||
playing = newValue;
|
||||
const playButton = document.getElementById('NavigatePlay');
|
||||
const playButton = document.querySelector('#NavigatePlay');
|
||||
localStorage.setItem('play', playing);
|
||||
|
||||
if (playing) {
|
||||
|
@ -272,14 +263,14 @@ const getDisplay = (index) => displays[index];
|
|||
|
||||
// resize the container on a page resize
|
||||
const resize = () => {
|
||||
const widthZoomPercent = (document.getElementById('divTwcBottom').getBoundingClientRect().width) / 640;
|
||||
const widthZoomPercent = (document.querySelector('#divTwcBottom').getBoundingClientRect().width) / 640;
|
||||
const heightZoomPercent = (window.innerHeight) / 480;
|
||||
|
||||
const scale = Math.min(widthZoomPercent, heightZoomPercent);
|
||||
if (scale < 1.0 || document.fullscreenElement) {
|
||||
document.getElementById('container').style.zoom = scale;
|
||||
document.querySelector('#container').style.zoom = scale;
|
||||
} else {
|
||||
document.getElementById('container').style.zoom = 1;
|
||||
document.querySelector('#container').style.zoom = 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -297,7 +288,7 @@ const registerDisplay = (display) => {
|
|||
};
|
||||
|
||||
const generateCheckboxes = () => {
|
||||
const availableDisplays = document.getElementById('enabledDisplays');
|
||||
const availableDisplays = document.querySelector('#enabledDisplays');
|
||||
|
||||
if (!availableDisplays) return;
|
||||
// generate checkboxes
|
||||
|
@ -314,11 +305,11 @@ const registerProgress = (_progress) => {
|
|||
};
|
||||
|
||||
const populateWeatherParameters = (params) => {
|
||||
document.getElementById('spanCity').innerHTML = `${params.city}, `;
|
||||
document.getElementById('spanState').innerHTML = params.state;
|
||||
document.getElementById('spanStationId').innerHTML = params.stationId;
|
||||
document.getElementById('spanRadarId').innerHTML = params.radarId;
|
||||
document.getElementById('spanZoneId').innerHTML = params.zoneId;
|
||||
document.querySelector('#spanCity').innerHTML = `${params.city}, `;
|
||||
document.querySelector('#spanState').innerHTML = params.state;
|
||||
document.querySelector('#spanStationId').innerHTML = params.stationId;
|
||||
document.querySelector('#spanRadarId').innerHTML = params.radarId;
|
||||
document.querySelector('#spanZoneId').innerHTML = params.zoneId;
|
||||
};
|
||||
|
||||
const autoRefreshChange = (e) => {
|
||||
|
@ -335,12 +326,12 @@ const autoRefreshChange = (e) => {
|
|||
|
||||
const AssignLastUpdate = (date) => {
|
||||
if (date) {
|
||||
document.getElementById('spanLastRefresh').innerHTML = date.toLocaleString('en-US', {
|
||||
document.querySelector('#spanLastRefresh').innerHTML = date.toLocaleString('en-US', {
|
||||
weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric', timeZoneName: 'short',
|
||||
});
|
||||
if (document.getElementById('chkAutoRefresh').checked) startAutoRefreshTimer();
|
||||
if (document.querySelector(CHK_AUTO_REFRESH_SELECTOR).checked) startAutoRefreshTimer();
|
||||
} else {
|
||||
document.getElementById('spanLastRefresh').innerHTML = '(none)';
|
||||
document.querySelector('#spanLastRefresh').innerHTML = '(none)';
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -367,7 +358,7 @@ const startAutoRefreshTimer = () => {
|
|||
RemainingMs = 0;
|
||||
}
|
||||
const dt = new Date(RemainingMs);
|
||||
document.getElementById('spanRefreshCountDown').innerHTML = `${dt.getMinutes() < 10 ? `0${dt.getMinutes()}` : dt.getMinutes()}:${dt.getSeconds() < 10 ? `0${dt.getSeconds()}` : dt.getSeconds()}`;
|
||||
document.querySelector('#spanRefreshCountDown').innerHTML = `${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}`;
|
||||
|
||||
// Time has elapsed.
|
||||
if (AutoRefreshCountMs >= AUTO_REFRESH_TIME_MS && !isPlaying()) loadTwcData();
|
||||
|
@ -378,7 +369,7 @@ const startAutoRefreshTimer = () => {
|
|||
const stopAutoRefreshTimer = () => {
|
||||
if (AutoRefreshIntervalId) {
|
||||
window.clearInterval(AutoRefreshIntervalId);
|
||||
document.getElementById('spanRefreshCountDown').innerHTML = '--:--';
|
||||
document.querySelector('#spanRefreshCountDown').innerHTML = '--:--';
|
||||
AutoRefreshIntervalId = null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ class Progress extends WeatherDisplay {
|
|||
|
||||
// setup event listener for dom-required initialization
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
this.version = document.getElementById('version').innerHTML;
|
||||
this.version = document.querySelector('#version').innerHTML;
|
||||
this.elem.querySelector('.container').addEventListener('click', this.lineClick.bind(this));
|
||||
});
|
||||
|
||||
|
@ -36,9 +36,9 @@ class Progress extends WeatherDisplay {
|
|||
if (!displays) return;
|
||||
const lines = displays.map((display, index) => {
|
||||
if (display.showOnProgress === false) return false;
|
||||
const fill = {};
|
||||
|
||||
fill.name = display.name;
|
||||
const fill = {
|
||||
name: display.name,
|
||||
};
|
||||
|
||||
const statusClass = calcStatusClass(display.status);
|
||||
|
||||
|
|
|
@ -71,25 +71,24 @@ class Radar extends WeatherDisplay {
|
|||
const lists = (await Promise.all(baseUrls.map(async (url) => {
|
||||
try {
|
||||
// get a list of available radars
|
||||
const radarHtml = await text(url, { cors: true });
|
||||
return radarHtml;
|
||||
} catch (e) {
|
||||
return text(url, { cors: true });
|
||||
} catch (error) {
|
||||
console.log('Unable to get list of radars');
|
||||
console.error(e);
|
||||
console.error(error);
|
||||
this.setStatus(STATUS.failed);
|
||||
return false;
|
||||
}
|
||||
}))).filter((d) => d);
|
||||
|
||||
// convert to an array of gif urls
|
||||
const pngs = lists.map((html, htmlIdx) => {
|
||||
const pngs = lists.flatMap((html, htmlIdx) => {
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(html, 'text/html');
|
||||
// add the base url
|
||||
const base = xmlDoc.createElement('base');
|
||||
base.href = baseUrls[htmlIdx];
|
||||
xmlDoc.head.append(base);
|
||||
const anchors = xmlDoc.getElementsByTagName('a');
|
||||
const anchors = xmlDoc.querySelectorAll('a');
|
||||
const urls = [];
|
||||
Array.from(anchors).forEach((elem) => {
|
||||
if (elem.innerHTML?.includes('.png') && elem.innerHTML?.includes('n0r_')) {
|
||||
|
@ -97,7 +96,7 @@ class Radar extends WeatherDisplay {
|
|||
}
|
||||
});
|
||||
return urls;
|
||||
}).flat();
|
||||
});
|
||||
|
||||
// get the last few images
|
||||
const sortedPngs = pngs.sort((a, b) => (Date(a) < Date(b) ? -1 : 1));
|
||||
|
|
|
@ -28,9 +28,9 @@ const getRegionalObservation = async (point, city) => {
|
|||
preloadImg(icon);
|
||||
// return the observation
|
||||
return observation.properties;
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.log(`Unable to get regional observations for ${city.Name ?? city.city}`);
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -195,7 +195,7 @@ const getXYForCityHI = (City, MaxLatitude, MinLongitude) => {
|
|||
};
|
||||
|
||||
// to fit on the map, remove anything after punctuation and then limit to 15 characters
|
||||
const formatCity = (city) => city.match(/[^-;/\\,]*/)[0].substr(0, 12);
|
||||
const formatCity = (city) => city.match(/[^,/;\\-]*/)[0].substr(0, 12);
|
||||
|
||||
export {
|
||||
buildForecast,
|
||||
|
|
|
@ -92,7 +92,7 @@ class RegionalForecast extends WeatherDisplay {
|
|||
|
||||
// format the observation the same as the forecast
|
||||
const regionalObservation = {
|
||||
daytime: !!observation.icon.match(/\/day\//),
|
||||
daytime: !!/\/day\//.test(observation.icon),
|
||||
temperature: celsiusToFahrenheit(observation.temperature.value),
|
||||
name: utils.formatCity(city.city),
|
||||
icon: observation.icon,
|
||||
|
@ -113,9 +113,9 @@ class RegionalForecast extends WeatherDisplay {
|
|||
utils.buildForecast(forecast.properties.periods[1], city, cityXY),
|
||||
utils.buildForecast(forecast.properties.periods[2], city, cityXY),
|
||||
];
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.log(`No regional forecast data for '${city.name ?? city.city}'`);
|
||||
console.log(e);
|
||||
console.log(error);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
@ -159,11 +159,9 @@ class RegionalForecast extends WeatherDisplay {
|
|||
const dayName = forecastDate.toLocaleString({ weekday: 'long' });
|
||||
titleTop.innerHTML = 'Forecast for';
|
||||
// draw the title
|
||||
if (data[0][this.screenIndex].daytime) {
|
||||
titleBottom.innerHTML = dayName;
|
||||
} else {
|
||||
titleBottom.innerHTML = `${dayName} Night`;
|
||||
}
|
||||
titleBottom.innerHTML = data[0][this.screenIndex].daytime
|
||||
? dayName
|
||||
: `${dayName} Night`;
|
||||
}
|
||||
|
||||
// draw the map
|
||||
|
@ -182,9 +180,11 @@ class RegionalForecast extends WeatherDisplay {
|
|||
const { temperature } = period;
|
||||
fill.temp = temperature;
|
||||
|
||||
const { x, y } = period;
|
||||
|
||||
const elem = this.fillTemplate('location', fill);
|
||||
elem.style.left = `${period.x}px`;
|
||||
elem.style.top = `${period.y}px`;
|
||||
elem.style.left = `${x}px`;
|
||||
elem.style.top = `${y}px`;
|
||||
|
||||
return elem;
|
||||
});
|
||||
|
|
|
@ -45,9 +45,9 @@ class TravelForecast extends WeatherDisplay {
|
|||
name: city.Name,
|
||||
icon: getWeatherRegionalIconFromIconLink(forecast.properties.periods[todayShift].icon),
|
||||
};
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.error(`GetTravelWeather for ${city.Name} failed`);
|
||||
console.error(e.status, e.responseJSON);
|
||||
console.error(error.status, error.responseJSON);
|
||||
return { name: city.Name, error: true };
|
||||
}
|
||||
});
|
||||
|
@ -77,10 +77,9 @@ class TravelForecast extends WeatherDisplay {
|
|||
|
||||
const lines = cities.map((city) => {
|
||||
if (city.error) return false;
|
||||
const fillValues = {};
|
||||
|
||||
// city name
|
||||
fillValues.city = city;
|
||||
const fillValues = {
|
||||
city,
|
||||
};
|
||||
|
||||
// check for forecast data
|
||||
if (city.icon) {
|
||||
|
@ -94,8 +93,9 @@ class TravelForecast extends WeatherDisplay {
|
|||
|
||||
fillValues.low = lowString;
|
||||
fillValues.high = highString;
|
||||
const { icon } = city;
|
||||
|
||||
fillValues.icon = { type: 'img', src: city.icon };
|
||||
fillValues.icon = { type: 'img', src: icon };
|
||||
} else {
|
||||
fillValues.error = 'NO TRAVEL DATA AVAILABLE';
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const fetchAsync = async (_url, responseType, _params = {}) => {
|
|||
if (params.cors === true) corsUrl = rewriteUrl(_url);
|
||||
const url = new URL(corsUrl, `${window.location.origin}/`);
|
||||
// match the security protocol when not on localhost
|
||||
url.protocol = window.location.hostname !== 'localhost' ? window.location.protocol : url.protocol;
|
||||
url.protocol = window.location.hostname === 'localhost' ? url.protocol : window.location.protocol;
|
||||
// add parameters if necessary
|
||||
if (params.data) {
|
||||
Object.keys(params.data).forEach((key) => {
|
||||
|
@ -73,7 +73,7 @@ const doFetch = (url, params) => new Promise((resolve, reject) => {
|
|||
// out of retries
|
||||
return resolve(response);
|
||||
})
|
||||
.catch((e) => reject(e));
|
||||
.catch((error) => reject(error));
|
||||
});
|
||||
|
||||
const delay = (time, func, ...args) => new Promise((resolve) => {
|
||||
|
@ -87,8 +87,8 @@ const retryDelay = (retryNumber) => {
|
|||
case 1: return 1000;
|
||||
case 2: return 2000;
|
||||
case 3: return 5000;
|
||||
case 4: return 10000;
|
||||
default: return 30000;
|
||||
case 4: return 10_000;
|
||||
default: return 30_000;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@ const locationCleanup = (input) => {
|
|||
// regexes to run
|
||||
const regexes = [
|
||||
// "Chicago / West Chicago", removes before slash
|
||||
/^[A-Za-z ]+ \/ /,
|
||||
/^[ A-Za-z]+ \/ /,
|
||||
// "Chicago/Waukegan" removes before slash
|
||||
/^[A-Za-z ]+\//,
|
||||
/^[ A-Za-z]+\//,
|
||||
// "Chicago, Chicago O'hare" removes before comma
|
||||
/^[A-Za-z ]+, /,
|
||||
/^[ A-Za-z]+, /,
|
||||
];
|
||||
|
||||
// run all regexes
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
const round2 = (value, decimals) => Math.trunc(value * 10 ** decimals) / 10 ** decimals;
|
||||
|
||||
const kphToMph = (Kph) => Math.round(Kph / 1.60934);
|
||||
const kphToMph = (Kph) => Math.round(Kph / 1.609_34);
|
||||
const celsiusToFahrenheit = (Celsius) => Math.round((Celsius * 9) / 5 + 32);
|
||||
const kilometersToMiles = (Kilometers) => Math.round(Kilometers / 1.60934);
|
||||
const kilometersToMiles = (Kilometers) => Math.round(Kilometers / 1.609_34);
|
||||
const metersToFeet = (Meters) => Math.round(Meters / 0.3048);
|
||||
const pascalToInHg = (Pascal) => round2(Pascal * 0.0002953, 2);
|
||||
const pascalToInHg = (Pascal) => round2(Pascal * 0.000_295_3, 2);
|
||||
|
||||
export {
|
||||
kphToMph,
|
||||
|
|
|
@ -3,9 +3,9 @@ import { json } from './fetch.mjs';
|
|||
const getPoint = async (lat, lon) => {
|
||||
try {
|
||||
return await json(`https://api.weather.gov/points/${lat},${lon}`);
|
||||
} catch (e) {
|
||||
} catch (error) {
|
||||
console.log(`Unable to get point ${lat}, ${lon}`);
|
||||
console.error(e);
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -53,11 +53,7 @@ class WeatherDisplay {
|
|||
// get the saved status of the checkbox
|
||||
let savedStatus = window.localStorage.getItem(`display-enabled: ${this.elemId}`);
|
||||
if (savedStatus === null) savedStatus = defaultEnabled;
|
||||
if (savedStatus === 'true' || savedStatus === true) {
|
||||
this.isEnabled = true;
|
||||
} else {
|
||||
this.isEnabled = false;
|
||||
}
|
||||
this.isEnabled = !!((savedStatus === 'true' || savedStatus === true));
|
||||
|
||||
// refresh (or initially store the state of the checkbox)
|
||||
window.localStorage.setItem(`display-enabled: ${this.elemId}`, this.isEnabled);
|
||||
|
@ -253,17 +249,13 @@ class WeatherDisplay {
|
|||
if (nextScreenIndex === this.screenIndex) return;
|
||||
|
||||
// test for -1 (no screen displayed yet)
|
||||
if (nextScreenIndex === -1) {
|
||||
this.screenIndex = 0;
|
||||
} else {
|
||||
this.screenIndex = nextScreenIndex;
|
||||
}
|
||||
this.screenIndex = nextScreenIndex === -1 ? 0 : nextScreenIndex;
|
||||
|
||||
// call the appropriate screen index change method
|
||||
if (!this.screenIndexChange) {
|
||||
await this.drawCanvas();
|
||||
} else {
|
||||
if (this.screenIndexChange) {
|
||||
this.screenIndexChange(this.screenIndex);
|
||||
} else {
|
||||
await this.drawCanvas();
|
||||
}
|
||||
this.showCanvas();
|
||||
}
|
||||
|
@ -377,7 +369,7 @@ class WeatherDisplay {
|
|||
|
||||
loadTemplates() {
|
||||
this.templates = {};
|
||||
this.elem = document.getElementById(`${this.elemId}-html`);
|
||||
this.elem = document.querySelector(`#${this.elemId}-html`);
|
||||
if (!this.elem) return;
|
||||
const templates = this.elem.querySelectorAll('.template');
|
||||
templates.forEach((template) => {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"Pngs",
|
||||
"PRECIP",
|
||||
"rtrim",
|
||||
"sonarjs",
|
||||
"T",
|
||||
"T'storm",
|
||||
"uscomp",
|
||||
|
|
Loading…
Reference in a new issue