Add NearestStations Card & Location monitor
This commit is contained in:
90
src/lib/geohash.svelte.ts
Normal file
90
src/lib/geohash.svelte.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { OwlClient, ValidationError, ApiError } from './owlClient';
|
||||
import type { ApiStationsNearestStations } from '@owlboard/owlboard-ts';
|
||||
|
||||
class NearestStationsState {
|
||||
list = $state<ApiStationsNearestStations.StationsNearestStations[]>([]);
|
||||
currentHash = $state('');
|
||||
loading = $state(true);
|
||||
error = $state<string | null>(null);
|
||||
|
||||
private geoConfig: PositionOptions = {
|
||||
enableHighAccuracy: false,
|
||||
timeout: 30000,
|
||||
maximumAge: 120000
|
||||
};
|
||||
|
||||
constructor() {
|
||||
if (typeof window !== 'undefined' && 'geolocation' in navigator) {
|
||||
this.jumpstart();
|
||||
this.initWatcher();
|
||||
}
|
||||
}
|
||||
|
||||
private jumpstart() {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(pos) => this.handleUpdate(pos.coords.latitude, pos.coords.longitude),
|
||||
(err) => this.handleError(err),
|
||||
this.geoConfig
|
||||
);
|
||||
}
|
||||
|
||||
private initWatcher() {
|
||||
navigator.geolocation.watchPosition(
|
||||
(pos) => this.handleUpdate(pos.coords.latitude, pos.coords.longitude),
|
||||
(err) => this.handleError(err),
|
||||
this.geoConfig
|
||||
);
|
||||
}
|
||||
|
||||
private async handleUpdate(lat: number, lon: number) {
|
||||
const newHash = OwlClient.stationData.generateGeohash(lat, lon);
|
||||
if (newHash !== this.currentHash) {
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
const result = await OwlClient.stationData.getNearestStations(newHash);
|
||||
this.list = result.data;
|
||||
this.error = null;
|
||||
this.currentHash = newHash;
|
||||
} catch (e) {
|
||||
this.handleApiError(e);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleError(err: GeolocationPositionError) {
|
||||
if (err.code === 1) {
|
||||
this.error = 'Location access denied by device';
|
||||
} else {
|
||||
this.error = 'Waiting for GPS signal...';
|
||||
}
|
||||
}
|
||||
|
||||
private handleApiError(e: unknown) {
|
||||
if (e instanceof ValidationError) {
|
||||
this.error = `Request Error: ${e.reason} (Field: ${e.field})`;
|
||||
} else if (e instanceof ApiError) {
|
||||
switch (e.status) {
|
||||
case 404:
|
||||
this.error = 'No stations found nearby';
|
||||
break;
|
||||
case 429:
|
||||
this.error = 'Too many requests, will retry';
|
||||
break;
|
||||
case 500:
|
||||
this.error = 'Server Error, will retry';
|
||||
break;
|
||||
default:
|
||||
this.error = `Service error: ${e.code}`;
|
||||
}
|
||||
} else {
|
||||
this.error = 'Connection lost, waiting for signal';
|
||||
}
|
||||
|
||||
console.error('OwlBoard API Error:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export const nearestStationsState = new NearestStationsState();
|
||||
Reference in New Issue
Block a user