UX: improve display if OSM.org is down

This commit is contained in:
Pieter Vander Vennet 2024-12-15 22:39:22 +01:00
parent d4dc5f3548
commit a55bd55b46
6 changed files with 101 additions and 59 deletions

View file

@ -5,7 +5,7 @@
import { Translation } from "../i18n/Translation"
import Translations from "../i18n/Translations"
import Tr from "./Tr.svelte"
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import Invalid from "../../assets/svg/Invalid.svelte"
import ArrowPath from "@babeard/svelte-heroicons/mini/ArrowPath"
@ -21,6 +21,10 @@
* Only show the 'successful' state, don't show loading or error messages
*/
export let silentFail: boolean = false
/**
* If set and the OSM-api fails, do _not_ show any error messages nor the successful state, just hide
*/
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
@ -30,7 +34,7 @@
unknown: t.loginFailedUnreachableMode,
readonly: t.loginFailedReadonlyMode,
}
const apiState =
const apiState: Store<string> =
state?.osmConnection?.apiIsOnline ?? new ImmutableStore<OsmServiceState>("online")
</script>
@ -39,19 +43,21 @@
<slot name="loading">
<Loading />
</slot>
{:else if !silentFail && $loadingStatus === "error"}
<slot name="error">
<div class="alert flex flex-col items-center">
<div class="max-w-64 flex items-center">
<Invalid class="m-2 h-8 w-8 shrink-0" />
<Tr t={offlineModes[$apiState] ?? t.loginFailedUnreachableMode} />
{:else if !silentFail && ($loadingStatus === "error" || $apiState === "readonly" || $apiState === "offline")}
{#if !hiddenFail}
<slot name="error">
<div class="alert flex flex-col items-center">
<div class="max-w-64 flex 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>
<button class="h-fit" on:click={() => state.osmConnection.AttemptLogin()}>
<ArrowPath class="h-6 w-6" />
<Tr t={t.retry} />
</button>
</div>
</slot>
</slot>
{/if}
{:else if $loadingStatus === "logged-in"}
<slot />
{:else if !silentFail && $loadingStatus === "not-attempted"}

View file

@ -124,7 +124,7 @@
</svelte:fragment>
<!-- All shown components are set by 'usersettings.json', which happily uses some special visualisations created specifically for it -->
<LoginToggle {state}>
<LoginToggle {state} silentFail>
<div class="flex flex-col" slot="not-logged-in">
<LanguagePicker availableLanguages={theme.language} />
<Tr cls="alert" t={Translations.t.userinfo.notLoggedIn} />
@ -144,7 +144,7 @@
</LoginToggle>
</Page>
<LoginToggle {state}>
<LoginToggle {state} silentFail>
<Page {onlyLink} shown={pg.favourites}>
<svelte:fragment slot="header">
<HeartIcon />

View file

@ -24,7 +24,7 @@
}
</script>
<LoginToggle ignoreLoading={true} {state}>
<LoginToggle ignoreLoading={true} hiddenFail {state}>
{#if $isFavourite}
<button
class="soft no-image-background m-0 h-8 w-8 p-0"

View file

@ -85,6 +85,8 @@
}
let answerId = "answer-" + Utils.randomString(5)
let debug = state?.featureSwitches?.featureSwitchIsDebugging ?? new ImmutableStore(false)
let apiState: Store<string> = state?.osmConnection?.apiIsOnline ?? new ImmutableStore("online")
</script>
<div bind:this={htmlElem} class={twMerge(clss, "tr-" + config.id)}>
@ -126,7 +128,7 @@
{layer}
extraClasses="my-2"
/>
{#if !editingEnabled || $editingEnabled}
{#if (!editingEnabled || $editingEnabled) && $apiState !== "readonly" && $apiState !== "offline"}
<EditButton
arialabel={config.editButtonAriaLabel}
ariaLabelledBy={answerId}

View file

@ -355,9 +355,11 @@
disabledInTheme.set(newList)
menuIsOpened.set(false)
}
let apiState = state.osmConnection.apiIsOnline
</script>
{#if question !== undefined}
{#if question !== undefined && $apiState !== "readonly" && $apiState !== "offline"}
<div class={clss}>
{#if layer.isNormal()}
<LoginToggle {state}>