forked from coracle/flotilla
Bring back some notification badges
This commit is contained in:
@@ -256,7 +256,7 @@
|
|||||||
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
|
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
|
||||||
{/if}
|
{/if}
|
||||||
{#each $userRooms as h, i (h)}
|
{#each $userRooms as h, i (h)}
|
||||||
<SpaceMenuRoomItem {replaceState} {url} {h} />
|
<SpaceMenuRoomItem notify {replaceState} {url} {h} />
|
||||||
{/each}
|
{/each}
|
||||||
{#if $otherRooms.length > 0}
|
{#if $otherRooms.length > 0}
|
||||||
<div class="h-2"></div>
|
<div class="h-2"></div>
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import SpaceMenu from "@app/components/SpaceMenu.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 {pushDrawer} from "@app/util/modal"
|
||||||
import {deriveSocketStatus} from "@app/core/state"
|
import {deriveSocketStatus} from "@app/core/state"
|
||||||
|
|
||||||
const {url} = $props()
|
const {url} = $props()
|
||||||
|
|
||||||
|
const path = makeSpacePath(url) + ":mobile"
|
||||||
|
|
||||||
const status = deriveSocketStatus(url)
|
const status = deriveSocketStatus(url)
|
||||||
|
|
||||||
const openMenu = () => pushDrawer(SpaceMenu, {url})
|
const openMenu = () => pushDrawer(SpaceMenu, {url})
|
||||||
@@ -17,5 +21,7 @@
|
|||||||
<Icon icon={MenuDots} />
|
<Icon icon={MenuDots} />
|
||||||
{#if $status.theme !== "success"}
|
{#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>
|
<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}
|
{/if}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -4,16 +4,18 @@
|
|||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
|
import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
|
||||||
import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
|
import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
|
||||||
|
import {notifications} from "@app/util/notifications"
|
||||||
import {makeRoomPath} from "@app/util/routes"
|
import {makeRoomPath} from "@app/util/routes"
|
||||||
import {deriveShouldNotify} from "@app/core/state"
|
import {deriveShouldNotify} from "@app/core/state"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
url: any
|
url: any
|
||||||
h: any
|
h: any
|
||||||
|
notify?: boolean
|
||||||
replaceState?: 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 path = makeRoomPath(url, h)
|
||||||
const shouldNotifyForSpace = deriveShouldNotify(url)
|
const shouldNotifyForSpace = deriveShouldNotify(url)
|
||||||
@@ -21,7 +23,10 @@
|
|||||||
const showDifferenceIcon = $derived($shouldNotifyForRoom !== $shouldNotifyForSpace)
|
const showDifferenceIcon = $derived($shouldNotifyForRoom !== $shouldNotifyForSpace)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SecondaryNavItem href={path} {replaceState}>
|
<SecondaryNavItem
|
||||||
|
href={path}
|
||||||
|
{replaceState}
|
||||||
|
notification={notify ? $notifications.has(path) : false}>
|
||||||
<RoomNameWithImage {url} {h} />
|
<RoomNameWithImage {url} {h} />
|
||||||
{#if showDifferenceIcon}
|
{#if showDifferenceIcon}
|
||||||
<Icon icon={$shouldNotifyForRoom ? VolumeLoud : VolumeCross} size={4} class="opacity-50" />
|
<Icon icon={$shouldNotifyForRoom ? VolumeLoud : VolumeCross} size={4} class="opacity-50" />
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ import {
|
|||||||
repository,
|
repository,
|
||||||
publishThunk,
|
publishThunk,
|
||||||
loadRelay,
|
loadRelay,
|
||||||
|
relaysByUrl,
|
||||||
waitForThunkError,
|
waitForThunkError,
|
||||||
userMessagingRelayList,
|
userMessagingRelayList,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import {
|
import {
|
||||||
on,
|
on,
|
||||||
call,
|
call,
|
||||||
|
find,
|
||||||
assoc,
|
assoc,
|
||||||
poll,
|
poll,
|
||||||
prop,
|
prop,
|
||||||
@@ -44,7 +46,14 @@ import {
|
|||||||
Address,
|
Address,
|
||||||
} from "@welshman/util"
|
} from "@welshman/util"
|
||||||
import {buildUrl} from "@lib/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 {
|
import {
|
||||||
DM_KINDS,
|
DM_KINDS,
|
||||||
CONTENT_KINDS,
|
CONTENT_KINDS,
|
||||||
@@ -57,9 +66,11 @@ import {
|
|||||||
userSettingsValues,
|
userSettingsValues,
|
||||||
userGroupList,
|
userGroupList,
|
||||||
getSpaceUrlsFromGroupList,
|
getSpaceUrlsFromGroupList,
|
||||||
|
getSpaceRoomsFromGroupList,
|
||||||
makeCommentFilter,
|
makeCommentFilter,
|
||||||
userSpaceUrls,
|
userSpaceUrls,
|
||||||
shouldNotify,
|
shouldNotify,
|
||||||
|
hasNip29,
|
||||||
device,
|
device,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
import {kv} from "@app/core/storage"
|
import {kv} from "@app/core/storage"
|
||||||
@@ -125,6 +136,7 @@ export const allNotifications = derived(
|
|||||||
pubkey,
|
pubkey,
|
||||||
checked,
|
checked,
|
||||||
chatsById,
|
chatsById,
|
||||||
|
relaysByUrl,
|
||||||
userGroupList,
|
userGroupList,
|
||||||
deriveEventsByIdByUrl({
|
deriveEventsByIdByUrl({
|
||||||
tracker,
|
tracker,
|
||||||
@@ -135,7 +147,7 @@ export const allNotifications = derived(
|
|||||||
identity,
|
identity,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
([$pubkey, $checked, $chatsById, $userGroupList, eventsByIdByUrl]) => {
|
([$pubkey, $checked, $chatsById, $relaysByUrl, $userGroupList, eventsByIdByUrl]) => {
|
||||||
const hasNotification = (path: string, latestEvent?: TrustedEvent) => {
|
const hasNotification = (path: string, latestEvent?: TrustedEvent) => {
|
||||||
if (!latestEvent || latestEvent.pubkey === $pubkey) {
|
if (!latestEvent || latestEvent.pubkey === $pubkey) {
|
||||||
return false
|
return false
|
||||||
@@ -168,12 +180,34 @@ export const allNotifications = derived(
|
|||||||
|
|
||||||
for (const url of getSpaceUrlsFromGroupList($userGroupList)) {
|
for (const url of getSpaceUrlsFromGroupList($userGroupList)) {
|
||||||
const spacePath = makeSpacePath(url)
|
const spacePath = makeSpacePath(url)
|
||||||
|
const spacePathMobile = spacePath + ":mobile"
|
||||||
const eventsById = eventsByIdByUrl.get(url) || new Map()
|
const eventsById = eventsByIdByUrl.get(url) || new Map()
|
||||||
const latestEvent = first(sortEventsDesc(eventsById.values()))
|
const latestEvent = first(sortEventsDesc(eventsById.values()))
|
||||||
|
|
||||||
if (hasNotification(spacePath, latestEvent)) {
|
if (hasNotification(spacePath, latestEvent)) {
|
||||||
paths.add(spacePath)
|
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
|
return paths
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
class:text-base-content={active}
|
class:text-base-content={active}
|
||||||
class:bg-base-100={active}>
|
class:bg-base-100={active}>
|
||||||
{@render children?.()}
|
{@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>
|
<div class="absolute right-2 top-5 h-2 w-2 rounded-full bg-primary" transition:fade></div>
|
||||||
{/if}
|
{/if}
|
||||||
</a>
|
</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="{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:text-base-content={active}
|
||||||
class:bg-base-100={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>
|
<div class="absolute right-2 top-5 h-2 w-2 rounded-full bg-primary" transition:fade></div>
|
||||||
{/if}
|
{/if}
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
Reference in New Issue
Block a user