aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-05 16:35:10 -0800
committerAdam Soltys <[email protected]>2023-01-05 16:35:16 -0800
commitd2582a22a6df7c257281d9511ad07a2d72498d26 (patch)
treec885ee295de14af7dcd74e0891d90d884c965924 /src
parentb74882b7e0eb0cc04c6cff5b20d56a7aa4470dda (diff)
downloadcoinos-ui-d2582a22a6df7c257281d9511ad07a2d72498d26.tar.gz
coinos-ui-d2582a22a6df7c257281d9511ad07a2d72498d26.zip
messages cache
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader.svelte2
-rw-r--r--src/lib/nostr.js2
-rw-r--r--src/lib/store.js3
-rw-r--r--src/routes/(app)/[username]/(profile)/+layout.svelte22
-rw-r--r--src/routes/(app)/[username]/(profile)/followers/+page.svelte5
-rw-r--r--src/routes/(app)/[username]/(profile)/messages/+page.server.js6
-rw-r--r--src/routes/(app)/[username]/(profile)/messages/+page.svelte74
-rw-r--r--src/routes/(app)/login/+page.svelte1
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;