diff --git a/UI/BigComponents/UserInformation.ts b/UI/BigComponents/UserInformation.ts index 5ee1ec693..87e7d28da 100644 --- a/UI/BigComponents/UserInformation.ts +++ b/UI/BigComponents/UserInformation.ts @@ -23,6 +23,8 @@ import * as usersettings from "../../assets/generated/layers/usersettings.json" import { LoginToggle } from "../Popup/LoginButton" import LayerConfig from "../../Models/ThemeConfig/LayerConfig" import * as translators from "../../assets/translators.json" +import * as codeContributors from "../../assets/contributors.json" + export class ImportViewerLinks extends VariableUiElement { constructor(osmConnection: OsmConnection) { super( @@ -101,6 +103,7 @@ class UserInformationMainPanel extends VariableUiElement { const imgSize = "h-6 w-6" const ud = osmConnection.userDetails const settings = new UIEventSource>({}) + const usersettingsConfig = new LayerConfig(usersettings, "userinformationpanel") const amendedPrefs = new UIEventSource({}) osmConnection.preferencesHandler.preferences.addCallback((newPrefs) => { @@ -113,14 +116,44 @@ class UserInformationMainPanel extends VariableUiElement { 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, + }) + console.warn("Calculation for", name, "yielded", result) + 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.some( + const isTranslator = translators.contributors.find( (c: { contributor: string; commits: number }) => { const replaced = c.contributor.toLowerCase().replace(/\s+/g, "") return replaced === simplifiedName } ) - amendedPrefs.data["_is_translator"] = "" + 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 + } + ) + amendedPrefs.data["_code_contributions"] = "" + isCodeContributor.commits amendedPrefs.ping() }) @@ -176,7 +209,6 @@ class UserInformationMainPanel extends VariableUiElement { }) } - const usersettingsConfig = new LayerConfig(usersettings, "userinformationpanel") const settingElements = [] for (const c of usersettingsConfig.tagRenderings) { const settingsPanel = new SingleUserSettingsPanel( @@ -243,6 +275,7 @@ class UserInformationMainPanel extends VariableUiElement { export default class UserInformationPanel extends ScrollableFullScreen { private readonly userPanel: UserInformationMainPanel + constructor( state: { readonly layoutToUse: LayoutConfig @@ -283,6 +316,6 @@ export default class UserInformationPanel extends ScrollableFullScreen { Activate() { super.Activate() - this.userPanel.focusOnSelectedQuestion() + this.userPanel?.focusOnSelectedQuestion() } } diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index 590dda6de..57736a7e7 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -7,6 +7,13 @@ "source": { "osmTags": "id~*" }, + "calculatedTags": [ + "_mastodon_candidate_md=feat.properties._description.match(/\\[[^\\]]*\\]\\((.*(mastodon|en.osm.town).*)\\).*/)?.at(1)", + "_d=feat.properties._description?.replace(/</g,'<')?.replace(/>/g,'>') ?? ''", + "_mastodon_candidate_a=(feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName(\"a\")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) ", + "_mastodon_link=(feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName(\"a\")).filter(a => a.getAttribute(\"rel\")?.indexOf('me') >= 0)[0]?.href})(feat) ", + "_mastodon_candidate=feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a" + ], "tagRenderings": [ { "id": "picture-license", @@ -43,13 +50,43 @@ ] }, { - "id": "translation-thanks", - "condition": "_is_translator=true", + "id": "verified-mastodon", "mappings": [ { - "if": "_is_translator=true", + "if": "_mastodon_link~*", "then": { - "en": "You have contributed to translating MapComplete! That's awesome!" + "en": "A link to your Mastodon-profile has been been found: {_mastodon_link}" + }, + "icon": "mastodon" + }, + { + "if": "_mastodon_candidate~*", + "then": { + "en": "We found a link to what looks to be a mastodon account, but it is unverified. Edit your profile description and place the following there: <a href=\"{_mastodon_candidate}\" rel=\"me\">Mastodon</a>" + }, + "icon": "invalid" + } + ] + }, + { + "id": "translation-thanks", + "mappings": [ + { + "if": "_translation_contributions>0", + "then": { + "en": "You have contributed to translating MapComplete with {_translation_contributions} commits! That's awesome!" + }, + "icon": "party" + } + ] + }, + { + "id": "contributor-thanks", + "mappings": [ + { + "if": "_code_contributions>0", + "then": { + "en": "You have contributed code to MapComplete with {_code_contributions} commits! That's awesome!" }, "icon": "party" } @@ -62,4 +99,4 @@ } ], "mapRendering": null -} \ No newline at end of file +}