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" | ||||
| 
 | ||||
| export default class Constants { | ||||
|     public static vNumber = "0.25.5" | ||||
|     public static vNumber = "0.25.6" | ||||
| 
 | ||||
|     public static ImgurApiKey = "7070e7167f0a25a" | ||||
|     public static readonly mapillary_client_token_v4 = | ||||
|  |  | |||
|  | @ -6,7 +6,8 @@ import Constants from "../Constants" | |||
| import TilesourceConfig from "./TilesourceConfig" | ||||
| import { ExtractImages } from "./Conversion/FixImages" | ||||
| import ExtraLinkConfig from "./ExtraLinkConfig" | ||||
| 
 | ||||
| import { Utils } from "../../Utils" | ||||
| import * as used_languages from "../../assets/generated/used_languages.json" | ||||
| export default class LayoutConfig { | ||||
|     public static readonly defaultSocialImage = "assets/SocialImage.png" | ||||
|     public readonly id: string | ||||
|  | @ -235,6 +236,54 @@ export default class LayoutConfig { | |||
|         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 { | ||||
|         if (tags === undefined) { | ||||
|             return undefined | ||||
|  |  | |||
|  | @ -15,15 +15,13 @@ import { Store } from "../../Logic/UIEventSource" | |||
| import { SubtleButton } from "../Base/SubtleButton" | ||||
| import Svg from "../../Svg" | ||||
| import * as native_languages from "../../assets/language_native.json" | ||||
| import * as used_languages from "../../assets/generated/used_languages.json" | ||||
| import BaseUIElement from "../BaseUIElement" | ||||
| 
 | ||||
| class TranslatorsPanelContent extends Combine { | ||||
|     constructor(layout: LayoutConfig, isTranslator: Store<boolean>) { | ||||
|         const t = Translations.t.translations | ||||
| 
 | ||||
|         const { completeness, untranslated, total } = | ||||
|             TranslatorsPanel.MissingTranslationsFor(layout) | ||||
|         const { completeness, untranslated, total } = layout.missingTranslations() | ||||
| 
 | ||||
|         const seed = t.completeness | ||||
|         for (const ln of Array.from(completeness.keys())) { | ||||
|  | @ -147,52 +145,4 @@ export default class TranslatorsPanel extends Toggle { | |||
|         ) | ||||
|         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 { LoginToggle } from "../Popup/LoginButton" | ||||
| import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | ||||
| 
 | ||||
| import * as translators from "../../assets/translators.json" | ||||
| export class ImportViewerLinks extends VariableUiElement { | ||||
|     constructor(osmConnection: OsmConnection) { | ||||
|         super( | ||||
|  | @ -44,24 +44,27 @@ export class ImportViewerLinks extends VariableUiElement { | |||
| } | ||||
| 
 | ||||
| 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) | ||||
|         // Isolate the preferences. THey'll be updated explicitely later on anyway
 | ||||
|         super( | ||||
|             osmConnection.preferencesHandler.preferences, | ||||
|             amendedPrefs, | ||||
|             config, | ||||
|             [], | ||||
|             { osmConnection }, | ||||
|             { | ||||
|                 answerElementClasses: "p-2", | ||||
|                 editMode, | ||||
|                 createSaveButton: (store) => | ||||
|                     new SaveButton( | ||||
|                         osmConnection.preferencesHandler.preferences, | ||||
|                         osmConnection | ||||
|                     ).onClick(() => { | ||||
|                         const prefs = osmConnection.preferencesHandler.preferences | ||||
|                     new SaveButton(amendedPrefs, osmConnection).onClick(() => { | ||||
|                         const selection = TagUtils.FlattenMultiAnswer( | ||||
|                             TagUtils.FlattenAnd(store.data, prefs.data) | ||||
|                         ).asChange(prefs.data) | ||||
|                             TagUtils.FlattenAnd(store.data, amendedPrefs.data) | ||||
|                         ).asChange(amendedPrefs.data) | ||||
|                         for (const kv of selection) { | ||||
|                             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, | ||||
|         locationControl: UIEventSource<Loc>, | ||||
|         layout: LayoutConfig, | ||||
|         isOpened: UIEventSource<boolean> | ||||
|         isOpened: UIEventSource<boolean>, | ||||
|         userInfoFocusedQuestion?: UIEventSource<string> | ||||
|     ) { | ||||
|         const t = Translations.t.userinfo | ||||
|         const imgSize = "h-6 w-6" | ||||
|         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( | ||||
|             ud.map((ud) => { | ||||
|                 let img: BaseUIElement = Svg.person_ui().SetClass("block") | ||||
|  | @ -138,7 +175,12 @@ class UserInformationMainPanel extends VariableUiElement { | |||
|                 const usersettingsConfig = new LayerConfig(usersettings, "userinformationpanel") | ||||
| 
 | ||||
|                 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([ | ||||
|  | @ -187,6 +229,7 @@ export default class UserInformationPanel extends ScrollableFullScreen { | |||
|         }, | ||||
|         options?: { | ||||
|             isOpened?: UIEventSource<boolean> | ||||
|             userInfoFocusedQuestion?: UIEventSource<string> | ||||
|         } | ||||
|     ) { | ||||
|         const isOpened = options?.isOpened ?? new UIEventSource<boolean>(false) | ||||
|  | @ -207,7 +250,8 @@ export default class UserInformationPanel extends ScrollableFullScreen { | |||
|                         state.osmConnection, | ||||
|                         state.locationControl, | ||||
|                         state.layoutToUse, | ||||
|                         isOpened | ||||
|                         isOpened, | ||||
|                         options?.userInfoFocusedQuestion | ||||
|                     ), | ||||
|                     Translations.t.general.getStartedLogin, | ||||
|                     state | ||||
|  |  | |||
|  | @ -205,9 +205,9 @@ export default class DefaultGUI { | |||
|         const self = this | ||||
| 
 | ||||
|         const userInfoMapControl = Toggle.If(state.featureSwitchUserbadge, () => { | ||||
|             console.log("Guistate is", guiState) | ||||
|             new UserInformationPanel(state, { | ||||
|                 isOpened: guiState.userInfoIsOpened, | ||||
|                 userInfoFocusedQuestion: guiState.userInfoFocusedQuestion, | ||||
|             }) | ||||
| 
 | ||||
|             const mapControl = new MapControlButton( | ||||
|  |  | |||
|  | @ -19,6 +19,9 @@ export class DefaultGuiState { | |||
|         false | ||||
|     ) | ||||
|     public readonly userInfoIsOpened: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||
|     public readonly userInfoFocusedQuestion: UIEventSource<string> = new UIEventSource<string>( | ||||
|         undefined | ||||
|     ) | ||||
|     public readonly welcomeMessageOpenedTab: UIEventSource<number> | ||||
| 
 | ||||
|     constructor() { | ||||
|  | @ -38,6 +41,14 @@ export class DefaultGuiState { | |||
|             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) | ||||
| 
 | ||||
|         if (Hash.hash.data === "" || Hash.hash.data === undefined) { | ||||
|  |  | |||
|  | @ -17,6 +17,8 @@ import { Changes } from "../../Logic/Osm/Changes" | |||
| import Loading from "../Base/Loading" | ||||
| import { LoginToggle } from "../Popup/LoginButton" | ||||
| import Constants from "../../Models/Constants" | ||||
| import { DefaultGuiState } from "../DefaultGuiState" | ||||
| import ScrollableFullScreen from "../Base/ScrollableFullScreen" | ||||
| 
 | ||||
| export class ImageUploadFlow extends Toggle { | ||||
|     private static readonly uploadCountsPerId = new Map<string, UIEventSource<number>>() | ||||
|  | @ -80,6 +82,10 @@ export class ImageUploadFlow extends Toggle { | |||
|         ]).SetClass( | ||||
|             "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) | ||||
|         fileSelector.GetValue().addCallback((filelist) => { | ||||
|  | @ -101,12 +107,7 @@ export class ImageUploadFlow extends Toggle { | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             console.log("Received images from the user, starting upload") | ||||
|             const license = | ||||
|                 state?.osmConnection?.GetPreference( | ||||
|                     Constants.OsmPreferenceKeyPicturesLicense, | ||||
|                     "CC0" | ||||
|                 )?.data ?? "CC0" | ||||
|             const license = licenseStore?.data ?? "CC0" | ||||
| 
 | ||||
|             const tags = tagsSource.data | ||||
| 
 | ||||
|  | @ -174,7 +175,21 @@ export class ImageUploadFlow extends Toggle { | |||
|             ), | ||||
| 
 | ||||
|             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") | ||||
| 
 | ||||
|         super( | ||||
|  |  | |||
|  | @ -21,6 +21,8 @@ export default class EditableTagRendering extends Toggle { | |||
|         options: { | ||||
|             editMode?: UIEventSource<boolean> | ||||
|             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 */ | ||||
|             createSaveButton?: (src: Store<UploadableTag>) => BaseUIElement | ||||
|         } | ||||
|  | @ -43,7 +45,10 @@ export default class EditableTagRendering extends Toggle { | |||
|                     configuration, | ||||
|                     units, | ||||
|                     editMode, | ||||
|                     { saveButtonConstructor: options?.createSaveButton } | ||||
|                     { | ||||
|                         saveButtonConstructor: options?.createSaveButton, | ||||
|                         answerElementClasses: options?.answerElementClasses, | ||||
|                     } | ||||
|                 ) | ||||
|                 rendering.SetClass(options.innerElementClasses) | ||||
|                 if (state?.featureSwitchIsDebugging?.data || state?.featureSwitchIsTesting?.data) { | ||||
|  | @ -73,6 +78,7 @@ export default class EditableTagRendering extends Toggle { | |||
|         editMode: UIEventSource<boolean>, | ||||
|         options?: { | ||||
|             saveButtonConstructor?: (src: Store<UploadableTag>) => BaseUIElement | ||||
|             answerElementClasses?: string | ||||
|         } | ||||
|     ): BaseUIElement { | ||||
|         const answer: BaseUIElement = new TagRenderingAnswer(tags, configuration, state) | ||||
|  | @ -107,7 +113,7 @@ export default class EditableTagRendering extends Toggle { | |||
|                         onlyIfPartiallyHidden: true, | ||||
|                     }) | ||||
|                 }), | ||||
|             ]).SetClass("flex justify-between w-full") | ||||
|             ]).SetClass("flex justify-between w-full " + (options?.answerElementClasses ?? "")) | ||||
|             rendering = new Toggle(question, answerWithEditButton, editMode) | ||||
|         } | ||||
|         return rendering | ||||
|  |  | |||
|  | @ -155,14 +155,13 @@ export class Translation extends BaseUIElement { | |||
|             return el | ||||
|         } | ||||
| 
 | ||||
|         const linkToWeblate = new LinkToWeblate(self.context, self.translations) | ||||
| 
 | ||||
|         const wrapper = document.createElement("span") | ||||
|         wrapper.appendChild(el) | ||||
|         Locale.showLinkToWeblate.addCallbackAndRun((doShow) => { | ||||
|             if (!doShow) { | ||||
|                 return | ||||
|             } | ||||
|             const linkToWeblate = new LinkToWeblate(self.context, self.translations) | ||||
|             wrapper.appendChild(linkToWeblate.ConstructElement()) | ||||
|             return true | ||||
|         }) | ||||
|  |  | |||
|  | @ -18,29 +18,45 @@ | |||
|         { | ||||
|           "if": "mapcomplete-pictures-license=", | ||||
|           "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 | ||||
|         }, | ||||
|         { | ||||
|           "if": "mapcomplete-pictures-license=CC0", | ||||
|           "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", | ||||
|           "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", | ||||
|           "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 | ||||
|  |  | |||
|  | @ -1493,7 +1493,7 @@ | |||
|       } | ||||
|     ] | ||||
|   }, | ||||
|    "induction-loop": { | ||||
|   "induction-loop": { | ||||
|     "description": "An accessibility feature: induction loops are for hard-hearing persons which have an FM-receiver.", | ||||
|     "question": { | ||||
|       "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 */ | ||||
| } | ||||
| 
 | ||||
| .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 { | ||||
|   /* A mapping icon type */ | ||||
|   height: 1.5rem; | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
|     background-color: var(--subtle-detail-color); | ||||
|     color: var(--subtle-detail-color-contrast); | ||||
|     padding: 1em; | ||||
|     border-radius: 1em; | ||||
|     border-radius: 0.75rem; | ||||
|     font-size: larger !important; | ||||
|     overflow-wrap: initial; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										14
									
								
								index.css
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								index.css
									
										
									
									
									
								
							|  | @ -637,7 +637,19 @@ input { | |||
|   /* 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 { | ||||
|   /* A mapping icon type */ | ||||
|  |  | |||
|  | @ -364,6 +364,7 @@ | |||
|     }, | ||||
|     "image": { | ||||
|         "addPicture": "Add picture", | ||||
|         "currentLicense": "Your images will be published under {license}", | ||||
|         "doDelete": "Remove image", | ||||
|         "dontDelete": "Cancel", | ||||
|         "isDeleted": "Deleted", | ||||
|  |  | |||
|  | @ -200,23 +200,6 @@ | |||
|         "phone": { | ||||
|             "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": { | ||||
|             "mappings": { | ||||
|                 "0": { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue