mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-15 08:09:31 -07:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52487319fa | ||
|
|
6a1e2da11e | ||
|
|
1cf9f41ca0 | ||
|
|
f7505e3e6f | ||
|
|
705fa9f582 | ||
|
|
5edf5cc947 | ||
|
|
d0382e0de1 | ||
|
|
69d14236f1 | ||
|
|
64fb06d7b4 |
2
dist/index.html
vendored
2
dist/index.html
vendored
File diff suppressed because one or more lines are too long
2
dist/resources/ws.min.css
vendored
2
dist/resources/ws.min.css
vendored
File diff suppressed because one or more lines are too long
2
dist/resources/ws.min.js
vendored
2
dist/resources/ws.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -142,6 +142,18 @@ gulp.task('upload', () => gulp.src(uploadSources, { base: './dist' })
|
||||
},
|
||||
})));
|
||||
|
||||
const imageSources = [
|
||||
'server/fonts/**',
|
||||
'server/images/**',
|
||||
];
|
||||
gulp.task('upload_images', () => gulp.src(imageSources, { base: './server' })
|
||||
.pipe(
|
||||
s3({
|
||||
Bucket: 'weatherstar',
|
||||
StorageClass: 'STANDARD',
|
||||
}),
|
||||
));
|
||||
|
||||
gulp.task('invalidate', async () => cloudfront.createInvalidation({
|
||||
DistributionId: 'E9171A4KV8KCW',
|
||||
InvalidationBatch: {
|
||||
@@ -153,4 +165,4 @@ gulp.task('invalidate', async () => cloudfront.createInvalidation({
|
||||
},
|
||||
}).promise());
|
||||
|
||||
module.exports = gulp.series(clean, gulp.parallel('build_js', 'compress_js_data', 'compress_js_vendor', 'copy_css', 'compress_html', 'copy_other_files'), 'upload', 'invalidate');
|
||||
module.exports = gulp.series(clean, gulp.parallel('build_js', 'compress_js_data', 'compress_js_vendor', 'copy_css', 'compress_html', 'copy_other_files'), gulp.parallel('upload', 'upload_images'), 'invalidate');
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ws4kp",
|
||||
"version": "5.3.0",
|
||||
"version": "5.4.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ws4kp",
|
||||
"version": "5.3.0",
|
||||
"version": "5.4.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eslint": "^8.21.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ws4kp",
|
||||
"version": "5.3.0",
|
||||
"version": "5.4.1",
|
||||
"description": "Welcome to the WeatherStar 4000+ project page!",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
BIN
server/images/nav/ic_gps_fixed_white_18dp_1x.png
Normal file
BIN
server/images/nav/ic_gps_fixed_white_18dp_1x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
server/images/nav/ic_gps_fixed_white_18dp_2x.png
Normal file
BIN
server/images/nav/ic_gps_fixed_white_18dp_2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
BIN
server/images/nav/ic_gps_fixed_white_24dp_1x.png
Normal file
BIN
server/images/nav/ic_gps_fixed_white_24dp_1x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
BIN
server/images/nav/ic_gps_fixed_whte_24dp_2x.png
Normal file
BIN
server/images/nav/ic_gps_fixed_whte_24dp_2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
@@ -23,7 +23,7 @@ const categories = [
|
||||
'Airport', 'Ferry', 'Marina', 'Pier', 'Port', 'Resort', // POI/Travel
|
||||
'Postal', 'Populated Place',
|
||||
];
|
||||
const cats = categories.join(',');
|
||||
const category = categories.join(',');
|
||||
|
||||
const init = () => {
|
||||
document.getElementById('txtAddress').addEventListener('focus', (e) => {
|
||||
@@ -54,7 +54,7 @@ const init = () => {
|
||||
params: {
|
||||
f: 'json',
|
||||
countryCode: 'USA', // 'USA,PRI,VIR,GUM,ASM',
|
||||
category: cats,
|
||||
category,
|
||||
maxSuggestions: 10,
|
||||
},
|
||||
dataType: 'json',
|
||||
|
||||
@@ -55,7 +55,9 @@ class CurrentWeather extends WeatherDisplay {
|
||||
// test for data received
|
||||
if (!observations) {
|
||||
console.error('All current weather stations exhausted');
|
||||
this.setStatus(STATUS.failed);
|
||||
if (this.enabled) this.setStatus(STATUS.failed);
|
||||
// send failed to subscribers
|
||||
this.getDataCallback(undefined);
|
||||
return;
|
||||
}
|
||||
// preload the icon
|
||||
|
||||
@@ -28,6 +28,10 @@ class HourlyGraph extends WeatherDisplay {
|
||||
if (!super.getData()) return;
|
||||
|
||||
const data = await getHourlyData();
|
||||
if (data === undefined) {
|
||||
this.setStatus(STATUS.failed);
|
||||
return;
|
||||
}
|
||||
|
||||
// get interesting data
|
||||
const temperature = data.map((d) => d.temperature);
|
||||
@@ -42,18 +46,20 @@ class HourlyGraph extends WeatherDisplay {
|
||||
}
|
||||
|
||||
drawCanvas() {
|
||||
if (!this.canvas) this.canvas = this.elem.querySelector('.chart canvas');
|
||||
if (!this.image) this.image = this.elem.querySelector('.chart img');
|
||||
|
||||
// get available space
|
||||
const boundingRect = this.canvas.getBoundingClientRect();
|
||||
const availableWidth = boundingRect.width;
|
||||
const availableHeight = boundingRect.height;
|
||||
const availableWidth = 532;
|
||||
const availableHeight = 285;
|
||||
|
||||
this.canvas.width = availableWidth;
|
||||
this.canvas.height = availableHeight;
|
||||
this.image.width = availableWidth;
|
||||
this.image.height = availableHeight;
|
||||
|
||||
// get context
|
||||
const ctx = this.canvas.getContext('2d');
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = availableWidth;
|
||||
canvas.height = availableHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
// calculate time scale
|
||||
@@ -93,9 +99,14 @@ class HourlyGraph extends WeatherDisplay {
|
||||
});
|
||||
|
||||
// temperature axis labels
|
||||
this.elem.querySelector('.y-axis .l-1').innerHTML = maxTemp;
|
||||
this.elem.querySelector('.y-axis .l-2').innerHTML = midTemp;
|
||||
this.elem.querySelector('.y-axis .l-3').innerHTML = minTemp;
|
||||
// limited to 3 characters, sacraficing degree character
|
||||
const degree = String.fromCharCode(176);
|
||||
this.elem.querySelector('.y-axis .l-1').innerHTML = (maxTemp + degree).substring(0, 3);
|
||||
this.elem.querySelector('.y-axis .l-2').innerHTML = (midTemp + degree).substring(0, 3);
|
||||
this.elem.querySelector('.y-axis .l-3').innerHTML = (minTemp + degree).substring(0, 3);
|
||||
|
||||
// set the image source
|
||||
this.image.src = canvas.toDataURL();
|
||||
|
||||
super.drawCanvas();
|
||||
this.finishDraw();
|
||||
|
||||
@@ -37,12 +37,13 @@ class Hourly extends WeatherDisplay {
|
||||
} catch (e) {
|
||||
console.error('Get hourly forecast failed');
|
||||
console.error(e.status, e.responseJSON);
|
||||
this.setStatus(STATUS.failed);
|
||||
if (this.enabled) this.setStatus(STATUS.failed);
|
||||
// return undefined to other subscribers
|
||||
this.getDataCallback(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
this.data = await Hourly.parseForecast(forecast.properties);
|
||||
|
||||
this.getDataCallback();
|
||||
if (!superResponse) return;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ let AutoRefreshCountMs = 0;
|
||||
const init = async () => {
|
||||
// set up resize handler
|
||||
window.addEventListener('resize', resize);
|
||||
resize();
|
||||
|
||||
// auto refresh
|
||||
const TwcAutoRefresh = localStorage.getItem('TwcAutoRefresh');
|
||||
@@ -251,11 +252,11 @@ const getDisplay = (index) => displays[index];
|
||||
|
||||
// resize the container on a page resize
|
||||
const resize = () => {
|
||||
const widthZoomPercent = window.innerWidth / 640;
|
||||
const heightZoomPercent = window.innerHeight / 480;
|
||||
const widthZoomPercent = document.body.clientWidth / 640;
|
||||
const heightZoomPercent = document.body.clientHeight / 480;
|
||||
|
||||
const scale = Math.min(widthZoomPercent, heightZoomPercent);
|
||||
|
||||
console.log(scale, document.body.clientWidth);
|
||||
if (scale < 1.0 || document.fullscreenElement) {
|
||||
document.getElementById('container').style.zoom = scale;
|
||||
} else {
|
||||
|
||||
@@ -367,8 +367,6 @@ class Radar extends WeatherDisplay {
|
||||
}
|
||||
|
||||
RadarContext.putImageData(RadarImageData, 0, 0);
|
||||
|
||||
// MapContext.drawImage(RadarContext.canvas, 0, 0);
|
||||
}
|
||||
|
||||
static mergeDopplerRadarImage(mapContext, radarContext) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -89,7 +89,7 @@
|
||||
top: 0px;
|
||||
left: 50px;
|
||||
|
||||
canvas {
|
||||
img {
|
||||
width: 532px;
|
||||
height: 285px;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,17 @@
|
||||
|
||||
body {
|
||||
font-family: "Star4000";
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
background-color: #000000;
|
||||
color: white;
|
||||
}
|
||||
|
||||
a {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
color: lightblue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input,
|
||||
@@ -20,12 +31,43 @@ button {
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
&.light {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.autocomplete-suggestions {
|
||||
@@ -90,6 +132,11 @@ button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background-color: #000000;
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
background-color: rgb(48, 48, 48);
|
||||
}
|
||||
|
||||
color: #ffffff;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
<meta name="keywords" content="WeatherStar 4000+" />
|
||||
<meta name="author" content="Matt Walsh" />
|
||||
<meta name="application-name" content="WeatherStar 4000+" />
|
||||
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1;maximum-scale=1;minimum-scale=1">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
@@ -61,7 +60,7 @@
|
||||
|
||||
<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 id="imgGetGps" src="images/nav/ic_gps_fixed_black_18dp_1x.png" /></button>
|
||||
<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>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="label l-3">55</div>
|
||||
</div>
|
||||
<div class="chart">
|
||||
<canvas id="chart-area"></canvas>
|
||||
<img id="chart-area"></img>
|
||||
</div>
|
||||
<div class="x-axis">
|
||||
<div class="label l-1">12a</div>
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
<div class="header">
|
||||
<div class="logo"><img src="images/Logo3.png" /></div>
|
||||
<div class="title dual">
|
||||
<div class="top">
|
||||
Local
|
||||
</div>
|
||||
<div class="bottom">
|
||||
Radar
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="precip">
|
||||
<div class="precip-header">PRECIP</div>
|
||||
<div class="scale">
|
||||
<div class="text">Light</div>
|
||||
<div class="scale-table">
|
||||
<div class="box box-1"></div>
|
||||
<div class="box box-2"></div>
|
||||
<div class="box box-3"></div>
|
||||
<div class="box box-4"></div>
|
||||
<div class="box box-5"></div>
|
||||
<div class="box box-6"></div>
|
||||
<div class="box box-7"></div>
|
||||
<div class="box box-7"></div>
|
||||
</div>
|
||||
<div class="text">Heavy</div>
|
||||
</div>
|
||||
<div class="time"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="logo"><img src="images/Logo3.png" /></div>
|
||||
<div class="title dual">
|
||||
<div class="top">
|
||||
Local
|
||||
</div>
|
||||
<div class="bottom">
|
||||
Radar
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="precip">
|
||||
<div class="precip-header">PRECIP</div>
|
||||
<div class="scale">
|
||||
<div class="text">Light</div>
|
||||
<div class="scale-table">
|
||||
<div class="box box-1"></div>
|
||||
<div class="box box-2"></div>
|
||||
<div class="box box-3"></div>
|
||||
<div class="box box-4"></div>
|
||||
<div class="box box-5"></div>
|
||||
<div class="box box-6"></div>
|
||||
<div class="box box-7"></div>
|
||||
<div class="box box-7"></div>
|
||||
</div>
|
||||
<div class="text">Heavy</div>
|
||||
</div>
|
||||
<div class="time"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main radar">
|
||||
<div class="container">
|
||||
<div class="scroll-area">
|
||||
<div class="frame template">
|
||||
<div class="map">
|
||||
<img src="images/4000RadarMap2.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="scroll-area">
|
||||
<div class="frame template">
|
||||
<div class="map">
|
||||
<img src="images/4000RadarMap2.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user