When a logged-in user opens a popup, the latest data will be downloaded and tags are updated to prevent duplicate work, fix #505

This commit is contained in:
pietervdvn 2021-10-10 00:53:14 +02:00
parent adf02af5fe
commit d4e63d90e4
4 changed files with 106 additions and 0 deletions

1
.gitignore vendored
View file

@ -17,3 +17,4 @@ missing_translations.txt
.DS_Store .DS_Store
Svg.ts Svg.ts
data/ data/
Folder.DotSettings.user

View file

@ -0,0 +1,100 @@
/**
* This actor will download the latest version of the selected element from OSM and update the tags if necessary.
*/
import {UIEventSource} from "../UIEventSource";
import {ElementStorage} from "../ElementStorage";
import {Changes} from "../Osm/Changes";
import {OsmObject} from "../Osm/OsmObject";
import {OsmConnection} from "../Osm/OsmConnection";
export default class SelectedElementTagsUpdater {
constructor(state: {
selectedElement: UIEventSource<any>,
allElements: ElementStorage,
changes: Changes,
osmConnection: OsmConnection
}) {
state.osmConnection.isLoggedIn.addCallbackAndRun(isLoggedIn => {
if(isLoggedIn){
SelectedElementTagsUpdater.installCallback(state)
return true;
}
})
}
private static installCallback(state: {
selectedElement: UIEventSource<any>,
allElements: ElementStorage,
changes: Changes,
osmConnection: OsmConnection
}) {
state.selectedElement.addCallbackAndRunD(s => {
const id = s.properties?.id
OsmObject.DownloadObjectAsync(id).then(obj => {
SelectedElementTagsUpdater.applyUpdate(state, obj, id)
}).catch(e => {
console.error("Could not update tags of ", id, "due to", e)
})
});
}
private static applyUpdate(state: {
selectedElement: UIEventSource<any>,
allElements: ElementStorage,
changes: Changes,
osmConnection: OsmConnection
}, obj: OsmObject, id: string
) {
const pendingChanges = state.changes.pendingChanges.data
.filter(change => change.type === obj.type && change.id === obj.id)
.filter(change => change.tags !== undefined);
const latestTags = obj.tags
console.log("Applying updates of ", id, " got tags", latestTags, "and still have to apply changes: ", pendingChanges)
for (const pendingChange of pendingChanges) {
const tagChanges = pendingChange.tags;
for (const tagChange of tagChanges) {
const key = tagChange.k
const v = tagChange.v
if (v === undefined || v === "") {
delete latestTags[key]
} else {
latestTags[key] = v
}
}
}
// With the changes applied, we merge them onto the upstream object
let somethingChanged = false;
const currentTagsSource = state.allElements.getEventSourceById(id);
const currentTags = currentTagsSource.data
for (const key in latestTags) {
let osmValue = latestTags[key]
if(typeof osmValue === "number"){
osmValue = ""+osmValue
}
const localValue = currentTags[key]
if (localValue !== osmValue) {
console.log("Local value:", localValue, "upstream", osmValue)
somethingChanged = true;
currentTags[key] = osmValue
}
}
if (somethingChanged) {
console.log("Detected upstream changes to the object when opening it, updating...")
currentTagsSource.ping()
}
}
}

View file

@ -18,6 +18,8 @@ export interface ChangeDescription {
/** /**
* All changes to tags * All changes to tags
* v = "" or v = undefined to erase this tag * v = "" or v = undefined to erase this tag
*
* Note that this list will only contain the _changes_ to the tags, not the full set of tags
*/ */
tags?: { k: string, v: string }[], tags?: { k: string, v: string }[],

View file

@ -18,6 +18,7 @@ import FilteredLayer from "./Models/FilteredLayer";
import ChangeToElementsActor from "./Logic/Actors/ChangeToElementsActor"; import ChangeToElementsActor from "./Logic/Actors/ChangeToElementsActor";
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
import {BBox} from "./Logic/BBox"; import {BBox} from "./Logic/BBox";
import SelectedElementTagsUpdater from "./Logic/Actors/SelectedElementTagsUpdater";
/** /**
* Contains the global state: a bunch of UI-event sources * Contains the global state: a bunch of UI-event sources
@ -376,6 +377,8 @@ export default class State {
new ChangeToElementsActor(this.changes, this.allElements) new ChangeToElementsActor(this.changes, this.allElements)
new PendingChangesUploader(this.changes, this.selectedElement); new PendingChangesUploader(this.changes, this.selectedElement);
new SelectedElementTagsUpdater(this)
this.mangroveIdentity = new MangroveIdentity( this.mangroveIdentity = new MangroveIdentity(
this.osmConnection.GetLongPreference("identity", "mangrove") this.osmConnection.GetLongPreference("identity", "mangrove")