mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2025-12-17 22:34:23 +01:00
feat: separate amountsats and amountfiat
This commit is contained in:
@@ -9,8 +9,8 @@ import { timeAgo } from "~/utils/prettyPrintTime";
|
||||
import { generateGradient } from "~/utils/gradientHash";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { Amount } from "~/components/Amount";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat, AmountSats } from "~/components/Amount";
|
||||
|
||||
export const ActivityAmount: ParentComponent<{
|
||||
amount: string;
|
||||
@@ -20,19 +20,27 @@ export const ActivityAmount: ParentComponent<{
|
||||
}> = (props) => {
|
||||
return (
|
||||
<div
|
||||
class="flex flex-col"
|
||||
class="flex flex-col gap-1"
|
||||
classList={{
|
||||
"items-end": !props.center,
|
||||
"items-center": props.center
|
||||
}}
|
||||
>
|
||||
<Amount
|
||||
amountSats={Number(props.amount)}
|
||||
align="right"
|
||||
icon={props.positive ? "plus" : undefined}
|
||||
showFiat
|
||||
green={props.positive ? true : false}
|
||||
/>
|
||||
<div
|
||||
class="justify-end"
|
||||
classList={{ "text-m-green": props.positive }}
|
||||
>
|
||||
<AmountSats
|
||||
amountSats={Number(props.amount)}
|
||||
icon={props.positive ? "plus" : undefined}
|
||||
/>
|
||||
</div>
|
||||
<div class="text-sm text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={Number(props.amount)}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,114 +12,84 @@ function prettyPrintAmount(n?: number | bigint): string {
|
||||
return n.toLocaleString();
|
||||
}
|
||||
|
||||
export function Amount(props: {
|
||||
export function AmountSats(props: {
|
||||
amountSats: bigint | number | undefined;
|
||||
showFiat?: boolean;
|
||||
loading?: boolean;
|
||||
whiteBg?: boolean;
|
||||
align?: "left" | "center" | "right";
|
||||
icon?: "lightning" | "chain" | "plus" | "minus";
|
||||
size?: "small" | "large" | "xl";
|
||||
green?: boolean;
|
||||
denominationSize?: "sm" | "lg" | "xl";
|
||||
}) {
|
||||
const [state, _] = useMegaStore();
|
||||
const i18n = useI18n();
|
||||
return (
|
||||
<div class="flex gap-2 items-center">
|
||||
<Show when={props.icon === "lightning"}>
|
||||
<img src={bolt} alt="lightning" class="h-[18px]" />
|
||||
</Show>
|
||||
<Show when={props.icon === "chain"}>
|
||||
<img src={chain} alt="chain" class="h-[18px]" />
|
||||
</Show>
|
||||
<h1 class="font-light text-right">
|
||||
<Show when={props.icon === "plus"}>
|
||||
<span>+</span>
|
||||
</Show>
|
||||
<Show when={props.icon === "minus"}>
|
||||
<span>-</span>
|
||||
</Show>
|
||||
{props.loading ? "..." : prettyPrintAmount(props.amountSats)}
|
||||
|
||||
<span
|
||||
class="font-light text-base"
|
||||
classList={{
|
||||
"text-sm": props.denominationSize === "sm",
|
||||
"text-lg": props.denominationSize === "lg",
|
||||
"text-xl": props.denominationSize === "xl"
|
||||
}}
|
||||
>
|
||||
<Show
|
||||
when={
|
||||
!props.amountSats ||
|
||||
Number(props.amountSats) > 1 ||
|
||||
Number(props.amountSats) === 0
|
||||
}
|
||||
>
|
||||
{i18n.t("common.sats")}
|
||||
</Show>
|
||||
<Show
|
||||
when={
|
||||
props.amountSats && Number(props.amountSats) === 1
|
||||
}
|
||||
>
|
||||
{i18n.t("common.sat")}
|
||||
</Show>
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function AmountFiat(props: {
|
||||
amountSats: bigint | number | undefined;
|
||||
loading?: boolean;
|
||||
denominationSize?: "sm" | "lg" | "xl";
|
||||
}) {
|
||||
const i18n = useI18n()
|
||||
const [state, _] = useMegaStore();
|
||||
|
||||
const amountInUsd = () =>
|
||||
satsToUsd(state.price, Number(props.amountSats) || 0, true);
|
||||
|
||||
return (
|
||||
<div
|
||||
class="flex flex-col gap-1"
|
||||
classList={{
|
||||
"items-start": props.align === "left",
|
||||
"items-center": props.align === "center",
|
||||
"items-end": props.align === "right"
|
||||
}}
|
||||
>
|
||||
<div class="flex gap-2 items-center">
|
||||
<Show when={props.icon === "lightning"}>
|
||||
<img src={bolt} alt="lightning" class="h-[18px]" />
|
||||
</Show>
|
||||
<Show when={props.icon === "chain"}>
|
||||
<img src={chain} alt="chain" class="h-[18px]" />
|
||||
</Show>
|
||||
<h1
|
||||
class="font-light text-right"
|
||||
classList={{
|
||||
"text-black": props.whiteBg,
|
||||
"text-sm": props.size === "small",
|
||||
"text-xl": props.size === "large",
|
||||
"text-2xl": props.size === "xl",
|
||||
"text-m-green": props.green
|
||||
}}
|
||||
>
|
||||
<Show when={props.icon === "plus"}>
|
||||
<span>+</span>
|
||||
</Show>
|
||||
<Show when={props.icon === "minus"}>
|
||||
<span>-</span>
|
||||
</Show>
|
||||
{props.loading
|
||||
? "..."
|
||||
: prettyPrintAmount(props.amountSats)}
|
||||
|
||||
<span
|
||||
class="font-light text-base"
|
||||
classList={{
|
||||
"text-sm": props.size === "small",
|
||||
"text-lg": props.size === "xl"
|
||||
}}
|
||||
>
|
||||
<Show
|
||||
when={
|
||||
!props.amountSats ||
|
||||
Number(props.amountSats) > 1 ||
|
||||
Number(props.amountSats) === 0
|
||||
}
|
||||
>
|
||||
{i18n.t("common.sats")}
|
||||
</Show>
|
||||
<Show
|
||||
when={
|
||||
props.amountSats &&
|
||||
Number(props.amountSats) === 1
|
||||
}
|
||||
>
|
||||
{i18n.t("common.sat")}
|
||||
</Show>
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
<Show when={props.showFiat}>
|
||||
<h2
|
||||
class="font-light text-white/70"
|
||||
classList={{
|
||||
"text-black": props.whiteBg,
|
||||
"text-white/70": !props.whiteBg,
|
||||
"text-sm": !props.size,
|
||||
"text-xs": props.size === "small",
|
||||
"text-base": props.size === "large",
|
||||
"text-lg": props.size === "xl"
|
||||
}}
|
||||
>
|
||||
~
|
||||
<Show when={props.size === "xl"}>
|
||||
<span> </span>
|
||||
</Show>
|
||||
{props.loading ? "..." : amountInUsd()}
|
||||
<span
|
||||
class="text-sm"
|
||||
classList={{
|
||||
"text-xs": props.size === "small",
|
||||
"text-base": props.size === "large"
|
||||
}}
|
||||
>
|
||||
{i18n.t("common.usd")}
|
||||
</span>
|
||||
</h2>
|
||||
</Show>
|
||||
</div>
|
||||
<h2 class="font-light">
|
||||
~{props.loading ? "..." : amountInUsd()}
|
||||
<span
|
||||
classList={{
|
||||
"text-sm": props.denominationSize === "sm",
|
||||
"text-lg": props.denominationSize === "lg",
|
||||
"text-xl": props.denominationSize === "xl"
|
||||
}}
|
||||
>
|
||||
{i18n.t("common.usd")}
|
||||
</span>
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,8 +102,8 @@ export function AmountSmall(props: {
|
||||
{prettyPrintAmount(props.amountSats)}
|
||||
<span class="text-sm">
|
||||
{props.amountSats === 1 || props.amountSats === 1n
|
||||
? `${i18n.t("common.sat")}`
|
||||
: `${i18n.t("common.sats")}`}
|
||||
? i18n.t("common.sat")
|
||||
: i18n.t("common.sats")}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { satsToUsd } from "~/utils/conversions";
|
||||
|
||||
export function AmountFiat(props: {
|
||||
amountSats: bigint | number | undefined;
|
||||
loading?: boolean;
|
||||
classes?: string;
|
||||
}) {
|
||||
const [state, _] = useMegaStore();
|
||||
|
||||
const amountInUsd = () =>
|
||||
satsToUsd(state.price, Number(props.amountSats) || 0, true);
|
||||
|
||||
return (
|
||||
<div class={`flex flex-col gap-1 ${props.classes}`}>
|
||||
<h2 class="font-light text-white/70">
|
||||
~{props.loading ? "..." : amountInUsd()}
|
||||
<span> USD</span>
|
||||
</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Show } from "solid-js";
|
||||
import { Button, FancyCard, Indicator } from "~/components/layout";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Amount } from "./Amount";
|
||||
import { AmountSats, AmountFiat } from "./Amount";
|
||||
import { A, useNavigate } from "solid-start";
|
||||
import shuffle from "~/assets/icons/shuffle.svg";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
@@ -43,22 +43,40 @@ export default function BalanceBox(props: { loading?: boolean }) {
|
||||
<>
|
||||
<FancyCard>
|
||||
<Show when={!props.loading} fallback={<LoadingShimmer />}>
|
||||
<Amount
|
||||
amountSats={state.balance?.lightning || 0}
|
||||
showFiat
|
||||
icon="lightning"
|
||||
size="xl"
|
||||
/>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-2xl">
|
||||
<AmountSats
|
||||
amountSats={state.balance?.lightning || 0}
|
||||
icon="lightning"
|
||||
denominationSize="lg"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-lg text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={state.balance?.lightning || 0}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
<hr class="my-2 border-m-grey-750" />
|
||||
<Show when={!props.loading} fallback={<LoadingShimmer />}>
|
||||
<div class="flex justify-between">
|
||||
<Amount
|
||||
amountSats={totalOnchain()}
|
||||
showFiat
|
||||
icon="chain"
|
||||
size="xl"
|
||||
/>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-2xl">
|
||||
<AmountSats
|
||||
amountSats={totalOnchain()}
|
||||
icon="chain"
|
||||
denominationSize="lg"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-lg text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={totalOnchain()}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end gap-1 justify-between">
|
||||
<Show when={state.balance?.unconfirmed != 0n}>
|
||||
<Indicator>Pending</Indicator>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Match, Show, Switch } from "solid-js";
|
||||
import { QRCodeSVG } from "solid-qr-code";
|
||||
import { ReceiveFlavor } from "~/routes/Receive";
|
||||
import { useCopy } from "~/utils/useCopy";
|
||||
import { Amount } from "./Amount";
|
||||
import { AmountSats, AmountFiat } from "./Amount";
|
||||
import { TruncateMiddle } from "./ShareCard";
|
||||
import copyBlack from "~/assets/icons/copy-black.svg";
|
||||
import shareBlack from "~/assets/icons/share-black.svg";
|
||||
@@ -76,11 +76,14 @@ export function IntegratedQr(props: {
|
||||
}}
|
||||
>
|
||||
<Show when={props.kind !== "onchain"}>
|
||||
<Amount
|
||||
amountSats={Number(props.amountSats)}
|
||||
showFiat
|
||||
whiteBg
|
||||
/>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="text-black">
|
||||
<AmountSats amountSats={Number(props.amountSats)} />
|
||||
</div>
|
||||
<div class="text-black text-sm">
|
||||
<AmountFiat amountSats={Number(props.amountSats)} />
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
<KindIndicator kind={props.kind} />
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@ import NavBar from "~/components/NavBar";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { objectToSearchParams } from "~/utils/objectToSearchParams";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Amount, AmountSmall } from "~/components/Amount";
|
||||
import { AmountSats, AmountFiat, AmountSmall } from "~/components/Amount";
|
||||
import { BackLink } from "~/components/layout/BackLink";
|
||||
import { TagEditor } from "~/components/TagEditor";
|
||||
import { StyledRadioGroup } from "~/components/layout/Radio";
|
||||
@@ -453,18 +453,32 @@ export default function Receive() {
|
||||
? i18n.t("receive.payment_received")
|
||||
: i18n.t("receive.payment_initiated")}
|
||||
</h1>
|
||||
<Amount
|
||||
amountSats={
|
||||
receiveState() === "paid" &&
|
||||
paidState() === "lightning_paid"
|
||||
? paymentInvoice()?.amount_sats
|
||||
: paymentTx()?.received
|
||||
}
|
||||
showFiat
|
||||
align="center"
|
||||
size="large"
|
||||
icon="plus"
|
||||
/>
|
||||
<div class="flex flex-col gap-1 items-center">
|
||||
<div class="text-xl">
|
||||
<AmountSats
|
||||
amountSats={
|
||||
receiveState() === "paid" &&
|
||||
paidState() === "lightning_paid"
|
||||
? paymentInvoice()
|
||||
?.amount_sats
|
||||
: paymentTx()?.received
|
||||
}
|
||||
icon="plus"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={
|
||||
receiveState() === "paid" &&
|
||||
paidState() === "lightning_paid"
|
||||
? paymentInvoice()
|
||||
?.amount_sats
|
||||
: paymentTx()?.received
|
||||
}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="w-16 bg-m-grey-400" />
|
||||
<Show
|
||||
when={
|
||||
@@ -477,12 +491,19 @@ export default function Receive() {
|
||||
{i18n.t("common.fee")}
|
||||
</p>
|
||||
<div class="flex items-start gap-1">
|
||||
<Amount
|
||||
amountSats={lspFee()}
|
||||
align="right"
|
||||
size="small"
|
||||
showFiat
|
||||
/>
|
||||
<div class="flex flex-col gap-1 items-end">
|
||||
<div class="text-right text-sm">
|
||||
<AmountSats
|
||||
amountSats={lspFee()}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-xs text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={lspFee()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start py-[1px]">
|
||||
{/*TODO: Add different fee hints insode of <FeesModal />*/}
|
||||
<FeesModal icon />
|
||||
|
||||
@@ -41,7 +41,7 @@ import { Button } from "~/components/layout/Button";
|
||||
import { ProgressBar } from "~/components/layout/ProgressBar";
|
||||
import { MutinyChannel } from "@mutinywallet/mutiny-wasm";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import { Amount } from "~/components/Amount";
|
||||
import { AmountSats } from "~/components/Amount";
|
||||
import { getRedshifted, setRedshifted } from "~/utils/fakeLabels";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
|
||||
@@ -165,17 +165,17 @@ function RedshiftReport(props: { redshift: RedshiftResult; utxo: UtxoItem }) {
|
||||
</Show>
|
||||
</KV> */}
|
||||
<KV key="Starting amount">
|
||||
<Amount
|
||||
<AmountSats
|
||||
amountSats={redshiftResource()!.amount_sats}
|
||||
/>
|
||||
</KV>
|
||||
<KV key="Fees paid">
|
||||
<Amount
|
||||
<AmountSats
|
||||
amountSats={redshiftResource()!.fees_paid}
|
||||
/>
|
||||
</KV>
|
||||
<KV key="Change">
|
||||
<Amount
|
||||
<AmountSats
|
||||
amountSats={redshiftResource()!.change_amt}
|
||||
/>
|
||||
</KV>
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
createSignal,
|
||||
onMount
|
||||
} from "solid-js";
|
||||
import { Amount } from "~/components/Amount";
|
||||
import { AmountSats, AmountFiat } from "~/components/Amount";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
Button,
|
||||
@@ -610,27 +610,45 @@ export default function Send() {
|
||||
? "Payment Initiated"
|
||||
: sentDetails()?.failure_reason}
|
||||
</h1>
|
||||
<Amount
|
||||
amountSats={sentDetails()?.amount}
|
||||
showFiat
|
||||
align="center"
|
||||
size="large"
|
||||
icon="minus"
|
||||
/>
|
||||
<div class="flex flex-col gap-1 items-center">
|
||||
<div class="text-xl">
|
||||
<AmountSats
|
||||
amountSats={sentDetails()?.amount}
|
||||
icon="minus"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={sentDetails()?.amount}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="w-16 bg-m-grey-400" />
|
||||
<div class="flex flex-row items-start gap-3">
|
||||
<p class="text-m-grey-400 text-sm leading-[17px] text-center">
|
||||
{i18n.t("common.fee")}
|
||||
</p>
|
||||
<div class="flex items-start gap-1">
|
||||
<Amount
|
||||
amountSats={
|
||||
sentDetails()?.fee_estimate
|
||||
}
|
||||
align="right"
|
||||
size="small"
|
||||
showFiat
|
||||
/>
|
||||
<div class="flex flex-col gap-1 items-end">
|
||||
<div class="text-right text-sm">
|
||||
<AmountSats
|
||||
amountSats={
|
||||
sentDetails()
|
||||
?.fee_estimate
|
||||
}
|
||||
denominationSize="sm"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-xs text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={
|
||||
sentDetails()
|
||||
?.fee_estimate
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start py-[1px]">
|
||||
<FeesModal icon />
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@ import { SuccessModal } from "~/components/successfail/SuccessModal";
|
||||
import { ExternalLink } from "~/components/layout/ExternalLink";
|
||||
import { Network } from "~/logic/mutinyWalletSetup";
|
||||
import { useI18n } from "~/i18n/context";
|
||||
import { AmountFiat } from "~/components/AmountFiat";
|
||||
import { AmountFiat } from "~/components/Amount";
|
||||
|
||||
const CHANNEL_FEE_ESTIMATE_ADDRESS =
|
||||
"bc1qf7546vg73ddsjznzq57z3e8jdn6gtw6au576j07kt6d9j7nz8mzsyn6lgf";
|
||||
@@ -305,13 +305,14 @@ export default function Swap() {
|
||||
"0"}{" "}
|
||||
{i18n.t("swap.sats_added")}
|
||||
</p>
|
||||
<AmountFiat
|
||||
amountSats={
|
||||
channelOpenResult()?.channel
|
||||
?.balance
|
||||
}
|
||||
classes="text-sm text-center"
|
||||
/>
|
||||
<div class="text-sm text-center text-white/70">
|
||||
<AmountFiat
|
||||
amountSats={
|
||||
channelOpenResult()?.channel
|
||||
?.balance
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="w-16 bg-m-grey-400" />
|
||||
<Show
|
||||
|
||||
Reference in New Issue
Block a user