From 2c6b94835c405c8a228871399bfdb4ccd675ef1a Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Sat, 29 Apr 2023 23:29:03 -0500 Subject: [PATCH] redshift optimistic ui --- src/components/Activity.tsx | 22 ++-- src/routes/Redshift.tsx | 203 ++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 src/routes/Redshift.tsx diff --git a/src/components/Activity.tsx b/src/components/Activity.tsx index 9171864..ef29eb5 100644 --- a/src/components/Activity.tsx +++ b/src/components/Activity.tsx @@ -1,17 +1,19 @@ import send from '~/assets/icons/send.svg'; import receive from '~/assets/icons/receive.svg'; -import { Card, LoadingSpinner, SmallAmount, SmallHeader, VStack } from './layout'; +import { ButtonLink, Card, LoadingSpinner, SmallAmount, SmallHeader, VStack } from './layout'; import { For, Match, ParentComponent, Suspense, Switch, createMemo, createResource, createSignal } from 'solid-js'; import { useMegaStore } from '~/state/megaStore'; import { MutinyInvoice } from '@mutinywallet/mutiny-wasm'; import { prettyPrintTime } from '~/utils/prettyPrintTime'; import { JsonModal } from '~/components/JsonModal'; import mempoolTxUrl from '~/utils/mempoolTxUrl'; +import wave from "~/assets/wave.gif" -const THREE_COLUMNS = 'grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0' -const CENTER_COLUMN = 'min-w-0 overflow-hidden max-w-full' -const MISSING_LABEL = 'py-1 px-2 bg-white/10 rounded inline-block text-sm' -const RIGHT_COLUMN = 'flex flex-col items-right text-right max-w-[8rem]' +export const THREE_COLUMNS = 'grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0' +export const CENTER_COLUMN = 'min-w-0 overflow-hidden max-w-full' +export const MISSING_LABEL = 'py-1 px-2 bg-white/10 rounded inline-block text-sm' +export const REDSHIFT_LABEL = 'py-1 px-2 bg-white text-m-red rounded inline-block text-sm' +export const RIGHT_COLUMN = 'flex flex-col items-right text-right max-w-[8rem]' type OnChainTx = { txid: string @@ -26,14 +28,15 @@ type OnChainTx = { } } -type Utxo = { +export type UtxoItem = { outpoint: string txout: { value: number script_pubkey: string } keychain: string - is_spent: boolean + is_spent: boolean, + redshifted?: boolean } const SubtleText: ParentComponent = (props) => { @@ -95,7 +98,7 @@ function InvoiceItem(props: { item: MutinyInvoice }) { ) } -function Utxo(props: { item: Utxo }) { +function Utxo(props: { item: UtxoItem }) { const spent = createMemo(() => props.item.is_spent); const [open, setOpen] = createSignal(false) @@ -136,7 +139,7 @@ export function Activity() { const getUtXos = async () => { console.log("Getting utxos"); - const utxos = await state.node_manager?.list_utxos() as Utxo[]; + const utxos = await state.node_manager?.list_utxos() as UtxoItem[]; return utxos; } @@ -197,6 +200,7 @@ export function Activity() { + Redshift redshift diff --git a/src/routes/Redshift.tsx b/src/routes/Redshift.tsx new file mode 100644 index 0000000..e0139af --- /dev/null +++ b/src/routes/Redshift.tsx @@ -0,0 +1,203 @@ +import { createEffect, createMemo, createResource, createSignal, For, Match, onMount, Suspense, Switch } from "solid-js"; +import { CENTER_COLUMN, MISSING_LABEL, REDSHIFT_LABEL, RIGHT_COLUMN, THREE_COLUMNS, UtxoItem } from "~/components/Activity"; +import { Card, DefaultMain, LargeHeader, LoadingSpinner, NiceP, NodeManagerGuard, SafeArea, SmallAmount, SmallHeader, VStack } from "~/components/layout"; +import { BackLink } from "~/components/layout/BackLink"; +import { StyledRadioGroup } from "~/components/layout/Radio"; +import NavBar from "~/components/NavBar"; +import { useMegaStore } from "~/state/megaStore"; +import wave from "~/assets/wave.gif" + +type ShiftOption = "utxo" | "lightning" + +type ShiftStage = "choose" | "observe" | "success" | "failure" + + +const SHIFT_OPTIONS = [{ value: "utxo", label: "UTXO", caption: "Trade your UTXO for a fresh UTXO" }, { value: "lightning", label: "Lightning", caption: "Convert your UTXO into Lightning" }] + +import receive from '~/assets/icons/receive.svg'; +import { Button } from "~/components/layout/Button"; +import { ProgressBar } from "~/components/layout/ProgressBar"; + +export function Utxo(props: { item: UtxoItem, onClick?: () => void, redshifted?: boolean }) { + const spent = createMemo(() => props.item.is_spent); + + + return ( + <> +
+ receive arrow + +
+
+ {props.redshifted &&

RS

} + {!props.item.redshifted &&

Unknown

} +
+ +
+
+ + {props.item?.is_spent ? "SPENT" : "UNSPENT"} + +
+
+ + ) +} + +const FAKE_STATES = ["Creating a new node", "Opening a channel", "Sending funds through", "Closing the channel", "Redshift complete"] + +function ShiftObserver(props: { setShiftStage: (stage: ShiftStage) => void }, utxo: UtxoItem) { + const [fakeStage, setFakeStage] = createSignal(2); + + // onMount(() => { + // const interval = setInterval(() => { + // console.log("intervaling") + // if (fakeStage() === FAKE_STATES.length - 1) { + // clearInterval(interval) + // props.setShiftStage("success"); + // } else { + // setFakeStage((fakeStage() + 1)) + // } + // // cont() + // }, 1000) + // // return () => clearInterval(interval); + // }) + + const [sentAmount, setSentAmount] = createSignal(0); + + onMount(() => { + const interval = setInterval(() => { + if (sentAmount() === 200000) { + // clearInterval(interval) + // props.setShiftStage("success"); + setSentAmount((0)) + + } else { + setSentAmount((sentAmount() + 50000)) + } + }, 1000) + }) + + return ( + <> + Watch it go! + + +
{FAKE_STATES[fakeStage()]}
+ + sine wave +
+
+ + ) +} + + +export default function Redshift() { + const [state, _actions] = useMegaStore(); + + const [shiftStage, setShiftStage] = createSignal("observe"); + const [shiftType, setShiftType] = createSignal("utxo"); + + const [chosenUtxo, setChosenUtxo] = createSignal(); + + const getUtXos = async () => { + console.log("Getting utxos"); + const utxos = await state.node_manager?.list_utxos() as UtxoItem[]; + return utxos; + } + + const [utxos, { refetch: _refetchUtxos }] = createResource(getUtXos); + + createEffect(() => { + if (chosenUtxo()) { + setShiftStage("observe"); + } + }) + + function resetState() { + setShiftStage("choose"); + setShiftType("utxo"); + setChosenUtxo(undefined); + } + + return ( + + + + + Redshift + + + + + Where is this going? + setShiftType(newValue as ShiftOption)} choices={SHIFT_OPTIONS} /> + + + Choose your sine wave UTXO to begin + + + + + + + + No utxos (empty state) + + = 0}> + + {(utxo) => + setChosenUtxo(utxo)} /> + } + + + + + + + Redshifted UTXOs}> + + + + + + No utxos (empty state) + + = 0}> + + {(utxo) => + + } + + + + + + + + + + + + + We did it. Here's your new UTXO: + + + + + + + + Oh dear + Here's what happened: + + + + + + + + + ) +} \ No newline at end of file