forked from philorg/treetrail-frontend
157 lines
4 KiB
TypeScript
157 lines
4 KiB
TypeScript
|
import { Injectable, Component } from "@angular/core"
|
||
|
import { Observable, BehaviorSubject, Subject, ReplaySubject, combineLatest } from 'rxjs'
|
||
|
import { map, take } from 'rxjs/operators'
|
||
|
|
||
|
import { LngLat, LngLatLike } from "maplibre-gl"
|
||
|
import { DataService } from "./data.service"
|
||
|
import { DefaultService } from "./openapi/services.gen"
|
||
|
import { Bootstrap, Map } from "./openapi/types.gen"
|
||
|
|
||
|
export type MapPos = {
|
||
|
center: LngLatLike,
|
||
|
zoom: number,
|
||
|
bearing: number,
|
||
|
pitch: number,
|
||
|
}
|
||
|
|
||
|
export const dbName = 'treetrail' // See also dbConfig in app.module
|
||
|
export const settingsDbName = 'settings'
|
||
|
|
||
|
export class Config {
|
||
|
constructor(
|
||
|
public user: string = undefined,
|
||
|
public skipIntro: boolean = false,
|
||
|
public vibrate: boolean = true,
|
||
|
public showZones: { [zone: string]: boolean } = {},
|
||
|
public alertDistance = 250,
|
||
|
public map?: Map,
|
||
|
public bootstrap?: Bootstrap,
|
||
|
public mapPos?: MapPos,
|
||
|
public background: string = undefined,
|
||
|
// public server: {} = {},
|
||
|
// public client: {} = {},
|
||
|
// public app: {} = {},
|
||
|
) { }
|
||
|
}
|
||
|
|
||
|
@Injectable()
|
||
|
export class ConfigService {
|
||
|
constructor(
|
||
|
public dataService: DataService,
|
||
|
private api: DefaultService,
|
||
|
) {
|
||
|
}
|
||
|
|
||
|
public conf: BehaviorSubject<Config> // = new BehaviorSubject<Config>(new Config())
|
||
|
|
||
|
userPrefsKeyList = ['userName', 'skipIntro', 'vibrate', 'showZones', 'background']
|
||
|
|
||
|
bootstrap(): Observable<Bootstrap> {
|
||
|
return this.api.getBootstrapBootstrapGet().pipe(map(
|
||
|
resp => {
|
||
|
this.conf = new BehaviorSubject<Config>(new Config(
|
||
|
'',
|
||
|
false,
|
||
|
true,
|
||
|
{},
|
||
|
250,
|
||
|
resp.map,
|
||
|
resp,
|
||
|
undefined,
|
||
|
))
|
||
|
// this.conf.value.bootstrap = resp
|
||
|
// this.conf.value.map = resp.map
|
||
|
// this.conf.next(this.conf.value)
|
||
|
return resp
|
||
|
}
|
||
|
))
|
||
|
}
|
||
|
|
||
|
getMapCenter(): Observable<LngLatLike> {
|
||
|
return this.conf.pipe(map(
|
||
|
conf => <LngLatLike>{
|
||
|
lng: conf.map.lng,
|
||
|
lat: conf.map.lat
|
||
|
}
|
||
|
))
|
||
|
}
|
||
|
|
||
|
loadUserSettings(data: unknown[]) {
|
||
|
// TODO: assert the whole idea and use of storing the config in a BahaviourSubject
|
||
|
data.forEach(kv => {
|
||
|
if (kv['value']) {
|
||
|
this.conf.value[kv['key']] = kv['value']
|
||
|
}
|
||
|
})
|
||
|
// Update the list of types of zones from actual data
|
||
|
this.dataService.all.subscribe(
|
||
|
all => {
|
||
|
let zoneTypes = new Set((Object.values(all.zones).map(
|
||
|
zone => zone.type
|
||
|
)))
|
||
|
zoneTypes.forEach(
|
||
|
zoneType => {
|
||
|
if (this.conf.value.showZones[zoneType] === undefined) {
|
||
|
this.conf.value.showZones[zoneType] = false
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
this.conf.next(this.conf.value)
|
||
|
}
|
||
|
)
|
||
|
// if (!this.conf.value.skipIntro) {
|
||
|
// this.router.navigate(['intro'], {relativeTo: this.route});
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
storeUserData(): void {
|
||
|
this.userPrefsKeyList.forEach(
|
||
|
key => this.dataService.dbService.update(
|
||
|
settingsDbName, {
|
||
|
key: key,
|
||
|
value: this.conf.value[key]
|
||
|
}).subscribe()
|
||
|
)
|
||
|
}
|
||
|
|
||
|
setUserPrefValue(pref: string, key: string, value: any) {
|
||
|
let conf = this.conf.value
|
||
|
conf[pref][key] = value
|
||
|
this.conf.next(conf)
|
||
|
this.storeUserData()
|
||
|
}
|
||
|
|
||
|
setUserPref(pref: string, value: any) {
|
||
|
let conf = this.conf.value
|
||
|
// userName is special, read (and thus stored) in bootstrap
|
||
|
if (pref == 'userName') {
|
||
|
conf.bootstrap.user = value
|
||
|
this.conf.next(this.conf.value)
|
||
|
}
|
||
|
else {
|
||
|
conf[pref] = value
|
||
|
}
|
||
|
this.conf.next(conf)
|
||
|
this.storeUserData()
|
||
|
}
|
||
|
|
||
|
setMapPos(mapPos: MapPos): Observable<unknown> {
|
||
|
this.updateConf({mapPos: mapPos})
|
||
|
return this.dataService.dbService.update(settingsDbName, {
|
||
|
key: 'mapPos',
|
||
|
value: {
|
||
|
center: mapPos.center,
|
||
|
zoom: mapPos.zoom,
|
||
|
pitch: mapPos.pitch,
|
||
|
bearing: mapPos.bearing,
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
updateConf(newConf: Object) {
|
||
|
this.conf.pipe(take(1)).subscribe(
|
||
|
conf => this.conf.next({ ...conf, ...newConf })
|
||
|
)
|
||
|
}
|
||
|
}
|