diff --git a/src/app/components/ContentQuote.svelte b/src/app/components/ContentQuote.svelte
index 0c8f02e4..5891a6ed 100644
--- a/src/app/components/ContentQuote.svelte
+++ b/src/app/components/ContentQuote.svelte
@@ -1,26 +1,14 @@
diff --git a/src/app/components/SpaceRecentActivity.svelte b/src/app/components/SpaceRecentActivity.svelte
index c0b7473c..02f1e455 100644
--- a/src/app/components/SpaceRecentActivity.svelte
+++ b/src/app/components/SpaceRecentActivity.svelte
@@ -10,6 +10,7 @@
import ProfileCircle from "@app/components/ProfileCircle.svelte"
import ProfileCircles from "@app/components/ProfileCircles.svelte"
import {deriveEventsForUrl} from "@app/state"
+ import {goToEvent} from "@app/routes"
type Props = {
url: string
@@ -80,7 +81,7 @@
{:else}
{#each $conversations.slice(0, limit) as { room, events, latest, earliest, participants } (latest.id)}
-
+
{/each}
{#if $conversations.length > limit}
diff --git a/src/app/routes.ts b/src/app/routes.ts
index 96aad395..c9da89d2 100644
--- a/src/app/routes.ts
+++ b/src/app/routes.ts
@@ -1,6 +1,19 @@
import type {Page} from "@sveltejs/kit"
+import {goto} from "$app/navigation"
+import {nthEq, sleep} from "@welshman/lib"
+import type {TrustedEvent} from "@welshman/util"
+import {tracker} from "@welshman/app"
+import {scrollToEvent} from "@lib/html"
import {identity} from "@welshman/lib"
-import {makeChatId, decodeRelay, encodeRelay, userRoomsByUrl} from "@app/state"
+import {
+ getTagValue,
+ DIRECT_MESSAGE,
+ DIRECT_MESSAGE_FILE,
+ MESSAGE,
+ THREAD,
+ EVENT_TIME,
+} from "@welshman/util"
+import {makeChatId, decodeRelay, encodeRelay, userRoomsByUrl, ROOM} from "@app/state"
export const makeSpacePath = (url: string, ...extra: (string | undefined)[]) => {
let path = `/spaces/${encodeRelay(url)}`
@@ -46,3 +59,50 @@ export const getPrimaryNavItemIndex = ($page: Page) => {
return 0
}
}
+
+export const goToMessage = async (url: string, room: string | undefined, id: string) => {
+ await goto(room ? makeRoomPath(url, room) : makeSpacePath(url, "chat"))
+ await sleep(300)
+
+ return scrollToEvent(id)
+}
+
+export const goToEvent = async (event: TrustedEvent) => {
+ if (event.kind === DIRECT_MESSAGE || event.kind === DIRECT_MESSAGE_FILE) {
+ return await scrollToEvent(event.id)
+ }
+
+ const [url] = tracker.getRelays(event.id)
+ const room = getTagValue(ROOM, event.tags)
+
+ if (url) {
+ if (event.kind === THREAD) {
+ return goto(makeThreadPath(url, event.id))
+ }
+
+ if (event.kind === EVENT_TIME) {
+ return goto(makeCalendarPath(url, event.id))
+ }
+
+ if (event.kind === MESSAGE) {
+ return goToMessage(url, room, event.id)
+ }
+
+ const kind = event.tags.find(nthEq(0, "K"))?.[1]
+ const id = event.tags.find(nthEq(0, "E"))?.[1]
+
+ if (id && kind) {
+ if (parseInt(kind) === THREAD) {
+ return goto(makeThreadPath(url, id))
+ }
+
+ if (parseInt(kind) === EVENT_TIME) {
+ return goto(makeCalendarPath(url, id))
+ }
+
+ if (parseInt(kind) === MESSAGE) {
+ return goToMessage(url, room, id)
+ }
+ }
+ }
+}
diff --git a/src/lib/html.ts b/src/lib/html.ts
index 8b4473b9..b4ee2db9 100644
--- a/src/lib/html.ts
+++ b/src/lib/html.ts
@@ -100,7 +100,7 @@ export const isIntersecting = async (element: Element) =>
observer.observe(element)
})
-export const scrollToEvent = async (id: string) => {
+export const scrollToEvent = async (id: string, attempts = 3): Promise => {
const element = document.querySelector(`[data-event="${id}"]`) as any
if (element) {
@@ -114,6 +114,8 @@ export const scrollToEvent = async (id: string) => {
setTimeout(() => {
element.style = ""
}, 800 + 400)
+
+ return true
} else {
const lastElement = last(Array.from(document.querySelectorAll("[data-event]")))
@@ -123,6 +125,10 @@ export const scrollToEvent = async (id: string) => {
await sleep(300)
- scrollToEvent(id)
+ if (attempts > 0) {
+ return scrollToEvent(id, attempts - 1)
+ } else {
+ return false
+ }
}
}