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, | ||||
|                     name: name, | ||||
|                     layer: () => L.tileLayer.provider(id, { | ||||
|                         maxNativeZoom: layer.options?.maxZoom | ||||
|                         maxNativeZoom: layer.options?.maxZoom, | ||||
|                        maxZoom: Math.max(layer.options?.maxZoom ?? 19, 21) | ||||
|                     }), | ||||
|                     min_zoom: 1, | ||||
|                     max_zoom: layer.options.maxZoom, | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import {Utils} from "../../Utils"; | |||
| export class OsmPreferences { | ||||
| 
 | ||||
|     public preferences = new UIEventSource<any>({}, "all-osm-preferences"); | ||||
|     public preferenceSources: any = {} | ||||
|     private readonly preferenceSources = new Map<string, UIEventSource<string>>() | ||||
|     private auth: any; | ||||
|     private userDetails: UIEventSource<UserDetails>; | ||||
|     private longPreferences = {}; | ||||
|  | @ -29,6 +29,7 @@ export class OsmPreferences { | |||
|             return this.longPreferences[prefix + key]; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key); | ||||
|         this.longPreferences[prefix + key] = source; | ||||
| 
 | ||||
|  | @ -36,6 +37,10 @@ export class OsmPreferences { | |||
|         // Gives the number of combined preferences
 | ||||
|         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; | ||||
|         source.addCallback(str => { | ||||
|             if (str === undefined || str === "") { | ||||
|  | @ -101,24 +106,21 @@ export class OsmPreferences { | |||
|         if (key.length >= 255) { | ||||
|             throw "Preferences: key length to big"; | ||||
|         } | ||||
|         if (this.preferenceSources[key] !== undefined) { | ||||
|             return this.preferenceSources[key]; | ||||
|         const cached = this.preferenceSources.get(key) | ||||
|         if (cached !== undefined) { | ||||
|             return cached; | ||||
|         } | ||||
|         if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) { | ||||
|             this.UpdatePreferences(); | ||||
|         } | ||||
|                  | ||||
|         const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key); | ||||
|         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; | ||||
|     } | ||||
| 
 | ||||
|  | @ -167,11 +169,25 @@ export class OsmPreferences { | |||
|                 const v = pref.getAttribute("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(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private SetPreference(k: string, v: string) { | ||||
|     private UploadPreference(k: string, v: string) { | ||||
|         if (!this.userDetails.data.loggedIn) { | ||||
|             console.debug(`Not saving preference ${k}: user not logged in`); | ||||
|             return; | ||||
|  |  | |||
|  | @ -29,17 +29,6 @@ export default class UserRelatedState extends ElementsState { | |||
|      */ | ||||
|     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 }) { | ||||
|         super(layoutToUse); | ||||
| 
 | ||||
|  | @ -73,50 +62,15 @@ export default class UserRelatedState extends ElementsState { | |||
|             }) | ||||
|         } | ||||
| 
 | ||||
|         this.installedThemes = this.osmConnection.GetLongPreference("installed-themes").map( | ||||
|             str => { | ||||
|                 if (str === undefined || str === "") { | ||||
|                     return [] | ||||
|                 } | ||||
|                 try { | ||||
|                     return JSON.parse(str); | ||||
|                 } catch (e) { | ||||
|                     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") | ||||
| 
 | ||||
|             }) | ||||
|         if (this.layoutToUse !== undefined && !this.layoutToUse.official) { | ||||
|             console.log("Marking unofficial theme as visited") | ||||
|             this.osmConnection.GetLongPreference("unofficial-theme-" + this.layoutToUse.id) | ||||
|                 .setData(JSON.stringify({ | ||||
|                     id: this.layoutToUse.id, | ||||
|                     icon: this.layoutToUse.icon, | ||||
|                     title: this.layoutToUse.title.translations, | ||||
|                     shortDescription: this.layoutToUse.shortDescription.translations | ||||
|                 })) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -120,14 +120,42 @@ export default class MoreScreen extends Combine { | |||
|     } | ||||
| 
 | ||||
|     private static createUnofficialThemeList(buttonClass: string, state: UserRelatedState, themeListClasses): BaseUIElement { | ||||
|         return new VariableUiElement(state.installedThemes.map(customThemes => { | ||||
|             if (customThemes.length <= 0) { | ||||
|         const prefix = "mapcomplete-unofficial-theme-"; | ||||
|         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; | ||||
|             } | ||||
|             const customThemeButtons = customThemes.map(theme => MoreScreen.createLinkButton(state, theme, true)?.SetClass(buttonClass)) | ||||
|             return new Combine([ | ||||
|                 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