aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-10-04 20:28:29 -0700
committerAdam Soltys <[email protected]>2022-10-04 20:28:29 -0700
commit59d43ba294e49cbb46ea4d2d0ddb0d22bbc7ba6e (patch)
treedead06dbd4ba44f0044ba916a5294ceccf6511fe
parent4f03f2401cc7bc58420dd2236ffb6c3424c79b32 (diff)
downloadcoinos-ui-59d43ba294e49cbb46ea4d2d0ddb0d22bbc7ba6e.tar.gz
coinos-ui-59d43ba294e49cbb46ea4d2d0ddb0d22bbc7ba6e.zip
tipping fixes
-rw-r--r--package.json1
-rw-r--r--pnpm-lock.yaml12
-rw-r--r--src/components/Qr.svelte22
-rw-r--r--src/components/Tip.svelte135
-rw-r--r--src/lib/invoice.js20
-rw-r--r--src/lib/socket.js13
-rw-r--r--src/locales/en.json2
-rw-r--r--src/routes/[username]/receive/+page.server.js20
-rw-r--r--src/routes/invoice/[id]/+page.server.js5
-rw-r--r--src/routes/invoice/[id]/+page.svelte9
-rw-r--r--src/routes/invoice/[id]/paid/+page.svelte23
-rw-r--r--static/icons/check.svg35
12 files changed, 115 insertions, 182 deletions
diff --git a/package.json b/package.json
index 5663853d..3afd183a 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,6 @@
"format": "prettier --write --plugin-search-dir=. ."
},
"devDependencies": {
- "@lottiefiles/svelte-lottie-player": "^0.2.0",
"@sveltejs/adapter-node": "next",
"@sveltejs/kit": "1.0.0-next.505",
"@zerodevx/svelte-toast": "^0.7.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4538dda2..52f20ba5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,7 +1,6 @@
lockfileVersion: 5.4
specifiers:
- '@lottiefiles/svelte-lottie-player': ^0.2.0
'@sveltejs/adapter-node': next
'@sveltejs/kit': 1.0.0-next.505
'@zerodevx/svelte-toast': ^0.7.2
@@ -27,7 +26,6 @@ specifiers:
vite: ^3.1.4
devDependencies:
- '@lottiefiles/svelte-lottie-player': 0.2.0
'@sveltejs/adapter-node': 1.0.0-next.96
'@zerodevx/svelte-toast': 0.7.2
@@ -72,12 +70,6 @@ packages:
dev: true
optional: true
- /@lottiefiles/svelte-lottie-player/0.2.0:
- resolution: {integrity: sha512-sV8YkO8hCDGq67LCCqjT+JW6cAbVCIw9wtgrOWz+Ao6Q8cD7ZvdsCiipSIMIH55Ja6MWwEXP4N4nKD+jL3XQLg==}
- dependencies:
- lottie-web: 5.9.6
- dev: true
-
/@nodelib/fs.scandir/2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -1059,10 +1051,6 @@ packages:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
- /lottie-web/5.9.6:
- resolution: {integrity: sha512-JFs7KsHwflugH5qIXBpB4905yC1Sub2MZWtl/elvO/QC6qj1ApqbUZJyjzJseJUtVpgiDaXQLjBlIJGS7UUUXA==}
- dev: true
-
/magic-string/0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
dependencies:
diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte
index 099d5fa5..23282589 100644
--- a/src/components/Qr.svelte
+++ b/src/components/Qr.svelte
@@ -1,4 +1,5 @@
<script>
+ import { fly, fade } from 'svelte/transition';
import screenfull from 'screenfull';
import { browser } from '$app/environment';
import { onMount, tick } from 'svelte';
@@ -7,16 +8,14 @@
export let image, text, qr, fullQr, full;
let toggle = async () => {
+ console.log('FULL', full);
full = !full;
await tick();
screenfull.toggle(fullQr.firstChild);
};
let opts = {
- height: 300,
- width: 300,
type: 'canvas',
- data: text,
backgroundOptions: {
color: 'rgba(0, 0, 0, 0)'
},
@@ -33,26 +32,33 @@
}
};
+ let mask = false;
$: update(text);
let update = async (text, fullscreen) => {
+ mask = true;
if (!(browser && text)) return;
let { default: QRCodeStyling } = await import('qr-code-styling');
+ opts.data = text;
+ opts.height = opts.width = 300;
const qrCode = new QRCodeStyling(opts);
- opts.height = Math.min(window.innerWidth, window.innerHeight);
- opts.width = opts.height;
+ opts.height = opts.width = Math.min(window.innerWidth, window.innerHeight);
const fullQrCode = new QRCodeStyling(opts);
- while (qr.firstChild) qr.removeChild(qr.lastChild);
+ while (qr && qr.firstChild) qr.removeChild(qr.lastChild);
qrCode.append(qr);
- while (fullQr.firstChild) fullQr.removeChild(fullQr.lastChild);
+ while (fullQr && fullQr.firstChild) fullQr.removeChild(fullQr.lastChild);
fullQrCode.append(fullQr);
+ mask = false;
};
</script>
-<div bind:this={qr} on:click={toggle} class:hidden={full} />
+{#if mask}
+ <div class="absolute bg-white w-[300px] h-[300px] t-0 l-0 z-10" out:fade />
+{/if}
+<div bind:this={qr} on:click={toggle} class:hidden={full} class="relative overflow-visible" />
<div bind:this={fullQr} on:click={toggle} class:hidden={!full} />
<style>
diff --git a/src/components/Tip.svelte b/src/components/Tip.svelte
index 83bf0dfa..093fef46 100644
--- a/src/components/Tip.svelte
+++ b/src/components/Tip.svelte
@@ -1,24 +1,15 @@
<script>
+ import { enhance } from '$app/forms';
import { Icon } from '$comp';
import { t } from '$lib/translations';
import { f, post, s } from '$lib/utils';
import { tick } from 'svelte';
import { goto } from '$app/navigation';
- export let amountFiat,
- showCustomAmount,
- showMobileTip,
- tipPercent,
- tipAmount,
- amount,
- currency,
- tip,
- prompt,
- rate,
- text,
- username;
+ export let amountFiat, showMobileTip, tipPercent, tipAmount, amount, currency, tip, username;
const tipAmounts = ['None', '10%', '15%', '20%'];
+ let showCustomAmount;
let customInput;
let customTipAmount;
@@ -26,42 +17,17 @@
let apply = async () => {
if (customTipAmount > 0) {
tipPercent = (customTipAmount / amountFiat) * 100;
- update();
showMobileTip = false;
showCustomAmount = false;
+ update();
}
};
- let update = async () => {
- await tick();
- let { uuid } = await post(`/invoice`, {
- amount: parseInt(amount + tip),
- prompt,
- rate,
- tip,
- text,
- user: { username }
- });
-
- goto(`/invoice/${uuid}`);
- };
-
const handleCustomTipAmount = (e) => {
tipPercent = 0;
customTipAmount = e.target.value;
};
- const handleMobileClose = () => {
- tipPercent = 0;
- if (customInput) {
- customInput.value = '';
- }
- customTipAmount = 0;
- tipAmount = 0;
- showMobileTip = false;
- showCustomAmount = false;
- };
-
let timeout;
const handleSlide = (e) => {
customTipAmount = '';
@@ -71,7 +37,7 @@
tipPercent = e.target.value;
clearTimeout(timeout);
- timeout = setTimeout(update, 100);
+ timeout = setTimeout(update, 800);
};
const handleTipButtonClick = (amount) => {
@@ -88,6 +54,12 @@
showMobileTip = false;
update();
};
+
+ let submit;
+ let update = async () => {
+ await tick();
+ submit.click();
+ };
</script>
<div
@@ -95,40 +67,34 @@
? 'bottom-0'
: '-top-full'} bg-white p-6 md:p-0 rounded-t-3xl md:rounded-none left-0 md:static text-center space-y-5"
>
- <div class="flex justify-end items-center">
- <button class="block md:hidden bg-primary rounded-full p-2" on:click={handleMobileClose}
- ><Icon icon="close" /></button
- >
- <button
- class="hidden {showCustomAmount ? 'md:block' : ''}"
- on:click={() => (showCustomAmount = false)}
- ><Icon icon="close" style="hover:opacity-80" /></button
- >
- </div>
- <h1 class="hidden md:block text-4xl font-semibold">{$t('invoice.addTipq')}</h1>
- {#if !showCustomAmount}
- <div>
- <span class="font-semibold mr-1">{f(tipAmount, currency)}</span><span
- class="text-secondary font-semibold text-sm">{`(${s(tip)} SAT)`}</span
- >
- <span class="block text-secondary text-sm">{Math.round(tipPercent)}%</span>
- </div>
+ <form method="POST" use:enhance>
+ <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="prompt" value="true" />
- <input
- id="slider"
- type="range"
- min="0"
- max="100"
- value={tipPercent}
- class="px-2 py-0"
- on:input={handleSlide}
- on:change={() => (showMobileTip = false)}
- />
- {/if}
- <div>
+ <h1 class="hidden md:block text-4xl font-semibold">{$t('invoice.addTipq')}</h1>
{#if !showCustomAmount}
+ <div>
+ <span class="font-semibold mr-1">{f(tipAmount, currency)}</span><span
+ class="text-secondary font-semibold text-sm">{`(${s(tip)} SAT)`}</span
+ >
+ <span class="block text-secondary text-sm">{Math.round(tipPercent)}%</span>
+ </div>
+
+ <input
+ id="slider"
+ type="range"
+ min="0"
+ max="100"
+ value={tipPercent}
+ class="px-2 py-0 mb-4"
+ on:input={handleSlide}
+ on:change={() => (showMobileTip = false)}
+ />
{#each tipAmounts as amount}
<button
+ type="button"
class="bg-black text-white md:text-black md:bg-primary md:hover:bg-black md:hover:text-white w-16 md:w-20 py-3 m-1 rounded-2xl font-semibold {customTipAmount
? ''
: Math.round(tipPercent) === parseInt(amount.slice(0, 2)) ||
@@ -138,8 +104,21 @@
on:click={() => handleTipButtonClick(amount)}>{amount}</button
>
{/each}
+
+ <div>
+ <button
+ type="button"
+ class="w-full md:w-auto mt-2 bg-black md:bg-primary text-white md:text-black md:hover:bg-black md:hover:text-white font-semibold py-3 px-7 rounded-2xl"
+ on:click={() => (showCustomAmount = true)}>Custom amount</button
+ >
+ </div>
{/if}
- {#if showCustomAmount}
+
+ <button type="submit" bind:this={submit} />
+ </form>
+
+ {#if showCustomAmount}
+ <form on:submit|preventDefault={apply}>
<div class="relative">
<span
class="absolute top-[18px] left-5 font-semibold {!customTipAmount
@@ -149,28 +128,22 @@
<input
bind:this={customInput}
type="number"
+ step="0.01"
on:input={(e) => handleCustomTipAmount(e)}
class="pl-10"
placeholder="Other"
/>
<button
+ type="submit"
class="w-full mt-2 bg-black text-white font-semibold py-3 px-7 rounded-2xl {!customTipAmount
? 'opacity-50'
: 'opacity-100 hover:opacity-80'}"
- disabled={!customTipAmount}
- on:click={apply}>Apply</button
+ disabled={!customTipAmount}>Apply</button
>
<!-- found missing translation --->
</div>
- {:else}
- <div>
- <button
- class="w-full md:w-auto mt-2 bg-black md:bg-primary text-white md:text-black md:hover:bg-black md:hover:text-white font-semibold py-3 px-7 rounded-2xl"
- on:click={() => (showCustomAmount = true)}>Custom amount</button
- >
- </div>
- {/if}
- </div>
+ </form>
+ {/if}
</div>
<div
diff --git a/src/lib/invoice.js b/src/lib/invoice.js
new file mode 100644
index 00000000..a0aa8402
--- /dev/null
+++ b/src/lib/invoice.js
@@ -0,0 +1,20 @@
+import { auth, get, post } from '$lib/utils';
+import { redirect } from '@sveltejs/kit';
+
+export default async ({ cookies, request }) => {
+ let form = await request.formData();
+
+ let invoice = {
+ amount: parseInt(form.get('amount')),
+ tip: parseInt(form.get('tip')),
+ network: 'lightning',
+ prompt: form.get('prompt') === 'true',
+ rate: await get('/rate')
+ };
+
+ let user = { username: form.get('username') };
+
+ let { uuid } = await post('/invoice', { invoice, user }, auth(cookies));
+
+ throw redirect(307, `/invoice/${uuid}`);
+};
diff --git a/src/lib/socket.js b/src/lib/socket.js
index 6317595b..a419faeb 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -19,12 +19,16 @@ export const messages = (data) => ({
},
payment() {
- if (data.invoice) invoices.set({ ...get(invoices), [data.invoice.uuid]: data.invoice });
+ let { amount, invoice } = data;
+ if (invoice) {
+ console.log('updating invoice', invoice.uuid, invoice.received, invoice.amount);
+ invoices.set({ ...get(invoices), [invoice.uuid]: invoice });
+ }
newPayment.set(true);
- if (data.amount > 0) {
- success(`Received ${data.amount} sats!`);
+ if (amount > 0) {
+ success(`Received ${amount} sats!`);
} else {
- success(`Sent ${-data.amount} sats!`);
+ success(`Sent ${-amount} sats!`);
}
},
@@ -37,7 +41,6 @@ const maxReconnectDelay = 16000;
let currentReconnectDelay = initialReconnectDelay;
export function connect(t) {
- console.log('CONNECT');
token = t;
clearInterval(interval);
diff --git a/src/locales/en.json b/src/locales/en.json
index 1d1a9749..86c1085b 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -96,7 +96,7 @@
"addTip": "Add a tip",
"addTipq": "Add a tip?",
"done": "Done",
- "paymentSuccessful": "Payment Successful!",
+ "paymentSuccessful": "Payment received!",
"invoice": "Invoice",
"total": "Total",
"tip": "Tip"
diff --git a/src/routes/[username]/receive/+page.server.js b/src/routes/[username]/receive/+page.server.js
index 60e94f0e..1068f273 100644
--- a/src/routes/[username]/receive/+page.server.js
+++ b/src/routes/[username]/receive/+page.server.js
@@ -1,21 +1,5 @@
-import { auth, get, post } from '$lib/utils';
-import { redirect } from '@sveltejs/kit';
+import invoice from '$lib/invoice';
export const actions = {
- default: async ({ cookies, request }) => {
- let form = await request.formData();
-
- let invoice = {
- amount: parseInt(form.get('amount')),
- network: 'lightning',
- prompt: form.get('prompt') === 'true',
- rate: await get('/rate')
- };
-
- let user = { username: form.get('username') };
-
- let { uuid } = await post('/invoice', { invoice, user }, auth(cookies));
-
- throw redirect(307, `/invoice/${uuid}`);
- }
+ default: invoice
};
diff --git a/src/routes/invoice/[id]/+page.server.js b/src/routes/invoice/[id]/+page.server.js
new file mode 100644
index 00000000..1068f273
--- /dev/null
+++ b/src/routes/invoice/[id]/+page.server.js
@@ -0,0 +1,5 @@
+import invoice from '$lib/invoice';
+
+export const actions = {
+ default: invoice
+};
diff --git a/src/routes/invoice/[id]/+page.svelte b/src/routes/invoice/[id]/+page.svelte
index 9d140bd5..04a31813 100644
--- a/src/routes/invoice/[id]/+page.svelte
+++ b/src/routes/invoice/[id]/+page.svelte
@@ -19,7 +19,6 @@
user: { username, currency }
} = invoice;
- let showCustomAmount = false;
let showMobileTip = false;
let qr;
@@ -39,15 +38,13 @@
user: { username, currency }
} = invoice);
- amount -= tip;
-
tipPercent = (tip / amount) * 100;
};
$: tip = Math.round((amount / 100) * tipPercent);
$invoices[id] = { amount, id, rate, received, text, tip, username };
- $: $invoices[id]?.received >= $invoices[id]?.amount && goto(`/invoice/${id}/paid`);
+ $: browser && $invoices[id]?.received >= $invoices[id]?.amount && goto(`/invoice/${id}/paid`);
$: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
@@ -73,15 +70,11 @@
{#if invoice.prompt}
<Tip
bind:amountFiat
- bind:showCustomAmount
bind:showMobileTip
bind:tipPercent
bind:tipAmount
bind:amount
bind:tip
- bind:rate
- bind:prompt
- bind:text
bind:currency
bind:username
/>
diff --git a/src/routes/invoice/[id]/paid/+page.svelte b/src/routes/invoice/[id]/paid/+page.svelte
index 456ee3ba..1b212a92 100644
--- a/src/routes/invoice/[id]/paid/+page.svelte
+++ b/src/routes/invoice/[id]/paid/+page.svelte
@@ -1,15 +1,19 @@
<script>
+ import { scale } from 'svelte/transition';
+ import { onMount } from 'svelte';
+ import { quintOut } from 'svelte/easing';
+ import { Icon } from '$comp';
import { toast } from '@zerodevx/svelte-toast';
import { browser } from '$app/environment';
import { t } from '$lib/translations';
import { f, s, sats } from '$lib/utils';
- import { LottiePlayer } from '@lottiefiles/svelte-lottie-player';
import { goto } from '$app/navigation';
import { invoices } from '$lib/store';
export let data;
let { invoice } = data;
let { amount, rate } = invoice;
+ let yeah;
toast.pop(0);
@@ -21,19 +25,10 @@
};
</script>
-<div class="text-center mt-20 md:mt-0">
- {#if browser}
- <div class="w-full mx-auto max-w-xl">
- <LottiePlayer
- src="/lottie/success.json"
- autoplay={true}
- loop={true}
- controls={false}
- renderer="svg"
- background="transparent"
- />
- </div>
- {/if}
+<div class="container px-4 text-center">
+ <div class="flex w-full py-10" in:scale={{ start: 0.5 }}>
+ <Icon icon="check" style="mx-auto" />
+ </div>
<h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1>
<h2 class="text-2xl md:text-3xl font-semibold">
{f(amountFiat, invoice.currency)}
diff --git a/static/icons/check.svg b/static/icons/check.svg
index 6bc4c06e..f29f8718 100644
--- a/static/icons/check.svg
+++ b/static/icons/check.svg
@@ -1,42 +1,9 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="405.272px" height="405.272px" viewBox="0 0 405.272 405.272" style="enable-background:new 0 0 405.272 405.272;"
+ width="405.272px" height="405.272px" viewBox="0 0 405.272 405.272" style="fill: #7ACC8F;"
xml:space="preserve">
<g>
<path d="M393.401,124.425L179.603,338.208c-15.832,15.835-41.514,15.835-57.361,0L11.878,227.836
c-15.838-15.835-15.838-41.52,0-57.358c15.841-15.841,41.521-15.841,57.355-0.006l81.698,81.699L336.037,67.064
c15.841-15.841,41.523-15.829,57.358,0C409.23,82.902,409.23,108.578,393.401,124.425z"/>
</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
-<g>
-</g>
</svg>