diff options
| -rw-r--r-- | src/components/Feed.svelte | 65 | ||||
| -rw-r--r-- | src/components/RegisterOrLogin.svelte | 6 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/+layout.server.js | 4 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/+page.svelte | 74 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/dashboard/+page.svelte | 6 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/generate/+page.svelte | 7 | ||||
| -rw-r--r-- | src/routes/(app)/feed/+page.svelte | 17 | ||||
| -rw-r--r-- | src/routes/(app)/register/+page.server.js | 4 |
8 files changed, 88 insertions, 95 deletions
diff --git a/src/components/Feed.svelte b/src/components/Feed.svelte index c00fd1c7..72443a8b 100644 --- a/src/components/Feed.svelte +++ b/src/components/Feed.svelte @@ -3,7 +3,54 @@ import { browser } from '$app/environment'; import VirtualScroll from 'svelte-virtual-scroll-list'; import { punk } from '$lib/utils'; + import { Buffer } from 'buffer'; + import { entropyToMnemonic, mnemonicToSeedSync } from 'bip39'; + import { enhance } from '$app/forms'; + import { bech32m } from 'bech32'; + import { calculateId, signId } from 'nostr'; + import { bip32, stretch, post } from '$lib/utils'; + export let events; + export let user; + + const { decode, fromWords } = bech32m; + + let message; + + let submit = async () => { + let mnemonic, key, password, seed, entropy, child, privkey; + entropy = Buffer.from( + await crypto.subtle.decrypt( + { name: 'AES-GCM', iv: new Uint8Array(16) }, + await stretch(password, Buffer.from(user.salt, 'hex')), + Uint8Array.from(fromWords(decode(user.cipher, 180).words)) + ), + 'hex' + ).toString('hex'); + + mnemonic = entropyToMnemonic(entropy); + seed = mnemonicToSeedSync(mnemonic); + key = bip32.fromSeed(seed); + child = key.derivePath("m/44'/1237'/0'/0/0"); + privkey = child.privateKey; + + let event = { + pubkey: user.pubkey, + created_at: Math.floor(Date.now() / 1000), + kind: 1, + content: message, + tags: [] + }; + + event.id = await calculateId(event); + event.sig = await signId(privkey, event.id); + await post(`/${user.username}`, { event }); + + event.user = user; + event.seen = event.created_at; + events[event.id] = event; + events = events; + }; let distance = (date) => { let m = 60; @@ -23,12 +70,28 @@ }; let w; + + $: sorted = Object.values(events) + .filter((ev) => ev?.pubkey) + .sort((a, b) => b.seen - a.seen); </script> <svelte:window bind:innerWidth={w} /> +<form on:submit|preventDefault={submit} class="flex justify-center gap-4 max-w-2xl mx-auto"> + <div class="grow"> + <input + name="message" + bind:value={message} + placeholder="What's happening?" + class="my-5 mx-auto" + /> + </div> + <button class="rounded-full border py-4 px-5 font-bold hover:opacity-80 w-40 my-5">Post</button> +</form> + {#if browser} - <VirtualScroll data={events} key="id" let:data pageMode={true} estimateSize={200}> + <VirtualScroll data={sorted} 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.user.anon ? data.user.pubkey : data.user.username}`}> <div class="mb-auto mr-2"> diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte index 8ee3af4a..b2070e9c 100644 --- a/src/components/RegisterOrLogin.svelte +++ b/src/components/RegisterOrLogin.svelte @@ -5,7 +5,7 @@ import { enhance } from '$app/forms'; import { Icon } from '$comp'; import { focus } from '$lib/utils'; - import { loginRedirect, password } from '$lib/store'; + import { password } from '$lib/store'; import { t } from '$lib/translations'; import { page } from '$app/stores'; @@ -82,10 +82,6 @@ {/if} <form class="space-y-5" {action} method="POST" use:enhance> - {#if $loginRedirect} - <input type="hidden" name="loginRedirect" value={$loginRedirect} /> - {/if} - <div> <label for="username" class="font-semibold">{$t('login.username')}</label> <input diff --git a/src/routes/(app)/[username]/+layout.server.js b/src/routes/(app)/[username]/+layout.server.js index 7823f7de..5e41fd4e 100644 --- a/src/routes/(app)/[username]/+layout.server.js +++ b/src/routes/(app)/[username]/+layout.server.js @@ -1,7 +1,9 @@ import { get } from '$lib/utils'; import { error } from '@sveltejs/kit'; -export let load = async ({ params: { username } }) => { +export let load = async ({ depends, params: { username } }) => { + depends('app:user'); + try { return { subject: await get(`/users/${username}`) }; } catch (e) { diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte index b4f609a9..f4598e6f 100644 --- a/src/routes/(app)/[username]/+page.svelte +++ b/src/routes/(app)/[username]/+page.svelte @@ -1,53 +1,14 @@ <script> - import { Buffer } from 'buffer'; - import { entropyToMnemonic, mnemonicToSeedSync } from 'bip39'; - import { enhance } from '$app/forms'; import { Feed, Icon, PageNotFound } from '$comp'; import { t } from '$lib/translations'; - import { bech32m } from 'bech32'; - import { calculateId, signId } from 'nostr'; - import { bip32, stretch, post } from '$lib/utils'; - const { decode, fromWords } = bech32m; export let data; - let message; - let { events, user, subject, src, text } = data; let followed = false; let { username: n } = subject; - let submit = async () => { - let mnemonic, key, password, seed, entropy, child, privkey; - entropy = Buffer.from( - await crypto.subtle.decrypt( - { name: 'AES-GCM', iv: new Uint8Array(16) }, - await stretch(password, Buffer.from(user.salt, 'hex')), - Uint8Array.from(fromWords(decode(user.cipher, 180).words)) - ), - 'hex' - ).toString('hex'); - - mnemonic = entropyToMnemonic(entropy); - seed = mnemonicToSeedSync(mnemonic); - key = bip32.fromSeed(seed); - child = key.derivePath("m/44'/1237'/0'/0/0"); - privkey = child.privateKey; - - let event = { - pubkey: user.pubkey, - created_at: Math.floor(Date.now() / 1000), - kind: 1, - content: message, - tags: [] - }; - - event.id = await calculateId(event); - event.sig = await signId(privkey, event.id); - await post(`/${user.username}`, { event }); - }; - $: username = n.length > 60 ? n.substr(0, 6) : n; </script> @@ -61,7 +22,7 @@ </div> <div class="flex flex-wrap gap-2 w-full"> - {#if subject.username.length < 60} + {#if !subject.anon} <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"> @@ -97,34 +58,23 @@ </div> {/if} {/if} - <div class="w-full flex"> - <a href={`/${subject.username}/message`} 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> + <!-- <div class="w-full flex"> --> + <!-- <a href={`/${subject.username}/message`} 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> --> </div> </div> <div class="w-full md:pt-12 lg:pt-0"> - {#if user.username === n} - <form on:submit|preventDefault={submit}> - <input - name="message" - bind:value={message} - placeholder="What's happening?" - class="w-full my-5 max-w-lg mx-auto" - /> - </form> - {/if} - <div class="mx-auto space-y-5 mt-5 lg:max-w-lg xl:max-w-2xl"> {#if events.length} - <Feed {events} /> + <Feed {events} {user} /> {:else} <div class="text-center text-2xl mt-20"> Nothing here yet. Post your first <a diff --git a/src/routes/(app)/[username]/dashboard/+page.svelte b/src/routes/(app)/[username]/dashboard/+page.svelte index 9c321472..2c5aa385 100644 --- a/src/routes/(app)/[username]/dashboard/+page.svelte +++ b/src/routes/(app)/[username]/dashboard/+page.svelte @@ -57,10 +57,6 @@ $: btcPrice = f($selectedRate, user.currency); $: accountBalanceBtc = user.account.balance / sats; - - $: sorted = Object.values($events) - .filter((ev) => ev?.pubkey) - .sort((a, b) => b.seen - a.seen); </script> <div class="container px-4 max-w-md mx-auto mt-20 space-y-12 mb-8"> @@ -179,6 +175,6 @@ <div class="mb-20"> <div class="container w-full mx-auto text-lg px-4 md:max-w-2xl space-y-5"> - <Feed events={sorted} /> + <Feed events={$events} {user} /> </div> </div> diff --git a/src/routes/(app)/[username]/generate/+page.svelte b/src/routes/(app)/[username]/generate/+page.svelte index fd6b6f7e..345b35a4 100644 --- a/src/routes/(app)/[username]/generate/+page.svelte +++ b/src/routes/(app)/[username]/generate/+page.svelte @@ -5,7 +5,8 @@ import { generateMnemonic, mnemonicToEntropy, mnemonicToSeedSync } from 'bip39'; import * as ecc from 'tiny-secp256k1'; import { bip32, stretch, post } from '$lib/utils'; - import { goto } from '$app/navigation'; + import { goto, invalidate } from '$app/navigation'; + import { loginRedirect } from '$lib/store'; export let data; let { user } = data; @@ -35,6 +36,8 @@ user.salt = Buffer.from(salt).toString('hex'); await post(`/${user.username}/generate`, user); - goto(`/${user.username}/dashboard`); + + invalidate('app:user'); + setTimeout(() => goto($loginRedirect || `/${user.username}/dashboard`), 10); }); </script> diff --git a/src/routes/(app)/feed/+page.svelte b/src/routes/(app)/feed/+page.svelte deleted file mode 100644 index 61f638e7..00000000 --- a/src/routes/(app)/feed/+page.svelte +++ /dev/null @@ -1,17 +0,0 @@ -<script> - import { Feed } from '$comp'; - import { events } from '$lib/store'; - - export let data; - let { user } = data; - - $: sorted = Object.values($events) - .filter((ev) => ev?.pubkey) - .sort((a, b) => b.seen - a.seen); -</script> - -<div class="mb-20"> - <div class="container w-full mx-auto text-lg px-4 md:max-w-2xl space-y-5"> - <Feed events={sorted} /> - </div> -</div> diff --git a/src/routes/(app)/register/+page.server.js b/src/routes/(app)/register/+page.server.js index 9ff5a2fc..33cad4d0 100644 --- a/src/routes/(app)/register/+page.server.js +++ b/src/routes/(app)/register/+page.server.js @@ -9,7 +9,7 @@ export const load = async ({ parent }) => { export const actions = { default: async ({ cookies, request }) => { let form = Object.fromEntries(await request.formData()); - let { username, password, loginRedirect } = form; + let { username, password } = form; let user = { username, password }; let error; @@ -28,6 +28,6 @@ export const actions = { } if (error) return invalid(400, { error }); - throw redirect(307, loginRedirect || `/${user.username}/dashboard`); + throw redirect(307, `/${user.username}/generate`); } }; |
