From bfdc69f18cb6669bd6a7cec3e0d7374940f5b677 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 25 Nov 2025 15:05:45 -0800 Subject: [PATCH] Fix chats --- src/app/components/Chat.svelte | 15 ++----- src/app/core/state.ts | 66 ++++++++++++++++------------- src/app/util/routes.ts | 10 +++-- src/routes/chat/[chat]/+page.svelte | 6 ++- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/app/components/Chat.svelte b/src/app/components/Chat.svelte index 1fc17bcd..bcd32979 100644 --- a/src/app/components/Chat.svelte +++ b/src/app/components/Chat.svelte @@ -48,26 +48,19 @@ import ChatCompose from "@app/components/ChatCompose.svelte" import ChatComposeParent from "@app/components/ChatComposeParent.svelte" import ThunkToast from "@app/components/ThunkToast.svelte" - import { - INDEXER_RELAYS, - userSettingsValues, - splitChatId, - PLATFORM_NAME, - deriveChat, - } from "@app/core/state" + import {INDEXER_RELAYS, userSettingsValues, PLATFORM_NAME, deriveChat} from "@app/core/state" import {pushModal} from "@app/util/modal" import {prependParent} from "@app/core/commands" import {pushToast} from "@app/util/toast" type Props = { - id: string + pubkeys: string[] info?: Snippet } - const {id, info}: Props = $props() + const {pubkeys, info}: Props = $props() - const chat = deriveChat(id) - const pubkeys = splitChatId(id) + const chat = deriveChat(pubkeys) const others = remove($pubkey!, pubkeys) const missingRelayLists = $derived(pubkeys.filter(pk => !$messagingRelayListsByPubkey.has(pk))) diff --git a/src/app/core/state.ts b/src/app/core/state.ts index 36a0fa0a..c56c5a08 100644 --- a/src/app/core/state.ts +++ b/src/app/core/state.ts @@ -408,49 +408,57 @@ export const chatsById = call(() => { } return readable(chatsById, set => { - const unsubscribers = [ - on(repository, "update", ({added}: RepositoryUpdate) => { - let dirty = false - for (const event of added) { - if ([DIRECT_MESSAGE, DIRECT_MESSAGE_FILE].includes(event.kind)) { - const pubkeys = getPubkeyTagValues(event.tags).concat(event.pubkey) - const id = makeChatId(pubkeys) - const chat = chatsById.get(id) - const messages = append(event, chat?.messages || []) - const last_activity = Math.max(chat?.last_activity || 0, event.created_at) - const updatedChat = addSearchText({id, pubkeys, messages, last_activity}) + const addEvents = (events: TrustedEvent[]) => { + let dirty = false + for (const event of events) { + if ([DIRECT_MESSAGE, DIRECT_MESSAGE_FILE].includes(event.kind)) { + const pubkeys = getPubkeyTagValues(event.tags).concat(event.pubkey) + const id = makeChatId(pubkeys) + const chat = chatsById.get(id) + const messages = append(event, chat?.messages || []) + const last_activity = Math.max(chat?.last_activity || 0, event.created_at) + const updatedChat = addSearchText({id, pubkeys, messages, last_activity}) - chatsById.set(id, updatedChat) + chatsById.set(id, updatedChat) - for (const pubkey of pubkeys) { - const pubkeyChats = chatsByPubkey.get(pubkey) || [] - const uniqueChats = uniqBy(chat => chat.id, append(updatedChat, pubkeyChats)) + for (const pubkey of pubkeys) { + const pubkeyChats = chatsByPubkey.get(pubkey) || [] + const uniqueChats = uniqBy(chat => chat.id, append(updatedChat, pubkeyChats)) - chatsByPubkey.set(pubkey, uniqueChats) - } + chatsByPubkey.set(pubkey, uniqueChats) + } + dirty = true + } + + if (event.kind === PROFILE) { + for (const chat of chatsByPubkey.get(event.pubkey) || []) { + addSearchText(chat) dirty = true } - - if (event.kind === PROFILE) { - for (const chat of chatsByPubkey.get(event.pubkey) || []) { - addSearchText(chat) - dirty = true - } - } } + } - if (dirty) { - set(chatsById) - } - }), + if (dirty) { + set(chatsById) + } + } + + addEvents(repository.query([{kinds: [DIRECT_MESSAGE, PROFILE]}])) + + const unsubscribers = [ + on(repository, "update", ({added}: RepositoryUpdate) => addEvents(added)), ] return () => unsubscribers.forEach(call) }) }) -export const deriveChat = makeDeriveItem(chatsById) +export const deriveChat = call(() => { + const _deriveChat = makeDeriveItem(chatsById) + + return (pubkeys: string[]) => _deriveChat(makeChatId(pubkeys)) +}) export const chatSearch = derived(throttled(800, chatsById), $chatsByPubkey => { return createSearch(Array.from($chatsByPubkey.values()), { diff --git a/src/app/util/routes.ts b/src/app/util/routes.ts index 898dba93..70d4d405 100644 --- a/src/app/util/routes.ts +++ b/src/app/util/routes.ts @@ -2,9 +2,9 @@ import type {Page} from "@sveltejs/kit" import {get} from "svelte/store" import * as nip19 from "nostr-tools/nip19" import {goto} from "$app/navigation" -import {nthEq, sleep} from "@welshman/lib" +import {nthEq, remove, sleep} from "@welshman/lib" import type {TrustedEvent} from "@welshman/util" -import {tracker, loadRelay} from "@welshman/app" +import {pubkey, tracker, loadRelay} from "@welshman/app" import {scrollToEvent} from "@lib/html" import {identity} from "@welshman/lib" import { @@ -55,7 +55,11 @@ export const goToSpace = async (url: string) => { } } -export const makeChatPath = (pubkeys: string[]) => `/chat/${makeChatId(pubkeys)}` +export const makeChatPath = (pubkeys: string[]) => { + const id = makeChatId(remove(pubkey.get()!, pubkeys)) + + return `/chat/${id}` +} export const makeRoomPath = (url: string, h: string) => `/spaces/${encodeRelay(url)}/${h}` diff --git a/src/routes/chat/[chat]/+page.svelte b/src/routes/chat/[chat]/+page.svelte index 84620f58..6ef3563e 100644 --- a/src/routes/chat/[chat]/+page.svelte +++ b/src/routes/chat/[chat]/+page.svelte @@ -1,10 +1,14 @@ - +