aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-02-02 23:26:34 -0800
committerAdam Soltys <[email protected]>2023-02-02 23:26:34 -0800
commit01333bb3f33da6b2c51e910c0fe74637a8c8e24e (patch)
treeaf238aebeab67adb0cf8f4cf9037b42270809b44 /src
parent43d893ff0195f14cd1fcb8acec17b7ca20ff6c28 (diff)
downloadcoinos-ui-01333bb3f33da6b2c51e910c0fe74637a8c8e24e.tar.gz
coinos-ui-01333bb3f33da6b2c51e910c0fe74637a8c8e24e.zip
move invoices, combine profile and dashboard
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader.svelte2
-rw-r--r--src/components/Balance.svelte19
-rw-r--r--src/components/Invoice.svelte2
-rw-r--r--src/components/Toggle.svelte3
-rw-r--r--src/components/index.js1
-rw-r--r--src/lib/invoice.js4
-rw-r--r--src/lib/socket.js11
-rw-r--r--src/lib/store.js1
-rw-r--r--src/lib/ticket.js2
-rw-r--r--src/lib/utils.js26
-rw-r--r--src/routes/(app)/[username]/(profile)/+layout.svelte99
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte24
-rw-r--r--src/routes/(app)/[username]/(profile)/followers/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/(profile)/follows/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/address/+page.server.js4
-rw-r--r--src/routes/(app)/[username]/dashboard/+page.server.js8
-rw-r--r--src/routes/(app)/[username]/dashboard/+page.svelte10
-rw-r--r--src/routes/(app)/[username]/invoice/+server.js (renamed from src/routes/(app)/invoice/+server.js)0
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/+layout.server.js (renamed from src/routes/(app)/invoice/[hash]/+layout.server.js)3
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/+layout.svelte (renamed from src/routes/(app)/invoice/[hash]/+layout.svelte)0
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/+page.server.js (renamed from src/routes/(app)/invoice/[hash]/+page.server.js)0
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/+page.svelte123
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte (renamed from src/routes/(app)/invoice/[hash]/paid/+page.svelte)2
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js (renamed from src/routes/(app)/invoice/[hash]/tip/+page.server.js)4
-rw-r--r--src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte (renamed from src/routes/(app)/invoice/[hash]/tip/+page.svelte)6
-rw-r--r--src/routes/(app)/[username]/invoice/sent/+page.svelte (renamed from src/routes/(app)/invoice/sent/+page.svelte)0
-rw-r--r--src/routes/(app)/[username]/receive/[...param]/+page.svelte4
-rw-r--r--src/routes/(app)/[username]/request/[id]/+page.server.js2
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte3
-rw-r--r--src/routes/(app)/invoice/[hash]/+page.svelte156
-rw-r--r--src/routes/(app)/launch/purchase/+page.server.js2
-rw-r--r--src/routes/(app)/send/[...text]/+page.svelte3
-rw-r--r--src/routes/(app)/send/user/[username]/[...amount]/+page.svelte2
33 files changed, 285 insertions, 245 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index 83571e62..29e96ce1 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -34,7 +34,7 @@
</script>
<header
- class="bg-gradient-to-r {$colorTheme} h-[175px] w-full relative bg-cover"
+ class="bg-gradient-to-r {$colorTheme} h-[175px] w-full relative bg-cover mb-20"
style:background-image={bg}
>
<nav class="flex justify-end items-center space-x-4 p-5">
diff --git a/src/components/Balance.svelte b/src/components/Balance.svelte
new file mode 100644
index 00000000..5d72bd45
--- /dev/null
+++ b/src/components/Balance.svelte
@@ -0,0 +1,19 @@
+<script>
+ import { f, s, sat, sats } from '$lib/utils';
+ import { animatedRate } from '$lib/store';
+ import { t } from '$lib/translations';
+
+ export let user;
+</script>
+
+<div class="space-y-2">
+ <div class="text-5xl font-bold tabular-nums">
+ {$animatedRate
+ ? f((user.balance * $animatedRate) / sats, user.currency)
+ : $t('user.dashboard.fetchingRate')}
+ </div>
+
+ <div class="text-secondary text-2xl">
+ ⚡️{s(user.balance)}
+ </div>
+</div>
diff --git a/src/components/Invoice.svelte b/src/components/Invoice.svelte
index a8d9cfc6..b0cd58a2 100644
--- a/src/components/Invoice.svelte
+++ b/src/components/Invoice.svelte
@@ -21,7 +21,7 @@
</div>
</div>
<div class="mx-auto my-auto flex gap-2">
- <a href={`/invoice/${$invoice.id}/tip`}>
+ <a href={`/${invoice.user.username}/invoice/${$invoice.id}/tip`}>
<button class="rounded-full border py-2 px-4 font-bold hover:opacity-80 w-32">
{$t('payments.pay')}
</button>
diff --git a/src/components/Toggle.svelte b/src/components/Toggle.svelte
index 7f3db2f5..3516e48b 100644
--- a/src/components/Toggle.svelte
+++ b/src/components/Toggle.svelte
@@ -1,11 +1,10 @@
<script>
export let id;
- export let checked;
export let value;
</script>
<label for={id} class="inline-flex relative items-center mr-5 cursor-pointer">
- <input type="checkbox" {value} {checked} {id} class="sr-only peer" />
+ <input type="checkbox" bind:checked={value} {id} name={id} class="sr-only peer" />
<div
class="w-11 h-6 bg-gray-200 rounded-full peer dark:bg-gray-700 peer-focus:ring-4 peer-focus:ring-gray-300 dark:peer-focus:ring-gray-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-gray-600"
/>
diff --git a/src/components/index.js b/src/components/index.js
index ea44c7d9..18a821ff 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,4 @@
+export { default as Balance } from './Balance.svelte';
export { default as Lnurlp } from './Lnurlp.svelte';
export { default as Lnurlw } from './Lnurlw.svelte';
export { default as Event } from './Event.svelte';
diff --git a/src/lib/invoice.js b/src/lib/invoice.js
index 983cde2a..4c487172 100644
--- a/src/lib/invoice.js
+++ b/src/lib/invoice.js
@@ -29,6 +29,6 @@ export default async ({ cookies, request, url }) => {
throw redirect(307, `/${user.username}/request/${request_id}`);
}
- if (invoice.prompt) throw redirect(307, `/invoice/${hash}/tip`);
- else throw redirect(307, `/invoice/${hash}`);
+ if (invoice.prompt) throw redirect(307, `/${user.username}/invoice/${hash}/tip`);
+ else throw redirect(307, `/${user.username}/invoice/${hash}`);
};
diff --git a/src/lib/socket.js b/src/lib/socket.js
index 4044d2a2..986fc268 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -60,10 +60,13 @@ export const messages = (data) => ({
let { amount, invoice } = data;
invalidate('app:invoice');
- let payments = get(payments);
- let i = payments.findIndex((p) => p.id === data.id);
- if (~i) (payments[i] = data), payments.set(payments);
- else newPayment.set(true);
+ let p = get(payments);
+ let i = p.findIndex((p) => p.id === data.id);
+
+ if (~i) {
+ p[i] = data;
+ payments.set(p);
+ } else newPayment.set(true);
invalidate((url) => url.pathname === '/payments');
diff --git a/src/lib/store.js b/src/lib/store.js
index d38eb411..93ac3d47 100644
--- a/src/lib/store.js
+++ b/src/lib/store.js
@@ -32,6 +32,7 @@ const persistLocal = (key, defaultValue) => {
return s;
};
+export const animatedRate = writable(0);
export const avatar = writable();
export const banner = writable();
export const colorTheme = writable('from-primary to-gradient');
diff --git a/src/lib/ticket.js b/src/lib/ticket.js
index 708c10f4..e1ebcb8c 100644
--- a/src/lib/ticket.js
+++ b/src/lib/ticket.js
@@ -6,7 +6,7 @@ export const createTicket = async (cookies, username) => {
let { ticket } = await get('/ticket');
let { address } = await post(
- '/invoice',
+ `/${username}/invoice`,
{ invoice: { network: 'liquid' }, user: { username } },
auth(cookies)
);
diff --git a/src/lib/utils.js b/src/lib/utils.js
index 2b5dda90..d0b0b1c2 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -202,3 +202,29 @@ export const stretch = async (password, salt) =>
);
export const bip32 = await BIP32Factory(ecc);
+
+function get_bigrams(string) {
+ var s = string.toLowerCase();
+ var v = s.split('');
+ for (var i = 0; i < v.length; i++) {
+ v[i] = s.slice(i, i + 2);
+ }
+ return v;
+}
+
+export function ss(str1, str2) {
+ if (str1.length > 0 && str2.length > 0) {
+ var pairs1 = get_bigrams(str1);
+ var pairs2 = get_bigrams(str2);
+ var union = pairs1.length + pairs2.length;
+ var hits = 0;
+ for (var x = 0; x < pairs1.length; x++) {
+ for (var y = 0; y < pairs2.length; y++) {
+ if (pairs1[x] == pairs2[y]) hit_count++;
+ }
+ }
+ if (hits > 0) return (2.0 * hits) / union;
+ }
+
+ return 0.0;
+}
diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte
index 6528d688..b318d777 100644
--- a/src/routes/(app)/[username]/(profile)/+layout.svelte
+++ b/src/routes/(app)/[username]/(profile)/+layout.svelte
@@ -1,12 +1,15 @@
<script>
+ import { f, s, sats } from '$lib/utils';
+ import { animatedRate, selectedRate } from '$lib/store';
import { Icon } from '$comp';
import { t } from '$lib/translations';
import { sign, send } from '$lib/nostr';
+ import { v4 } from 'uuid';
export let data;
let events, user, subject, src, text;
$: ({ events, user, subject, src, text } = data);
- $: ({ username: n, display } = subject);
+ $: ({ currency, username: n, display } = subject);
$: username = n.length > 60 ? n.substr(0, 6) : display || n;
@@ -39,12 +42,30 @@
};
$: 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);
+ };
</script>
-<div class="container mx-auto w-full px-4 mb-4 flex flex-wrap md:flex-nowrap">
- <div class="hidden lg:block w-[240px] md:mr-10" />
- <div class="w-[240px] lg:absolute pt-20 space-y-5 left-20 mx-auto md:mr-10">
- <h1 class="text-3xl font-bold text-center mx-auto lg:text-left">{display || username}</h1>
+<div class="container mx-auto w-full px-4 mb-4 flex flex-wrap lg:flex-nowrap">
+ <div class="hidden lg:block w-[240px] lg:mr-10" />
+ <div class="w-[240px] lg:absolute space-y-5 left-20 mx-auto lg:mr-10 mb-10">
+ <h1 class="text-3xl font-bold text-center mx-auto">{display || username}</h1>
<div class="text-secondary mx-auto text-center lg:text-left lg:mx-0">
{subject.address && subject.address !== 'null' ? subject.address : ''}
@@ -100,7 +121,7 @@
</a>
</div>
{/if}
- {#if !subject.anon}
+ {#if !subject.anon && subject.username !== user?.username}
<div class="w-full flex">
<a href={`/${subject.username}/receive`} class="mx-auto">
<button class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60">
@@ -111,26 +132,64 @@
</button>
</a>
</div>
+ {/if}
- <!-- {#if user?.username !== subject.username} -->
- <!-- <div class="w-full flex"> -->
- <!-- <a href={`/${subject.username}/request`} 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-1" /> -->
- <!-- <div>{$t('payments.requestAnInvoice')}</div> -->
- <!-- </div> -->
- <!-- </button> -->
- <!-- </a> -->
- <!-- </div> -->
- <!-- {/if} -->
+ {#if user?.id === subject.id}
+ <div class="w-full flex">
+ <a href={`/send`} 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.dashboard.send')}</div>
+ </div>
+ </button>
+ </a>
+ </div>
+ <div class="w-full flex">
+ <a href={`/${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" />
+ <div class="mt-1">{$t('user.dashboard.receive')}</div>
+ </div>
+ </button>
+ </a>
+ </div>
+ <!-- <div class="w-full flex"> -->
+ <!-- <a href={`/${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="support" style="mr-2" /> -->
+ <!-- <div class="mt-1">{$t('user.messages')}</div> -->
+ <!-- </div> -->
+ <!-- </button> -->
+ <!-- </a> -->
+ <!-- </div> -->
{/if}
</div>
</div>
- <div class="w-full md:pt-12 lg:pt-0">
- <div class="mx-auto space-y-5 mt-5 lg:max-w-lg xl:max-w-2xl">
+ <div class="w-full">
+ <div class="mx-auto space-y-5 lg:max-w-lg xl:max-w-2xl">
<slot />
</div>
</div>
</div>
+
+{#if currency && $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">
+ <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>
+ <div class="text-secondary flex ml-auto">
+ <div class="flex">
+ <div class="mr-1">⚡️{s((1 * sats) / $animatedRate)} =</div>
+ <div>{f(1, currency)}</div>
+ </div>
+ </div>
+ </div>
+{/if}
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte
index f9ded033..40c73ea4 100644
--- a/src/routes/(app)/[username]/(profile)/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/+page.svelte
@@ -1,29 +1,11 @@
<script>
- import { Feed } from '$comp';
+ import { Balance, Feed } from '$comp';
import { t } from '$lib/translations';
export let data;
let { events, subject, user } = data;
</script>
-<!-- <div class="font-bold flex justify-around items-center border-b pb-3 text-secondary mt-20"> -->
-<!-- <a href={`/${user.username}`}> -->
-<!-- <button class="hover:opacity-80 uppercase" class:text-black={true}> -->
-<!-- {$t(`user.notes`)} -->
-<!-- </button> -->
-<!-- </a> -->
-<!-- <a href={`/${user.username}`}> -->
-<!-- <button class="hover:opacity-80 uppercase"> -->
-<!-- {$t(`user.feed`)} -->
-<!-- </button> -->
-<!-- </a> -->
-<!-- <a href={`/${user.username}`}> -->
-<!-- <button class="hover:opacity-80 uppercase"> -->
-<!-- {$t(`user.messages`)} -->
-<!-- </button> -->
-<!-- </a> -->
-<!-- </div> -->
-
-<div class="mt-20">
- <Feed {events} user={subject?.username === user?.username && user} />
+<div class="flex justify-center lg:justify-start">
+ <Balance {user} />
</div>
diff --git a/src/routes/(app)/[username]/(profile)/followers/+page.svelte b/src/routes/(app)/[username]/(profile)/followers/+page.svelte
index 87a3b947..77b337b6 100644
--- a/src/routes/(app)/[username]/(profile)/followers/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/followers/+page.svelte
@@ -13,7 +13,7 @@
<svelte:window bind:innerWidth={w} />
-<div class="mt-24 mb-20 px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
+<div class="px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
<h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold">Followers</h1>
{#if browser}
diff --git a/src/routes/(app)/[username]/(profile)/follows/+page.svelte b/src/routes/(app)/[username]/(profile)/follows/+page.svelte
index 97269f45..78566fc4 100644
--- a/src/routes/(app)/[username]/(profile)/follows/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/follows/+page.svelte
@@ -12,7 +12,7 @@
<svelte:window bind:innerWidth={w} />
-<div class="mt-24 mb-20 px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
+<div class="px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
<h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold">Following</h1>
{#if browser}
diff --git a/src/routes/(app)/[username]/address/+page.server.js b/src/routes/(app)/[username]/address/+page.server.js
index 5d7c3044..247a33a2 100644
--- a/src/routes/(app)/[username]/address/+page.server.js
+++ b/src/routes/(app)/[username]/address/+page.server.js
@@ -5,6 +5,6 @@ export async function load({ cookies, params, parent }) {
let user = (await parent()).subject;
let rates = await get('/rates');
let invoice = { type: 'bitcoin' };
- let { hash } = await post('/invoice', { invoice, user }, auth(cookies));
- throw redirect(307, `/invoice/${hash}`);
+ let { hash } = await post(`/invoice`, { invoice, user }, auth(cookies));
+ throw redirect(307, `/${user.username}/invoice/${hash}`);
}
diff --git a/src/routes/(app)/[username]/dashboard/+page.server.js b/src/routes/(app)/[username]/dashboard/+page.server.js
index f7e276a0..ae66a20d 100644
--- a/src/routes/(app)/[username]/dashboard/+page.server.js
+++ b/src/routes/(app)/[username]/dashboard/+page.server.js
@@ -1,6 +1,4 @@
-import { auth, get } from '$lib/utils';
-
-export async function load({ cookies, depends }) {
- depends('app:invoice');
- return get('/requests', auth(cookies));
+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
index feb49c65..d136943e 100644
--- a/src/routes/(app)/[username]/dashboard/+page.svelte
+++ b/src/routes/(app)/[username]/dashboard/+page.svelte
@@ -81,16 +81,6 @@
>{$t('user.dashboard.receive')}</button
>
</a>
- <a href={`/${user.username}/address`}>
- <button class="rounded-full border py-4 px-5 font-bold hover:opacity-80 w-full"
- >{$t('user.dashboard.deposit')}</button
- >
- </a>
- <a href={`/send/pot/${v4()}`}>
- <button class="rounded-full border py-4 px-5 font-bold hover:opacity-80 w-full"
- >{$t('user.dashboard.voucher')}</button
- >
- </a>
</div>
<!-- <div> -->
diff --git a/src/routes/(app)/invoice/+server.js b/src/routes/(app)/[username]/invoice/+server.js
index 1321739e..1321739e 100644
--- a/src/routes/(app)/invoice/+server.js
+++ b/src/routes/(app)/[username]/invoice/+server.js
diff --git a/src/routes/(app)/invoice/[hash]/+layout.server.js b/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
index d38f945f..0f6168e3 100644
--- a/src/routes/(app)/invoice/[hash]/+layout.server.js
+++ b/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
@@ -11,7 +11,8 @@ export async function load({ depends, params, url }) {
amount = parseInt(amount);
let paid = (!amount && received) || (amount > 0 && received >= amount);
- if (paid && !url.pathname.endsWith('paid')) throw redirect(307, `/invoice/${hash}/paid`);
+ if (paid && !url.pathname.endsWith('paid'))
+ throw redirect(307, `/${params.username}/invoice/${hash}/paid`);
let sm = Qr.drawImg(invoice.text, { size: 300 });
diff --git a/src/routes/(app)/invoice/[hash]/+layout.svelte b/src/routes/(app)/[username]/invoice/[hash]/+layout.svelte
index 4fa864ce..4fa864ce 100644
--- a/src/routes/(app)/invoice/[hash]/+layout.svelte
+++ b/src/routes/(app)/[username]/invoice/[hash]/+layout.svelte
diff --git a/src/routes/(app)/invoice/[hash]/+page.server.js b/src/routes/(app)/[username]/invoice/[hash]/+page.server.js
index 1068f273..1068f273 100644
--- a/src/routes/(app)/invoice/[hash]/+page.server.js
+++ b/src/routes/(app)/[username]/invoice/[hash]/+page.server.js
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+page.svelte b/src/routes/(app)/[username]/invoice/[hash]/+page.svelte
new file mode 100644
index 00000000..6d7e1dda
--- /dev/null
+++ b/src/routes/(app)/[username]/invoice/[hash]/+page.svelte
@@ -0,0 +1,123 @@
+<script>
+ import { send } from '$lib/socket';
+ import { back, copy, f, get, sat, reverseFormat, s, sats } from '$lib/utils';
+ import { tick, onMount, onDestroy } from 'svelte';
+ import { browser } from '$app/environment';
+ import { last } from '$lib/store';
+ import { Avatar, Icon, Heart, Image } from '$comp';
+ import { t } from '$lib/translations';
+ import screenfull from 'screenfull';
+
+ export let data;
+
+ $: refresh(data);
+ let { invoice, id, user, sm, lg } = data;
+ let {
+ address,
+ amount,
+ type,
+ rate,
+ received,
+ prompt,
+ text,
+ tip,
+ user: { username, currency }
+ } = invoice;
+
+ let showQr = !amount;
+
+ let src = sm;
+
+ let qr;
+ let tipPercent = 0;
+
+ let refresh = (data) => {
+ ({ invoice, id } = data);
+ ({
+ address,
+ amount,
+ type,
+ rate,
+ received,
+ prompt,
+ text,
+ tip,
+ user: { username, currency }
+ } = invoice);
+
+ tipPercent = (tip / amount) * 100;
+ };
+
+ $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ $: tipAmount = ((tip * rate) / sats).toFixed(2);
+
+ let subbed;
+ onMount(() => {
+ browser &&
+ last.subscribe((v) => {
+ if (!v || subbed) return;
+ subbed = true;
+ send('subscribe', invoice);
+ });
+ });
+
+ $: link = address ? text : `lightning:${text}`;
+ $: txt = address || text;
+
+ let full;
+ let toggle = () => {
+ screenfull.toggle(qr);
+ full = !full;
+ if (full) src = lg;
+ else src = sm;
+ };
+</script>
+
+<div class="container mx-auto max-w-lg px-4 space-y-5">
+ <div class="relative flex">
+ <div class="flex mx-auto w-[360px] h-[360px]">
+ <img
+ {src}
+ class:p-4={full}
+ class="w-[300px] h-[300px] mx-auto z-10 mt-[20px]"
+ bind:this={qr}
+ on:click={toggle}
+ on:keydown={toggle}
+ alt={txt}
+ />
+ </div>
+ <div
+ class="absolute m-auto left-0 right-0 w-[340px] h-[340px] rounded-full bg-gradient-to-r from-[#F2F6FC] to-[#E1E3FF] z-0"
+ />
+ </div>
+
+ {#if amount > 0}
+ <div class="text-center font-bold text-2xl">
+ <div>
+ {f(amountFiat, currency)}
+
+ {#if tip}
+ <span class="text-sm">
+ +{f(tip * (rate / sats), currency)}
+ </span>
+ {/if}
+ </div>
+ <div>
+ <span class="text-secondary font-normal text-lg">{`${sat(amount)}`}</span>
+
+ {#if tip}
+ <span class="text-sm text-secondary font-normal">
+ +{sat(tip)}
+ </span>
+ {/if}
+ </div>
+ </div>
+ {/if}
+
+ <div class="w-full flex justify-center">
+ <button class="flex rounded-full border py-2 px-5 hover:opacity-80" on:click={() => copy(txt)}
+ ><Icon icon="copy" style="mr-1" />
+ <div class="text-secondary">{txt.substr(0, 10)}..{txt.substr(-6)}</div></button
+ >
+ </div>
+</div>
diff --git a/src/routes/(app)/invoice/[hash]/paid/+page.svelte b/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
index 2ccbc971..432b137a 100644
--- a/src/routes/(app)/invoice/[hash]/paid/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
@@ -55,7 +55,7 @@
{/if}
</div>
-<a href={`/${user.username}/receive`}>
+<a href={`/${user.username}/payments`}>
<div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
</a>
diff --git a/src/routes/(app)/invoice/[hash]/tip/+page.server.js b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js
index c78e5020..814900fb 100644
--- a/src/routes/(app)/invoice/[hash]/tip/+page.server.js
+++ b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js
@@ -1,9 +1,9 @@
import invoice from '$lib/invoice';
import { redirect } from '@sveltejs/kit';
-export async function load({ parent }) {
+export async function load({ parent, params }) {
let { invoice } = await parent();
- if (!invoice.amount) throw redirect(307, `/invoice/${invoice.id}`);
+ if (!invoice.amount) throw redirect(307, `/${params.username}/invoice/${invoice.id}`);
}
export const actions = {
diff --git a/src/routes/(app)/invoice/[hash]/tip/+page.svelte b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
index ea0ab903..d033c413 100644
--- a/src/routes/(app)/invoice/[hash]/tip/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import { invoice as inv, request } from '$lib/store';
- import { back, copy, focus, f, sat, get, reverseFormat, s, sats } from '$lib/utils';
+ import { copy, focus, f, sat, get, reverseFormat, s, sats } from '$lib/utils';
import { Icon } from '$comp';
import { goto } from '$app/navigation';
import { t } from '$lib/translations';
@@ -109,10 +109,6 @@
onMount(() => ($request = undefined));
</script>
-<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}>
- <Icon icon="arrow-left" style="w-10" />
-</button>
-
<div class="container px-4 max-w-lg text-center mx-auto">
<form method="POST" use:enhance class:invisible={submitting}>
<input type="hidden" name="amount" value={amount} />
diff --git a/src/routes/(app)/invoice/sent/+page.svelte b/src/routes/(app)/[username]/invoice/sent/+page.svelte
index ae71eb2e..ae71eb2e 100644
--- a/src/routes/(app)/invoice/sent/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/sent/+page.svelte
diff --git a/src/routes/(app)/[username]/receive/[...param]/+page.svelte b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
index 7ca2770e..29a0f7a5 100644
--- a/src/routes/(app)/[username]/receive/[...param]/+page.svelte
+++ b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
@@ -16,7 +16,7 @@
let amount;
- let { currency, username } = data.subject;
+ let { currency, username, prompt } = data.subject;
let { user } = data;
let submit;
</script>
@@ -31,7 +31,7 @@
<input type="hidden" name="request_id" value={request.id} />
{/if}
- <input type="hidden" name="prompt" value={false} />
+ <input type="hidden" name="prompt" value={prompt} />
<div class="space-y-3 w-[300px] mx-auto">
<Numpad bind:amount bind:currency {submit} />
diff --git a/src/routes/(app)/[username]/request/[id]/+page.server.js b/src/routes/(app)/[username]/request/[id]/+page.server.js
index 001bd6e0..542a3ccb 100644
--- a/src/routes/(app)/[username]/request/[id]/+page.server.js
+++ b/src/routes/(app)/[username]/request/[id]/+page.server.js
@@ -14,7 +14,7 @@ export let load = async ({ cookies, depends, locals: { user }, params }) => {
request.recipient.username === user.username &&
((received && !amount) || received >= amount)
)
- throw redirect(307, `/invoice/${id}/paid`);
+ throw redirect(307, `/${user.username}/invoice/${id}/paid`);
if (request.requester.username === user.username) throw redirect(307, `/send/${id}`);
}
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
index e9fcc5ba..94dc8c88 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
@@ -25,7 +25,8 @@
<div>
<div class="flex justify-between items-center">
<span class="font-bold">{$t('user.settings.tipPrompt')}</span>
- <Toggle id="sms-notify" />
+ {user.prompt}
+ <Toggle id="prompt" checked={user.prompt} bind:value={user.prompt} />
</div>
<p class="text-secondary mt-1 w-9/12">
{$t('user.settings.tipPromptDescription')}
diff --git a/src/routes/(app)/invoice/[hash]/+page.svelte b/src/routes/(app)/invoice/[hash]/+page.svelte
deleted file mode 100644
index a2f05cc9..00000000
--- a/src/routes/(app)/invoice/[hash]/+page.svelte
+++ /dev/null
@@ -1,156 +0,0 @@
-<script>
- import { send } from '$lib/socket';
- import { back, copy, f, get, sat, reverseFormat, s, sats } from '$lib/utils';
- import { tick, onMount, onDestroy } from 'svelte';
- import { browser } from '$app/environment';
- import { last } from '$lib/store';
- import { Avatar, Icon, Heart, Image } from '$comp';
- import { t } from '$lib/translations';
- import screenfull from 'screenfull';
-
- export let data;
-
- $: refresh(data);
- let { invoice, id, user, sm, lg } = data;
- let {
- address,
- amount,
- type,
- rate,
- received,
- prompt,
- text,
- tip,
- user: { username, currency }
- } = invoice;
-
- let showQr = !amount;
-
- let src = sm;
-
- let qr;
- let tipPercent = 0;
-
- let refresh = (data) => {
- ({ invoice, id } = data);
- ({
- address,
- amount,
- type,
- rate,
- received,
- prompt,
- text,
- tip,
- user: { username, currency }
- } = invoice);
-
- tipPercent = (tip / amount) * 100;
- };
-
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
- $: tipAmount = ((tip * rate) / sats).toFixed(2);
-
- let subbed;
- onMount(() => {
- browser &&
- last.subscribe((v) => {
- if (!v || subbed) return;
- subbed = true;
- send('subscribe', invoice);
- });
- });
-
- $: link = address ? text : `lightning:${text}`;
-
- let full;
- let toggle = () => {
- screenfull.toggle(qr);
- full = !full;
- if (full) src = lg;
- else src = sm;
- };
-</script>
-
-<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}>
- <Icon icon="arrow-left" style="w-10" />
-</button>
-
-<div class="container mx-auto max-w-lg px-4 space-y-2 sm:space-y-5">
- <div>
- <div class="flex w-full">
- <div class="mx-auto">
- <a href="/{username}" class="text-black font-semibold hover:opacity-80 mx-auto">
- <div class="flex my-auto">
- <Avatar user={invoice.user} size={20} />
- <div class="my-auto text-lg">{username}</div>
- </div>
- </a>
- </div>
- </div>
- </div>
-
- <div class="w-full">
- <img
- {src}
- class:p-4={full}
- class="w-[300px] mx-auto"
- bind:this={qr}
- on:click={toggle}
- on:keydown={toggle}
- alt={address || text}
- />
- </div>
-
- {#if address}
- <div class="text-secondary text-center">{address}</div>
- {/if}
-
- <div class="flex gap-2 justify-center">
- <button
- class="flex rounded-full border py-2 px-5 font-bold hover:opacity-80"
- on:click={() => copy(address ? address : text)}
- ><Icon icon="copy" style="mr-1" />
- <div>Copy</div></button
- >
-
- {#if user && user.username !== username}
- <a href={`/send/${invoice.id}`}>
- <button class="flex rounded-full border py-2 px-5 font-bold hover:opacity-80">
- <Icon icon="send" style="mr-1" />
- <div class="my-auto">Pay</div>
- </button>
- </a>
- {/if}
- </div>
-
- <div class="space-y-2 w-80 mx-auto">
- {#if invoice.tip}
- <div class="flex justify-between">
- {$t('invoice.invoice')}
- <span>
- {f(amountFiat, currency)}
- <span class="text-secondary">{`${sat(amount)}`}</span>
- </span>
- </div>
-
- <div class="flex justify-between">
- {$t('invoice.tip')}
- <span
- >{f(tipAmount, currency)}
- <span class="text-secondary">{`${sat(tip)}`}</span>
- </span>
- </div>
- {/if}
-
- {#if amount > 0}
- <div class="flex flex-wrap justify-between font-bold text-2xl !my-5">
- <span class="mr-1">{$t('invoice.total')}</span>
- <span
- >{f(amountFiat + parseFloat(tipAmount), currency)}
- <span class="text-secondary font-normal">{`${sat(tip + amount)}`}</span></span
- >
- </div>
- {/if}
- </div>
-</div>
diff --git a/src/routes/(app)/launch/purchase/+page.server.js b/src/routes/(app)/launch/purchase/+page.server.js
index ad5cb039..a3043d9c 100644
--- a/src/routes/(app)/launch/purchase/+page.server.js
+++ b/src/routes/(app)/launch/purchase/+page.server.js
@@ -40,6 +40,6 @@ export const actions = {
let { id } = await post('/invoice', { invoice, user }, auth(cookies));
- throw redirect(307, `/invoice/${id}`);
+ throw redirect(307, `/${user.username}/invoice/${id}`);
}
};
diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte
index 92ee7a33..e3d8091f 100644
--- a/src/routes/(app)/send/[...text]/+page.svelte
+++ b/src/routes/(app)/send/[...text]/+page.svelte
@@ -98,9 +98,6 @@
<Avatar user={c} size={20} disabled={true} />
<div class="my-auto text-left">
<p class="ml-1 text-lg break-words">{c.username}</p>
- <p class="ml-1 text-secondary">
- {format(parseISO(c.last), 'MMM d')}
- </p>
</div>
</div>
</div>
diff --git a/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte b/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
index a5b463be..87eba733 100644
--- a/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
+++ b/src/routes/(app)/send/user/[username]/[...amount]/+page.svelte
@@ -24,7 +24,7 @@
amount = a;
amountFiat = af;
- ({ hash } = await post('/invoice', {
+ ({ hash } = await post(`/${recipient.username}/invoice`, {
invoice: {
amount,
rate: rates[recipient.currency],