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?",
|
||||||
|
@ -1766,4 +1766,4 @@
|
||||||
"ca": "El nom de la xarxa és <b>{internet_access:ssid}</b>"
|
"ca": "El nom de la xarxa és <b>{internet_access:ssid}</b>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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…
Reference in a new issue