backup and restore prompts

This commit is contained in:
Paul Miller
2023-05-04 15:18:10 -05:00
parent 6fed129275
commit 91f66f345d
9 changed files with 164 additions and 59 deletions

View File

@@ -6,6 +6,7 @@ import ReloadPrompt from "~/components/Reload";
import { A } from 'solid-start';
import { Activity } from './Activity';
import settings from '~/assets/icons/settings.svg';
import { OnboardWarning } from './OnboardWarning';
export default function App() {
return (
@@ -16,6 +17,7 @@ export default function App() {
<img src={logo} class="h-10" alt="logo" />
<A class="md:hidden p-2 hover:bg-white/5 rounded-lg active:bg-m-blue" href="/settings"><img src={settings} alt="Settings" /></A>
</header>
<OnboardWarning />
<ReloadPrompt />
<BalanceBox />
<Activity />

View File

@@ -17,54 +17,26 @@ function SyncingIndicator() {
}
export default function BalanceBox() {
const [state, _] = useMegaStore();
const fetchOnchainBalance = async () => {
console.log("Refetching onchain balance");
await state.node_manager?.sync();
const balance = await state.node_manager?.get_balance();
return balance
};
// TODO: it's hacky to do these separately, but ln doesn't need the sync so I don't want to wait
const fetchLnBalance = async () => {
console.log("Refetching ln balance");
const balance = await state.node_manager?.get_balance();
return balance
};
const [onChainBalance, { refetch: refetchOnChainBalance }] = createResource(fetchOnchainBalance);
const [lnBalance, { refetch: refetchLnBalance }] = createResource(fetchLnBalance);
function refetchBalance() {
refetchLnBalance();
refetchOnChainBalance();
}
const [state, actions] = useMegaStore();
return (
<>
<FancyCard title="Lightning">
<Suspense fallback={<Amount amountSats={0} showFiat loading={true} />}>
<Show when={lnBalance()}>
<Amount amountSats={lnBalance()?.lightning} showFiat />
</Show>
</Suspense>
<Amount amountSats={state.balance?.lightning || 0} showFiat />
</FancyCard>
<FancyCard title="On-Chain" tag={onChainBalance.loading && <SyncingIndicator />}>
<Suspense fallback={<Amount amountSats={0} showFiat loading={true} />}>
<div onClick={refetchBalance}>
<Amount amountSats={onChainBalance()?.confirmed} showFiat loading={onChainBalance.loading} />
</div>
</Suspense>
<FancyCard title="On-Chain" tag={state.is_syncing && <SyncingIndicator />}>
<div onClick={actions.sync}>
<Amount amountSats={state.balance?.confirmed} showFiat />
</div>
<Suspense>
<Show when={onChainBalance()?.unconfirmed}>
<Show when={state.balance?.unconfirmed}>
<div class="flex flex-col gap-2">
<header class='text-sm font-semibold uppercase text-white/50'>
Unconfirmed Balance
</header>
<div class="text-white/50">
{prettyPrintAmount(onChainBalance()?.unconfirmed)} <span class='text-sm'>SATS</span>
{prettyPrintAmount(state.balance?.unconfirmed)} <span class='text-sm'>SATS</span>
</div>
</div>
</Show>

View File

@@ -0,0 +1,48 @@
import { Show, createSignal, onMount } from "solid-js";
import { Button, ButtonLink, SmallHeader, VStack } from "./layout";
import { useMegaStore } from "~/state/megaStore";
export function OnboardWarning() {
const [state, actions] = useMegaStore();
const [dismissedBackup, setDismissedBackup] = createSignal(false);
onMount(() => {
actions.sync()
})
function hasMoney() {
return state.balance?.confirmed || state.balance?.lightning || state.balance?.unconfirmed
}
return (
<>
{/* TODO: show this once we have a restore flow */}
<Show when={!state.dismissed_restore_prompt && false}>
<div class='rounded-xl p-4 flex flex-col gap-2 bg-neutral-950 overflow-x-hidden'>
<SmallHeader>Welcome!</SmallHeader>
<VStack>
<p class="text-2xl font-light">
Do you want to restore an existing Mutiny Wallet?
</p>
<div class="w-full flex gap-2">
<Button intent="green" onClick={() => { }}>Restore</Button>
<Button onClick={actions.dismissRestorePrompt}>Nope</Button>
</div>
</VStack>
</div>
</Show>
<Show when={!state.has_backed_up && hasMoney() && !dismissedBackup()}>
<div class='rounded-xl p-4 flex flex-col gap-2 bg-neutral-950 overflow-x-hidden'>
<SmallHeader>Secure your funds</SmallHeader>
<p class="text-2xl font-light">
You have money stored in this browser. Let's make sure you have a backup.
</p>
<div class="w-full flex gap-2">
<ButtonLink intent="blue" href="/backup">Backup</ButtonLink>
<Button onClick={() => { setDismissedBackup(true) }}>Nope</Button>
</div>
</div>
</Show>
</>
)
}

View File

@@ -1,27 +1,36 @@
import { Match, Switch, createSignal } from "solid-js"
import { For, Match, Switch, createMemo, createSignal } from "solid-js"
export function SeedWords(props: { words: string }) {
export function SeedWords(props: { words: string, setHasSeen?: (hasSeen: boolean) => void }) {
const [shouldShow, setShouldShow] = createSignal(false)
function toggleShow() {
setShouldShow(!shouldShow())
if (shouldShow()) {
props.setHasSeen?.(true)
}
}
return (<pre class="flex items-center gap-4 bg-m-red p-4 rounded-xl overflow-hidden">
const splitWords = createMemo(() => props.words.split(" "))
return (<button class="flex items-center gap-4 bg-m-red p-4 rounded-xl overflow-hidden" onClick={toggleShow}>
<Switch>
<Match when={!shouldShow()}>
<div onClick={toggleShow} class="cursor-pointer">
<div class="cursor-pointer">
<code class="text-red">TAP TO REVEAL SEED WORDS</code>
</div>
</Match>
<Match when={shouldShow()}>
<div onClick={toggleShow} class="cursor-pointer overflow-hidden">
<p class="font-mono w-full whitespace-pre-wrap">
{props.words}
</p>
</div>
<ol class="cursor-pointer overflow-hidden grid grid-cols-2 w-full list-decimal list-inside">
<For each={splitWords()}>
{(word) => (
<li class="font-mono text-left">
{word}
</li>
)}
</For>
</ol>
</Match>
</Switch>
</pre >)
</button >)
}

View File

@@ -31,7 +31,7 @@ export function ToastItem(props: { toastId: number, title: string, description:
return (
<Toast.Root toastId={props.toastId} class={`w-[80vw] max-w-[400px] mx-auto p-4 bg-neutral-900/80 backdrop-blur-md shadow-xl rounded-xl border ${props.isError ? "border-m-red/50" : "border-white/10"} `}>
<div class="flex gap-4 w-full justify-between items-start">
<div>
<div class="flex-1">
<Toast.Title>
<SmallHeader>
{props.title}
@@ -43,7 +43,7 @@ export function ToastItem(props: { toastId: number, title: string, description:
</p>
</Toast.Description>
</div>
<Toast.CloseButton class="hover:bg-white/10 rounded-lg active:bg-m-blue w-[5rem]">
<Toast.CloseButton class="hover:bg-white/10 rounded-lg active:bg-m-blue w-[5rem] flex-0">
<img src={close} alt="Close" />
</Toast.CloseButton>
</div>

View File

@@ -103,6 +103,10 @@ const SmallAmount: ParentComponent<{ amount: number | bigint }> = (props) => {
return (<h2 class="font-light text-lg">{props.amount.toLocaleString()} <span class="text-sm">SATS</span></h2>)
}
export const NiceP: ParentComponent = (props) => {
return (<p class="text-2xl font-light">{props.children}</p>)
}
export {
SmallHeader,
Card,