aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-04-07 14:46:09 -0700
committerAdam Soltys <[email protected]>2023-04-07 14:46:09 -0700
commitd145b9de59cb20181f6fe48f6aa4677d406cf16d (patch)
tree16439dbce4ff7e48c60f57875489c16ea5532a13 /src/routes/(app)
parentd4de8dce613f5ee49068ce90b868ffda5d4771d7 (diff)
parent648d9fb41c5302672822fd76fb1b1a90f654b05b (diff)
downloadcoinos-ui-d145b9de59cb20181f6fe48f6aa4677d406cf16d.tar.gz
coinos-ui-d145b9de59cb20181f6fe48f6aa4677d406cf16d.zip
Merge branch 'master' into hashme
Diffstat (limited to 'src/routes/(app)')
-rw-r--r--src/routes/(app)/+layout.svelte17
-rw-r--r--src/routes/(app)/[username]/(profile)/+layout.svelte60
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte44
-rw-r--r--src/routes/(app)/[username]/dashboard/+page.server.js4
-rw-r--r--src/routes/(app)/[username]/dashboard/+page.svelte163
-rw-r--r--src/routes/(app)/[username]/generate/+page.svelte3
-rw-r--r--src/routes/(app)/[username]/generate/+server.js3
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/+layout.server.js4
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte8
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte10
-rw-r--r--src/routes/(app)/[username]/messages/+page.server.js3
-rw-r--r--src/routes/(app)/[username]/messages/+page.svelte4
-rw-r--r--src/routes/(app)/[username]/payments/[...page]/+page.svelte11
-rw-r--r--src/routes/(app)/[username]/receive/[...param]/+page.svelte5
-rw-r--r--src/routes/(app)/[username]/reset/+server.js10
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.svelte7
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_security.svelte6
-rw-r--r--src/routes/(app)/admin/+page.server.js6
-rw-r--r--src/routes/(app)/admin/+page.svelte15
-rw-r--r--src/routes/(app)/buy/+page.svelte21
-rw-r--r--src/routes/(app)/launch/purchase/+page.svelte1
-rw-r--r--src/routes/(app)/login/+page.svelte8
-rw-r--r--src/routes/(app)/payment/[id]/+page.svelte15
-rw-r--r--src/routes/(app)/payment/[id]/print/+server.js7
-rw-r--r--src/routes/(app)/pot/[name]/+page.svelte2
-rw-r--r--src/routes/(app)/send/+layout.svelte21
-rw-r--r--src/routes/(app)/send/bitcoin/[address]/[...amount]/+page.svelte11
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.server.js3
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.svelte10
-rw-r--r--src/routes/(app)/send/lightning/[payreq]/+page.svelte5
-rw-r--r--src/routes/(app)/send/pot/[name]/[...amount]/+page.svelte5
-rw-r--r--src/routes/(app)/send/user/[username]/[...amount]/+page.server.js32
-rw-r--r--src/routes/(app)/send/user/[username]/[...amount]/+page.svelte13
-rw-r--r--src/routes/(app)/support/+page.svelte28
34 files changed, 220 insertions, 345 deletions
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
index 0dcdc1b2..9eb8f18c 100644
--- a/src/routes/(app)/+layout.svelte
+++ b/src/routes/(app)/+layout.svelte
@@ -2,7 +2,7 @@
import { SvelteToast } from '@zerodevx/svelte-toast';
import { onDestroy, onMount } from 'svelte';
import { close, connect, send } from '$lib/socket';
- import { last, selectedRate, invoice, rate, user, request, passwordPrompt } from '$lib/store';
+ import { last, invoice, request, passwordPrompt } from '$lib/store';
import { page } from '$app/stores';
import { browser } from '$app/environment';
import { goto } from '$app/navigation';
@@ -15,16 +15,7 @@
export let data;
let { subject } = $page.data;
- let r, u, token, rates;
-
- $: update(data);
- let update = () => {
- ({ user: u, rate: r, token, rates } = data);
- $rate = r;
- $user = u;
- };
-
- $: $selectedRate = r * (rates[u?.currency || 'USD'] / rates.USD);
+ let { rate, user, token, rates } = data;
onMount(() => {
let localStorageLocale = localStorage.getItem(localeLocalStorageKey);
@@ -89,9 +80,9 @@
</main>
{#if $invoice}
- <Invoice user={u} />
+ <Invoice {user} />
{/if}
{#if $request}
- <Request user={u} />
+ <Request {user} />
{/if}
diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte
index bbb2379e..df9b9ad8 100644
--- a/src/routes/(app)/[username]/(profile)/+layout.svelte
+++ b/src/routes/(app)/[username]/(profile)/+layout.svelte
@@ -1,13 +1,13 @@
<script>
import { f, s, sats } from '$lib/utils';
- import { animatedRate, selectedRate } from '$lib/store';
+ import { animatedRate } from '$lib/store';
import { Icon } from '$comp';
import { t } from '$lib/translations';
import { sign, send } from '$lib/nostr';
export let data;
- let events, user, subject, src, text;
- $: ({ events, user, subject, src, text } = data);
+ let events, user, subject, rates, src, text;
+ $: ({ events, user, rates, subject, src, text } = data);
$: ({ currency, username: n, display } = subject);
$: username = n.length > 60 ? n.substr(0, 6) : display || n;
@@ -42,24 +42,6 @@
$: following = !!user?.follows.find((t) => t.includes(subject.pubkey));
- let ease = (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t);
- let i;
-
- let o = $selectedRate;
- $: animate($selectedRate);
- let animate = (n) => {
- clearInterval(i);
-
- let t = 0;
- let d = o - n;
-
- i = setInterval(() => {
- $animatedRate = (o - d * ease(t / 100)).toFixed(2);
- if (t > 80) (o = n) && clearInterval(i);
- t++;
- }, 10);
- };
-
let hideBio = true;
let toggleBio = () => (hideBio = false);
</script>
@@ -115,39 +97,31 @@
</button>
</div>
{/if}
+ {/if}
+ {#if !subject.anon && subject.username !== user?.username}
<div class="w-full flex">
- <a href={`/${subject.username}/messages`} class="mx-auto">
- <button class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60">
- <div class="mx-auto flex">
- <Icon icon="support" style="mr-2 my-auto" />
- <div class="mt-1 my-auto">{$t('user.message')}</div>
- </div>
- </button>
- </a>
- </div>
-
- <div class="w-full flex">
- <a href={`/${subject.username}/request`} class="mx-auto">
+ <a
+ href={user ? `/send/${subject.username}` : `/${subject.username}/receive`}
+ class="mx-auto"
+ >
<button class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60">
<div class="mx-auto flex">
- <Icon icon="numpad" style="mr-2 my-auto" />
- <div class="mt-1 my-auto">{$t('payments.requestAnInvoice')}</div>
+ <Icon icon="send" style="mr-2" />
+ <div class="mt-1">{$t('user.pay')}</div>
</div>
</button>
</a>
</div>
{/if}
- {#if !subject.anon && subject.username !== user?.username}
+
+ {#if user && user.username !== subject.username && subject.pubkey}
<div class="w-full flex">
- <a
- href={user ? `/send/${subject.username}` : `/${subject.username}/receive`}
- class="mx-auto"
- >
+ <a href={`/${subject.username}/messages`} class="mx-auto">
<button class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60">
<div class="mx-auto flex">
- <Icon icon="send" style="mr-2" />
- <div class="mt-1">{$t('user.pay')}</div>
+ <Icon icon="support" style="mr-2 my-auto" />
+ <div class="mt-1 my-auto">{$t('user.message')}</div>
</div>
</button>
</a>
@@ -163,7 +137,7 @@
</div>
</div>
-{#if currency && $animatedRate}
+{#if currency && !isNaN($animatedRate)}
<div class="flex fixed w-full px-4 bg-white py-2 bottom-0 bg-opacity-90 tabular-nums">
<div class="text-secondary flex mr-auto">
<div class="flex mr-1">
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte
index 09335e9c..308289b0 100644
--- a/src/routes/(app)/[username]/(profile)/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/+page.svelte
@@ -2,24 +2,23 @@
import { onMount } from 'svelte';
import { Icon, Avatar, Balance, Feed } from '$comp';
import { t } from '$lib/translations';
- import { f, sat, sats } from '$lib/utils';
+ import { ease, f, sat, sats } from '$lib/utils';
import { sign, send, encrypt, decrypt } from '$lib/nostr';
- import { event as e, password } from '$lib/store';
+ import { event as e, password, rate, animatedRate } from '$lib/store';
import { browser } from '$app/environment';
export let data;
- let { messages, notes, invoices, sent, received, subject, user } = data;
+ let { messages, notes, invoices, sent, received, subject, user, rates } = data;
$: refresh(data);
- let refresh = (d) => ({ messages, notes, invoices, sent, received, subject, user } = d);
+ let refresh = (d) => ({ messages, notes, invoices, sent, received, subject, user, rates } = d);
let keys = new Set();
let latest = [];
- let i = 0;
let ready;
e.subscribe(async (event) => {
if (!(event && ready)) return;
- if (event.recipient.id === user?.id && !~latest.findIndex((m) => m.id === event.id)) {
+ if (event.recipient?.id === user.id && !~latest.findIndex((m) => m.id === event.id)) {
event.content = await decrypt({ event, user });
let i = latest.findIndex((m) => m.pubkey === event.pubkey);
@@ -34,22 +33,49 @@
$: initialize($password);
let initialize = async (p) => {
+ let i = 0;
ready = false;
- if (!p) return;
+ if (!p || !user) return;
while (i < messages.length) {
let event = messages[i];
- let k = event.author.id === user.id ? event.recipient.pubkey : event.author.pubkey;
+ i++;
+
+ if (!(event.author && event.recipient)) continue;
+
+ let k = event.author.id === user.id ? event.recipient?.pubkey : event.author.pubkey;
if (!keys.has(k)) {
keys.add(k);
event.content = await decrypt({ event, user });
if (event.content) latest.push(event);
}
- i++;
}
latest = latest;
ready = true;
};
+
+ let i;
+ let o;
+
+ rate.subscribe((n) => {
+ if (!user?.currency) return;
+ clearInterval(i);
+
+ let r = ((rates[user.currency] / rates['USD']) * n).toFixed(2);
+
+ if (!r || isNaN(r)) return;
+ if (!o) o = r;
+
+ let t = 0;
+ let d = o - r;
+
+ i = setInterval(() => {
+ if (!r) return;
+ $animatedRate = (o - d * ease(t / 100)).toFixed(2);
+ if (t > 80) (o = r) && clearInterval(i);
+ t++;
+ }, 10);
+ });
</script>
<div class="space-y-8">
diff --git a/src/routes/(app)/[username]/dashboard/+page.server.js b/src/routes/(app)/[username]/dashboard/+page.server.js
deleted file mode 100644
index ae66a20d..00000000
--- a/src/routes/(app)/[username]/dashboard/+page.server.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import { redirect } from '@sveltejs/kit';
-export async function load({ params: { username } }) {
- throw redirect(301, `/${username}`);
-}
diff --git a/src/routes/(app)/[username]/dashboard/+page.svelte b/src/routes/(app)/[username]/dashboard/+page.svelte
deleted file mode 100644
index d8761ea9..00000000
--- a/src/routes/(app)/[username]/dashboard/+page.svelte
+++ /dev/null
@@ -1,163 +0,0 @@
-<script>
- import { enhance } from '$app/forms';
- import { f, s, post, fail, sat, sats } from '$lib/utils';
- import { tick } from 'svelte';
- import { Avatar, Icon } from '$comp';
- import { rate, password, selectedRate } from '$lib/store';
- import { goto } from '$app/navigation';
- import { t } from '$lib/translations';
- import { events } from '$lib/store';
-
- export let data;
- $: ({ invoices, requests } = data);
-
- let ease = (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t);
- let interval, rateInterval;
-
- let oldRate = $selectedRate;
- let animatedRate = oldRate;
- $: animateRate($selectedRate);
- let animateRate = (newRate) => {
- if (!accountBalanceFiat) return;
- let t = 0;
- let newBalance = (user.balance * newRate) / sats;
- let oldBalance = parseFloat(accountBalanceFiat);
- let diff = oldBalance - newBalance;
- let rateDiff = oldRate - newRate;
-
- clearInterval(rateInterval);
- rateInterval = setInterval(() => {
- let delta = rateDiff * ease(t / 100);
- animatedRate = (oldRate - delta).toFixed(2);
- if (t > 80) clearInterval(interval);
- t++;
- }, 10);
-
- oldRate = newRate;
-
- clearInterval(interval);
- interval = setInterval(() => {
- let delta = diff * ease(t / 100);
- accountBalanceFiat = (oldBalance - delta).toFixed(2);
- if (t > 80) clearInterval(interval);
- t++;
- }, 10);
- };
-
- $: user = data.user;
- $: accountBalanceFiat =
- accountBalanceFiat ||
- (user && $selectedRate && ((user.balance * $selectedRate) / sats).toFixed(2));
-
- let payreq = '',
- payreqField,
- loading;
-
- $: btcPrice = f($selectedRate, user.currency);
-
- $: accountBalanceBtc = user.balance / sats;
-</script>
-
-<div class="container px-4 max-w-md mx-auto mt-20 space-y-12 mb-8">
- <div class="mt-24 space-y-2">
- <div class="text-5xl font-bold">
- {$selectedRate ? f(accountBalanceFiat, user.currency) : $t('user.dashboard.fetchingRate')}
- </div>
-
- <div class="text-secondary text-2xl">
- ⚡️{s(user.balance)}
- </div>
- </div>
-
- <div class="grid sm:grid-cols-2 gap-2 text-lg">
- <a href="/send">
- <button class="rounded-full border py-4 px-5 font-bold hover:opacity-80 w-full"
- >{$t('user.dashboard.send')}</button
- >
- </a>
- <a href={`/${user.username}/receive`}>
- <button class="rounded-full border py-4 px-5 font-bold hover:opacity-80 w-full"
- >{$t('user.dashboard.receive')}</button
- >
- </a>
- </div>
-
- <!-- <div> -->
- <!-- {#each invoices as { request_id, amount, currency, rate, user: recipient, requester, id }} -->
- <!-- {@const requested = user.username === requester?.username} -->
- <!-- <a href={`/invoice/${id}` + (requested ? '/tip' : '')}> -->
- <!-- <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> -->
- <!-- <div class="flex gap-2"> -->
- <!-- <div> -->
- <!-- {#if requested} -->
- <!-- <div class="flex"> -->
- <!-- <Avatar user={recipient} size={20} /> -->
- <!-- <div class="my-auto text-left"> -->
- <!-- <p class="text-secondary">{$t('payments.invoiceFrom')}</p> -->
- <!-- <p class="ml-1 text-lg break-words">{recipient.username}</p> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- {:else} -->
- <!-- <div class="flex"> -->
- <!-- <Avatar user={requester} size={20} /> -->
- <!-- <div class="my-auto text-left"> -->
- <!-- <p class="text-secondary">{$t('payments.awaiting')}</p> -->
- <!-- <p class="ml-1 text-lg break-words">{requester.username}</p> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- {/if} -->
- <!-- </div> -->
- <!-- <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> -->
- <!-- <div class="font-bold"> -->
- <!-- {f(amount * (rate / sats), currency)} -->
- <!-- </div> -->
- <!-- -->
- <!-- <div class="text-secondary">{sat(amount)}</div> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- </a> -->
- <!-- {/each} -->
- <!-- </div> -->
-
- <!-- <div> -->
- <!-- {#each requests as { id, invoice, memo, requester: r }} -->
- <!-- <a href={`/${user.username}/receive/${id}`}> -->
- <!-- <div class="border-b p-2 last:border-b-0 hover:bg-gray-100"> -->
- <!-- <div class="flex"> -->
- <!-- <div> -->
- <!-- <div class="flex"> -->
- <!-- <Avatar user={r} size={20} /> -->
- <!-- <div class="my-auto text-left"> -->
- <!-- <p class="ml-1 text-lg break-words">{r.username}</p> -->
- <!-- <p class="ml-1 text-secondary">{memo}</p> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- <div class="whitespace-nowrap my-auto ml-auto flex gap-2"> -->
- <!-- <button class="rounded-full border py-2 px-4 font-bold hover:opacity-80 w-full" -->
- <!-- >Invoice</button -->
- <!-- > -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- </div> -->
- <!-- </a> -->
- <!-- {/each} -->
- <!-- </div> -->
-</div>
-
-<div class="flex fixed w-full px-4 bg-white py-2 bottom-0 bg-opacity-90">
- <div class="text-secondary flex mr-auto">
- <div class="flex mr-1">
- <div class="my-auto mr-1">1</div>
- <img src="/images/bitcoin.svg" class="w-5 my-auto" alt="Bitcoin" />
- </div>
- <div>= {f(animatedRate, user.currency)}</div>
- </div>
- <div class="text-secondary flex ml-auto">
- <div class="flex">
- <div class="mr-1">⚡️{s((1 * sats) / animatedRate)} =</div>
- <div>{f(1, user.currency)}</div>
- </div>
- </div>
-</div>
diff --git a/src/routes/(app)/[username]/generate/+page.svelte b/src/routes/(app)/[username]/generate/+page.svelte
index 32a38592..3548ccd4 100644
--- a/src/routes/(app)/[username]/generate/+page.svelte
+++ b/src/routes/(app)/[username]/generate/+page.svelte
@@ -1,9 +1,6 @@
<script>
import { fail, post, wait } from '$lib/utils';
- import { Buffer } from 'buffer';
import { onMount } from 'svelte';
- import { bech32m } from 'bech32';
- import { generateMnemonic, mnemonicToEntropy, mnemonicToSeedSync } from 'bip39';
import { goto, invalidate } from '$app/navigation';
import { Pin } from '$comp';
import { loginRedirect, pin, password, passwordPrompt } from '$lib/store';
diff --git a/src/routes/(app)/[username]/generate/+server.js b/src/routes/(app)/[username]/generate/+server.js
index 1335c3e2..e1df08e3 100644
--- a/src/routes/(app)/[username]/generate/+server.js
+++ b/src/routes/(app)/[username]/generate/+server.js
@@ -3,7 +3,8 @@ import { error, json } from '@sveltejs/kit';
export async function POST({ cookies, request }) {
try {
- return json(await post(`/user`, await request.json(), auth(cookies)));
+ let body = await request.json();
+ return json(await post(`/user`, body, auth(cookies)));
} catch (e) {
throw error(500, e.message);
}
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js b/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
index 7cf87e14..875c4e11 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
+++ b/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
@@ -12,10 +12,10 @@ export async function load({ depends, params, url, parent }) {
if (user && invoice.uid !== user.id && !url.pathname.includes('tip'))
throw redirect(307, `/send/invoice/${hash}`);
- let { amount, received } = invoice;
+ let { amount, pending, received } = invoice;
amount = parseInt(amount);
- let paid = (!amount && received) || (amount > 0 && received >= amount);
+ let paid = (!amount && received) || (amount > 0 && (pending >= amount || received >= amount));
if (paid && !url.pathname.endsWith('paid'))
throw redirect(307, `/${params.username}/invoice/${hash}/paid`);
diff --git a/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte b/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
index 4d7aae51..c9619cee 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
@@ -21,7 +21,7 @@
{#if received}
<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(fiat(received, rate), currency)}
+ {f(fiat(received - tip, rate), currency)}
{#if tip}
<span class="text-lg">
+ {f(fiat(tip, rate), currency)}
@@ -29,7 +29,7 @@
{/if}
</h2>
<h3 class="text-secondary md:text-lg mb-6 mt-1">
- ⚡️{s(received)}
+ ⚡️{s(received - tip)}
{#if tip}
<span class="text-lg">
@@ -42,13 +42,13 @@
{#if pending}
<h1 class="text-3xl md:text-4xl font-bold mb-6">Payment detected</h1>
<h2 class="text-2xl md:text-3xl font-semibold">
- {f(fiat(pending, rate), currency)}
+ {f(fiat(pending - tip, rate), currency)}
{#if tip}
+ {f(fiat(tip, rate), currency)}
{/if}
</h2>
<h3 class="text-secondary md:text-lg mb-6 mt-1">
- ⚡️{s(pending)}
+ ⚡️{s(pending - tip)}
{#if tip}
<span class="text-lg">
+ ⚡️{s(tip)}
diff --git a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
index 9d9021a6..fe6c67be 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
@@ -56,7 +56,7 @@
export let data;
$: refresh(data);
- let { invoice, id, user } = data;
+ let { invoice, id, user, rates } = data;
let {
amount,
hash,
@@ -82,17 +82,19 @@
amount,
hash,
type,
- rate,
received,
prompt,
text,
tip,
- user: { username, currency }
+ user: { username }
} = invoice);
tipPercent = (tip / amount) * 100;
};
+ $: currency = user?.currency || invoice.currency;
+ $: rate = invoice.rate * (rates[currency] / rates[invoice.currency]);
+
$: tip = Math.round((amount / 100) * tipPercent);
$: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
@@ -109,7 +111,7 @@
<input type="hidden" name="amount" value={amount} />
<input type="hidden" name="tip" value={tip} />
<input type="hidden" name="username" value={username} />
- <input type="hidden" name="rate" value={rate} />
+ <input type="hidden" name="rate" value={invoice.rate} />
<input type="hidden" name="prompt" value="false" />
<input type="hidden" name="type" value={type} />
<input type="hidden" name="hash" value={hash} />
diff --git a/src/routes/(app)/[username]/messages/+page.server.js b/src/routes/(app)/[username]/messages/+page.server.js
index 8347c184..ec5c5eee 100644
--- a/src/routes/(app)/[username]/messages/+page.server.js
+++ b/src/routes/(app)/[username]/messages/+page.server.js
@@ -8,8 +8,9 @@ export async function load({ params, parent, url }) {
try {
messages = await get(`/${user.pubkey}/${since}/messages`);
+
messages = messages
- .filter((m) => m.recipient.id === subject.id || m.author.id === subject.id)
+ .filter((m) => m.recipient?.id === subject.id || m.author?.id === subject.id)
.sort((a, b) => a.created_at - b.created_at);
if (user.id === subject.id) messages = messages.filter((m) => m.recipient.id === m.author.id);
diff --git a/src/routes/(app)/[username]/messages/+page.svelte b/src/routes/(app)/[username]/messages/+page.svelte
index 7a10d605..cfa7f741 100644
--- a/src/routes/(app)/[username]/messages/+page.svelte
+++ b/src/routes/(app)/[username]/messages/+page.svelte
@@ -10,7 +10,7 @@
import { sign, send, encrypt, decrypt } from '$lib/nostr';
import { event as e, password } from '$lib/store';
import { tick, onMount } from 'svelte';
- import { calculateId } from 'nostr';
+ import { getEventHash } from 'nostr-tools';
export let data;
@@ -77,8 +77,8 @@
tick().then(() => pane && (pane.scrollTop = pane.scrollHeight));
try {
- event.id = await calculateId(event);
event.content = await encrypt({ message: event.message, recipient: subject.pubkey, user });
+ event.id = getEventHash(event);
await sign({ event, user });
await send(event);
diff --git a/src/routes/(app)/[username]/payments/[...page]/+page.svelte b/src/routes/(app)/[username]/payments/[...page]/+page.svelte
index c9cc5c40..744b35ec 100644
--- a/src/routes/(app)/[username]/payments/[...page]/+page.svelte
+++ b/src/routes/(app)/[username]/payments/[...page]/+page.svelte
@@ -148,19 +148,16 @@
<div class="grid grid-cols-3 border-b h-24 hover:bg-gray-100 px-4">
<div class="whitespace-nowrap my-auto">
<div class="font-bold" class:text-red-800={p.amount < 0}>
- {f((Math.abs(p.amount) + (p.tip || 0)) * (p.rate / sats), p.currency)}
+ {f(Math.abs(p.amount) * (p.rate / sats), p.currency)}
{#if p.tip}
- <span class="text-xs text-secondary">
- {f(Math.abs(p.amount) * (p.rate / sats), p.currency)} + {f(
- p.tip * (p.rate / sats),
- p.currency
- )}
+ <span class="text-sm text-secondary">
+ +{Math.round((p.tip / Math.abs(p.amount)) * 100)}%
</span>
{/if}
</div>
<div class="text-secondary">
- {sat(p.amount + (p.tip || 0))}
+ {sat(Math.abs(p.amount) + (p.tip || 0))}
</div>
</div>
diff --git a/src/routes/(app)/[username]/receive/[...param]/+page.svelte b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
index 95495368..27b339aa 100644
--- a/src/routes/(app)/[username]/receive/[...param]/+page.svelte
+++ b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
@@ -18,9 +18,10 @@
let lightning = true;
let { currency, username, prompt } = data.subject;
- let { user } = data;
+ let { rates, user } = data;
let submit;
+ $: rate = rates[currency];
$: type = lightning ? 'lightning' : 'bitcoin';
</script>
@@ -37,7 +38,7 @@
<input type="hidden" name="prompt" value={prompt} />
<div class="space-y-3 w-[300px] mx-auto">
- <Numpad bind:amount bind:currency {submit} />
+ <Numpad bind:amount bind:currency bind:rate {submit} />
<button
bind:this={submit}
type="submit"
diff --git a/src/routes/(app)/[username]/reset/+server.js b/src/routes/(app)/[username]/reset/+server.js
new file mode 100644
index 00000000..52fff367
--- /dev/null
+++ b/src/routes/(app)/[username]/reset/+server.js
@@ -0,0 +1,10 @@
+import { json } from '@sveltejs/kit';
+import { auth, post } from '$lib/utils';
+
+export async function POST({ cookies, request, params }) {
+ let { username } = params;
+ let r = await request.json();
+ let { password } = r;
+ let result = await post('/reset', { password, username }, auth(cookies));
+ return json(result);
+}
diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
index 997d8b4a..1b212abe 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
@@ -112,13 +112,10 @@
loading = false;
}
-
- let loaded;
- onMount(() => setTimeout(() => (loaded = true), 50));
</script>
-{#if loaded && user.haspin && $pin?.length !== 6}
- <Pin bind:value={$pin} />
+{#if user.haspin && $pin?.length !== 6}
+ <Pin />
{/if}
<form
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
index eb3b405e..40947bda 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
@@ -148,9 +148,9 @@
{$t('user.settings.securityPINDescription')}
</p>
{#if verifying}
- <Pin bind:value={verify} {cancel} />
+ <Pin bind:value={verify} {cancel} notify={false} />
{:else if settingPin}
- <Pin bind:value={pin} title={$t('user.settings.setPIN')} {cancel} />
+ <Pin bind:value={pin} title={$t('user.settings.setPIN')} {cancel} notify={false} />
{:else}
<button type="button" class="primary" on:click={togglePin}
><Icon icon="lock" style="mr-1" />
@@ -192,7 +192,7 @@
{/if}
{#if confirming2fa || disabling2fa}
- <Pin bind:value={token} title="Enter 2FA Code" {cancel} />
+ <Pin bind:value={token} title="Enter 2FA Code" {cancel} persist={false} notify={false} />
{/if}
</div>
diff --git a/src/routes/(app)/admin/+page.server.js b/src/routes/(app)/admin/+page.server.js
index c4079a2f..e19f894c 100644
--- a/src/routes/(app)/admin/+page.server.js
+++ b/src/routes/(app)/admin/+page.server.js
@@ -1,10 +1,10 @@
-import { get } from '$lib/utils';
+import { auth, get } from '$lib/utils';
import { redirect } from '@sveltejs/kit';
-export async function load({ parent }) {
+export async function load({ cookies, parent }) {
let { user } = await parent();
if (!user) throw redirect(307, '/login');
- let users = (await get('/users')).sort((a, b) => b.balance - a.balance);
+ let users = (await get('/users', auth(cookies))).sort((a, b) => b.balance - a.balance);
return { users };
}
diff --git a/src/routes/(app)/admin/+page.svelte b/src/routes/(app)/admin/+page.svelte
index 1a747f1f..529d2f77 100644
--- a/src/routes/(app)/admin/+page.svelte
+++ b/src/routes/(app)/admin/+page.svelte
@@ -1,11 +1,22 @@
<script>
+ import { post } from '$lib/utils';
export let data;
+ let reset = (username) => post(`/${username}/reset`, { password });
let { users } = data;
+ let password;
</script>
-{#each users as { balance, username }}
- <div class="grid grid-cols-2">
+{#each users as { balance, username, expected }}
+ <div class="grid grid-cols-5">
<div>{username}</div>
<div>{balance}</div>
+ <div>{expected}</div>
+ <div><input bind:value={password} /></div>
+ <div>
+ <button
+ class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
+ on:click={() => reset(username)}>Reset</button
+ >
+ </div>
</div>
{/each}
diff --git a/src/routes/(app)/buy/+page.svelte b/src/routes/(app)/buy/+page.svelte
index 2f556ada..22e7e9ec 100644
--- a/src/routes/(app)/buy/+page.svelte
+++ b/src/routes/(app)/buy/+page.svelte
@@ -1,7 +1,7 @@
<script>
import { enhance } from '$app/forms';
import { Icon, Lock, Card, Calendar, Spinner } from '$comp';
- import { animatedRate, selectedRate } from '$lib/store';
+ import { animatedRate } from '$lib/store';
import { f } from '$lib/utils';
export let data, form;
@@ -10,24 +10,6 @@
let loading;
let amount, n, d, cvc;
-
- let ease = (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t);
- let i;
-
- let o = $selectedRate;
- $: animate($selectedRate);
- let animate = (n) => {
- clearInterval(i);
-
- let t = 0;
- let d = o - n;
-
- i = setInterval(() => {
- $animatedRate = (o - d * ease(t / 100)).toFixed(2);
- if (t > 80) (o = n) && clearInterval(i);
- t++;
- }, 10);
- };
</script>
<div class="container px-4 max-w-xl mx-auto mt-10 space-y-5">
@@ -141,7 +123,6 @@
<div class="my-auto mr-1">1</div>
<img src="/images/bitcoin.svg" class="w-5 my-auto" alt="Bitcoin" />
</div>
- <div>= {f($animatedRate, currency)}</div>
</div>
<p class="text-secondary">3% credit card fee applies</p>
</div>
diff --git a/src/routes/(app)/launch/purchase/+page.svelte b/src/routes/(app)/launch/purchase/+page.svelte
index 3273752a..fbaa58c0 100644
--- a/src/routes/(app)/launch/purchase/+page.svelte
+++ b/src/routes/(app)/launch/purchase/+page.svelte
@@ -1,7 +1,6 @@
<script>
import { onMount } from 'svelte';
import { enhance } from '$app/forms';
- import { selectedRate } from '$lib/store';
import { post } from '$lib/utils';
import { goto } from '$app/navigation';
diff --git a/src/routes/(app)/login/+page.svelte b/src/routes/(app)/login/+page.svelte
index 75998cd0..eb3ae26b 100644
--- a/src/routes/(app)/login/+page.svelte
+++ b/src/routes/(app)/login/+page.svelte
@@ -1,5 +1,13 @@
<script>
import { RegisterOrLogin } from '$comp';
+ import { onMount } from 'svelte';
+ import { pin } from '$lib/store';
+
+ onMount(() => {
+ $pin = undefined;
+ localStorage.clear();
+ sessionStorage.clear();
+ });
export let form;
</script>
diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte
index cf30db35..9e61cbd6 100644
--- a/src/routes/(app)/payment/[id]/+page.svelte
+++ b/src/routes/(app)/payment/[id]/+page.svelte
@@ -1,6 +1,6 @@
<script>
import { t } from '$lib/translations';
- import { back, copy, f, s, fiat, sats } from '$lib/utils';
+ import { back, copy, f, s, fiat, post, sats, success } from '$lib/utils';
import { Avatar, Icon } from '$comp';
import { format } from 'date-fns';
import { PUBLIC_EXPLORER as expl } from '$env/static/public';
@@ -12,6 +12,11 @@
let { id, amount, created, rate, type, ref, tip, ourfee, fee, currency } = p;
let a = Math.abs(amount);
+ let print = async () => {
+ await post(`/payment/${id}/print`, { id });
+ success('Printing!');
+ };
+
fee = fee || 0;
</script>
@@ -52,6 +57,7 @@
<span class="text-lg text-secondary">Tip</span>
<div>
{f(fiat(tip, rate), currency)}
+ ({Math.round((tip * 100) / Math.abs(a))}%)
<span class="text-secondary text-lg">
⚡️{s(tip)}
</span>
@@ -106,4 +112,11 @@
</div>
</div>
{/if}
+
+ {#if user.username.toLowerCase() === 'laughingbean'}
+ <button
+ class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
+ on:click={print}>Print Receipt</button
+ >
+ {/if}
</div>
diff --git a/src/routes/(app)/payment/[id]/print/+server.js b/src/routes/(app)/payment/[id]/print/+server.js
new file mode 100644
index 00000000..fde834d1
--- /dev/null
+++ b/src/routes/(app)/payment/[id]/print/+server.js
@@ -0,0 +1,7 @@
+import { auth, post } from '$lib/utils';
+import { json } from '@sveltejs/kit';
+
+export async function POST({ cookies, request }) {
+ let body = await request.json();
+ return json(post('/print', body, auth(cookies)));
+}
diff --git a/src/routes/(app)/pot/[name]/+page.svelte b/src/routes/(app)/pot/[name]/+page.svelte
index 2d93abfc..7b3d890b 100644
--- a/src/routes/(app)/pot/[name]/+page.svelte
+++ b/src/routes/(app)/pot/[name]/+page.svelte
@@ -6,7 +6,7 @@
import { toast } from '@zerodevx/svelte-toast';
import { t } from '$lib/translations';
import { copy, f, s, sat, sats } from '$lib/utils';
- import { loginRedirect, selectedRate } from '$lib/store';
+ import { loginRedirect } from '$lib/store';
export let data;
diff --git a/src/routes/(app)/send/+layout.svelte b/src/routes/(app)/send/+layout.svelte
index e5c9c051..6192cd40 100644
--- a/src/routes/(app)/send/+layout.svelte
+++ b/src/routes/(app)/send/+layout.svelte
@@ -8,30 +8,11 @@
export let data;
- let loaded;
let { user } = data;
-
- onMount(() => setTimeout(() => (loaded = true), 500));
let cancel = () => goto(`/${user.username}`);
-
- $: browser && loaded && checkPin($pin);
- let checkPin = async (p) => {
- if (p?.length !== 6 || p === JSON.parse(sessionStorage.getItem('pin'))) return;
- let result;
- try {
- result = await post('/pin', { pin: p });
- } catch (e) {}
-
- if (result) {
- success('Pin confirmed');
- } else {
- fail('Invalid pin');
- $pin = '';
- }
- };
</script>
-{#if loaded && user.haspin && (!$pin || $pin?.length !== 6)}
+{#if user.haspin && (!$pin || $pin?.length !== 6)}
<Pin bind:value={$pin} {cancel} />
{/if}
diff --git a/src/routes/(app)/send/bitcoin/[address]/[...amount]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/[...amount]/+page.svelte
index 77d5fde6..342eeebe 100644
--- a/src/routes/(app)/send/bitcoin/[address]/[...amount]/+page.svelte
+++ b/src/routes/(app)/send/bitcoin/[address]/[...amount]/+page.svelte
@@ -5,15 +5,18 @@
import { Toggle, Slider, Icon, Numpad, Spinner } from '$comp';
import { page } from '$app/stores';
import { fiat as toFiat, f, back, s, sat } from '$lib/utils';
- import { pin, selectedRate } from '$lib/store';
+ import { pin } from '$lib/store';
export let data;
export let form;
+ let { rates } = data;
let { address, amount } = $page.params;
let { balance, currency } = data.user;
let loading, submit, fiat, confirmed, feeRate, min, max, fee, ourfee, stale, subtract, adjusting;
+ $: rate = rates[currency];
+
let toggle = () => (loading = true);
let toggleAdjusting = () => (adjusting = !adjusting);
@@ -64,7 +67,7 @@
{#if confirmed}
<div class="text-center">
<h2 class="text-2xl md:text-3xl font-semibold">
- {f(toFiat(amount, $selectedRate), currency)}
+ {f(toFiat(amount, rate), currency)}
</h2>
<h3 class="text-secondary md:text-lg mb-6 mt-1">⚡️{s(amount)}</h3>
</div>
@@ -74,7 +77,7 @@
<div class="relative">
<h2 class="text-xl font-semibold">
- {f(toFiat(fee + ourfee, $selectedRate), currency)}
+ {f(toFiat(fee + ourfee, rate), currency)}
</h2>
<h3 class="text-secondary mb-6 mt-1">⚡️{s(fee + ourfee)}</h3>
<button class="absolute right-1/4 top-0 text-secondary p-4" on:click={toggleAdjusting}
@@ -83,7 +86,7 @@
</div>
</div>
{:else}
- <Numpad bind:amount bind:fiat {currency} {submit} />
+ <Numpad bind:amount bind:fiat {currency} {submit} bind:rate />
{/if}
<form method="POST" use:enhance on:submit={toggle}>
diff --git a/src/routes/(app)/send/invoice/[id]/+page.server.js b/src/routes/(app)/send/invoice/[id]/+page.server.js
index c9c2b222..4cbbb03f 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.server.js
+++ b/src/routes/(app)/send/invoice/[id]/+page.server.js
@@ -7,6 +7,7 @@ export async function load({ params: { id }, parent, url }) {
let {
amount,
address,
+ currency,
hash,
rate,
prompt,
@@ -17,7 +18,7 @@ export async function load({ params: { id }, parent, url }) {
if (prompt && tip === null) throw redirect(307, `/${recipient.username}/invoice/${id}/tip`);
if (recipient.username === user.username) throw error(500, { message: 'Cannot send to self' });
- return { amount, address, hash, tip, rate, payreq: text, recipient };
+ return { amount, address, currency, hash, tip, rate, payreq: text, recipient };
}
export const actions = {
diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte
index c9cb9392..d5c548a7 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/send/invoice/[id]/+page.svelte
@@ -1,7 +1,7 @@
<script>
import { t } from '$lib/translations';
import { goto } from '$app/navigation';
- import { pin, selectedRate } from '$lib/store';
+ import { pin } from '$lib/store';
import { enhance } from '$app/forms';
import { Avatar, Icon, Numpad, Spinner } from '$comp';
import { page } from '$app/stores';
@@ -9,13 +9,13 @@
export let data;
export let form;
- let { address, payreq, recipient, rate, tip, user } = data;
+ let { address, rate, payreq, recipient, tip, rates, user } = data;
let { currency } = user;
let amount = form?.amount || data.amount;
let a,
af,
- amountFiat = amount * ($selectedRate / sats),
+ amountFiat = amount * (rate / sats),
fiat = !amount;
let setAmount = () => {
@@ -26,6 +26,8 @@
let loading;
let submit = () => (loading = true);
+ $: rate = data.rate * (rates[user.currency] / rates[data.currency]);
+
$: update(form);
let update = () => {
if (form?.message.includes('pin')) $pin = undefined;
@@ -75,7 +77,7 @@
</div>
</div>
{:else}
- <Numpad bind:amount={a} bind:amountFiat={af} {currency} bind:fiat />
+ <Numpad bind:amount={a} bind:amountFiat={af} {currency} bind:fiat bind:rate />
{/if}
<form method="POST" use:enhance on:submit={submit}>
diff --git a/src/routes/(app)/send/lightning/[payreq]/+page.svelte b/src/routes/(app)/send/lightning/[payreq]/+page.svelte
index af07a565..cb1b539e 100644
--- a/src/routes/(app)/send/lightning/[payreq]/+page.svelte
+++ b/src/routes/(app)/send/lightning/[payreq]/+page.svelte
@@ -10,13 +10,14 @@
export let form;
let { payreq } = $page.params;
- let { alias } = data;
+ let { alias, rates } = data;
let { currency } = data.user;
let a;
let maxfee = 100;
$: amount = form?.amount || data.amount;
+ $: rate = rates[currency];
let loading;
let submit = () => (loading = true);
@@ -91,7 +92,7 @@
{:else}
<form method="POST" action="?/setAmount" class="w-[300px] mx-auto" use:enhance>
<input type="hidden" value={a} name="amount" />
- <Numpad bind:amount={a} {currency} />
+ <Numpad bind:amount={a} {currency} {rate} />
<button
type="submit"
class="bg-black text-white rounded-xl h-[48px] flex w-full justify-center items-center font-semibold
diff --git a/src/routes/(app)/send/pot/[name]/[...amount]/+page.svelte b/src/routes/(app)/send/pot/[name]/[...amount]/+page.svelte
index da761cc2..6aecf8f3 100644
--- a/src/routes/(app)/send/pot/[name]/[...amount]/+page.svelte
+++ b/src/routes/(app)/send/pot/[name]/[...amount]/+page.svelte
@@ -10,9 +10,12 @@
export let form;
let { amount, name } = $page.params;
+ let { rates } = data;
let { currency } = data.user;
let loading;
+ $: rate = rates[currency];
+
let submit = () => (loading = true);
$: update(form);
let update = () => {
@@ -32,7 +35,7 @@
{/if}
<div class="container px-4 mt-20 max-w-xl mx-auto">
- <Numpad bind:amount {currency} />
+ <Numpad bind:amount {currency} bind:rate />
<form method="POST" use:enhance on:submit={submit}>
<input name="name" value={name} type="hidden" />
diff --git a/src/routes/(app)/send/user/[username]/[...amount]/+page.server.js b/src/routes/(app)/send/user/[username]/[...amount]/+page.server.js
index c63328e2..a01cdcfc 100644
--- a/src/routes/(app)/send/user/[username]/[...amount]/+page.server.js
+++ b/src/routes/(app)/send/user/[username]/[...amount]/+page.server.js
@@ -1,12 +1,34 @@
import { error, fail, redirect } from '@sveltejs/kit';
-import { fd, auth, get, post } from '$lib/utils';
+import { types, sats, fd, auth, get, post } from '$lib/utils';
-export async function load({ params, parent }) {
- let { user } = await parent();
- let { amount } = params;
+export async function load({ cookies, params, parent }) {
let subject = await get(`/users/${params.username}`);
+
+ let { rates, user } = await parent();
+ let { username } = params;
+ let [amount, currency] = params.amount.split('/');
+
if (subject.username === user?.username) throw error(500, { message: 'Cannot send to self' });
- return { amount, subject };
+
+ let rate;
+ if (amount) {
+ rate = rates[currency ? currency.toUpperCase() : subject.currency];
+ if (!rate) throw error(500, 'Invalid currency symbol');
+ if (currency) amount = (amount * sats) / rate;
+
+ let { hash } = await post(
+ '/invoice',
+ {
+ invoice: { amount, prompt: false, type: types.lightning },
+ user: { username }
+ },
+ auth(cookies)
+ );
+
+ throw redirect(307, `/${username}/invoice/${hash}`);
+ }
+
+ return { amount, rate, subject };
}
export const actions = {
diff --git a/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte b/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
index af6a6368..9ce82d2e 100644
--- a/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
+++ b/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
@@ -1,7 +1,7 @@
<script>
import { t } from '$lib/translations';
import { goto } from '$app/navigation';
- import { pin, selectedRate } from '$lib/store';
+ import { pin } from '$lib/store';
import { enhance } from '$app/forms';
import { AppHeader, Avatar, Icon, Numpad, Spinner } from '$comp';
import { page } from '$app/stores';
@@ -10,23 +10,22 @@
export let data;
export let form;
- let { subject, rates, user } = data;
- let currency = user?.currency || 'USD';
+ let { subject, rate, rates, user } = data;
+ let currency = user.currency || subject.currency || 'USD';
let amount = form?.amount || data.amount;
let a,
af,
fiat = !amount,
hash,
- rate,
amountFiat = 0;
- selectedRate.subscribe((r) => rate || (amountFiat = amount * (r / sats)));
+ $: r = rate || rates[user.currency || subject.currency];
let setAmount = async () => {
amount = a;
amountFiat = parseFloat(af).toFixed(2);
- rate = fiat ? (sats * amountFiat) / amount : $selectedRate;
+ rate = fiat ? (sats * amountFiat) / amount : r;
({ hash } = await post(`/${subject.username}/invoice`, {
invoice: {
amount,
@@ -60,7 +59,7 @@
{/if}
<div class="container px-4 mt-20 max-w-xl mx-auto space-y-8">
- <Numpad bind:amount={a} bind:amountFiat={af} {currency} bind:fiat />
+ <Numpad bind:amount={a} bind:amountFiat={af} {currency} bind:fiat bind:rate={r} />
<form method="POST" use:enhance on:submit={submit}>
<input name="amount" value={amount} type="hidden" />
diff --git a/src/routes/(app)/support/+page.svelte b/src/routes/(app)/support/+page.svelte
index 8dbfc1af..b2f82e89 100644
--- a/src/routes/(app)/support/+page.svelte
+++ b/src/routes/(app)/support/+page.svelte
@@ -1,4 +1,5 @@
<script>
+ import { onDestroy } from 'svelte';
import { fail, success, post } from '$lib/utils';
import { scale } from 'svelte/transition';
import { AppHeader, Icon } from '$comp';
@@ -14,19 +15,32 @@
let email;
let message;
let sent;
+ let recaptchaSiteKey = '6LfCd8YkAAAAANmVJgzN3SQY3n3fv1RhiS5PgMYM';
let submit = (e) => {
e.preventDefault();
grecaptcha.ready(() => {
- grecaptcha
- .execute('6LfCd8YkAAAAANmVJgzN3SQY3n3fv1RhiS5PgMYM', { action: 'submit' })
- .then((token) =>
- post('/support', { email, message, token })
- .then(() => (sent = true))
- .catch(() => fail('problem submitting'))
- );
+ grecaptcha.execute(recaptchaSiteKey, { action: 'submit' }).then((token) =>
+ post('/support', { username: user?.username, email, message, token })
+ .then(() => (sent = true))
+ .catch(() => fail('problem submitting'))
+ );
});
};
+
+ onDestroy(() => {
+ const nodeBadge = document.querySelector('.grecaptcha-badge');
+ if (nodeBadge) {
+ document.body.removeChild(nodeBadge.parentNode);
+ }
+
+ const scriptSelector =
+ "script[src='https://www.google.com/recaptcha/api.js?render=" + recaptchaSiteKey + "']";
+ const script = document.querySelector(scriptSelector);
+ if (script) {
+ script.remove();
+ }
+ });
</script>
<svelte:head>