diff --git a/src/app/components/MenuSpacesItem.svelte b/src/app/components/MenuSpacesItem.svelte
index 9eba280..1e0099f 100644
--- a/src/app/components/MenuSpacesItem.svelte
+++ b/src/app/components/MenuSpacesItem.svelte
@@ -5,7 +5,7 @@
import RelayName from "@app/components/RelayName.svelte"
import RelayDescription from "@app/components/RelayDescription.svelte"
import {makeSpacePath} from "@app/routes"
- import {inactiveNotifications} from "@app/notifications"
+ import {notifications} from "@app/notifications"
export let url
@@ -17,7 +17,7 @@
- {#if $inactiveNotifications.has(path)}
+ {#if $notifications.has(path)}
{/if}
diff --git a/src/app/components/PrimaryNav.svelte b/src/app/components/PrimaryNav.svelte
index 8dcab4c..252e530 100644
--- a/src/app/components/PrimaryNav.svelte
+++ b/src/app/components/PrimaryNav.svelte
@@ -1,4 +1,5 @@
diff --git a/src/app/notifications.ts b/src/app/notifications.ts
index 25bd9f1..f1d2485 100644
--- a/src/app/notifications.ts
+++ b/src/app/notifications.ts
@@ -1,7 +1,6 @@
import {writable, derived} from "svelte/store"
-import {page} from "$app/stores"
import {pubkey} from "@welshman/app"
-import {prop, max, sortBy, now} from "@welshman/lib"
+import {prop, sortBy, now} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {MESSAGE} from "@welshman/util"
import {makeSpacePath, makeChatPath, makeThreadPath, makeRoomPath} from "@app/routes"
@@ -20,8 +19,7 @@ export const checked = writable>({})
export const deriveChecked = (key: string) => derived(checked, prop(key))
-export const setChecked = (key: string) =>
- checked.update(state => ({...state, [key]: now()}))
+export const setChecked = (key: string) => checked.update(state => ({...state, [key]: now()}))
// Derived notifications state
@@ -35,15 +33,15 @@ export const notifications = derived(
return false
}
- let checkPath = ""
- let lastChecked = $checked["*"]
+ for (const [entryPath, ts] of Object.entries($checked)) {
+ const isMatch = entryPath === "*" || entryPath.startsWith(path)
- for (const segment of path.slice(1).split("/")) {
- checkPath += "/" + segment
- lastChecked = max([lastChecked, $checked[checkPath]])
+ if (isMatch && ts > latestEvent.created_at) {
+ return false
+ }
}
- return lastChecked < latestEvent.created_at
+ return true
}
const paths = new Set()
@@ -83,9 +81,3 @@ export const notifications = derived(
return paths
},
)
-
-export const inactiveNotifications = derived(
- [page, notifications],
- ([$page, $notifications]) =>
- new Set(Array.from($notifications).filter(path => !$page.url.pathname.startsWith(path))),
-)
diff --git a/src/app/requests.ts b/src/app/requests.ts
index 87e1506..5f1156c 100644
--- a/src/app/requests.ts
+++ b/src/app/requests.ts
@@ -1,6 +1,6 @@
import type {Unsubscriber} from "svelte/store"
import {sleep, partition, assoc, now} from "@welshman/lib"
-import {MESSAGE, DELETE, THREAD, COMMENT} from "@welshman/util"
+import {MESSAGE, REACTION, DELETE, THREAD, COMMENT} from "@welshman/util"
import type {SubscribeRequestWithHandlers, Subscription} from "@welshman/net"
import {SubscriptionEvent} from "@welshman/net"
import type {AppSyncOpts} from "@welshman/app"
@@ -93,14 +93,15 @@ export const listenForNotifications = () => {
export const listenForChannelMessages = (url: string, room: string) => {
const since = now()
const relays = [url]
+ const kinds = [MESSAGE, REACTION, DELETE]
const legacyRoom = room === GENERAL ? "general" : room
// Load legacy immediate so our request doesn't get rejected by nip29 relays
load({relays, filters: [{kinds: [LEGACY_MESSAGE], "#~": [legacyRoom]}], delay: 0})
// Load historical state with negentropy if available
- pullConservatively({relays, filters: [{kinds: [MESSAGE, DELETE], "#h": [room]}]})
+ pullConservatively({relays, filters: [{kinds, "#h": [room]}]})
// Listen for new messages
- return subscribePersistent({relays, filters: [{kinds: [MESSAGE, DELETE], "#h": [room], since}]})
+ return subscribePersistent({relays, filters: [{kinds, "#h": [room], since}]})
}
diff --git a/src/routes/spaces/[relay]/+page.svelte b/src/routes/spaces/[relay]/+page.svelte
index bd02f6e..1d08f71 100644
--- a/src/routes/spaces/[relay]/+page.svelte
+++ b/src/routes/spaces/[relay]/+page.svelte
@@ -2,6 +2,7 @@
import {page} from "$app/stores"
import type {TrustedEvent} from "@welshman/util"
import {deriveRelay} from "@welshman/app"
+ import {fade} from "@lib/transition"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
@@ -25,12 +26,14 @@
getMembershipUrls,
} from "@app/state"
import {makeChatPath, makeRoomPath, makeSpacePath} from "@app/routes"
+ import {notifications} from "@app/notifications"
import {pushModal} from "@app/modal"
const url = decodeRelay($page.params.relay)
const relay = deriveRelay(url)
const userRooms = deriveUserRooms(url)
const otherRooms = deriveOtherRooms(url)
+ const threadsPath = makeSpacePath(url, "threads")
const joinSpace = () => pushModal(SpaceJoin, {url})
@@ -116,17 +119,33 @@
{/if}
-
-
Threads
+
+
+
+ Threads
+ {#if $notifications.has(threadsPath)}
+
+ {/if}
+
{#each $userRooms as room (room)}
-
+ {@const roomPath = makeRoomPath(url, room)}
+
{#if channelIsLocked($channelsById.get(makeChannelId(url, room)))}
{:else}
{/if}
-
+
+
+ {#if $notifications.has(roomPath)}
+
+ {/if}
+
{/each}
{#each $otherRooms as room (room)}