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"}
{value}
{:else}
-
-
-
+ {@const event = $state.snapshot(value as TrustedEvent)}
+ {#if event.kind === ROOM_ADD_MEMBER}
+
+ {:else if event.kind === ROOM_REMOVE_MEMBER}
+
+ {:else}
+
+
+
+ {/if}
{/if}
{/each}
diff --git a/src/routes/spaces/[relay]/chat/+page.svelte b/src/routes/spaces/[relay]/chat/+page.svelte
index 19a0d10..af41400 100644
--- a/src/routes/spaces/[relay]/chat/+page.svelte
+++ b/src/routes/spaces/[relay]/chat/+page.svelte
@@ -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 @@
{value}
{:else}
{@const event = $state.snapshot(value as TrustedEvent)}
-
-
-
+ {#if event.kind === RELAY_ADD_MEMBER}
+
+ {:else if event.kind === RELAY_REMOVE_MEMBER}
+
+ {:else}
+
+
+
+ {/if}
{/if}
{/each}
diff --git a/tailwind.config.js b/tailwind.config.js
index 77a9a61..ea7fe03 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -9,6 +9,10 @@ config({path: ".env.template"})
export default {
content: ["./src/**/*.{html,js,svelte,ts}"],
darkMode: ['selector', '[data-theme="dark"]'],
+ safelist: [
+ 'bg-success',
+ 'bg-warning',
+ ],
theme: {
extend: {},
zIndex: {