aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-12-20 17:41:40 -0800
committerAdam Soltys <[email protected]>2022-12-20 17:41:40 -0800
commit268d71cb57ff19382ff8834ca3406dda2f79343e (patch)
tree2cb012b7f74f0947f9b03304d62c4604ab79fdfd
parent70208aaa216a147f2f1d43a42a5fc8e1f4be767f (diff)
downloadcoinos-ui-268d71cb57ff19382ff8834ca3406dda2f79343e.tar.gz
coinos-ui-268d71cb57ff19382ff8834ca3406dda2f79343e.zip
new profile page
-rw-r--r--src/components/Avatar.svelte5
-rw-r--r--src/components/Feed.svelte49
-rw-r--r--src/components/index.js1
-rw-r--r--src/lib/runners.js79
-rw-r--r--src/lib/utils.js3
-rw-r--r--src/locales/en.json3
-rw-r--r--src/routes/(app)/[username]/+layout.server.js1
-rw-r--r--src/routes/(app)/[username]/+page.server.js15
-rw-r--r--src/routes/(app)/[username]/+page.svelte105
-rw-r--r--src/routes/(app)/feed/+page.svelte42
10 files changed, 124 insertions, 179 deletions
diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte
index cfbec54f..7ee774bf 100644
--- a/src/components/Avatar.svelte
+++ b/src/components/Avatar.svelte
@@ -5,12 +5,13 @@
export let user;
export let size = 32;
export let disabled = false;
- export let src;
+ export let src = undefined;
$: s = size.toString();
+ $: link = user ? `/${user.username}` : '/';
</script>
-<a href={`/${user ? user.username : ''}`} class:pointer-events-none={disabled}>
+<a href={link} class:pointer-events-none={disabled}>
<div
class="w-{s} h-{s} rounded-full border-4 border-white overflow-hidden bg-gradient-to-r {$colorTheme} flex justify-center items-center"
>
diff --git a/src/components/Feed.svelte b/src/components/Feed.svelte
new file mode 100644
index 00000000..973afa19
--- /dev/null
+++ b/src/components/Feed.svelte
@@ -0,0 +1,49 @@
+<script>
+ import { Avatar } from '$comp';
+ import { browser } from '$app/environment';
+ import VirtualScroll from 'svelte-virtual-scroll-list';
+ import { runner } from '$lib/utils';
+ export let events;
+
+ let distance = (d) => {
+ let diff = Math.round(Date.now() / 1000) - d;
+ return diff > 3600
+ ? Math.round(diff / 3600) + 'd'
+ : diff > 60
+ ? Math.round(diff / 60) + 'm'
+ : diff > 2
+ ? diff + 's'
+ : 'now';
+ };
+
+ let w;
+</script>
+
+<svelte:window bind:innerWidth={w} />
+
+{#if browser}
+ <VirtualScroll data={events} key="id" let:data pageMode={true} estimateSize={200}>
+ <div class="flex border-b py-4 text-sm lg:text-lg text-secondary" :key={data.id}>
+ <a href={`/${data.pubkey}`}>
+ <div class="mb-auto mr-2">
+ <div class="md:hidden">
+ <Avatar size={12} src={`/api/public/runners/${runner(data.pubkey)}`} disabled={true} />
+ </div>
+ <div class="hidden md:block">
+ <Avatar size={20} src={`/api/public/runners/${runner(data.pubkey)}`} disabled={true} />
+ </div>
+ </div>
+ </a>
+
+ <div class="grow" style={`max-width: ${w - 100}px`}>
+ <div class="w-full flex pb-1 text-black">
+ <div>{data.pubkey.substr(0, 6)}</div>
+ <div class="text-secondary">&nbsp;{distance(data.seen)}</div>
+ </div>
+ <div class="break-words">
+ {data.content}
+ </div>
+ </div>
+ </div>
+ </VirtualScroll>
+{/if}
diff --git a/src/components/index.js b/src/components/index.js
index 07b169bb..90bc1e7e 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,4 @@
+export { default as Feed } from './Feed.svelte';
export { default as Invoice } from './Invoice.svelte';
export { default as Request } from './Request.svelte';
export { default as Pin } from './Pin.svelte';
diff --git a/src/lib/runners.js b/src/lib/runners.js
deleted file mode 100644
index 363594d2..00000000
--- a/src/lib/runners.js
+++ /dev/null
@@ -1,79 +0,0 @@
-export default [
- 'Qma97iPUioF6VcpjYhFiSFHqsGkAVgTMqbQ1GVehM2pp4C.webp',
- 'QmagBTQuuUk1M1NLynLNyQkYC7DsUiiFSAU1evW37SRSwx.webp',
- 'QmbeKTXKLVj93h3YWj982fk1enGKQnhK8AtBYmPn4wY7dZ.webp',
- 'QmbK8cqgzG5hrWaiUpUbzdgVyE794FBwtom2b7iAgiXQSH.webp',
- 'QmbWXGrxDE9y651Vv9MgrogKto7u3Ybyh4WMULronJwNnr.webp',
- 'QmbxFA62kwH5oXUbjvF2Gd2F5GGB3QPBzgW6RBUSw8pZzh.webp',
- 'Qmc7PyW1wQFnj21A87xcuicwipCvaH8A77o9jaY9zgmana.webp',
- 'QmcicA4dudWA373vnchnSVGe38UiyB6dqxqoEsyX3KrJzQ.webp',
- 'QmcSy2SDhKYkNLonwEKVab3bR24AHAbMwDwQ16e4trmjpX.webp',
- 'Qmd8afMsK5FZsDmuARphzCP3mpDa57f8FzMF9bHPSywwXB.webp',
- 'QmdjPgJyjj3Pm1LTixswHUMFfgmG3uFxvjNC36qWVENmZ5.webp',
- 'Qme1VjBDnswkW8kk88aoFxaRTNRLRdbkz7YqWKWZby1jE3.webp',
- 'Qme9dxEfyn8pzt1g6PZZphUoFWnYjg2LMfF5drb2K2iLNF.webp',
- 'QmeddNU7LGkfmzXzvepChaVxRJvZGAG8vvthLChDC2tEYj.webp',
- 'QmedXmb6nLU7pYbyRknyZ1SvdZwKPjjpm2zVRtYpy7otXx.webp',
- 'QmefpdjwVZUJvLzGKxKoygtmXN6GHr8nr4o4jNpzdwCXEu.webp',
- 'QmehU24Epg96y4ZUabrW6qj4eLQH9QBV6k4c9aRM8xy2AT.webp',
- 'QmeioKyTRUYkQqJUuxrwffmv16WwpA1cVDVFmsZzY3NNaW.webp',
- 'QmeMawqD5VBcpxodUbhFFSNRxPEGoFKS7jhTbFCayNvNBn.webp',
- 'QmeMvib26HHuZeib7Wp4juU5WioyDRTuSu4WDCmjkTXQx1.webp',
- 'QmeW63YBirM8snAhRoDhWHQEv6QKNRFg66wZpphb9bPXrH.webp',
- 'QmfBT4ZfpyjZGKfQfpEeHXCio8AemckucF8maKWvgNmeJt.webp',
- 'QmfFk5p2m67Nnw4dy5bt3DK3XEYxscACJDAEAFi1CdvSmk.webp',
- 'QmfMsRyPxGrWiQhyS3UQqUVbMZWn5VASkwtRYypqMLX9te.webp',
- 'QmfNKusvYqWVyG5Zz3N51ujU9qhYH1F6sbDxz55pYfj3Xr.webp',
- 'QmfXzwHuSG1VscFDArZumVALCAisdHqHuetxwY51Pda1NU.webp',
- 'QmNatn6kdBZtNbSXcP6v4B9dgjqiubTbWRKYBSM1zQGgyS.webp',
- 'QmNWrLehxdsRozLCgcmuGMFPn5Ns1VqQmJuGnGUujaQtmd.webp',
- 'QmNxyEoaFMoAWtWbFMF3MyWtUDWMAYxGRGYzyy5LtyP9K3.webp',
- 'QmPfgfagqM9R9tWWYBSEhaZr1NP1XZYtBXkUYorCMBZwjK.webp',
- 'QmPkLz8DG83AN9jtSq5ECxpkZnhsugW2wmDMBDUbj3Y739.webp',
- 'QmPNZ6aVvENjB9g3ujaqxTMjQ9NhYZpZk9A6VgC5YLJDHA.webp',
- 'QmQ37PgXP5rNU1udKjiy4VmzjwjgBgfNzwSVENdCZvvjuF.webp',
- 'QmQfEcHQXxpEw5NVvsxC69MHPqQ77cNgW9Gk4KyYbD6qAB.webp',
- 'QmQGSZV3nJudGuEZTGAtoj2xaQ9shButYNG9YJRN9hydCT.webp',
- 'QmQGwJXCtNjc84uMLtyNjoGjqu1mtbiMcydVuSMWCrJYg3.webp',
- 'QmQNBhQuvor1RigscMF5nUk9LHz4pGJwXpFE3WAGQFi31H.webp',
- 'QmQutjFQni2fwVBLJWJZJxdjiy6HRGaJY878ZZYBVP2gwD.webp',
- 'QmQwCerH77D2xmvKKRtAQkxwJ4rGFqKXPd5q8QqY6DyxWw.webp',
- 'QmRdcJmvem9gdYpNcsXhsZpZ5CShrce22QCDVV7bP3mAWa.webp',
- 'QmRgz9FE5awn4B59tgNfPeWPNMBchAChxNQxxGSXphjzUr.webp',
- 'QmRLFwrM89hW9UYbwsFMAohcAruMZQhzTHrgNQr6GGFdwa.webp',
- 'QmRsNUKTzAkamrs336zoWGRyR1vK9tA237MLPMV7uN8yPK.webp',
- 'QmRXxrfQ4PjDCpR5ABpMVpv9HrkoaCAqTewMbz14tCQhSD.webp',
- 'QmSg5eyj1hYRTf9Y5XP9iErHeN55RkvgNF9NdKkiv1qSaw.webp',
- 'QmSkRtY1FoQCgHhc5o6QNwufBHCv5sS9ZTHcQ2U3qbj5RX.webp',
- 'QmSroPbEoFMGWrfqe55jpgHoiuDaiGj4FLqrxi7cjZz2nZ.webp',
- 'QmSYJj61VGBSaNGGen7nmwdmxtAEHj3nAev5hzy7sKQvxR.webp',
- 'QmTByAPptSDbHZsJRd52RgCcxhpXFdq4ppFTnSZ7U6ytpi.webp',
- 'QmUCNzXjPpR4ZCTJTvMpphYktEsvQ8GLQQiTKd1s7QGiGY.webp',
- 'QmUmbAD837VXSaswskCcgdqQ4UuMPC35bQHJCr7GovPmaZ.webp',
- 'QmUnTpgH1WmzHYhtMtsLggPrNKkvwDfWaGzQzfpghveVCY.webp',
- 'QmUNZkQPLUwz8cvmUtdC5PTmas7bxhGctB6HucPeC9MjSU.webp',
- 'QmUqgre9anYKfmdSwH5N7S6ueoci8Q58TcfPaLGpumLKs1.webp',
- 'QmV3w7aXh6NGiB8YH3Jbo5cNy8o6t8u2KRgaSUVds2jhu1.webp',
- 'QmVMf9MY7t29gmuVpusuHX5WGQSm4xyZ7sb3Cc1nJq3WTr.webp',
- 'QmVpVAijTi6NaVfn2rmYoQ6idu82UB8sXGADpyfHrNvSZu.webp',
- 'QmW1UPkwVgU8QCWiEPyoJoBqzTm1jRPuC8LyW158x4pnAA.webp',
- 'QmW8z18VErUt8LvT6r28piJzKvZTbiAHD9GG5nTLd4KYCE.webp',
- 'QmWaJhEtvFh114pBxfEkX9giS7usg49tK4dsWgHvwPeVzu.webp',
- 'QmWiJAyFRrTSwVAMB3hhD1cKZGz8HTt844u3ibcRqQPTje.webp',
- 'QmWMFkLBYREzfcbuznpYXtgR6LEyxFDgNsnHRn4bELszem.webp',
- 'QmWU9QJU8p6hUzanPakPF5QaZtSf5CF5vCHHkwNyYJNGAN.webp',
- 'QmWYgYnUYw6pYzaQ9j8DYsTydYtJNZ3L6FRZQzW4bWnP7E.webp',
- 'QmXBm6r15Lj1g8eABA8CqytV829kxANtYj3mqvWPmx5jSi.webp',
- 'QmXCAUh3MpDFZ3u3MnWcosBzKv8vfaxMsKvqm7AGbdwdei.webp',
- 'QmXip2hTHZcuxAyg82gQsiSddZmHXY7d557RC1UURMtrer.webp',
- 'QmXVrUBK4YDGfqpK9fED2Tk6ghzjbjsDo7Ss77QrntoDFq.webp',
- 'QmYp51YmcALY2v31pa55sviwawkopQ3VC1kbA57LKsjE8w.webp',
- 'QmYzPXHdRqALFic8hBEc8NcdB6UJM5Xw3qMuCvWFAMJdb1.webp',
- 'QmZgPvTiuiVAymjNpfVNVFkbc7z6r2Nk2sdEtFQJ79wH3o.webp',
- 'QmZgQideTeAq8tm58Yg5dSy1HMDg9r5ULv82GzyNYWackh.webp',
- 'QmZHgKSucFxJjhsVVYh6iqAKdFw66KPFiTHsSsbXWL4cJW.webp',
- 'QmZPe1aMGyJK76T5hqknVv9N8JyGkjsgDBbTKjdKrNTKrS.webp',
- 'QmZrUF8DcagN8AGawoz8vGKcBxKdfaeaFgsd7A52zRzuH5.webp',
- 'QmZuwrCX6xqibVY5WDRAjcx3tDHsRX1KdWZuncHjrH4hkS.webp',
- 'QmZXNZpEXTMwkpgx5kJ8VQhFeV3ksn6JsiZhX3sACVD3rX.webp'
-];
diff --git a/src/lib/utils.js b/src/lib/utils.js
index bd428160..02c318b6 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -8,6 +8,9 @@ export function scroll(section) {
}
const base = browser ? '' : PUBLIC_COINOS_URL;
+export const runner = (k) => {
+ return Math.round((parseInt(k[0], 16) - 1) / 15 * 7) + 1 + '.webp';
+};
export const g = (url, fetch, headers) =>
fetch(base + url, { headers })
diff --git a/src/locales/en.json b/src/locales/en.json
index 33b7c5cf..d455f107 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -277,6 +277,7 @@
"from": "from",
"redeem": "Redeem",
"redeemed": "Redeemed",
- "redeemedBy": "Redeemed by"
+ "redeemedBy": "Redeemed by",
+ "sendMessage": "Message"
}
}
diff --git a/src/routes/(app)/[username]/+layout.server.js b/src/routes/(app)/[username]/+layout.server.js
index a352fe45..035536aa 100644
--- a/src/routes/(app)/[username]/+layout.server.js
+++ b/src/routes/(app)/[username]/+layout.server.js
@@ -5,6 +5,7 @@ export let load = async ({ params: { username } }) => {
try {
return { subject: await get(`/users/${username}`) };
} catch (e) {
+ if (username.length === 64) return { subject: { username }}
throw error(500, 'Unable to retrieve user account data');
}
};
diff --git a/src/routes/(app)/[username]/+page.server.js b/src/routes/(app)/[username]/+page.server.js
index 1d07a1db..25835d8a 100644
--- a/src/routes/(app)/[username]/+page.server.js
+++ b/src/routes/(app)/[username]/+page.server.js
@@ -1,7 +1,18 @@
+import { get } from '$lib/utils';
import Qr from 'qrcode-base64';
export async function load({ params, url }) {
- let text = `${encodeURI(params.username)}@${url.hostname}`;
+ let { username } = params;
+ let text = `${encodeURI(username)}@${url.hostname}`;
let src = Qr.drawImg(text, { size: 300 });
- return { src, text };
+ let events = [];
+ console.log("EV", events)
+
+ try {
+ events = await get(`/${username}/events`);
+ } catch (e) {
+ console.log(e);
+ }
+
+ return { events, src, text };
}
diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte
index 42e3dd3a..e8cd2d10 100644
--- a/src/routes/(app)/[username]/+page.svelte
+++ b/src/routes/(app)/[username]/+page.svelte
@@ -1,83 +1,78 @@
<script>
- import { browser } from '$app/environment';
- import { onMount } from 'svelte';
- import { Icon, PageNotFound } from '$comp';
- import { copy } from '$lib/utils';
+ import { Feed, Icon, PageNotFound } from '$comp';
import { t } from '$lib/translations';
export let data;
- let { user, subject, src, text } = data;
+ let { events, user, subject, src, text } = data;
let followed = false;
+
+ let { username: n } = subject;
+ $: username = n.length > 60 ? n.substr(0, 6) : n;
</script>
-<div class="container mx-auto w-full px-4 mb-4 flex flex-wrap">
- <div class="w-[240px] pt-20 space-y-5 lg:absolute left-20 mx-auto">
- <h1 class="text-3xl font-bold text-center mx-auto lg:text-left">{subject.username}</h1>
+<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">{username}</h1>
<div class="text-secondary mx-auto text-center lg:text-left lg:mx-0">
{subject.address && subject.address !== 'null' ? subject.address : ''}
</div>
<div class="flex flex-wrap gap-2 w-full">
- <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">
- <div style="mr-1">⚡️</div>
- <div>{$t('user.lightning')} {$t('user.invoice')}</div>
- </div>
- </button>
- </a>
- </div>
-
- <div class="w-full flex">
- <a href={`/${subject.username}/receive/bitcoin`} 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">
- <img src="/images/bitcoin.svg" class="w-5 my-auto mr-1" />
- <div>{$t('user.bitcoin')} {$t('user.invoice')}</div>
- </div>
- </button>
- </a>
- </div>
+ {#if subject.username.length < 60}
+ <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">
+ <div style="mr-1">⚡️</div>
+ <div>{$t('user.lightning')} {$t('user.invoice')}</div>
+ </div>
+ </button>
+ </a>
+ </div>
- {#if user?.username !== subject.username}
<div class="w-full flex">
- <a href={`/${subject.username}/request`} class="mx-auto">
+ <a href={`/${subject.username}/receive/bitcoin`} 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('transactions.requestAnInvoice')}</div>
+ <img src="/images/bitcoin.svg" class="w-5 my-auto mr-1" />
+ <div>{$t('user.bitcoin')} {$t('user.invoice')}</div>
</div>
</button>
</a>
</div>
+
+ {#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('transactions.requestAnInvoice')}</div>
+ </div>
+ </button>
+ </a>
+ </div>
+ {/if}
+ {:else}
+ <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('transactions.sendMessage')}</div>
+ </div>
+ </button>
+ </a>
+ </div>
{/if}
</div>
</div>
- <div class="w-full flex">
- <div class="space-y-5 mt-5 lg:pt-20 mx-auto max-w-lg">
- <div class="border-2 rounded-[20%] w-[380px] py-6 mx-auto">
- <img {src} class="mx-auto" on:click={() => copy(text)} alt="Lightning address" />
- </div>
-
- <div class="bg-primary font-semibold rounded-3xl text-sm p-3 flex">
- <div class="my-auto font-semibold text-lg w-full text-center">{text}</div>
- <button class="ml-auto hover:opacity-80" on:click={() => copy(text)}>
- <Icon icon="copy" />
- </button>
- </div>
-
- {#if user?.username === subject.username}
- <p class="text-secondary mb-1">
- {$t('user.this')}
- <a href="https://lightningaddress.com" class="underline" target="_blank" rel="noreferrer"
- >{$t('user.lightningAddress')}</a
- >
- {$t('user.likeAnEmail')}
- </p>
- {/if}
+ <div class="w-full flex md:pt-12 lg:pt-0">
+ <div class="mx-auto space-y-5 mt-5 lg:max-w-lg xl:max-w-2xl">
+ <Feed {events} />
</div>
</div>
</div>
diff --git a/src/routes/(app)/feed/+page.svelte b/src/routes/(app)/feed/+page.svelte
index 3269e0d2..2bbadc64 100644
--- a/src/routes/(app)/feed/+page.svelte
+++ b/src/routes/(app)/feed/+page.svelte
@@ -1,15 +1,9 @@
<script>
- import { fade } from 'svelte/transition';
- import { Avatar, Icon } from '$comp';
- import { t } from '$lib/translations';
+ import { Feed } from '$comp';
import { events } from '$lib/store';
- import VirtualScroll from 'svelte-virtual-scroll-list';
- import { browser } from '$app/environment';
- import runners from '$lib/runners';
export let data;
let { user } = data;
- let runner = () => runners[Math.floor(Math.random() * runners.length)];
$: length = $events?.q?.length;
$: sorted = Object.values($events)
@@ -17,44 +11,12 @@
.sort((a, b) => b.seen - a.seen);
let w;
-
- let distance = (d) => {
- let diff = Math.round(Date.now() / 1000) - d;
- return diff > 3600
- ? Math.round(diff / 3600) + 'd'
- : diff > 60
- ? Math.round(diff / 60) + 'm'
- : diff > 2 ? diff + 's' : 'now';
- };
</script>
<svelte:window bind:innerWidth={w} />
<div class="mb-20">
<div class="container w-full mx-auto text-lg px-4 md:max-w-2xl space-y-5">
- {#if browser}
- <VirtualScroll data={sorted} key="id" let:data pageMode={true} estimateSize={200}>
- <div class="flex border-b py-4 text-sm text-secondary" :key={data.id} use:fade>
- <div class="mb-auto mr-2">
- <div class="md:hidden">
- <Avatar size={12} src={`/api/public/runners/${runner()}`} />
- </div>
- <div class="hidden md:block">
- <Avatar size={20} src={`/api/public/runners/${runner()}`} />
- </div>
- </div>
-
- <div class="grow" style={`max-width: ${w - 100}px`}>
- <div class="w-full flex pb-1 text-black">
- <div>{data.pubkey.substr(0, 6)}</div>
- <div class="text-secondary">&nbsp;{distance(data.seen)}</div>
- </div>
- <div class="break-words">
- {data.content}
- </div>
- </div>
- </div>
- </VirtualScroll>
- {/if}
+ <Feed events={sorted} />
</div>
</div>