Rename channel to room

This commit is contained in:
Jon Staab
2025-10-30 15:36:14 -07:00
parent dbaa0f5d49
commit a324dad2ba
36 changed files with 148 additions and 148 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ Here are a few important domain objects:
- Spaces are relays used as community groups. Their `url`s are core to a lot of data and components, and are frequently passed around from place to place. - Spaces are relays used as community groups. Their `url`s are core to a lot of data and components, and are frequently passed around from place to place.
- Chats are direct message conversations. There is currently some ambiguity in routing, since relays that don't support NIP 29 also have a "chat" tab, which uses vanilla NIP-C7. - Chats are direct message conversations. There is currently some ambiguity in routing, since relays that don't support NIP 29 also have a "chat" tab, which uses vanilla NIP-C7.
- NIP 29 groups are variously called "rooms" and "channels". Conventionally, a "room" is a group id, while a "channel" as an object representing the group's metadata. - NIP 29 groups are variously called "rooms" and "rooms". Conventionally, a "room" is a group id, while a "room" as an object representing the group's metadata.
- "Alerts" are records of requests the user has made to be notified, following [this NIP](https://github.com/nostr-protocol/nips/pull/1796) - "Alerts" are records of requests the user has made to be notified, following [this NIP](https://github.com/nostr-protocol/nips/pull/1796)
`app/core/requests` contains utilities related to loading data from the nostr network. This might include feed manager utilities, loaders, or listeners. `app/core/requests` contains utilities related to loading data from the nostr network. This might include feed manager utilities, loaders, or listeners.
+14 -14
View File
@@ -4179,19 +4179,19 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'} engines: {node: '>=8'}
side-channel-list@1.0.0: side-room-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
side-channel-map@1.0.1: side-room-map@1.0.1:
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
side-channel-weakmap@1.0.2: side-room-weakmap@1.0.2:
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
side-channel@1.1.0: side-room@1.1.0:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@@ -8136,7 +8136,7 @@ snapshots:
dependencies: dependencies:
es-errors: 1.3.0 es-errors: 1.3.0
hasown: 2.0.2 hasown: 2.0.2
side-channel: 1.1.0 side-room: 1.1.0
is-array-buffer@3.0.5: is-array-buffer@3.0.5:
dependencies: dependencies:
@@ -9334,33 +9334,33 @@ snapshots:
shebang-regex@3.0.0: {} shebang-regex@3.0.0: {}
side-channel-list@1.0.0: side-room-list@1.0.0:
dependencies: dependencies:
es-errors: 1.3.0 es-errors: 1.3.0
object-inspect: 1.13.4 object-inspect: 1.13.4
side-channel-map@1.0.1: side-room-map@1.0.1:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
es-errors: 1.3.0 es-errors: 1.3.0
get-intrinsic: 1.3.0 get-intrinsic: 1.3.0
object-inspect: 1.13.4 object-inspect: 1.13.4
side-channel-weakmap@1.0.2: side-room-weakmap@1.0.2:
dependencies: dependencies:
call-bound: 1.0.4 call-bound: 1.0.4
es-errors: 1.3.0 es-errors: 1.3.0
get-intrinsic: 1.3.0 get-intrinsic: 1.3.0
object-inspect: 1.13.4 object-inspect: 1.13.4
side-channel-map: 1.0.1 side-room-map: 1.0.1
side-channel@1.1.0: side-room@1.1.0:
dependencies: dependencies:
es-errors: 1.3.0 es-errors: 1.3.0
object-inspect: 1.13.4 object-inspect: 1.13.4
side-channel-list: 1.0.0 side-room-list: 1.0.0
side-channel-map: 1.0.1 side-room-map: 1.0.1
side-channel-weakmap: 1.0.2 side-room-weakmap: 1.0.2
signal-exit@3.0.7: {} signal-exit@3.0.7: {}
@@ -9483,7 +9483,7 @@ snapshots:
internal-slot: 1.1.0 internal-slot: 1.1.0
regexp.prototype.flags: 1.5.4 regexp.prototype.flags: 1.5.4
set-function-name: 2.0.2 set-function-name: 2.0.2
side-channel: 1.1.0 side-room: 1.1.0
string.prototype.trim@1.2.10: string.prototype.trim@1.2.10:
dependencies: dependencies:
+7 -7
View File
@@ -21,7 +21,7 @@
type Props = { type Props = {
url?: string url?: string
channel?: string room?: string
notifyChat?: boolean notifyChat?: boolean
notifyThreads?: boolean notifyThreads?: boolean
notifyCalendar?: boolean notifyCalendar?: boolean
@@ -30,7 +30,7 @@
let { let {
url = "", url = "",
channel = "email", room = "email",
notifyChat = true, notifyChat = true,
notifyThreads = true, notifyThreads = true,
notifyCalendar = true, notifyCalendar = true,
@@ -50,7 +50,7 @@
const back = () => history.back() const back = () => history.back()
const submit = async () => { const submit = async () => {
if (channel === "email" && !email.includes("@")) { if (room === "email" && !email.includes("@")) {
return pushToast({ return pushToast({
theme: "error", theme: "error",
message: "Please provide an email address", message: "Please provide an email address",
@@ -100,7 +100,7 @@
feed: makeIntersectionFeed(feedFromFilters(filters), makeRelayFeed(url)), feed: makeIntersectionFeed(feedFromFilters(filters), makeRelayFeed(url)),
claims: claim ? {[url]: claim} : {}, claims: claim ? {[url]: claim} : {},
description: `for ${displayList(display)} on ${displayRelayUrl(url)}`, description: `for ${displayList(display)} on ${displayRelayUrl(url)}`,
email: channel === "email" ? {cron, email} : undefined, email: room === "email" ? {cron, email} : undefined,
}) })
if (error) { if (error) {
@@ -116,7 +116,7 @@
onMount(() => { onMount(() => {
if (!canSendPushNotifications()) { if (!canSendPushNotifications()) {
channel = "email" room = "email"
} }
}) })
</script> </script>
@@ -136,14 +136,14 @@
<p>Alert Type*</p> <p>Alert Type*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<select bind:value={channel} class="select select-bordered"> <select bind:value={room} class="select select-bordered">
<option value="email">Email Digest</option> <option value="email">Email Digest</option>
<option value="push">Push Notification</option> <option value="push">Push Notification</option>
</select> </select>
{/snippet} {/snippet}
</FieldInline> </FieldInline>
{/if} {/if}
{#if channel === "email"} {#if room === "email"}
<FieldInline> <FieldInline>
{#snippet label()} {#snippet label()}
<p>Email Address*</p> <p>Email Address*</p>
+2 -2
View File
@@ -17,14 +17,14 @@
const {alert}: Props = $props() const {alert}: Props = $props()
const cron = $derived(getTagValue("cron", alert.tags)) const cron = $derived(getTagValue("cron", alert.tags))
const channel = $derived(getTagValue("channel", alert.tags)) const room = $derived(getTagValue("room", alert.tags))
const feeds = $derived(getTagValues("feed", alert.tags)) const feeds = $derived(getTagValues("feed", alert.tags))
const description = $derived( const description = $derived(
getTagValue("description", alert.tags) || getTagValue("description", alert.tags) ||
[ [
`${cron?.endsWith("1") ? "Weekly" : "Daily"} alert for events`, `${cron?.endsWith("1") ? "Weekly" : "Daily"} alert for events`,
displayFeeds(feeds.map(parseJson)), displayFeeds(feeds.map(parseJson)),
`sent via ${channel}.`, `sent via ${room}.`,
].join(" "), ].join(" "),
) )
+3 -3
View File
@@ -24,11 +24,11 @@
type Props = { type Props = {
url?: string url?: string
channel?: string room?: string
hideSpaceField?: boolean hideSpaceField?: boolean
} }
const {url = "", channel = "push", hideSpaceField = false}: Props = $props() const {url = "", room = "push", hideSpaceField = false}: Props = $props()
const dmStatus = $derived($dmAlert ? deriveAlertStatus(getAddress($dmAlert.event)) : undefined) const dmStatus = $derived($dmAlert ? deriveAlertStatus(getAddress($dmAlert.event)) : undefined)
@@ -46,7 +46,7 @@
}), }),
) )
const startAlert = () => pushModal(AlertAdd, {url, channel, hideSpaceField}) const startAlert = () => pushModal(AlertAdd, {url, room, hideSpaceField})
const uncheckDmAlert = async (message: string) => { const uncheckDmAlert = async (message: string) => {
await sleep(100) await sleep(100)
@@ -5,7 +5,7 @@
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 Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import ReactionSummary from "@app/components/ReactionSummary.svelte" import ReactionSummary from "@app/components/ReactionSummary.svelte"
import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte" import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte"
import EventActivity from "@app/components/EventActivity.svelte" import EventActivity from "@app/components/EventActivity.svelte"
@@ -41,7 +41,7 @@
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
+2 -2
View File
@@ -5,7 +5,7 @@
import CalendarEventActions from "@app/components/CalendarEventActions.svelte" import CalendarEventActions from "@app/components/CalendarEventActions.svelte"
import CalendarEventHeader from "@app/components/CalendarEventHeader.svelte" import CalendarEventHeader from "@app/components/CalendarEventHeader.svelte"
import ProfileLink from "@app/components/ProfileLink.svelte" import ProfileLink from "@app/components/ProfileLink.svelte"
import ChannelLink from "@app/components/ChannelLink.svelte" import RoomLink from "@app/components/RoomLink.svelte"
import {makeCalendarPath} from "@app/util/routes" import {makeCalendarPath} from "@app/util/routes"
type Props = { type Props = {
@@ -24,7 +24,7 @@
<span class="whitespace-nowrap py-1 text-sm opacity-75"> <span class="whitespace-nowrap py-1 text-sm opacity-75">
Posted by <ProfileLink pubkey={event.pubkey} {url} /> Posted by <ProfileLink pubkey={event.pubkey} {url} />
{#if h} {#if h}
in <ChannelLink {url} {h} /> in <RoomLink {url} {h} />
{/if} {/if}
</span> </span>
<CalendarEventActions showActivity {url} {event} /> <CalendarEventActions showActivity {url} {event} />
-7
View File
@@ -1,7 +0,0 @@
<script lang="ts">
import {channelsById, makeChannelId} from "@app/core/state"
const {url, h} = $props()
</script>
{$channelsById.get(makeChannelId(url, h))?.name || h}
+2 -2
View File
@@ -8,7 +8,7 @@
import ProfileCircle from "@app/components/ProfileCircle.svelte" import ProfileCircle from "@app/components/ProfileCircle.svelte"
import ProfileCircles from "@app/components/ProfileCircles.svelte" import ProfileCircles from "@app/components/ProfileCircles.svelte"
import {goToEvent} from "@app/util/routes" import {goToEvent} from "@app/util/routes"
import {displayChannel} from "@app/core/state" import {displayRoom} from "@app/core/state"
type Props = { type Props = {
url: string url: string
@@ -30,7 +30,7 @@
<div class="flex items-center gap-2 text-sm opacity-70"> <div class="flex items-center gap-2 text-sm opacity-70">
{#if h} {#if h}
<span class="truncate font-medium text-blue-400"> <span class="truncate font-medium text-blue-400">
#{displayChannel(url, h)} #{displayRoom(url, h)}
</span> </span>
<span class="opacity-50"></span> <span class="opacity-50"></span>
{/if} {/if}
+7 -7
View File
@@ -9,8 +9,8 @@
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte" import ModalFooter from "@lib/components/ModalFooter.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import {channelsByUrl} from "@app/core/state" import {roomsByUrl} from "@app/core/state"
import {makeRoomPath} from "@app/util/routes" import {makeRoomPath} from "@app/util/routes"
const {url, noun, event}: {url: string; noun: string; event: TrustedEvent} = $props() const {url, noun, event}: {url: string; noun: string; event: TrustedEvent} = $props()
@@ -39,14 +39,14 @@
{/snippet} {/snippet}
</ModalHeader> </ModalHeader>
<div class="grid grid-cols-3 gap-2"> <div class="grid grid-cols-3 gap-2">
{#each $channelsByUrl.get(url) || [] as channel (channel.h)} {#each $roomsByUrl.get(url) || [] as room (room.h)}
<button <button
type="button" type="button"
class="btn" class="btn"
class:btn-neutral={selection !== channel.h} class:btn-neutral={selection !== room.h}
class:btn-primary={selection === channel.h} class:btn-primary={selection === room.h}
onclick={() => toggleRoom(channel.h)}> onclick={() => toggleRoom(room.h)}>
#<ChannelName {...channel} /> #<RoomName {...room} />
</button> </button>
{/each} {/each}
</div> </div>
+2 -2
View File
@@ -6,7 +6,7 @@
import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte" import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte"
import EventActivity from "@app/components/EventActivity.svelte" import EventActivity from "@app/components/EventActivity.svelte"
import EventActions from "@app/components/EventActions.svelte" import EventActions from "@app/components/EventActions.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import {publishDelete, publishReaction, canEnforceNip70} from "@app/core/commands" import {publishDelete, publishReaction, canEnforceNip70} from "@app/core/commands"
import {makeGoalPath, makeSpacePath} from "@app/util/routes" import {makeGoalPath, makeSpacePath} from "@app/util/routes"
@@ -33,7 +33,7 @@
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
+2 -2
View File
@@ -6,7 +6,7 @@
import ProfileLink from "@app/components/ProfileLink.svelte" import ProfileLink from "@app/components/ProfileLink.svelte"
import GoalActions from "@app/components/GoalActions.svelte" import GoalActions from "@app/components/GoalActions.svelte"
import GoalSummary from "@app/components/GoalSummary.svelte" import GoalSummary from "@app/components/GoalSummary.svelte"
import ChannelLink from "@app/components/ChannelLink.svelte" import RoomLink from "@app/components/RoomLink.svelte"
import {makeGoalPath} from "@app/util/routes" import {makeGoalPath} from "@app/util/routes"
type Props = { type Props = {
@@ -33,7 +33,7 @@
<span class="whitespace-nowrap py-1 text-sm opacity-75"> <span class="whitespace-nowrap py-1 text-sm opacity-75">
Posted by <ProfileLink pubkey={event.pubkey} {url} /> Posted by <ProfileLink pubkey={event.pubkey} {url} />
{#if h} {#if h}
in <ChannelLink {url} {h} /> in <RoomLink {url} {h} />
{/if} {/if}
</span> </span>
<GoalActions showActivity {url} {event} /> <GoalActions showActivity {url} {event} />
+1 -1
View File
@@ -98,7 +98,7 @@
const manageAlerts = () => { const manageAlerts = () => {
const component = hasAlerts ? Alerts : AlertAdd const component = hasAlerts ? Alerts : AlertAdd
const params = {url, channel: "push", hideSpaceField: true} const params = {url, room: "push", hideSpaceField: true}
pushModal(component, params, {replaceState}) pushModal(component, params, {replaceState})
} }
+2 -2
View File
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte" import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
import ChannelNameWithImage from "@app/components/ChannelNameWithImage.svelte" import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
import {makeRoomPath} from "@app/util/routes" import {makeRoomPath} from "@app/util/routes"
import {notifications} from "@app/util/notifications" import {notifications} from "@app/util/notifications"
@@ -20,5 +20,5 @@
href={path} href={path}
{replaceState} {replaceState}
notification={notify ? $notifications.has(path) : false}> notification={notify ? $notifications.has(path) : false}>
<ChannelNameWithImage {url} {h} /> <RoomNameWithImage {url} {h} />
</SecondaryNavItem> </SecondaryNavItem>
+3 -3
View File
@@ -12,7 +12,7 @@
import ModalHeader from "@lib/components/ModalHeader.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte" import ModalFooter from "@lib/components/ModalFooter.svelte"
import RoomForm from "@app/components/RoomForm.svelte" import RoomForm from "@app/components/RoomForm.svelte"
import {deriveChannel} from "@app/core/state" import {deriveRoom} from "@app/core/state"
import {makeSpacePath} from "@app/util/routes" import {makeSpacePath} from "@app/util/routes"
import {pushModal} from "@app/util/modal" import {pushModal} from "@app/util/modal"
import {pushToast} from "@app/util/toast" import {pushToast} from "@app/util/toast"
@@ -24,8 +24,8 @@
const {url, h}: Props = $props() const {url, h}: Props = $props()
const channel = deriveChannel(url, h) const room = deriveRoom(url, h)
const initialValues = $channel ? readRoomMeta($channel.event) : makeRoomMeta({h}) const initialValues = $room ? readRoomMeta($room.event) : makeRoomMeta({h})
const back = () => history.back() const back = () => history.back()
@@ -23,14 +23,14 @@
import ThunkFailure from "@app/components/ThunkFailure.svelte" import ThunkFailure from "@app/components/ThunkFailure.svelte"
import ProfileDetail from "@app/components/ProfileDetail.svelte" import ProfileDetail from "@app/components/ProfileDetail.svelte"
import ReactionSummary from "@app/components/ReactionSummary.svelte" import ReactionSummary from "@app/components/ReactionSummary.svelte"
import ChannelItemZapButton from "@app/components/ChannelItemZapButton.svelte" import RoomItemZapButton from "@app/components/RoomItemZapButton.svelte"
import ChannelItemEmojiButton from "@app/components/ChannelItemEmojiButton.svelte" import RoomItemEmojiButton from "@app/components/RoomItemEmojiButton.svelte"
import ChannelItemMenuButton from "@app/components/ChannelItemMenuButton.svelte" import RoomItemMenuButton from "@app/components/RoomItemMenuButton.svelte"
import ChannelItemMenuMobile from "@app/components/ChannelItemMenuMobile.svelte" import RoomItemMenuMobile from "@app/components/RoomItemMenuMobile.svelte"
import ChannelItemContent from "@app/components/ChannelItemContent.svelte" import RoomItemContent from "@app/components/RoomItemContent.svelte"
import {colors, ENABLE_ZAPS, deriveEventsForUrl} from "@app/core/state" import {colors, ENABLE_ZAPS, deriveEventsForUrl} from "@app/core/state"
import {publishDelete, publishReaction, canEnforceNip70} from "@app/core/commands" import {publishDelete, publishReaction, canEnforceNip70} from "@app/core/commands"
import {getChannelItemPath} from "@app/util/routes" import {getRoomItemPath} from "@app/util/routes"
import {pushModal} from "@app/util/modal" import {pushModal} from "@app/util/modal"
interface Props { interface Props {
@@ -53,7 +53,7 @@
onEdit, onEdit,
}: Props = $props() }: Props = $props()
const path = getChannelItemPath(url, event) const path = getRoomItemPath(url, event)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
const today = formatTimestampAsDate(now()) const today = formatTimestampAsDate(now())
const profile = deriveProfile(event.pubkey, [url]) const profile = deriveProfile(event.pubkey, [url])
@@ -65,7 +65,7 @@
const reply = () => replyTo!(event) const reply = () => replyTo!(event)
const edit = canEdit(event) ? () => onEdit(event) : undefined const edit = canEdit(event) ? () => onEdit(event) : undefined
const onTap = () => pushModal(ChannelItemMenuMobile, {url, event, reply, edit}) const onTap = () => pushModal(RoomItemMenuMobile, {url, event, reply, edit})
const openProfile = () => pushModal(ProfileDetail, {pubkey: event.pubkey, url}) const openProfile = () => pushModal(ProfileDetail, {pubkey: event.pubkey, url})
@@ -105,7 +105,7 @@
</div> </div>
{/if} {/if}
<div class:mt-2={showPubkey && event.kind !== MESSAGE}> <div class:mt-2={showPubkey && event.kind !== MESSAGE}>
<ChannelItemContent {url} {event} /> <RoomItemContent {url} {event} />
{#if thunk} {#if thunk}
<ThunkFailure showToastOnRetry {thunk} class="mt-2 text-sm" /> <ThunkFailure showToastOnRetry {thunk} class="mt-2 text-sm" />
{/if} {/if}
@@ -142,9 +142,9 @@
class="join absolute right-1 top-1 border border-solid border-neutral text-xs opacity-0 transition-all" class="join absolute right-1 top-1 border border-solid border-neutral text-xs opacity-0 transition-all"
class:group-hover:opacity-100={!isMobile}> class:group-hover:opacity-100={!isMobile}>
{#if ENABLE_ZAPS} {#if ENABLE_ZAPS}
<ChannelItemZapButton {url} {event} /> <RoomItemZapButton {url} {event} />
{/if} {/if}
<ChannelItemEmojiButton {url} {event} /> <RoomItemEmojiButton {url} {event} />
{#if replyTo} {#if replyTo}
<Button class="btn join-item btn-xs" onclick={reply}> <Button class="btn join-item btn-xs" onclick={reply}>
<Icon icon={Reply} size={4} /> <Icon icon={Reply} size={4} />
@@ -155,7 +155,7 @@
<Icon icon={Pen} size={4} /> <Icon icon={Pen} size={4} />
</Button> </Button>
{/if} {/if}
<ChannelItemMenuButton {url} {event} /> <RoomItemMenuButton {url} {event} />
</button> </button>
{/if} {/if}
</TapTarget> </TapTarget>
@@ -5,11 +5,11 @@
import {isMobile} from "@lib/html" import {isMobile} from "@lib/html"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import NoteContent from "@app/components/NoteContent.svelte" import NoteContent from "@app/components/NoteContent.svelte"
import {getChannelItemPath} from "@app/util/routes" import {getRoomItemPath} from "@app/util/routes"
const props: ComponentProps<typeof NoteContent> = $props() const props: ComponentProps<typeof NoteContent> = $props()
const path = getChannelItemPath(props.url!, props.event) const path = getRoomItemPath(props.url!, props.event)
</script> </script>
<div class={cx("text-sm", {"card2 card2-sm bg-alt": props.event.kind !== MESSAGE})}> <div class={cx("text-sm", {"card2 card2-sm bg-alt": props.event.kind !== MESSAGE})}>
@@ -5,7 +5,7 @@
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 Tippy from "@lib/components/Tippy.svelte" import Tippy from "@lib/components/Tippy.svelte"
import ChannelItemMenu from "@app/components/ChannelItemMenu.svelte" import RoomItemMenu from "@app/components/RoomItemMenu.svelte"
const {url, event} = $props() const {url, event} = $props()
@@ -34,7 +34,7 @@
</Button> </Button>
<Tippy <Tippy
bind:popover bind:popover
component={ChannelItemMenu} component={RoomItemMenu}
props={{url, event, onClick}} props={{url, event, onClick}}
params={{trigger: "manual", interactive: true}} /> params={{trigger: "manual", interactive: true}} />
</div> </div>
@@ -17,7 +17,7 @@
import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte" import EventDeleteConfirm from "@app/components/EventDeleteConfirm.svelte"
import {ENABLE_ZAPS} from "@app/core/state" import {ENABLE_ZAPS} from "@app/core/state"
import {publishReaction, canEnforceNip70} from "@app/core/commands" import {publishReaction, canEnforceNip70} from "@app/core/commands"
import {getChannelItemPath} from "@app/util/routes" import {getRoomItemPath} from "@app/util/routes"
import {pushModal} from "@app/util/modal" import {pushModal} from "@app/util/modal"
type Props = { type Props = {
@@ -28,7 +28,7 @@
const {url, event, reply}: Props = $props() const {url, event, reply}: Props = $props()
const path = getChannelItemPath(url, event) const path = getRoomItemPath(url, event)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames" import cx from "classnames"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import {makeSpacePath} from "@app/util/routes" import {makeSpacePath} from "@app/util/routes"
type Props = { type Props = {
@@ -17,5 +17,5 @@
</script> </script>
<Link href={path} class={cx(props.class, {"link-content bg-alt": !unstyled})}> <Link href={path} class={cx(props.class, {"link-content bg-alt": !unstyled})}>
#<ChannelName {h} {url} /> #<RoomName {h} {url} />
</Link> </Link>
+7
View File
@@ -0,0 +1,7 @@
<script lang="ts">
import {roomsById, makeRoomId} from "@app/core/state"
const {url, h} = $props()
</script>
{$roomsById.get(makeRoomId(url, h))?.name || h}
@@ -2,8 +2,8 @@
import Lock from "@assets/icons/lock-keyhole.svg?dataurl" import Lock from "@assets/icons/lock-keyhole.svg?dataurl"
import Hashtag from "@assets/icons/hashtag.svg?dataurl" import Hashtag from "@assets/icons/hashtag.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import {deriveChannel} from "@app/core/state" import {deriveRoom} from "@app/core/state"
interface Props { interface Props {
url: any url: any
@@ -12,21 +12,21 @@
const {url, h}: Props = $props() const {url, h}: Props = $props()
const channel = deriveChannel(url, h) const room = deriveRoom(url, h)
</script> </script>
{#if $channel?.picture} {#if $room?.picture}
{@const src = $channel.picture} {@const src = $room.picture}
{#if src.match("\.(png|svg)$") || src.match("image/(png|svg)")} {#if src.match("\.(png|svg)$") || src.match("image/(png|svg)")}
<Icon icon={src} /> <Icon icon={src} />
{:else} {:else}
<img alt="Room icon" {src} class="h-6 w-6 rounded-lg" /> <img alt="Room icon" {src} class="h-6 w-6 rounded-lg" />
{/if} {/if}
{:else if $channel?.closed || $channel?.private} {:else if $room?.closed || $room?.private}
<Icon icon={Lock} /> <Icon icon={Lock} />
{:else} {:else}
<Icon icon={Hashtag} /> <Icon icon={Hashtag} />
{/if} {/if}
<div class="min-w-0 overflow-hidden text-ellipsis"> <div class="min-w-0 overflow-hidden text-ellipsis">
<ChannelName {url} {h} /> <RoomName {url} {h} />
</div> </div>
+2 -2
View File
@@ -2,7 +2,7 @@
import type {TrustedEvent, EventContent} from "@welshman/util" import type {TrustedEvent, EventContent} from "@welshman/util"
import {getTagValue} from "@welshman/util" import {getTagValue} from "@welshman/util"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import ReactionSummary from "@app/components/ReactionSummary.svelte" import ReactionSummary from "@app/components/ReactionSummary.svelte"
import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte" import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte"
import EventActivity from "@app/components/EventActivity.svelte" import EventActivity from "@app/components/EventActivity.svelte"
@@ -33,7 +33,7 @@
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
+2 -2
View File
@@ -6,7 +6,7 @@
import Content from "@app/components/Content.svelte" import Content from "@app/components/Content.svelte"
import ProfileLink from "@app/components/ProfileLink.svelte" import ProfileLink from "@app/components/ProfileLink.svelte"
import ThreadActions from "@app/components/ThreadActions.svelte" import ThreadActions from "@app/components/ThreadActions.svelte"
import ChannelLink from "@app/components/ChannelLink.svelte" import RoomLink from "@app/components/RoomLink.svelte"
import {makeThreadPath} from "@app/util/routes" import {makeThreadPath} from "@app/util/routes"
type Props = { type Props = {
@@ -39,7 +39,7 @@
Posted by Posted by
<ProfileLink pubkey={event.pubkey} {url} /> <ProfileLink pubkey={event.pubkey} {url} />
{#if h} {#if h}
in <ChannelLink {url} {h} /> in <RoomLink {url} {h} />
{/if} {/if}
</span> </span>
<ThreadActions showActivity {url} {event} /> <ThreadActions showActivity {url} {event} />
+24 -24
View File
@@ -530,11 +530,11 @@ export const chatSearch = derived(chats, $chats =>
}), }),
) )
// Channels // Rooms
export const messages = deriveEvents(repository, {filters: [{kinds: [MESSAGE]}]}) export const messages = deriveEvents(repository, {filters: [{kinds: [MESSAGE]}]})
export type Channel = { export type Room = {
id: string id: string
url: string url: string
h: string h: string
@@ -546,17 +546,17 @@ export type Channel = {
about?: string about?: string
} }
export const makeChannelId = (url: string, h: string) => `${url}'${h}` export const makeRoomId = (url: string, h: string) => `${url}'${h}`
export const splitChannelId = (id: string) => id.split("'") export const splitRoomId = (id: string) => id.split("'")
export const hasNip29 = (relay?: RelayProfile) => export const hasNip29 = (relay?: RelayProfile) =>
relay?.supported_nips?.map?.(String)?.includes?.("29") relay?.supported_nips?.map?.(String)?.includes?.("29")
export const channels = derived( export const rooms = derived(
[deriveEvents(repository, {filters: [{kinds: [ROOM_META, ROOM_DELETE]}]}), getUrlsForEvent], [deriveEvents(repository, {filters: [{kinds: [ROOM_META, ROOM_DELETE]}]}), getUrlsForEvent],
([$events, $getUrlsForEvent]) => { ([$events, $getUrlsForEvent]) => {
const result = new Map<string, Channel>() const result = new Map<string, Room>()
for (const event of sortBy(e => e.created_at, $events)) { for (const event of sortBy(e => e.created_at, $events)) {
for (const url of $getUrlsForEvent(event.id)) { for (const url of $getUrlsForEvent(event.id)) {
@@ -565,7 +565,7 @@ export const channels = derived(
const h = meta.d const h = meta.d
if (h) { if (h) {
const id = makeChannelId(url, h) const id = makeRoomId(url, h)
result.set(id, { result.set(id, {
id, id,
@@ -583,7 +583,7 @@ export const channels = derived(
if (event.kind === ROOM_DELETE) { if (event.kind === ROOM_DELETE) {
for (const h of getTagValues("h", event.tags)) { for (const h of getTagValues("h", event.tags)) {
result.delete(makeChannelId(url, h)) result.delete(makeRoomId(url, h))
} }
} }
} }
@@ -593,18 +593,18 @@ export const channels = derived(
}, },
) )
export const channelsByUrl = derived(channels, $channels => groupBy(c => c.url, $channels)) export const roomsByUrl = derived(rooms, $rooms => groupBy(c => c.url, $rooms))
export const { export const {
indexStore: channelsById, indexStore: roomsById,
deriveItem: _deriveChannel, deriveItem: _deriveRoom,
loadItem: _loadChannel, loadItem: _loadRoom,
} = collection({ } = collection({
name: "channels", name: "rooms",
store: channels, store: rooms,
getKey: channel => channel.id, getKey: room => room.id,
load: async (id: string) => { load: async (id: string) => {
const [url, h] = splitChannelId(id) const [url, h] = splitRoomId(id)
await load({ await load({
relays: [url], relays: [url],
@@ -613,12 +613,12 @@ export const {
}, },
}) })
export const deriveChannel = (url: string, h: string) => _deriveChannel(makeChannelId(url, h)) export const deriveRoom = (url: string, h: string) => _deriveRoom(makeRoomId(url, h))
export const displayChannel = (url: string, h: string) => export const displayRoom = (url: string, h: string) =>
channelsById.get().get(makeChannelId(url, h))?.name || h roomsById.get().get(makeRoomId(url, h))?.name || h
export const roomComparator = (url: string) => (h: string) => displayChannel(url, h).toLowerCase() export const roomComparator = (url: string) => (h: string) => displayRoom(url, h).toLowerCase()
// User space/room selections // User space/room selections
@@ -701,11 +701,11 @@ export const loadUserGroupSelections = makeUserLoader(loadGroupSelections)
export const userSpaceUrls = derived(userGroupSelections, getSpaceUrlsFromGroupSelections) export const userSpaceUrls = derived(userGroupSelections, getSpaceUrlsFromGroupSelections)
export const deriveUserRooms = (url: string) => export const deriveUserRooms = (url: string) =>
derived([userGroupSelections, channelsById], ([$userGroupSelections, $channelsById]) => { derived([userGroupSelections, roomsById], ([$userGroupSelections, $roomsById]) => {
const rooms: string[] = [] const rooms: string[] = []
for (const h of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) { for (const h of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) {
if ($channelsById.has(makeChannelId(url, h))) { if ($roomsById.has(makeRoomId(url, h))) {
rooms.push(h) rooms.push(h)
} }
} }
@@ -714,10 +714,10 @@ export const deriveUserRooms = (url: string) =>
}) })
export const deriveOtherRooms = (url: string) => export const deriveOtherRooms = (url: string) =>
derived([deriveUserRooms(url), channelsByUrl], ([$userRooms, $channelsByUrl]) => { derived([deriveUserRooms(url), roomsByUrl], ([$userRooms, $roomsByUrl]) => {
const rooms: string[] = [] const rooms: string[] = []
for (const {h} of $channelsByUrl.get(url) || []) { for (const {h} of $roomsByUrl.get(url) || []) {
if (!$userRooms.includes(h)) { if (!$userRooms.includes(h)) {
rooms.push(h) rooms.push(h)
} }
+1 -1
View File
@@ -149,7 +149,7 @@ export const getEventPath = async (event: TrustedEvent, urls: string[]) => {
return entityLink(nip19.neventEncode({id: event.id, relays: urls})) return entityLink(nip19.neventEncode({id: event.id, relays: urls}))
} }
export const getChannelItemPath = (url: string, event: TrustedEvent) => { export const getRoomItemPath = (url: string, event: TrustedEvent) => {
switch (event.kind) { switch (event.kind) {
case THREAD: case THREAD:
return makeThreadPath(url, event.id) return makeThreadPath(url, event.id)
+21 -21
View File
@@ -32,19 +32,19 @@
import ThunkToast from "@app/components/ThunkToast.svelte" import ThunkToast from "@app/components/ThunkToast.svelte"
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte" import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
import RoomEdit from "@app/components/RoomEdit.svelte" import RoomEdit from "@app/components/RoomEdit.svelte"
import ChannelName from "@app/components/ChannelName.svelte" import RoomName from "@app/components/RoomName.svelte"
import ChannelItem from "@app/components/ChannelItem.svelte" import RoomItem from "@app/components/RoomItem.svelte"
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte" import RoomItemAddMember from "@src/app/components/RoomItemAddMember.svelte"
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte" import RoomItemRemoveMember from "@src/app/components/RoomItemRemoveMember.svelte"
import ChannelCompose from "@app/components/ChannelCompose.svelte" import RoomCompose from "@app/components/RoomCompose.svelte"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte" import RoomComposeEdit from "@src/app/components/RoomComposeEdit.svelte"
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte" import RoomComposeParent from "@app/components/RoomComposeParent.svelte"
import { import {
deriveUserRooms, deriveUserRooms,
userSettingsValues, userSettingsValues,
decodeRelay, decodeRelay,
deriveUserRoomMembershipStatus, deriveUserRoomMembershipStatus,
deriveChannel, deriveRoom,
MembershipStatus, MembershipStatus,
PROTECTED, PROTECTED,
MESSAGE_KINDS, MESSAGE_KINDS,
@@ -67,7 +67,7 @@
const mounted = now() const mounted = now()
const lastChecked = $checked[$page.url.pathname] const lastChecked = $checked[$page.url.pathname]
const url = decodeRelay(relay) const url = decodeRelay(relay)
const channel = deriveChannel(url, h) const room = deriveRoom(url, h)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
const userRooms = deriveUserRooms(url) const userRooms = deriveUserRooms(url)
const userIsAdmin = deriveUserIsRoomAdmin(url, h) const userIsAdmin = deriveUserIsRoomAdmin(url, h)
@@ -204,7 +204,7 @@
let showScrollButton = $state(false) let showScrollButton = $state(false)
let cleanup: () => void let cleanup: () => void
let events: Readable<TrustedEvent[]> = $state(readable([])) let events: Readable<TrustedEvent[]> = $state(readable([]))
let compose: ChannelCompose | undefined = $state() let compose: RoomCompose | undefined = $state()
let eventToEdit: TrustedEvent | undefined = $state() let eventToEdit: TrustedEvent | undefined = $state()
const elements = $derived.by(() => { const elements = $derived.by(() => {
@@ -334,7 +334,7 @@
{/snippet} {/snippet}
{#snippet title()} {#snippet title()}
<strong class="ellipsize"> <strong class="ellipsize">
<ChannelName {url} {h} /> <RoomName {url} {h} />
</strong> </strong>
{/snippet} {/snippet}
{#snippet action()} {#snippet action()}
@@ -386,7 +386,7 @@
<PageContent bind:element onscroll={onScroll} class="flex flex-col-reverse pt-4"> <PageContent bind:element onscroll={onScroll} class="flex flex-col-reverse pt-4">
<div bind:this={dynamicPadding}></div> <div bind:this={dynamicPadding}></div>
{#if $channel?.private && $membershipStatus !== MembershipStatus.Granted} {#if $room?.private && $membershipStatus !== MembershipStatus.Granted}
<div class="py-20"> <div class="py-20">
<div class="card2 col-8 m-auto max-w-md items-center text-center"> <div class="card2 col-8 m-auto max-w-md items-center text-center">
<p class="row-2">You aren't currently a member of this room.</p> <p class="row-2">You aren't currently a member of this room.</p>
@@ -423,12 +423,12 @@
{:else} {:else}
{@const event = $state.snapshot(value as TrustedEvent)} {@const event = $state.snapshot(value as TrustedEvent)}
{#if event.kind === ROOM_ADD_MEMBER} {#if event.kind === ROOM_ADD_MEMBER}
<ChannelItemAddMember {url} {event} /> <RoomItemAddMember {url} {event} />
{:else if event.kind === ROOM_REMOVE_MEMBER} {:else if event.kind === ROOM_REMOVE_MEMBER}
<ChannelItemRemoveMember {url} {event} /> <RoomItemRemoveMember {url} {event} />
{:else} {:else}
<div in:slide class:-mt-1={!showPubkey}> <div in:slide class:-mt-1={!showPubkey}>
<ChannelItem <RoomItem
{url} {url}
{event} {event}
{replyTo} {replyTo}
@@ -450,9 +450,9 @@
</PageContent> </PageContent>
<div class="chat__compose bg-base-200" bind:this={chatCompose}> <div class="chat__compose bg-base-200" bind:this={chatCompose}>
{#if $channel?.private && $membershipStatus !== MembershipStatus.Granted} {#if $room?.private && $membershipStatus !== MembershipStatus.Granted}
<!-- pass --> <!-- pass -->
{:else if $channel?.closed && $membershipStatus !== MembershipStatus.Granted} {:else if $room?.closed && $membershipStatus !== MembershipStatus.Granted}
<div class="bg-alt card m-4 flex flex-row items-center justify-between px-4 py-3"> <div class="bg-alt card m-4 flex flex-row items-center justify-between px-4 py-3">
<p>Only members are allowed to post to this room.</p> <p>Only members are allowed to post to this room.</p>
{#if $membershipStatus === MembershipStatus.Pending} {#if $membershipStatus === MembershipStatus.Pending}
@@ -474,17 +474,17 @@
{:else} {:else}
<div> <div>
{#if parent} {#if parent}
<ChannelComposeParent event={parent} clear={clearParent} verb="Replying to" /> <RoomComposeParent event={parent} clear={clearParent} verb="Replying to" />
{/if} {/if}
{#if share} {#if share}
<ChannelComposeParent event={share} clear={clearShare} verb="Sharing" /> <RoomComposeParent event={share} clear={clearShare} verb="Sharing" />
{/if} {/if}
{#if eventToEdit} {#if eventToEdit}
<ChannelComposeEdit clear={clearEventToEdit} /> <RoomComposeEdit clear={clearEventToEdit} />
{/if} {/if}
</div> </div>
{#key eventToEdit} {#key eventToEdit}
<ChannelCompose <RoomCompose
{url} {url}
{h} {h}
{onSubmit} {onSubmit}
+14 -14
View File
@@ -18,12 +18,12 @@
import Divider from "@lib/components/Divider.svelte" import Divider from "@lib/components/Divider.svelte"
import ThunkToast from "@app/components/ThunkToast.svelte" import ThunkToast from "@app/components/ThunkToast.svelte"
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte" import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
import ChannelItem from "@app/components/ChannelItem.svelte" import RoomItem from "@app/components/RoomItem.svelte"
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte" import RoomItemAddMember from "@src/app/components/RoomItemAddMember.svelte"
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte" import RoomItemRemoveMember from "@src/app/components/RoomItemRemoveMember.svelte"
import ChannelCompose from "@app/components/ChannelCompose.svelte" import RoomCompose from "@app/components/RoomCompose.svelte"
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte" import RoomComposeEdit from "@src/app/components/RoomComposeEdit.svelte"
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte" import RoomComposeParent from "@app/components/RoomComposeParent.svelte"
import {userSettingsValues, decodeRelay, PROTECTED, MESSAGE_KINDS} from "@app/core/state" import {userSettingsValues, decodeRelay, PROTECTED, MESSAGE_KINDS} from "@app/core/state"
import {prependParent, canEnforceNip70, publishDelete} from "@app/core/commands" import {prependParent, canEnforceNip70, publishDelete} from "@app/core/commands"
import {setChecked, checked} from "@app/util/notifications" import {setChecked, checked} from "@app/util/notifications"
@@ -128,7 +128,7 @@
let showScrollButton = $state(false) let showScrollButton = $state(false)
let cleanup: () => void let cleanup: () => void
let events: Readable<TrustedEvent[]> = $state(readable([])) let events: Readable<TrustedEvent[]> = $state(readable([]))
let compose: ChannelCompose | undefined = $state() let compose: RoomCompose | undefined = $state()
let eventToEdit: TrustedEvent | undefined = $state() let eventToEdit: TrustedEvent | undefined = $state()
const elements = $derived.by(() => { const elements = $derived.by(() => {
@@ -274,12 +274,12 @@
{:else} {:else}
{@const event = $state.snapshot(value as TrustedEvent)} {@const event = $state.snapshot(value as TrustedEvent)}
{#if event.kind === RELAY_ADD_MEMBER} {#if event.kind === RELAY_ADD_MEMBER}
<ChannelItemAddMember {url} {event} /> <RoomItemAddMember {url} {event} />
{:else if event.kind === RELAY_REMOVE_MEMBER} {:else if event.kind === RELAY_REMOVE_MEMBER}
<ChannelItemRemoveMember {url} {event} /> <RoomItemRemoveMember {url} {event} />
{:else} {:else}
<div class:-mt-1={!showPubkey}> <div class:-mt-1={!showPubkey}>
<ChannelItem <RoomItem
{url} {url}
{event} {event}
{replyTo} {replyTo}
@@ -302,17 +302,17 @@
<div class="chat__compose bg-base-200" bind:this={chatCompose}> <div class="chat__compose bg-base-200" bind:this={chatCompose}>
<div> <div>
{#if parent} {#if parent}
<ChannelComposeParent event={parent} clear={clearParent} verb="Replying to" /> <RoomComposeParent event={parent} clear={clearParent} verb="Replying to" />
{/if} {/if}
{#if share} {#if share}
<ChannelComposeParent event={share} clear={clearShare} verb="Sharing" /> <RoomComposeParent event={share} clear={clearShare} verb="Sharing" />
{/if} {/if}
{#if eventToEdit} {#if eventToEdit}
<ChannelComposeEdit clear={clearEventToEdit} /> <RoomComposeEdit clear={clearEventToEdit} />
{/if} {/if}
</div> </div>
{#key eventToEdit} {#key eventToEdit}
<ChannelCompose <RoomCompose
{url} {url}
{onSubmit} {onSubmit}
{onEditPrevious} {onEditPrevious}