forked from MapComplete/MapComplete
		
	Move license picker into usersettings, add possibility to highlight a setting
This commit is contained in:
		
							parent
							
								
									9202cbe8e2
								
							
						
					
					
						commit
						4ed88609e5
					
				
					 16 changed files with 204 additions and 103 deletions
				
			
		|  | @ -1,7 +1,7 @@ | ||||||
| import { Utils } from "../Utils" | import { Utils } from "../Utils" | ||||||
| 
 | 
 | ||||||
| export default class Constants { | export default class Constants { | ||||||
|     public static vNumber = "0.25.5" |     public static vNumber = "0.25.6" | ||||||
| 
 | 
 | ||||||
|     public static ImgurApiKey = "7070e7167f0a25a" |     public static ImgurApiKey = "7070e7167f0a25a" | ||||||
|     public static readonly mapillary_client_token_v4 = |     public static readonly mapillary_client_token_v4 = | ||||||
|  |  | ||||||
|  | @ -6,7 +6,8 @@ import Constants from "../Constants" | ||||||
| import TilesourceConfig from "./TilesourceConfig" | import TilesourceConfig from "./TilesourceConfig" | ||||||
| import { ExtractImages } from "./Conversion/FixImages" | import { ExtractImages } from "./Conversion/FixImages" | ||||||
| import ExtraLinkConfig from "./ExtraLinkConfig" | import ExtraLinkConfig from "./ExtraLinkConfig" | ||||||
| 
 | import { Utils } from "../../Utils" | ||||||
|  | import * as used_languages from "../../assets/generated/used_languages.json" | ||||||
| export default class LayoutConfig { | export default class LayoutConfig { | ||||||
|     public static readonly defaultSocialImage = "assets/SocialImage.png" |     public static readonly defaultSocialImage = "assets/SocialImage.png" | ||||||
|     public readonly id: string |     public readonly id: string | ||||||
|  | @ -235,6 +236,54 @@ export default class LayoutConfig { | ||||||
|         return this.layers.some((l) => l.isLeftRightSensitive()) |         return this.layers.some((l) => l.isLeftRightSensitive()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public missingTranslations(): { | ||||||
|  |         completeness: Map<string, number> | ||||||
|  |         untranslated: Map<string, string[]> | ||||||
|  |         total: number | ||||||
|  |     } { | ||||||
|  |         const layout = this | ||||||
|  |         let total = 0 | ||||||
|  |         const completeness = new Map<string, number>() | ||||||
|  |         const untranslated = new Map<string, string[]>() | ||||||
|  | 
 | ||||||
|  |         Utils.WalkObject( | ||||||
|  |             layout, | ||||||
|  |             (o) => { | ||||||
|  |                 const translation = <Translation>(<any>o) | ||||||
|  |                 if (translation.translations["*"] !== undefined) { | ||||||
|  |                     return | ||||||
|  |                 } | ||||||
|  |                 if (translation.context === undefined || translation.context.indexOf(":") < 0) { | ||||||
|  |                     // no source given - lets ignore
 | ||||||
|  |                     return | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 total++ | ||||||
|  |                 used_languages.languages.forEach((ln) => { | ||||||
|  |                     const trans = translation.translations | ||||||
|  |                     if (trans["*"] !== undefined) { | ||||||
|  |                         return | ||||||
|  |                     } | ||||||
|  |                     if (trans[ln] === undefined) { | ||||||
|  |                         if (!untranslated.has(ln)) { | ||||||
|  |                             untranslated.set(ln, []) | ||||||
|  |                         } | ||||||
|  |                         untranslated.get(ln).push(translation.context) | ||||||
|  |                     } else { | ||||||
|  |                         completeness.set(ln, 1 + (completeness.get(ln) ?? 0)) | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |             }, | ||||||
|  |             (o) => { | ||||||
|  |                 if (o === undefined || o === null) { | ||||||
|  |                     return false | ||||||
|  |                 } | ||||||
|  |                 return o instanceof Translation | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         return { completeness, untranslated, total } | ||||||
|  |     } | ||||||
|     public getMatchingLayer(tags: any): LayerConfig | undefined { |     public getMatchingLayer(tags: any): LayerConfig | undefined { | ||||||
|         if (tags === undefined) { |         if (tags === undefined) { | ||||||
|             return undefined |             return undefined | ||||||
|  |  | ||||||
|  | @ -15,15 +15,13 @@ import { Store } from "../../Logic/UIEventSource" | ||||||
| import { SubtleButton } from "../Base/SubtleButton" | import { SubtleButton } from "../Base/SubtleButton" | ||||||
| import Svg from "../../Svg" | import Svg from "../../Svg" | ||||||
| import * as native_languages from "../../assets/language_native.json" | import * as native_languages from "../../assets/language_native.json" | ||||||
| import * as used_languages from "../../assets/generated/used_languages.json" |  | ||||||
| import BaseUIElement from "../BaseUIElement" | import BaseUIElement from "../BaseUIElement" | ||||||
| 
 | 
 | ||||||
| class TranslatorsPanelContent extends Combine { | class TranslatorsPanelContent extends Combine { | ||||||
|     constructor(layout: LayoutConfig, isTranslator: Store<boolean>) { |     constructor(layout: LayoutConfig, isTranslator: Store<boolean>) { | ||||||
|         const t = Translations.t.translations |         const t = Translations.t.translations | ||||||
| 
 | 
 | ||||||
|         const { completeness, untranslated, total } = |         const { completeness, untranslated, total } = layout.missingTranslations() | ||||||
|             TranslatorsPanel.MissingTranslationsFor(layout) |  | ||||||
| 
 | 
 | ||||||
|         const seed = t.completeness |         const seed = t.completeness | ||||||
|         for (const ln of Array.from(completeness.keys())) { |         for (const ln of Array.from(completeness.keys())) { | ||||||
|  | @ -147,52 +145,4 @@ export default class TranslatorsPanel extends Toggle { | ||||||
|         ) |         ) | ||||||
|         this.SetClass("hidden-on-mobile") |         this.SetClass("hidden-on-mobile") | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     public static MissingTranslationsFor(layout: LayoutConfig): { |  | ||||||
|         completeness: Map<string, number> |  | ||||||
|         untranslated: Map<string, string[]> |  | ||||||
|         total: number |  | ||||||
|     } { |  | ||||||
|         let total = 0 |  | ||||||
|         const completeness = new Map<string, number>() |  | ||||||
|         const untranslated = new Map<string, string[]>() |  | ||||||
| 
 |  | ||||||
|         Utils.WalkObject( |  | ||||||
|             layout, |  | ||||||
|             (o) => { |  | ||||||
|                 const translation = <Translation>(<any>o) |  | ||||||
|                 if (translation.translations["*"] !== undefined) { |  | ||||||
|                     return |  | ||||||
|                 } |  | ||||||
|                 if (translation.context === undefined || translation.context.indexOf(":") < 0) { |  | ||||||
|                     // no source given - lets ignore
 |  | ||||||
|                     return |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 total++ |  | ||||||
|                 used_languages.languages.forEach((ln) => { |  | ||||||
|                     const trans = translation.translations |  | ||||||
|                     if (trans["*"] !== undefined) { |  | ||||||
|                         return |  | ||||||
|                     } |  | ||||||
|                     if (trans[ln] === undefined) { |  | ||||||
|                         if (!untranslated.has(ln)) { |  | ||||||
|                             untranslated.set(ln, []) |  | ||||||
|                         } |  | ||||||
|                         untranslated.get(ln).push(translation.context) |  | ||||||
|                     } else { |  | ||||||
|                         completeness.set(ln, 1 + (completeness.get(ln) ?? 0)) |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
|             }, |  | ||||||
|             (o) => { |  | ||||||
|                 if (o === undefined || o === null) { |  | ||||||
|                     return false |  | ||||||
|                 } |  | ||||||
|                 return o instanceof Translation |  | ||||||
|             } |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         return { completeness, untranslated, total } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ import { TagUtils } from "../../Logic/Tags/TagUtils" | ||||||
| import * as usersettings from "../../assets/generated/layers/usersettings.json" | import * as usersettings from "../../assets/generated/layers/usersettings.json" | ||||||
| import { LoginToggle } from "../Popup/LoginButton" | import { LoginToggle } from "../Popup/LoginButton" | ||||||
| import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | ||||||
| 
 | import * as translators from "../../assets/translators.json" | ||||||
| export class ImportViewerLinks extends VariableUiElement { | export class ImportViewerLinks extends VariableUiElement { | ||||||
|     constructor(osmConnection: OsmConnection) { |     constructor(osmConnection: OsmConnection) { | ||||||
|         super( |         super( | ||||||
|  | @ -44,24 +44,27 @@ export class ImportViewerLinks extends VariableUiElement { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class SingleUserSettingsPanel extends EditableTagRendering { | class SingleUserSettingsPanel extends EditableTagRendering { | ||||||
|     constructor(config: TagRenderingConfig, osmConnection: OsmConnection) { |     constructor( | ||||||
|  |         config: TagRenderingConfig, | ||||||
|  |         osmConnection: OsmConnection, | ||||||
|  |         amendedPrefs: UIEventSource<any>, | ||||||
|  |         userInfoFocusedQuestion?: UIEventSource<string> | ||||||
|  |     ) { | ||||||
|         const editMode = new UIEventSource(false) |         const editMode = new UIEventSource(false) | ||||||
|  |         // Isolate the preferences. THey'll be updated explicitely later on anyway
 | ||||||
|         super( |         super( | ||||||
|             osmConnection.preferencesHandler.preferences, |             amendedPrefs, | ||||||
|             config, |             config, | ||||||
|             [], |             [], | ||||||
|             { osmConnection }, |             { osmConnection }, | ||||||
|             { |             { | ||||||
|  |                 answerElementClasses: "p-2", | ||||||
|                 editMode, |                 editMode, | ||||||
|                 createSaveButton: (store) => |                 createSaveButton: (store) => | ||||||
|                     new SaveButton( |                     new SaveButton(amendedPrefs, osmConnection).onClick(() => { | ||||||
|                         osmConnection.preferencesHandler.preferences, |  | ||||||
|                         osmConnection |  | ||||||
|                     ).onClick(() => { |  | ||||||
|                         const prefs = osmConnection.preferencesHandler.preferences |  | ||||||
|                         const selection = TagUtils.FlattenMultiAnswer( |                         const selection = TagUtils.FlattenMultiAnswer( | ||||||
|                             TagUtils.FlattenAnd(store.data, prefs.data) |                             TagUtils.FlattenAnd(store.data, amendedPrefs.data) | ||||||
|                         ).asChange(prefs.data) |                         ).asChange(amendedPrefs.data) | ||||||
|                         for (const kv of selection) { |                         for (const kv of selection) { | ||||||
|                             osmConnection.GetPreference(kv.k, "", "").setData(kv.v) |                             osmConnection.GetPreference(kv.k, "", "").setData(kv.v) | ||||||
|                         } |                         } | ||||||
|  | @ -70,6 +73,16 @@ class SingleUserSettingsPanel extends EditableTagRendering { | ||||||
|                     }), |                     }), | ||||||
|             } |             } | ||||||
|         ) |         ) | ||||||
|  |         const self = this | ||||||
|  |         this.SetClass("rounded-xl") | ||||||
|  |         userInfoFocusedQuestion.addCallbackAndRun((selected) => { | ||||||
|  |             if (config.id !== selected) { | ||||||
|  |                 console.log("Removing the glowingshadow...") | ||||||
|  |                 self.RemoveClass("glowing-shadow") | ||||||
|  |             } else { | ||||||
|  |                 self.SetClass("glowing-shadow") | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -78,11 +91,35 @@ class UserInformationMainPanel extends VariableUiElement { | ||||||
|         osmConnection: OsmConnection, |         osmConnection: OsmConnection, | ||||||
|         locationControl: UIEventSource<Loc>, |         locationControl: UIEventSource<Loc>, | ||||||
|         layout: LayoutConfig, |         layout: LayoutConfig, | ||||||
|         isOpened: UIEventSource<boolean> |         isOpened: UIEventSource<boolean>, | ||||||
|  |         userInfoFocusedQuestion?: UIEventSource<string> | ||||||
|     ) { |     ) { | ||||||
|         const t = Translations.t.userinfo |         const t = Translations.t.userinfo | ||||||
|         const imgSize = "h-6 w-6" |         const imgSize = "h-6 w-6" | ||||||
|         const ud = osmConnection.userDetails |         const ud = osmConnection.userDetails | ||||||
|  | 
 | ||||||
|  |         const amendedPrefs = new UIEventSource<any>({}) | ||||||
|  |         osmConnection.preferencesHandler.preferences.addCallback((newPrefs) => { | ||||||
|  |             for (const k in newPrefs) { | ||||||
|  |                 amendedPrefs.data[k] = newPrefs[k] | ||||||
|  |             } | ||||||
|  |             amendedPrefs.ping() | ||||||
|  |         }) | ||||||
|  |         osmConnection.userDetails.addCallback((userDetails) => { | ||||||
|  |             for (const k in userDetails) { | ||||||
|  |                 amendedPrefs.data["_" + k] = "" + userDetails[k] | ||||||
|  |             } | ||||||
|  |             const simplifiedName = userDetails.name.toLowerCase().replace(/\s+/g, "") | ||||||
|  |             const isTranslator = translators.contributors.some( | ||||||
|  |                 (c: { contributor: string; commits: number }) => { | ||||||
|  |                     const replaced = c.contributor.toLowerCase().replace(/\s+/g, "") | ||||||
|  |                     return replaced === simplifiedName | ||||||
|  |                 } | ||||||
|  |             ) | ||||||
|  |             amendedPrefs.data["_is_translator"] = "" + isTranslator | ||||||
|  |             amendedPrefs.ping() | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|         super( |         super( | ||||||
|             ud.map((ud) => { |             ud.map((ud) => { | ||||||
|                 let img: BaseUIElement = Svg.person_ui().SetClass("block") |                 let img: BaseUIElement = Svg.person_ui().SetClass("block") | ||||||
|  | @ -138,7 +175,12 @@ class UserInformationMainPanel extends VariableUiElement { | ||||||
|                 const usersettingsConfig = new LayerConfig(usersettings, "userinformationpanel") |                 const usersettingsConfig = new LayerConfig(usersettings, "userinformationpanel") | ||||||
| 
 | 
 | ||||||
|                 const questions = usersettingsConfig.tagRenderings.map((c) => |                 const questions = usersettingsConfig.tagRenderings.map((c) => | ||||||
|                     new SingleUserSettingsPanel(c, osmConnection).SetClass("block my-4") |                     new SingleUserSettingsPanel( | ||||||
|  |                         c, | ||||||
|  |                         osmConnection, | ||||||
|  |                         amendedPrefs, | ||||||
|  |                         userInfoFocusedQuestion | ||||||
|  |                     ).SetClass("block my-4") | ||||||
|                 ) |                 ) | ||||||
| 
 | 
 | ||||||
|                 return new Combine([ |                 return new Combine([ | ||||||
|  | @ -187,6 +229,7 @@ export default class UserInformationPanel extends ScrollableFullScreen { | ||||||
|         }, |         }, | ||||||
|         options?: { |         options?: { | ||||||
|             isOpened?: UIEventSource<boolean> |             isOpened?: UIEventSource<boolean> | ||||||
|  |             userInfoFocusedQuestion?: UIEventSource<string> | ||||||
|         } |         } | ||||||
|     ) { |     ) { | ||||||
|         const isOpened = options?.isOpened ?? new UIEventSource<boolean>(false) |         const isOpened = options?.isOpened ?? new UIEventSource<boolean>(false) | ||||||
|  | @ -207,7 +250,8 @@ export default class UserInformationPanel extends ScrollableFullScreen { | ||||||
|                         state.osmConnection, |                         state.osmConnection, | ||||||
|                         state.locationControl, |                         state.locationControl, | ||||||
|                         state.layoutToUse, |                         state.layoutToUse, | ||||||
|                         isOpened |                         isOpened, | ||||||
|  |                         options?.userInfoFocusedQuestion | ||||||
|                     ), |                     ), | ||||||
|                     Translations.t.general.getStartedLogin, |                     Translations.t.general.getStartedLogin, | ||||||
|                     state |                     state | ||||||
|  |  | ||||||
|  | @ -205,9 +205,9 @@ export default class DefaultGUI { | ||||||
|         const self = this |         const self = this | ||||||
| 
 | 
 | ||||||
|         const userInfoMapControl = Toggle.If(state.featureSwitchUserbadge, () => { |         const userInfoMapControl = Toggle.If(state.featureSwitchUserbadge, () => { | ||||||
|             console.log("Guistate is", guiState) |  | ||||||
|             new UserInformationPanel(state, { |             new UserInformationPanel(state, { | ||||||
|                 isOpened: guiState.userInfoIsOpened, |                 isOpened: guiState.userInfoIsOpened, | ||||||
|  |                 userInfoFocusedQuestion: guiState.userInfoFocusedQuestion, | ||||||
|             }) |             }) | ||||||
| 
 | 
 | ||||||
|             const mapControl = new MapControlButton( |             const mapControl = new MapControlButton( | ||||||
|  |  | ||||||
|  | @ -19,6 +19,9 @@ export class DefaultGuiState { | ||||||
|         false |         false | ||||||
|     ) |     ) | ||||||
|     public readonly userInfoIsOpened: UIEventSource<boolean> = new UIEventSource<boolean>(false) |     public readonly userInfoIsOpened: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||||
|  |     public readonly userInfoFocusedQuestion: UIEventSource<string> = new UIEventSource<string>( | ||||||
|  |         undefined | ||||||
|  |     ) | ||||||
|     public readonly welcomeMessageOpenedTab: UIEventSource<number> |     public readonly welcomeMessageOpenedTab: UIEventSource<number> | ||||||
| 
 | 
 | ||||||
|     constructor() { |     constructor() { | ||||||
|  | @ -38,6 +41,14 @@ export class DefaultGuiState { | ||||||
|             userinfo: this.userInfoIsOpened, |             userinfo: this.userInfoIsOpened, | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         const self = this | ||||||
|  |         this.userInfoIsOpened.addCallback((isOpen) => { | ||||||
|  |             if (!isOpen) { | ||||||
|  |                 console.log("Resetting focused question") | ||||||
|  |                 self.userInfoFocusedQuestion.setData(undefined) | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|         sources[Hash.hash.data?.toLowerCase()]?.setData(true) |         sources[Hash.hash.data?.toLowerCase()]?.setData(true) | ||||||
| 
 | 
 | ||||||
|         if (Hash.hash.data === "" || Hash.hash.data === undefined) { |         if (Hash.hash.data === "" || Hash.hash.data === undefined) { | ||||||
|  |  | ||||||
|  | @ -17,6 +17,8 @@ import { Changes } from "../../Logic/Osm/Changes" | ||||||
| import Loading from "../Base/Loading" | import Loading from "../Base/Loading" | ||||||
| import { LoginToggle } from "../Popup/LoginButton" | import { LoginToggle } from "../Popup/LoginButton" | ||||||
| import Constants from "../../Models/Constants" | import Constants from "../../Models/Constants" | ||||||
|  | import { DefaultGuiState } from "../DefaultGuiState" | ||||||
|  | import ScrollableFullScreen from "../Base/ScrollableFullScreen" | ||||||
| 
 | 
 | ||||||
| export class ImageUploadFlow extends Toggle { | export class ImageUploadFlow extends Toggle { | ||||||
|     private static readonly uploadCountsPerId = new Map<string, UIEventSource<number>>() |     private static readonly uploadCountsPerId = new Map<string, UIEventSource<number>>() | ||||||
|  | @ -80,6 +82,10 @@ export class ImageUploadFlow extends Toggle { | ||||||
|         ]).SetClass( |         ]).SetClass( | ||||||
|             "p-2 border-4 border-detail rounded-full font-bold h-full align-middle w-full flex justify-center" |             "p-2 border-4 border-detail rounded-full font-bold h-full align-middle w-full flex justify-center" | ||||||
|         ) |         ) | ||||||
|  |         const licenseStore = state?.osmConnection?.GetPreference( | ||||||
|  |             Constants.OsmPreferenceKeyPicturesLicense, | ||||||
|  |             "CC0" | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         const fileSelector = new FileSelectorButton(label) |         const fileSelector = new FileSelectorButton(label) | ||||||
|         fileSelector.GetValue().addCallback((filelist) => { |         fileSelector.GetValue().addCallback((filelist) => { | ||||||
|  | @ -101,12 +107,7 @@ export class ImageUploadFlow extends Toggle { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             console.log("Received images from the user, starting upload") |             const license = licenseStore?.data ?? "CC0" | ||||||
|             const license = |  | ||||||
|                 state?.osmConnection?.GetPreference( |  | ||||||
|                     Constants.OsmPreferenceKeyPicturesLicense, |  | ||||||
|                     "CC0" |  | ||||||
|                 )?.data ?? "CC0" |  | ||||||
| 
 | 
 | ||||||
|             const tags = tagsSource.data |             const tags = tagsSource.data | ||||||
| 
 | 
 | ||||||
|  | @ -174,7 +175,21 @@ export class ImageUploadFlow extends Toggle { | ||||||
|             ), |             ), | ||||||
| 
 | 
 | ||||||
|             fileSelector, |             fileSelector, | ||||||
|             Translations.t.image.respectPrivacy.Clone().SetStyle("font-size:small;"), |             new Combine([ | ||||||
|  |                 Translations.t.image.respectPrivacy, | ||||||
|  |                 new VariableUiElement( | ||||||
|  |                     licenseStore.map((license) => | ||||||
|  |                         Translations.t.image.currentLicense.Subs({ license }) | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  |                     .onClick(() => { | ||||||
|  |                         console.log("Opening the license settings... ") | ||||||
|  |                         ScrollableFullScreen.collapse() | ||||||
|  |                         DefaultGuiState.state.userInfoIsOpened.setData(true) | ||||||
|  |                         DefaultGuiState.state.userInfoFocusedQuestion.setData("picture-license") | ||||||
|  |                     }) | ||||||
|  |                     .SetClass("underline"), | ||||||
|  |             ]).SetStyle("font-size:small;"), | ||||||
|         ]).SetClass("flex flex-col image-upload-flow mt-4 mb-8 text-center") |         ]).SetClass("flex flex-col image-upload-flow mt-4 mb-8 text-center") | ||||||
| 
 | 
 | ||||||
|         super( |         super( | ||||||
|  |  | ||||||
|  | @ -21,6 +21,8 @@ export default class EditableTagRendering extends Toggle { | ||||||
|         options: { |         options: { | ||||||
|             editMode?: UIEventSource<boolean> |             editMode?: UIEventSource<boolean> | ||||||
|             innerElementClasses?: string |             innerElementClasses?: string | ||||||
|  |             /* Classes applied _only_ on the rendered element, not on the question*/ | ||||||
|  |             answerElementClasses?: string | ||||||
|             /* Default will apply the tags to the relevant object, only use in special cases */ |             /* Default will apply the tags to the relevant object, only use in special cases */ | ||||||
|             createSaveButton?: (src: Store<UploadableTag>) => BaseUIElement |             createSaveButton?: (src: Store<UploadableTag>) => BaseUIElement | ||||||
|         } |         } | ||||||
|  | @ -43,7 +45,10 @@ export default class EditableTagRendering extends Toggle { | ||||||
|                     configuration, |                     configuration, | ||||||
|                     units, |                     units, | ||||||
|                     editMode, |                     editMode, | ||||||
|                     { saveButtonConstructor: options?.createSaveButton } |                     { | ||||||
|  |                         saveButtonConstructor: options?.createSaveButton, | ||||||
|  |                         answerElementClasses: options?.answerElementClasses, | ||||||
|  |                     } | ||||||
|                 ) |                 ) | ||||||
|                 rendering.SetClass(options.innerElementClasses) |                 rendering.SetClass(options.innerElementClasses) | ||||||
|                 if (state?.featureSwitchIsDebugging?.data || state?.featureSwitchIsTesting?.data) { |                 if (state?.featureSwitchIsDebugging?.data || state?.featureSwitchIsTesting?.data) { | ||||||
|  | @ -73,6 +78,7 @@ export default class EditableTagRendering extends Toggle { | ||||||
|         editMode: UIEventSource<boolean>, |         editMode: UIEventSource<boolean>, | ||||||
|         options?: { |         options?: { | ||||||
|             saveButtonConstructor?: (src: Store<UploadableTag>) => BaseUIElement |             saveButtonConstructor?: (src: Store<UploadableTag>) => BaseUIElement | ||||||
|  |             answerElementClasses?: string | ||||||
|         } |         } | ||||||
|     ): BaseUIElement { |     ): BaseUIElement { | ||||||
|         const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration, state) |         const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration, state) | ||||||
|  | @ -107,7 +113,7 @@ export default class EditableTagRendering extends Toggle { | ||||||
|                         onlyIfPartiallyHidden: true, |                         onlyIfPartiallyHidden: true, | ||||||
|                     }) |                     }) | ||||||
|                 }), |                 }), | ||||||
|             ]).SetClass("flex justify-between w-full") |             ]).SetClass("flex justify-between w-full " + (options?.answerElementClasses ?? "")) | ||||||
|             rendering = new Toggle(question, answerWithEditButton, editMode) |             rendering = new Toggle(question, answerWithEditButton, editMode) | ||||||
|         } |         } | ||||||
|         return rendering |         return rendering | ||||||
|  |  | ||||||
|  | @ -155,14 +155,13 @@ export class Translation extends BaseUIElement { | ||||||
|             return el |             return el | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const linkToWeblate = new LinkToWeblate(self.context, self.translations) |  | ||||||
| 
 |  | ||||||
|         const wrapper = document.createElement("span") |         const wrapper = document.createElement("span") | ||||||
|         wrapper.appendChild(el) |         wrapper.appendChild(el) | ||||||
|         Locale.showLinkToWeblate.addCallbackAndRun((doShow) => { |         Locale.showLinkToWeblate.addCallbackAndRun((doShow) => { | ||||||
|             if (!doShow) { |             if (!doShow) { | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
|  |             const linkToWeblate = new LinkToWeblate(self.context, self.translations) | ||||||
|             wrapper.appendChild(linkToWeblate.ConstructElement()) |             wrapper.appendChild(linkToWeblate.ConstructElement()) | ||||||
|             return true |             return true | ||||||
|         }) |         }) | ||||||
|  |  | ||||||
|  | @ -18,29 +18,45 @@ | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-pictures-license=", |           "if": "mapcomplete-pictures-license=", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "No license has been chosen yet" |             "en": "Pictures you take will be licensed with <b>CC0</b> and added to the public domain. This means that everyone can use your pictures for any purpose. <span class='subtle'>This is the default choice.</span>" | ||||||
|           }, |           }, | ||||||
|           "hideInAnswer": true |           "hideInAnswer": true | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-pictures-license=CC0", |           "if": "mapcomplete-pictures-license=CC0", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "Pictures you take will be licensed with CC0 and added to the public domain. This means that everyone can use your pictures for any purpose." |             "en": "Pictures you take will be licensed with <b>CC0</b> and added to the public domain. This means that everyone can use your pictures for any purpose." | ||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-pictures-license=CC-BY 4.0", |           "if": "mapcomplete-pictures-license=CC-BY 4.0", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "Pictures you take will be licensed with CC-BY 4.0 which requires everyone using your picture that they have to attribute you" |             "en": "Pictures you take will be licensed with <b>CC-BY 4.0</b> which requires everyone using your picture that they have to attribute you" | ||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "if": "mapcomplete-pictures-license=CC-BY-SA 4.0", |           "if": "mapcomplete-pictures-license=CC-BY-SA 4.0", | ||||||
|           "then": { |           "then": { | ||||||
|             "en": "Pictures you take will be licensed with CC-BY-SA 4.0 which means that everyone using your picture must attribute you and that derivatives of your picture must be reshared with the same license." |             "en": "Pictures you take will be licensed with <b>CC-BY-SA 4.0</b> which means that everyone using your picture must attribute you and that derivatives of your picture must be reshared with the same license." | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       ] |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "id": "translation-thanks", | ||||||
|  |       "condition": "_is_translator=true", | ||||||
|  |       "mappings": [{ | ||||||
|  |         "if": "_is_translator=true", | ||||||
|  |         "then": { | ||||||
|  |           "en": "You have contributed to translating MapComplete! That's awesome!" | ||||||
|  |         }, | ||||||
|  |         "icon": "party" | ||||||
|  |       }] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "id": "debug", | ||||||
|  |       "condition": "_name=Pieter Vander Vennet", | ||||||
|  |       "render": "{all_tags()}" | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   "mapRendering": null |   "mapRendering": null | ||||||
|  |  | ||||||
|  | @ -1493,7 +1493,7 @@ | ||||||
|       } |       } | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|    "induction-loop": { |   "induction-loop": { | ||||||
|     "description": "An accessibility feature: induction loops are for hard-hearing persons which have an FM-receiver.", |     "description": "An accessibility feature: induction loops are for hard-hearing persons which have an FM-receiver.", | ||||||
|     "question": { |     "question": { | ||||||
|       "en": "Does this place have an audio induction loop for people with reduced hearing?", |       "en": "Does this place have an audio induction loop for people with reduced hearing?", | ||||||
|  |  | ||||||
|  | @ -2505,6 +2505,21 @@ input { | ||||||
|   /* The checkbox that toggles a single layer */ |   /* The checkbox that toggles a single layer */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .glowing-shadow { | ||||||
|  |   -webkit-animation: glowing 1s ease-in-out infinite alternate; | ||||||
|  |   animation: glowing 1s ease-in-out infinite alternate; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @-webkit-keyframes glowing { | ||||||
|  |   from { | ||||||
|  |     box-shadow: 0 0 20px 10px #eaaf2588, inset 0 0 0px 1px #eaaf25; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   to { | ||||||
|  |     box-shadow: 0 0 20px 20px #eaaf2588, inset 0 0 5px 1px #eaaf25; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .mapping-icon-small-height { | .mapping-icon-small-height { | ||||||
|   /* A mapping icon type */ |   /* A mapping icon type */ | ||||||
|   height: 1.5rem; |   height: 1.5rem; | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ | ||||||
|     background-color: var(--subtle-detail-color); |     background-color: var(--subtle-detail-color); | ||||||
|     color: var(--subtle-detail-color-contrast); |     color: var(--subtle-detail-color-contrast); | ||||||
|     padding: 1em; |     padding: 1em; | ||||||
|     border-radius: 1em; |     border-radius: 0.75rem; | ||||||
|     font-size: larger !important; |     font-size: larger !important; | ||||||
|     overflow-wrap: initial; |     overflow-wrap: initial; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								index.css
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								index.css
									
										
									
									
									
								
							|  | @ -637,7 +637,19 @@ input { | ||||||
|   /* The checkbox that toggles a single layer */ |   /* The checkbox that toggles a single layer */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | .glowing-shadow { | ||||||
|  |   -webkit-animation: glowing 1s ease-in-out infinite alternate; | ||||||
|  |   -moz-animation: glowing 1s ease-in-out infinite alternate; | ||||||
|  |   animation: glowing 1s ease-in-out infinite alternate; | ||||||
|  | } | ||||||
|  | @-webkit-keyframes glowing { | ||||||
|  |   from { | ||||||
|  |     box-shadow: 0 0 20px 10px #eaaf2588, inset 0 0 0px 1px #eaaf25; | ||||||
|  |   } | ||||||
|  |   to { | ||||||
|  |     box-shadow: 0 0 20px 20px #eaaf2588, inset 0 0 5px 1px #eaaf25; | ||||||
|  |   } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| .mapping-icon-small-height { | .mapping-icon-small-height { | ||||||
|   /* A mapping icon type */ |   /* A mapping icon type */ | ||||||
|  |  | ||||||
|  | @ -364,6 +364,7 @@ | ||||||
|     }, |     }, | ||||||
|     "image": { |     "image": { | ||||||
|         "addPicture": "Add picture", |         "addPicture": "Add picture", | ||||||
|  |         "currentLicense": "Your images will be published under {license}", | ||||||
|         "doDelete": "Remove image", |         "doDelete": "Remove image", | ||||||
|         "dontDelete": "Cancel", |         "dontDelete": "Cancel", | ||||||
|         "isDeleted": "Deleted", |         "isDeleted": "Deleted", | ||||||
|  |  | ||||||
|  | @ -200,23 +200,6 @@ | ||||||
|         "phone": { |         "phone": { | ||||||
|             "question": "What is the phone number of {title()}?" |             "question": "What is the phone number of {title()}?" | ||||||
|         }, |         }, | ||||||
|         "picture-license": { |  | ||||||
|             "mappings": { |  | ||||||
|                 "0": { |  | ||||||
|                     "then": "No license has been chosen yet" |  | ||||||
|                 }, |  | ||||||
|                 "1": { |  | ||||||
|                     "then": "Pictures you take will be licensed with CC0 and added to the public domain. This means that everyone can use your pictures for any purpose." |  | ||||||
|                 }, |  | ||||||
|                 "2": { |  | ||||||
|                     "then": "Pictures you take will be licensed with CC-BY 4.0 which requires everyone using your picture that they have to attribute you" |  | ||||||
|                 }, |  | ||||||
|                 "3": { |  | ||||||
|                     "then": "Pictures you take will be licensed with CC-BY-SA 4.0 which means that everyone using your picture must attribute you and that derivatives of your picture must be reshared with the same license." |  | ||||||
|                 } |  | ||||||
|             }, |  | ||||||
|             "question": "Under what license do you want to publish your pictures?" |  | ||||||
|         }, |  | ||||||
|         "service:electricity": { |         "service:electricity": { | ||||||
|             "mappings": { |             "mappings": { | ||||||
|                 "0": { |                 "0": { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue