aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-09-07 13:58:00 -0700
committerAdam Soltys <[email protected]>2022-09-07 13:58:00 -0700
commitec5a14d7d61d5f1797fcfba67dd2d8ef0cca2360 (patch)
tree0b138f7fce9b7b6f64bdbb8c0a0103d48f9088b5 /src
parent7efa00c9a9cf6587e9c24c1c94d3c8969949e360 (diff)
downloadcoinos-ui-ec5a14d7d61d5f1797fcfba67dd2d8ef0cca2360.tar.gz
coinos-ui-ec5a14d7d61d5f1797fcfba67dd2d8ef0cca2360.zip
image uploads
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader.svelte25
-rw-r--r--src/components/Qr.svelte5
-rw-r--r--src/lib/upload.js6
-rw-r--r--src/lib/utils.js8
-rw-r--r--src/routes/[username]/settings/_account.svelte76
-rw-r--r--src/routes/invoice/+server.js1
-rw-r--r--src/routes/invoice/[id]/+page.server.js3
-rw-r--r--src/routes/invoice/[id]/+page.svelte4
8 files changed, 88 insertions, 40 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index 7b3987d5..35e6f250 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -1,6 +1,4 @@
<script>
- // we will want to dynamically use the users avatar on this screen if they have uploaded one
-
import OutClick from 'svelte-outclick';
import { user, newPayment, colorTheme } from '$lib/store';
import { goto } from '$app/navigation';
@@ -26,9 +24,11 @@
goto(`/${$user.username + '/' + item}`);
}
};
+
+ $: background = $user?.banner ? `url(/api/public/${$user.username}-banner.png)` : undefined;
</script>
-<header class="bg-gradient-to-r {$colorTheme} h-[175px] w-full relative">
+<header class="bg-gradient-to-r {$colorTheme} h-[175px] w-full relative" style:background>
<nav class="flex justify-end items-center space-x-4 p-5">
{#if $user}
<a href={`/${$user.username}/receive`}>
@@ -91,11 +91,20 @@
</a>
{/if}
</nav>
- <div
- class="absolute top-[calc(175px-48px)] {avatarPosition} rounded-full border-4 border-white p-4 bg-gradient-to-r {$colorTheme} w-24 h-24"
- >
- <Icon icon="logo-symbol-white" style="mx-auto" />
- </div>
+ {#if $user.profile}
+ <div class="absolute top-[calc(175px-48px)] {avatarPosition} rounded-full overflow-hidden text-center w-24 h-24 my-auto">
+ <img
+ src={`/api/public/${$user.username}-profile.png`}
+ class="absolute w-full h-full object-cover object-center visible overflow-hidden"
+ />
+ </div>
+ {:else}
+ <div
+ class="absolute top-[calc(175px-48px)] {avatarPosition} rounded-full border-4 border-white p-4 bg-gradient-to-r {$colorTheme} w-24 h-24"
+ >
+ <Icon icon="logo-symbol-white" style="mx-auto" />
+ </div>
+ {/if}
</header>
<style>
diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte
index 52bb7a65..4929137a 100644
--- a/src/components/Qr.svelte
+++ b/src/components/Qr.svelte
@@ -5,7 +5,8 @@
export let image, text, qr;
- onMount(async () => {
+ $: update(text);
+ let update = async (text) => {
if (!(browser && text)) return;
let { default: QRCodeStyling } = await import('qr-code-styling');
@@ -28,7 +29,7 @@
while (qr.firstChild) qr.removeChild(qr.lastChild);
qrCode.append(qr);
- });
+ }
</script>
<div bind:this={qr} on:click={() => copy(text)} />
diff --git a/src/lib/upload.js b/src/lib/upload.js
index e7a73fee..d43148fb 100644
--- a/src/lib/upload.js
+++ b/src/lib/upload.js
@@ -1,13 +1,11 @@
import { get } from 'svelte/store';
import { token } from '$lib/store';
-export const upload = async (file, progress) => {
- let url = '/api/profile';
+export const upload = async (file, type, progress) => {
+ let url = `/api/upload/${type}`;
let formData = new FormData();
formData.append('file', file);
- console.log('uploading', file);
-
return new Promise((resolve, reject) => {
let ajax = new XMLHttpRequest();
ajax.addEventListener('load', () => {
diff --git a/src/lib/utils.js b/src/lib/utils.js
index ecf93062..0f665ec4 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -20,12 +20,8 @@ export const get = (url, headers = {}) =>
});
export const post = (url, body, headers) => {
- headers = { ...headers, 'content-type': 'application/json' };
- return fetch(base + url, {
- method: 'POST',
- body: JSON.stringify(body),
- headers
- })
+ headers = { ...headers, 'content-type': 'application/json', accept: 'application/json' };
+ return fetch(base + url, { method: 'POST', body: JSON.stringify(body), headers })
.then((r) => r.text())
.then((body) => {
try {
diff --git a/src/routes/[username]/settings/_account.svelte b/src/routes/[username]/settings/_account.svelte
index 7f14ff50..000ea519 100644
--- a/src/routes/[username]/settings/_account.svelte
+++ b/src/routes/[username]/settings/_account.svelte
@@ -9,7 +9,10 @@
let revealPassword = false;
let password;
let profileFile;
- let selectFile = () => profileFile.click();
+ let select = (type) => files[type].el.click();
+
+ $: profile = files.profile.src || user.profile;
+ $: banner = files.banner.src || user.banner;
let colorThemes = [
{ theme: 1, color1: 'from-[#F5F7FA]', color2: 'to-[#C3CFE2]' },
@@ -29,10 +32,18 @@
let progress = async (event) => {
percent = Math.round((event.loaded / event.total) * 100);
};
- let handleFile = async ({ target: { files } }) => {
- let file = files[0];
- file.filename = "squirt";
- let filename = await upload(file, progress);
+
+ let files = { profile: {}, banner: {} };
+ let handleFile = async ({ target }, type) => {
+ let file = target.files[0];
+ var reader = new FileReader();
+ reader.onload = async (e) => {
+ files[type].src = e.target.result;
+ };
+ reader.readAsDataURL(file);
+ console.log(file);
+ files[type].filename = file.name;
+ await upload(file, type, progress);
};
$: $user.password = $user.confirm = password;
@@ -100,19 +111,38 @@
</div>
<div class="flex">
+ {#if profile}
+ <div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto">
+ <img
+ src={profile}
+ class="absolute w-full h-full object-cover object-center visible overflow-hidden"
+ />
+ </div>
+ {:else}
+ <div
+ class="rounded-full border-4 border-white p-4 bg-gradient-to-r {$colorTheme} w-24 h-24 my-auto"
+ >
+ <Icon icon="logo-symbol-white" style="mx-auto" />
+ </div>
+ {/if}
<div
- class="rounded-full border-4 border-white p-4 bg-gradient-to-r {$colorTheme} w-24 h-24 my-auto"
+ class="ml-2 border border-dashed border-2 p-2 border-white hover:border-secondary w-full cursor-pointer"
+ on:click={() => select('profile')}
>
- <Icon icon="logo-symbol-white" style="mx-auto" />
- </div>
- <div class="ml-2 border border-dashed border-2 p-2 border-white hover:border-secondary w-full">
<button
type="button"
class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:bg-primary"
- on:click={selectFile}>Select</button
+ >Select</button
>
- <input type="file" class="hidden" bind:this={profileFile} on:change={handleFile} />
- <div class="mt-2 text-sm">gumbo.jpg</div>
+ <input
+ type="file"
+ class="hidden"
+ bind:this={files.profile.el}
+ on:change={(e) => handleFile(e, 'profile')}
+ />
+ {#if files.profile.filename}
+ <div class="mt-2 text-sm">{files.profile.filename}</div>
+ {/if}
</div>
</div>
</div>
@@ -122,12 +152,28 @@
<span class="font-bold">{$t('user.settings.bannerImage')}</span>
</div>
<p class="text-secondary mb-4">Recommended size: 1920x540px</p>
- <div class="bg-gradient-to-r {$colorTheme} w-full h-48 mb-4" />
+ {#if banner}
+ <img src={banner} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4" />
+ {:else}
+ <div
+ class="bg-gradient-to-r {$colorTheme} w-full h-48 mb-4 cursor-pointer"
+ on:click={() => select('banner')}
+ />
+ {/if}
<button
type="button"
- class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:bg-primary">Select</button
+ class="border rounded-2xl font-bold w-24 text-center px-0 py-2 hover:bg-primary"
+ on:click={() => select('banner')}>Select</button
>
- <div class="mt-2 text-sm">gumbo.jpg</div>
+ <input
+ type="file"
+ class="hidden"
+ bind:this={files.banner.el}
+ on:change={(e) => handleFile(e, 'banner')}
+ />
+ {#if files.banner.filename}
+ <div class="mt-2 text-sm">{files.banner.filename}</div>
+ {/if}
</div>
<div>
diff --git a/src/routes/invoice/+server.js b/src/routes/invoice/+server.js
index a4c4f9c8..225f6bb1 100644
--- a/src/routes/invoice/+server.js
+++ b/src/routes/invoice/+server.js
@@ -3,7 +3,6 @@ import { auth, get, post } from '$lib/utils';
export async function POST({ request }) {
let network = 'lightning';
let { amount, currency, rate, tip, text, username } = await request.json();
-
({ text } = await post('/lightning/invoice', { amount }, auth(request)));
let invoice = { amount, currency, network, rate, tip, text };
let { uuid } = await post('/invoice', { invoice, user: { username } }, auth(request));
diff --git a/src/routes/invoice/[id]/+page.server.js b/src/routes/invoice/[id]/+page.server.js
index 5ab0069a..e123c7d7 100644
--- a/src/routes/invoice/[id]/+page.server.js
+++ b/src/routes/invoice/[id]/+page.server.js
@@ -1,5 +1,4 @@
-import cookie from 'cookie';
-import { get, post } from '$lib/utils';
+import { get } from '$lib/utils';
export async function load({ params }) {
let { id } = params;
diff --git a/src/routes/invoice/[id]/+page.svelte b/src/routes/invoice/[id]/+page.svelte
index e8d5562c..f6ecdc0e 100644
--- a/src/routes/invoice/[id]/+page.svelte
+++ b/src/routes/invoice/[id]/+page.svelte
@@ -69,9 +69,9 @@
let update = async () => {
await tick();
- tip = (tipAmount * 100000000) / rate;
+ tip = Math.round((tipAmount * 100000000) / rate);
let r = await post(`/invoice`, {
- amount: amount + tip,
+ amount: parseInt(amount + tip),
rate,
tip,
text,