forked from MapComplete/MapComplete
Merge develop
This commit is contained in:
commit
bcd53405c8
197 changed files with 5675 additions and 5188 deletions
|
@ -27,6 +27,7 @@
|
|||
import Github from "../assets/svg/Github.svelte"
|
||||
import { Utils } from "../Utils"
|
||||
import { ArrowTrendingUp } from "@babeard/svelte-heroicons/solid/ArrowTrendingUp"
|
||||
import Searchbar from "./Base/Searchbar.svelte"
|
||||
|
||||
const featureSwitches = new OsmConnectionFeatureSwitches()
|
||||
const osmConnection = new OsmConnection({
|
||||
|
@ -42,7 +43,7 @@
|
|||
const tr = Translations.t.general.morescreen
|
||||
|
||||
let userLanguages = osmConnection.userDetails.map((ud) => ud.languages)
|
||||
let themeSearchText: UIEventSource<string | undefined> = new UIEventSource<string>(undefined)
|
||||
let themeSearchText: UIEventSource<string | undefined> = new UIEventSource<string>("")
|
||||
|
||||
document.addEventListener("keydown", function(event) {
|
||||
if (event.ctrlKey && event.code === "KeyF") {
|
||||
|
@ -91,24 +92,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<form
|
||||
class="flex justify-center"
|
||||
on:submit|preventDefault={() => MoreScreen.applySearch(themeSearchText.data)}
|
||||
>
|
||||
<label
|
||||
class="neutral-label my-2 flex w-full items-center rounded-full border-2 border-black sm:w-1/2"
|
||||
>
|
||||
<SearchIcon aria-hidden="true" class="h-8 w-8" />
|
||||
<input
|
||||
autofocus
|
||||
bind:value={$themeSearchText}
|
||||
class="mr-4 w-full outline-none"
|
||||
id="theme-search"
|
||||
type="search"
|
||||
use:placeholder={tr.searchForATheme}
|
||||
/>
|
||||
</label>
|
||||
</form>
|
||||
<Searchbar value={themeSearchText} placeholder={tr.searchForATheme} on:search={() => MoreScreen.applySearch(themeSearchText.data)}/>
|
||||
|
||||
<ThemesList search={themeSearchText} {state} themes={MoreScreen.officialThemes} />
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { XCircleIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import { CloseButton } from "flowbite-svelte"
|
||||
|
||||
/**
|
||||
* The slotted element will be shown on top, with a lower-opacity border
|
||||
|
@ -29,7 +30,7 @@
|
|||
}}
|
||||
>
|
||||
<div
|
||||
class="content normal-background pointer-events-auto h-full"
|
||||
class="content relative normal-background pointer-events-auto h-full"
|
||||
on:click|stopPropagation={() => {}}
|
||||
>
|
||||
<div class="h-full rounded-xl">
|
||||
|
@ -37,22 +38,21 @@
|
|||
</div>
|
||||
<slot name="close-button">
|
||||
<!-- The close button is placed _after_ the default slot in order to always paint it on top -->
|
||||
<div
|
||||
class="absolute right-10 top-10 m-0 cursor-pointer rounded-full border-0 border-none bg-white p-0"
|
||||
style="margin: -0.25rem"
|
||||
on:click={() => dispatch("close")}
|
||||
use:ariaLabel={Translations.t.general.backToMap}
|
||||
>
|
||||
<XCircleIcon class="h-8 w-8" />
|
||||
<div class="absolute top-0 right-0">
|
||||
|
||||
<CloseButton class="normal-background mt-2 mr-2"
|
||||
on:click={() => dispatch("close")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 0 0 1rem #00000088;
|
||||
}
|
||||
.content {
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
box-shadow: 0 0 1rem #00000088;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
size="xl"
|
||||
{defaultClass} {bodyClass} {dialogClass} {headerClass}
|
||||
color="none">
|
||||
<h1 slot="header" class="w-full">
|
||||
<h1 slot="header" class="page-header w-full">
|
||||
<slot name="header" />
|
||||
</h1>
|
||||
<slot />
|
||||
|
@ -44,3 +44,16 @@
|
|||
</slot>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
:global(.page-header) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:global(.page-header svg) {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
</style>
|
||||
|
|
43
src/UI/Base/Searchbar.svelte
Normal file
43
src/UI/Base/Searchbar.svelte
Normal file
|
@ -0,0 +1,43 @@
|
|||
<script lang="ts">
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { placeholder as set_placeholder } from "../../Utils/placeholder"
|
||||
import { SearchIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
|
||||
export let value: UIEventSource<string>
|
||||
let _value = value.data ?? ""
|
||||
value.addCallbackD(v => {
|
||||
_value = v
|
||||
})
|
||||
$: value.set(_value)
|
||||
|
||||
const dispatch = createEventDispatcher<{ search }>()
|
||||
export let placeholder: Translation = Translations.t.general.search.search
|
||||
</script>
|
||||
|
||||
|
||||
<form
|
||||
class="flex justify-center"
|
||||
on:submit|preventDefault={() => dispatch("search")}
|
||||
>
|
||||
<label
|
||||
class="neutral-label my-2 flex w-full items-center rounded-full border-2 border-black sm:w-1/2 box-shadow"
|
||||
>
|
||||
<input
|
||||
type="search"
|
||||
style=" --tw-ring-color: rgb(0 0 0 / 0) !important;"
|
||||
class="ml-4 pl-1 w-full outline-none border-none"
|
||||
on:keypress={(keypr) => {
|
||||
return keypr.key === "Enter" ? dispatch("search") : undefined
|
||||
}}
|
||||
bind:value={_value}
|
||||
use:set_placeholder={placeholder}
|
||||
use:ariaLabel={Translations.t.general.search.search}
|
||||
/>
|
||||
<SearchIcon aria-hidden="true" class="h-8 w-8 mx-2" />
|
||||
|
||||
</label>
|
||||
</form>
|
|
@ -11,7 +11,7 @@
|
|||
import CommunityIndexView from "./CommunityIndexView.svelte"
|
||||
import Community from "../../assets/svg/Community.svelte"
|
||||
import LoginToggle from "../Base/LoginToggle.svelte"
|
||||
import { Sidebar } from "flowbite-svelte"
|
||||
import { CloseButton, Sidebar } from "flowbite-svelte"
|
||||
import HotkeyTable from "./HotkeyTable.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import Constants from "../../Models/Constants"
|
||||
|
@ -47,6 +47,8 @@
|
|||
import LogoutButton from "../Base/LogoutButton.svelte"
|
||||
import { BoltIcon } from "@babeard/svelte-heroicons/mini"
|
||||
import Copyright from "../../assets/svg/Copyright.svelte"
|
||||
import Pencil from "../../assets/svg/Pencil.svelte"
|
||||
import Squares2x2 from "@babeard/svelte-heroicons/mini/Squares2x2"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let userdetails = state.osmConnection.userDetails
|
||||
|
@ -62,6 +64,23 @@
|
|||
</script>
|
||||
|
||||
<div class="flex flex-col p-2 sm:p-3 low-interaction gap-y-2 sm:gap-y-3 h-screen overflow-y-auto">
|
||||
<div class="flex justify-between">
|
||||
<h2>
|
||||
<Tr t={t.title}/>
|
||||
</h2>
|
||||
<CloseButton on:click={() => {pg.menu.set(false)}} />
|
||||
</div>
|
||||
{#if $showHome}
|
||||
<a class="flex button primary" href={Utils.HomepageLink()}>
|
||||
<Squares2x2 class="h-10 w-10" />
|
||||
{#if Utils.isIframe}
|
||||
<Tr t={Translations.t.general.seeIndex} />
|
||||
{:else}
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
|
||||
<!-- User related: avatar, settings, favourits, logout -->
|
||||
<div class="sidebar-unit">
|
||||
|
@ -77,10 +96,10 @@
|
|||
|
||||
|
||||
<Page {onlyLink} shown={pg.usersettings}>
|
||||
<div class="flex" slot="header">
|
||||
<CogIcon class="h-6 w-6" />
|
||||
<svelte:fragment slot="header">
|
||||
<CogIcon/>
|
||||
<Tr t={UserRelatedState.usersettingsConfig.title.GetRenderValue({})} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<!-- All shown components are set by 'usersettings.json', which happily uses some special visualisations created specifically for it -->
|
||||
<LoginToggle {state}>
|
||||
|
@ -109,10 +128,12 @@
|
|||
<LoginToggle {state}>
|
||||
<Page {onlyLink} shown={pg.favourites}>
|
||||
|
||||
<div class="flex" slot="header">
|
||||
<HeartIcon class="h-6 w-6" />
|
||||
<svelte:fragment slot="header">
|
||||
<HeartIcon />
|
||||
<Tr t={Translations.t.favouritePoi.tab} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
|
||||
<h3>
|
||||
|
||||
<Tr t={Translations.t.favouritePoi.title} />
|
||||
|
@ -146,10 +167,10 @@
|
|||
<Marker icons={layout.icon} size="h-6 w-6 mr-2" />
|
||||
<Tr t={t.showIntroduction} />
|
||||
</div>
|
||||
<div class="flex" slot="header">
|
||||
<Marker icons={layout.icon} size="h-8 w-8 mr-4" />
|
||||
<svelte:fragment slot="header">
|
||||
<Marker icons={layout.icon} />
|
||||
<Tr t={layout.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<ThemeIntroPanel {state} />
|
||||
</Page>
|
||||
|
||||
|
@ -158,20 +179,20 @@
|
|||
<RasterLayerOverview {onlyLink} {state} />
|
||||
|
||||
<Page {onlyLink} shown={pg.share}>
|
||||
<div class="flex" slot="header">
|
||||
<Share class="h-4 w-4" />
|
||||
<svelte:fragment slot="header">
|
||||
<Share/>
|
||||
<Tr t={Translations.t.general.sharescreen.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<ShareScreen {state} />
|
||||
</Page>
|
||||
|
||||
|
||||
{#if state.featureSwitches.featureSwitchEnableExport}
|
||||
<Page {onlyLink} shown={pg.download}>
|
||||
<div slot="header" class="flex">
|
||||
<ArrowDownTray class="h-4 w-4" />
|
||||
<svelte:fragment slot="header">
|
||||
<ArrowDownTray />
|
||||
<Tr t={Translations.t.general.download.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<DownloadPanel {state} />
|
||||
</Page>
|
||||
{/if}
|
||||
|
@ -206,22 +227,13 @@
|
|||
<h3>
|
||||
<Tr t={t.moreUtilsTitle} />
|
||||
</h3>
|
||||
{#if $showHome}
|
||||
<a class="flex" href={Utils.HomepageLink()}>
|
||||
<Add class="h-6 w-6" />
|
||||
{#if Utils.isIframe}
|
||||
<Tr t={Translations.t.general.seeIndex} />
|
||||
{:else}
|
||||
<Tr t={Translations.t.general.backToIndex} />
|
||||
{/if}
|
||||
</a>
|
||||
{/if}
|
||||
|
||||
|
||||
<Page {onlyLink} shown={pg.community_index}>
|
||||
<div class="flex" slot="header">
|
||||
<Community class="h-6 w-6" />
|
||||
<svelte:fragment slot="header">
|
||||
<Community/>
|
||||
<Tr t={Translations.t.communityIndex.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<CommunityIndexView location={state.mapProperties.location} />
|
||||
</Page>
|
||||
|
||||
|
@ -242,13 +254,20 @@
|
|||
<Tr t={Translations.t.general.menu.aboutMapComplete} />
|
||||
</h3>
|
||||
|
||||
<div class="hidden-on-mobile">
|
||||
<a
|
||||
class="flex"
|
||||
href={window.location.protocol + "//" + window.location.host + "/studio.html"}
|
||||
>
|
||||
<Pencil class="mr-2 h-6 w-6" />
|
||||
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
|
||||
</a>
|
||||
|
||||
<div class="hidden-on-mobile w-full">
|
||||
<Page {onlyLink} shown={pg.hotkeys}>
|
||||
<div class="flex" slot="header">
|
||||
<BoltIcon class="w-6 h-6" />
|
||||
<svelte:fragment slot="header">
|
||||
<BoltIcon />
|
||||
<Tr t={ Translations.t.hotkeyDocumentation.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<HotkeyTable />
|
||||
</Page>
|
||||
</div>
|
||||
|
@ -276,29 +295,29 @@
|
|||
|
||||
|
||||
<Page {onlyLink} shown={pg.copyright}>
|
||||
<div slot="header" class="flex">
|
||||
<Copyright class="w-8 h-8" />
|
||||
<svelte:fragment slot="header">
|
||||
<Copyright />
|
||||
<Tr t={Translations.t.general.attribution.attributionTitle} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<CopyrightPanel {state} />
|
||||
</Page>
|
||||
|
||||
|
||||
<Page {onlyLink} shown={pg.copyright_icons}>
|
||||
<div slot="header" class="flex">
|
||||
<Copyright class="w-8 h-8" />
|
||||
<svelte:fragment slot="header" >
|
||||
<Copyright/>
|
||||
<Tr t={ Translations.t.general.attribution.iconAttribution.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<CopyrightAllIcons {state} />
|
||||
|
||||
</Page>
|
||||
|
||||
|
||||
<Page {onlyLink} shown={pg.privacy}>
|
||||
<div class="flex" slot="header">
|
||||
<EyeIcon class="w-8 h-8" />
|
||||
<svelte:fragment slot="header">
|
||||
<EyeIcon />
|
||||
<Tr t={Translations.t.privacy.title} />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<PrivacyPolicy {state} />
|
||||
</Page>
|
||||
|
||||
|
@ -340,12 +359,14 @@
|
|||
}
|
||||
|
||||
|
||||
:global(.sidebar-button, .sidebar-button, .sidebar-unit > a) {
|
||||
:global(.sidebar-button, .sidebar-unit > a) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.25rem !important;
|
||||
padding: 0.4rem 0.75rem !important;
|
||||
text-decoration: none !important;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
:global(.sidebar-button > svg , .sidebar-button > img, .sidebar-unit a > img, .sidebar-unit > a svg) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import Tr from "../Base/Tr.svelte"
|
||||
import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import { CloseButton } from "flowbite-svelte"
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
export let layer: LayerConfig
|
||||
|
@ -72,14 +73,10 @@
|
|||
{/if}
|
||||
</div>
|
||||
<slot name="close-button">
|
||||
<button
|
||||
class="mt-2 h-fit shrink-0 cursor-pointer self-center rounded-full border-none p-0"
|
||||
on:click={() => state.selectedElement.setData(undefined)}
|
||||
style="border: 0 !important; padding: 0 !important;"
|
||||
use:ariaLabel={Translations.t.general.backToMap}
|
||||
>
|
||||
<XCircleIcon aria-hidden={true} class="h-8 w-8" />
|
||||
</button>
|
||||
<div class="mt-4">
|
||||
<CloseButton on:click={() => state.selectedElement.setData(undefined)}/>
|
||||
</div>
|
||||
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
let enableBackground = true
|
||||
let enableGeolocation = true
|
||||
|
||||
let location = state.mapProperties.location
|
||||
|
||||
function calculateLinkToShare(
|
||||
showWelcomeMessage: boolean,
|
||||
enableLogin: boolean,
|
||||
|
@ -116,10 +118,12 @@
|
|||
)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col link-underline">
|
||||
|
||||
<a href="geo:{$location.lat},{$location.lon}">Open the current location in other applications</a>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<Tr t={tr.intro} />
|
||||
|
||||
<Copyable {state} text={linkToShare} />
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
state.mapProperties.location.setData({ lon, lat })
|
||||
const z = state.mapProperties.zoom.data
|
||||
state.mapProperties.zoom.setData(Math.min(17, Math.max(12, z)))
|
||||
state.guistate.menuIsOpened.setData(false)
|
||||
state.guistate.pageStates.menu.setData(false)
|
||||
}
|
||||
|
||||
function select() {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
/>
|
||||
|
||||
{#if canZoom && loaded}
|
||||
<div class="absolute right-0 top-0 bg-black-transparent rounded-bl-full">
|
||||
<div class="absolute right-0 top-0 bg-black-transparent rounded-bl-full" on:click={() => previewedImage.set(image)}>
|
||||
<MagnifyingGlassPlusIcon class="w-8 h-8 pl-3 pb-3 cursor-zoom-in" color="white" />
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
import { twMerge } from "tailwind-merge"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
export let image: ProvidedImage
|
||||
export let clss: string = undefined
|
||||
|
@ -48,7 +50,7 @@
|
|||
on:click={() => download()}
|
||||
>
|
||||
<DownloadIcon class="h-6 w-6 px-2 opacity-100" />
|
||||
Download
|
||||
<Tr t={Translations.t.general.download.downloadImage}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1996,6 +1996,9 @@ export default class SpecialVisualizations {
|
|||
): BaseUIElement {
|
||||
const translation = tagSource.map((tags) => {
|
||||
const presets = state.layout.getMatchingLayer(tags)?.presets
|
||||
if(!presets){
|
||||
return undefined
|
||||
}
|
||||
const matchingPresets = presets
|
||||
.filter((pr) => pr.description !== undefined)
|
||||
.filter((pr) => new And(pr.tags).matchesProperties(tags))
|
||||
|
|
|
@ -46,10 +46,12 @@
|
|||
import DrawerRight from "./Base/DrawerRight.svelte"
|
||||
import SearchResults from "./Search/SearchResults.svelte"
|
||||
import { CloseButton } from "flowbite-svelte"
|
||||
import Hash from "../Logic/Web/Hash"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let layout = state.layout
|
||||
let maplibremap: UIEventSource<MlMap> = state.map
|
||||
let state_selectedElement = state.selectedElement
|
||||
let selectedElement: UIEventSource<Feature> = new UIEventSource<Feature>(undefined)
|
||||
let compass = Orientation.singleton.alpha
|
||||
let compassLoaded = Orientation.singleton.gotMeasurement
|
||||
|
@ -71,6 +73,7 @@
|
|||
})
|
||||
})
|
||||
|
||||
|
||||
let selectedLayer: Store<LayerConfig> = state.selectedElement.mapD((element) => {
|
||||
if (element.properties.id.startsWith("current_view")) {
|
||||
return currentViewLayer
|
||||
|
@ -85,11 +88,11 @@
|
|||
state.mapProperties.installCustomKeyboardHandler(viewport)
|
||||
let canZoomIn = mapproperties.maxzoom.map(
|
||||
(mz) => mapproperties.zoom.data < mz,
|
||||
[mapproperties.zoom]
|
||||
[mapproperties.zoom],
|
||||
)
|
||||
let canZoomOut = mapproperties.minzoom.map(
|
||||
(mz) => mapproperties.zoom.data > mz,
|
||||
[mapproperties.zoom]
|
||||
[mapproperties.zoom],
|
||||
)
|
||||
|
||||
function updateViewport() {
|
||||
|
@ -105,7 +108,7 @@
|
|||
const bottomRight = mlmap.unproject([rect.right, rect.bottom])
|
||||
const bbox = new BBox([
|
||||
[topLeft.lng, topLeft.lat],
|
||||
[bottomRight.lng, bottomRight.lat]
|
||||
[bottomRight.lng, bottomRight.lat],
|
||||
])
|
||||
state.visualFeedbackViewportBounds.setData(bbox)
|
||||
}
|
||||
|
@ -125,7 +128,7 @@
|
|||
onDestroy(
|
||||
rasterLayer.addCallbackAndRunD((l) => {
|
||||
rasterLayerName = l.properties.name
|
||||
})
|
||||
}),
|
||||
)
|
||||
let previewedImage = state.previewedImage
|
||||
let addNewFeatureMode = state.userRelatedState.addNewFeatureMode
|
||||
|
@ -154,6 +157,7 @@
|
|||
animation?.cameraAnimation(mlmap)
|
||||
}
|
||||
|
||||
let hash = Hash.hash
|
||||
</script>
|
||||
|
||||
<main>
|
||||
|
@ -172,6 +176,110 @@
|
|||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="pointer-events-none absolute top-0 left-0 w-full">
|
||||
<!-- Top components -->
|
||||
|
||||
<div
|
||||
class="flex bg-black-light-transparent pointer-events-auto items-center justify-between px-4 py-1 flex-wrap-reverse">
|
||||
<!-- Top bar with tools -->
|
||||
<div class="flex items-center">
|
||||
|
||||
<MapControlButton
|
||||
cls="m-0.5 p-0.5 sm:p-1"
|
||||
arialabel={Translations.t.general.labels.menu}
|
||||
on:click={() => {console.log("Opening...."); state.guistate.pageStates.menu.setData(true)}}
|
||||
on:keydown={forwardEventToMap}
|
||||
>
|
||||
<MenuIcon class="h-6 w-6 cursor-pointer" />
|
||||
</MapControlButton>
|
||||
|
||||
<MapControlButton
|
||||
on:click={() => state.guistate.pageStates.about_theme.set(true)}
|
||||
on:keydown={forwardEventToMap}
|
||||
>
|
||||
<div
|
||||
class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 mr-2"
|
||||
>
|
||||
<Marker icons={layout.icon} size="h-6 w-6 shrink-0 mr-0.5 sm:mr-1 md:mr-2" />
|
||||
<b class="mr-1">
|
||||
<Tr t={layout.title} />
|
||||
</b>
|
||||
</div>
|
||||
</MapControlButton>
|
||||
</div>
|
||||
|
||||
{#if $debug && $hash}
|
||||
<div class="alert">
|
||||
{$hash}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<If condition={state.featureSwitches.featureSwitchSearch}>
|
||||
<div class="w-full sm:w-64 my-2 sm:mt-0">
|
||||
|
||||
<Geosearch
|
||||
bounds={state.mapProperties.bounds}
|
||||
on:searchCompleted={() => {
|
||||
state.map?.data?.getCanvas()?.focus()
|
||||
}}
|
||||
perLayer={state.perLayer}
|
||||
selectedElement={state.selectedElement}
|
||||
geolocationState={state.geolocation.geolocationState}
|
||||
/>
|
||||
</div>
|
||||
</If>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="pointer-events-auto float-right mt-1 flex flex-col px-1 max-[480px]:w-full sm:m-2">
|
||||
<If condition={state.visualFeedback}>
|
||||
{#if $selectedElement === undefined}
|
||||
<div class="w-fit">
|
||||
<VisualFeedbackPanel {state} />
|
||||
</div>
|
||||
{/if}
|
||||
</If>
|
||||
|
||||
</div>
|
||||
<div class="float-left m-1 flex flex-col sm:mt-2">
|
||||
<If condition={state.featureSwitches.featureSwitchWelcomeMessage}>
|
||||
|
||||
|
||||
</If>
|
||||
{#if currentViewLayer?.tagRenderings && currentViewLayer.defaultIcon()}
|
||||
<MapControlButton
|
||||
on:click={() => {
|
||||
state.selectCurrentView()
|
||||
}}
|
||||
on:keydown={forwardEventToMap}
|
||||
>
|
||||
<div class="h-8 w-8 cursor-pointer">
|
||||
<ToSvelte construct={() => currentViewLayer.defaultIcon()} />
|
||||
</div>
|
||||
</MapControlButton>
|
||||
{/if}
|
||||
<ExtraLinkButton {state} />
|
||||
<UploadingImageCounter featureId="*" showThankYou={false} {state} />
|
||||
<PendingChangesIndicator {state} />
|
||||
<If condition={state.featureSwitchIsTesting}>
|
||||
<div class="alert w-fit">Testmode</div>
|
||||
</If>
|
||||
{#if state.osmConnection.Backend().startsWith("https://master.apis.dev.openstreetmap.org")}
|
||||
<div class="thanks">Testserver</div>
|
||||
{/if}
|
||||
<If condition={state.featureSwitches.featureSwitchFakeUser}>
|
||||
<div class="alert w-fit">Faking a user (Testmode)</div>
|
||||
</If>
|
||||
</div>
|
||||
<div class="flex w-full flex-col items-center justify-center">
|
||||
<!-- Flex and w-full are needed for the positioning -->
|
||||
<!-- Centermessage -->
|
||||
<StateIndicator {state} />
|
||||
<ReverseGeocoding {state} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pointer-events-none absolute bottom-0 left-0 mb-4 w-screen">
|
||||
<!-- bottom controls -->
|
||||
<div class="flex w-full items-end justify-between px-4">
|
||||
|
@ -395,7 +503,7 @@
|
|||
<svelte:fragment slot="error" />
|
||||
</LoginToggle>
|
||||
|
||||
<DrawerLeft shown={state.guistate.menuIsOpened}>
|
||||
<DrawerLeft shown={state.guistate.pageStates.menu}>
|
||||
<div class="h-screen overflow-y-auto">
|
||||
<MenuDrawer onlyLink={true} {state} />
|
||||
</div>
|
||||
|
@ -406,11 +514,11 @@
|
|||
<!-- right modal with the selected element view -->
|
||||
<ModalRight
|
||||
on:close={() => {
|
||||
selectedElement.setData(undefined)
|
||||
state.selectedElement.setData(undefined)
|
||||
}}
|
||||
>
|
||||
<div slot="close-button" />
|
||||
<SelectedElementPanel {state} selected={$selectedElement} />
|
||||
<SelectedElementPanel {state} selected={$state_selectedElement} />
|
||||
</ModalRight>
|
||||
{/if}
|
||||
|
||||
|
@ -424,7 +532,7 @@
|
|||
}}
|
||||
>
|
||||
<span slot="close-button" />
|
||||
<SelectedElementPanel absolute={false} {state} selected={$selectedElement} />
|
||||
<SelectedElementPanel absolute={false} {state} selected={$state_selectedElement} />
|
||||
</FloatOver>
|
||||
{:else}
|
||||
<FloatOver
|
||||
|
@ -432,7 +540,7 @@
|
|||
state.selectedElement.setData(undefined)
|
||||
}}
|
||||
>
|
||||
<SelectedElementView {state} layer={$selectedLayer} selectedElement={$selectedElement} />
|
||||
<SelectedElementView {state} layer={$selectedLayer} selectedElement={$state_selectedElement} />
|
||||
</FloatOver>
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue