aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-12-22 23:09:36 -0800
committerAdam Soltys <[email protected]>2024-12-22 23:09:36 -0800
commitab82b405be6f2665c43518b4ad253becc8ab7430 (patch)
tree6e6fa488e6d78aa15f38da081b203423e4bb9d92 /src
parente2fcfdc4d608e260bb596952d8b54a7dcef05258 (diff)
downloadcoinos-ui-ab82b405be6f2665c43518b4ad253becc8ab7430.tar.gz
coinos-ui-ab82b405be6f2665c43518b4ad253becc8ab7430.zip
set memo
Diffstat (limited to 'src')
-rw-r--r--src/components/Invoice.svelte40
-rw-r--r--src/components/InvoiceActions.svelte14
-rw-r--r--src/components/InvoiceData.svelte23
-rw-r--r--src/components/InvoiceTypes.svelte13
-rw-r--r--src/components/SetAmount.svelte3
-rw-r--r--src/components/SetMemo.svelte44
-rw-r--r--src/locales/en.json4
-rw-r--r--src/routes/(app)/[username]/receive/+page.svelte63
-rw-r--r--src/routes/(app)/invoice/+server.ts11
-rw-r--r--src/routes/(app)/invoice/[id]/+page.svelte67
-rw-r--r--src/routes/(app)/invoice/[id]/memo/+page.server.ts8
-rw-r--r--src/routes/(app)/invoice/[id]/memo/+page.svelte2
-rw-r--r--src/routes/(app)/pay/[username]/[...amount]/+page.server.ts2
-rw-r--r--src/routes/(app)/pay/[username]/[...amount]/+page.svelte21
14 files changed, 196 insertions, 119 deletions
diff --git a/src/components/Invoice.svelte b/src/components/Invoice.svelte
deleted file mode 100644
index 3298dfe5..00000000
--- a/src/components/Invoice.svelte
+++ /dev/null
@@ -1,40 +0,0 @@
-<script>
- import { t } from "$lib/translations";
- import { f, sat, sats } from "$lib/utils";
- import { fly } from "svelte/transition";
- import Avatar from "$comp/Avatar.svelte";
- import Icon from "$comp/Icon.svelte";
- import { invoice } from "$lib/store";
-</script>
-
-{#if $invoice}
- <div class="fixed bottom-0 border-t w-full p-4 bg-white z-50" in:fly>
- <div class="flex flex-wrap md:flex-nowrap max-w-xl mx-auto gap-2">
- <div class="my-auto mx-auto">
- <div class="flex">
- <Avatar user={$invoice.user.username} size={12} />
- <h1 class="my-auto">
- <b>{$invoice.user.username}</b>
- {$t("payments.isRequesting")}
- <b
- >{f(
- ($invoice.amount * $invoice.rate) / sats,
- $invoice.currency,
- )}</b
- >
- {sat($invoice.amount)}
- </h1>
- </div>
- </div>
- <div class="mx-auto my-auto flex gap-2">
- <a href={`/invoice/${$invoice.id}/tip`}>
- <button
- class="rounded-full border py-2 px-4 font-bold hover:opacity-80 w-32"
- >
- {$t("payments.pay")}
- </button>
- </a>
- </div>
- </div>
- </div>
-{/if}
diff --git a/src/components/InvoiceActions.svelte b/src/components/InvoiceActions.svelte
index cd66fc36..23268a19 100644
--- a/src/components/InvoiceActions.svelte
+++ b/src/components/InvoiceActions.svelte
@@ -6,10 +6,10 @@
t,
link,
type,
- types,
showQr = $bindable(),
txt,
- toggleAmount
+ toggleAmount,
+ toggleMemo,
} = $props();
</script>
@@ -35,11 +35,19 @@
</a>
{/if}
+ <button class="btn" onclick={toggleMemo}>
+ <iconify-icon icon="ph:chat-centered-text-bold" width="32"></iconify-icon>
+ <div class="my-auto">
+ {t("invoice.setMemo")}
+ </div>
+ </button>
+
{#if txt.length > 120}
<div class="w-full flex justify-center gap-2 flex-wrap">
<button class="btn" onclick={() => (showQr = !showQr)}>
{#if showQr}
- <iconify-icon icon="ph:text-align-center-bold" width="32"></iconify-icon>
+ <iconify-icon icon="ph:text-align-center-bold" width="32"
+ ></iconify-icon>
{:else}
<iconify-icon icon="ph:qr-code-bold" width="32"></iconify-icon>
{/if}
diff --git a/src/components/InvoiceData.svelte b/src/components/InvoiceData.svelte
index 4ce39036..bd6adb97 100644
--- a/src/components/InvoiceData.svelte
+++ b/src/components/InvoiceData.svelte
@@ -1,7 +1,7 @@
<script>
import Amount from "$comp/Amount.svelte";
- import { btc, f, sat, s, sats } from "$lib/utils";
+ import { btc, f, sat, s, sats, types } from "$lib/utils";
let {
showQr,
link,
@@ -13,7 +13,10 @@
locale,
tip,
rate,
+ t,
} = $props();
+
+ let { memo } = $derived(invoice);
</script>
{#if showQr}
@@ -28,6 +31,20 @@
</div>
{/if}
+{#if invoice.type === types.liquid}
+ <div class="flex justify-center p-4 shadow items-center gap-2">
+ <iconify-icon icon="ph:warning-bold" width="48" class="text-warning"
+ ></iconify-icon>
+ <div>
+ <div class="my-auto text-xl text-center text-secondary">
+ {t("payments.onlyLbtc")}
+ <span class="text-teal-500 font-bold">L-BTC</span> &mdash;
+ {t("payments.dontDeposit")}
+ </div>
+ </div>
+ </div>
+{/if}
+
{#if !showQr || txt.length <= 120}
<div class="break-all text-center text-secondary text-xl">
{txt}
@@ -52,3 +69,7 @@
{#if amount > 0}
<Amount {amount} {currency} {rate} {locale} {tip} />
{/if}
+
+{#if memo}
+ <div class="text-xl text-center">{memo}</div>
+{/if}
diff --git a/src/components/InvoiceTypes.svelte b/src/components/InvoiceTypes.svelte
index a0a1fc12..00b5cfb3 100644
--- a/src/components/InvoiceTypes.svelte
+++ b/src/components/InvoiceTypes.svelte
@@ -1,6 +1,7 @@
<script>
+ import { types } from "$lib/utils";
import { goto } from "$app/navigation";
- let { aid, invoice, user, type, types, t, setType } = $props();
+ let { aid, invoice, user, type, t, setType } = $props();
</script>
{#if invoice.uid === aid}
@@ -89,14 +90,4 @@
</div>
<div class="my-auto text-lg">Bolt 12</div>
</button>
-
- {#if type === types.liquid}
- <div class="flex justify-center">
- <div class="my-auto text-xl text-center text-secondary">
- {t("payments.onlyLbtc")}
- <span class="text-teal-500 font-bold">L-BTC</span>,
- {t("payments.dontDeposit")}
- </div>
- </div>
- {/if}
{/if}
diff --git a/src/components/SetAmount.svelte b/src/components/SetAmount.svelte
index ddf90a17..a453b9d1 100644
--- a/src/components/SetAmount.svelte
+++ b/src/components/SetAmount.svelte
@@ -3,12 +3,13 @@
import Numpad from "$comp/Numpad.svelte";
import Toggle from "$comp/Toggle.svelte";
+ let submit = $state();
+
let {
currency = $bindable(),
fiat = $bindable(),
locale = $bindable(),
rate = $bindable(),
- submit = $bindable(),
settingAmount,
setAmount,
newAmount = $bindable(),
diff --git a/src/components/SetMemo.svelte b/src/components/SetMemo.svelte
new file mode 100644
index 00000000..f11bf780
--- /dev/null
+++ b/src/components/SetMemo.svelte
@@ -0,0 +1,44 @@
+<script>
+ import { focus } from "$lib/utils";
+
+ let {
+ submit = $bindable(),
+ settingMemo,
+ setMemo,
+ memo = $bindable(),
+ toggleMemo,
+ t,
+ } = $props();
+</script>
+
+{#if settingMemo}
+ <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-5"
+ >
+ <form onsubmit={setMemo} class="space-y-5">
+ <input use:focus placeholder={t("invoice.memo")} bind:value={memo} />
+ <div class="w-full flex flex-wrap gap-2">
+ <button
+ bind:this={submit}
+ type="submit"
+ onclick={setMemo}
+ class="btn btn-accent"
+ >
+ <div class="my-auto">{t("payments.ok")}</div>
+ </button>
+ <button
+ type="button"
+ class="btn"
+ onclick={toggleMemo}
+ onkeydown={toggleMemo}
+ >
+ <div class="my-auto">{t("payments.cancel")}</div>
+ </button>
+ </div>
+ </form>
+ </div>
+ </div>
+{/if}
diff --git a/src/locales/en.json b/src/locales/en.json
index 4cb6eb1c..26f9779b 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -110,6 +110,8 @@
"addTip": "Add a tip",
"addTipq": "Add a tip?",
"addMemo": "Add memo",
+ "setMemo": "Set memo",
+ "memo": "Memo",
"done": "Done",
"paymentSuccessful": "Payment received!",
"invoice": "Invoice",
@@ -439,7 +441,7 @@
"fundsClaimed": "Funds claimed!",
"print": "Print",
"onlyLbtc": "We only support",
- "dontDeposit": "don't deposit other assets"
+ "dontDeposit": "Please don't deposit other Liquid assets"
},
"items": {
"add": "Add item",
diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte
index 28d33754..9f3a3fd8 100644
--- a/src/routes/(app)/[username]/receive/+page.svelte
+++ b/src/routes/(app)/[username]/receive/+page.svelte
@@ -5,6 +5,7 @@
loc,
post,
copy,
+ fail,
f,
get,
types,
@@ -20,6 +21,7 @@
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 { t } from "$lib/translations";
import { goto, invalidate } from "$app/navigation";
@@ -48,21 +50,30 @@
amountFiat,
tip;
+ let update = async () => {
+ try {
+ ({ id } = await post(`/invoice`, {
+ invoice,
+ user: { username, currency },
+ }));
+
+ let url = `/invoice/${id}`;
+ if (subject?.prompt) url += "/tip";
+ else url += "?options=true";
+
+ goto(url, { invalidateAll: true, noScroll: true });
+ } catch (e) {
+ fail(e.message);
+ }
+ };
+
let setType = async (type) => {
$showQr = true;
if (type === types.lightning && !amount)
goto(`/${username}/receive`, { invalidateAll: true, noScroll: true });
else {
invoice.type = type;
- ({ id } = await post(`/invoice`, {
- invoice,
- user: { username, currency },
- }));
-
- goto(`/invoice/${id}?options=true`, {
- invalidateAll: true,
- noScroll: true,
- });
+ await update();
}
};
@@ -77,23 +88,27 @@
invoice.amount = newAmount;
invoice.tip = 0;
- ({ id } = await post(`/invoice`, {
- invoice,
- user: { username, currency },
- }));
-
- let url = `/invoice/${id}`;
- if (subject?.prompt) url += "/tip";
- else url += "?options=true";
-
- goto(url, { invalidateAll: true, noScroll: true });
+ await update();
};
let newAmount = $state();
let settingAmount = $state();
let fiat = $state(true);
let toggleAmount = () => (settingAmount = !settingAmount);
- let submit;
+
+ let setMemo = async (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ settingMemo = false;
+ invoice.memo = memo;
+ await update();
+ };
+
+ let memo = $state();
+ let settingMemo = $state();
+ let toggleMemo = () => (settingMemo = !settingMemo);
+
let link = $derived(
[types.bitcoin, types.liquid].includes(type) ? text : `lightning:${text}`,
);
@@ -119,22 +134,23 @@
{tip}
{rate}
showQr={$showQr}
+ t={$t}
/>
<InvoiceActions
{toggleAmount}
+ {toggleMemo}
{user}
{invoice}
{copy}
{link}
{type}
- {types}
{showQr}
{txt}
t={$t}
/>
- <InvoiceTypes {aid} {invoice} {user} {type} {types} {setType} t={$t} />
+ <InvoiceTypes {aid} {invoice} {user} {type} {setType} t={$t} />
</div>
<SetAmount
@@ -143,9 +159,10 @@
{currency}
locale={loc(user)}
{rate}
- {submit}
{settingAmount}
{setAmount}
{toggleAmount}
t={$t}
/>
+
+<SetMemo bind:memo {settingMemo} {setMemo} {toggleMemo} t={$t} />
diff --git a/src/routes/(app)/invoice/+server.ts b/src/routes/(app)/invoice/+server.ts
index f20d70f3..f494c153 100644
--- a/src/routes/(app)/invoice/+server.ts
+++ b/src/routes/(app)/invoice/+server.ts
@@ -1,7 +1,12 @@
import { auth, post } from "$lib/utils";
-import { json } from "@sveltejs/kit";
+import { error, json } from "@sveltejs/kit";
export const POST = async ({ cookies, request }) => {
- const body = await request.json();
- return json(await post("/invoice", body, auth(cookies)));
+ try {
+ const body = await request.json();
+ return json(await post("/invoice", body, auth(cookies)));
+ } catch (e) {
+ const { message } = e as Error;
+ error(500, message);
+ }
};
diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte
index 8ad555bb..350d2398 100644
--- a/src/routes/(app)/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/+page.svelte
@@ -7,6 +7,7 @@
post,
copy,
f,
+ fail,
get,
types,
sat,
@@ -21,6 +22,7 @@
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 { t } from "$lib/translations";
import { goto, invalidate } from "$app/navigation";
@@ -38,6 +40,7 @@
let { id, subject, user } = $state(data);
let { invoice, src } = $derived(data);
let { aid, amount, rate, tip, hash, text, type } = $derived(invoice);
+ let { memo } = $state(invoice);
let { username, currency } = $derived(invoice.user);
let locale = loc(user);
@@ -65,24 +68,37 @@
}
});
+ let update = async () => {
+ try {
+ ({ id } = await post(`/invoice`, {
+ invoice,
+ user: { username, currency },
+ }));
+
+ let url = `/invoice/${id}`;
+ if (subject?.prompt) url += "/tip";
+ else url += "?options=true";
+
+ goto(url, { invalidateAll: true, noScroll: true });
+ } catch (e) {
+ fail(e.message);
+ }
+ };
+
let setType = async (type) => {
$showQr = true;
if (type === types.lightning && !amount)
goto(`/${username}/receive`, { invalidateAll: true, noScroll: true });
else {
invoice.type = type;
- ({ id } = await post(`/invoice`, {
- invoice,
- user: { username, currency },
- }));
-
- goto(`/invoice/${id}?options=true`, {
- invalidateAll: true,
- noScroll: true,
- });
+ await update();
}
};
+ let newAmount = $state(0);
+ let settingAmount = $state();
+ let toggleAmount = $state(() => (settingAmount = !settingAmount));
+
let setAmount = async (e) => {
e.preventDefault();
e.stopPropagation();
@@ -93,23 +109,24 @@
invoice.amount = newAmount;
invoice.tip = 0;
- ({ id } = await post(`/invoice`, {
- invoice,
- user: { username, currency },
- }));
+ await update();
+ };
- let url = `./${id}`;
- if (subject?.prompt) url += "/tip";
- else url += "?options=true";
+ let setMemo = async (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ console.log("setting");
- goto(url, { invalidateAll: true, noScroll: true });
+ settingMemo = false;
+ invoice.memo = memo;
+ console.log("MEMO", invoice.memo);
+ await update();
};
- let newAmount = $state(0);
- let settingAmount = $state();
- let toggleAmount = $state(() => (settingAmount = !settingAmount));
+ let settingMemo = $state();
+ let toggleMemo = () => (settingMemo = !settingMemo);
+
let fiat = $state(true);
- let submit = $state();
let amountFiat = $derived(parseFloat(((amount * rate) / sats).toFixed(2)));
let tipAmount = $derived(((tip * rate) / sats).toFixed(2));
let link = $derived(
@@ -134,22 +151,23 @@
{tip}
{rate}
showQr={$showQr}
+ t={$t}
/>
<InvoiceActions
{toggleAmount}
+ {toggleMemo}
{user}
{invoice}
{copy}
{link}
{type}
- {types}
{txt}
t={$t}
bind:showQr={$showQr}
/>
- <InvoiceTypes {aid} {invoice} {user} {type} {types} {setType} t={$t} />
+ <InvoiceTypes {aid} {invoice} {user} {type} {setType} t={$t} />
</div>
<SetAmount
@@ -158,10 +176,11 @@
{currency}
{locale}
{rate}
- {submit}
{settingAmount}
{setAmount}
{toggleAmount}
amountPrompt={$amountPrompt}
t={$t}
/>
+
+<SetMemo bind:memo {settingMemo} {setMemo} {toggleMemo} t={$t} />
diff --git a/src/routes/(app)/invoice/[id]/memo/+page.server.ts b/src/routes/(app)/invoice/[id]/memo/+page.server.ts
index a2609658..d54ff30d 100644
--- a/src/routes/(app)/invoice/[id]/memo/+page.server.ts
+++ b/src/routes/(app)/invoice/[id]/memo/+page.server.ts
@@ -1,12 +1,4 @@
import invoice from "$lib/invoice";
-import { redirect } from "@sveltejs/kit";
-
-export async function load({ parent, params }) {
- const { invoice } = await parent();
- if (!invoice.amount) {
- redirect(307, `/invoice/${invoice.id}`);
- }
-}
export const actions = {
default: invoice,
diff --git a/src/routes/(app)/invoice/[id]/memo/+page.svelte b/src/routes/(app)/invoice/[id]/memo/+page.svelte
index 67283148..c8b1a429 100644
--- a/src/routes/(app)/invoice/[id]/memo/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/memo/+page.svelte
@@ -26,8 +26,6 @@
tip,
user: { username, currency },
} = $derived(invoice);
-
- invoice.memo = user?.username;
</script>
<form
diff --git a/src/routes/(app)/pay/[username]/[...amount]/+page.server.ts b/src/routes/(app)/pay/[username]/[...amount]/+page.server.ts
index 65665610..431310a3 100644
--- a/src/routes/(app)/pay/[username]/[...amount]/+page.server.ts
+++ b/src/routes/(app)/pay/[username]/[...amount]/+page.server.ts
@@ -33,6 +33,8 @@ export async function load({ cookies, params, parent }) {
auth(cookies),
);
+ const { balance } = await get(`/account/${user.id}`, auth(cookies));
+
redirect(307, `/invoice/${id}`);
}
diff --git a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
index b22e3c1f..7e696b22 100644
--- a/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
+++ b/src/routes/(app)/pay/[username]/[...amount]/+page.svelte
@@ -16,6 +16,14 @@
let initialAmount = form?.amount || data.amount;
let amount = $state(initialAmount);
let fiat = $state(!initialAmount);
+
+ let setMax = (e) => {
+ e.preventDefault();
+ fiat = false;
+ amount = user.balance;
+ console.log("OK YES", amount);
+ next.click();
+ };
</script>
{#if form?.message}
@@ -27,13 +35,22 @@
<div class="container px-4 mt-20 max-w-xl mx-auto space-y-2">
<Numpad bind:amount bind:fiat {currency} {locale} {rate} submit={next} />
- <form method="POST" use:enhance>
+ <form method="POST" use:enhance class="flex gap-2 justify-center">
<input name="amount" value={amount} type="hidden" />
<input name="rate" value={rate} type="hidden" />
<input name="username" value={subject.username} type="hidden" />
<input name="prompt" value={subject.prompt} type="hidden" />
- <button type="submit" bind:this={next} class="btn btn-accent">
+ {#if user?.balance}
+ <button
+ type="button"
+ class="btn !w-auto grow"
+ onclick={setMax}
+ onkeydown={setMax}>Max ⚡️{s(user.balance)}</button
+ >
+ {/if}
+
+ <button type="submit" bind:this={next} class="btn btn-accent !w-auto grow">
{$t("payments.next")}</button
>
</form>