diff options
| author | Adam Soltys <[email protected]> | 2025-01-15 15:37:19 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2025-01-15 15:37:19 -0800 |
| commit | 0a69cf4077363c56e6e5e1b8c8857c2d25e3986a (patch) | |
| tree | 70648825da0e86cdb76decf44023b71a696b3b36 /src | |
| parent | 97f9c4f245fb90df5c8048ac5a9e62208e37c484 (diff) | |
| download | coinos-ui-0a69cf4077363c56e6e5e1b8c8857c2d25e3986a.tar.gz coinos-ui-0a69cf4077363c56e6e5e1b8c8857c2d25e3986a.zip | |
invoice type selection
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/InvoiceActions.svelte | 84 | ||||
| -rw-r--r-- | src/components/InvoiceTypes.svelte | 185 | ||||
| -rw-r--r-- | src/components/SetType.svelte | 37 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/receive/+page.svelte | 30 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/+page.svelte | 34 |
5 files changed, 274 insertions, 96 deletions
diff --git a/src/components/InvoiceActions.svelte b/src/components/InvoiceActions.svelte index c0f8f572..0f500fe6 100644 --- a/src/components/InvoiceActions.svelte +++ b/src/components/InvoiceActions.svelte @@ -1,4 +1,6 @@ <script> + import { goto } from "$app/navigation"; + import InvoiceTypes from "$comp/InvoiceTypes.svelte"; let { user, invoice, @@ -8,39 +10,72 @@ type, showQr = $bindable(), txt, + setAmount, + newAmount = $bindable(), + toggleType, toggleAmount, + setType, toggleMemo, } = $props(); </script> <div class="text-secondary space-y-2 text-xl pt-2"> - <button type="button" class="btn" onclick={() => copy(txt)}> - <iconify-icon noobserver icon="ph:copy-bold" width="32"></iconify-icon> - <div class="my-auto"> - {t("payments.copy")} - </div> - </button> + <InvoiceTypes + {invoice} + {user} + {toggleType} + bind:newAmount + {setAmount} + {setType} + t={$t} + activeOnly={true} + /> + + <div class="flex flex-wrap gap-2 justify-around text-secondary w-full"> + <button type="button" class="btn !w-auto grow" onclick={() => copy(txt)}> + <iconify-icon noobserver icon="ph:copy-bold" width="32"></iconify-icon> + <div class="my-auto"> + {t("payments.copy")} + </div> + </button> - {#if user?.id === invoice?.user?.id} - <button class="btn" onclick={toggleAmount}> - <iconify-icon noobserver icon="ph:pencil-simple-bold" width="32"></iconify-icon> - <div class="my-auto">{t("payments.setAmount")}</div> + <button class="btn grow !w-auto" onclick={() => goto("/receive")}> + <iconify-icon noobserver icon="ph:clipboard-text-bold" width="32" + ></iconify-icon> + <div class="my-auto text-lg">{t("user.send.paste")}</div> </button> - {:else} - <a href={link} class="block"> - <button class="btn"> - <iconify-icon noobserver icon="ph:wallet-bold" width="32"></iconify-icon> - <div class="my-auto">{t("payments.openLink")}</div> + + <button class="btn grow !w-auto" onclick={() => goto("/scan")}> + <iconify-icon noobserver icon="ph:camera-bold" width="32"></iconify-icon> + <div class="my-auto text-lg">{t("user.send.scan")}</div> + </button> + </div> + + <div class="flex flex-wrap gap-2 justify-around text-secondary w-full"> + {#if user?.id === invoice?.user?.id} + <button class="btn grow !w-auto" onclick={toggleAmount}> + <iconify-icon noobserver icon="ph:pencil-simple-bold" width="32" + ></iconify-icon> + <div class="my-auto">{t("payments.setAmount")}</div> </button> - </a> - {/if} + {:else} + <a href={link} class="block"> + <button class="btn grow !w-auto"> + <iconify-icon noobserver icon="ph:wallet-bold" width="32" + ></iconify-icon> + <div class="my-auto">{t("payments.openLink")}</div> + </button> + </a> + {/if} - <button class="btn" onclick={toggleMemo}> - <iconify-icon noobserver icon="ph:chat-centered-text-bold" width="32"></iconify-icon> - <div class="my-auto"> - {t("invoice.setMemo")} - </div> - </button> + <button class="btn grow !w-auto" onclick={toggleMemo}> + <iconify-icon noobserver icon="ph:chat-centered-text-bold" width="32" + ></iconify-icon> + <div class="my-auto"> + {t("invoice.setMemo")} + </div> + </button> + </div> {#if txt.length > 120} <div class="w-full flex justify-center gap-2 flex-wrap"> @@ -49,7 +84,8 @@ <iconify-icon noobserver icon="ph:text-align-center-bold" width="32" ></iconify-icon> {:else} - <iconify-icon noobserver icon="ph:qr-code-bold" width="32"></iconify-icon> + <iconify-icon noobserver icon="ph:qr-code-bold" width="32" + ></iconify-icon> {/if} <div class="my-auto"> {showQr ? t("payments.showText") : t("payments.showQr")} diff --git a/src/components/InvoiceTypes.svelte b/src/components/InvoiceTypes.svelte index c4d7fa77..0829fc82 100644 --- a/src/components/InvoiceTypes.svelte +++ b/src/components/InvoiceTypes.svelte @@ -1,79 +1,133 @@ <script> import { types } from "$lib/utils"; - import { goto } from "$app/navigation"; import { page } from "$app/stores"; - let { aid, invoice, user, type, t, setType } = $props(); + import { amountPrompt } from "$lib/store"; + let { + newAmount = $bindable(), + invoice, + user, + t, + toggleType, + setAmount, + setType, + activeOnly, + } = $props(); + + let { aid, address_type, type } = $derived(invoice); </script> {#if invoice.uid === aid} - <div class="grid grid-cols-2 gap-2 justify-around text-secondary"> - <button - class="btn flex-nowrap" - class:bg-base-300={type === types.lightning} - class:text-secondary={type === types.lightning} - onclick={() => setType(types.lightning)} - > - <div - class="bg-black rounded-full w-8 h-8 items-center justify-center flex" - > - <div class="m-auto"> - <iconify-icon - noobserver - icon="ph:lightning-fill" - class="text-yellow-300 text-2xl" - ></iconify-icon> - </div> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.lightning && + $page.url.pathname.includes("/receive")} + class:text-secondary={type === types.lightning && + $page.url.pathname.includes("/receive")} + class:hidden={activeOnly && + (type !== types.lightning || !$page.url.pathname.includes("/receive"))} + onclick={() => { + if (activeOnly) toggleType(); + else { + $amountPrompt = false; + newAmount = undefined; + setType(types.lightning); + } + }} + > + <div class="bg-black rounded-full w-8 h-8 items-center justify-center flex"> + <div class="m-auto"> + <iconify-icon + noobserver + icon="ph:lightning-fill" + class="text-yellow-300 text-2xl" + ></iconify-icon> </div> - <div class="my-auto text-lg">Lightning</div> - </button> + </div> + <div class="my-auto text-lg">LNURL</div> + </button> - <button - class="btn flex-nowrap" - class:bg-base-300={type === types.ecash} - class:text-secondary={type === types.ecash} - onclick={() => setType(types.ecash)} - > - <img src="/images/cash.png" class="w-8 my-auto" /> - <div class="my-auto text-lg">Ecash</div> - </button> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.ecash} + class:text-secondary={type === types.ecash} + class:hidden={activeOnly && type !== types.ecash} + onclick={() => (activeOnly ? toggleType() : setType(types.ecash))} + > + <img src="/images/cash.png" class="w-8 my-auto" /> + <div class="my-auto text-lg">Ecash</div> + </button> - <button - class="btn flex-nowrap" - class:bg-base-300={type === types.bitcoin} - class:text-secondary={type === types.bitcoin} - onclick={() => setType(types.bitcoin)} - > - <img src="/images/bitcoin.svg" class="w-8" alt="Bitcoin" /> - <div class="my-auto text-lg">Bitcoin</div> - </button> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.bitcoin && address_type === "bech32"} + class:text-secondary={type === types.bitcoin && address_type === "bech32"} + class:hidden={activeOnly && + (type !== types.bitcoin || address_type !== "bech32")} + onclick={() => (activeOnly ? toggleType() : setType(types.bitcoin))} + > + <img src="/images/bitcoin.svg" class="w-8" alt="Bitcoin" /> + <div class="my-auto text-lg">Segwit</div> + </button> - <button - class="btn flex-nowrap" - class:bg-base-300={type === types.liquid} - class:text-secondary={type === types.liquid} - onclick={() => setType(types.liquid)} - > - <img src="/images/liquid.svg" class="w-8" alt="Liquid" /> - <div class="my-auto text-lg">Liquid</div> - </button> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.liquid} + class:text-secondary={type === types.liquid} + class:hidden={activeOnly && type !== types.liquid} + onclick={() => (activeOnly ? toggleType() : setType(types.liquid))} + > + <img src="/images/liquid.svg" class="w-8" alt="Liquid" /> + <div class="my-auto text-lg">Liquid</div> + </button> - <button class="btn flex-nowrap" onclick={() => goto("/scan")}> - <iconify-icon noobserver icon="ph:camera-bold" width="32"></iconify-icon> - <div class="my-auto text-lg">{t("user.send.scan")}</div> - </button> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.lightning && + !$page.url.pathname.includes("/receive")} + class:text-secondary={type === types.lightning && + !$page.url.pathname.includes("/receive")} + class:hidden={activeOnly && + (type !== types.lightning || $page.url.pathname.includes("/receive"))} + onclick={() => { + if (activeOnly) toggleType(); + else { + $amountPrompt = false; + newAmount = 0; + setType(types.lightning); + } + }} + > + <div class="bg-black rounded-full w-8 h-8 items-center justify-center flex"> + <div class="m-auto"> + <iconify-icon + noobserver + icon="ph:lightning-fill" + class="text-yellow-300 text-2xl" + ></iconify-icon> + </div> + </div> + <div class="my-auto text-lg">Bolt 11</div> + </button> - <button class="btn flex-nowrap" onclick={() => goto("/receive")}> - <iconify-icon noobserver icon="ph:clipboard-text-bold" width="32" - ></iconify-icon> - <div class="my-auto text-lg">{t("user.send.paste")}</div> - </button> - </div> + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.bitcoin && address_type !== "legacy"} + class:text-secondary={type === types.bitcoin && address_type !== "legacy"} + class:hidden={activeOnly && + (type !== types.bitcoin || address_type !== "legacy")} + onclick={() => + activeOnly ? toggleType() : setType(types.bitcoin, "legacy")} + > + <img src="/images/bitcoin.svg" class="w-8" alt="Bitcoin" /> + <div class="my-auto text-lg">Legacy</div> + </button> <button class="btn flex-nowrap" class:bg-base-300={type === types.bolt12} class:text-secondary={type === types.bolt12} - onclick={() => setType(types.bolt12)} + class:hidden={activeOnly && type !== types.bolt12} + onclick={() => (activeOnly ? toggleType() : setType(types.bolt12))} > <div class="bg-black rounded-full w-8 h-8 items-center justify-center flex"> <div class="m-auto"> @@ -86,4 +140,17 @@ </div> <div class="my-auto text-lg">Bolt 12</div> </button> + + <button + class="btn flex-nowrap" + class:bg-base-300={type === types.bitcoin} + class:text-secondary={type === types.bitcoin} + class:hidden={activeOnly && + (type !== types.bitcoin || address_type !== "bech32m")} + onclick={() => + activeOnly ? toggleType() : setType(types.bitcoin, "bech32m")} + > + <img src="/images/bitcoin.svg" class="w-8" alt="Bitcoin" /> + <div class="my-auto text-lg">Taproot</div> + </button> {/if} diff --git a/src/components/SetType.svelte b/src/components/SetType.svelte new file mode 100644 index 00000000..7e80d0bc --- /dev/null +++ b/src/components/SetType.svelte @@ -0,0 +1,37 @@ +<script> + import InvoiceTypes from "$comp/InvoiceTypes.svelte"; + import { focus } from "$lib/utils"; + + let { + newAmount = $bindable(), + invoice, + user, + submit = $bindable(), + settingType, + setAmount, + setType, + toggleType, + t, + } = $props(); + + let { aid, type } = $derived(invoice); +</script> + +{#if settingType} + <div + class="fixed inset-0 bg-base-100 bg-opacity-90 overflow-y-auto h-full w-full z-50" + > + <div + class="relative mx-auto p-12 max-w-xl shadow-lg rounded-md bg-base-100 space-y-2" + > + <InvoiceTypes + bind:newAmount + {setAmount} + {invoice} + {user} + {setType} + t={$t} + /> + </div> + </div> +{/if} diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte index e02d6651..887e9680 100644 --- a/src/routes/(app)/[username]/receive/+page.svelte +++ b/src/routes/(app)/[username]/receive/+page.svelte @@ -22,6 +22,7 @@ import InvoiceTypes from "$comp/InvoiceTypes.svelte"; import SetAmount from "$comp/SetAmount.svelte"; import SetMemo from "$comp/SetMemo.svelte"; + import SetType from "$comp/SetType.svelte"; import { t } from "$lib/translations"; import { goto, invalidate } from "$app/navigation"; import { page } from "$app/stores"; @@ -68,20 +69,24 @@ } }; + let settingType = $state(); + let toggleType = () => (settingType = !settingType); let setType = async (type, address_type) => { $showQr = true; - if (type === types.lightning && !amount) + if (type === types.lightning && !amount && typeof newAmount === "undefined") goto(`/${username}/receive`, { invalidateAll: true, noScroll: true }); else { + if (typeof newAmount !== "undefined") invoice.amount = newAmount; invoice.address_type = address_type; invoice.type = type; await update(); } + settingType = false; }; let setAmount = async (e) => { - e.preventDefault(); - e.stopPropagation(); + e?.preventDefault(); + e?.stopPropagation(); settingAmount = false; @@ -142,6 +147,10 @@ /> <InvoiceActions + bind:newAmount + {setAmount} + {toggleType} + {setType} {toggleAmount} {toggleMemo} {user} @@ -153,8 +162,6 @@ {txt} t={$t} /> - - <InvoiceTypes {aid} {invoice} {user} {type} {setType} t={$t} /> </div> <SetAmount @@ -170,3 +177,16 @@ /> <SetMemo bind:memo {settingMemo} {setMemo} {toggleMemo} t={$t} /> + +<SetType + {aid} + {invoice} + {user} + {type} + {settingType} + {setType} + {toggleType} + t={$t} + bind:newAmount + {setAmount} +/> diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte index fdb180ef..4c5c3b50 100644 --- a/src/routes/(app)/invoice/[id]/+page.svelte +++ b/src/routes/(app)/invoice/[id]/+page.svelte @@ -20,9 +20,9 @@ import Avatar from "$comp/Avatar.svelte"; import InvoiceData from "$comp/InvoiceData.svelte"; import InvoiceActions from "$comp/InvoiceActions.svelte"; - import InvoiceTypes from "$comp/InvoiceTypes.svelte"; import SetAmount from "$comp/SetAmount.svelte"; import SetMemo from "$comp/SetMemo.svelte"; + import SetType from "$comp/SetType.svelte"; import { t } from "$lib/translations"; import { goto, invalidate } from "$app/navigation"; @@ -85,23 +85,28 @@ } }; - let setType = async (type) => { + let settingType = $state(); + let toggleType = () => (settingType = !settingType); + let setType = async (type, address_type) => { $showQr = true; - if (type === types.lightning && !amount) + if (type === types.lightning && !amount && typeof newAmount === "undefined") goto(`/${username}/receive`, { invalidateAll: true, noScroll: true }); else { + if (typeof newAmount !== "undefined") invoice.amount = newAmount; + invoice.address_type = address_type; invoice.type = type; await update(); } + settingType = false; }; let newAmount = $state(0); let settingAmount = $state(); - let toggleAmount = $state(() => (settingAmount = !settingAmount)); + let toggleAmount = () => (settingAmount = !settingAmount); let setAmount = async (e) => { - e.preventDefault(); - e.stopPropagation(); + e?.preventDefault(); + e?.stopPropagation(); settingAmount = false; @@ -153,6 +158,9 @@ /> <InvoiceActions + bind:newAmount + {setAmount} + {toggleType} {toggleAmount} {toggleMemo} {user} @@ -164,8 +172,6 @@ t={$t} bind:showQr={$showQr} /> - - <InvoiceTypes {aid} {invoice} {user} {type} {setType} t={$t} /> </div> <SetAmount @@ -182,3 +188,15 @@ /> <SetMemo bind:memo {settingMemo} {setMemo} {toggleMemo} t={$t} /> + +<SetType + bind:newAmount + {setAmount} + {invoice} + {user} + {type} + {settingType} + {setType} + {toggleType} + t={$t} +/> |
