Add relay members list and room join/leave events

This commit is contained in:
Matthew Remmel
2025-10-15 12:04:17 -04:00
committed by hodlbod
parent 43cf91e877
commit a730384baf
22 changed files with 499 additions and 323 deletions
+32 -16
View File
@@ -7,7 +7,13 @@
import type {MakeNonOptional} from "@welshman/lib"
import {now, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib"
import type {TrustedEvent, EventContent} from "@welshman/util"
import {makeEvent, makeRoomMeta, MESSAGE} from "@welshman/util"
import {
makeEvent,
makeRoomMeta,
MESSAGE,
ROOM_ADD_MEMBER,
ROOM_REMOVE_MEMBER,
} from "@welshman/util"
import {pubkey, publishThunk, waitForThunkError, joinRoom, leaveRoom} from "@welshman/app"
import {slide, fade, fly} from "@lib/transition"
import Hashtag from "@assets/icons/hashtag.svg?dataurl"
@@ -26,13 +32,16 @@
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
import ChannelName from "@app/components/ChannelName.svelte"
import ChannelItem from "@app/components/ChannelItem.svelte"
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte"
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte"
import ChannelCompose from "@app/components/ChannelCompose.svelte"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte"
import {
userRoomsByUrl,
deriveUserRooms,
userSettingsValues,
decodeRelay,
deriveUserMembershipStatus,
deriveUserRoomMembershipStatus,
deriveChannel,
MembershipStatus,
PROTECTED,
@@ -49,16 +58,16 @@
import {makeFeed} from "@app/core/requests"
import {popKey} from "@lib/implicit"
import {pushToast} from "@app/util/toast"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
const {room, relay} = $page.params as MakeNonOptional<typeof $page.params>
const mounted = now()
const lastChecked = $checked[$page.url.pathname]
const url = decodeRelay(relay)
const channel = deriveChannel(url, room)
const isFavorite = $derived($userRoomsByUrl.get(url)?.has(room))
const shouldProtect = canEnforceNip70(url)
const membershipStatus = deriveUserMembershipStatus(url, room)
const userRooms = deriveUserRooms(url)
const isFavorite = $derived($userRooms.includes(room))
const membershipStatus = deriveUserRoomMembershipStatus(url, room)
const addFavorite = () => addRoomMembership(url, room)
@@ -256,7 +265,7 @@
const feed = makeFeed({
url,
element: element!,
filters: [{kinds: MESSAGE_KINDS, "#h": [room]}],
filters: [{kinds: [...MESSAGE_KINDS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [room]}],
onExhausted: () => {
loadingEvents = false
},
@@ -398,15 +407,22 @@
{:else if type === "date"}
<Divider>{value}</Divider>
{:else}
<div in:slide class:-mt-1={!showPubkey}>
<ChannelItem
{url}
{replyTo}
event={$state.snapshot(value as TrustedEvent)}
{showPubkey}
canEdit={canEditEvent}
onEdit={onEditEvent} />
</div>
{@const event = $state.snapshot(value as TrustedEvent)}
{#if event.kind === ROOM_ADD_MEMBER}
<ChannelItemAddMember {url} {event} />
{:else if event.kind === ROOM_REMOVE_MEMBER}
<ChannelItemRemoveMember {url} {event} />
{:else}
<div in:slide class:-mt-1={!showPubkey}>
<ChannelItem
{url}
{event}
{replyTo}
{showPubkey}
canEdit={canEditEvent}
onEdit={onEditEvent} />
</div>
{/if}
{/if}
{/each}
<p class="flex h-10 items-center justify-center py-20">
+22 -14
View File
@@ -5,9 +5,9 @@
import {readable} from "svelte/store"
import {now, formatTimestampAsDate, MINUTE, ago} from "@welshman/lib"
import type {TrustedEvent, EventContent} from "@welshman/util"
import {makeEvent, MESSAGE} from "@welshman/util"
import {makeEvent, MESSAGE, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER} from "@welshman/util"
import {pubkey, publishThunk} from "@welshman/app"
import {slide, fade, fly} from "@lib/transition"
import {fade, fly} from "@lib/transition"
import ChatRound from "@assets/icons/chat-round.svg?dataurl"
import AltArrowDown from "@assets/icons/alt-arrow-down.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
@@ -19,15 +19,17 @@
import ThunkToast from "@app/components/ThunkToast.svelte"
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
import ChannelItem from "@app/components/ChannelItem.svelte"
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte"
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte"
import ChannelCompose from "@app/components/ChannelCompose.svelte"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte"
import {userSettingsValues, decodeRelay, MESSAGE_FILTER, PROTECTED} from "@app/core/state"
import {userSettingsValues, decodeRelay, PROTECTED, MESSAGE_KINDS} from "@app/core/state"
import {prependParent, canEnforceNip70, publishDelete} from "@app/core/commands"
import {setChecked, checked} from "@app/util/notifications"
import {pushToast} from "@app/util/toast"
import {makeFeed} from "@app/core/requests"
import {popKey} from "@lib/implicit"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
const mounted = now()
const lastChecked = $checked[$page.url.pathname]
@@ -218,7 +220,7 @@
const feed = makeFeed({
url,
element: element!,
filters: [MESSAGE_FILTER],
filters: [{kinds: [...MESSAGE_KINDS, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER]}],
onExhausted: () => {
loadingEvents = false
},
@@ -271,15 +273,21 @@
<Divider>{value}</Divider>
{:else}
{@const event = $state.snapshot(value as TrustedEvent)}
<div in:slide class:-mt-1={!showPubkey}>
<ChannelItem
{url}
{event}
{replyTo}
{showPubkey}
canEdit={canEditEvent}
onEdit={onEditEvent} />
</div>
{#if event.kind === RELAY_ADD_MEMBER}
<ChannelItemAddMember {url} {event} />
{:else if event.kind === RELAY_REMOVE_MEMBER}
<ChannelItemRemoveMember {url} {event} />
{:else}
<div class:-mt-1={!showPubkey}>
<ChannelItem
{url}
{event}
{replyTo}
{showPubkey}
canEdit={canEditEvent}
onEdit={onEditEvent} />
</div>
{/if}
{/if}
{/each}
<p class="flex h-10 items-center justify-center py-20">