mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-12-03 02:12:12 +00:00
fix embedding + playground
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { db, type Database } from '$lib/db';
|
||||
import { type Database } from '$lib/db';
|
||||
import { liveQuery } from 'dexie';
|
||||
import {
|
||||
defaultBasemap,
|
||||
@@ -14,17 +14,22 @@ import { browser } from '$app/environment';
|
||||
import { get, writable, type Writable } from 'svelte/store';
|
||||
|
||||
export class Setting<V> {
|
||||
private _db: Database;
|
||||
private _db: Database | null = null;
|
||||
private _subscription: { unsubscribe: () => void } | null = null;
|
||||
private _key: string;
|
||||
private _value: Writable<V>;
|
||||
|
||||
constructor(db: Database, key: string, initial: V) {
|
||||
this._db = db;
|
||||
constructor(key: string, initial: V) {
|
||||
this._key = key;
|
||||
this._value = writable(initial);
|
||||
}
|
||||
|
||||
connectToDatabase(db: Database) {
|
||||
if (this._db) return;
|
||||
this._db = db;
|
||||
|
||||
let first = true;
|
||||
liveQuery(() => db.settings.get(key)).subscribe((value) => {
|
||||
this._subscription = liveQuery(() => db.settings.get(this._key)).subscribe((value) => {
|
||||
if (value === undefined) {
|
||||
if (!first) {
|
||||
this._value.set(value);
|
||||
@@ -36,39 +41,53 @@ export class Setting<V> {
|
||||
});
|
||||
}
|
||||
|
||||
disconnectFromDatabase() {
|
||||
this._subscription?.unsubscribe();
|
||||
this._subscription = null;
|
||||
this._db = null;
|
||||
}
|
||||
|
||||
subscribe(run: (value: V) => void, invalidate?: (value?: V) => void) {
|
||||
return this._value.subscribe(run, invalidate);
|
||||
}
|
||||
|
||||
set(newValue: V) {
|
||||
if (typeof newValue === 'object' || newValue !== get(this._value)) {
|
||||
this._db.settings.put(newValue, this._key);
|
||||
set(value: V) {
|
||||
if (typeof value === 'object' || value !== get(this._value)) {
|
||||
if (this._db) {
|
||||
this._db.settings.put(value, this._key);
|
||||
} else {
|
||||
this._value.set(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update(callback: (value: any) => any) {
|
||||
let newValue = callback(get(this._value));
|
||||
if (typeof newValue === 'object' || newValue !== get(this._value)) {
|
||||
this._db.settings.put(newValue, this._key);
|
||||
}
|
||||
this.set(callback(get(this._value)));
|
||||
}
|
||||
}
|
||||
|
||||
export class SettingInitOnFirstRead<V> {
|
||||
private _db: Database;
|
||||
private _db: Database | null = null;
|
||||
private _subscription: { unsubscribe: () => void } | null = null;
|
||||
private _key: string;
|
||||
private _value: Writable<V | undefined>;
|
||||
private _initial: V;
|
||||
|
||||
constructor(db: Database, key: string, initial: V) {
|
||||
this._db = db;
|
||||
constructor(key: string, initial: V) {
|
||||
this._key = key;
|
||||
this._value = writable(undefined);
|
||||
this._initial = initial;
|
||||
}
|
||||
|
||||
connectToDatabase(db: Database) {
|
||||
if (this._db) return;
|
||||
this._db = db;
|
||||
|
||||
let first = true;
|
||||
liveQuery(() => db.settings.get(key)).subscribe((value) => {
|
||||
this._subscription = liveQuery(() => db.settings.get(this._key)).subscribe((value) => {
|
||||
if (value === undefined) {
|
||||
if (first) {
|
||||
this._value.set(initial);
|
||||
this._value.set(this._initial);
|
||||
} else {
|
||||
this._value.set(value);
|
||||
}
|
||||
@@ -79,58 +98,80 @@ export class SettingInitOnFirstRead<V> {
|
||||
});
|
||||
}
|
||||
|
||||
disconnectFromDatabase() {
|
||||
this._subscription?.unsubscribe();
|
||||
this._subscription = null;
|
||||
this._db = null;
|
||||
}
|
||||
|
||||
subscribe(run: (value: V | undefined) => void, invalidate?: (value?: V | undefined) => void) {
|
||||
return this._value.subscribe(run, invalidate);
|
||||
}
|
||||
|
||||
set(newValue: V) {
|
||||
if (typeof newValue === 'object' || newValue !== get(this._value)) {
|
||||
this._db.settings.put(newValue, this._key);
|
||||
set(value: V) {
|
||||
if (typeof value === 'object' || value !== get(this._value)) {
|
||||
if (this._db) {
|
||||
this._db.settings.put(value, this._key);
|
||||
} else {
|
||||
this._value.set(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update(callback: (value: any) => any) {
|
||||
let newValue = callback(get(this._value));
|
||||
if (typeof newValue === 'object' || newValue !== get(this._value)) {
|
||||
this._db.settings.put(newValue, this._key);
|
||||
}
|
||||
this.set(callback(get(this._value)));
|
||||
}
|
||||
}
|
||||
|
||||
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<boolean>(db, 'elevationProfile', true),
|
||||
additionalDatasets: new Setting<string[]>(db, 'additionalDatasets', []),
|
||||
elevationFill: new Setting<'slope' | 'surface' | undefined>(db, 'elevationFill', undefined),
|
||||
treeFileView: new Setting<boolean>(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),
|
||||
distanceUnits: new Setting<'metric' | 'imperial' | 'nautical'>('distanceUnits', 'metric'),
|
||||
velocityUnits: new Setting<'speed' | 'pace'>('velocityUnits', 'speed'),
|
||||
temperatureUnits: new Setting<'celsius' | 'fahrenheit'>('temperatureUnits', 'celsius'),
|
||||
elevationProfile: new Setting<boolean>('elevationProfile', true),
|
||||
additionalDatasets: new Setting<string[]>('additionalDatasets', []),
|
||||
elevationFill: new Setting<'slope' | 'surface' | undefined>('elevationFill', undefined),
|
||||
treeFileView: new Setting<boolean>('fileView', false),
|
||||
minimizeRoutingMenu: new Setting('minimizeRoutingMenu', false),
|
||||
routing: new Setting('routing', true),
|
||||
routingProfile: new Setting('routingProfile', 'bike'),
|
||||
privateRoads: new Setting('privateRoads', false),
|
||||
currentBasemap: new Setting('currentBasemap', defaultBasemap),
|
||||
previousBasemap: new Setting('previousBasemap', defaultBasemap),
|
||||
selectedBasemapTree: new Setting('selectedBasemapTree', defaultBasemapTree),
|
||||
currentOverlays: new SettingInitOnFirstRead('currentOverlays', defaultOverlays),
|
||||
previousOverlays: new Setting('previousOverlays', defaultOverlays),
|
||||
selectedOverlayTree: new Setting('selectedOverlayTree', defaultOverlayTree),
|
||||
currentOverpassQueries: new SettingInitOnFirstRead(
|
||||
db,
|
||||
'currentOverpassQueries',
|
||||
defaultOverpassQueries
|
||||
),
|
||||
selectedOverpassTree: new Setting(db, 'selectedOverpassTree', defaultOverpassTree),
|
||||
opacities: new Setting(db, 'opacities', defaultOpacities),
|
||||
customLayers: new Setting<Record<string, CustomLayer>>(db, 'customLayers', {}),
|
||||
customBasemapOrder: new Setting<string[]>(db, 'customBasemapOrder', []),
|
||||
customOverlayOrder: new Setting<string[]>(db, 'customOverlayOrder', []),
|
||||
directionMarkers: new Setting(db, 'directionMarkers', false),
|
||||
distanceMarkers: new Setting(db, 'distanceMarkers', false),
|
||||
streetViewSource: new Setting(db, 'streetViewSource', 'mapillary'),
|
||||
fileOrder: new Setting<string[]>(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),
|
||||
selectedOverpassTree: new Setting('selectedOverpassTree', defaultOverpassTree),
|
||||
opacities: new Setting('opacities', defaultOpacities),
|
||||
customLayers: new Setting<Record<string, CustomLayer>>('customLayers', {}),
|
||||
customBasemapOrder: new Setting<string[]>('customBasemapOrder', []),
|
||||
customOverlayOrder: new Setting<string[]>('customOverlayOrder', []),
|
||||
directionMarkers: new Setting('directionMarkers', false),
|
||||
distanceMarkers: new Setting('distanceMarkers', false),
|
||||
streetViewSource: new Setting('streetViewSource', 'mapillary'),
|
||||
fileOrder: new Setting<string[]>('fileOrder', []),
|
||||
defaultOpacity: new Setting('defaultOpacity', 0.7),
|
||||
defaultWidth: new Setting('defaultWidth', browser && window.innerWidth < 600 ? 8 : 5),
|
||||
bottomPanelSize: new Setting('bottomPanelSize', 170),
|
||||
rightPanelSize: new Setting('rightPanelSize', 240),
|
||||
connectToDatabase(db: Database) {
|
||||
for (const key in settings) {
|
||||
const setting = (settings as any)[key];
|
||||
if (setting instanceof Setting || setting instanceof SettingInitOnFirstRead) {
|
||||
setting.connectToDatabase(db);
|
||||
}
|
||||
}
|
||||
},
|
||||
disconnectFromDatabase() {
|
||||
for (const key in settings) {
|
||||
const setting = (settings as any)[key];
|
||||
if (setting instanceof Setting || setting instanceof SettingInitOnFirstRead) {
|
||||
setting.disconnectFromDatabase();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user