From f48b8db55e62f44fcb955fdb47abec2f02c46ce6 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Mon, 15 May 2023 12:25:41 -0500 Subject: [PATCH] lightning details view --- src/assets/icons/bolt-black.svg | 3 + src/assets/icons/chain-black.svg | 4 + src/components/Activity.tsx | 4 +- src/components/ActivityItem.tsx | 10 ++- src/components/DetailsModal.tsx | 142 +++++++++++++++++++++++++++++++ src/components/ShareCard.tsx | 13 ++- src/root.css | 5 -- src/utils/prettyPrintTime.ts | 1 - 8 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 src/assets/icons/bolt-black.svg create mode 100644 src/assets/icons/chain-black.svg create mode 100644 src/components/DetailsModal.tsx diff --git a/src/assets/icons/bolt-black.svg b/src/assets/icons/bolt-black.svg new file mode 100644 index 0000000..99fa865 --- /dev/null +++ b/src/assets/icons/bolt-black.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/icons/chain-black.svg b/src/assets/icons/chain-black.svg new file mode 100644 index 0000000..ff993a4 --- /dev/null +++ b/src/assets/icons/chain-black.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/components/Activity.tsx b/src/components/Activity.tsx index 9234832..d893926 100644 --- a/src/components/Activity.tsx +++ b/src/components/Activity.tsx @@ -9,6 +9,7 @@ import { getRedshifted } from '~/utils/fakeLabels'; import { ActivityItem } from './ActivityItem'; import { MutinyTagItem } from '~/utils/tags'; import { Network } from '~/logic/mutinyWalletSetup'; +import { DetailsModal } from './DetailsModal'; 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' @@ -53,7 +54,6 @@ function OnChainItem(props: { item: OnChainTx, labels: MutinyTagItem[], network: Mempool Link - {/* {JSON.stringify(props.labels)} */} - + setOpen(!open())} /> ) diff --git a/src/components/ActivityItem.tsx b/src/components/ActivityItem.tsx index 604bc68..f1df9d8 100644 --- a/src/components/ActivityItem.tsx +++ b/src/components/ActivityItem.tsx @@ -1,13 +1,13 @@ import { ParentComponent, createMemo, createResource } from "solid-js"; -import { InlineAmount } from "./AmountCard"; import { satsToUsd } from "~/utils/conversions"; import bolt from "~/assets/icons/bolt.svg" import chain from "~/assets/icons/chain.svg" import { timeAgo } from "~/utils/prettyPrintTime"; import { MutinyTagItem } from "~/utils/tags"; import { generateGradient } from "~/utils/gradientHash"; +import { useMegaStore } from "~/state/megaStore"; -export const ActivityAmount: ParentComponent<{ amount: string, price: number, positive?: boolean }> = (props) => { +export const ActivityAmount: ParentComponent<{ amount: string, price: number, positive?: boolean, center?: boolean }> = (props) => { const amountInUsd = createMemo(() => { const parsed = Number(props.amount); if (isNaN(parsed)) { @@ -27,7 +27,8 @@ export const ActivityAmount: ParentComponent<{ amount: string, price: number, po }) return ( -
+
{props.positive && "+ "}{prettyPrint()} SATS @@ -74,6 +75,7 @@ function labelString(labels: MutinyTagItem[]) { export function ActivityItem(props: { kind: "lightning" | "onchain", labels: MutinyTagItem[], amount: number | bigint, date?: number | bigint, positive?: boolean, onClick?: () => void }) { const labels = () => sortLabels(props.labels) + const [state, _actions] = useMegaStore(); return (
props.onClick && props.onClick()} @@ -93,7 +95,7 @@ export function ActivityItem(props: { kind: "lightning" | "onchain", labels: Mut
- +
) diff --git a/src/components/DetailsModal.tsx b/src/components/DetailsModal.tsx new file mode 100644 index 0000000..71036ea --- /dev/null +++ b/src/components/DetailsModal.tsx @@ -0,0 +1,142 @@ +import { Dialog } from "@kobalte/core"; +import { For, JSX, ParentComponent, Show, createMemo } from "solid-js"; +import { Hr, TinyButton, VStack } from "~/components/layout"; +import { MutinyInvoice } from "@mutinywallet/mutiny-wasm"; +import { OnChainTx } from "./Activity"; + +import eyeIcon from "~/assets/icons/eye.svg" +import close from "~/assets/icons/close.svg"; +import bolt from "~/assets/icons/bolt-black.svg"; + +import { ActivityAmount } from "./ActivityItem"; +import { CopyButton } from "./ShareCard"; +import { prettyPrintTime } from "~/utils/prettyPrintTime"; +import { useMegaStore } from "~/state/megaStore"; +import { tagToMutinyTag } from "~/utils/tags"; + +const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm" +const DIALOG_POSITIONER = "fixed inset-0 z-50 flex items-center justify-center" +const DIALOG_CONTENT = "max-w-[500px] w-[90vw] max-h-[100dvh] overflow-y-scroll disable-scrollbars mx-4 p-4 bg-neutral-800/80 backdrop-blur-md shadow-xl rounded-xl border border-white/10" + +function LightningHeader(props: { info: MutinyInvoice }) { + const [state, _actions] = useMegaStore(); + + const tags = createMemo(() => { + if (props.info.labels.length) { + let contact = state.mutiny_wallet?.get_contact(props.info.labels[0]); + if (contact) { + return [tagToMutinyTag(contact)] + } else { + return [] + } + } else { + return [] + } + }) + + return ( +
+
+ lightning bolt +
+

{props.info.is_send ? "Lightning send" : "Lightning receive"}

+ + + {(tag) => ( + { }}> + {tag.name} + + )} + +
+ ) +} + +const KeyValue: ParentComponent<{ key: string }> = (props) => { + return ( +
  • + {props.key} + {props.children} +
  • + + ) + +} + +function MiniStringShower(props: { text: string }) { + return ( +
    +
    {props.text}
    + +
    + ) +} + +function LightningDetails(props: { info: MutinyInvoice }) { + return ( + +
      + + {props.info.paid ? "Paid" : "Unpaid"} + + + {prettyPrintTime(Number(props.info.last_updated))} + + + + {props.info.description} + + + + {props.info.fees_paid?.toLocaleString() ?? 0} + + + + + + + + + + +
    +
    + + ) +} + +export function DetailsModal(props: { title: string, open: boolean, data?: MutinyInvoice | OnChainTx, setOpen: (open: boolean) => void, children?: JSX.Element }) { + const json = createMemo(() => JSON.stringify(props.data, null, 2)); + + return ( + props.setOpen(isOpen)}> + + +
    + +
    +
    + + + +
    + + + +
    + + +
    + +
    +
    + +
    + + + ) +} diff --git a/src/components/ShareCard.tsx b/src/components/ShareCard.tsx index 32ab3b3..abcc072 100644 --- a/src/components/ShareCard.tsx +++ b/src/components/ShareCard.tsx @@ -8,7 +8,7 @@ import { JsonModal } from "./JsonModal"; const STYLE = "px-4 py-2 rounded-xl border-2 border-white flex gap-2 items-center font-semibold" -function ShareButton(props: { receiveString: string }) { +export function ShareButton(props: { receiveString: string }) { async function share(receiveString: string) { // If the browser doesn't support share we can just copy the address if (!navigator.share) { @@ -45,20 +45,25 @@ export function StringShower(props: { text: string }) { ) } -export function ShareCard(props: { text?: string }) { +export function CopyButton(props: { text?: string, title?: string }) { const [copy, copied] = useCopy({ copiedTimeout: 1000 }); function handleCopy() { copy(props.text ?? "") } + return ( + + ) +} + +export function ShareCard(props: { text?: string }) { return ( -
    - + diff --git a/src/root.css b/src/root.css index a544dea..72da87c 100644 --- a/src/root.css +++ b/src/root.css @@ -39,8 +39,3 @@ a { #video-container .scan-region-highlight-svg { display: none; } - -/* Missing you sveltekit */ -dd { - @apply mb-8 mt-2; -} diff --git a/src/utils/prettyPrintTime.ts b/src/utils/prettyPrintTime.ts index de82a2a..6a94184 100644 --- a/src/utils/prettyPrintTime.ts +++ b/src/utils/prettyPrintTime.ts @@ -1,6 +1,5 @@ export function prettyPrintTime(ts: number) { const options: Intl.DateTimeFormatOptions = { - weekday: 'long', year: 'numeric', month: 'short', day: 'numeric',