diff options
| author | Adam Soltys <[email protected]> | 2023-01-05 16:35:10 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-01-05 16:35:16 -0800 |
| commit | d2582a22a6df7c257281d9511ad07a2d72498d26 (patch) | |
| tree | c885ee295de14af7dcd74e0891d90d884c965924 /src | |
| parent | b74882b7e0eb0cc04c6cff5b20d56a7aa4470dda (diff) | |
| download | coinos-ui-d2582a22a6df7c257281d9511ad07a2d72498d26.tar.gz coinos-ui-d2582a22a6df7c257281d9511ad07a2d72498d26.zip | |
messages cache
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/AppHeader.svelte | 2 | ||||
| -rw-r--r-- | src/lib/nostr.js | 2 | ||||
| -rw-r--r-- | src/lib/store.js | 3 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/+layout.svelte | 22 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/followers/+page.svelte | 5 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/messages/+page.server.js | 6 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/messages/+page.svelte | 74 | ||||
| -rw-r--r-- | src/routes/(app)/login/+page.svelte | 1 |
8 files changed, 70 insertions, 45 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index e5747542..e182a60f 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -100,7 +100,7 @@ <ul class="space-y-5 w-48"> {#each menuButtons as { href, icon, key }} <li> - <a {href} data-sveltekit-prefetch="off"> + <a {href} data-sveltekit-prefetch="off"> <button class="flex justify-center items-center font-semibold hover:opacity-80" ><Icon {icon} style="mr-2 w-6 md:w-8" /> {$t(key)} </button> diff --git a/src/lib/nostr.js b/src/lib/nostr.js index aff75c1b..ae18fbf1 100644 --- a/src/lib/nostr.js +++ b/src/lib/nostr.js @@ -60,7 +60,7 @@ export let encrypt = async ({ message, recipient, user }) => { export let decrypt = async ({ event, user }) => { try { let { content, pubkey } = event; - if (pubkey === user.pubkey) pubkey = event.tags[0][1]; + if (pubkey === user.pubkey) pubkey = event.tags[0][1]; pubkey = Uint8Array.from(Buffer.from('02' + pubkey, 'hex')); let sharedPoint = Buffer.from( diff --git a/src/lib/store.js b/src/lib/store.js index 9660bf55..6a2d7fd6 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -55,5 +55,6 @@ export const request = writable(); export const invoice = writable(); export const txns = persistLocal('transactions', []); export const events = writable({}); -export const password = writable(); +export const password = persistLocal('password'); export const passwordPrompt = writable(); +export const messages = persistLocal('messages', {}); diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte index 98842016..8a651852 100644 --- a/src/routes/(app)/[username]/(profile)/+layout.svelte +++ b/src/routes/(app)/[username]/(profile)/+layout.svelte @@ -83,16 +83,18 @@ </div> {/if} {/if} - <div class="w-full flex"> - <a href={`/${subject.pubkey}/messages`} 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>Message</div> - </div> - </button> - </a> - </div> + {#if user.pubkey !== subject.pubkey} + <div class="w-full flex"> + <a href={`/${subject.pubkey}/messages`} 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>Message</div> + </div> + </button> + </a> + </div> + {/if} {#if !subject.anon} <div class="w-full flex"> <a href={`/${subject.username}/receive`} class="mx-auto"> diff --git a/src/routes/(app)/[username]/(profile)/followers/+page.svelte b/src/routes/(app)/[username]/(profile)/followers/+page.svelte index eebc11f3..87a3b947 100644 --- a/src/routes/(app)/[username]/(profile)/followers/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/followers/+page.svelte @@ -20,7 +20,10 @@ {#if followers.length} <VirtualScroll data={followers} key="pubkey" let:data pageMode={true}> <a href={`/${data.pubkey}`}> - <div class="flex border-b last:border-b-0 py-4 text-sm lg:text-lg text-secondary" :key={data.pubkey}> + <div + class="flex border-b last:border-b-0 py-4 text-sm lg:text-lg text-secondary" + :key={data.pubkey} + > <div class="mb-auto mr-2"> <div class="md:hidden"> <Avatar size={12} user={data} disabled={true} /> diff --git a/src/routes/(app)/[username]/(profile)/messages/+page.server.js b/src/routes/(app)/[username]/(profile)/messages/+page.server.js index 2efddf77..63116099 100644 --- a/src/routes/(app)/[username]/(profile)/messages/+page.server.js +++ b/src/routes/(app)/[username]/(profile)/messages/+page.server.js @@ -2,15 +2,15 @@ import { get } from '$lib/utils'; export async function load({ params, parent, url }) { let { user, subject } = await parent(); + let { since = 0 } = params; let messages = []; try { - messages = await get(`/nostr/${user.pubkey}/${subject.pubkey}/messages`); - console.log('MESSAGES', messages); + messages = await get(`/nostr/${user.pubkey}/${subject.pubkey}/${since}/messages`); } catch (e) { console.log(`failed to fetch nostr messages`, e); } - return { messages }; + return { newMessages: messages }; } diff --git a/src/routes/(app)/[username]/(profile)/messages/+page.svelte b/src/routes/(app)/[username]/(profile)/messages/+page.svelte index 3f8f5a72..dbf02cf2 100644 --- a/src/routes/(app)/[username]/(profile)/messages/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/messages/+page.svelte @@ -1,27 +1,45 @@ <script> + import { browser } from '$app/environment'; import { t } from '$lib/translations'; import { format, parseISO } from 'date-fns'; import { scale } from 'svelte/transition'; import { enhance } from '$app/forms'; import { Icon } from '$comp'; - import { back, failure } from '$lib/utils'; + import { back, failure, focus } from '$lib/utils'; import { sign, send, encrypt, decrypt } from '$lib/nostr'; + import { messages, password } from '$lib/store'; + import { tick, onMount } from 'svelte'; + import { calculateId } from 'nostr'; export let data; export let form; - const scrollToBottom = (node) => { - const scroll = () => - node.scroll({ - top: node.scrollHeight, - behavior: 'smooth' - }); - scroll(); + let { newMessages, subject, user } = data; + let input, pane; - return { update: scroll }; + $: initialize($password); + let initialize = async (p) => { + if (!p) return; + $messages[user.pubkey] = $messages[user.pubkey] || {}; + $messages[user.pubkey][subject.pubkey] = $messages[user.pubkey][subject.pubkey] || {}; + + for (let m of newMessages) { + if (!$messages[user.pubkey][subject.pubkey][m.id]) { + m.message = await decrypt({ event: m, user }); + $messages[user.pubkey][subject.pubkey][m.id] = m; + tick().then(() => (pane.scrollTop = pane.scrollHeight)); + } + } + tick().then(() => (pane.scrollTop = pane.scrollHeight)); }; - let { messages, subject, user } = data; + $: events = + ($messages[user.pubkey] && + $messages[user.pubkey][subject.pubkey] && + Object.values($messages[user.pubkey][subject.pubkey]).sort( + (a, b) => a.created_at - b.created + )) || + []; let sent, submitting, message; let submit = async () => { @@ -35,8 +53,10 @@ }; event.message = message; - messages.push(event); - messages = messages; + event.id = await calculateId(event); + $messages[user.pubkey][subject.pubkey][event.id] = event; + $messages = $messages; + tick().then(() => (pane.scrollTop = pane.scrollHeight)); try { event.content = await encrypt({ message, recipient: subject.pubkey, user }); @@ -46,10 +66,11 @@ sent = true; } catch (e) { failure('Failed to send message'); - messages.pop(); - messages = messages; + delete $messages[user.pubkey][subject.pubkey][event.id]; + $messages = $messages; } + message = ''; submitting = false; }; </script> @@ -59,25 +80,20 @@ {$t('transactions.sendMessage')} </h1> - <div class="max-h-[calc(50vh)] overflow-y-scroll p-4" use:scrollToBottom={messages}> - {#each messages as event} - {@const ours = event.pubkey === user.pubkey} + <div class="max-h-[calc(50vh)] overflow-y-scroll p-4" bind:this={pane}> + {#each events as data} + {@const ours = data.pubkey === user.pubkey} {@const theirs = !ours} <div class="rounded-2xl p-4 max-w-[300px] mb-1 text-md" class:ours class:theirs> - {#if event.message} - {event.message} + {#if data.message} + {data.message} {:else} - {#await decrypt({ event, user })} - - - {:then message} - {(event.message = message) && ''} - {event.message} - {/await} + - {/if} </div> - <div class="text-sm text-gray-400 ml-2 mb-6"> - {format(new Date(event.created_at * 1000), 'MMM d')}, - {format(new Date(event.created_at * 1000), 'h:mm aa')} + <div class="text-sm text-gray-400 mb-6" class:text-right={ours}> + {format(new Date(data.created_at * 1000), 'MMM d')}, + {format(new Date(data.created_at * 1000), 'h:mm aa')} </div> {/each} </div> @@ -87,10 +103,12 @@ <input type="hidden" name="recipient" value={subject.username} /> <input + use:focus name="message" placeholder={$t('transactions.sendMessage')} class="w-full p-4 border rounded-xl" bind:value={message} + bind:this={input} /> </form> </div> diff --git a/src/routes/(app)/login/+page.svelte b/src/routes/(app)/login/+page.svelte index 75998cd0..9a1e41da 100644 --- a/src/routes/(app)/login/+page.svelte +++ b/src/routes/(app)/login/+page.svelte @@ -1,4 +1,5 @@ <script> + import { messages } from '$lib/store'; import { RegisterOrLogin } from '$comp'; export let form; |
