Bring back some notification badges

This commit is contained in:
Jon Staab
2026-02-27 12:25:16 -08:00
parent dfedf4e879
commit ccfe1bded5
5 changed files with 52 additions and 7 deletions
+1 -1
View File
@@ -256,7 +256,7 @@
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
{/if}
{#each $userRooms as h, i (h)}
<SpaceMenuRoomItem {replaceState} {url} {h} />
<SpaceMenuRoomItem notify {replaceState} {url} {h} />
{/each}
{#if $otherRooms.length > 0}
<div class="h-2"></div>
@@ -3,11 +3,15 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import SpaceMenu from "@app/components/SpaceMenu.svelte"
import {notifications} from "@app/util/notifications"
import {makeSpacePath} from "@app/util/routes"
import {pushDrawer} from "@app/util/modal"
import {deriveSocketStatus} from "@app/core/state"
const {url} = $props()
const path = makeSpacePath(url) + ":mobile"
const status = deriveSocketStatus(url)
const openMenu = () => pushDrawer(SpaceMenu, {url})
@@ -17,5 +21,7 @@
<Icon icon={MenuDots} />
{#if $status.theme !== "success"}
<div class="absolute right-0 top-0 -mr-1 -mt-1 h-2 w-2 rounded-full bg-{$status.theme}"></div>
{:else if $notifications.has(path)}
<div class="absolute right-0 top-0 -mr-1 -mt-1 h-2 w-2 rounded-full bg-primary"></div>
{/if}
</Button>
+7 -2
View File
@@ -4,16 +4,18 @@
import Icon from "@lib/components/Icon.svelte"
import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
import {notifications} from "@app/util/notifications"
import {makeRoomPath} from "@app/util/routes"
import {deriveShouldNotify} from "@app/core/state"
interface Props {
url: any
h: any
notify?: boolean
replaceState?: boolean
}
const {url, h, replaceState = false}: Props = $props()
const {url, h, notify = false, replaceState = false}: Props = $props()
const path = makeRoomPath(url, h)
const shouldNotifyForSpace = deriveShouldNotify(url)
@@ -21,7 +23,10 @@
const showDifferenceIcon = $derived($shouldNotifyForRoom !== $shouldNotifyForSpace)
</script>
<SecondaryNavItem href={path} {replaceState}>
<SecondaryNavItem
href={path}
{replaceState}
notification={notify ? $notifications.has(path) : false}>
<RoomNameWithImage {url} {h} />
{#if showDifferenceIcon}
<Icon icon={$shouldNotifyForRoom ? VolumeLoud : VolumeCross} size={4} class="opacity-50" />
+36 -2
View File
@@ -12,12 +12,14 @@ import {
repository,
publishThunk,
loadRelay,
relaysByUrl,
waitForThunkError,
userMessagingRelayList,
} from "@welshman/app"
import {
on,
call,
find,
assoc,
poll,
prop,
@@ -44,7 +46,14 @@ import {
Address,
} from "@welshman/util"
import {buildUrl} from "@lib/util"
import {makeSpacePath, makeChatPath, getEventPath, goToEvent} from "@app/util/routes"
import {
makeSpacePath,
makeRoomPath,
makeSpaceChatPath,
makeChatPath,
getEventPath,
goToEvent,
} from "@app/util/routes"
import {
DM_KINDS,
CONTENT_KINDS,
@@ -57,9 +66,11 @@ import {
userSettingsValues,
userGroupList,
getSpaceUrlsFromGroupList,
getSpaceRoomsFromGroupList,
makeCommentFilter,
userSpaceUrls,
shouldNotify,
hasNip29,
device,
} from "@app/core/state"
import {kv} from "@app/core/storage"
@@ -125,6 +136,7 @@ export const allNotifications = derived(
pubkey,
checked,
chatsById,
relaysByUrl,
userGroupList,
deriveEventsByIdByUrl({
tracker,
@@ -135,7 +147,7 @@ export const allNotifications = derived(
identity,
),
),
([$pubkey, $checked, $chatsById, $userGroupList, eventsByIdByUrl]) => {
([$pubkey, $checked, $chatsById, $relaysByUrl, $userGroupList, eventsByIdByUrl]) => {
const hasNotification = (path: string, latestEvent?: TrustedEvent) => {
if (!latestEvent || latestEvent.pubkey === $pubkey) {
return false
@@ -168,12 +180,34 @@ export const allNotifications = derived(
for (const url of getSpaceUrlsFromGroupList($userGroupList)) {
const spacePath = makeSpacePath(url)
const spacePathMobile = spacePath + ":mobile"
const eventsById = eventsByIdByUrl.get(url) || new Map()
const latestEvent = first(sortEventsDesc(eventsById.values()))
if (hasNotification(spacePath, latestEvent)) {
paths.add(spacePath)
}
if (hasNip29($relaysByUrl.get(url))) {
for (const h of getSpaceRoomsFromGroupList(url, $userGroupList)) {
const roomPath = makeRoomPath(url, h)
const latestEvent = find(e => e.tags.some(spec(["h", h])), eventsById.values())
if (hasNotification(roomPath, latestEvent)) {
paths.add(spacePathMobile)
paths.add(spacePath)
paths.add(roomPath)
}
}
} else {
const messagesPath = makeSpaceChatPath(url)
if (hasNotification(messagesPath, first(eventsById.values()))) {
paths.add(spacePathMobile)
paths.add(spacePath)
paths.add(messagesPath)
}
}
}
return paths
+2 -2
View File
@@ -38,7 +38,7 @@
class:text-base-content={active}
class:bg-base-100={active}>
{@render children?.()}
{#if !active && notification}
{#if notification}
<div class="absolute right-2 top-5 h-2 w-2 rounded-full bg-primary" transition:fade></div>
{/if}
</a>
@@ -48,7 +48,7 @@
class="{restProps.class} relative flex w-full items-center gap-3 text-left transition-all hover:bg-base-100 hover:text-base-content"
class:text-base-content={active}
class:bg-base-100={active}>
{#if !active && notification}
{#if notification}
<div class="absolute right-2 top-5 h-2 w-2 rounded-full bg-primary" transition:fade></div>
{/if}
{@render children?.()}