forked from MapComplete/MapComplete
		
	Unofficial themes are remembered now
This commit is contained in:
		
							parent
							
								
									3305d108c7
								
							
						
					
					
						commit
						dd68cc39e7
					
				
					 4 changed files with 71 additions and 72 deletions
				
			
		|  | @ -103,7 +103,8 @@ export default class AvailableBaseLayersImplementation implements AvailableBaseL | ||||||
|                     id: id, |                     id: id, | ||||||
|                     name: name, |                     name: name, | ||||||
|                     layer: () => L.tileLayer.provider(id, { |                     layer: () => L.tileLayer.provider(id, { | ||||||
|                         maxNativeZoom: layer.options?.maxZoom |                         maxNativeZoom: layer.options?.maxZoom, | ||||||
|  |                        maxZoom: Math.max(layer.options?.maxZoom ?? 19, 21) | ||||||
|                     }), |                     }), | ||||||
|                     min_zoom: 1, |                     min_zoom: 1, | ||||||
|                     max_zoom: layer.options.maxZoom, |                     max_zoom: layer.options.maxZoom, | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import {Utils} from "../../Utils"; | ||||||
| export class OsmPreferences { | export class OsmPreferences { | ||||||
| 
 | 
 | ||||||
|     public preferences = new UIEventSource<any>({}, "all-osm-preferences"); |     public preferences = new UIEventSource<any>({}, "all-osm-preferences"); | ||||||
|     public preferenceSources: any = {} |     private readonly preferenceSources = new Map<string, UIEventSource<string>>() | ||||||
|     private auth: any; |     private auth: any; | ||||||
|     private userDetails: UIEventSource<UserDetails>; |     private userDetails: UIEventSource<UserDetails>; | ||||||
|     private longPreferences = {}; |     private longPreferences = {}; | ||||||
|  | @ -29,6 +29,7 @@ export class OsmPreferences { | ||||||
|             return this.longPreferences[prefix + key]; |             return this.longPreferences[prefix + key]; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key); |         const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key); | ||||||
|         this.longPreferences[prefix + key] = source; |         this.longPreferences[prefix + key] = source; | ||||||
| 
 | 
 | ||||||
|  | @ -36,6 +37,10 @@ export class OsmPreferences { | ||||||
|         // Gives the number of combined preferences
 |         // Gives the number of combined preferences
 | ||||||
|         const length = this.GetPreference(allStartWith + "-length", ""); |         const length = this.GetPreference(allStartWith + "-length", ""); | ||||||
| 
 | 
 | ||||||
|  |        if( (allStartWith + "-length").length > 255){ | ||||||
|  |            throw "This preference key is too long, it has "+key.length+" characters, but at most "+(255 - "-length".length - "-combined".length - prefix.length)+" characters are allowed" | ||||||
|  |        } | ||||||
|  | 
 | ||||||
|         const self = this; |         const self = this; | ||||||
|         source.addCallback(str => { |         source.addCallback(str => { | ||||||
|             if (str === undefined || str === "") { |             if (str === undefined || str === "") { | ||||||
|  | @ -101,24 +106,21 @@ export class OsmPreferences { | ||||||
|         if (key.length >= 255) { |         if (key.length >= 255) { | ||||||
|             throw "Preferences: key length to big"; |             throw "Preferences: key length to big"; | ||||||
|         } |         } | ||||||
|         if (this.preferenceSources[key] !== undefined) { |         const cached = this.preferenceSources.get(key) | ||||||
|             return this.preferenceSources[key]; |         if (cached !== undefined) { | ||||||
|  |             return cached; | ||||||
|         } |         } | ||||||
|         if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) { |         if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) { | ||||||
|             this.UpdatePreferences(); |             this.UpdatePreferences(); | ||||||
|         } |         } | ||||||
|  |                  | ||||||
|         const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key); |         const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key); | ||||||
|         pref.addCallback((v) => { |         pref.addCallback((v) => { | ||||||
|             this.SetPreference(key, v); |             this.UploadPreference(key, v); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         this.preferences.addCallback((prefs) => { |  | ||||||
|             if (prefs[key] !== undefined) { |  | ||||||
|                 pref.setData(prefs[key]); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|          |          | ||||||
|         this.preferenceSources[key] = pref; |         this.preferenceSources.set(key, pref) | ||||||
|         return pref; |         return pref; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -167,11 +169,25 @@ export class OsmPreferences { | ||||||
|                 const v = pref.getAttribute("v"); |                 const v = pref.getAttribute("v"); | ||||||
|                 self.preferences.data[k] = v; |                 self.preferences.data[k] = v; | ||||||
|             } |             } | ||||||
|  |              | ||||||
|  |             // We merge all the preferences: new keys are uploaded
 | ||||||
|  |             // For differing values, the server overrides local changes
 | ||||||
|  |             self.preferenceSources.forEach((preference, key) => { | ||||||
|  |                 const osmValue = self.preferences[key] | ||||||
|  |                 if(osmValue === undefined){ | ||||||
|  |                     // OSM doesn't know this value yet
 | ||||||
|  |                     self.UploadPreference(key, preference.data) | ||||||
|  |                 } else { | ||||||
|  |                     // OSM does have a value - set it
 | ||||||
|  |                     preference.setData(osmValue) | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |              | ||||||
|             self.preferences.ping(); |             self.preferences.ping(); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private SetPreference(k: string, v: string) { |     private UploadPreference(k: string, v: string) { | ||||||
|         if (!this.userDetails.data.loggedIn) { |         if (!this.userDetails.data.loggedIn) { | ||||||
|             console.debug(`Not saving preference ${k}: user not logged in`); |             console.debug(`Not saving preference ${k}: user not logged in`); | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|  | @ -29,17 +29,6 @@ export default class UserRelatedState extends ElementsState { | ||||||
|      */ |      */ | ||||||
|     public favouriteLayers: UIEventSource<string[]>; |     public favouriteLayers: UIEventSource<string[]>; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * WHich other themes the user previously visited |  | ||||||
|      */ |  | ||||||
|     public installedThemes: UIEventSource<{ |  | ||||||
|         id: string, // The id doubles as the URL
 |  | ||||||
|         icon: string, |  | ||||||
|         title: any, |  | ||||||
|         shortDescription: any |  | ||||||
|     }[]>; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { |     constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { | ||||||
|         super(layoutToUse); |         super(layoutToUse); | ||||||
| 
 | 
 | ||||||
|  | @ -73,50 +62,15 @@ export default class UserRelatedState extends ElementsState { | ||||||
|             }) |             }) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.installedThemes = this.osmConnection.GetLongPreference("installed-themes").map( |         if (this.layoutToUse !== undefined && !this.layoutToUse.official) { | ||||||
|             str => { |             console.log("Marking unofficial theme as visited") | ||||||
|                 if (str === undefined || str === "") { |             this.osmConnection.GetLongPreference("unofficial-theme-" + this.layoutToUse.id) | ||||||
|                     return [] |                 .setData(JSON.stringify({ | ||||||
|                 } |                     id: this.layoutToUse.id, | ||||||
|                 try { |                     icon: this.layoutToUse.icon, | ||||||
|                     return JSON.parse(str); |                     title: this.layoutToUse.title.translations, | ||||||
|                 } catch (e) { |                     shortDescription: this.layoutToUse.shortDescription.translations | ||||||
|                     console.warn("Could not parse preference with installed themes due to ", e, "\nThe offending string is", str) |                 })) | ||||||
|                     return [] |  | ||||||
|                 } |  | ||||||
|             }, [], (installed) => JSON.stringify(installed) |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         const self = this; |  | ||||||
| 
 |  | ||||||
|         if (this.layoutToUse?.id?.startsWith("http")) { |  | ||||||
|             this.installedThemes.addCallbackAndRun(currentThemes => { |  | ||||||
|                 if (currentThemes === undefined) { |  | ||||||
|                     // We wait till we are logged in
 |  | ||||||
|                     return |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (self.osmConnection.isLoggedIn.data == false) { |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (currentThemes.some(installed => installed.id === this.layoutToUse.id)) { |  | ||||||
|                     // Already added to the 'installed theme' list
 |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 console.log("Current installed themes are", this.installedThemes.data) |  | ||||||
|                 currentThemes.push({ |  | ||||||
|                     id: self.layoutToUse.id, |  | ||||||
|                     icon: self.layoutToUse.icon, |  | ||||||
|                     title: self.layoutToUse.title.translations, |  | ||||||
|                     shortDescription: self.layoutToUse.shortDescription.translations |  | ||||||
|                 }) |  | ||||||
|                 self.installedThemes.ping() |  | ||||||
|                 console.log("Registered " + self.layoutToUse.id + " as installed themes") |  | ||||||
| 
 |  | ||||||
|             }) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -120,14 +120,42 @@ export default class MoreScreen extends Combine { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static createUnofficialThemeList(buttonClass: string, state: UserRelatedState, themeListClasses): BaseUIElement { |     private static createUnofficialThemeList(buttonClass: string, state: UserRelatedState, themeListClasses): BaseUIElement { | ||||||
|         return new VariableUiElement(state.installedThemes.map(customThemes => { |         const prefix = "mapcomplete-unofficial-theme-"; | ||||||
|             if (customThemes.length <= 0) { |         return new VariableUiElement(state.osmConnection.preferencesHandler.preferences.map(allPreferences => { | ||||||
|  |             console.log("All preferences are ", allPreferences) | ||||||
|  |             const allThemes: BaseUIElement[] = [] | ||||||
|  |             for (const key in allPreferences) { | ||||||
|  |                 if (key.startsWith(prefix) && key.endsWith("-combined-length")) { | ||||||
|  |                     const id = key.substring(0, key.length - "-length".length) | ||||||
|  |                     const length = Number(allPreferences[key]) | ||||||
|  | 
 | ||||||
|  |                     let str = ""; | ||||||
|  |                     for (let i = 0; i < length; i++) { | ||||||
|  |                         str += allPreferences[id + "-" + i] | ||||||
|  |                     } | ||||||
|  |                     console.log("Theme " + id + " has settings ", str) | ||||||
|  |                     try { | ||||||
|  |                         const value: { | ||||||
|  |                             id: string | ||||||
|  |                             icon: string, | ||||||
|  |                             title: any, | ||||||
|  |                             shortDescription: any | ||||||
|  |                         } = JSON.parse(str) | ||||||
|  | 
 | ||||||
|  |                         const link = MoreScreen.createLinkButton(state, value, true).SetClass(buttonClass) | ||||||
|  |                         allThemes.push(link) | ||||||
|  |                     } catch (e) { | ||||||
|  |                         console.error("Could not parse unofficial theme information for " + id, e) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (allThemes.length <= 0) { | ||||||
|                 return undefined; |                 return undefined; | ||||||
|             } |             } | ||||||
|             const customThemeButtons = customThemes.map(theme => MoreScreen.createLinkButton(state, theme, true)?.SetClass(buttonClass)) |  | ||||||
|             return new Combine([ |             return new Combine([ | ||||||
|                 Translations.t.general.customThemeIntro.Clone(), |                 Translations.t.general.customThemeIntro.Clone(), | ||||||
|                 new Combine(customThemeButtons).SetClass(themeListClasses) |                 new Combine(allThemes).SetClass(themeListClasses) | ||||||
|             ]); |             ]); | ||||||
|         })); |         })); | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue