2023-06-16 02:36:11 +02:00
|
|
|
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
2023-06-18 00:44:57 +02:00
|
|
|
import { ConfigMeta } from "./configMeta"
|
2023-06-20 01:32:24 +02:00
|
|
|
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
|
|
|
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
2023-09-15 01:16:33 +02:00
|
|
|
import { QueryParameters } from "../../Logic/Web/QueryParameters"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sends changes back to the server
|
|
|
|
*/
|
|
|
|
export class LayerStateSender {
|
|
|
|
constructor(serverLocation: string, layerState: EditLayerState) {
|
|
|
|
layerState.configuration.addCallback(async (config) => {
|
|
|
|
// console.log("Current config is", Utils.Clone(config))
|
|
|
|
const id = config.id
|
|
|
|
if (id === undefined) {
|
|
|
|
console.log("No id found in layer, not updating")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
const response = await fetch(`${serverLocation}/layers/${id}/${id}.json`, {
|
|
|
|
method: "POST",
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json;charset=utf-8",
|
|
|
|
},
|
|
|
|
body: JSON.stringify(config, null, " "),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-06-16 02:36:11 +02:00
|
|
|
|
|
|
|
export default class EditLayerState {
|
|
|
|
public readonly osmConnection: OsmConnection
|
2023-06-18 00:44:57 +02:00
|
|
|
public readonly schema: ConfigMeta[]
|
|
|
|
|
2023-06-20 01:32:24 +02:00
|
|
|
public readonly featureSwitches: { featureSwitchIsDebugging: UIEventSource<boolean> }
|
|
|
|
|
|
|
|
public readonly configuration: UIEventSource<Partial<LayerConfigJson>> = new UIEventSource<
|
|
|
|
Partial<LayerConfigJson>
|
|
|
|
>({})
|
|
|
|
|
2023-06-18 00:44:57 +02:00
|
|
|
constructor(schema: ConfigMeta[]) {
|
|
|
|
this.schema = schema
|
2023-09-15 01:16:33 +02:00
|
|
|
this.osmConnection = new OsmConnection({
|
|
|
|
oauth_token: QueryParameters.GetQueryParameter(
|
|
|
|
"oauth_token",
|
|
|
|
undefined,
|
|
|
|
"Used to complete the login"
|
|
|
|
),
|
|
|
|
})
|
2023-06-20 01:32:24 +02:00
|
|
|
this.featureSwitches = {
|
|
|
|
featureSwitchIsDebugging: new UIEventSource<boolean>(true),
|
|
|
|
}
|
2023-09-15 01:16:33 +02:00
|
|
|
console.log("Configuration store:", this.configuration)
|
2023-06-20 01:32:24 +02:00
|
|
|
}
|
|
|
|
|
2023-06-23 16:14:43 +02:00
|
|
|
public getCurrentValueFor(path: ReadonlyArray<string | number>): any | undefined {
|
|
|
|
// Walk the path down to see if we find something
|
|
|
|
let entry = this.configuration.data
|
|
|
|
for (let i = 0; i < path.length; i++) {
|
|
|
|
if (entry === undefined) {
|
|
|
|
// We reached a dead end - no old vlaue
|
|
|
|
return undefined
|
2023-06-20 01:32:24 +02:00
|
|
|
}
|
2023-06-23 16:14:43 +02:00
|
|
|
const breadcrumb = path[i]
|
|
|
|
entry = entry[breadcrumb]
|
|
|
|
}
|
|
|
|
return entry
|
|
|
|
}
|
|
|
|
|
2023-08-23 11:11:53 +02:00
|
|
|
public getStoreFor(path: ReadonlyArray<string | number>): UIEventSource<any | undefined> {
|
|
|
|
const store = new UIEventSource<any>(this.getCurrentValueFor(path))
|
|
|
|
store.addCallback((v) => {
|
|
|
|
console.log("UPdating store", path, v)
|
|
|
|
this.setValueAt(path, v)
|
|
|
|
})
|
|
|
|
return store
|
|
|
|
}
|
|
|
|
|
2023-06-23 16:14:43 +02:00
|
|
|
public register(
|
|
|
|
path: ReadonlyArray<string | number>,
|
|
|
|
value: Store<any>,
|
|
|
|
noInitialSync: boolean = false
|
|
|
|
): () => void {
|
2023-06-23 17:28:44 +02:00
|
|
|
const unsync = value.addCallback((v) => this.setValueAt(path, v))
|
2023-06-23 16:14:43 +02:00
|
|
|
if (!noInitialSync) {
|
2023-06-23 17:28:44 +02:00
|
|
|
this.setValueAt(path, value.data)
|
2023-06-23 16:14:43 +02:00
|
|
|
}
|
|
|
|
return unsync
|
2023-06-16 02:36:11 +02:00
|
|
|
}
|
2023-06-18 00:44:57 +02:00
|
|
|
|
|
|
|
public getSchemaStartingWith(path: string[]) {
|
|
|
|
return this.schema.filter(
|
|
|
|
(sch) =>
|
|
|
|
!path.some((part, i) => !(sch.path.length > path.length && sch.path[i] === part))
|
|
|
|
)
|
|
|
|
}
|
2023-06-21 17:13:09 +02:00
|
|
|
|
2023-06-30 13:36:02 +02:00
|
|
|
public getTranslationAt(path: string[]): ConfigMeta {
|
|
|
|
const origConfig = this.getSchema(path)[0]
|
|
|
|
return {
|
|
|
|
path,
|
|
|
|
type: "translation",
|
|
|
|
hints: {
|
|
|
|
typehint: "translation",
|
|
|
|
},
|
|
|
|
required: origConfig.required ?? false,
|
|
|
|
description: origConfig.description ?? "A translatable object",
|
|
|
|
}
|
|
|
|
}
|
2023-09-15 01:16:33 +02:00
|
|
|
|
2023-06-30 13:36:02 +02:00
|
|
|
public getSchema(path: string[]): ConfigMeta[] {
|
2023-09-15 01:16:33 +02:00
|
|
|
const schemas = this.schema.filter(
|
2023-06-21 17:13:09 +02:00
|
|
|
(sch) =>
|
2023-06-23 16:14:43 +02:00
|
|
|
sch !== undefined &&
|
2023-06-21 17:13:09 +02:00
|
|
|
!path.some((part, i) => !(sch.path.length == path.length && sch.path[i] === part))
|
|
|
|
)
|
2023-09-15 01:16:33 +02:00
|
|
|
if (schemas.length == 0) {
|
|
|
|
console.warn("No schemas found for path", path.join("."))
|
|
|
|
}
|
|
|
|
return schemas
|
2023-06-21 17:13:09 +02:00
|
|
|
}
|
2023-06-23 16:14:43 +02:00
|
|
|
|
2023-06-23 17:28:44 +02:00
|
|
|
public setValueAt(path: ReadonlyArray<string | number>, v: any) {
|
2023-10-06 23:56:50 +02:00
|
|
|
let entry = this.configuration.data
|
|
|
|
console.log("Setting value", v, "to", path, "in entry", entry)
|
|
|
|
for (let i = 0; i < path.length - 1; i++) {
|
|
|
|
const breadcrumb = path[i]
|
|
|
|
if (entry[breadcrumb] === undefined) {
|
|
|
|
entry[breadcrumb] = typeof path[i + 1] === "number" ? [] : {}
|
2023-06-23 16:14:43 +02:00
|
|
|
}
|
2023-10-06 23:56:50 +02:00
|
|
|
entry = entry[breadcrumb]
|
|
|
|
}
|
2023-10-07 03:07:32 +02:00
|
|
|
if (v !== undefined && v !== null && v !== "") {
|
2023-10-06 23:56:50 +02:00
|
|
|
entry[path.at(-1)] = v
|
|
|
|
} else if (entry) {
|
|
|
|
delete entry[path.at(-1)]
|
2023-06-23 16:14:43 +02:00
|
|
|
}
|
2023-10-06 23:56:50 +02:00
|
|
|
this.configuration.ping()
|
2023-06-23 16:14:43 +02:00
|
|
|
}
|
2023-06-16 02:36:11 +02:00
|
|
|
}
|