| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  | import {OsmConnection} from "../Osm/OsmConnection" | 
					
						
							|  |  |  | import {MangroveIdentity} from "../Web/MangroveReviews" | 
					
						
							|  |  |  | import {Store, Stores, UIEventSource} from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | import StaticFeatureSource from "../FeatureSource/Sources/StaticFeatureSource" | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  | import {FeatureSource} from "../FeatureSource/FeatureSource" | 
					
						
							|  |  |  | import {Feature} from "geojson" | 
					
						
							|  |  |  | import {Utils} from "../../Utils" | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | import translators from "../../assets/translators.json" | 
					
						
							|  |  |  | import codeContributors from "../../assets/contributors.json" | 
					
						
							|  |  |  | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  | import {LayerConfigJson} from "../../Models/ThemeConfig/Json/LayerConfigJson" | 
					
						
							| 
									
										
										
										
											2023-05-19 11:35:38 +02:00
										 |  |  | import usersettings from "../../assets/generated/layers/usersettings.json" | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | import Locale from "../../UI/i18n/Locale" | 
					
						
							|  |  |  | import LinkToWeblate from "../../UI/Base/LinkToWeblate" | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  | import FeatureSwitchState from "./FeatureSwitchState" | 
					
						
							| 
									
										
										
										
											2023-05-11 02:17:41 +02:00
										 |  |  | import Constants from "../../Models/Constants"; | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The part of the state which keeps track of user-related stuff, e.g. the OSM-connection, | 
					
						
							|  |  |  |  * which layers they enabled, ... | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | export default class UserRelatedState { | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |     public static readonly usersettingsConfig = UserRelatedState.initUserRelatedState() | 
					
						
							|  |  |  |     public static readonly availableUserSettingsIds: string[] = | 
					
						
							|  |  |  |         UserRelatedState.usersettingsConfig?.tagRenderings?.map((tr) => tr.id) ?? [] | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      The user credentials | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public osmConnection: OsmConnection | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The key for mangrove | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     public readonly mangroveIdentity: MangroveIdentity | 
					
						
							| 
									
										
										
										
											2022-06-22 20:18:17 +02:00
										 |  |  |     public readonly installedUserThemes: Store<string[]> | 
					
						
							| 
									
										
										
										
											2023-03-08 01:36:27 +01:00
										 |  |  |     public readonly showAllQuestionsAtOnce: UIEventSource<boolean> | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |     public readonly showTags: UIEventSource<"no" | undefined | "always" | "yes">; | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     public readonly homeLocation: FeatureSource | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The number of seconds that the GPS-locations are stored in memory. | 
					
						
							|  |  |  |      * Time in seconds | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |     public readonly gpsLocationHistoryRetentionTime = new UIEventSource( | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         7 * 24 * 60 * 60, | 
					
						
							|  |  |  |         "gps_location_retention" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Preferences as tags exposes many preferences and state properties as record. | 
					
						
							|  |  |  |      * This is used to bridge the internal state with the usersettings.json layerconfig file | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public readonly preferencesAsTags: UIEventSource<Record<string, string>> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor( | 
					
						
							|  |  |  |         osmConnection: OsmConnection, | 
					
						
							|  |  |  |         availableLanguages?: string[], | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |         layout?: LayoutConfig, | 
					
						
							|  |  |  |         featureSwitches?: FeatureSwitchState | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         this.osmConnection = osmConnection | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |             const translationMode: UIEventSource<undefined | "true" | "false" | "mobile" | string> = | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                 this.osmConnection.GetPreference("translation-mode", "false") | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |             translationMode.addCallbackAndRunD((mode) => { | 
					
						
							|  |  |  |                 mode = mode.toLowerCase() | 
					
						
							|  |  |  |                 if (mode === "true" || mode === "yes") { | 
					
						
							|  |  |  |                     Locale.showLinkOnMobile.setData(false) | 
					
						
							|  |  |  |                     Locale.showLinkToWeblate.setData(true) | 
					
						
							|  |  |  |                 } else if (mode === "false" || mode === "no") { | 
					
						
							|  |  |  |                     Locale.showLinkToWeblate.setData(false) | 
					
						
							|  |  |  |                 } else if (mode === "mobile") { | 
					
						
							|  |  |  |                     Locale.showLinkOnMobile.setData(true) | 
					
						
							|  |  |  |                     Locale.showLinkToWeblate.setData(true) | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     Locale.showLinkOnMobile.setData(false) | 
					
						
							|  |  |  |                     Locale.showLinkToWeblate.setData(false) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-16 01:46:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 01:36:27 +01:00
										 |  |  |         this.showAllQuestionsAtOnce = UIEventSource.asBoolean( | 
					
						
							|  |  |  |             this.osmConnection.GetPreference("show-all-questions", "false", { | 
					
						
							|  |  |  |                 documentation: | 
					
						
							|  |  |  |                     "Either 'true' or 'false'. If set, all questions will be shown all at once", | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |         this.showTags = <UIEventSource<any>>this.osmConnection.GetPreference("show_tags") | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         this.mangroveIdentity = new MangroveIdentity( | 
					
						
							|  |  |  |             this.osmConnection.GetLongPreference("identity", "mangrove") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         this.InitializeLanguage(availableLanguages) | 
					
						
							| 
									
										
										
										
											2022-07-13 08:03:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         this.installedUserThemes = this.InitInstalledUserThemes() | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.homeLocation = this.initHomeLocation() | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |         this.preferencesAsTags = this.initAmendedPrefs(layout, featureSwitches) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |     private static initUserRelatedState(): LayerConfig { | 
					
						
							|  |  |  |         try{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new LayerConfig( | 
					
						
							|  |  |  |             <LayerConfigJson>usersettings, | 
					
						
							|  |  |  |             "userinformationpanel" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         }catch(e){ | 
					
						
							|  |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |     public GetUnofficialTheme(id: string): | 
					
						
							|  |  |  |         | { | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |         id: string | 
					
						
							|  |  |  |         icon: string | 
					
						
							|  |  |  |         title: any | 
					
						
							|  |  |  |         shortDescription: any | 
					
						
							|  |  |  |         definition?: any | 
					
						
							|  |  |  |         isOfficial: boolean | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         | undefined { | 
					
						
							|  |  |  |         console.log("GETTING UNOFFICIAL THEME") | 
					
						
							|  |  |  |         const pref = this.osmConnection.GetLongPreference("unofficial-theme-" + id) | 
					
						
							|  |  |  |         const str = pref.data | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         if (str === undefined || str === "undefined" || str === "") { | 
					
						
							|  |  |  |             pref.setData(null) | 
					
						
							|  |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         try { | 
					
						
							|  |  |  |             const value: { | 
					
						
							|  |  |  |                 id: string | 
					
						
							|  |  |  |                 icon: string | 
					
						
							|  |  |  |                 title: any | 
					
						
							|  |  |  |                 shortDescription: any | 
					
						
							|  |  |  |                 definition?: any | 
					
						
							|  |  |  |                 isOfficial: boolean | 
					
						
							|  |  |  |             } = JSON.parse(str) | 
					
						
							|  |  |  |             value.isOfficial = false | 
					
						
							|  |  |  |             return value | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							|  |  |  |             console.warn( | 
					
						
							|  |  |  |                 "Removing theme " + | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |                 id + | 
					
						
							|  |  |  |                 " as it could not be parsed from the preferences; the content is:", | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |                 str | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             pref.setData(null) | 
					
						
							|  |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     public markLayoutAsVisited(layout: LayoutConfig) { | 
					
						
							|  |  |  |         if (!layout) { | 
					
						
							|  |  |  |             console.error("Trying to mark a layout as visited, but ", layout, " got passed") | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (layout.hideFromOverview) { | 
					
						
							|  |  |  |             this.osmConnection.isLoggedIn.addCallbackAndRunD((loggedIn) => { | 
					
						
							|  |  |  |                 if (loggedIn) { | 
					
						
							|  |  |  |                     this.osmConnection | 
					
						
							|  |  |  |                         .GetPreference("hidden-theme-" + layout?.id + "-enabled") | 
					
						
							|  |  |  |                         .setData("true") | 
					
						
							|  |  |  |                     return true | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!layout.official) { | 
					
						
							|  |  |  |             this.osmConnection.GetLongPreference("unofficial-theme-" + layout.id).setData( | 
					
						
							|  |  |  |                 JSON.stringify({ | 
					
						
							|  |  |  |                     id: layout.id, | 
					
						
							|  |  |  |                     icon: layout.icon, | 
					
						
							|  |  |  |                     title: layout.title.translations, | 
					
						
							|  |  |  |                     shortDescription: layout.shortDescription.translations, | 
					
						
							|  |  |  |                     definition: layout["definition"], | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private InitializeLanguage(availableLanguages?: string[]) { | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |         Locale.language.syncWith(this.osmConnection.GetPreference("language")) | 
					
						
							|  |  |  |         Locale.language.addCallback((currentLanguage) => { | 
					
						
							|  |  |  |             if (Locale.showLinkToWeblate.data) { | 
					
						
							|  |  |  |                 return true // Disable auto switching as we are in translators mode
 | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |             if (availableLanguages?.indexOf(currentLanguage) < 0) { | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |                 console.log( | 
					
						
							|  |  |  |                     "Resetting language to", | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |                     availableLanguages[0], | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |                     "as", | 
					
						
							|  |  |  |                     currentLanguage, | 
					
						
							|  |  |  |                     " is unsupported" | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |                 // The current language is not supported -> switch to a supported one
 | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |                 Locale.language.setData(availableLanguages[0]) | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         Locale.language.ping() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private InitInstalledUserThemes(): Store<string[]> { | 
					
						
							|  |  |  |         const prefix = "mapcomplete-unofficial-theme-" | 
					
						
							|  |  |  |         const postfix = "-combined-length" | 
					
						
							|  |  |  |         return this.osmConnection.preferencesHandler.preferences.map((prefs) => | 
					
						
							|  |  |  |             Object.keys(prefs) | 
					
						
							|  |  |  |                 .filter((k) => k.startsWith(prefix) && k.endsWith(postfix)) | 
					
						
							|  |  |  |                 .map((k) => k.substring(prefix.length, k.length - postfix.length)) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private initHomeLocation(): FeatureSource { | 
					
						
							|  |  |  |         const empty = [] | 
					
						
							| 
									
										
										
										
											2023-03-25 02:48:24 +01:00
										 |  |  |         const feature: Store<Feature[]> = Stores.ListStabilized( | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |             this.osmConnection.userDetails.map((userDetails) => { | 
					
						
							|  |  |  |                 if (userDetails === undefined) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 const home = userDetails.home | 
					
						
							|  |  |  |                 if (home === undefined) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return [home.lon, home.lat] | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         ).map((homeLonLat) => { | 
					
						
							|  |  |  |             if (homeLonLat === undefined) { | 
					
						
							|  |  |  |                 return empty | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return [ | 
					
						
							| 
									
										
										
										
											2023-03-25 02:48:24 +01:00
										 |  |  |                 <Feature>{ | 
					
						
							|  |  |  |                     type: "Feature", | 
					
						
							|  |  |  |                     properties: { | 
					
						
							|  |  |  |                         id: "home", | 
					
						
							|  |  |  |                         "user:home": "yes", | 
					
						
							|  |  |  |                         _lon: homeLonLat[0], | 
					
						
							|  |  |  |                         _lat: homeLonLat[1], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     geometry: { | 
					
						
							|  |  |  |                         type: "Point", | 
					
						
							|  |  |  |                         coordinates: homeLonLat, | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |                     }, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         return new StaticFeatureSource(feature) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Initialize the 'amended preferences'. | 
					
						
							|  |  |  |      * This is inherently a dirty and chaotic method, as it shoves many properties into this EventSourcd | 
					
						
							|  |  |  |      * */ | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |     private initAmendedPrefs( | 
					
						
							|  |  |  |         layout?: LayoutConfig, | 
					
						
							|  |  |  |         featureSwitches?: FeatureSwitchState | 
					
						
							|  |  |  |     ): UIEventSource<Record<string, string>> { | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         const amendedPrefs = new UIEventSource<Record<string, string>>({ | 
					
						
							|  |  |  |             _theme: layout?.id, | 
					
						
							|  |  |  |             _backend: this.osmConnection.Backend(), | 
					
						
							| 
									
										
										
										
											2023-04-20 17:42:07 +02:00
										 |  |  |             _applicationOpened: new Date().toISOString(), | 
					
						
							| 
									
										
										
										
											2023-05-24 00:50:04 +02:00
										 |  |  |             _supports_sharing: (typeof window === "undefined") ? "no" : (window.navigator.share ? "yes" : "no") | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-11 02:17:41 +02:00
										 |  |  |         for (const key in Constants.userJourney) { | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |             amendedPrefs.data["__userjourney_" + key] = Constants.userJourney[key] | 
					
						
							| 
									
										
										
										
											2023-05-11 02:17:41 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         const osmConnection = this.osmConnection | 
					
						
							|  |  |  |         osmConnection.preferencesHandler.preferences.addCallback((newPrefs) => { | 
					
						
							|  |  |  |             for (const k in newPrefs) { | 
					
						
							|  |  |  |                 amendedPrefs.data[k] = newPrefs[k] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             amendedPrefs.ping() | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         const usersettingsConfig = UserRelatedState.usersettingsConfig | 
					
						
							|  |  |  |         const translationMode = osmConnection.GetPreference("translation-mode") | 
					
						
							|  |  |  |         Locale.language.mapD( | 
					
						
							|  |  |  |             (language) => { | 
					
						
							|  |  |  |                 amendedPrefs.data["_language"] = language | 
					
						
							|  |  |  |                 const trmode = translationMode.data | 
					
						
							|  |  |  |                 if ((trmode === "true" || trmode === "mobile") && layout !== undefined) { | 
					
						
							|  |  |  |                     const missing = layout.missingTranslations() | 
					
						
							|  |  |  |                     const total = missing.total | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     const untranslated = missing.untranslated.get(language) ?? [] | 
					
						
							|  |  |  |                     const hasMissingTheme = untranslated.some((k) => k.startsWith("themes:")) | 
					
						
							|  |  |  |                     const missingLayers = Utils.Dedup( | 
					
						
							|  |  |  |                         untranslated | 
					
						
							|  |  |  |                             .filter((k) => k.startsWith("layers:")) | 
					
						
							|  |  |  |                             .map((k) => k.slice("layers:".length).split(".")[0]) | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     const zenLinks: { link: string; id: string }[] = Utils.NoNull([ | 
					
						
							|  |  |  |                         hasMissingTheme | 
					
						
							|  |  |  |                             ? { | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |                                 id: "theme:" + layout.id, | 
					
						
							|  |  |  |                                 link: LinkToWeblate.hrefToWeblateZen( | 
					
						
							|  |  |  |                                     language, | 
					
						
							|  |  |  |                                     "themes", | 
					
						
							|  |  |  |                                     layout.id | 
					
						
							|  |  |  |                                 ), | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                             : undefined, | 
					
						
							|  |  |  |                         ...missingLayers.map((id) => ({ | 
					
						
							|  |  |  |                             id: "layer:" + id, | 
					
						
							|  |  |  |                             link: LinkToWeblate.hrefToWeblateZen(language, "layers", id), | 
					
						
							|  |  |  |                         })), | 
					
						
							|  |  |  |                     ]) | 
					
						
							|  |  |  |                     const untranslated_count = untranslated.length | 
					
						
							|  |  |  |                     amendedPrefs.data["_translation_total"] = "" + total | 
					
						
							|  |  |  |                     amendedPrefs.data["_translation_translated_count"] = | 
					
						
							|  |  |  |                         "" + (total - untranslated_count) | 
					
						
							|  |  |  |                     amendedPrefs.data["_translation_percentage"] = | 
					
						
							|  |  |  |                         "" + Math.floor((100 * (total - untranslated_count)) / total) | 
					
						
							|  |  |  |                     amendedPrefs.data["_translation_links"] = JSON.stringify(zenLinks) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 amendedPrefs.ping() | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             [translationMode] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         osmConnection.userDetails.addCallback((userDetails) => { | 
					
						
							|  |  |  |             for (const k in userDetails) { | 
					
						
							|  |  |  |                 amendedPrefs.data["_" + k] = "" + userDetails[k] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (const [name, code, _] of usersettingsConfig.calculatedTags) { | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                     let result = new Function("feat", "return " + code + ";")({ | 
					
						
							|  |  |  |                         properties: amendedPrefs.data, | 
					
						
							|  |  |  |                     }) | 
					
						
							|  |  |  |                     if (result !== undefined && result !== "" && result !== null) { | 
					
						
							|  |  |  |                         if (typeof result !== "string") { | 
					
						
							|  |  |  |                             result = JSON.stringify(result) | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         amendedPrefs.data[name] = result | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } catch (e) { | 
					
						
							|  |  |  |                     console.error( | 
					
						
							|  |  |  |                         "Calculating a tag for userprofile-settings failed for variable", | 
					
						
							|  |  |  |                         name, | 
					
						
							|  |  |  |                         e | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const simplifiedName = userDetails.name.toLowerCase().replace(/\s+/g, "") | 
					
						
							|  |  |  |             const isTranslator = translators.contributors.find( | 
					
						
							|  |  |  |                 (c: { contributor: string; commits: number }) => { | 
					
						
							|  |  |  |                     const replaced = c.contributor.toLowerCase().replace(/\s+/g, "") | 
					
						
							|  |  |  |                     return replaced === simplifiedName | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             if (isTranslator) { | 
					
						
							|  |  |  |                 amendedPrefs.data["_translation_contributions"] = "" + isTranslator.commits | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const isCodeContributor = codeContributors.contributors.find( | 
					
						
							|  |  |  |                 (c: { contributor: string; commits: number }) => { | 
					
						
							|  |  |  |                     const replaced = c.contributor.toLowerCase().replace(/\s+/g, "") | 
					
						
							|  |  |  |                     return replaced === simplifiedName | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             if (isCodeContributor) { | 
					
						
							|  |  |  |                 amendedPrefs.data["_code_contributions"] = "" + isCodeContributor.commits | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             amendedPrefs.ping() | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         amendedPrefs.addCallbackD((tags) => { | 
					
						
							|  |  |  |             for (const key in tags) { | 
					
						
							| 
									
										
										
										
											2023-04-20 17:42:07 +02:00
										 |  |  |                 if (key.startsWith("_") || key === "mapcomplete-language") { | 
					
						
							|  |  |  |                     // Language is managed seperately
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |                 this.osmConnection.GetPreference(key, undefined, {prefix: ""}).setData(tags[key]) | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |         for (const key in featureSwitches) { | 
					
						
							|  |  |  |             if (featureSwitches[key].addCallbackAndRun) { | 
					
						
							|  |  |  |                 featureSwitches[key].addCallbackAndRun((v) => { | 
					
						
							|  |  |  |                     const oldV = amendedPrefs.data["__" + key] | 
					
						
							|  |  |  |                     if (oldV === v) { | 
					
						
							|  |  |  |                         return | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     amendedPrefs.data["__" + key] = "" + v | 
					
						
							|  |  |  |                     amendedPrefs.ping() | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         return amendedPrefs | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | } |