| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  | import {UIEventSource} from "../UIEventSource"; | 
					
						
							| 
									
										
										
										
											2021-01-04 04:36:21 +01:00
										 |  |  | import UserDetails, {OsmConnection} from "./OsmConnection"; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  | import {Utils} from "../../Utils"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class OsmPreferences { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 03:12:09 +01:00
										 |  |  |     public preferences = new UIEventSource<any>({}, "all-osm-preferences"); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |     public preferenceSources: any = {} | 
					
						
							| 
									
										
										
										
											2021-01-15 01:57:46 +01:00
										 |  |  |     private auth: any; | 
					
						
							|  |  |  |     private userDetails: UIEventSource<UserDetails>; | 
					
						
							|  |  |  |     private longPreferences = {}; | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     constructor(auth, osmConnection: OsmConnection) { | 
					
						
							|  |  |  |         this.auth = auth; | 
					
						
							|  |  |  |         this.userDetails = osmConnection.userDetails; | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         osmConnection.OnLoggedIn(() => self.UpdatePreferences()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * OSM preferences can be at most 255 chars | 
					
						
							|  |  |  |      * @param key | 
					
						
							|  |  |  |      * @param prefix | 
					
						
							|  |  |  |      * @constructor | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public GetLongPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource<string> { | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (this.longPreferences[prefix + key] !== undefined) { | 
					
						
							|  |  |  |             return this.longPreferences[prefix + key]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  |         const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key); | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |         this.longPreferences[prefix + key] = source; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |         const allStartWith = prefix + key + "-combined"; | 
					
						
							|  |  |  |         // Gives the number of combined preferences
 | 
					
						
							|  |  |  |         const length = this.GetPreference(allStartWith + "-length", ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         source.addCallback(str => { | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |             if (str === undefined || str === "") { | 
					
						
							| 
									
										
										
										
											2020-10-18 00:28:51 +02:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-15 01:57:46 +01:00
										 |  |  |             if (str === null) { | 
					
						
							|  |  |  |                 console.error("Deleting " + allStartWith); | 
					
						
							| 
									
										
										
										
											2020-10-18 00:28:51 +02:00
										 |  |  |                 let count = parseInt(length.data); | 
					
						
							|  |  |  |                 for (let i = 0; i < count; i++) { | 
					
						
							|  |  |  |                     // Delete all the preferences
 | 
					
						
							|  |  |  |                     self.GetPreference(allStartWith + "-" + i, "") | 
					
						
							|  |  |  |                         .setData(""); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 self.GetPreference(allStartWith + "-length", "") | 
					
						
							|  |  |  |                     .setData(""); | 
					
						
							|  |  |  |                 return | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let i = 0; | 
					
						
							|  |  |  |             while (str !== "") { | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |                 if (str === undefined || str === "undefined") { | 
					
						
							|  |  |  |                     throw "Long pref became undefined?" | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (i > 100) { | 
					
						
							|  |  |  |                     throw "This long preference is getting very long... " | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                 self.GetPreference(allStartWith + "-" + i, "").setData(str.substr(0, 255)); | 
					
						
							|  |  |  |                 str = str.substr(255); | 
					
						
							|  |  |  |                 i++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |             length.setData("" + i); // We use I, the number of preference fields used
 | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function updateData(l: number) { | 
					
						
							|  |  |  |             if (l === undefined) { | 
					
						
							|  |  |  |                 source.setData(undefined); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-09-15 02:29:31 +02:00
										 |  |  |             const prefsCount = Number(l); | 
					
						
							|  |  |  |             if (prefsCount > 100) { | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |                 throw "Length to long"; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             let str = ""; | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |             for (let i = 0; i < prefsCount; i++) { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                 str += self.GetPreference(allStartWith + "-" + i, "").data; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             source.setData(str); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         length.addCallback(l => { | 
					
						
							|  |  |  |             updateData(Number(l)); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         updateData(Number(length.data)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return source; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public GetPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource<string> { | 
					
						
							|  |  |  |         key = prefix + key; | 
					
						
							| 
									
										
										
										
											2021-06-22 14:29:22 +02:00
										 |  |  |         key = key.replace(/[:\\\/"' {}.%]/g, '') | 
					
						
							| 
									
										
										
										
											2021-01-15 01:57:46 +01:00
										 |  |  |         if (key.length >= 255) { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             throw "Preferences: key length to big"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this.preferenceSources[key] !== undefined) { | 
					
						
							|  |  |  |             return this.preferenceSources[key]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) { | 
					
						
							|  |  |  |             this.UpdatePreferences(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  |         const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |         pref.addCallback((v) => { | 
					
						
							|  |  |  |             this.SetPreference(key, v); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.preferences.addCallback((prefs) => { | 
					
						
							|  |  |  |             if (prefs[key] !== undefined) { | 
					
						
							|  |  |  |                 pref.setData(prefs[key]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.preferenceSources[key] = pref; | 
					
						
							|  |  |  |         return pref; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private UpdatePreferences() { | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         this.auth.xhr({ | 
					
						
							|  |  |  |             method: 'GET', | 
					
						
							|  |  |  |             path: '/api/0.6/user/preferences' | 
					
						
							|  |  |  |         }, function (error, value: XMLDocument) { | 
					
						
							|  |  |  |             if (error) { | 
					
						
							|  |  |  |                 console.log("Could not load preferences", error); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const prefs = value.getElementsByTagName("preference"); | 
					
						
							|  |  |  |             for (let i = 0; i < prefs.length; i++) { | 
					
						
							|  |  |  |                 const pref = prefs[i]; | 
					
						
							|  |  |  |                 const k = pref.getAttribute("k"); | 
					
						
							|  |  |  |                 const v = pref.getAttribute("v"); | 
					
						
							|  |  |  |                 self.preferences.data[k] = v; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             self.preferences.ping(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private SetPreference(k: string, v: string) { | 
					
						
							|  |  |  |         if (!this.userDetails.data.loggedIn) { | 
					
						
							| 
									
										
										
										
											2021-09-22 16:07:56 +02:00
										 |  |  |             console.debug(`Not saving preference ${k}: user not logged in`); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (this.preferences.data[k] === v) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-22 16:07:56 +02:00
										 |  |  |         console.debug("Updating preference", k, " to ", Utils.EllipsesAfter(v, 15)); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 20:11:43 +02:00
										 |  |  |         if (v === undefined || v === "") { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             this.auth.xhr({ | 
					
						
							|  |  |  |                 method: 'DELETE', | 
					
						
							| 
									
										
										
										
											2021-01-15 01:57:46 +01:00
										 |  |  |                 path: '/api/0.6/user/preferences/' + encodeURIComponent(k), | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                 options: {header: {'Content-Type': 'text/plain'}}, | 
					
						
							| 
									
										
										
										
											2020-08-30 01:13:18 +02:00
										 |  |  |             }, function (error) { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                 if (error) { | 
					
						
							| 
									
										
										
										
											2021-09-22 16:07:56 +02:00
										 |  |  |                     console.warn("Could not remove preference", error); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                     return; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-09-22 16:07:56 +02:00
										 |  |  |                 console.debug("Preference ", k, "removed!"); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.auth.xhr({ | 
					
						
							|  |  |  |             method: 'PUT', | 
					
						
							| 
									
										
										
										
											2021-01-15 01:57:46 +01:00
										 |  |  |             path: '/api/0.6/user/preferences/' + encodeURIComponent(k), | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             options: {header: {'Content-Type': 'text/plain'}}, | 
					
						
							|  |  |  |             content: v | 
					
						
							| 
									
										
										
										
											2020-08-30 01:13:18 +02:00
										 |  |  |         }, function (error) { | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |             if (error) { | 
					
						
							| 
									
										
										
										
											2020-08-27 11:11:20 +02:00
										 |  |  |                 console.log(`Could not set preference "${k}"'`, error); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-08-27 11:11:20 +02:00
										 |  |  |             console.log(`Preference ${k} written!`); | 
					
						
							| 
									
										
										
										
											2020-08-26 15:36:04 +02:00
										 |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |