import { db, type Database } from '$lib/db'; import { liveQuery } from 'dexie'; import { defaultBasemap, defaultBasemapTree, defaultOpacities, defaultOverlays, defaultOverlayTree, defaultOverpassQueries, defaultOverpassTree, type CustomLayer, } from '$lib/assets/layers'; import { browser } from '$app/environment'; export class Setting { private _db: Database; private _key: string; private _value: V; constructor(db: Database, key: string, initial: V) { this._db = db; this._key = key; this._value = $state(initial); let first = true; liveQuery(() => db.settings.get(key)).subscribe((value) => { if (value === undefined) { if (!first) { this._value = value; } } else { this._value = value; } first = false; }); } get value(): V { return this._value; } set value(newValue: V) { if (newValue !== this._value) { this._db.settings.put(newValue, this._key); } } } export class SettingInitOnFirstRead { private _db: Database; private _key: string; private _value: V | undefined; constructor(db: Database, key: string, initial: V) { this._db = db; this._key = key; this._value = $state(undefined); let first = true; liveQuery(() => db.settings.get(key)).subscribe((value) => { if (value === undefined) { if (first) { this._value = initial; } else { this._value = value; } } else { this._value = value; } first = false; }); } get value(): V | undefined { return this._value; } set value(newValue: V) { if (newValue !== this._value) { this._db.settings.put(newValue, this._key); } } } export const settings = { distanceUnits: new Setting<'metric' | 'imperial' | 'nautical'>(db, 'distanceUnits', 'metric'), velocityUnits: new Setting<'speed' | 'pace'>(db, 'velocityUnits', 'speed'), temperatureUnits: new Setting<'celsius' | 'fahrenheit'>(db, 'temperatureUnits', 'celsius'), elevationProfile: new Setting(db, 'elevationProfile', true), additionalDatasets: new Setting(db, 'additionalDatasets', []), elevationFill: new Setting<'slope' | 'surface' | undefined>(db, 'elevationFill', undefined), treeFileView: new Setting(db, 'fileView', false), minimizeRoutingMenu: new Setting(db, 'minimizeRoutingMenu', false), routing: new Setting(db, 'routing', true), routingProfile: new Setting(db, 'routingProfile', 'bike'), privateRoads: new Setting(db, 'privateRoads', false), currentBasemap: new Setting(db, 'currentBasemap', defaultBasemap), previousBasemap: new Setting(db, 'previousBasemap', defaultBasemap), selectedBasemapTree: new Setting(db, 'selectedBasemapTree', defaultBasemapTree), currentOverlays: new SettingInitOnFirstRead(db, 'currentOverlays', defaultOverlays), previousOverlays: new Setting(db, 'previousOverlays', defaultOverlays), selectedOverlayTree: new Setting(db, 'selectedOverlayTree', defaultOverlayTree), currentOverpassQueries: new SettingInitOnFirstRead( db, 'currentOverpassQueries', defaultOverpassQueries ), selectedOverpassTree: new Setting(db, 'selectedOverpassTree', defaultOverpassTree), opacities: new Setting(db, 'opacities', defaultOpacities), customLayers: new Setting>(db, 'customLayers', {}), customBasemapOrder: new Setting(db, 'customBasemapOrder', []), customOverlayOrder: new Setting(db, 'customOverlayOrder', []), directionMarkers: new Setting(db, 'directionMarkers', false), distanceMarkers: new Setting(db, 'distanceMarkers', false), streetViewSource: new Setting(db, 'streetViewSource', 'mapillary'), fileOrder: new Setting(db, 'fileOrder', []), defaultOpacity: new Setting(db, 'defaultOpacity', 0.7), defaultWidth: new Setting(db, 'defaultWidth', browser && window.innerWidth < 600 ? 8 : 5), bottomPanelSize: new Setting(db, 'bottomPanelSize', 170), rightPanelSize: new Setting(db, 'rightPanelSize', 240), };