Compare commits

...

7 Commits

Author SHA1 Message Date
Matt Walsh
407da90f8a 6.2.5 2025-10-21 04:15:53 +00:00
Matt Walsh
3a0e6aa345 Merge branch 'geolookup-latlongquery' 2025-10-21 04:15:38 +00:00
Matt Walsh
650dda7b61 allow for latLon only in query string #154 2025-10-21 04:12:21 +00:00
Matt Walsh
8f1e8ffb74 Merge branch 'rmitchellscott-static-redirect-index' 2025-10-21 03:26:25 +00:00
Mitchell Scott
93af84cbd8 fix: geolookup if only latLonQuery is provided 2025-10-20 13:37:18 -06:00
Mitchell Scott
117f66e9d0 fix(static builds): duplicate query params 2025-10-20 13:28:45 -06:00
Mitchell Scott
bca9376edc fix: nginx query parameter redirect works like node.js 2025-10-20 11:42:42 -06:00
5 changed files with 82 additions and 9 deletions

View File

@@ -10,8 +10,10 @@ server {
add_header X-Weatherstar true always;
include /etc/nginx/includes/wsqs_redirect.conf;
location / {
index redirect.html index.html index.htm;
index index.html index.htm;
try_files $uri $uri/ =404;
}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "ws4kp",
"version": "6.2.4",
"version": "6.2.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ws4kp",
"version": "6.2.4",
"version": "6.2.5",
"license": "MIT",
"dependencies": {
"dotenv": "^17.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "ws4kp",
"version": "6.2.4",
"version": "6.2.5",
"description": "Welcome to the WeatherStar 4000+ project page!",
"main": "index.mjs",
"type": "module",

View File

@@ -106,17 +106,34 @@ const init = async () => {
// attempt to parse the url parameters
const parsedParameters = parseQueryString();
const loadFromParsed = parsedParameters.latLonQuery && parsedParameters.latLon;
const loadFromParsed = !!parsedParameters.latLon;
// Auto load the parsed parameters and fall back to the previous query
const query = parsedParameters.latLonQuery ?? localStorage.getItem('latLonQuery');
const latLon = parsedParameters.latLon ?? localStorage.getItem('latLon');
const fromGPS = localStorage.getItem('latLonFromGPS') && !loadFromParsed;
if (query && latLon && !fromGPS) {
if (parsedParameters.latLonQuery && !parsedParameters.latLon) {
const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR);
txtAddress.value = query;
loadData(JSON.parse(latLon));
txtAddress.value = parsedParameters.latLonQuery;
const geometry = await geocodeLatLonQuery(parsedParameters.latLonQuery);
if (geometry) {
doRedirectToGeometry(geometry);
}
} else if (latLon && !fromGPS) {
// update in-page search box if using cached data, or parsed parameter
if ((query && !loadFromParsed) || (parsedParameters.latLonQuery && loadFromParsed)) {
const txtAddress = document.querySelector(TXT_ADDRESS_SELECTOR);
txtAddress.value = query;
}
// use lat-long lookup if that's all that was provided in the query string
if (loadFromParsed && parsedParameters.latLon && !parsedParameters.latLonQuery) {
const { lat, lon } = JSON.parse(latLon);
getForecastFromLatLon(lat, lon, true);
} else {
// otherwise use pre-stored data
loadData(JSON.parse(latLon));
}
}
if (fromGPS) {
btnGetGpsClick();
@@ -162,6 +179,26 @@ const init = async () => {
document.querySelector('#container').addEventListener('swiped-right', () => swipeCallBack('right'));
};
const geocodeLatLonQuery = async (query) => {
try {
const data = await json('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find', {
data: {
text: query,
f: 'json',
},
});
const loc = data.locations?.[0];
if (loc) {
return loc.feature.geometry;
}
return null;
} catch (error) {
console.error('Geocoding failed:', error);
return null;
}
};
const autocompleteOnSelect = async (suggestion) => {
// Note: it's fine that this uses json instead of safeJson since it's infrequent and user-initiated
const data = await json('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find', {

View File

@@ -12,6 +12,9 @@ url_encode() {
# build query string from WSQS_ env vars
while IFS='=' read -r key val; do
# Skip empty lines
[ -z "$key" ] && continue
# Remove WSQS_ prefix and convert underscores to hyphens
key="${key#WSQS_}"
key="${key//_/-}"
@@ -23,11 +26,16 @@ while IFS='=' read -r key val; do
QS="${key}=${encoded_val}"
fi
done << EOF
$(env | grep '^WSQS_')
$(env | grep '^WSQS_' || true)
EOF
mkdir -p /etc/nginx/includes
if [ -n "$QS" ]; then
# Escape the query string for use in JavaScript (escape backslashes and single quotes)
QS_ESCAPED=$(printf '%s' "$QS" | sed "s/\\\\/\\\\\\\\/g; s/'/\\\'/g")
# Generate redirect.html with JavaScript logic
cat > "$ROOT/redirect.html" <<EOF
<!DOCTYPE html>
<html>
@@ -35,10 +43,36 @@ if [ -n "$QS" ]; then
<meta charset="utf-8" />
<title>Redirecting</title>
<meta http-equiv="refresh" content="0;url=/index.html?$QS" />
<script>
(function() {
var wsqsParams = '$QS_ESCAPED';
var currentParams = window.location.search.substring(1);
var targetParams = currentParams || wsqsParams;
window.location.replace('/index.html?' + targetParams);
})();
</script>
</head>
<body></body>
</html>
EOF
# Generate nginx config for conditional redirects
cat > /etc/nginx/includes/wsqs_redirect.conf <<'EOF'
location = / {
if ($args = '') {
rewrite ^ /redirect.html last;
}
rewrite ^/$ /index.html?$args? redirect;
}
location = /index.html {
if ($args = '') {
rewrite ^ /redirect.html last;
}
}
EOF
else
touch /etc/nginx/includes/wsqs_redirect.conf
fi
exec nginx -g 'daemon off;'