diff options
| author | Adam Soltys <[email protected]> | 2024-11-14 13:32:52 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-14 16:09:51 -0800 |
| commit | 0f35462ebdde3701e8fe927b3debace9abf79305 (patch) | |
| tree | 786d8c833e16762b87a193fb4c09d634784f7744 /src | |
| parent | 614fbd99b7963ec89666b8b4252fa5f73c81653c (diff) | |
| download | coinos-ui-0f35462ebdde3701e8fe927b3debace9abf79305.tar.gz coinos-ui-0f35462ebdde3701e8fe927b3debace9abf79305.zip | |
payment amount helpers
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/InvoiceTypes.svelte | 4 | ||||
| -rw-r--r-- | src/components/Success.svelte | 59 | ||||
| -rw-r--r-- | src/lib/invoice.ts | 1 | ||||
| -rw-r--r-- | src/lib/socket.ts | 17 | ||||
| -rw-r--r-- | src/routes/(app)/+layout.svelte | 10 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/+page.svelte | 8 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/receive/+page.svelte | 2 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/[email protected] | 27 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/paid/+page.svelte | 74 | ||||
| -rw-r--r-- | src/routes/(app)/payment/[id]/+page.svelte | 40 | ||||
| -rw-r--r-- | src/routes/(app)/payments/[...page]/+page.svelte | 33 | ||||
| -rw-r--r-- | src/routes/(app)/send/lightning/[payreq]/+page.svelte | 25 | ||||
| -rw-r--r-- | src/routes/(app)/sent/[id]/+page.svelte | 18 | ||||
| -rw-r--r-- | src/routes/(app)/settings/preferences/+page.svelte | 6 | ||||
| -rw-r--r-- | src/routes/(static)/login/+page.server.ts | 1 |
15 files changed, 127 insertions, 198 deletions
diff --git a/src/components/InvoiceTypes.svelte b/src/components/InvoiceTypes.svelte index 4dae235a..4e1e5b20 100644 --- a/src/components/InvoiceTypes.svelte +++ b/src/components/InvoiceTypes.svelte @@ -30,9 +30,9 @@ class:text-secondary={type === types.lightning} onclick={() => setType(types.lightning)} > - <div class="bg-base-100 rounded-full w-8 h-8 text-center flex"> + <div class="bg-base-100 rounded-full w-8 h-8 items-center justify-center flex"> <div class="m-auto"> - <iconify-icon icon="ph:lightning-fill" class="text-yellow-300" + <iconify-icon icon="ph:lightning-fill" class="text-yellow-300 text-3xl" ></iconify-icon> </div> </div> diff --git a/src/components/Success.svelte b/src/components/Success.svelte new file mode 100644 index 00000000..f82a4dcb --- /dev/null +++ b/src/components/Success.svelte @@ -0,0 +1,59 @@ +<script> + import { browser } from "$app/environment"; + import { scale } from "svelte/transition"; + import Amount from "$comp/Amount.svelte"; + import { Confetti } from "svelte-confetti"; + const { amount, tip, rate, currency, title } = $props(); + + let loaded = $state(false); + $effect(() => { + if (browser) + window.requestAnimationFrame((p) => { + loaded = true; + }); + }); +</script> + +<div class="text-center mt-20 md:mt-0"> + {#if loaded} + <div class="relative flex justify-center"> + <div class="absolute top-64 pointer-events-none"> + <Confetti + amount="20" + size="40" + duration="1600" + delay={[0, 500]} + fallDistance="50px" + colorArray={["url(/images/bolt.svg)"]} + /> + <Confetti + amount="40" + delay={[0, 500]} + size="15" + fallDistance="50px" + duration="1600" + colorArray={[ + "#FFD700", // Gold + "#FF6F61", // Coral + "#6BCB77", // Mint green + "#4D96FF", // Light blue + "#FF9CEE", // Light pink + "#FFD580", // Soft orange + "#87CEEB", // Sky blue + "#FFB6C1", // Light coral pink + "#C1C7FF", // Lavender + ]} + /> + </div> + </div> + + <iconify-icon + icon="ph:check-fat-fill" + class="text-green-400" + width="160" + in:scale={{ start: 0.2, duration: 500 }} + /> + {/if} + <h1 class="text-3xl md:text-4xl font-bold mb-6">{title}</h1> + <Amount {amount} {tip} {rate} {currency} /> +</div> diff --git a/src/lib/invoice.ts b/src/lib/invoice.ts index a48e02a4..9563d924 100644 --- a/src/lib/invoice.ts +++ b/src/lib/invoice.ts @@ -2,6 +2,7 @@ import { auth, get, post } from "$lib/utils"; import { redirect } from "@sveltejs/kit"; export default async ({ cookies, request }) => { + console.log("LOADING"); const form = await request.formData(); const aid = form.get("aid") || cookies.get("aid"); diff --git a/src/lib/socket.ts b/src/lib/socket.ts index 02d441bf..566e989d 100644 --- a/src/lib/socket.ts +++ b/src/lib/socket.ts @@ -1,8 +1,8 @@ -import { invalidate } from "$app/navigation"; -import { navigating } from "$app/stores"; +import { goto, invalidate } from "$app/navigation"; +import { navigating, page } from "$app/stores"; import { PUBLIC_SOCKET } from "$env/static/public"; import { event, invoice, last, request } from "$lib/store"; -import { sat, sleep, success, wait } from "$lib/utils"; +import { s, sleep, success, wait } from "$lib/utils"; import { get } from "svelte/store"; let socket; @@ -38,13 +38,20 @@ export const messages = (data) => ({ }, async payment() { - const { amount, confirmed } = data; + const { amount, confirmed, iid } = data; invalidate("app:user"); invalidate("app:invoice"); invalidate("app:payments"); + const { + url: { pathname }, + } = get(page); + if (amount > 0) { - success(`${confirmed ? "Received" : "Detected"} ${sat(amount)}!`); + if (pathname.includes("receive")) { + await wait(() => !get(navigating)); + await goto(`/invoice/${iid}`); + } else success(`${confirmed ? "Received" : "Detected"} ⚡️${s(amount)}!`); } }, diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index ba1eb49a..aaaf543f 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -1,6 +1,4 @@ <script> - import { run } from "svelte/legacy"; - import { SvelteToast } from "@zerodevx/svelte-toast"; import { onDestroy, onMount } from "svelte"; import { close, connect, send } from "$lib/socket"; @@ -26,7 +24,7 @@ let { data, children } = $props(); - let { generate, rate, user, subject, token, rates } = $derived(data); + let { user, subject, token } = $derived(data); let { theme } = $state(data); $themeStore = theme; @@ -113,13 +111,9 @@ <SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> -<main class="pb-20 min-h-dvh" data-theme={theme}> +<main class="pb-4 min-h-dvh" data-theme={theme}> <AppHeader {user} {subject} /> {#if !$loading} {@render children?.()} {/if} </main> - -{#if $invoice} - <Invoice {user} /> -{/if} diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte index e956aab7..b3b91405 100644 --- a/src/routes/(app)/[username]/(profile)/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/+page.svelte @@ -1,6 +1,5 @@ <script> - import { run } from 'svelte/legacy'; - + import { scale } from "svelte/transition"; import { btc, f, sat } from "$lib/utils"; import Icon from "$comp/Icon.svelte"; import Account from "$comp/Account.svelte"; @@ -22,11 +21,6 @@ let rate = $derived(rates[currency]); let total = $derived(items.reduce((a, b) => a + b.price * b.quantity, 0)); - let refresh = (d) => ({ accounts, items, subject, user, rates } = d); - run(() => { - refresh(data); - }); - let install = async () => { if (!$installPrompt) return; await $installPrompt.prompt(); diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte index 17cb4f09..be4ed3d0 100644 --- a/src/routes/(app)/[username]/receive/+page.svelte +++ b/src/routes/(app)/[username]/receive/+page.svelte @@ -1,7 +1,5 @@ <script> import { run } from "svelte/legacy"; - - import { send } from "$lib/socket"; import { btc, post, copy, f, get, types, sat, s, sats } from "$lib/utils"; import { tick, onMount, onDestroy } from "svelte"; import { browser } from "$app/environment"; diff --git a/src/routes/(app)/invoice/[id]/[email protected] b/src/routes/(app)/invoice/[id]/[email protected] index 05fd603f..13b121d8 100644 --- a/src/routes/(app)/invoice/[id]/[email protected] +++ b/src/routes/(app)/invoice/[id]/[email protected] @@ -1,6 +1,4 @@ <script> - import { run } from 'svelte/legacy'; - import { SvelteToast } from "@zerodevx/svelte-toast"; import { onDestroy, onMount } from "svelte"; import { close, connect, send } from "$lib/socket"; @@ -26,13 +24,12 @@ let { data, children } = $props(); - let { generate, rate, user, subject, token, rates, theme } = $state(data); - - let update = (data) => { - ({ rate, user, subject, token, rates, theme } = data); - }; + let { user, subject, token } = $derived(data); + let { theme } = $state(data); $themeStore = theme; + $effect(() => (theme = $themeStore)); + $effect(() => browser && connect(token)); onMount(async () => { if (browser) { @@ -58,7 +55,6 @@ } }); - let lost, checkTimer, expireTimer, @@ -83,15 +79,6 @@ clearTimeout(expireTimer); } }); - run(() => { - update(data); - }); - run(() => { - theme = $themeStore; - }); - run(() => { - browser && connect(token); - }); </script> {#if browser && user && $passwordPrompt} @@ -115,13 +102,9 @@ <SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> -<main class="min-h-dvh" data-theme={theme}> +<main class="pb-4 min-h-dvh" data-theme={theme}> <AppHeader {user} {subject} /> {#if !$loading} {@render children?.()} {/if} </main> - -{#if $invoice} - <Invoice {user} /> -{/if} diff --git a/src/routes/(app)/invoice/[id]/paid/+page.svelte b/src/routes/(app)/invoice/[id]/paid/+page.svelte index d6cfaa46..b031dd8c 100644 --- a/src/routes/(app)/invoice/[id]/paid/+page.svelte +++ b/src/routes/(app)/invoice/[id]/paid/+page.svelte @@ -1,70 +1,26 @@ <script> - import { run } from "svelte/legacy"; - - import { scale } from "svelte/transition"; - import Icon from "$comp/Icon.svelte"; - import { toast } from "@zerodevx/svelte-toast"; - import { browser } from "$app/environment"; + import Success from "$comp/Success.svelte"; import { t } from "$lib/translations"; - import { toFiat, f, s, sat, sats } from "$lib/utils"; let { data } = $props(); - let amount, - currency = $state(), - rate = $state(), - received = $state(), - pending = $state(), - tip = $state(), - user = $state(), - id; - let update = (data) => { - ({ amount, currency, rate, received, pending, tip, user, id } = - data.invoice); - }; + let { amount, currency, rate, received, pending, tip, user, id } = $derived( + data.invoice, + ); - toast.pop(0); - run(() => { - update(data); - }); + // toast.pop(0); </script> <div class="container px-4 text-center mx-auto"> - {#if received} - <div - class="flex w-full py-5 max-w-[200px] mx-auto" - in:scale={{ start: 0.5 }} - > - <Icon icon="check" style="mx-auto" /> - </div> - - <h1 class="text-3xl md:text-4xl font-bold mb-6"> - {$t("invoice.paymentSuccessful")} - </h1> - - <h2 class="text-2xl md:text-3xl font-semibold"> - {f(toFiat(received - tip, rate), currency)} - {#if tip} - <span class="text-lg"> - + {f(toFiat(tip, rate), currency)} - </span> - {/if} - </h2> - <h3 class="text-secondary md:text-lg mb-6 mt-1"> - ⚡️{s(received - tip)} - - {#if tip} - <span class="text-lg"> - + ⚡️{s(tip)} - </span> - {/if} - </h3> - {/if} + <Success + amount={received - tip} + {rate} + {tip} + {currency} + title={$t("invoice.paymentSuccessful")} + /> {#if pending} - <div - class="flex w-full py-5 max-w-[200px] mx-auto" - in:scale={{ start: 0.5 }} - > + <div class="flex w-full py-5 max-w-[200px] mx-auto"> <Icon icon="orangeclock" style="mx-auto" /> </div> @@ -88,9 +44,9 @@ </div> <a href={`/${user.username}`}> - <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div> + <div class="opacity-0 w-screen h-screen fixed top-24 left-0 z-50"></div> </a> -<div class="flex justify-center"> +<div class="flex justify-center mt-4"> {$t("payments.tapAnywhere")} </div> diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte index 45dc8642..94226931 100644 --- a/src/routes/(app)/payment/[id]/+page.svelte +++ b/src/routes/(app)/payment/[id]/+page.svelte @@ -25,31 +25,6 @@ let { user, payment: p } = $state(data); let locale = locales[user.language]; - let refresh = (d) => { - ({ user, payment: p } = d); - ({ - id, - hash, - amount, - created, - confirmed, - memo, - rate, - type, - ref, - path, - tip, - ourfee, - fee, - currency, - } = p); - - if (amount > 0) [txid, vout] = ref.split(":"); - else txid = hash; - - if (!fee) fee = 0; - }; - let { username } = user; let { id, @@ -64,9 +39,10 @@ path, tip, ourfee, - fee, + fee = 0, currency, - } = $state(p); + } = $derived(p); + let [txid, vout] = $derived(amount > 0 ? ref.split(":") : [hash]); let a = Math.abs(amount); let expl = { @@ -87,11 +63,6 @@ } }; - let txid = $state(), - vout = $state(); - if (amount > 0) [txid, vout] = ref.split(":"); - else txid = hash; - let direction = $state(""); onMount(() => { direction = amount > 0 ? $t("payments.from") : $t("payments.to"); @@ -100,9 +71,6 @@ direction = direction[0].toUpperCase() + direction.substr(1, direction.length); }); - run(() => { - refresh(data); - }); </script> {#snippet field(title, amount)} @@ -111,7 +79,7 @@ <div class="flex gap-2 items-end"> <div class="flex items-center"> <iconify-icon icon="ph:lightning-fill" class="text-yellow-300" - ></iconify-icon>{amount} + ></iconify-icon>{s(amount)} </div> <span class="text-secondary text-lg"> {f(toFiat(amount, rate), currency)} diff --git a/src/routes/(app)/payments/[...page]/+page.svelte b/src/routes/(app)/payments/[...page]/+page.svelte index d2f9782b..e651ba90 100644 --- a/src/routes/(app)/payments/[...page]/+page.svelte +++ b/src/routes/(app)/payments/[...page]/+page.svelte @@ -214,12 +214,14 @@ class="font-bold flex items-center" class:text-red-800={p.amount < 0} > - <iconify-icon - icon="ph:lightning-fill" - width="24" - class="text-yellow-300" - ></iconify-icon> - {si(Math.abs(p.amount) + (p.tip || 0), 0, 1)} + <div class="flex items-center"> + <iconify-icon + icon="ph:lightning-fill" + width="24" + class="text-yellow-300" + ></iconify-icon> + <div>{si(Math.abs(p.amount), 0, 1)}</div> + </div> {#if p.tip} <span class="text-sm text-secondary"> @@ -256,28 +258,25 @@ </div> </div> {:else} - <div class="text-secondary flex gap-2"> + <div class="text-secondary flex items-center gap-1"> {#if p.type === types.lightning} - <div class="text-3xl"><iconify-icon icon="ph:lightning-fill" class="text-yellow-300" - ></iconify-icon></div> + <iconify-icon + icon="ph:lightning-fill" + class="text-yellow-300 text-3xl" + ></iconify-icon> {:else if p.type === types.ecash} <img src="/images/cash.png" class="w-12" /> {:else if p.type === types.reconcile} <iconify-icon icon="ph:scales-bold" width="32" ></iconify-icon> {:else if p.type === types.bitcoin} - <div class="my-auto"> - <img - src="/images/bitcoin.svg" - class="w-12 border-4 border-transparent" - alt="Bitcoin" - /> - </div> + <iconify-icon icon="logos:bitcoin" class="text-3xl" + ></iconify-icon> {:else if p.type === types.liquid} <div class="my-auto"> <img src="/images/liquid.svg" - class="w-12 border-4 border-transparent" + class="w-10 border-4 border-transparent" alt="Liquid" /> </div> diff --git a/src/routes/(app)/send/lightning/[payreq]/+page.svelte b/src/routes/(app)/send/lightning/[payreq]/+page.svelte index af3e09f4..d8bd5f8c 100644 --- a/src/routes/(app)/send/lightning/[payreq]/+page.svelte +++ b/src/routes/(app)/send/lightning/[payreq]/+page.svelte @@ -1,9 +1,7 @@ <script> - import { run } from "svelte/legacy"; - import { t } from "$lib/translations"; import { enhance } from "$app/forms"; - import Icon from "$comp/Icon.svelte"; + import Amount from "$comp/Amount.svelte"; import Numpad from "$comp/Numpad.svelte"; import Spinner from "$comp/Spinner.svelte"; import { page } from "$app/stores"; @@ -21,15 +19,7 @@ } = $state(data); let a = $state(); - let reload = (data) => { - ({ - alias, - ourfee, - rates, - user: { currency }, - } = data); - if (!$rate) $rate = rates[currency]; - }; + $effect(() => ($rate ||= rates[currency])); let showMax = $state(); @@ -42,17 +32,8 @@ let show; let toggle = () => (show = !show); - run(() => { - reload(data); - }); let amount = $derived(form?.amount || data.amount); - let maxfee; - run(() => { - maxfee = Math.max(5, Math.round(amount * 0.005)); - }); - run(() => { - update(form); - }); + let maxfee = $state(Math.max(5, Math.round(amount * 0.005))); </script> <div class="container px-4 max-w-xl mx-auto text-center space-y-2"> diff --git a/src/routes/(app)/sent/[id]/+page.svelte b/src/routes/(app)/sent/[id]/+page.svelte index f2f14fef..2eb1f18b 100644 --- a/src/routes/(app)/sent/[id]/+page.svelte +++ b/src/routes/(app)/sent/[id]/+page.svelte @@ -1,27 +1,15 @@ <script> - import { f, focus, s, sat, sats } from "$lib/utils"; - import { scale } from "svelte/transition"; - import Amount from "$comp/Amount.svelte"; - import Icon from "$comp/Icon.svelte"; - import { toast } from "@zerodevx/svelte-toast"; + import { focus } from "$lib/utils"; import { t } from "$lib/translations"; + import Success from "$comp/Success.svelte"; let { data } = $props(); let { amount, rate, tip, user } = $state(data); let { currency, username } = user; amount = Math.abs(amount); - - toast.pop(0); </script> -<div class="text-center mt-20 md:mt-0"> - <div class="flex w-full max-w-[200px] mx-auto py-4" in:scale={{ start: 0.5 }}> - <Icon icon="check" style="mx-auto" /> - </div> - <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t("payments.sent")}!</h1> - <Amount {amount} {tip} {rate} {currency} /> -</div> - +<Success {amount} {rate} {tip} {currency} title={`${$t("payments.sent")}!`} /> <a href={`/${username}`} use:focus> <div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div> </a> diff --git a/src/routes/(app)/settings/preferences/+page.svelte b/src/routes/(app)/settings/preferences/+page.svelte index 1f761ecb..a08eb952 100644 --- a/src/routes/(app)/settings/preferences/+page.svelte +++ b/src/routes/(app)/settings/preferences/+page.svelte @@ -179,7 +179,8 @@ > <button type="button" class="flex w-full" onclick={editThreshold}> <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200"> - ⚡️ + <iconify-icon icon="ph:lightning-fill" class="text-yellow-300" + ></iconify-icon> </div> <div class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left" @@ -199,7 +200,8 @@ > <button type="button" class="flex w-full" onclick={editReserve}> <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200"> - ⚡️ + <iconify-icon icon="ph:lightning-fill" class="text-yellow-300" + ></iconify-icon> </div> <div class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left" diff --git a/src/routes/(static)/login/+page.server.ts b/src/routes/(static)/login/+page.server.ts index f77f24f2..6e268c92 100644 --- a/src/routes/(static)/login/+page.server.ts +++ b/src/routes/(static)/login/+page.server.ts @@ -18,7 +18,6 @@ export const actions = { await login(user, cookies, request.headers.get("cf-connecting-ip")); } catch (e) { const { message } = e as Error; - console.log("message", message); return fail(400, { error: "Login failed", message, ...form }); } |
