MapComplete/src/UI/BigComponents/ShareScreen.svelte

183 lines
5.6 KiB
Svelte
Raw Normal View History

2023-09-16 18:52:42 +02:00
<script lang="ts">
/**
* A screen showing:
* - A link to share the current view
* - Some query parameters that can be enabled/disabled
* - The code to embed MC as IFrame
*/
import ThemeViewState from "../../Models/ThemeViewState"
import { QueryParameters } from "../../Logic/Web/QueryParameters"
import Tr from "../Base/Tr.svelte"
import Translations from "../i18n/Translations"
import { Utils } from "../../Utils"
import { DocumentDuplicateIcon } from "@rgossiaux/svelte-heroicons/outline"
import ToSvelte from "../Base/ToSvelte.svelte"
import Img from "../Base/Img"
import Qr from "../../Utils/Qr"
import AccordionSingle from "../Flowbite/AccordionSingle.svelte"
2024-06-16 19:00:43 +02:00
import Share from "@babeard/svelte-heroicons/solid/Share"
import Constants from "../../Models/Constants"
import Copyable from "../Base/Copyable.svelte"
2023-09-16 18:52:42 +02:00
export let state: ThemeViewState
const tr = Translations.t.general.sharescreen
let url = window.location
let linkToShare: string = undefined
/**
* In some cases (local deploys, custom themes), we need to set the URL to `/theme.html?layout=xyz` instead of `/xyz?...`
* Note that the 'layout='-param will be included automatically
2023-09-16 18:52:42 +02:00
*/
let needsThemeRedirect = url.port !== "" || url.hostname.match(/^[0-9]/) || !state.layout.official
let layoutId = state.layout.id
2024-07-09 13:42:08 +02:00
let baseLink = `${url.protocol}//${url.host}/${needsThemeRedirect ? "theme.html" : layoutId}?`
2023-09-16 18:52:42 +02:00
let showWelcomeMessage = true
let enableLogin = true
let enableFilters = true
let enableBackground = true
let enableGeolocation = true
function calculateLinkToShare(
showWelcomeMessage: boolean,
enableLogin: boolean,
enableFilters: boolean,
enableBackground: boolean,
2024-07-09 13:42:08 +02:00
enableGeolocation: boolean
) {
2023-09-16 18:52:42 +02:00
const layout = state.layout
let excluded = Utils.NoNull([
showWelcomeMessage ? undefined : "fs-welcome-message",
enableLogin ? undefined : "fs-enable-login",
enableFilters ? undefined : "fs-filter",
enableBackground ? undefined : "fs-background",
enableGeolocation ? undefined : "fs-geolocation",
2023-09-16 18:52:42 +02:00
])
const layerParamsWhitelist: string[] = ["fs-layers-enabled=false"]
const layerParamsBlacklist: string[] = []
for (const flayer of state.layerState.filteredLayers.values()) {
const id = flayer.layerDef.id
if (flayer.layerDef.filterIsSameAs) {
continue
}
if (id.indexOf("note_import") >= 0) {
continue
}
if (Constants.added_by_default.indexOf(<any>id) >= 0) {
continue
}
const enabled = flayer.isDisplayed.data
if (enabled) {
layerParamsWhitelist.push("layer-" + id + "=true")
} else {
layerParamsBlacklist.push("layer-" + id + "=false")
}
}
const layersBlack = layerParamsBlacklist.join("&")
const layersWhite = layerParamsWhitelist.join("&")
2024-07-09 13:42:08 +02:00
const layers =
layersBlack.length < layersWhite.length ? layerParamsBlacklist : layerParamsWhitelist
const params = QueryParameters.GetParts(new Set(excluded))
2024-07-09 13:42:08 +02:00
.filter((part) => !part.startsWith("layer-"))
.concat(...layers)
.concat(excluded.map((k) => k + "=" + false))
linkToShare = baseLink + Utils.Dedup(params).join("&")
2023-09-16 18:52:42 +02:00
if (layout.definitionRaw !== undefined) {
linkToShare += "&userlayout=" + (layout.definedAtUrl ?? layout.id)
}
}
2024-07-09 13:42:08 +02:00
$: calculateLinkToShare(
showWelcomeMessage,
enableLogin,
enableFilters,
enableBackground,
enableGeolocation
)
let iframeCode: string
$: iframeCode = `<iframe src="${linkToShare}"
2024-07-09 13:42:08 +02:00
${
enableGeolocation ? 'allow="geolocation"' : ""
} width="100%" height="100%" style="min-width: 250px; min-height: 250px"
title="${state.layout.title?.txt ?? "MapComplete"} with MapComplete">
</iframe>`
2024-07-09 13:42:08 +02:00
Array.from(state.layerState.filteredLayers.values()).forEach((flayer) =>
flayer.isDisplayed.addCallbackAndRunD((_) => {
calculateLinkToShare(
showWelcomeMessage,
enableLogin,
enableFilters,
enableBackground,
enableGeolocation
)
})
)
</script>
<div class="flex flex-col">
<div class="flex flex-col">
<Tr t={tr.intro} />
2024-07-09 13:42:08 +02:00
<Copyable {state} text={linkToShare} />
</div>
<div class="flex justify-center">
2024-04-13 02:40:21 +02:00
<ToSvelte
construct={() => new Img(new Qr(linkToShare).toImageElement(125)).SetStyle("width: 125px")}
/>
</div>
2023-09-16 18:52:42 +02:00
<Tr t={tr.embedIntro} />
2024-07-09 13:42:08 +02:00
<Copyable text={iframeCode} />
<AccordionSingle>
<div slot="header">
2024-07-09 13:42:08 +02:00
<Tr t={tr.options} />
</div>
<div class="link-underline my-1 flex flex-col">
<label>
<input bind:checked={showWelcomeMessage} type="checkbox" id="share_show_welcome" />
<Tr t={tr.fsWelcomeMessage} />
</label>
<label>
2024-04-13 02:40:21 +02:00
<input bind:checked={enableLogin} type="checkbox" id="share_enable_login" />
<Tr t={tr.fsUserbadge} />
</label>
<label>
<input bind:checked={enableFilters} type="checkbox" id="share_enable_filter" />
<Tr t={tr.fsFilter} />
</label>
<label>
<input bind:checked={enableBackground} type="checkbox" id="share_enable_background" />
<Tr t={tr.fsBackground} />
</label>
<label>
<input bind:checked={enableGeolocation} type="checkbox" id="share_enable_geolocation" />
<Tr t={tr.fsGeolocation} />
</label>
<span>
2024-07-09 13:42:08 +02:00
<Tr t={tr.stateIsIncluded} />
<a
class="inline-block w-fit cursor-pointer"
on:click={() => state.guistate.filtersPanelIsOpened.set(true)}
>
<Tr t={tr.openLayers} />
</a>
</span>
<Tr cls="link-underline" t={tr.documentation} />
</div>
</AccordionSingle>
</div>