From 3ca8ba18fd6a1569214f5d6298eca291cb8ceefc Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 27 Jul 2023 01:50:23 +0200 Subject: [PATCH] Fix: URL-parameter language disables the language picker, fix #1506 --- assets/layers/usersettings/usersettings.json | 11 ++++++++++- src/Logic/State/UserRelatedState.ts | 18 ++++++++++++++++-- src/Logic/Web/QueryParameters.ts | 3 +++ src/UI/LanguagePicker.ts | 7 ++++++- src/UI/i18n/Locale.ts | 2 +- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index c4b0e0ad3c..196a3b2a33 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -33,7 +33,16 @@ "id": "language_picker", "render": { "*": "{language_picker()}" - } + }, + "mappings": [ + { + "if": "__url_parameter_initialized:language=yes", + "icon": "./assets/layers/usersettings/translate_disabled.svg", + "then": { + "en": "The language was set via an URL-parameter and cannot be set by the user.²" + } + } + ] }, { "id": "inbox", diff --git a/src/Logic/State/UserRelatedState.ts b/src/Logic/State/UserRelatedState.ts index 390aa0657a..a84d814006 100644 --- a/src/Logic/State/UserRelatedState.ts +++ b/src/Logic/State/UserRelatedState.ts @@ -15,6 +15,7 @@ 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" /** * The part of the state which keeps track of user-related stuff, e.g. the OSM-connection, @@ -93,13 +94,21 @@ export default class UserRelatedState { this.osmConnection.GetLongPreference("identity", "mangrove") ) - this.language.addCallbackAndRunD((language) => Locale.language.setData(language)) - this.installedUserThemes = this.InitInstalledUserThemes() this.homeLocation = this.initHomeLocation() this.preferencesAsTags = this.initAmendedPrefs(layout, featureSwitches) + + this.syncLanguage() + } + + private syncLanguage() { + if (QueryParameters.wasInitialized("language")) { + return + } + + this.language.addCallbackAndRunD((language) => Locale.language.setData(language)) } private static initUserRelatedState(): LayerConfig { @@ -246,6 +255,10 @@ export default class UserRelatedState { amendedPrefs.data["__userjourney_" + key] = Constants.userJourney[key] } + for (const key of QueryParameters.initializedParameters()) { + amendedPrefs.data["__url_parameter_initialized:" + key] = "yes" + } + const osmConnection = this.osmConnection osmConnection.preferencesHandler.preferences.addCallback((newPrefs) => { for (const k in newPrefs) { @@ -268,6 +281,7 @@ export default class UserRelatedState { }) const usersettingsConfig = UserRelatedState.usersettingsConfig const translationMode = osmConnection.GetPreference("translation-mode") + Locale.language.mapD( (language) => { amendedPrefs.data["_language"] = language diff --git a/src/Logic/Web/QueryParameters.ts b/src/Logic/Web/QueryParameters.ts index 62158ae9fa..446982b499 100644 --- a/src/Logic/Web/QueryParameters.ts +++ b/src/Logic/Web/QueryParameters.ts @@ -71,6 +71,9 @@ export class QueryParameters { this.init() return QueryParameters._wasInitialized.has(key) } + public static initializedParameters(): ReadonlyArray { + return Array.from(QueryParameters._wasInitialized.keys()) + } private static addOrder(key) { if (this.order.indexOf(key) < 0) { diff --git a/src/UI/LanguagePicker.ts b/src/UI/LanguagePicker.ts index 5166f72673..497e0024b5 100644 --- a/src/UI/LanguagePicker.ts +++ b/src/UI/LanguagePicker.ts @@ -8,11 +8,16 @@ import Lazy from "./Base/Lazy" import Toggle from "./Input/Toggle" import LanguageUtils from "../Utils/LanguageUtils" import { UIEventSource } from "../Logic/UIEventSource" +import { QueryParameters } from "../Logic/Web/QueryParameters" export default class LanguagePicker extends Toggle { constructor(languages: string[], assignTo: UIEventSource) { console.log("Constructing a language pîcker for languages", languages) - if (languages === undefined || languages.length <= 1) { + if ( + languages === undefined || + languages.length <= 1 || + QueryParameters.wasInitialized("language") + ) { super(undefined, undefined, undefined) } else { const normalPicker = LanguagePicker.dropdownFor(languages, assignTo ?? Locale.language) diff --git a/src/UI/i18n/Locale.ts b/src/UI/i18n/Locale.ts index 4112ef8a4b..09848aa0d4 100644 --- a/src/UI/i18n/Locale.ts +++ b/src/UI/i18n/Locale.ts @@ -39,8 +39,8 @@ export default class Locale { "The language to display MapComplete in.", "The user display language is determined in the following order:", "", + "1. Use the language as set by the URL-parameter `language`. This will _disable_ setting the language by the user", "1. If the user did log in and did set their language before with MapComplete, use this language. This language selection is synchronized accross devices using the openstreetmap.org user preferences.", - "2. Use the language as set by the URL-parameter `language`. This will _disable_ saving the language to localStorage in case a non-logged-in user changes their language", "3. If the user visited MapComplete before and did change their language manually, this changed language will be saved in local storage. Use the language from local storage", "4. Use the navigator-language (if available)", "5. Use English",