aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Avatar.svelte6
-rw-r--r--src/lib/runners.js79
-rw-r--r--src/lib/socket.js23
-rw-r--r--src/lib/store.js1
-rw-r--r--src/routes/(app)/feed/+page.svelte49
-rw-r--r--src/routes/(static)/+layout.svelte2
-rw-r--r--src/routes/(static)/docs/+page.svelte6
-rw-r--r--src/routes/+page.svelte1
8 files changed, 161 insertions, 6 deletions
diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte
index d636416d..cfbec54f 100644
--- a/src/components/Avatar.svelte
+++ b/src/components/Avatar.svelte
@@ -5,10 +5,12 @@
export let user;
export let size = 32;
export let disabled = false;
+ export let src;
+
$: s = size.toString();
</script>
-<a href={`/${user.username}`} class:pointer-events-none={disabled}>
+<a href={`/${user ? user.username : ''}`} 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"
>
@@ -18,6 +20,8 @@
class="w-full h-full object-cover object-center overflow-hidden"
alt={user.username}
/>
+ {:else if src}
+ <img {src} class="w-full h-full object-cover object-center overflow-hidden" alt="Avatar" />
{:else}
<Icon icon="logo-symbol-white" style="w-4/5" />
{/if}
diff --git a/src/lib/runners.js b/src/lib/runners.js
new file mode 100644
index 00000000..363594d2
--- /dev/null
+++ b/src/lib/runners.js
@@ -0,0 +1,79 @@
+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/socket.js b/src/lib/socket.js
index 95b4a512..43f6c386 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -1,10 +1,23 @@
import { get } from 'svelte/store';
-import { invoices, invoice, request, newPayment, last, rate, txns, user } from '$lib/store';
+import {
+ events as $events,
+ invoices,
+ invoice,
+ request,
+ newPayment,
+ last,
+ rate,
+ txns,
+ user
+} from '$lib/store';
import { success, sat } from '$lib/utils';
import { PUBLIC_SOCKET } from '$env/static/public';
import { invalidate } from '$app/navigation';
let socket, token;
+let events = get($events);
+delete events.q;
+events.q = Object.keys(events);
export const auth = () => token && send('login', token) && send('heartbeat');
@@ -22,6 +35,14 @@ export const messages = (data) => ({
invoice.set(data);
},
+ event() {
+ data.seen = Math.round(Date.now() / 1000);
+ events[data.id] = data;
+ events.q.push(data.id);
+ $events.set(events);
+ if (events.q.length > 1000) events.delete[events.q.shift()];
+ },
+
rate() {
rate.set(data);
},
diff --git a/src/lib/store.js b/src/lib/store.js
index 342bdc40..df1525d3 100644
--- a/src/lib/store.js
+++ b/src/lib/store.js
@@ -47,3 +47,4 @@ export const last = writable();
export const request = writable();
export const invoice = writable();
export const txns = persistLocal('transactions', []);
+export const events = persistLocal('events', {});
diff --git a/src/routes/(app)/feed/+page.svelte b/src/routes/(app)/feed/+page.svelte
new file mode 100644
index 00000000..196763f6
--- /dev/null
+++ b/src/routes/(app)/feed/+page.svelte
@@ -0,0 +1,49 @@
+<script>
+ import { fade } from 'svelte/transition';
+ import { Avatar, Icon } from '$comp';
+ import { format, parseISO } from 'date-fns';
+ import { t } from '$lib/translations';
+ 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)
+ .filter((ev) => ev?.pubkey)
+ .sort((a, b) => b.seen - a.seen);
+</script>
+
+<div class="mt-24 mb-20">
+ <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold mb-10">Nostr</h1>
+
+ <div class="container w-full mx-auto text-lg px-4 max-w-2xl space-y-5">
+ <div class="vs">
+ {#if browser}
+ <VirtualScroll data={sorted} key="id" let:data pageMode={true}>
+ <div class="grid grid-cols-3 border-b pb-5" :key={data.id} use:fade>
+ <div class="my-auto text-secondary">
+ <div class="flex">
+ <div class="my-auto">
+ <Avatar size={20} src={`/api/public/runners/${runner()}`} />
+ </div>
+ <div class="my-auto ml-1">
+ {data.pubkey.substr(0, 6)}<br />
+ <span class="text-sm">{format(new Date(data.seen * 1000), 'h:mm aaa')}</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="my-auto col-span-2">
+ <div class="text-secondary break-words">{data.content}</div>
+ </div>
+ </div>
+ </VirtualScroll>
+ {/if}
+ </div>
+ </div>
+</div>
diff --git a/src/routes/(static)/+layout.svelte b/src/routes/(static)/+layout.svelte
index 2eb47149..a7a1ab22 100644
--- a/src/routes/(static)/+layout.svelte
+++ b/src/routes/(static)/+layout.svelte
@@ -1,3 +1,3 @@
<main class="container flex px-10 md:px-40 mx-auto">
-<slot />
+ <slot />
</main>
diff --git a/src/routes/(static)/docs/+page.svelte b/src/routes/(static)/docs/+page.svelte
index 5361c87e..0e11decb 100644
--- a/src/routes/(static)/docs/+page.svelte
+++ b/src/routes/(static)/docs/+page.svelte
@@ -1,5 +1,6 @@
<h1>API Examples</h1>
-<pre><code class="whitespace-pre-wrap">{`
+<pre><code class="whitespace-pre-wrap"
+ >{`
api="https://coinos.io/api"
json="Content-Type: application/json"
@@ -71,4 +72,5 @@ fee=$(echo $tx | jq -r .tx.fee)
curl -s "$api/bitcoin/send" -H "$json" -H "$auth" -d '{"address": "bc1qqc9azhdjjpdxenrndt8cw4tw9del5pyrjn0wln", "tx": { "hex": "'$hex'", "fee": "'$fee'" }}' | jq -r '{ amount, fee, balance: (.account.balance)}'
echo ""
-`}</code></pre>
+`}</code
+ ></pre>
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index bf191b7f..2db2854a 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -17,7 +17,6 @@
export let data;
let { user } = data;
let { locations } = data;
- console.log('LOCATIONS', locations);
let howItWorks;
let faq;