forked from MapComplete/MapComplete
		
	Add robustness when run via console, formatting
This commit is contained in:
		
							parent
							
								
									83af5adaea
								
							
						
					
					
						commit
						89d4a6bcce
					
				
					 11 changed files with 118 additions and 67 deletions
				
			
		|  | @ -23,11 +23,11 @@ export default class AvailableBaseLayers { | |||
|     private static implementation: AvailableBaseLayersObj | ||||
|      | ||||
|     static AvailableLayersAt(location: UIEventSource<Loc>): UIEventSource<BaseLayer[]> { | ||||
|         return AvailableBaseLayers.implementation.AvailableLayersAt(location); | ||||
|         return AvailableBaseLayers.implementation?.AvailableLayersAt(location) ?? new UIEventSource<BaseLayer[]>([]); | ||||
|     } | ||||
| 
 | ||||
|     static SelectBestLayerAccordingTo(location: UIEventSource<Loc>, preferedCategory: UIEventSource<string | string[]>): UIEventSource<BaseLayer> { | ||||
|         return AvailableBaseLayers.implementation.SelectBestLayerAccordingTo(location, preferedCategory); | ||||
|         return AvailableBaseLayers.implementation?.SelectBestLayerAccordingTo(location, preferedCategory) ?? new UIEventSource<BaseLayer>(undefined); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import {UIEventSource} from "../UIEventSource"; | |||
| import BaseLayer from "../../Models/BaseLayer"; | ||||
| import AvailableBaseLayers from "./AvailableBaseLayers"; | ||||
| import Loc from "../../Models/Loc"; | ||||
| import {Utils} from "../../Utils"; | ||||
| 
 | ||||
| /** | ||||
|  * Sets the current background layer to a layer that is actually available | ||||
|  | @ -12,6 +13,11 @@ export default class BackgroundLayerResetter { | |||
|                 location: UIEventSource<Loc>, | ||||
|                 availableLayers: UIEventSource<BaseLayer[]>, | ||||
|                 defaultLayerId: string = undefined) { | ||||
|          | ||||
|         if(Utils.runningFromConsole){ | ||||
|             return | ||||
|         } | ||||
|          | ||||
|         defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id; | ||||
| 
 | ||||
|         // Change the baselayer back to OSM if we go out of the current range of the layer
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import {Changes} from "../Osm/Changes"; | ||||
| import Constants from "../../Models/Constants"; | ||||
| import {UIEventSource} from "../UIEventSource"; | ||||
| import {Utils} from "../../Utils"; | ||||
| 
 | ||||
| export default class PendingChangesUploader { | ||||
| 
 | ||||
|  | @ -30,6 +31,10 @@ export default class PendingChangesUploader { | |||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|         if(Utils.runningFromConsole){ | ||||
|             return; | ||||
|         } | ||||
|          | ||||
|         document.addEventListener('mouseout', e => { | ||||
|             // @ts-ignore
 | ||||
|             if (!e.toElement && !e.relatedTarget) { | ||||
|  |  | |||
|  | @ -9,6 +9,13 @@ import {OsmConnection} from "../Osm/OsmConnection"; | |||
| 
 | ||||
| export default class SelectedElementTagsUpdater { | ||||
| 
 | ||||
|     private static readonly metatags = new Set(["timestamp", | ||||
|         "version", | ||||
|         "changeset", | ||||
|         "user", | ||||
|         "uid", | ||||
|         "id"]                                         ) | ||||
| 
 | ||||
|     constructor(state: { | ||||
|         selectedElement: UIEventSource<any>, | ||||
|         allElements: ElementStorage, | ||||
|  | @ -18,15 +25,15 @@ export default class SelectedElementTagsUpdater { | |||
| 
 | ||||
| 
 | ||||
|         state.osmConnection.isLoggedIn.addCallbackAndRun(isLoggedIn => { | ||||
|             if(isLoggedIn){ | ||||
|             if (isLoggedIn) { | ||||
|                 SelectedElementTagsUpdater.installCallback(state) | ||||
|                 return true; | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
|      | ||||
|     private static installCallback(state: { | ||||
| 
 | ||||
|     public static installCallback(state: { | ||||
|         selectedElement: UIEventSource<any>, | ||||
|         allElements: ElementStorage, | ||||
|         changes: Changes, | ||||
|  | @ -36,80 +43,99 @@ export default class SelectedElementTagsUpdater { | |||
| 
 | ||||
|         state.selectedElement.addCallbackAndRunD(s => { | ||||
|             let id = s.properties?.id | ||||
|              | ||||
| 
 | ||||
|             const backendUrl = state.osmConnection._oauth_config.url | ||||
|             if(id.startsWith(backendUrl)){ | ||||
|             if (id.startsWith(backendUrl)) { | ||||
|                 id = id.substring(backendUrl.length) | ||||
|             } | ||||
|              | ||||
|             if(!(id.startsWith("way") || id.startsWith("node") || id.startsWith("relation"))){ | ||||
| 
 | ||||
|             if (!(id.startsWith("way") || id.startsWith("node") || id.startsWith("relation"))) { | ||||
|                 // This object is _not_ from OSM, so we skip it!
 | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if(id.indexOf("-") >= 0){ | ||||
| 
 | ||||
|             if (id.indexOf("-") >= 0) { | ||||
|                 // This is a new object
 | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             OsmObject.DownloadPropertiesOf(id).then(tags => { | ||||
|                 SelectedElementTagsUpdater.applyUpdate(state, tags, id) | ||||
|             }).catch(e => { | ||||
|                 console.error("Could not update tags of ", id, "due to", e) | ||||
|             OsmObject.DownloadPropertiesOf(id).then(latestTags => { | ||||
|                 SelectedElementTagsUpdater.applyUpdate(state, latestTags, id) | ||||
|             }) | ||||
| 
 | ||||
|         }); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static applyUpdate(state: { | ||||
|                                    selectedElement: UIEventSource<any>, | ||||
|                                    allElements: ElementStorage, | ||||
|                                    changes: Changes, | ||||
|                                    osmConnection: OsmConnection | ||||
|                                }, latestTags: any, id: string | ||||
|     public static applyUpdate(state: { | ||||
|                                   selectedElement: UIEventSource<any>, | ||||
|                                   allElements: ElementStorage, | ||||
|                                   changes: Changes, | ||||
|                                   osmConnection: OsmConnection | ||||
|                               }, latestTags: any, id: string | ||||
|     ) { | ||||
|         const pendingChanges = state.changes.pendingChanges.data | ||||
|             .filter(change => change.type +"/"+ change.id === id) | ||||
|             .filter(change => change.tags !== undefined); | ||||
|         | ||||
|         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 | ||||
|         try { | ||||
| 
 | ||||
|             const pendingChanges = state.changes.pendingChanges.data | ||||
|                 .filter(change => change.type + "/" + change.id === id) | ||||
|                 .filter(change => change.tags !== undefined); | ||||
| 
 | ||||
|             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 for ", key ,":", localValue, "upstream", osmValue) | ||||
|                 somethingChanged = true; | ||||
|                 currentTags[key] = osmValue | ||||
|             } | ||||
|         } | ||||
|         if (somethingChanged) { | ||||
|             console.log("Detected upstream changes to the object when opening it, updating...") | ||||
|             currentTagsSource.ping() | ||||
|         }else{ | ||||
|             console.debug("Fetched latest tags for ", id, "but detected no changes") | ||||
|         } | ||||
|             // 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 for ", key, ":", localValue, "upstream", osmValue) | ||||
|                     somethingChanged = true; | ||||
|                     currentTags[key] = osmValue | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             for (const currentKey in currentTags) { | ||||
|                 if (currentKey.startsWith("_")) { | ||||
|                     continue | ||||
|                 } | ||||
|                 if(this.metatags.has(currentKey)){ | ||||
|                     continue | ||||
|                 } | ||||
|                 if (currentKey in latestTags) { | ||||
|                     continue | ||||
|                 } | ||||
|                 console.log("Removing key as deleted upstream", currentKey) | ||||
|                 delete currentTags[currentKey] | ||||
|                 somethingChanged = true | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             if (somethingChanged) { | ||||
|                 console.log("Detected upstream changes to the object when opening it, updating...") | ||||
|                 currentTagsSource.ping() | ||||
|             } else { | ||||
|                 console.debug("Fetched latest tags for ", id, "but detected no changes") | ||||
|             } | ||||
|         } catch (e) { | ||||
|             console.error("Updating the tags of selected element ", id, "failed due to", e) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer"; | |||
| import Combine from "../../UI/Base/Combine"; | ||||
| import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; | ||||
| import {ElementStorage} from "../ElementStorage"; | ||||
| import {Utils} from "../../Utils"; | ||||
| 
 | ||||
| export default class TitleHandler { | ||||
|     constructor(state : { | ||||
|  | @ -38,6 +39,9 @@ export default class TitleHandler { | |||
| 
 | ||||
| 
 | ||||
|         currentTitle.addCallbackAndRunD(title => { | ||||
|             if(Utils.runningFromConsole){ | ||||
|                 return | ||||
|             } | ||||
|             document.title = title | ||||
|         }) | ||||
|     } | ||||
|  |  | |||
|  | @ -21,11 +21,13 @@ export default class AllImageProviders { | |||
|         ) | ||||
|              | ||||
|     ] | ||||
|      | ||||
|     public static defaultKeys = [].concat(AllImageProviders.ImageAttributionSource.map(provider => provider.defaultKeyPrefixes)) | ||||
| 
 | ||||
| 
 | ||||
|     private static _cache: Map<string, UIEventSource<ProvidedImage[]>> = new Map<string, UIEventSource<ProvidedImage[]>>() | ||||
| 
 | ||||
|     public static LoadImagesFor(tags: UIEventSource<any>, tagKey?: string): UIEventSource<ProvidedImage[]> { | ||||
|     public static LoadImagesFor(tags: UIEventSource<any>, tagKey?: string[]): UIEventSource<ProvidedImage[]> { | ||||
|         if (tags.data.id === undefined) { | ||||
|             return undefined; | ||||
|         } | ||||
|  | @ -44,7 +46,7 @@ export default class AllImageProviders { | |||
|              | ||||
|             let prefixes = imageProvider.defaultKeyPrefixes | ||||
|             if(tagKey !== undefined){ | ||||
|                 prefixes = [...prefixes, tagKey] | ||||
|                 prefixes = tagKey | ||||
|             } | ||||
|              | ||||
|             const singleSource = imageProvider.GetRelevantUrls(tags, { | ||||
|  |  | |||
|  | @ -27,7 +27,8 @@ export default class ImgurUploader { | |||
|             files, | ||||
|             function (url) { | ||||
|                 console.log("File saved at", url); | ||||
|                 self.success.setData([...self.success.data, url]); | ||||
|                 self.success.data.push(url) | ||||
|                 self.success.ping(); | ||||
|                 self._handleSuccessUrl(url); | ||||
|             }, | ||||
|             function () { | ||||
|  |  | |||
|  | @ -97,6 +97,7 @@ export class Changes { | |||
|             console.log("Is already uploading... Abort") | ||||
|             return; | ||||
|         } | ||||
|         console.log("Uploading changes due to: ", flushreason) | ||||
|         this.isUploading.setData(true) | ||||
| 
 | ||||
|         this.flushChangesAsync() | ||||
|  | @ -287,7 +288,7 @@ export class Changes { | |||
|                     v = undefined; | ||||
|                 } | ||||
| 
 | ||||
|                 const oldV = obj.type[k] | ||||
|                 const oldV = obj.tags[k] | ||||
|                 if (oldV === v) { | ||||
|                     continue; | ||||
|                 } | ||||
|  |  | |||
|  | @ -66,7 +66,9 @@ export abstract class OsmObject { | |||
| 
 | ||||
|         const url = `${OsmObject.backendURL}api/0.6/${id}`; | ||||
|         const rawData = await Utils.downloadJsonCached(url, 1000) | ||||
|         return rawData.elements[0].tags | ||||
|         const tags = rawData.elements[0].tags | ||||
|         console.log("Tags are", tags) | ||||
|         return tags | ||||
|     } | ||||
| 
 | ||||
|     static async DownloadObjectAsync(id: string): Promise<OsmObject> { | ||||
|  | @ -263,7 +265,7 @@ export abstract class OsmObject { | |||
|                 continue; | ||||
|             } | ||||
|             const v = this.tags[key]; | ||||
|             if (v !== "") { | ||||
|             if (v !== "" && v !== undefined) { | ||||
|                 tags += '        <tag k="' + Utils.EncodeXmlValue(key) + '" v="' + Utils.EncodeXmlValue(this.tags[key]) + '"/>\n' | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; | |||
| import {UIEventSource} from "../UIEventSource"; | ||||
| import {QueryParameters} from "../Web/QueryParameters"; | ||||
| import Constants from "../../Models/Constants"; | ||||
| import {Utils} from "../../Utils"; | ||||
| 
 | ||||
| export default class FeatureSwitchState { | ||||
| 
 | ||||
|  | @ -137,7 +138,7 @@ export default class FeatureSwitchState { | |||
| 
 | ||||
| 
 | ||||
|         let testingDefaultValue = false; | ||||
|         if (this.featureSwitchApiURL.data !== "osm-test" && | ||||
|         if (this.featureSwitchApiURL.data !== "osm-test" && !Utils.runningFromConsole && | ||||
|             (location.hostname === "localhost" || location.hostname === "127.0.0.1")) { | ||||
|             testingDefaultValue = true | ||||
|         } | ||||
|  |  | |||
|  | @ -286,6 +286,9 @@ export class UIEventSource<T> { | |||
|     } | ||||
| 
 | ||||
|     public stabilized(millisToStabilize): UIEventSource<T> { | ||||
|         if(Utils.runningFromConsole){ | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         const newSource = new UIEventSource<T>(this.data); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue