Add Ambient station primary source toggle; swap location name to station
When configured, a new "Use as primary source" toggle appears in Settings under Ambient Weather Station (defaults on). When on, the location header shows the station name and "Ambient Weather Station" subtitle instead of the city; the hero badge is hidden as redundant. Toggling off restores the city name immediately and re-shows the hero badge. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d2e36d9fa
commit
9620c1b0cd
2 files changed
+59
-6
No files matched your search
+52
-6
@@ -302,6 +302,7 @@ const STORAGE_KEYS = {
|
|||||||
pwsUrl: 'weather.pwsUrl',
|
pwsUrl: 'weather.pwsUrl',
|
||||||
ambientApiKey: 'weather.ambientApiKey',
|
ambientApiKey: 'weather.ambientApiKey',
|
||||||
ambientAppKey: 'weather.ambientAppKey',
|
ambientAppKey: 'weather.ambientAppKey',
|
||||||
|
ambientUseStation: 'weather.ambientUseStation',
|
||||||
alertIdsSeen: 'weather.alertIdsSeen',
|
alertIdsSeen: 'weather.alertIdsSeen',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -348,6 +349,7 @@ const state = {
|
|||||||
pwsUrl: localStorage.getItem(STORAGE_KEYS.pwsUrl) || '',
|
pwsUrl: localStorage.getItem(STORAGE_KEYS.pwsUrl) || '',
|
||||||
ambientApiKey: localStorage.getItem(STORAGE_KEYS.ambientApiKey) || '',
|
ambientApiKey: localStorage.getItem(STORAGE_KEYS.ambientApiKey) || '',
|
||||||
ambientAppKey: localStorage.getItem(STORAGE_KEYS.ambientAppKey) || '',
|
ambientAppKey: localStorage.getItem(STORAGE_KEYS.ambientAppKey) || '',
|
||||||
|
ambientUseStation: localStorage.getItem(STORAGE_KEYS.ambientUseStation) !== 'false',
|
||||||
ambientDevice: null,
|
ambientDevice: null,
|
||||||
pushSub: null,
|
pushSub: null,
|
||||||
hourlyExtended: false,
|
hourlyExtended: false,
|
||||||
@@ -2696,6 +2698,8 @@ if (ambientSaveBtn) {
|
|||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
const stationName = devices?.[0]?.info?.name || devices?.[0]?.macAddress || 'station';
|
const stationName = devices?.[0]?.info?.name || devices?.[0]?.macAddress || 'station';
|
||||||
if (ambientStatusEl) { ambientStatusEl.textContent = `✓ Connected to ${stationName} — saved for all devices`; show(ambientStatusEl); }
|
if (ambientStatusEl) { ambientStatusEl.textContent = `✓ Connected to ${stationName} — saved for all devices`; show(ambientStatusEl); }
|
||||||
|
const useRow = document.getElementById('ambient-use-row');
|
||||||
|
if (useRow) useRow.style.display = '';
|
||||||
fetchAmbientStation();
|
fetchAmbientStation();
|
||||||
} else {
|
} else {
|
||||||
const { error } = await res.json().catch(() => ({}));
|
const { error } = await res.json().catch(() => ({}));
|
||||||
@@ -2714,8 +2718,46 @@ fetch('/api/ambient-config').then(r => r.json()).then(({ configured }) => {
|
|||||||
if (ambientStatusEl) { ambientStatusEl.textContent = '✓ Keys configured on server'; show(ambientStatusEl); }
|
if (ambientStatusEl) { ambientStatusEl.textContent = '✓ Keys configured on server'; show(ambientStatusEl); }
|
||||||
fetchAmbientStation();
|
fetchAmbientStation();
|
||||||
}
|
}
|
||||||
|
if (configured || state.ambientApiKey) {
|
||||||
|
const useRow = document.getElementById('ambient-use-row');
|
||||||
|
if (useRow) useRow.style.display = '';
|
||||||
|
}
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
|
|
||||||
|
// ── Ambient "use as primary source" toggle ────────────────────────────────────
|
||||||
|
const ambientUseToggle = document.getElementById('ambient-use-toggle');
|
||||||
|
if (ambientUseToggle) {
|
||||||
|
ambientUseToggle.checked = state.ambientUseStation;
|
||||||
|
ambientUseToggle.addEventListener('change', () => {
|
||||||
|
state.ambientUseStation = ambientUseToggle.checked;
|
||||||
|
localStorage.setItem(STORAGE_KEYS.ambientUseStation, state.ambientUseStation);
|
||||||
|
if (state.ambientUseStation) {
|
||||||
|
// Re-apply station overlay immediately
|
||||||
|
if (state.ambientDevice) applyStationOverlay(state.ambientDevice);
|
||||||
|
} else {
|
||||||
|
// Restore location name from current city
|
||||||
|
if (state.currentCity) {
|
||||||
|
const locNameEl = document.getElementById('loc-name');
|
||||||
|
const locSubEl = document.getElementById('loc-sub');
|
||||||
|
if (locNameEl) locNameEl.textContent = state.currentCity.name;
|
||||||
|
if (locSubEl) locSubEl.textContent = [state.currentCity.admin1, state.currentCity.country].filter(Boolean).join(', ');
|
||||||
|
}
|
||||||
|
// Show station badge so user knows station is still fetching but not overriding
|
||||||
|
if (state.ambientDevice) {
|
||||||
|
const badge = document.getElementById('station-badge');
|
||||||
|
const badgeName = document.getElementById('station-badge-name');
|
||||||
|
if (badge) { if (badgeName) badgeName.textContent = state.ambientDevice.info?.name || 'My Station'; show(badge); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show toggle row if keys are already saved locally
|
||||||
|
if (state.ambientApiKey && state.ambientAppKey) {
|
||||||
|
const useRow = document.getElementById('ambient-use-row');
|
||||||
|
if (useRow) useRow.style.display = '';
|
||||||
|
}
|
||||||
|
|
||||||
const pwsUrlInput = document.getElementById('pws-url-input');
|
const pwsUrlInput = document.getElementById('pws-url-input');
|
||||||
const pwsSaveBtn = document.getElementById('pws-save-btn');
|
const pwsSaveBtn = document.getElementById('pws-save-btn');
|
||||||
const pwsStatusEl = document.getElementById('pws-status');
|
const pwsStatusEl = document.getElementById('pws-status');
|
||||||
@@ -2879,6 +2921,7 @@ async function fetchAmbientStation() {
|
|||||||
|
|
||||||
function applyStationOverlay(device) {
|
function applyStationOverlay(device) {
|
||||||
if (!device) return;
|
if (!device) return;
|
||||||
|
if (!state.ambientUseStation) return;
|
||||||
const data = device.lastData || {};
|
const data = device.lastData || {};
|
||||||
if (!data.dateutc || Date.now() - data.dateutc > 15 * 60 * 1000) return; // stale > 15 min
|
if (!data.dateutc || Date.now() - data.dateutc > 15 * 60 * 1000) return; // stale > 15 min
|
||||||
|
|
||||||
@@ -2948,13 +2991,16 @@ function applyStationOverlay(device) {
|
|||||||
peekEl.textContent = `· ${fS(data.windspeedmph)} ${speedUnit()} ${compassDir(data.winddir || 0)} · ${data.humidity ?? '--'}% humidity`;
|
peekEl.textContent = `· ${fS(data.windspeedmph)} ${speedUnit()} ${compassDir(data.winddir || 0)} · ${data.humidity ?? '--'}% humidity`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Station badge
|
// Replace location name with station name
|
||||||
|
const stationName = device.info?.name || device.macAddress || 'My Station';
|
||||||
|
const locNameEl = document.getElementById('loc-name');
|
||||||
|
const locSubEl = document.getElementById('loc-sub');
|
||||||
|
if (locNameEl) locNameEl.textContent = stationName;
|
||||||
|
if (locSubEl) locSubEl.textContent = 'Ambient Weather Station';
|
||||||
|
|
||||||
|
// Hide the hero badge (redundant — location header now identifies the station)
|
||||||
const badge = document.getElementById('station-badge');
|
const badge = document.getElementById('station-badge');
|
||||||
const badgeName = document.getElementById('station-badge-name');
|
if (badge) hide(badge);
|
||||||
if (badge) {
|
|
||||||
if (badgeName) badgeName.textContent = device.info?.name || 'My Station';
|
|
||||||
show(badge);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAmbientStation(device) {
|
function renderAmbientStation(device) {
|
||||||
|
|||||||
@@ -601,6 +601,13 @@
|
|||||||
<p class="settings-help">From ambientweather.net → Account → API Keys. Keys are stored locally in your browser.</p>
|
<p class="settings-help">From ambientweather.net → Account → API Keys. Keys are stored locally in your browser.</p>
|
||||||
<p id="ambient-status" class="settings-help hidden"></p>
|
<p id="ambient-status" class="settings-help hidden"></p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="settings-row" id="ambient-use-row" style="display:none">
|
||||||
|
<span class="settings-label">Use as primary source</span>
|
||||||
|
<label class="switch-toggle">
|
||||||
|
<input id="ambient-use-toggle" type="checkbox" checked>
|
||||||
|
<span class="toggle-slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="settings-section-title">Personal Weather Station</div>
|
<div class="settings-section-title">Personal Weather Station</div>
|
||||||
<div class="settings-row settings-row--block">
|
<div class="settings-row settings-row--block">
|
||||||
|
|||||||
Reference in new issue
Block a user