mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2026-02-23 07:04:19 +01:00
add channelopen and channelclose modals
This commit is contained in:
3
src/assets/icons/download-channel.svg
Normal file
3
src/assets/icons/download-channel.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 20C5.45 20 4.979 19.804 4.587 19.412C4.195 19.02 3.99934 18.5493 4 18V15H6V18H18V15H20V18C20 18.55 19.804 19.021 19.412 19.413C19.02 19.805 18.5493 20.0007 18 20H6ZM12 16L7 11L8.4 9.55L11 12.15V4H13V12.15L15.6 9.55L17 11L12 16Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 359 B |
3
src/assets/icons/shuffle-black.svg
Normal file
3
src/assets/icons/shuffle-black.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 8.99985h3.5c.736 0 1.393.391 1.851 1.00095.32529-.60198.7255-1.16042 1.191-1.66195-.803-.823-1.866-1.339-3.042-1.339H4c-.26522 0-.51957.10536-.70711.29289C3.10536 7.48028 3 7.73463 3 7.99985s.10536.51957.29289.70711c.18754.18753.44189.29289.70711.29289Zm7.685 3.11095c.551-1.657 2.256-3.11095 3.649-3.11095h1.838l-1.293 1.29295c-.0928.0929-.1665.2031-.2167.3244-.0503.1213-.0761.2513-.0761.3826 0 .1314.0258.2614.0761.3827.0502.1213.1239.2315.2167.3243.0928.0929.2031.1665.3244.2168.1213.0502.2513.0761.3826.0761.1313 0 .2613-.0259.3826-.0761.1213-.0503.2316-.1239.3244-.2168L21 7.99985l-3.707-3.707c-.0928-.09285-.2031-.16649-.3244-.21674C16.8473 4.02586 16.7173 4 16.586 4c-.1313 0-.2613.02586-.3826.07611-.1213.05025-.2316.12389-.3244.21674-.0928.09284-.1665.20307-.2167.32437-.0503.12131-.0761.25133-.0761.38263 0 .1313.0258.26132.0761.38262.0502.12131.1239.23153.2167.32438l1.293 1.293h-1.838c-2.274 0-4.711 1.967-5.547 4.47895l-.472 1.411c-.641 1.926-2.072 3.11-2.815 3.11H4c-.26522 0-.51957.1054-.70711.2929-.18753.1876-.29289.4419-.29289.7071 0 .2653.10536.5196.29289.7072.18754.1875.44189.2928.70711.2928h2.5c1.837 0 3.863-1.925 4.713-4.479l.472-1.41Zm4.194 1.182c-.0929.0928-.1667.203-.217.3244-.0503.1213-.0762.2513-.0762.3826 0 .1314.0259.2614.0762.3827.0503.1214.1241.2316.217.3243l1.293 1.293h-2.338c-1.268 0-2.33-.891-2.691-2.108-.2661.773-.6326 1.5076-1.09 2.185.886 1.162 2.243 1.923 3.781 1.923h2.338l-1.293 1.293c-.0928.0929-.1665.2031-.2167.3244-.0503.1213-.0761.2513-.0761.3826 0 .1314.0258.2614.0761.3827.0502.1213.1239.2315.2167.3244.0928.0928.2031.1664.3244.2167.1213.0502.2513.0761.3826.0761.1313 0 .2613-.0259.3826-.0761.1213-.0503.2316-.1239.3244-.2167L21 16.9998l-3.707-3.707c-.0928-.0929-.203-.1666-.3243-.2169-.1213-.0504-.2514-.0763-.3827-.0763-.1313 0-.2614.0259-.3827.0763-.1213.0503-.2315.124-.3243.2169Z" fill="#000"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
3
src/assets/icons/upload-channel.svg
Normal file
3
src/assets/icons/upload-channel.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 20C5.45 20 4.979 19.804 4.587 19.412C4.195 19.02 3.99934 18.5493 4 18V15H6V18H18V15H20V18C20 18.55 19.804 19.021 19.412 19.413C19.02 19.805 18.5493 20.0007 18 20H6ZM11 16V7.85L8.4 10.45L7 9L12 4L17 9L15.6 10.45L13 7.85V16H11Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 357 B |
@@ -1,5 +1,13 @@
|
||||
import { NiceP } from "./layout";
|
||||
import { For, Match, Show, Switch, createEffect, createSignal } from "solid-js";
|
||||
import {
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
createEffect,
|
||||
createSignal,
|
||||
onMount
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { ActivityItem as MutinyActivity } from "@mutinywallet/mutiny-wasm";
|
||||
import { ActivityItem, HackActivityType } from "./ActivityItem";
|
||||
@@ -43,6 +51,10 @@ function UnifiedActivityItem(props: {
|
||||
item: MutinyActivity;
|
||||
onClick: (id: string, kind: HackActivityType) => void;
|
||||
}) {
|
||||
onMount(() => {
|
||||
console.log(props.item);
|
||||
});
|
||||
|
||||
const click = () => {
|
||||
props.onClick(
|
||||
props.item.id,
|
||||
|
||||
@@ -9,7 +9,10 @@ import { satsToUsd } from "~/utils/conversions";
|
||||
import bolt from "~/assets/icons/bolt.svg";
|
||||
import chain from "~/assets/icons/chain.svg";
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import on from "~/assets/icons/upload-channel.svg";
|
||||
import off from "~/assets/icons/download-channel.svg";
|
||||
import { timeAgo } from "~/utils/prettyPrintTime";
|
||||
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
@@ -65,10 +68,14 @@ function LabelCircle(props: {
|
||||
name?: string;
|
||||
contact: boolean;
|
||||
label: boolean;
|
||||
channel?: HackActivityType;
|
||||
}) {
|
||||
// TODO: don't need to run this if it's not a contact
|
||||
const [gradient] = createResource(async () => {
|
||||
return generateGradient(props.name || "?");
|
||||
if (props.name && props.contact) {
|
||||
return generateGradient(props.name || "?");
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
const text = () =>
|
||||
@@ -77,19 +84,31 @@ function LabelCircle(props: {
|
||||
: props.label
|
||||
? "≡"
|
||||
: "?";
|
||||
const bg = () => (props.name && props.contact ? gradient() : "gray");
|
||||
const bg = () => (props.name && props.contact ? gradient() : "");
|
||||
|
||||
return (
|
||||
<div
|
||||
class="flex-none h-[3rem] w-[3rem] rounded-full flex items-center justify-center text-3xl uppercase border-t border-b border-t-white/50 border-b-white/10"
|
||||
class="flex-none h-[3rem] w-[3rem] rounded-full bg-neutral-700 flex items-center justify-center text-3xl uppercase border-t border-b border-t-white/50 border-b-white/10"
|
||||
style={{ background: bg() }}
|
||||
>
|
||||
{text()}
|
||||
<Switch>
|
||||
<Match when={props.channel === "ChannelOpen"}>
|
||||
<img src={on} alt="channel open" />
|
||||
</Match>
|
||||
<Match when={props.channel === "ChannelClose"}>
|
||||
<img src={off} alt="channel close" />
|
||||
</Match>
|
||||
<Match when={true}>{text()}</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export type HackActivityType = "Lightning" | "OnChain" | "ChannelOpen";
|
||||
export type HackActivityType =
|
||||
| "Lightning"
|
||||
| "OnChain"
|
||||
| "ChannelOpen"
|
||||
| "ChannelClose";
|
||||
|
||||
export function ActivityItem(props: {
|
||||
// This is actually the ActivityType enum but wasm is hard
|
||||
@@ -121,7 +140,12 @@ export function ActivityItem(props: {
|
||||
<Match when={props.kind === "OnChain"}>
|
||||
<img class="w-[1rem]" src={chain} alt="onchain" />
|
||||
</Match>
|
||||
<Match when={props.kind === "ChannelOpen"}>
|
||||
<Match
|
||||
when={
|
||||
props.kind === "ChannelOpen" ||
|
||||
props.kind === "ChannelClose"
|
||||
}
|
||||
>
|
||||
<img class="w-[1rem]" src={shuffle} alt="swap" />
|
||||
</Match>
|
||||
</Switch>
|
||||
@@ -131,11 +155,22 @@ export function ActivityItem(props: {
|
||||
name={firstContact()?.name}
|
||||
contact={props.contacts?.length > 0}
|
||||
label={props.labels?.length > 0}
|
||||
channel={props.kind}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<Switch>
|
||||
<Match when={props.kind === "ChannelClose"}>
|
||||
<span class="text-base font-semibold text-neutral-500">
|
||||
Channel Close
|
||||
</span>
|
||||
</Match>
|
||||
<Match when={props.kind === "ChannelOpen"}>
|
||||
<span class="text-base font-semibold text-neutral-500">
|
||||
Channel Open
|
||||
</span>{" "}
|
||||
</Match>
|
||||
<Match when={firstContact()?.name}>
|
||||
<span class="text-base font-semibold truncate">
|
||||
{firstContact()?.name}
|
||||
@@ -146,9 +181,15 @@ export function ActivityItem(props: {
|
||||
{props.labels[0]}
|
||||
</span>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<Match when={props.positive}>
|
||||
<span class="text-base font-semibold text-neutral-500">
|
||||
Unknown
|
||||
Unknown sender
|
||||
</span>
|
||||
</Match>
|
||||
|
||||
<Match when={!props.positive}>
|
||||
<span class="text-base font-semibold text-neutral-500">
|
||||
Unknown receiver
|
||||
</span>
|
||||
</Match>
|
||||
</Switch>
|
||||
@@ -164,11 +205,18 @@ export function ActivityItem(props: {
|
||||
</Switch>
|
||||
</div>
|
||||
<div class="">
|
||||
<ActivityAmount
|
||||
amount={props.amount.toString()}
|
||||
price={state.price}
|
||||
positive={props.positive}
|
||||
/>
|
||||
<Switch>
|
||||
<Match when={props.kind === "ChannelClose"}>
|
||||
<div />
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<ActivityAmount
|
||||
amount={props.amount.toString()}
|
||||
price={state.price}
|
||||
positive={props.positive}
|
||||
/>
|
||||
</Match>{" "}
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -11,22 +11,29 @@ import {
|
||||
createResource
|
||||
} from "solid-js";
|
||||
import { Hr, ModalCloseButton, TinyButton, VStack } from "~/components/layout";
|
||||
import { MutinyInvoice } from "@mutinywallet/mutiny-wasm";
|
||||
import {
|
||||
ChannelClosure,
|
||||
MutinyChannel,
|
||||
MutinyInvoice
|
||||
} from "@mutinywallet/mutiny-wasm";
|
||||
import { OnChainTx } from "./Activity";
|
||||
|
||||
import bolt from "~/assets/icons/bolt-black.svg";
|
||||
import chain from "~/assets/icons/chain-black.svg";
|
||||
import copyIcon from "~/assets/icons/copy.svg";
|
||||
import shuffle from "~/assets/icons/shuffle-black.svg";
|
||||
|
||||
import { ActivityAmount, HackActivityType } from "./ActivityItem";
|
||||
import { CopyButton, TruncateMiddle } from "./ShareCard";
|
||||
import { prettyPrintTime } from "~/utils/prettyPrintTime";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { tagToMutinyTag } from "~/utils/tags";
|
||||
import { MutinyTagItem, tagToMutinyTag } from "~/utils/tags";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { AmountSmall } from "./Amount";
|
||||
import { ExternalLink } from "./layout/ExternalLink";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
|
||||
export const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
||||
export const DIALOG_POSITIONER =
|
||||
@@ -34,24 +41,12 @@ export const DIALOG_POSITIONER =
|
||||
export 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 }) {
|
||||
function LightningHeader(props: {
|
||||
info: MutinyInvoice;
|
||||
tags: MutinyTagItem[];
|
||||
}) {
|
||||
const [state, _actions] = useMegaStore();
|
||||
|
||||
const tags = createMemo(() => {
|
||||
if (props.info.labels.length) {
|
||||
const contact = state.mutiny_wallet?.get_contact(
|
||||
props.info.labels[0]
|
||||
);
|
||||
if (contact) {
|
||||
return [tagToMutinyTag(contact)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="p-4 bg-neutral-100 rounded-full">
|
||||
@@ -66,7 +61,7 @@ function LightningHeader(props: { info: MutinyInvoice }) {
|
||||
price={state.price}
|
||||
positive={props.info.inbound}
|
||||
/>
|
||||
<For each={tags()}>
|
||||
<For each={props.tags}>
|
||||
{(tag) => (
|
||||
<TinyButton
|
||||
tag={tag}
|
||||
@@ -82,24 +77,13 @@ function LightningHeader(props: { info: MutinyInvoice }) {
|
||||
);
|
||||
}
|
||||
|
||||
function OnchainHeader(props: { info: OnChainTx }) {
|
||||
function OnchainHeader(props: {
|
||||
info: OnChainTx;
|
||||
tags: MutinyTagItem[];
|
||||
kind?: HackActivityType;
|
||||
}) {
|
||||
const [state, _actions] = useMegaStore();
|
||||
|
||||
const tags = createMemo(() => {
|
||||
if (props.info.labels.length) {
|
||||
const contact = state.mutiny_wallet?.get_contact(
|
||||
props.info.labels[0]
|
||||
);
|
||||
if (contact) {
|
||||
return [tagToMutinyTag(contact)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
const isSend = () => {
|
||||
return props.info.sent > props.info.received;
|
||||
};
|
||||
@@ -115,18 +99,38 @@ function OnchainHeader(props: { info: OnChainTx }) {
|
||||
return (
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="p-4 bg-neutral-100 rounded-full">
|
||||
<img src={chain} alt="blockchain" class="w-8 h-8" />
|
||||
<Switch>
|
||||
<Match
|
||||
when={
|
||||
props.kind === "ChannelOpen" ||
|
||||
props.kind === "ChannelClose"
|
||||
}
|
||||
>
|
||||
<img src={shuffle} alt="swap" class="w-8 h-8" />
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<img src={chain} alt="blockchain" class="w-8 h-8" />
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
<h1 class="uppercase font-semibold">
|
||||
{isSend() ? "On-chain send" : "On-chain receive"}
|
||||
{props.kind === "ChannelOpen"
|
||||
? "Channel Open"
|
||||
: props.kind === "ChannelClose"
|
||||
? "Channel Close"
|
||||
: isSend()
|
||||
? "On-chain send"
|
||||
: "On-chain receive"}
|
||||
</h1>
|
||||
<ActivityAmount
|
||||
center
|
||||
amount={amount() ?? "0"}
|
||||
price={state.price}
|
||||
positive={!isSend()}
|
||||
/>
|
||||
<For each={tags()}>
|
||||
<Show when={props.kind !== "ChannelClose"}>
|
||||
<ActivityAmount
|
||||
center
|
||||
amount={amount() ?? "0"}
|
||||
price={state.price}
|
||||
positive={!isSend()}
|
||||
/>
|
||||
</Show>
|
||||
<For each={props.tags}>
|
||||
{(tag) => (
|
||||
<TinyButton
|
||||
tag={tag}
|
||||
@@ -211,7 +215,7 @@ function LightningDetails(props: { info: MutinyInvoice }) {
|
||||
);
|
||||
}
|
||||
|
||||
function OnchainDetails(props: { info: OnChainTx }) {
|
||||
function OnchainDetails(props: { info: OnChainTx; kind?: HackActivityType }) {
|
||||
const [state, _actions] = useMegaStore();
|
||||
|
||||
const confirmationTime = () => {
|
||||
@@ -220,9 +224,30 @@ function OnchainDetails(props: { info: OnChainTx }) {
|
||||
|
||||
const network = state.mutiny_wallet?.get_network() as Network;
|
||||
|
||||
// Can return nothing if the channel is already closed
|
||||
const [channelInfo] = createResource(async () => {
|
||||
if (props.kind === "ChannelOpen") {
|
||||
try {
|
||||
const channels =
|
||||
await (state.mutiny_wallet?.list_channels() as Promise<
|
||||
MutinyChannel[]
|
||||
>);
|
||||
const channel = channels.find((channel) =>
|
||||
channel.outpoint?.startsWith(props.info.txid)
|
||||
);
|
||||
console.log(channel);
|
||||
return channel;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<VStack>
|
||||
{/* <pre>{JSON.stringify(props.info, null, 2)}</pre> */}
|
||||
{/* <pre>{JSON.stringify(channelInfo() || "", null, 2)}</pre> */}
|
||||
<ul class="flex flex-col gap-4">
|
||||
<KeyValue key="Status">
|
||||
<span class="text-neutral-300">
|
||||
@@ -248,15 +273,70 @@ function OnchainDetails(props: { info: OnChainTx }) {
|
||||
<KeyValue key="Txid">
|
||||
<MiniStringShower text={props.info.txid ?? ""} />
|
||||
</KeyValue>
|
||||
<Switch>
|
||||
<Match when={props.kind === "ChannelOpen" && channelInfo()}>
|
||||
<KeyValue key="Balance">
|
||||
<span class="text-neutral-300">
|
||||
<AmountSmall
|
||||
amountSats={channelInfo()?.balance}
|
||||
/>
|
||||
</span>
|
||||
</KeyValue>
|
||||
<KeyValue key="Reserve">
|
||||
<span class="text-neutral-300">
|
||||
<AmountSmall
|
||||
amountSats={channelInfo()?.reserve}
|
||||
/>
|
||||
</span>
|
||||
</KeyValue>
|
||||
<KeyValue key="Peer">
|
||||
<span class="text-neutral-300">
|
||||
<MiniStringShower
|
||||
text={channelInfo()?.peer ?? ""}
|
||||
/>
|
||||
</span>
|
||||
</KeyValue>
|
||||
</Match>
|
||||
<Match when={props.kind === "ChannelOpen"}>
|
||||
<InfoBox accent="blue">
|
||||
No channel details found, which means this channel
|
||||
has likely been closed.
|
||||
</InfoBox>
|
||||
</Match>
|
||||
</Switch>
|
||||
</ul>
|
||||
<div class="text-center">
|
||||
<ExternalLink href={mempoolTxUrl(props.info.txid, network)}>
|
||||
View Transaction
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
|
||||
function ChannelCloseDetails(props: { info: ChannelClosure }) {
|
||||
return (
|
||||
<VStack>
|
||||
{/* <pre>{JSON.stringify(props.info.value, null, 2)}</pre> */}
|
||||
<ul class="flex flex-col gap-4">
|
||||
<KeyValue key="Channel ID">
|
||||
<MiniStringShower text={props.info.channel_id ?? ""} />
|
||||
</KeyValue>
|
||||
<Show when={props.info.timestamp}>
|
||||
<KeyValue key="When">
|
||||
<span class="text-neutral-300">
|
||||
{props.info.timestamp
|
||||
? prettyPrintTime(Number(props.info.timestamp))
|
||||
: "Pending"}
|
||||
</span>
|
||||
</KeyValue>
|
||||
</Show>
|
||||
<KeyValue key="Reason">
|
||||
<p class="text-neutral-300 text-right">
|
||||
{props.info.reason ?? ""}
|
||||
</p>
|
||||
</KeyValue>
|
||||
</ul>
|
||||
<a
|
||||
class="uppercase font-light text-center"
|
||||
href={mempoolTxUrl(props.info.txid, network)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Mempool.space
|
||||
</a>
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
@@ -280,13 +360,34 @@ export function DetailsIdModal(props: {
|
||||
id()
|
||||
);
|
||||
return invoice;
|
||||
} else if (kind() === "ChannelClose") {
|
||||
console.log("reading channel close: ", id());
|
||||
const closeItem = await state.mutiny_wallet?.get_channel_closure(
|
||||
id()
|
||||
);
|
||||
|
||||
return closeItem;
|
||||
} else {
|
||||
console.log("reading tx: ", id());
|
||||
const tx = await state.mutiny_wallet?.get_transaction(id());
|
||||
|
||||
return tx;
|
||||
}
|
||||
});
|
||||
|
||||
const tags = createMemo(() => {
|
||||
if (data() && data().labels && data().labels.length > 0) {
|
||||
const contact = state.mutiny_wallet?.get_contact(data().labels[0]);
|
||||
if (contact) {
|
||||
return [tagToMutinyTag(contact)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (props.id && props.kind && props.open) {
|
||||
refetch();
|
||||
@@ -295,10 +396,6 @@ export function DetailsIdModal(props: {
|
||||
|
||||
const json = createMemo(() => JSON.stringify(data() || "", null, 2));
|
||||
|
||||
const isInvoice = () => {
|
||||
return props.kind === "Lightning";
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog.Root open={props.open} onOpenChange={props.setOpen}>
|
||||
<Dialog.Portal>
|
||||
@@ -314,14 +411,23 @@ export function DetailsIdModal(props: {
|
||||
</div>
|
||||
<Dialog.Title>
|
||||
<Switch>
|
||||
<Match when={isInvoice()}>
|
||||
<Match when={props.kind === "Lightning"}>
|
||||
<LightningHeader
|
||||
info={data() as MutinyInvoice}
|
||||
tags={tags()}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<Match
|
||||
when={
|
||||
props.kind === "OnChain" ||
|
||||
props.kind === "ChannelOpen" ||
|
||||
props.kind === "ChannelClose"
|
||||
}
|
||||
>
|
||||
<OnchainHeader
|
||||
info={data() as OnChainTx}
|
||||
tags={tags()}
|
||||
kind={props.kind}
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
@@ -329,20 +435,36 @@ export function DetailsIdModal(props: {
|
||||
<Hr />
|
||||
<Dialog.Description class="flex flex-col gap-4">
|
||||
<Switch>
|
||||
<Match when={isInvoice()}>
|
||||
<Match when={props.kind === "Lightning"}>
|
||||
<LightningDetails
|
||||
info={data() as MutinyInvoice}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<Match
|
||||
when={
|
||||
props.kind === "OnChain" ||
|
||||
props.kind === "ChannelOpen"
|
||||
}
|
||||
>
|
||||
<OnchainDetails
|
||||
info={data() as OnChainTx}
|
||||
kind={props.kind}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={props.kind === "ChannelClose"}>
|
||||
<ChannelCloseDetails
|
||||
info={data() as ChannelClosure}
|
||||
/>
|
||||
</Match>
|
||||
</Switch>
|
||||
<div class="flex justify-center">
|
||||
<CopyButton title="Copy" text={json()} />
|
||||
</div>
|
||||
<Show when={props.kind !== "ChannelClose"}>
|
||||
<div class="flex justify-center">
|
||||
<CopyButton
|
||||
title="Copy"
|
||||
text={json()}
|
||||
/>
|
||||
</div>
|
||||
</Show>
|
||||
</Dialog.Description>
|
||||
</Suspense>
|
||||
</Dialog.Content>
|
||||
|
||||
Reference in New Issue
Block a user