mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
fix: improve mapped installations and map-source guidance (#183)
Improve mapped installation recovery, deselection, retry feedback, and visual-style and map-source guidance.
This commit is contained in:
1 parent
3b6b3f1007
commit
759652207f
25 files changed
+479
-41
No files matched your search
+37
-5
@@ -1,3 +1,5 @@
|
||||
import { installationFeedback } from './data/installationFeedback.js';
|
||||
|
||||
export const LOADING_REVEAL_DELAY_MS = 160;
|
||||
export const LOADING_TERMINAL_DWELL_MS = 2200;
|
||||
export const LOADING_FAILURE_DWELL_MS = 5000;
|
||||
@@ -17,10 +19,11 @@ export function normalizeLayerLoading(layer = {}) {
|
||||
const disabling = lifecycleState === 'disabling';
|
||||
const loading = lifecycleState === 'enabling' || disabling || stats.loading === true || stats.refreshing === true;
|
||||
const count = finiteCount(stats.count);
|
||||
const error = stats.error || stats.lastError || stats.managerRefreshError || null;
|
||||
const unavailable = stats.unavailable === true
|
||||
const stoppingInstallations = layer.id === 'military-installations' && disabling;
|
||||
const error = stoppingInstallations ? null : stats.error || stats.lastError || stats.managerRefreshError || null;
|
||||
const unavailable = !stoppingInstallations && (stats.unavailable === true
|
||||
|| stats.available === false
|
||||
|| ['unavailable', 'offline', 'down', 'error'].includes(status);
|
||||
|| ['unavailable', 'offline', 'down', 'error'].includes(status));
|
||||
const keyRequired = stats.keyRequired === true || stats.missingKey === true;
|
||||
const degraded = stats.degraded === true || Boolean(error);
|
||||
const accepted = Boolean(stats.lastUpdate) || count > 0;
|
||||
@@ -37,6 +40,10 @@ export function normalizeLayerLoading(layer = {}) {
|
||||
unavailable,
|
||||
keyRequired,
|
||||
degraded,
|
||||
installationRetry: layer.id === 'military-installations' && layer.enabled && !disabling
|
||||
? { retryAt: Number(stats.retryAt) || 0, retrying: stats.retrying === true,
|
||||
failureReason: stats.failureReason, loading, status: stats.status }
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -129,7 +136,7 @@ export function canPresentDeferredStatusNotice(expectedGeneration, currentGenera
|
||||
*/
|
||||
export function presentGlobalLoadingStatus(notice, loadingState, summary, nowMs = 0) {
|
||||
const loadingPresentation = presentLoadingFeedback(loadingState, summary, nowMs);
|
||||
if (loadingPresentation?.state === 'error') return loadingPresentation;
|
||||
if (['error', 'retry'].includes(loadingPresentation?.state)) return loadingPresentation;
|
||||
return presentGlobalStatusNotice(notice, nowMs) || loadingPresentation;
|
||||
}
|
||||
|
||||
@@ -244,6 +251,10 @@ export function reduceLoadingFeedback(previous, summary, nowMs, event = null) {
|
||||
batchOutcome,
|
||||
terminal: null,
|
||||
operation: summary.disabling ? 'disabling' : summary.refresh ? 'refresh' : 'loading',
|
||||
failedEventIds: [...new Set([
|
||||
...(beginning ? [] : state.failedEventIds || []),
|
||||
...(eventParticipates && terminalFromEvent(event) === 'error' ? [eventLayerId] : []),
|
||||
])],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -267,6 +278,10 @@ export function reduceLoadingFeedback(previous, summary, nowMs, event = null) {
|
||||
hideAt: now + dwell,
|
||||
batchOutcome: terminal,
|
||||
terminal,
|
||||
failedEventIds: [...new Set([
|
||||
...(state.failedEventIds || []),
|
||||
...(eventParticipates && terminalFromEvent(event) === 'error' ? [eventLayerId] : []),
|
||||
])],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -276,15 +291,32 @@ export function reduceLoadingFeedback(previous, summary, nowMs, event = null) {
|
||||
|
||||
/** Build the user-facing status copy for the current loading state. */
|
||||
export function presentLoadingFeedback(state, summary, nowMs) {
|
||||
const site = summary.records.find(record => record.installationRetry?.retryAt > 0);
|
||||
const otherFailure = summary.records.some(record => record.id !== 'military-installations'
|
||||
&& (state?.activeIds || []).includes(record.id)
|
||||
&& (record.error || record.unavailable || record.keyRequired))
|
||||
|| (state?.failedEventIds || []).some(id => id !== 'military-installations');
|
||||
// Keep the actual retry visible between attempts, without hiding another
|
||||
// participant's failure or pretending that a scheduled retry is fetching.
|
||||
if (site && !summary.active.length && !otherFailure) {
|
||||
const message = installationFeedback(site.installationRetry);
|
||||
const [label, detail] = message.split(' — ');
|
||||
return { state: 'retry', label: label.toUpperCase(), detail: detail || '' };
|
||||
}
|
||||
if (!state?.visible) return null;
|
||||
if (state.phase === 'terminal') {
|
||||
const labels = { complete: 'LOAD COMPLETE', cancelled: 'LOAD CANCELLED', error: 'LOAD FAILED' };
|
||||
const label = state.operation === 'disabling' && state.terminal === 'complete'
|
||||
? 'LIVE DATA OFF'
|
||||
: labels[state.terminal] || 'LOAD COMPLETE';
|
||||
: state.terminal === 'complete' && state.activeIds?.length === 1 && state.activeIds[0] === 'military-installations'
|
||||
? 'MAPPED SITES LOADED' : labels[state.terminal] || 'LOAD COMPLETE';
|
||||
return { state: state.terminal, label, detail: '' };
|
||||
}
|
||||
const active = summary.active;
|
||||
if (active.length === 1 && active[0].installationRetry && !summary.disabling) {
|
||||
return { state: 'loading', label: active[0].installationRetry.retrying
|
||||
? 'RETRYING MAPPED SITES' : 'FETCHING MAPPED SITES', detail: 'OpenStreetMap · Overpass' };
|
||||
}
|
||||
const elapsed = Math.max(0, nowMs - state.startedAt);
|
||||
const label = summary.disabling
|
||||
? 'TURNING OFF LIVE DATA'
|
||||
|
||||
Reference in new issue
Block a user