forked from MapComplete/MapComplete
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:
parent
adf02af5fe
commit
d4e63d90e4
4 changed files with 106 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ missing_translations.txt
|
|||
.DS_Store
|
||||
Svg.ts
|
||||
data/
|
||||
Folder.DotSettings.user
|
||||
|
|
100
Logic/Actors/SelectedElementTagsUpdater.ts
Normal file
100
Logic/Actors/SelectedElementTagsUpdater.ts
Normal 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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -18,6 +18,8 @@ export interface ChangeDescription {
|
|||
/**
|
||||
* All changes to tags
|
||||
* 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 }[],
|
||||
|
||||
|
|
3
State.ts
3
State.ts
|
@ -18,6 +18,7 @@ import FilteredLayer from "./Models/FilteredLayer";
|
|||
import ChangeToElementsActor from "./Logic/Actors/ChangeToElementsActor";
|
||||
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
|
||||
import {BBox} from "./Logic/BBox";
|
||||
import SelectedElementTagsUpdater from "./Logic/Actors/SelectedElementTagsUpdater";
|
||||
|
||||
/**
|
||||
* 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 PendingChangesUploader(this.changes, this.selectedElement);
|
||||
|
||||
new SelectedElementTagsUpdater(this)
|
||||
|
||||
this.mangroveIdentity = new MangroveIdentity(
|
||||
this.osmConnection.GetLongPreference("identity", "mangrove")
|
||||
|
|
Loading…
Reference in a new issue