MapComplete/src/UI/Base/LoginToggle.svelte

78 lines
2.9 KiB
Svelte

<script lang="ts">
import Loading from "./Loading.svelte"
import type { OsmServiceState } from "../../Logic/Osm/OsmConnection"
import { OsmConnection } from "../../Logic/Osm/OsmConnection"
import { Translation } from "../i18n/Translation"
import Translations from "../i18n/Translations"
import Tr from "./Tr.svelte"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import Invalid from "../../assets/svg/Invalid.svelte"
import ArrowPath from "@babeard/svelte-heroicons/mini/ArrowPath"
import { IsOnline } from "../../Logic/Web/IsOnline"
export let state: {
osmConnection: OsmConnection
featureSwitches?: { featureSwitchEnableLogin?: UIEventSource<boolean> }
}
/**
* Do show this element when in offline mode
*/
export let offline = false
/**
* If set, 'loading' will act as if we are already logged in.
*/
export let ignoreLoading: boolean = offline // If it works in offline mode, it'll work while we are logging in too
/**
* If set and the OSM-api fails, do _not_ show any error messages nor the successful state, just hide.
* Will still show the "not-logged-in"-slot
*/
export let hiddenFail: boolean = false
let loadingStatus = state?.osmConnection?.loadingStatus ?? new ImmutableStore("logged-in")
let badge = state?.featureSwitches?.featureSwitchEnableLogin ?? new ImmutableStore(true)
const t = Translations.t.general
const offlineModes: Partial<Record<OsmServiceState, Translation>> = {
offline: t.loginFailedOfflineMode,
unreachable: t.loginFailedUnreachableMode,
unknown: t.loginFailedUnreachableMode,
readonly: t.loginFailedReadonlyMode,
}
const apiState: Store<OsmServiceState> =
state?.osmConnection?.apiIsOnline ?? new ImmutableStore<OsmServiceState>("online")
const online = IsOnline.isOnline
let loggedIn = state?.osmConnection?.isLoggedIn
</script>
{#if $badge}
{#if !$online && !offline}
{#if !hiddenFail}
<div class="alert">
<Tr t={t.offline} />
</div>
{/if}
{:else if !ignoreLoading && !hiddenFail && $loadingStatus === "loading"}
<slot name="loading">
<Loading />
</slot>
{:else if $loggedIn}
<slot />
{:else if ($loadingStatus === "error" || $apiState === "readonly" || $apiState === "offline" || $apiState === "unreachable")}
{#if !hiddenFail}
<slot name="error">
<div class="alert flex flex-col items-center">
<div class="flex max-w-64 items-center">
<Invalid class="m-2 h-8 w-8 shrink-0" />
<Tr t={offlineModes[$apiState] ?? t.loginFailedUnreachableMode} />
</div>
<button class="h-fit" on:click={() => state.osmConnection.AttemptLogin()}>
<ArrowPath class="h-6 w-6" />
<Tr t={t.retry} />
</button>
</div>
</slot>
{/if}
{:else if $loadingStatus === "not-attempted"}
<slot name="not-logged-in" />
{/if}
{/if}