Huge refactoring: split readonly and writable stores

This commit is contained in:
Pieter Vander Vennet 2022-06-05 02:24:14 +02:00
parent 0946d8ac9c
commit 4283b76f36
95 changed files with 819 additions and 625 deletions

View file

@ -1,11 +1,12 @@
import {UIEventSource} from "../../Logic/UIEventSource";
import {Store, UIEventSource} from "../../Logic/UIEventSource";
import BaseUIElement from "../BaseUIElement";
export abstract class InputElement<T> extends BaseUIElement {
abstract GetValue(): UIEventSource<T>;
abstract IsValid(t: T): boolean;
export interface ReadonlyInputElement<T> extends BaseUIElement{
GetValue(): Store<T>;
}
export abstract class InputElement<T> extends BaseUIElement implements ReadonlyInputElement<any>{
abstract GetValue(): UIEventSource<T>;
abstract IsValid(t: T): boolean;
}

View file

@ -21,7 +21,7 @@ export default class InputElementMap<T, X> extends InputElement<X> {
this.toX = toX;
this._inputElement = inputElement;
const self = this;
this._value = inputElement.GetValue().map(
this._value = inputElement.GetValue().sync(
(t => {
const newX = toX(t);
const currentX = self.GetValue()?.data;

View file

@ -1,6 +1,6 @@
import {InputElement} from "./InputElement";
import {ReadonlyInputElement} from "./InputElement";
import Loc from "../../Models/Loc";
import {UIEventSource} from "../../Logic/UIEventSource";
import {Store, UIEventSource} from "../../Logic/UIEventSource";
import Minimap, {MinimapObj} from "../Base/Minimap";
import BaseLayer from "../../Models/BaseLayer";
import Combine from "../Base/Combine";
@ -17,11 +17,10 @@ import BaseUIElement from "../BaseUIElement";
import Toggle from "./Toggle";
import * as matchpoint from "../../assets/layers/matchpoint/matchpoint.json"
export default class LocationInput extends InputElement<Loc> implements MinimapObj {
export default class LocationInput extends BaseUIElement implements ReadonlyInputElement<Loc>, MinimapObj {
private static readonly matchLayer = new LayerConfig(matchpoint, "LocationInput.matchpoint", true)
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
public readonly snappedOnto: UIEventSource<any> = new UIEventSource<any>(undefined)
public readonly _matching_layer: LayerConfig;
public readonly leafletMap: UIEventSource<any>
@ -33,9 +32,9 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO
* The features to which the input should be snapped
* @private
*/
private readonly _snapTo: UIEventSource<{ feature: any }[]>
private readonly _value: UIEventSource<Loc>
private readonly _snappedPoint: UIEventSource<any>
private readonly _snapTo: Store<{ feature: any }[]>
private readonly _value: Store<Loc>
private readonly _snappedPoint: Store<any>
private readonly _maxSnapDistance: number
private readonly _snappedPointTags: any;
private readonly _bounds: UIEventSource<BBox>;
@ -151,7 +150,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO
this.location = this.map.location;
}
GetValue(): UIEventSource<Loc> {
GetValue(): Store<Loc> {
return this._value;
}
@ -188,7 +187,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO
// Show the lines to snap to
console.log("Constructing the snap-to layer", this._snapTo)
new ShowDataMultiLayer({
features: new StaticFeatureSource(this._snapTo, true),
features: StaticFeatureSource.fromDateless(this._snapTo),
zoomToFeatures: false,
leafletMap: this.map.leafletMap,
layers: State.state.filteredLayers
@ -201,8 +200,10 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO
}
return [{feature: loc}];
})
console.log("Constructing the match layer", matchPoint)
new ShowDataLayer({
features: new StaticFeatureSource(matchPoint, true),
features: StaticFeatureSource.fromDateless(matchPoint),
zoomToFeatures: false,
leafletMap: this.map.leafletMap,
layerToShow: this._matching_layer,

View file

@ -152,7 +152,7 @@ export class RadioButton<T> extends InputElement<T> {
form.appendChild(block);
}
value.addCallbackAndRun((selected) => {
value.addCallbackAndRun((selected:T) => {
let somethingChecked = false;
for (let i = 0; i < inputs.length; i++) {
let input = inputs[i];

View file

@ -1,4 +1,4 @@
import {UIEventSource} from "../../Logic/UIEventSource";
import {Store, UIEventSource} from "../../Logic/UIEventSource";
import BaseUIElement from "../BaseUIElement";
import {VariableUiElement} from "../Base/VariableUIElement";
import Lazy from "../Base/Lazy";
@ -9,16 +9,16 @@ import Lazy from "../Base/Lazy";
*/
export default class Toggle extends VariableUiElement {
public readonly isEnabled: UIEventSource<boolean>;
public readonly isEnabled: Store<boolean>;
constructor(showEnabled: string | BaseUIElement, showDisabled: string | BaseUIElement, isEnabled: UIEventSource<boolean> = new UIEventSource<boolean>(false)) {
constructor(showEnabled: string | BaseUIElement, showDisabled: string | BaseUIElement, isEnabled: Store<boolean> = new UIEventSource<boolean>(false)) {
super(
isEnabled?.map(isEnabled => isEnabled ? showEnabled : showDisabled)
);
this.isEnabled = isEnabled
}
public static If(condition: UIEventSource<boolean>, constructor: () => BaseUIElement): BaseUIElement {
public static If(condition: Store<boolean>, constructor: () => BaseUIElement): BaseUIElement {
if (constructor === undefined) {
return undefined
}
@ -29,8 +29,24 @@ export default class Toggle extends VariableUiElement {
)
}
}
public ToggleOnClick(): Toggle {
/**
* Same as `Toggle`, but will swap on click
*/
export class ClickableToggle extends Toggle {
public readonly isEnabled: UIEventSource<boolean>;
constructor(showEnabled: string | BaseUIElement, showDisabled: string | BaseUIElement, isEnabled: UIEventSource<boolean> = new UIEventSource<boolean>(false)) {
super(
showEnabled, showDisabled, isEnabled
);
this.isEnabled = isEnabled
}
public ToggleOnClick(): ClickableToggle {
const self = this;
this.onClick(() => {
self.isEnabled.setData(!self.isEnabled.data);

View file

@ -1,23 +1,22 @@
import {InputElement} from "./InputElement";
import {UIEventSource} from "../../Logic/UIEventSource";
import {InputElement, ReadonlyInputElement} from "./InputElement";
import {Store} from "../../Logic/UIEventSource";
import BaseUIElement from "../BaseUIElement";
import {VariableUiElement} from "../Base/VariableUIElement";
export default class VariableInputElement<T> extends InputElement<T> {
export default class VariableInputElement<T> extends BaseUIElement implements ReadonlyInputElement<T> {
private readonly value: UIEventSource<T>;
private readonly value: Store<T>;
private readonly element: BaseUIElement
private readonly upstream: UIEventSource<InputElement<T>>;
constructor(upstream: UIEventSource<InputElement<T>>) {
private readonly upstream: Store<InputElement<T>>;
constructor(upstream: Store<InputElement<T>>) {
super()
this.upstream = upstream;
this.value = upstream.bind(v => v.GetValue())
this.element = new VariableUiElement(upstream)
}
GetValue(): UIEventSource<T> {
GetValue(): Store<T> {
return this.value;
}