| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  | import ThemeConfig, { MinimalThemeInformation } from "../../Models/ThemeConfig/ThemeConfig" | 
					
						
							| 
									
										
										
										
											2023-09-28 23:50:27 +02:00
										 |  |  | import { OsmConnection } from "../Osm/OsmConnection" | 
					
						
							|  |  |  | import { MangroveIdentity } from "../Web/MangroveReviews" | 
					
						
							|  |  |  | import { Store, Stores, UIEventSource } from "../UIEventSource" | 
					
						
							|  |  |  | import StaticFeatureSource from "../FeatureSource/Sources/StaticFeatureSource" | 
					
						
							|  |  |  | import { FeatureSource } from "../FeatureSource/FeatureSource" | 
					
						
							|  |  |  | import { Feature } from "geojson" | 
					
						
							|  |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import translators from "../../assets/translators.json" | 
					
						
							|  |  |  | import codeContributors from "../../assets/contributors.json" | 
					
						
							|  |  |  | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | 
					
						
							|  |  |  | import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson" | 
					
						
							|  |  |  | import usersettings from "../../../src/assets/generated/layers/usersettings.json" | 
					
						
							|  |  |  | import Locale from "../../UI/i18n/Locale" | 
					
						
							|  |  |  | import LinkToWeblate from "../../UI/Base/LinkToWeblate" | 
					
						
							|  |  |  | import FeatureSwitchState from "./FeatureSwitchState" | 
					
						
							|  |  |  | import Constants from "../../Models/Constants" | 
					
						
							|  |  |  | import { QueryParameters } from "../Web/QueryParameters" | 
					
						
							|  |  |  | import { ThemeMetaTagging } from "./UserSettingsMetaTagging" | 
					
						
							|  |  |  | import { MapProperties } from "../../Models/MapProperties" | 
					
						
							| 
									
										
										
										
											2024-08-10 12:09:55 +02:00
										 |  |  | import Showdown from "showdown" | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  | import { LocalStorageSource } from "../Web/LocalStorageSource" | 
					
						
							| 
									
										
										
										
											2024-09-11 01:46:55 +02:00
										 |  |  | import { GeocodeResult } from "../Search/GeocodingProvider" | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class OptionallySyncedHistory<T> { | 
					
						
							|  |  |  |     public readonly syncPreference: UIEventSource<"sync" | "local" | "no"> | 
					
						
							|  |  |  |     public readonly value: Store<T[]> | 
					
						
							|  |  |  |     private readonly synced: UIEventSource<T[]> | 
					
						
							|  |  |  |     private readonly local: UIEventSource<T[]> | 
					
						
							|  |  |  |     private readonly thisSession: UIEventSource<T[]> | 
					
						
							|  |  |  |     private readonly _maxHistory: number | 
					
						
							|  |  |  |     private readonly _isSame: (a: T, b: T) => boolean | 
					
						
							|  |  |  |     private osmconnection: OsmConnection | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         key: string, | 
					
						
							|  |  |  |         osmconnection: OsmConnection, | 
					
						
							|  |  |  |         maxHistory: number = 20, | 
					
						
							|  |  |  |         isSame?: (a: T, b: T) => boolean | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         this.osmconnection = osmconnection | 
					
						
							|  |  |  |         this._maxHistory = maxHistory | 
					
						
							|  |  |  |         this._isSame = isSame | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         this.syncPreference = osmconnection.getPreference("preference-" + key + "-history", "sync") | 
					
						
							|  |  |  |         const synced = (this.synced = UIEventSource.asObject<T[]>( | 
					
						
							|  |  |  |             osmconnection.getPreference(key + "-history"), | 
					
						
							|  |  |  |             [] | 
					
						
							|  |  |  |         )) | 
					
						
							|  |  |  |         const local = (this.local = LocalStorageSource.getParsed<T[]>(key + "-history", [])) | 
					
						
							|  |  |  |         const thisSession = (this.thisSession = new UIEventSource<T[]>( | 
					
						
							|  |  |  |             [], | 
					
						
							|  |  |  |             "optionally-synced:" + key + "(session only)" | 
					
						
							|  |  |  |         )) | 
					
						
							|  |  |  |         this.syncPreference.addCallback((syncmode) => { | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |             if (syncmode === "sync") { | 
					
						
							|  |  |  |                 let list = [...thisSession.data, ...synced.data].slice(0, maxHistory) | 
					
						
							|  |  |  |                 if (this._isSame) { | 
					
						
							|  |  |  |                     for (let i = 0; i < list.length; i++) { | 
					
						
							|  |  |  |                         for (let j = i + 1; j < list.length; j++) { | 
					
						
							|  |  |  |                             if (this._isSame(list[i], list[j])) { | 
					
						
							|  |  |  |                                 list.splice(j, 1) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 synced.set(list) | 
					
						
							|  |  |  |             } else if (syncmode === "local") { | 
					
						
							|  |  |  |                 local.set(synced.data?.slice(0, maxHistory)) | 
					
						
							|  |  |  |                 synced.set([]) | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 synced.set([]) | 
					
						
							|  |  |  |                 local.set([]) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         this.value = this.syncPreference.bind((syncPref) => this.getAppropriateStore(syncPref)) | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private getAppropriateStore(syncPref?: string) { | 
					
						
							|  |  |  |         syncPref ??= this.syncPreference.data | 
					
						
							|  |  |  |         if (syncPref === "sync") { | 
					
						
							|  |  |  |             return this.synced | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (syncPref === "local") { | 
					
						
							|  |  |  |             return this.local | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return this.thisSession | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public add(t: T) { | 
					
						
							|  |  |  |         const store = this.getAppropriateStore() | 
					
						
							|  |  |  |         let oldList = store.data ?? [] | 
					
						
							|  |  |  |         if (this._isSame) { | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             oldList = oldList.filter((x) => !this._isSame(t, x)) | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         store.set([t, ...oldList].slice(0, this._maxHistory)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Adds the value when the user is actually logged in | 
					
						
							|  |  |  |      * @param t | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public addDefferred(t: T) { | 
					
						
							|  |  |  |         if (t === undefined) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         this.osmconnection.isLoggedIn.addCallbackAndRun((loggedIn) => { | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |             if (!loggedIn) { | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             this.add(t) | 
					
						
							|  |  |  |             return true | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     clear() { | 
					
						
							|  |  |  |         this.getAppropriateStore().set([]) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											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-12-26 12:09:48 +01:00
										 |  |  |     public static readonly usersettingsConfig = UserRelatedState.initUserSettingsState() | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |     public static readonly availableUserSettingsIds: string[] = | 
					
						
							|  |  |  |         UserRelatedState.usersettingsConfig?.tagRenderings?.map((tr) => tr.id) ?? [] | 
					
						
							| 
									
										
										
										
											2023-07-17 01:07:01 +02:00
										 |  |  |     public static readonly SHOW_TAGS_VALUES = ["always", "yes", "full"] as const | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      The user credentials | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public osmConnection: OsmConnection | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * 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-06-14 20:39:36 +02:00
										 |  |  |     public readonly showTags: UIEventSource<"no" | undefined | "always" | "yes" | "full"> | 
					
						
							| 
									
										
										
										
											2023-12-07 21:57:20 +01:00
										 |  |  |     public readonly showCrosshair: UIEventSource<"yes" | "always" | "no" | undefined> | 
					
						
							| 
									
										
										
										
											2024-08-26 17:23:04 +02:00
										 |  |  |     public readonly translationMode: UIEventSource<"false" | "true" | "mobile" | undefined | string> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-18 01:26:04 +02:00
										 |  |  |     public readonly fixateNorth: UIEventSource<undefined | "yes"> | 
					
						
							| 
									
										
										
										
											2024-01-01 03:29:57 +01:00
										 |  |  |     public readonly a11y: UIEventSource<undefined | "always" | "never" | "default"> | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     public readonly homeLocation: FeatureSource | 
					
						
							| 
									
										
										
										
											2024-05-06 18:58:19 +02:00
										 |  |  |     public readonly morePrivacy: UIEventSource<undefined | "yes" | "no"> | 
					
						
							| 
									
										
										
										
											2023-11-19 01:05:15 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * The language as saved into the preferences of the user, if logged in. | 
					
						
							|  |  |  |      * Note that this is _different_ from the languages a user can set via the osm.org interface here: https://www.openstreetmap.org/preferences
 | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-06 00:03:50 +02:00
										 |  |  |     public readonly language: UIEventSource<string> | 
					
						
							| 
									
										
										
										
											2023-09-28 23:50:27 +02:00
										 |  |  |     public readonly preferredBackgroundLayer: UIEventSource< | 
					
						
							|  |  |  |         string | "photo" | "map" | "osmbasedmap" | undefined | 
					
						
							|  |  |  |     > | 
					
						
							|  |  |  |     public readonly imageLicense: UIEventSource<string> | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * 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, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         "gps_location_retention" | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-06-21 02:36:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-24 13:11:35 +02:00
										 |  |  |     public readonly addNewFeatureMode = new UIEventSource< | 
					
						
							|  |  |  |         "button" | "button_click_right" | "button_click" | "click" | "click_right" | 
					
						
							|  |  |  |     >("button_click_right") | 
					
						
							| 
									
										
										
										
											2024-06-21 02:36:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |     public readonly showScale: UIEventSource<boolean> | 
					
						
							| 
									
										
										
										
											2024-09-12 01:53:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2023-09-24 16:34:36 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * Some metainformation that should not be edited starts with a single underscore | 
					
						
							|  |  |  |      * Constants and query parameters start with two underscores | 
					
						
							|  |  |  |      * Note: these are linked via OsmConnection.preferences which exports all preferences as UIEventSource | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public readonly preferencesAsTags: UIEventSource<Record<string, string>> | 
					
						
							| 
									
										
										
										
											2023-09-28 23:50:27 +02:00
										 |  |  |     private readonly _mapProperties: MapProperties | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |     public readonly recentlyVisitedThemes: OptionallySyncedHistory<string> | 
					
						
							|  |  |  |     public readonly recentlyVisitedSearch: OptionallySyncedHistory<GeocodeResult> | 
					
						
							| 
									
										
										
										
											2024-08-22 02:54:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         osmConnection: OsmConnection, | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |         layout?: ThemeConfig, | 
					
						
							| 
									
										
										
										
											2023-09-24 16:34:36 +02:00
										 |  |  |         featureSwitches?: FeatureSwitchState, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         mapProperties?: MapProperties | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         this.osmConnection = osmConnection | 
					
						
							| 
									
										
										
										
											2023-09-28 23:50:27 +02:00
										 |  |  |         this._mapProperties = mapProperties | 
					
						
							| 
									
										
										
										
											2022-02-16 01:46:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 01:36:27 +01:00
										 |  |  |         this.showAllQuestionsAtOnce = UIEventSource.asBoolean( | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             this.osmConnection.getPreference("show-all-questions", "false") | 
					
						
							| 
									
										
										
										
											2023-03-08 01:36:27 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |         this.language = this.osmConnection.getPreference("language") | 
					
						
							|  |  |  |         this.showTags = this.osmConnection.getPreference("show_tags") | 
					
						
							|  |  |  |         this.showCrosshair = this.osmConnection.getPreference("show_crosshair") | 
					
						
							|  |  |  |         this.fixateNorth = this.osmConnection.getPreference("fixate-north") | 
					
						
							|  |  |  |         this.morePrivacy = this.osmConnection.getPreference("more_privacy", "no") | 
					
						
							| 
									
										
										
										
											2024-05-06 18:58:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |         this.a11y = this.osmConnection.getPreference("a11y") | 
					
						
							| 
									
										
										
										
											2024-01-01 03:29:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         this.mangroveIdentity = new MangroveIdentity( | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |             this.osmConnection.getPreference("identity", undefined, "mangrove"), | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             this.osmConnection.getPreference("identity-creation-date", undefined, "mangrove") | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         this.preferredBackgroundLayer = this.osmConnection.getPreference( | 
					
						
							|  |  |  |             "preferred-background-layer" | 
					
						
							| 
									
										
										
										
											2023-09-28 23:50:27 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |         this.addNewFeatureMode = this.osmConnection.getPreference( | 
					
						
							| 
									
										
										
										
											2024-06-21 02:36:36 +02:00
										 |  |  |             "preferences-add-new-mode", | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             "button_click_right" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         this.showScale = UIEventSource.asBoolean( | 
					
						
							|  |  |  |             this.osmConnection.GetPreference("preference-show-scale", "false") | 
					
						
							| 
									
										
										
										
											2024-06-21 02:36:36 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |         this.imageLicense = this.osmConnection.getPreference("pictures-license", "CC0") | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         this.installedUserThemes = UserRelatedState.initInstalledUserThemes(osmConnection) | 
					
						
							| 
									
										
										
										
											2024-08-26 17:23:04 +02:00
										 |  |  |         this.translationMode = this.initTranslationMode() | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2023-07-27 01:50:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         this.recentlyVisitedThemes = new OptionallySyncedHistory<string>( | 
					
						
							|  |  |  |             "theme", | 
					
						
							|  |  |  |             this.osmConnection, | 
					
						
							|  |  |  |             10, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             (a, b) => a === b | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         this.recentlyVisitedSearch = new OptionallySyncedHistory<GeocodeResult>( | 
					
						
							|  |  |  |             "places", | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |             this.osmConnection, | 
					
						
							|  |  |  |             15, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             (a, b) => a.osm_id === b.osm_id && a.osm_type === b.osm_type | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-07-27 01:50:23 +02:00
										 |  |  |         this.syncLanguage() | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         this.recentlyVisitedThemes.addDefferred(layout?.id) | 
					
						
							| 
									
										
										
										
											2023-07-27 01:50:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private syncLanguage() { | 
					
						
							|  |  |  |         if (QueryParameters.wasInitialized("language")) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 01:05:15 +01:00
										 |  |  |         this.language.syncWith(Locale.language) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 17:23:04 +02:00
										 |  |  |     private initTranslationMode(): UIEventSource<"false" | "true" | "mobile" | undefined | string> { | 
					
						
							|  |  |  |         const translationMode: UIEventSource<undefined | "true" | "false" | "mobile" | string> = | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |             this.osmConnection.getPreference("translation-mode", "false") | 
					
						
							| 
									
										
										
										
											2024-08-26 17:23:04 +02: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) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         return translationMode | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 12:09:48 +01:00
										 |  |  |     private static initUserSettingsState(): LayerConfig { | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |         try { | 
					
						
							|  |  |  |             return new LayerConfig(<LayerConfigJson>usersettings, "userinformationpanel") | 
					
						
							|  |  |  |         } catch (e) { | 
					
						
							| 
									
										
										
										
											2023-05-19 11:22:25 +02:00
										 |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Adds a newly visited unofficial theme (or update the info). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param themeInfo note that themeInfo.id should be the URL where it was found | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |     public addUnofficialTheme(themeInfo: MinimalThemeInformation) { | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |         const pref = this.osmConnection.getPreference("unofficial-theme-" + themeInfo.id) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         this.osmConnection.isLoggedIn.when(() => pref.set(JSON.stringify(themeInfo))) | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |     public getUnofficialTheme(id: string): MinimalThemeInformation | undefined { | 
					
						
							| 
									
										
										
										
											2024-09-24 17:52:46 +02:00
										 |  |  |         const pref = this.osmConnection.getPreference("unofficial-theme-" + id) | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         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 { | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |             return JSON.parse(str) | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |         } catch (e) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             console.warn( | 
					
						
							|  |  |  |                 "Removing theme " + | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                     id + | 
					
						
							|  |  |  |                     " as it could not be parsed from the preferences; the content is:", | 
					
						
							|  |  |  |                 str | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-06-21 18:22:09 +02:00
										 |  |  |             pref.setData(null) | 
					
						
							|  |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |     public markLayoutAsVisited(layout: ThemeConfig) { | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  |                         .getPreference("hidden-theme-" + layout?.id + "-enabled") | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |                         .setData("true") | 
					
						
							|  |  |  |                     return true | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!layout.official) { | 
					
						
							| 
									
										
										
										
											2024-09-24 17:52:46 +02:00
										 |  |  |             this.osmConnection.getPreference("unofficial-theme-" + layout.id).setData( | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |                 JSON.stringify({ | 
					
						
							|  |  |  |                     id: layout.id, | 
					
						
							|  |  |  |                     icon: layout.icon, | 
					
						
							|  |  |  |                     title: layout.title.translations, | 
					
						
							|  |  |  |                     shortDescription: layout.shortDescription.translations, | 
					
						
							| 
									
										
										
										
											2024-09-02 12:48:15 +02:00
										 |  |  |                     definition: layout["definition"], | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-17 01:07:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |     public static initInstalledUserThemes(osmConnection: OsmConnection): Store<string[]> { | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |         const prefix = "mapcomplete-unofficial-theme-" | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         return osmConnection.preferencesHandler.allPreferences.map((prefs) => | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |             Object.keys(prefs) | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |                 .filter((k) => k.startsWith(prefix)) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 .map((k) => k.substring(prefix.length)) | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * List of all hidden themes that have been seen before | 
					
						
							|  |  |  |      * @param osmConnection | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static initDiscoveredHiddenThemes(osmConnection: OsmConnection): Store<string[]> { | 
					
						
							|  |  |  |         const prefix = "mapcomplete-hidden-theme-" | 
					
						
							|  |  |  |         const userPreferences = osmConnection.preferencesHandler.allPreferences | 
					
						
							|  |  |  |         return userPreferences.map((preferences) => | 
					
						
							|  |  |  |             Object.keys(preferences) | 
					
						
							|  |  |  |                 .filter((key) => key.startsWith(prefix)) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 .map((key) => key.substring(prefix.length, key.length - "-enabled".length)) | 
					
						
							| 
									
										
										
										
											2023-02-09 02:45:19 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             }) | 
					
						
							| 
									
										
										
										
											2023-03-24 19:21:15 +01:00
										 |  |  |         ).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], | 
					
						
							| 
									
										
										
										
											2024-09-02 12:48:15 +02:00
										 |  |  |                         _lat: homeLonLat[1], | 
					
						
							| 
									
										
										
										
											2023-03-25 02:48:24 +01:00
										 |  |  |                     }, | 
					
						
							|  |  |  |                     geometry: { | 
					
						
							|  |  |  |                         type: "Point", | 
					
						
							| 
									
										
										
										
											2024-09-02 12:48:15 +02:00
										 |  |  |                         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'. | 
					
						
							| 
									
										
										
										
											2023-12-15 01:46:01 +01:00
										 |  |  |      * This is inherently a dirty and chaotic method, as it shoves many properties into this EventSource | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |      * */ | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |     private initAmendedPrefs( | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |         layout?: ThemeConfig, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         featureSwitches?: FeatureSwitchState | 
					
						
							| 
									
										
										
										
											2023-04-14 17:53:08 +02:00
										 |  |  |     ): UIEventSource<Record<string, string>> { | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         const amendedPrefs = new UIEventSource<Record<string, string>>({ | 
					
						
							|  |  |  |             _theme: layout?.id, | 
					
						
							| 
									
										
										
										
											2023-09-24 18:24:10 +02:00
										 |  |  |             "_theme:backgroundLayer": layout?.defaultBackgroundId, | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             _backend: this.osmConnection.Backend(), | 
					
						
							| 
									
										
										
										
											2023-04-20 17:42:07 +02:00
										 |  |  |             _applicationOpened: new Date().toISOString(), | 
					
						
							| 
									
										
										
										
											2023-06-14 20:39:36 +02:00
										 |  |  |             _supports_sharing: | 
					
						
							|  |  |  |                 typeof window === "undefined" ? "no" : window.navigator.share ? "yes" : "no", | 
					
						
							| 
									
										
										
										
											2024-09-02 12:48:15 +02:00
										 |  |  |             _iframe: Utils.isIframe ? "yes" : "no", | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2025-01-22 18:22:03 +01:00
										 |  |  |         if(!Utils.runningFromConsole){ | 
					
						
							|  |  |  |             amendedPrefs.data["_host"] = window.location.host | 
					
						
							|  |  |  |             amendedPrefs.data["_path"] = window.location.pathname | 
					
						
							|  |  |  |             amendedPrefs.data["_userAgent"] = navigator.userAgent | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											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-07-27 01:50:23 +02:00
										 |  |  |         for (const key of QueryParameters.initializedParameters()) { | 
					
						
							|  |  |  |             amendedPrefs.data["__url_parameter_initialized:" + key] = "yes" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         const osmConnection = this.osmConnection | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |         osmConnection.preferencesHandler.allPreferences.addCallback((newPrefs) => { | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             for (const k in newPrefs) { | 
					
						
							| 
									
										
										
										
											2023-07-17 01:07:01 +02:00
										 |  |  |                 const v = newPrefs[k] | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |                 if (v === "undefined" || v === "null" || !v) { | 
					
						
							| 
									
										
										
										
											2023-11-23 17:06:30 +01:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |                 amendedPrefs.data[k] = newPrefs[k] ?? "" | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-07-17 01:07:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             amendedPrefs.ping() | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         Locale.language.mapD( | 
					
						
							|  |  |  |             (language) => { | 
					
						
							|  |  |  |                 amendedPrefs.data["_language"] = language | 
					
						
							| 
									
										
										
										
											2024-08-26 17:23:04 +02:00
										 |  |  |                 const trmode = this.translationMode.data | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                 if ((trmode === "true" || trmode === "mobile") && layout !== undefined) { | 
					
						
							| 
									
										
										
										
											2023-12-26 12:09:48 +01:00
										 |  |  |                     const extraInspection = UserRelatedState.usersettingsConfig | 
					
						
							|  |  |  |                     const missing = layout.missingTranslations(extraInspection) | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                     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:")) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                             .map((k) => k.slice("layers:".length).split(".")[0]) | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     const zenLinks: { link: string; id: string }[] = Utils.NoNull([ | 
					
						
							|  |  |  |                         hasMissingTheme | 
					
						
							|  |  |  |                             ? { | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +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, | 
					
						
							| 
									
										
										
										
											2024-09-02 12:48:15 +02:00
										 |  |  |                             link: LinkToWeblate.hrefToWeblateZen(language, "layers", id), | 
					
						
							|  |  |  |                         })), | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                     ]) | 
					
						
							|  |  |  |                     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() | 
					
						
							|  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |             [this.translationMode] | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-09-22 11:20:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 13:33:38 +01:00
										 |  |  |         this.mangroveIdentity.getKeyId().addCallbackAndRun((kid) => { | 
					
						
							| 
									
										
										
										
											2024-02-15 03:11:10 +01:00
										 |  |  |             amendedPrefs.data["mangrove_kid"] = kid | 
					
						
							|  |  |  |             amendedPrefs.ping() | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-22 11:20:22 +02:00
										 |  |  |         const usersettingMetaTagging = new ThemeMetaTagging() | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         osmConnection.userDetails.addCallback((userDetails) => { | 
					
						
							|  |  |  |             for (const k in userDetails) { | 
					
						
							|  |  |  |                 amendedPrefs.data["_" + k] = "" + userDetails[k] | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-08-22 02:54:46 +02:00
										 |  |  |             if (userDetails.description) { | 
					
						
							| 
									
										
										
										
											2024-08-14 13:53:56 +02:00
										 |  |  |                 amendedPrefs.data["_description_html"] = Utils.purify( | 
					
						
							|  |  |  |                     new Showdown.Converter() | 
					
						
							|  |  |  |                         .makeHtml(userDetails.description) | 
					
						
							|  |  |  |                         ?.replace(/>/g, ">") | 
					
						
							|  |  |  |                         ?.replace(/</g, "<") | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                         ?.replace(/\n/g, "") | 
					
						
							| 
									
										
										
										
											2024-08-14 13:53:56 +02:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-08-10 12:09:55 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-22 11:20:22 +02:00
										 |  |  |             usersettingMetaTagging.metaTaggging_for_usersettings({ properties: amendedPrefs.data }) | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             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 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |             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 | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |             ) | 
					
						
							|  |  |  |             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") { | 
					
						
							| 
									
										
										
										
											2024-08-23 02:16:24 +02:00
										 |  |  |                     // Language is managed separately
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |                 if (tags[key] === null) { | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-10-17 02:10:25 +02:00
										 |  |  |                 let pref = this.osmConnection.GetPreference(key, undefined, { prefix: "" }) | 
					
						
							| 
									
										
										
										
											2024-09-16 23:36:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 02:19:55 +02:00
										 |  |  |                 pref.set(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-09-28 23:50:27 +02:00
										 |  |  |         this._mapProperties?.rasterLayer?.addCallbackAndRun((l) => { | 
					
						
							| 
									
										
										
										
											2023-09-24 16:34:36 +02:00
										 |  |  |             amendedPrefs.data["__current_background"] = l?.properties?.id | 
					
						
							|  |  |  |             amendedPrefs.ping() | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 02:13:57 +02:00
										 |  |  |         return amendedPrefs | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-08 22:37:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The disabled questions for this theme and layer | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public getThemeDisabled(themeId: string, layerId: string): UIEventSource<string[]> { | 
					
						
							| 
									
										
										
										
											2024-11-28 12:00:23 +01:00
										 |  |  |         const flatSource = this.osmConnection.getPreference( | 
					
						
							|  |  |  |             "disabled-questions-" + themeId + "-" + layerId, | 
					
						
							|  |  |  |             "[]" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-10-08 22:37:11 +02:00
										 |  |  |         return UIEventSource.asObject<string[]>(flatSource, []) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |