forked from MapComplete/MapComplete
Performance: trim svg.ts, use Svelte-SVG-componenets where possible (WIP)
This commit is contained in:
parent
ac5c60c3f0
commit
c13d80f062
37 changed files with 367 additions and 378 deletions
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import { onDestroy } from "svelte"
|
||||
import Hand from "../../assets/svg/Hand.svelte";
|
||||
|
||||
let mainElem: HTMLElement
|
||||
export let hideSignal: Store<any>
|
||||
|
|
@ -34,7 +35,7 @@
|
|||
|
||||
<div bind:this={mainElem} class="pointer-events-none absolute bottom-0 right-0 h-full w-full">
|
||||
<div id="hand-container">
|
||||
<img src="./assets/svg/hand.svg" />
|
||||
<Hand />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import Tr from "./Tr.svelte"
|
||||
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
||||
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Invalid from "../../assets/svg/Invalid.svelte";
|
||||
|
||||
export let state: {
|
||||
osmConnection: OsmConnection
|
||||
|
|
@ -35,7 +36,7 @@
|
|||
</slot>
|
||||
{:else if $loadingStatus === "error"}
|
||||
<div class="alert max-w-64 flex items-center">
|
||||
<img src="./assets/svg/invalid.svg" class="m-2 h-8 w-8 shrink-0" />
|
||||
<Invalid class="m-2 h-8 w-8 shrink-0" />
|
||||
<Tr t={offlineModes[$apiState]} />
|
||||
</div>
|
||||
{:else if $loadingStatus === "logged-in"}
|
||||
|
|
|
|||
15
src/UI/Base/LogoutButton.svelte
Normal file
15
src/UI/Base/LogoutButton.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { OsmConnection } from "../../Logic/Osm/OsmConnection";
|
||||
import Logout from "../../assets/svg/Logout.svelte";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Tr from "./Tr.svelte";
|
||||
|
||||
export let osmConnection: OsmConnection
|
||||
</script>
|
||||
|
||||
<button on:click={() => {
|
||||
state.osmConnection.LogOut()
|
||||
}}>
|
||||
<Logout class="w-6 h-6"/>
|
||||
<Tr t={Translations.t.general.logout}/>
|
||||
</button>
|
||||
48
src/UI/Base/OpenJosm.svelte
Normal file
48
src/UI/Base/OpenJosm.svelte
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<script lang="ts">
|
||||
import { UIEventSource } from "../../Logic/UIEventSource";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Tr from "./Tr.svelte";
|
||||
import Josm_logo from "../../assets/svg/Josm_logo.svelte";
|
||||
import Constants from "../../Models/Constants";
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization";
|
||||
|
||||
export let state : SpecialVisualizationState
|
||||
const t = Translations.t.general.attribution;
|
||||
const josmState = new UIEventSource<"OK" | string>(undefined);
|
||||
// Reset after 15s
|
||||
josmState.stabilized(15000).addCallbackD(() => josmState.setData(undefined));
|
||||
|
||||
const showButton = state.osmConnection.userDetails.map(
|
||||
(ud) => ud.loggedIn && ud.csCount >= Constants.userJourney.historyLinkVisible
|
||||
);
|
||||
|
||||
function openJosm() {
|
||||
const bbox = state.mapProperties. bounds.data;
|
||||
if (bbox === undefined) {
|
||||
return;
|
||||
}
|
||||
const top = bbox.getNorth();
|
||||
const bottom = bbox.getSouth();
|
||||
const right = bbox.getEast();
|
||||
const left = bbox.getWest();
|
||||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`;
|
||||
Utils.download(josmLink)
|
||||
.then((answer) => josmState.setData(answer.replace(/\n/g, "").trim()))
|
||||
.catch(() => josmState.setData("ERROR"));
|
||||
}
|
||||
|
||||
</script>
|
||||
{#if $showButton}
|
||||
{#if $josmState === undefined}
|
||||
<!-- empty -->
|
||||
{:else if state === "OK"}
|
||||
<Tr cls="thanks" t={t.josmOpened} />
|
||||
{:else}
|
||||
<Tr cls="alert" t={t.josmNotOpened} />
|
||||
{/if}
|
||||
|
||||
<button class="flex items-center" on:click={openJosm}>
|
||||
<Josm_logo class="h-12 w-12 p-2 pr-4" />
|
||||
<Tr t={t.editJosm} />
|
||||
</button>
|
||||
{/if}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import ToSvelte from "./ToSvelte.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import Share from "../../assets/svg/Share.svelte";
|
||||
|
||||
export let generateShareData: () => {
|
||||
text: string
|
||||
|
|
@ -25,6 +26,6 @@
|
|||
|
||||
<button on:click={share} class="secondary m-0 h-8 w-8 p-0">
|
||||
<slot name="content">
|
||||
<ToSvelte construct={Svg.share_svg().SetClass("w-7 h-7 p-1")} />
|
||||
<Share class="w-7 h-7 p-1"/>
|
||||
</slot>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ export default class SvelteUIElement<
|
|||
private readonly _events: Events
|
||||
private readonly _slots: Slots
|
||||
|
||||
constructor(svelteElement, props: Props, events?: Events, slots?: Slots) {
|
||||
constructor(svelteElement, props?: Props, events?: Events, slots?: Slots) {
|
||||
super()
|
||||
this._svelteComponent = svelteElement
|
||||
this._props = props
|
||||
this._props = props ?? <Props>{}
|
||||
this._events = events
|
||||
this._slots = slots
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import Locale from "../i18n/Locale"
|
||||
import LinkToWeblate from "./LinkToWeblate"
|
||||
import Translate from "../../assets/svg/Translate.svelte";
|
||||
|
||||
/**
|
||||
* Shows a small icon which will open up weblate; a contributor can translate the item for 'context' there
|
||||
|
|
@ -19,7 +20,7 @@
|
|||
target="_blank"
|
||||
class="weblate-link mx-1"
|
||||
>
|
||||
<img src="./assets/svg/translate.svg" class="font-gray" />
|
||||
<Translate class="font-gray" />
|
||||
</a>
|
||||
{:else if $linkToWeblate}
|
||||
<a
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
class="weblate-link hidden-on-mobile mx-1"
|
||||
target="_blank"
|
||||
>
|
||||
<img src="./assets/svg/translate.svg" class="font-gray inline-block" />
|
||||
<Translate class="font-gray inline-block" />
|
||||
</a>
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import { Store } from "../../Logic/UIEventSource"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Mapillary_black from "../../assets/svg/Mapillary_black.svelte";
|
||||
|
||||
/*
|
||||
A subtleButton which opens mapillary in a new tab at the current location
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
</script>
|
||||
|
||||
<a class="button flex items-center" href={mapillaryLink} target="_blank">
|
||||
<ToSvelte construct={() => Svg.mapillary_black_svg().SetClass("w-12 h-12 m-2 mr-4 shrink-0")} />
|
||||
<Mapillary_black class="w-12 h-12 m-2 mr-4 shrink-0"/>
|
||||
<div class="flex flex-col">
|
||||
<Tr t={Translations.t.general.attribution.openMapillary} />
|
||||
<Tr cls="subtle" t={Translations.t.general.attribution.mapillaryHelp} />
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import { Utils } from "../../Utils"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import Move_arrows from "../../assets/svg/Move_arrows.svelte";
|
||||
|
||||
/**
|
||||
* An advanced location input, which has support to:
|
||||
|
|
@ -125,6 +126,6 @@
|
|||
maxDistanceInMeters="50"
|
||||
>
|
||||
<slot name="image" slot="image">
|
||||
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" />
|
||||
<Move_arrows class="h-full max-h-24" />
|
||||
</slot>
|
||||
</LocationInput>
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
import Combine from "../Base/Combine"
|
||||
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import Toggle from "../Input/Toggle"
|
||||
import { SubtleButton } from "../Base/SubtleButton"
|
||||
import Svg from "../../Svg"
|
||||
import { Utils } from "../../Utils"
|
||||
import Constants from "../../Models/Constants"
|
||||
|
||||
export class OpenJosm extends Combine {
|
||||
public static readonly needsUrls = ["http://127.0.0.1:8111/load_and_zoom"]
|
||||
constructor(osmConnection: OsmConnection, bounds: Store<BBox>, iconStyle?: string) {
|
||||
const t = Translations.t.general.attribution
|
||||
|
||||
const josmState = new UIEventSource<string>(undefined)
|
||||
// Reset after 15s
|
||||
josmState.stabilized(15000).addCallbackD(() => josmState.setData(undefined))
|
||||
|
||||
const stateIndication = new VariableUiElement(
|
||||
josmState.map((state) => {
|
||||
if (state === undefined) {
|
||||
return undefined
|
||||
}
|
||||
state = state.toUpperCase()
|
||||
if (state === "OK") {
|
||||
return t.josmOpened.SetClass("thanks")
|
||||
}
|
||||
return t.josmNotOpened.SetClass("alert")
|
||||
})
|
||||
)
|
||||
|
||||
const toggle = new Toggle(
|
||||
new SubtleButton(Svg.josm_logo_svg().SetStyle(iconStyle), t.editJosm)
|
||||
.onClick(() => {
|
||||
const bbox = bounds.data
|
||||
if (bbox === undefined) {
|
||||
return
|
||||
}
|
||||
const top = bbox.getNorth()
|
||||
const bottom = bbox.getSouth()
|
||||
const right = bbox.getEast()
|
||||
const left = bbox.getWest()
|
||||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`
|
||||
Utils.download(josmLink)
|
||||
.then((answer) => josmState.setData(answer.replace(/\n/g, "").trim()))
|
||||
.catch(() => josmState.setData("ERROR"))
|
||||
})
|
||||
.SetClass("w-full"),
|
||||
undefined,
|
||||
osmConnection.userDetails.map(
|
||||
(ud) => ud.loggedIn && ud.csCount >= Constants.userJourney.historyLinkVisible
|
||||
)
|
||||
)
|
||||
|
||||
super([stateIndication, toggle])
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
import If from "../Base/If.svelte"
|
||||
import { ExclamationTriangleIcon } from "@babeard/svelte-heroicons/mini"
|
||||
import type { Readable } from "svelte/store"
|
||||
import Add from "../../assets/svg/Add.svelte";
|
||||
|
||||
/**
|
||||
* The theme introduction panel
|
||||
|
|
@ -156,7 +157,7 @@
|
|||
<div class="links-as-button links-w-full m-2 flex flex-col gap-y-1">
|
||||
<!-- bottom buttons, a bit hidden away: switch layout -->
|
||||
<a class="flex" href={Utils.HomepageLink()}>
|
||||
<img class="h-6 w-6" src="./assets/svg/add.svg" />
|
||||
<Add class="h-6 w-6"/>
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import { OsmConnection } from "../../Logic/Osm/OsmConnection"
|
|||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import { LoginToggle } from "../Popup/LoginButton"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import Upload from "../../assets/svg/Upload.svelte"
|
||||
|
||||
export default class UploadTraceToOsmUI extends LoginToggle {
|
||||
constructor(
|
||||
|
|
@ -83,7 +85,7 @@ export default class UploadTraceToOsmUI extends LoginToggle {
|
|||
clicked.setData(false)
|
||||
})
|
||||
.SetClass(""),
|
||||
new SubtleButton(Svg.upload_svg(), t.confirm).OnClickWithLoading(
|
||||
new SubtleButton(new SvelteUIElement(Upload, {}), t.confirm).OnClickWithLoading(
|
||||
t.uploading,
|
||||
async () => {
|
||||
const titleStr = UploadTraceToOsmUI.createDefault(
|
||||
|
|
@ -119,7 +121,7 @@ export default class UploadTraceToOsmUI extends LoginToggle {
|
|||
]).SetClass("flex p-2 rounded-xl border-2 subtle-border items-center"),
|
||||
new Toggle(
|
||||
confirmPanel,
|
||||
new SubtleButton(Svg.upload_svg(), t.title).onClick(() =>
|
||||
new SubtleButton(new SvelteUIElement(Upload), t.title).onClick(() =>
|
||||
clicked.setData(true)
|
||||
),
|
||||
clicked
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@
|
|||
* Shows an 'upload'-button which will start the upload for this feature
|
||||
*/
|
||||
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
|
||||
import type { OsmTags } from "../../Models/OsmFeature"
|
||||
import LoginToggle from "../Base/LoginToggle.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import UploadingImageCounter from "./UploadingImageCounter.svelte"
|
||||
import FileSelector from "../Base/FileSelector.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization";
|
||||
import { ImmutableStore, Store } from "../../Logic/UIEventSource";
|
||||
import type { OsmTags } from "../../Models/OsmFeature";
|
||||
import LoginToggle from "../Base/LoginToggle.svelte";
|
||||
import Translations from "../i18n/Translations";
|
||||
import Tr from "../Base/Tr.svelte";
|
||||
import UploadingImageCounter from "./UploadingImageCounter.svelte";
|
||||
import FileSelector from "../Base/FileSelector.svelte";
|
||||
import Camera_plus from "../../assets/svg/Camera_plus.svelte";
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
|
||||
|
|
@ -58,7 +57,7 @@
|
|||
{#if image !== undefined}
|
||||
<img src={image} />
|
||||
{:else}
|
||||
<ToSvelte construct={Svg.camera_plus_svg().SetClass("block w-12 h-12 p-1 text-4xl ")} />
|
||||
<Camera_plus class="block w-12 h-12 p-1 text-4xl"/>
|
||||
{/if}
|
||||
{#if labelText}
|
||||
{labelText}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import * as turf from "@turf/turf"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import { createEventDispatcher, onDestroy } from "svelte"
|
||||
import Move_arrows from "../../../assets/svg/Move_arrows.svelte";
|
||||
|
||||
/**
|
||||
* A visualisation to pick a location on a map background
|
||||
|
|
@ -90,7 +91,7 @@
|
|||
class="pointer-events-none absolute top-0 left-0 flex h-full w-full items-center p-8 opacity-50"
|
||||
>
|
||||
<slot name="image">
|
||||
<img class="h-full max-h-24" src="./assets/svg/move-arrows.svg" />
|
||||
<Move_arrows class="h-full max-h-24"/>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
<script lang="ts">
|
||||
import PointRenderingConfig, { IconConfig } from "../../Models/ThemeConfig/PointRenderingConfig"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import DynamicIcon from "./DynamicIcon.svelte"
|
||||
import { IconConfig } from "../../Models/ThemeConfig/PointRenderingConfig";
|
||||
import { ImmutableStore, Store } from "../../Logic/UIEventSource";
|
||||
import DynamicIcon from "./DynamicIcon.svelte";
|
||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
|
||||
|
||||
/**
|
||||
* Renders a 'marker', which consists of multiple 'icons'
|
||||
*/
|
||||
export let config: PointRenderingConfig
|
||||
let icons: IconConfig[] = config.marker
|
||||
export let tags: Store<Record<string, string>>
|
||||
let rotation = tags.map(tags => config.rotation.GetRenderValue(tags).Subs(tags).txt)
|
||||
|
||||
export let marker: IconConfig[] = config?.marker;
|
||||
export let rotation: TagRenderingConfig
|
||||
export let tags: Store<Record<string, string>>;
|
||||
let _rotation = rotation ? tags.map(tags => rotation.GetRenderValue(tags).Subs(tags).txt) : new ImmutableStore(0);
|
||||
</script>
|
||||
|
||||
{#if config !== undefined}
|
||||
<div class="relative h-full w-full" style={`transform: rotate(${$rotation})`}>
|
||||
{#each icons as icon}
|
||||
{#if marker && marker}
|
||||
<div class="relative h-full w-full" style={`transform: rotate(${$_rotation})`}>
|
||||
{#each marker as icon}
|
||||
<DynamicIcon {icon} {tags} />
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import { createEventDispatcher } from "svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import Plantnet_logo from "../../assets/svg/Plantnet_logo.svelte";
|
||||
|
||||
/**
|
||||
* The main entry point for the plantnet wizard
|
||||
|
|
@ -142,9 +143,7 @@
|
|||
</BackButton>
|
||||
{/if}
|
||||
<div class="low-interaction flex self-end rounded-xl p-2">
|
||||
<ToSvelte
|
||||
construct={Svg.plantnet_logo_svg().SetClass("w-8 h-8 p-1 mr-1 bg-white rounded-full")}
|
||||
/>
|
||||
<Plantnet_logo class="w-8 h-8 p-1 mr-1 bg-white rounded-full"/>
|
||||
<Tr t={t.poweredByPlantnet} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,109 +3,110 @@
|
|||
* This component ties together all the steps that are needed to create a new point.
|
||||
* There are many subcomponents which help with that
|
||||
*/
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
||||
import PresetList from "./PresetList.svelte"
|
||||
import type PresetConfig from "../../../Models/ThemeConfig/PresetConfig"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import Tr from "../../Base/Tr.svelte"
|
||||
import SubtleButton from "../../Base/SubtleButton.svelte"
|
||||
import FromHtml from "../../Base/FromHtml.svelte"
|
||||
import Translations from "../../i18n/Translations.js"
|
||||
import TagHint from "../TagHint.svelte"
|
||||
import { And } from "../../../Logic/Tags/And.js"
|
||||
import LoginToggle from "../../Base/LoginToggle.svelte"
|
||||
import Constants from "../../../Models/Constants.js"
|
||||
import FilteredLayer from "../../../Models/FilteredLayer"
|
||||
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
||||
import { EyeIcon, EyeOffIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import LoginButton from "../../Base/LoginButton.svelte"
|
||||
import NewPointLocationInput from "../../BigComponents/NewPointLocationInput.svelte"
|
||||
import CreateNewNodeAction from "../../../Logic/Osm/Actions/CreateNewNodeAction"
|
||||
import { OsmWay } from "../../../Logic/Osm/OsmObject"
|
||||
import { Tag } from "../../../Logic/Tags/Tag"
|
||||
import type { WayId } from "../../../Models/OsmFeature"
|
||||
import Loading from "../../Base/Loading.svelte"
|
||||
import type { GlobalFilter } from "../../../Models/GlobalFilter"
|
||||
import { onDestroy } from "svelte"
|
||||
import NextButton from "../../Base/NextButton.svelte"
|
||||
import BackButton from "../../Base/BackButton.svelte"
|
||||
import ToSvelte from "../../Base/ToSvelte.svelte"
|
||||
import Svg from "../../../Svg"
|
||||
import OpenBackgroundSelectorButton from "../../BigComponents/OpenBackgroundSelectorButton.svelte"
|
||||
import { twJoin } from "tailwind-merge"
|
||||
import type { SpecialVisualizationState } from "../../SpecialVisualization";
|
||||
import PresetList from "./PresetList.svelte";
|
||||
import type PresetConfig from "../../../Models/ThemeConfig/PresetConfig";
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
|
||||
import Tr from "../../Base/Tr.svelte";
|
||||
import SubtleButton from "../../Base/SubtleButton.svelte";
|
||||
import Translations from "../../i18n/Translations.js";
|
||||
import TagHint from "../TagHint.svelte";
|
||||
import { And } from "../../../Logic/Tags/And.js";
|
||||
import LoginToggle from "../../Base/LoginToggle.svelte";
|
||||
import Constants from "../../../Models/Constants.js";
|
||||
import FilteredLayer from "../../../Models/FilteredLayer";
|
||||
import { Store, UIEventSource } from "../../../Logic/UIEventSource";
|
||||
import { EyeIcon, EyeOffIcon } from "@rgossiaux/svelte-heroicons/solid";
|
||||
import LoginButton from "../../Base/LoginButton.svelte";
|
||||
import NewPointLocationInput from "../../BigComponents/NewPointLocationInput.svelte";
|
||||
import CreateNewNodeAction from "../../../Logic/Osm/Actions/CreateNewNodeAction";
|
||||
import { OsmWay } from "../../../Logic/Osm/OsmObject";
|
||||
import { Tag } from "../../../Logic/Tags/Tag";
|
||||
import type { WayId } from "../../../Models/OsmFeature";
|
||||
import Loading from "../../Base/Loading.svelte";
|
||||
import type { GlobalFilter } from "../../../Models/GlobalFilter";
|
||||
import { onDestroy } from "svelte";
|
||||
import NextButton from "../../Base/NextButton.svelte";
|
||||
import BackButton from "../../Base/BackButton.svelte";
|
||||
import ToSvelte from "../../Base/ToSvelte.svelte";
|
||||
import Svg from "../../../Svg";
|
||||
import OpenBackgroundSelectorButton from "../../BigComponents/OpenBackgroundSelectorButton.svelte";
|
||||
import { twJoin } from "tailwind-merge";
|
||||
import Confirm from "../../../assets/svg/Confirm.svelte";
|
||||
import Close from "../../../assets/svg/Close.svelte";
|
||||
|
||||
export let coordinate: { lon: number; lat: number }
|
||||
export let state: SpecialVisualizationState
|
||||
export let coordinate: { lon: number; lat: number };
|
||||
export let state: SpecialVisualizationState;
|
||||
|
||||
let selectedPreset: {
|
||||
preset: PresetConfig
|
||||
layer: LayerConfig
|
||||
icon: string
|
||||
tags: Record<string, string>
|
||||
} = undefined
|
||||
let checkedOfGlobalFilters: number = 0
|
||||
let confirmedCategory = false
|
||||
} = undefined;
|
||||
let checkedOfGlobalFilters: number = 0;
|
||||
let confirmedCategory = false;
|
||||
$: if (selectedPreset === undefined) {
|
||||
confirmedCategory = false
|
||||
creating = false
|
||||
checkedOfGlobalFilters = 0
|
||||
confirmedCategory = false;
|
||||
creating = false;
|
||||
checkedOfGlobalFilters = 0;
|
||||
}
|
||||
|
||||
let flayer: FilteredLayer = undefined
|
||||
let layerIsDisplayed: UIEventSource<boolean> | undefined = undefined
|
||||
let layerHasFilters: Store<boolean> | undefined = undefined
|
||||
let globalFilter: UIEventSource<GlobalFilter[]> = state.layerState.globalFilters
|
||||
let _globalFilter: GlobalFilter[] = []
|
||||
let flayer: FilteredLayer = undefined;
|
||||
let layerIsDisplayed: UIEventSource<boolean> | undefined = undefined;
|
||||
let layerHasFilters: Store<boolean> | undefined = undefined;
|
||||
let globalFilter: UIEventSource<GlobalFilter[]> = state.layerState.globalFilters;
|
||||
let _globalFilter: GlobalFilter[] = [];
|
||||
onDestroy(
|
||||
globalFilter.addCallbackAndRun((globalFilter) => {
|
||||
console.log("Global filters are", globalFilter)
|
||||
_globalFilter = globalFilter ?? []
|
||||
console.log("Global filters are", globalFilter);
|
||||
_globalFilter = globalFilter ?? [];
|
||||
})
|
||||
)
|
||||
);
|
||||
$: {
|
||||
flayer = state.layerState.filteredLayers.get(selectedPreset?.layer?.id)
|
||||
layerIsDisplayed = flayer?.isDisplayed
|
||||
layerHasFilters = flayer?.hasFilter
|
||||
flayer = state.layerState.filteredLayers.get(selectedPreset?.layer?.id);
|
||||
layerIsDisplayed = flayer?.isDisplayed;
|
||||
layerHasFilters = flayer?.hasFilter;
|
||||
}
|
||||
const t = Translations.t.general.add
|
||||
const t = Translations.t.general.add;
|
||||
|
||||
const zoom = state.mapProperties.zoom
|
||||
const zoom = state.mapProperties.zoom;
|
||||
|
||||
const isLoading = state.dataIsLoading
|
||||
let preciseCoordinate: UIEventSource<{ lon: number; lat: number }> = new UIEventSource(undefined)
|
||||
let snappedToObject: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||
const isLoading = state.dataIsLoading;
|
||||
let preciseCoordinate: UIEventSource<{ lon: number; lat: number }> = new UIEventSource(undefined);
|
||||
let snappedToObject: UIEventSource<string> = new UIEventSource<string>(undefined);
|
||||
|
||||
// Small helper variable: if the map is tapped, we should let the 'Next'-button grab some attention as users have to click _that_ to continue, not the map
|
||||
let preciseInputIsTapped = false
|
||||
let preciseInputIsTapped = false;
|
||||
|
||||
let creating = false
|
||||
let creating = false;
|
||||
|
||||
/**
|
||||
* Call when the user should restart the flow by clicking on the map, e.g. because they disabled filters.
|
||||
* Will delete the lastclick-location
|
||||
*/
|
||||
function abort() {
|
||||
state.selectedElement.setData(undefined)
|
||||
state.selectedElement.setData(undefined);
|
||||
// When aborted, we force the contributors to place the pin _again_
|
||||
// This is because there might be a nearby object that was disabled; this forces them to re-evaluate the map
|
||||
state.lastClickObject.features.setData([])
|
||||
preciseInputIsTapped = false
|
||||
state.lastClickObject.features.setData([]);
|
||||
preciseInputIsTapped = false;
|
||||
}
|
||||
|
||||
async function confirm() {
|
||||
creating = true
|
||||
const location: { lon: number; lat: number } = preciseCoordinate.data
|
||||
const snapTo: WayId | undefined = <WayId>snappedToObject.data
|
||||
creating = true;
|
||||
const location: { lon: number; lat: number } = preciseCoordinate.data;
|
||||
const snapTo: WayId | undefined = <WayId>snappedToObject.data;
|
||||
const tags: Tag[] = selectedPreset.preset.tags.concat(
|
||||
..._globalFilter.map((f) => f?.onNewPoint?.tags ?? [])
|
||||
)
|
||||
console.log("Creating new point at", location, "snapped to", snapTo, "with tags", tags)
|
||||
);
|
||||
console.log("Creating new point at", location, "snapped to", snapTo, "with tags", tags);
|
||||
|
||||
let snapToWay: undefined | OsmWay = undefined
|
||||
let snapToWay: undefined | OsmWay = undefined;
|
||||
if (snapTo !== undefined && snapTo !== null) {
|
||||
const downloaded = await state.osmObjectDownloader.DownloadObjectAsync(snapTo, 0)
|
||||
const downloaded = await state.osmObjectDownloader.DownloadObjectAsync(snapTo, 0);
|
||||
if (downloaded !== "deleted") {
|
||||
snapToWay = downloaded
|
||||
snapToWay = downloaded;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,44 +114,44 @@
|
|||
theme: state.layout?.id ?? "unkown",
|
||||
changeType: "create",
|
||||
snapOnto: snapToWay,
|
||||
reusePointWithinMeters: 1,
|
||||
})
|
||||
await state.changes.applyAction(newElementAction)
|
||||
state.newFeatures.features.ping()
|
||||
reusePointWithinMeters: 1
|
||||
});
|
||||
await state.changes.applyAction(newElementAction);
|
||||
state.newFeatures.features.ping();
|
||||
// The 'changes' should have created a new point, which added this into the 'featureProperties'
|
||||
const newId = newElementAction.newElementId
|
||||
console.log("Applied pending changes, fetching store for", newId)
|
||||
const tagsStore = state.featureProperties.getStore(newId)
|
||||
const newId = newElementAction.newElementId;
|
||||
console.log("Applied pending changes, fetching store for", newId);
|
||||
const tagsStore = state.featureProperties.getStore(newId);
|
||||
if (!tagsStore) {
|
||||
console.error("Bug: no tagsStore found for", newId)
|
||||
console.error("Bug: no tagsStore found for", newId);
|
||||
}
|
||||
{
|
||||
// Set some metainfo
|
||||
const properties = tagsStore.data
|
||||
const properties = tagsStore.data;
|
||||
if (snapTo) {
|
||||
// metatags (starting with underscore) are not uploaded, so we can safely mark this
|
||||
delete properties["_referencing_ways"]
|
||||
properties["_referencing_ways"] = `["${snapTo}"]`
|
||||
delete properties["_referencing_ways"];
|
||||
properties["_referencing_ways"] = `["${snapTo}"]`;
|
||||
}
|
||||
properties["_backend"] = state.osmConnection.Backend()
|
||||
properties["_last_edit:timestamp"] = new Date().toISOString()
|
||||
const userdetails = state.osmConnection.userDetails.data
|
||||
properties["_last_edit:contributor"] = userdetails.name
|
||||
properties["_last_edit:uid"] = "" + userdetails.uid
|
||||
tagsStore.ping()
|
||||
properties["_backend"] = state.osmConnection.Backend();
|
||||
properties["_last_edit:timestamp"] = new Date().toISOString();
|
||||
const userdetails = state.osmConnection.userDetails.data;
|
||||
properties["_last_edit:contributor"] = userdetails.name;
|
||||
properties["_last_edit:uid"] = "" + userdetails.uid;
|
||||
tagsStore.ping();
|
||||
}
|
||||
const feature = state.indexedFeatures.featuresById.data.get(newId)
|
||||
console.log("Selecting feature", feature, "and opening their popup")
|
||||
abort()
|
||||
state.selectedLayer.setData(selectedPreset.layer)
|
||||
state.selectedElement.setData(feature)
|
||||
tagsStore.ping()
|
||||
const feature = state.indexedFeatures.featuresById.data.get(newId);
|
||||
console.log("Selecting feature", feature, "and opening their popup");
|
||||
abort();
|
||||
state.selectedLayer.setData(selectedPreset.layer);
|
||||
state.selectedElement.setData(feature);
|
||||
tagsStore.ping();
|
||||
}
|
||||
|
||||
function confirmSync() {
|
||||
confirm()
|
||||
.then((_) => console.debug("New point successfully handled"))
|
||||
.catch((e) => console.error("Handling the new point went wrong due to", e))
|
||||
.catch((e) => console.error("Handling the new point went wrong due to", e));
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -285,7 +286,7 @@
|
|||
<NextButton on:click={() => (confirmedCategory = true)} clss="primary w-full">
|
||||
<div slot="image" class="relative">
|
||||
<ToSvelte construct={selectedPreset.icon} />
|
||||
<img class="absolute bottom-0 right-0 h-4 w-4" src="./assets/svg/confirm.svg" />
|
||||
<Confirm class="absolute bottom-0 right-0 h-4 w-4" />
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<Tr t={selectedPreset.text} />
|
||||
|
|
@ -299,11 +300,7 @@
|
|||
checkedOfGlobalFilters = checkedOfGlobalFilters + 1
|
||||
}}
|
||||
>
|
||||
<img
|
||||
slot="image"
|
||||
src={_globalFilter[checkedOfGlobalFilters].onNewPoint?.icon ?? "./assets/svg/confirm.svg"}
|
||||
class="h-12 w-12"
|
||||
/>
|
||||
<Confirm slot="image" class="h-12 w-12" />
|
||||
<Tr
|
||||
slot="message"
|
||||
t={_globalFilter[checkedOfGlobalFilters].onNewPoint?.confirmAddNew.Subs({
|
||||
|
|
@ -317,7 +314,7 @@
|
|||
abort()
|
||||
}}
|
||||
>
|
||||
<img slot="image" src="./assets/svg/close.svg" class="h-8 w-8" />
|
||||
<Close slot="image" class="h-8 w-8" />
|
||||
<Tr slot="message" t={Translations.t.general.cancel} />
|
||||
</SubtleButton>
|
||||
{:else if !creating}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
import NewPointLocationInput from "../BigComponents/NewPointLocationInput.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import Layers from "../../assets/svg/Layers.svelte";
|
||||
import AddSmall from "../../assets/svg/AddSmall.svelte";
|
||||
|
||||
export let coordinate: UIEventSource<{ lon: number; lat: number }>
|
||||
export let state: SpecialVisualizationState
|
||||
|
|
@ -97,7 +99,7 @@
|
|||
<Tr t={Translations.t.notes.noteLayerHasFilters} />
|
||||
</div>
|
||||
<SubtleButton on:click={() => notelayer.disableAllFilters()}>
|
||||
<img slot="image" src="./assets/svg/filter.svg" class="mr-4 h-8 w-8" />
|
||||
<Layers class="mr-4 h-8 w-8"/>
|
||||
<Tr slot="message" t={Translations.t.notes.disableAllNoteFilters} />
|
||||
</SubtleButton>
|
||||
</div>
|
||||
|
|
@ -126,7 +128,7 @@
|
|||
|
||||
{#if $comment?.length >= 3}
|
||||
<SubtleButton on:click={uploadNote}>
|
||||
<img slot="image" src="./assets/svg/addSmall.svg" class="mr-4 h-8 w-8" />
|
||||
<AddSmall slot="image" class="mr-4 h-8 w-8" />
|
||||
<Tr slot="message" t={Translations.t.notes.createNote} />
|
||||
</SubtleButton>
|
||||
{:else}
|
||||
|
|
@ -143,7 +145,7 @@
|
|||
<Tr t={Translations.t.notes.noteLayerNotEnabled} />
|
||||
</div>
|
||||
<SubtleButton on:click={enableNoteLayer}>
|
||||
<img slot="image" src="./assets/svg/layers.svg" class="mr-4 h-8 w-8" />
|
||||
<Layers slot="image" class="mr-4 h-8 w-8" />
|
||||
<Tr slot="message" t={Translations.t.notes.noteLayerDoEnable} />
|
||||
</SubtleButton>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { XCircleIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import exp from "constants"
|
||||
import Camera_plus from "../../assets/svg/Camera_plus.svelte";
|
||||
|
||||
export let tags: Store<OsmTags>
|
||||
export let state: SpecialVisualizationState
|
||||
|
|
@ -42,7 +43,7 @@
|
|||
expanded = true
|
||||
}}
|
||||
>
|
||||
<ToSvelte construct={Svg.camera_plus_svg().SetClass("block w-8 h-8 p-1 mr-2 ")} />
|
||||
<Camera_plus class="block w-8 h-8 p-1 mr-2"/>
|
||||
<Tr t={t.seeNearby} />
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
import UserRelatedState from "../../../Logic/State/UserRelatedState"
|
||||
import { twJoin } from "tailwind-merge"
|
||||
import { TagUtils } from "../../../Logic/Tags/TagUtils"
|
||||
import Search from "../../../assets/svg/Search.svelte";
|
||||
import Login from "../../../assets/svg/Login.svelte";
|
||||
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
|
|
@ -217,7 +219,7 @@
|
|||
|
||||
{#if config.mappings?.length >= 8}
|
||||
<div class="sticky flex w-full">
|
||||
<img src="./assets/svg/search.svg" class="h-6 w-6" />
|
||||
<Search class="h-6 w-6"/>
|
||||
<input type="text" bind:value={$searchTerm} class="w-full" />
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -324,7 +326,7 @@
|
|||
<LoginToggle {state}>
|
||||
<Loading slot="loading" />
|
||||
<SubtleButton slot="not-logged-in" on:click={() => state?.osmConnection?.AttemptLogin()}>
|
||||
<img slot="image" src="./assets/svg/login.svg" class="h-8 w-8" />
|
||||
<Login slot="image" class="h-8 w-8" />
|
||||
<Tr t={Translations.t.general.loginToStart} slot="message" />
|
||||
</SubtleButton>
|
||||
{#if $feedback !== undefined}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Svg from "../../Svg"
|
||||
import Mangrove_logo from "../../assets/svg/Mangrove_logo.svelte";
|
||||
|
||||
/**
|
||||
* An element showing all reviews
|
||||
|
|
@ -40,7 +41,7 @@
|
|||
<Tr t={Translations.t.reviews.no_reviews_yet} />
|
||||
{/if}
|
||||
<div class="flex justify-end">
|
||||
<ToSvelte construct={Svg.mangrove_logo_svg().SetClass("w-12 h-12 shrink-0 p-1 ")} />
|
||||
<Mangrove_logo class="w-12 h-12 shrink-0 p-1"/>
|
||||
<Tr cls="text-sm subtle" t={Translations.t.reviews.attribution} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ import { PointImportButtonViz } from "./Popup/ImportButtons/PointImportButtonViz
|
|||
import WayImportButtonViz from "./Popup/ImportButtons/WayImportButtonViz"
|
||||
import ConflateImportButtonViz from "./Popup/ImportButtons/ConflateImportButtonViz"
|
||||
import DeleteWizard from "./Popup/DeleteFlow/DeleteWizard.svelte"
|
||||
import { OpenJosm } from "./BigComponents/OpenJosm"
|
||||
import OpenIdEditor from "./BigComponents/OpenIdEditor.svelte"
|
||||
import FediverseValidator from "./InputElement/Validators/FediverseValidator"
|
||||
import SendEmail from "./Popup/SendEmail.svelte"
|
||||
|
|
@ -78,6 +77,8 @@ import { TagUtils } from "../Logic/Tags/TagUtils"
|
|||
import Giggity from "./BigComponents/Giggity.svelte"
|
||||
import ThemeViewState from "../Models/ThemeViewState"
|
||||
import LanguagePicker from "./InputElement/LanguagePicker.svelte"
|
||||
import LogoutButton from "./Base/LogoutButton.svelte"
|
||||
import OpenJosm from "./Base/OpenJosm.svelte"
|
||||
|
||||
class NearbyImageVis implements SpecialVisualization {
|
||||
// Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
|
||||
|
|
@ -465,11 +466,7 @@ export default class SpecialVisualizations {
|
|||
needsUrls: [Constants.osmAuthConfig.url],
|
||||
docs: "Shows a button where the user can log out",
|
||||
constr(state: SpecialVisualizationState): BaseUIElement {
|
||||
return new SubtleButton(Svg.logout_svg(), Translations.t.general.logout, {
|
||||
imgSize: "w-6 h-6",
|
||||
}).onClick(() => {
|
||||
state.osmConnection.LogOut()
|
||||
})
|
||||
return new SvelteUIElement(LogoutButton, { osmConnection: state.osmConnection })
|
||||
},
|
||||
},
|
||||
new HistogramViz(),
|
||||
|
|
@ -903,10 +900,10 @@ export default class SpecialVisualizations {
|
|||
funcName: "open_in_josm",
|
||||
docs: "Opens the current view in the JOSM-editor",
|
||||
args: [],
|
||||
needsUrls: OpenJosm.needsUrls,
|
||||
needsUrls: ["http://127.0.0.1:8111/load_and_zoom"],
|
||||
|
||||
constr: (state) => {
|
||||
return new OpenJosm(state.osmConnection, state.mapProperties.bounds)
|
||||
return new SvelteUIElement(OpenJosm, { state })
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -1099,12 +1096,6 @@ export default class SpecialVisualizations {
|
|||
if (maproulette_id_key === "" || maproulette_id_key === undefined) {
|
||||
maproulette_id_key = "mr_taskId"
|
||||
}
|
||||
if (Svg.All[image] !== undefined || Svg.All[image + ".svg"] !== undefined) {
|
||||
if (image.endsWith(".svg")) {
|
||||
image = image.substring(0, image.length - 4)
|
||||
}
|
||||
image = Svg[image + "_svg"]()
|
||||
}
|
||||
const failed = new UIEventSource(false)
|
||||
|
||||
const closeButton = new SubtleButton(image, message).OnClickWithLoading(
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
import { Utils } from "../Utils";
|
||||
import Translations from "./i18n/Translations";
|
||||
import Tr from "./Base/Tr.svelte";
|
||||
import Add from "../assets/svg/Add.svelte";
|
||||
|
||||
export let studioUrl =
|
||||
window.location.hostname === "127.0.0.2"
|
||||
|
|
@ -197,7 +198,7 @@
|
|||
Show the introduction again
|
||||
</button>
|
||||
<a class="flex button" href={Utils.HomepageLink()}>
|
||||
<img class="h-6 w-6" src="./assets/svg/add.svg" />
|
||||
<Add class="h-6 w-6" />
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -43,18 +43,25 @@
|
|||
import RasterLayerOverview from "./Map/RasterLayerOverview.svelte";
|
||||
import IfHidden from "./Base/IfHidden.svelte";
|
||||
import { onDestroy } from "svelte";
|
||||
import { OpenJosm } from "./BigComponents/OpenJosm";
|
||||
import MapillaryLink from "./BigComponents/MapillaryLink.svelte";
|
||||
import OpenIdEditor from "./BigComponents/OpenIdEditor.svelte";
|
||||
import OpenBackgroundSelectorButton from "./BigComponents/OpenBackgroundSelectorButton.svelte";
|
||||
import StateIndicator from "./BigComponents/StateIndicator.svelte";
|
||||
import Locale from "./i18n/Locale";
|
||||
import ShareScreen from "./BigComponents/ShareScreen.svelte";
|
||||
import UploadingImageCounter from "./Image/UploadingImageCounter.svelte";
|
||||
import PendingChangesIndicator from "./BigComponents/PendingChangesIndicator.svelte";
|
||||
import Cross from "../assets/svg/Cross.svelte";
|
||||
import Summary from "./BigComponents/Summary.svelte";
|
||||
import LanguagePicker from "./InputElement/LanguagePicker.svelte";
|
||||
import Mastodon from "../assets/svg/Mastodon.svelte";
|
||||
import Bug from "../assets/svg/Bug.svelte";
|
||||
import Liberapay from "../assets/svg/Liberapay.svelte";
|
||||
import OpenJosm from "./Base/OpenJosm.svelte";
|
||||
import Min from "../assets/svg/Min.svelte";
|
||||
import Plus from "../assets/svg/Plus.svelte";
|
||||
import Filter from "../assets/svg/Filter.svelte";
|
||||
import Add from "../assets/svg/Add.svelte";
|
||||
import Statistics from "../assets/svg/Statistics.svelte";
|
||||
|
||||
export let state: ThemeViewState;
|
||||
let layout = state.layout;
|
||||
|
|
@ -205,7 +212,7 @@
|
|||
<!-- bottom left elements -->
|
||||
<If condition={state.featureSwitches.featureSwitchFilter}>
|
||||
<MapControlButton on:click={() => state.guistate.openFilterView()}>
|
||||
<ToSvelte construct={Svg.filter_svg().SetClass("h-6 w-6")} />
|
||||
<Filter class="h-6 w-6"/>
|
||||
</MapControlButton>
|
||||
</If>
|
||||
<If condition={state.featureSwitches.featureSwitchBackgroundSelection}>
|
||||
|
|
@ -244,10 +251,10 @@
|
|||
</div>
|
||||
</If>
|
||||
<MapControlButton on:click={() => mapproperties.zoom.update((z) => z + 1)}>
|
||||
<ToSvelte construct={Svg.plus_svg().SetClass("w-8 h-8")} />
|
||||
<Plus class="w-8 h-8" />
|
||||
</MapControlButton>
|
||||
<MapControlButton on:click={() => mapproperties.zoom.update((z) => z - 1)}>
|
||||
<ToSvelte construct={Svg.min_svg().SetClass("w-8 h-8")} />
|
||||
<Min class="w-8 h-8"/>
|
||||
</MapControlButton>
|
||||
<If condition={featureSwitches.featureSwitchGeolocation}>
|
||||
<MapControlButton>
|
||||
|
|
@ -340,7 +347,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex" slot="title1">
|
||||
<ToSvelte construct={Svg.filter_svg().SetClass("w-4 h-4")} />
|
||||
<Filter class="w-4 h-4"/>
|
||||
<Tr t={Translations.t.general.menu.filter} />
|
||||
</div>
|
||||
|
||||
|
|
@ -431,27 +438,27 @@
|
|||
<Tr t={Translations.t.general.aboutMapComplete.intro} />
|
||||
|
||||
<a class="flex" href={Utils.HomepageLink()}>
|
||||
<img class="h-6 w-6" src="./assets/svg/add.svg" />
|
||||
<Add class="h-6 w-6"/>
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/bug.svg" />
|
||||
<Bug class="h-6 w-6"/>
|
||||
<Tr t={Translations.t.general.attribution.openIssueTracker} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/mastodon.svg" />
|
||||
<Mastodon class="w-6 h-6" />
|
||||
<Tr t={Translations.t.general.attribution.followOnMastodon} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/liberapay.svg" />
|
||||
<Liberapay class="h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.donate} />
|
||||
</a>
|
||||
|
||||
<a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/statistics.svg" />
|
||||
<Statistics class="h-6 w-6" />
|
||||
<Tr t={Translations.t.general.attribution.openOsmcha.Subs({ theme: "MapComplete" })} />
|
||||
</a>
|
||||
{Constants.vNumber}
|
||||
|
|
@ -503,10 +510,7 @@
|
|||
<div class="m-2 flex flex-col" slot="content4">
|
||||
<If condition={featureSwitches.featureSwitchEnableLogin}>
|
||||
<OpenIdEditor mapProperties={state.mapProperties} />
|
||||
<ToSvelte
|
||||
construct={() =>
|
||||
new OpenJosm(state.osmConnection, state.mapProperties.bounds).SetClass("w-full")}
|
||||
/>
|
||||
<OpenJosm {state}/>
|
||||
<MapillaryLink mapProperties={state.mapProperties} />
|
||||
</If>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import WikidataPreviewBox from "./WikidataPreviewBox"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Wikipedia from "../../assets/svg/Wikipedia.svelte";
|
||||
|
||||
/**
|
||||
* Shows a wikipedia-article + wikidata preview for the given item
|
||||
|
|
@ -18,7 +19,7 @@
|
|||
|
||||
{#if $wikipediaDetails.articleUrl}
|
||||
<a class="flex" href={$wikipediaDetails.articleUrl} rel="noreferrer" target="_blank">
|
||||
<img class="h-6 w-6" src="./assets/svg/wikipedia.svg" />
|
||||
<Wikipedia class="h-6 w-6"/>
|
||||
<Tr t={Translations.t.general.wikipedia.fromWikipedia} />
|
||||
</a>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue