Offer a way out when startup stalls on an unresponsive signer
This commit is contained in:
parent
b3f9df7941
commit
795819c2ad
3 changed files with 69 additions and 10 deletions
52
src/app/components/Startup.svelte
Normal file
52
src/app/components/Startup.svelte
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {ms} from "@welshman/lib"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
import {resetSession} from "@app/session"
|
||||
|
||||
type Props = {
|
||||
error?: unknown
|
||||
}
|
||||
|
||||
const {error}: Props = $props()
|
||||
|
||||
let stalled = $state(false)
|
||||
let loading = $state(false)
|
||||
|
||||
const logout = async () => {
|
||||
loading = true
|
||||
|
||||
await resetSession()
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const timeout = setTimeout(() => (stalled = true), ms(10))
|
||||
|
||||
return () => clearTimeout(timeout)
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if error || stalled}
|
||||
<div class="flex h-screen flex-col items-center justify-center gap-4 p-8 text-center">
|
||||
<p class="text-xl font-bold">
|
||||
{#if error}
|
||||
{PLATFORM_NAME} couldn't start
|
||||
{:else}
|
||||
{PLATFORM_NAME} is still starting
|
||||
{/if}
|
||||
</p>
|
||||
<p class="max-w-sm">
|
||||
This usually means your signer isn't responding. Logging out clears this device and takes you
|
||||
back to the login screen.
|
||||
</p>
|
||||
<Button class="button button-primary" onclick={logout} disabled={loading}>
|
||||
<Spinner {loading} reserveSpace>Log out</Spinner>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -84,15 +84,19 @@ export const restoreSession = async () => {
|
|||
})
|
||||
}
|
||||
|
||||
export const logout = async () => {
|
||||
await deactivateCurrentPomadeSession()
|
||||
await Push.disable()
|
||||
// A revoked signer can leave the app unable to start, so this clears the device without asking it anything.
|
||||
export const resetSession = async () => {
|
||||
await kv.clear()
|
||||
await ss.clear()
|
||||
await storage.get()?.clear()
|
||||
|
||||
app.get().cleanup()
|
||||
localStorage.clear()
|
||||
|
||||
window.location.href = "/"
|
||||
}
|
||||
|
||||
export const logout = async () => {
|
||||
await deactivateCurrentPomadeSession()
|
||||
await Push.disable()
|
||||
await resetSession()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
import * as plugins from "@welshman/app"
|
||||
import {isMobile, documentActive} from "@lib/html"
|
||||
import AppContainer from "@app/components/AppContainer.svelte"
|
||||
import Startup from "@app/components/Startup.svelte"
|
||||
import ModalContainer from "@app/components/ModalContainer.svelte"
|
||||
import * as core from "@app/core"
|
||||
import {goToChat, goToHome, setupHistory} from "@app/routes"
|
||||
|
|
@ -320,15 +321,17 @@
|
|||
{/if}
|
||||
</svelte:head>
|
||||
|
||||
{#await unsubscribe}
|
||||
<!-- pass -->
|
||||
{:then}
|
||||
<div class={isMobile ? "fl mobile" : "fl"} data-fl-theme={$flTheme}>
|
||||
<div class={isMobile ? "fl mobile" : "fl"} data-fl-theme={$flTheme}>
|
||||
{#await unsubscribe}
|
||||
<Startup />
|
||||
{:then}
|
||||
<AppContainer>
|
||||
{@render children()}
|
||||
</AppContainer>
|
||||
<ModalContainer />
|
||||
<div class="tippy-target"></div>
|
||||
<NewNotificationSound />
|
||||
</div>
|
||||
{/await}
|
||||
{:catch error}
|
||||
<Startup {error} />
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue