Refactoring: remove old, no longer needed classes
This commit is contained in:
parent
b8de80bee3
commit
61f20d0092
14 changed files with 60 additions and 293 deletions
|
@ -216,6 +216,7 @@
|
|||
"panoramaxHelp": "<b>Panoramax</b> is an online service which gathers street-level pictures and offers them under a free license. Contributors are allowed to use these pictures to improve OpenStreetMap",
|
||||
"panoramaxLicenseCCBYSA": "Your pictures are published under CC-BY-SA - everyone can reuse your image if they mention your name",
|
||||
"seeOnMapillary": "See this image on Mapillary",
|
||||
|
||||
"themeBy": "Theme maintained by {author}",
|
||||
"title": "Copyright and attribution",
|
||||
"translatedBy": "MapComplete has been translated by {contributors} and <a href='https://source.mapcomplete.org/MapComplete/MapComplete/activity/contributors' target='_blank'>{hiddenCount} more contributors</a>"
|
||||
|
@ -941,4 +942,4 @@
|
|||
"startsWithQ": "A wikidata identifier starts with Q and is followed by a number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import ImageProvider, { PanoramaView, ProvidedImage } from "./ImageProvider"
|
||||
import BaseUIElement from "../../UI/BaseUIElement"
|
||||
import { Utils } from "../../Utils"
|
||||
import { LicenseInfo } from "./LicenseInfo"
|
||||
import Constants from "../../Models/Constants"
|
||||
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
||||
import MapillaryIcon from "./MapillaryIcon.svelte"
|
||||
import { default as MapillaryIcon } from "./Mapillary.svelte"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
||||
|
@ -139,19 +138,8 @@ export class Mapillary extends ImageProvider {
|
|||
}))
|
||||
}
|
||||
|
||||
SourceIcon(
|
||||
img: { id: string; url: string },
|
||||
location?: {
|
||||
lon: number
|
||||
lat: number
|
||||
}
|
||||
): BaseUIElement {
|
||||
let url: string = undefined
|
||||
const id = img.id
|
||||
if (id) {
|
||||
url = Mapillary.createLink(location, 16, "" + id)
|
||||
}
|
||||
return new SvelteUIElement(MapillaryIcon, { url })
|
||||
SourceIcon(): SvelteUIElement {
|
||||
return new SvelteUIElement(MapillaryIcon)
|
||||
}
|
||||
|
||||
async ExtractUrls(key: string, value: string): Promise<ProvidedImage[]> {
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Mapillary from "../../assets/svg/Mapillary.svelte"
|
||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import Translations from "../../UI/i18n/Translations"
|
||||
|
||||
/**
|
||||
* Accessible, linked mapillary icon
|
||||
*/
|
||||
export let url: string = undefined
|
||||
</script>
|
||||
|
||||
{#if url}
|
||||
<a
|
||||
href={url}
|
||||
use:ariaLabel={Translations.t.general.attribution.seeOnMapillary}
|
||||
target="_blank"
|
||||
rel="noopener nofollower"
|
||||
>
|
||||
<Mapillary />
|
||||
</a>
|
||||
{:else}
|
||||
<Mapillary />
|
||||
{/if}
|
|
@ -9,7 +9,6 @@ import Constants from "../../Models/Constants"
|
|||
import { Store, Stores, UIEventSource } from "../UIEventSource"
|
||||
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
||||
import Panoramax_bw from "../../assets/svg/Panoramax_bw.svelte"
|
||||
import Link from "../../UI/Base/Link"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { AddImageOptions } from "panoramax-js/dist/Panoramax"
|
||||
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
||||
|
@ -40,23 +39,8 @@ export default class PanoramaxImageProvider extends ImageProvider {
|
|||
{ data: Promise<{ data: ImageData; url: string }>; time: Date }
|
||||
> = {}
|
||||
|
||||
public SourceIcon(
|
||||
img?: { id: string; url: string },
|
||||
location?: {
|
||||
lon: number
|
||||
lat: number
|
||||
}
|
||||
): BaseUIElement {
|
||||
const host = "https://" + new URL(img.url).host
|
||||
const p = new Panoramax(host)
|
||||
return new Link(
|
||||
new SvelteUIElement(Panoramax_bw),
|
||||
p.createViewLink({
|
||||
imageId: img?.id,
|
||||
location,
|
||||
}),
|
||||
true
|
||||
)
|
||||
public SourceIcon(): SvelteUIElement {
|
||||
return new SvelteUIElement(Panoramax_bw)
|
||||
}
|
||||
|
||||
visitUrl(
|
||||
|
|
|
@ -3,7 +3,7 @@ import BaseUIElement from "../../UI/BaseUIElement"
|
|||
import { WikimediaImageProvider } from "./WikimediaImageProvider"
|
||||
import Wikidata from "../Web/Wikidata"
|
||||
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
||||
import * as Wikidata_icon from "../../assets/svg/Wikidata.svelte"
|
||||
import Wikidata_icon from "../../assets/svg/Wikidata.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
||||
|
|
|
@ -12,7 +12,6 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
|||
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import usersettings from "../../../public/assets/generated/layers/usersettings.json"
|
||||
import Locale from "../../UI/i18n/Locale"
|
||||
import LinkToWeblate from "../../UI/Base/LinkToWeblate"
|
||||
import FeatureSwitchState from "./FeatureSwitchState"
|
||||
import Constants from "../../Models/Constants"
|
||||
import { QueryParameters } from "../Web/QueryParameters"
|
||||
|
@ -20,6 +19,7 @@ import { ThemeMetaTagging } from "./UserSettingsMetaTagging"
|
|||
import Showdown from "showdown"
|
||||
import { LocalStorageSource } from "../Web/LocalStorageSource"
|
||||
import { GeocodeResult } from "../Search/GeocodingProvider"
|
||||
import Translations from "../../UI/i18n/Translations"
|
||||
|
||||
class RoundRobinStore<T> {
|
||||
private readonly _store: UIEventSource<T[]>
|
||||
|
@ -562,7 +562,7 @@ export default class UserRelatedState {
|
|||
hasMissingTheme
|
||||
? {
|
||||
id: "theme:" + layout.id,
|
||||
link: LinkToWeblate.hrefToWeblateZen(
|
||||
link: Translations.hrefToWeblateZen(
|
||||
language,
|
||||
"themes",
|
||||
layout.id
|
||||
|
@ -571,7 +571,7 @@ export default class UserRelatedState {
|
|||
: undefined,
|
||||
...missingLayers.map((id) => ({
|
||||
id: "layer:" + id,
|
||||
link: LinkToWeblate.hrefToWeblateZen(language, "layers", id),
|
||||
link: Translations.hrefToWeblateZen(language, "layers", id),
|
||||
})),
|
||||
])
|
||||
const untranslated_count = untranslated.length
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
import { Utils } from "../../Utils"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export default class Img extends BaseUIElement {
|
||||
private readonly _src: string
|
||||
private readonly _rawSvg: boolean
|
||||
private readonly _options: { readonly fallbackImage?: string }
|
||||
|
||||
/** @deprecated
|
||||
*/
|
||||
constructor(
|
||||
src: string,
|
||||
rawSvg = false,
|
||||
options?: {
|
||||
fallbackImage?: string
|
||||
}
|
||||
) {
|
||||
super()
|
||||
if (src === undefined || src === "undefined") {
|
||||
throw "Undefined src for image"
|
||||
}
|
||||
this._src = src
|
||||
this._rawSvg = rawSvg
|
||||
this._options = options
|
||||
}
|
||||
|
||||
static AsData(source: string) {
|
||||
if (Utils.runningFromConsole) {
|
||||
return source
|
||||
}
|
||||
try {
|
||||
return `data:image/svg+xml;base64,${btoa(source)}`
|
||||
} catch (e) {
|
||||
console.error("Cannot create an image for", source.slice(0, 100))
|
||||
console.trace("Cannot create an image for the given source string due to ", e)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
static AsImageElement(source: string, css_class: string = "", style = ""): string {
|
||||
return `<img class="${css_class}" style="${style}" alt="" src="${Img.AsData(source)}">`
|
||||
}
|
||||
|
||||
AsMarkdown(): string {
|
||||
if (this._rawSvg === true) {
|
||||
console.warn("Converting raw svgs to markdown is not supported")
|
||||
return undefined
|
||||
}
|
||||
let src = this._src
|
||||
if (this._src.startsWith("./")) {
|
||||
src = "https://mapcomplete.org/" + src
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
if (this._rawSvg) {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = this._src
|
||||
return e
|
||||
}
|
||||
|
||||
const el = document.createElement("img")
|
||||
el.src = this._src
|
||||
el.onload = () => {
|
||||
el.style.opacity = "1"
|
||||
}
|
||||
el.onerror = () => {
|
||||
if (this._options?.fallbackImage) {
|
||||
if (el.src === this._options.fallbackImage) {
|
||||
// Sigh... nothing to be done anymore
|
||||
return
|
||||
}
|
||||
el.src = this._options.fallbackImage
|
||||
}
|
||||
}
|
||||
return el
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import BaseUIElement from "../BaseUIElement"
|
||||
|
||||
export default class Lazy extends BaseUIElement {
|
||||
private readonly _f: () => BaseUIElement
|
||||
|
||||
constructor(f: () => BaseUIElement) {
|
||||
super()
|
||||
this._f = f
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
// The caching of the BaseUIElement will guarantee that _f will only be called once
|
||||
return this._f().ConstructElement()
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
import { VariableUiElement } from "./VariableUIElement"
|
||||
import Locale from "../i18n/Locale"
|
||||
import Link from "./Link"
|
||||
import SvelteUIElement from "./SvelteUIElement"
|
||||
import Translate from "../../assets/svg/Translate.svelte"
|
||||
import Constants from "../../Models/Constants"
|
||||
|
||||
/**
|
||||
* The little 'translate'-icon next to every icon + some static helper functions
|
||||
*/
|
||||
export default class LinkToWeblate extends VariableUiElement {
|
||||
constructor(context: string, availableTranslations: object) {
|
||||
super(
|
||||
Locale.language.map(
|
||||
(ln) => {
|
||||
if (Locale.showLinkToWeblate.data === false) {
|
||||
return undefined
|
||||
}
|
||||
if (availableTranslations["*"] !== undefined) {
|
||||
return undefined
|
||||
}
|
||||
if (context === undefined || context.indexOf(":") < 0) {
|
||||
return undefined
|
||||
}
|
||||
const icon = new SvelteUIElement(Translate).SetClass(
|
||||
"rounded-full inline-block w-3 h-3 ml-1 weblate-link self-center"
|
||||
)
|
||||
if (availableTranslations[ln] === undefined) {
|
||||
icon.SetClass("bg-red-400")
|
||||
}
|
||||
return new Link(icon, LinkToWeblate.hrefToWeblate(ln, context), true).SetClass(
|
||||
"weblate-link"
|
||||
)
|
||||
},
|
||||
[Locale.showLinkToWeblate]
|
||||
)
|
||||
)
|
||||
this.SetClass("enable-links")
|
||||
const self = this
|
||||
Locale.showLinkOnMobile.addCallbackAndRunD((showOnMobile) => {
|
||||
if (showOnMobile) {
|
||||
self.RemoveClass("hidden-on-mobile")
|
||||
} else {
|
||||
self.SetClass("hidden-on-mobile")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the url to Hosted weblate
|
||||
*
|
||||
* LinkToWeblate.hrefToWeblate("nl", "category:some.context") // => "https://translate.mapcomplete.org/translate/mapcomplete/category/nl/?offset=1&q=context%3A%3D%22some.context%22"
|
||||
*/
|
||||
public static hrefToWeblate(language: string, contextKey: string): string {
|
||||
if (contextKey === undefined || contextKey.indexOf(":") < 0) {
|
||||
return undefined
|
||||
}
|
||||
const [category, ...rest] = contextKey.split(":")
|
||||
const key = rest.join(":")
|
||||
|
||||
const baseUrl = Constants.weblate + "translate/mapcomplete/"
|
||||
return baseUrl + category + "/" + language + "/?offset=1&q=context%3A%3D%22" + key + "%22"
|
||||
}
|
||||
|
||||
public static hrefToWeblateZen(
|
||||
language: string,
|
||||
category: "core" | "themes" | "layers" | "shared-questions" | "glossary" | string,
|
||||
searchKey: string
|
||||
): string {
|
||||
const baseUrl = Constants.weblate + "zen/mapcomplete/"
|
||||
// ?offset=1&q=+state%3A%3Ctranslated+context%3Acampersite&sort_by=-priority%2Cposition&checksum=
|
||||
return (
|
||||
baseUrl +
|
||||
category +
|
||||
"/" +
|
||||
language +
|
||||
"?offset=1&q=+state%3A%3Ctranslated+context%3A" +
|
||||
encodeURIComponent(searchKey) +
|
||||
"&sort_by=-priority%2Cposition&checksum="
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import Locale from "../i18n/Locale"
|
||||
import LinkToWeblate from "./LinkToWeblate"
|
||||
import Translate from "../../assets/svg/Translate.svelte"
|
||||
import { LanguageIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
/**
|
||||
* Shows a small icon which will open up weblate; a contributor can translate the item for 'context' there
|
||||
|
@ -17,7 +17,7 @@
|
|||
{#if !!context && context.indexOf(":") > 0}
|
||||
{#if $linkOnMobile}
|
||||
<a
|
||||
href={LinkToWeblate.hrefToWeblate($language, context)}
|
||||
href={Translations.hrefToWeblate($language, context)}
|
||||
target="_blank"
|
||||
class="weblate-link mx-1"
|
||||
tabindex="-1"
|
||||
|
@ -26,7 +26,7 @@
|
|||
</a>
|
||||
{:else if $linkToWeblate}
|
||||
<a
|
||||
href={LinkToWeblate.hrefToWeblate($language, context)}
|
||||
href={Translations.hrefToWeblate($language, context)}
|
||||
class="weblate-link hidden-on-mobile"
|
||||
target="_blank"
|
||||
tabindex="-1"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
? new ImmutableStore(image.license)
|
||||
: UIEventSource.FromPromise(image.provider?.DownloadAttribution(image))
|
||||
let icon = image.provider?.SourceIcon(image)
|
||||
let openOriginal = image.provider?.visitUrl(image)
|
||||
</script>
|
||||
|
||||
{#if $license !== undefined}
|
||||
|
@ -25,9 +26,15 @@
|
|||
class="no-images bg-black-transparent flex items-center rounded-lg p-0.5 px-3 text-sm text-white"
|
||||
>
|
||||
{#if icon !== undefined}
|
||||
<div class="mr-2 h-6 w-6">
|
||||
<ToSvelte construct={icon} />
|
||||
</div>
|
||||
{#if openOriginal}
|
||||
<a href={openOriginal} target="_blank" rel="noopener" class="mr-2 h-6 w-6">
|
||||
<ToSvelte construct={icon} />
|
||||
</a>
|
||||
{:else}
|
||||
<div class="mr-2 h-6 w-6">
|
||||
<ToSvelte construct={icon} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<div class="flex gap-x-2" class:flex-col={attributionFormat !== "minimal"}>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import BaseUIElement from "./BaseUIElement"
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export abstract class UIElement extends BaseUIElement {
|
||||
/**
|
||||
* Should be overridden for specific HTML functionality
|
||||
*/
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
// Uses the old fashioned way to construct an element using 'InnerRender'
|
||||
const innerRender = this.InnerRender()
|
||||
if (innerRender === undefined || innerRender === "") {
|
||||
return undefined
|
||||
}
|
||||
const el = document.createElement("span")
|
||||
if (typeof innerRender === "string") {
|
||||
el.innerHTML = innerRender
|
||||
} else {
|
||||
const subElement = innerRender.ConstructElement()
|
||||
if (subElement === undefined) {
|
||||
return undefined
|
||||
}
|
||||
el.appendChild(subElement)
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
protected abstract InnerRender(): string | BaseUIElement
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import Locale from "./Locale"
|
||||
import { Utils } from "../../Utils"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import LinkToWeblate from "../Base/LinkToWeblate"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
|
||||
export class Translation extends BaseUIElement {
|
||||
|
@ -209,22 +208,7 @@ export class Translation extends BaseUIElement {
|
|||
}
|
||||
})
|
||||
|
||||
if (this.context === undefined || this.context?.indexOf(":") < 0) {
|
||||
return el
|
||||
}
|
||||
|
||||
const wrapper = document.createElement("span")
|
||||
wrapper.appendChild(el)
|
||||
Locale.showLinkToWeblate.addCallbackAndRun((doShow) => {
|
||||
if (!doShow) {
|
||||
return
|
||||
}
|
||||
const linkToWeblate = new LinkToWeblate(this.context, this.translations)
|
||||
wrapper.appendChild(linkToWeblate.ConstructElement())
|
||||
return true
|
||||
})
|
||||
|
||||
return wrapper
|
||||
return el
|
||||
}
|
||||
|
||||
public SupportedLanguages(): string[] {
|
||||
|
|
|
@ -6,6 +6,7 @@ import LanguageUtils from "../../Utils/LanguageUtils"
|
|||
import { Store } from "../../Logic/UIEventSource"
|
||||
import Locale from "./Locale"
|
||||
import { Utils } from "../../Utils"
|
||||
import Constants from "../../Models/Constants"
|
||||
|
||||
export default class Translations {
|
||||
static readonly t: Readonly<typeof CompiledTranslations.t> = CompiledTranslations.t
|
||||
|
@ -169,4 +170,38 @@ export default class Translations {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the url to Hosted weblate
|
||||
*
|
||||
* LinkToWeblate.hrefToWeblate("nl", "category:some.context") // => "https://translate.mapcomplete.org/translate/mapcomplete/category/nl/?offset=1&q=context%3A%3D%22some.context%22"
|
||||
*/
|
||||
public static hrefToWeblate(language: string, contextKey: string): string {
|
||||
if (contextKey === undefined || contextKey.indexOf(":") < 0) {
|
||||
return undefined
|
||||
}
|
||||
const [category, ...rest] = contextKey.split(":")
|
||||
const key = rest.join(":")
|
||||
|
||||
const baseUrl = Constants.weblate + "translate/mapcomplete/"
|
||||
return baseUrl + category + "/" + language + "/?offset=1&q=context%3A%3D%22" + key + "%22"
|
||||
}
|
||||
|
||||
public static hrefToWeblateZen(
|
||||
language: string,
|
||||
category: "core" | "themes" | "layers" | "shared-questions" | "glossary" | string,
|
||||
searchKey: string
|
||||
): string {
|
||||
const baseUrl = Constants.weblate + "zen/mapcomplete/"
|
||||
// ?offset=1&q=+state%3A%3Ctranslated+context%3Acampersite&sort_by=-priority%2Cposition&checksum=
|
||||
return (
|
||||
baseUrl +
|
||||
category +
|
||||
"/" +
|
||||
language +
|
||||
"?offset=1&q=+state%3A%3Ctranslated+context%3A" +
|
||||
encodeURIComponent(searchKey) +
|
||||
"&sort_by=-priority%2Cposition&checksum="
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue