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 () => {
|
// A revoked signer can leave the app unable to start, so this clears the device without asking it anything.
|
||||||
await deactivateCurrentPomadeSession()
|
export const resetSession = async () => {
|
||||||
await Push.disable()
|
|
||||||
await kv.clear()
|
await kv.clear()
|
||||||
await ss.clear()
|
await ss.clear()
|
||||||
await storage.get()?.clear()
|
await storage.get()?.clear()
|
||||||
|
|
||||||
app.get().cleanup()
|
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
|
||||||
window.location.href = "/"
|
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 * as plugins from "@welshman/app"
|
||||||
import {isMobile, documentActive} from "@lib/html"
|
import {isMobile, documentActive} from "@lib/html"
|
||||||
import AppContainer from "@app/components/AppContainer.svelte"
|
import AppContainer from "@app/components/AppContainer.svelte"
|
||||||
|
import Startup from "@app/components/Startup.svelte"
|
||||||
import ModalContainer from "@app/components/ModalContainer.svelte"
|
import ModalContainer from "@app/components/ModalContainer.svelte"
|
||||||
import * as core from "@app/core"
|
import * as core from "@app/core"
|
||||||
import {goToChat, goToHome, setupHistory} from "@app/routes"
|
import {goToChat, goToHome, setupHistory} from "@app/routes"
|
||||||
|
|
@ -320,15 +321,17 @@
|
||||||
{/if}
|
{/if}
|
||||||
</svelte:head>
|
</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>
|
<AppContainer>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</AppContainer>
|
</AppContainer>
|
||||||
<ModalContainer />
|
<ModalContainer />
|
||||||
<div class="tippy-target"></div>
|
<div class="tippy-target"></div>
|
||||||
<NewNotificationSound />
|
<NewNotificationSound />
|
||||||
</div>
|
{:catch error}
|
||||||
|
<Startup {error} />
|
||||||
{/await}
|
{/await}
|
||||||
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue