forked from coracle/flotilla
Fix chats
This commit is contained in:
@@ -48,26 +48,19 @@
|
|||||||
import ChatCompose from "@app/components/ChatCompose.svelte"
|
import ChatCompose from "@app/components/ChatCompose.svelte"
|
||||||
import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
|
import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
|
||||||
import ThunkToast from "@app/components/ThunkToast.svelte"
|
import ThunkToast from "@app/components/ThunkToast.svelte"
|
||||||
import {
|
import {INDEXER_RELAYS, userSettingsValues, PLATFORM_NAME, deriveChat} from "@app/core/state"
|
||||||
INDEXER_RELAYS,
|
|
||||||
userSettingsValues,
|
|
||||||
splitChatId,
|
|
||||||
PLATFORM_NAME,
|
|
||||||
deriveChat,
|
|
||||||
} from "@app/core/state"
|
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {prependParent} from "@app/core/commands"
|
import {prependParent} from "@app/core/commands"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string
|
pubkeys: string[]
|
||||||
info?: Snippet
|
info?: Snippet
|
||||||
}
|
}
|
||||||
|
|
||||||
const {id, info}: Props = $props()
|
const {pubkeys, info}: Props = $props()
|
||||||
|
|
||||||
const chat = deriveChat(id)
|
const chat = deriveChat(pubkeys)
|
||||||
const pubkeys = splitChatId(id)
|
|
||||||
const others = remove($pubkey!, pubkeys)
|
const others = remove($pubkey!, pubkeys)
|
||||||
const missingRelayLists = $derived(pubkeys.filter(pk => !$messagingRelayListsByPubkey.has(pk)))
|
const missingRelayLists = $derived(pubkeys.filter(pk => !$messagingRelayListsByPubkey.has(pk)))
|
||||||
|
|
||||||
|
|||||||
+37
-29
@@ -408,49 +408,57 @@ export const chatsById = call(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return readable(chatsById, set => {
|
return readable(chatsById, set => {
|
||||||
const unsubscribers = [
|
const addEvents = (events: TrustedEvent[]) => {
|
||||||
on(repository, "update", ({added}: RepositoryUpdate) => {
|
let dirty = false
|
||||||
let dirty = false
|
for (const event of events) {
|
||||||
for (const event of added) {
|
if ([DIRECT_MESSAGE, DIRECT_MESSAGE_FILE].includes(event.kind)) {
|
||||||
if ([DIRECT_MESSAGE, DIRECT_MESSAGE_FILE].includes(event.kind)) {
|
const pubkeys = getPubkeyTagValues(event.tags).concat(event.pubkey)
|
||||||
const pubkeys = getPubkeyTagValues(event.tags).concat(event.pubkey)
|
const id = makeChatId(pubkeys)
|
||||||
const id = makeChatId(pubkeys)
|
const chat = chatsById.get(id)
|
||||||
const chat = chatsById.get(id)
|
const messages = append(event, chat?.messages || [])
|
||||||
const messages = append(event, chat?.messages || [])
|
const last_activity = Math.max(chat?.last_activity || 0, event.created_at)
|
||||||
const last_activity = Math.max(chat?.last_activity || 0, event.created_at)
|
const updatedChat = addSearchText({id, pubkeys, messages, last_activity})
|
||||||
const updatedChat = addSearchText({id, pubkeys, messages, last_activity})
|
|
||||||
|
|
||||||
chatsById.set(id, updatedChat)
|
chatsById.set(id, updatedChat)
|
||||||
|
|
||||||
for (const pubkey of pubkeys) {
|
for (const pubkey of pubkeys) {
|
||||||
const pubkeyChats = chatsByPubkey.get(pubkey) || []
|
const pubkeyChats = chatsByPubkey.get(pubkey) || []
|
||||||
const uniqueChats = uniqBy(chat => chat.id, append(updatedChat, pubkeyChats))
|
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
|
dirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.kind === PROFILE) {
|
|
||||||
for (const chat of chatsByPubkey.get(event.pubkey) || []) {
|
|
||||||
addSearchText(chat)
|
|
||||||
dirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
set(chatsById)
|
set(chatsById)
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
|
|
||||||
|
addEvents(repository.query([{kinds: [DIRECT_MESSAGE, PROFILE]}]))
|
||||||
|
|
||||||
|
const unsubscribers = [
|
||||||
|
on(repository, "update", ({added}: RepositoryUpdate) => addEvents(added)),
|
||||||
]
|
]
|
||||||
|
|
||||||
return () => unsubscribers.forEach(call)
|
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 => {
|
export const chatSearch = derived(throttled(800, chatsById), $chatsByPubkey => {
|
||||||
return createSearch(Array.from($chatsByPubkey.values()), {
|
return createSearch(Array.from($chatsByPubkey.values()), {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import type {Page} from "@sveltejs/kit"
|
|||||||
import {get} from "svelte/store"
|
import {get} from "svelte/store"
|
||||||
import * as nip19 from "nostr-tools/nip19"
|
import * as nip19 from "nostr-tools/nip19"
|
||||||
import {goto} from "$app/navigation"
|
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 type {TrustedEvent} from "@welshman/util"
|
||||||
import {tracker, loadRelay} from "@welshman/app"
|
import {pubkey, tracker, loadRelay} from "@welshman/app"
|
||||||
import {scrollToEvent} from "@lib/html"
|
import {scrollToEvent} from "@lib/html"
|
||||||
import {identity} from "@welshman/lib"
|
import {identity} from "@welshman/lib"
|
||||||
import {
|
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}`
|
export const makeRoomPath = (url: string, h: string) => `/spaces/${encodeRelay(url)}/${h}`
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import type {MakeNonOptional} from "@welshman/lib"
|
import type {MakeNonOptional} from "@welshman/lib"
|
||||||
|
import {append, uniq} from "@welshman/lib"
|
||||||
|
import {pubkey} from "@welshman/app"
|
||||||
import Chat from "@app/components/Chat.svelte"
|
import Chat from "@app/components/Chat.svelte"
|
||||||
import {notifications, setChecked} from "@app/util/notifications"
|
import {notifications, setChecked} from "@app/util/notifications"
|
||||||
|
import {splitChatId} from "@app/core/state"
|
||||||
|
|
||||||
const {chat} = $page.params as MakeNonOptional<typeof $page.params>
|
const {chat} = $page.params as MakeNonOptional<typeof $page.params>
|
||||||
|
const pubkeys = uniq(append($pubkey!, splitChatId(chat)))
|
||||||
|
|
||||||
// We have to watch this one, since on mobile the badge will be visible when active
|
// We have to watch this one, since on mobile the badge will be visible when active
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -14,4 +18,4 @@
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Chat id={chat} />
|
<Chat {pubkeys} />
|
||||||
|
|||||||
Reference in New Issue
Block a user