Rename room variables to h

This commit is contained in:
Jon Staab
2025-10-30 15:33:34 -07:00
parent 478721d349
commit dbaa0f5d49
28 changed files with 158 additions and 158 deletions
@@ -25,7 +25,7 @@
const {url, event, showRoom, showActivity}: Props = $props() const {url, event, showRoom, showActivity}: Props = $props()
const room = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
const path = makeCalendarPath(url, event.id) const path = makeCalendarPath(url, event.id)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
@@ -39,9 +39,9 @@
</script> </script>
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if room && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, room)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {room} {url} /> Posted in #<ChannelName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
@@ -4,13 +4,13 @@
type Props = { type Props = {
url: string url: string
room?: string h?: string
} }
const {url, room}: Props = $props() const {url, h}: Props = $props()
</script> </script>
<CalendarEventForm {url} {room}> <CalendarEventForm {url} {h}>
{#snippet header()} {#snippet header()}
<ModalHeader> <ModalHeader>
{#snippet title()} {#snippet title()}
+4 -4
View File
@@ -23,7 +23,7 @@
type Props = { type Props = {
url: string url: string
room?: string h?: string
header: Snippet header: Snippet
initialValues?: { initialValues?: {
d: string d: string
@@ -35,7 +35,7 @@
} }
} }
const {url, room, header, initialValues}: Props = $props() const {url, h, header, initialValues}: Props = $props()
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
@@ -85,8 +85,8 @@
tags.push(PROTECTED) tags.push(PROTECTED)
} }
if (room) { if (h) {
tags.push(["h", room]) tags.push(["h", h])
} }
const event = makeEvent(EVENT_TIME, {content, tags}) const event = makeEvent(EVENT_TIME, {content, tags})
+3 -3
View File
@@ -15,7 +15,7 @@
const {url, event}: Props = $props() const {url, event}: Props = $props()
const room = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
</script> </script>
<Link class="col-3 card2 bg-alt w-full cursor-pointer" href={makeCalendarPath(url, event.id)}> <Link class="col-3 card2 bg-alt w-full cursor-pointer" href={makeCalendarPath(url, event.id)}>
@@ -23,8 +23,8 @@
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row"> <div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
<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 room} {#if h}
in <ChannelLink {url} {room} /> in <ChannelLink {url} {h} />
{/if} {/if}
</span> </span>
<CalendarEventActions showActivity {url} {event} /> <CalendarEventActions showActivity {url} {event} />
+3 -3
View File
@@ -16,13 +16,13 @@
type Props = { type Props = {
url?: string url?: string
room?: string h?: string
content?: string content?: string
onEditPrevious?: () => void onEditPrevious?: () => void
onSubmit: (event: EventContent) => void onSubmit: (event: EventContent) => void
} }
const {url, room, content, onEditPrevious, onSubmit}: Props = $props() const {url, h, content, onEditPrevious, onSubmit}: Props = $props()
const autofocus = !isMobile const autofocus = !isMobile
@@ -90,7 +90,7 @@
<Tippy <Tippy
bind:popover bind:popover
component={ComposeMenu} component={ComposeMenu}
props={{url, room, onClick: hidePopover}} props={{url, h, onClick: hidePopover}}
params={{trigger: "manual", interactive: true}}> params={{trigger: "manual", interactive: true}}>
<Button <Button
data-tip="More options" data-tip="More options"
+4 -4
View File
@@ -5,17 +5,17 @@
import {makeSpacePath} from "@app/util/routes" import {makeSpacePath} from "@app/util/routes"
type Props = { type Props = {
room: string h: string
url: string url: string
class?: string class?: string
unstyled?: boolean unstyled?: boolean
} }
const {room, url, unstyled, ...props}: Props = $props() const {h, url, unstyled, ...props}: Props = $props()
const path = makeSpacePath(url, room) const path = makeSpacePath(url, h)
</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 {room} {url} /> #<ChannelName {h} {url} />
</Link> </Link>
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import {channelsById, makeChannelId} from "@app/core/state" import {channelsById, makeChannelId} from "@app/core/state"
const {url, room} = $props() const {url, h} = $props()
</script> </script>
{$channelsById.get(makeChannelId(url, room))?.name || room} {$channelsById.get(makeChannelId(url, h))?.name || h}
@@ -7,12 +7,12 @@
interface Props { interface Props {
url: any url: any
room: any h: any
} }
const {url, room}: Props = $props() const {url, h}: Props = $props()
const channel = deriveChannel(url, room) const channel = deriveChannel(url, h)
</script> </script>
{#if $channel?.picture} {#if $channel?.picture}
@@ -28,5 +28,5 @@
<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} {room} /> <ChannelName {url} {h} />
</div> </div>
+5 -5
View File
@@ -13,16 +13,16 @@
type Props = { type Props = {
url: string url: string
onClick: () => void onClick: () => void
room?: string h?: string
} }
const {url, room, onClick}: Props = $props() const {url, h, onClick}: Props = $props()
const createGoal = () => pushModal(GoalCreate, {url, room}) const createGoal = () => pushModal(GoalCreate, {url, h})
const createCalendarEvent = () => pushModal(CalendarEventCreate, {url, room}) const createCalendarEvent = () => pushModal(CalendarEventCreate, {url, h})
const createThread = () => pushModal(ThreadCreate, {url, room}) const createThread = () => pushModal(ThreadCreate, {url, h})
let ul: Element let ul: Element
+4 -4
View File
@@ -12,14 +12,14 @@
type Props = { type Props = {
url: string url: string
room?: string h?: string
events: TrustedEvent[] events: TrustedEvent[]
latest: TrustedEvent latest: TrustedEvent
earliest: TrustedEvent earliest: TrustedEvent
participants: string[] participants: string[]
} }
const {url, room, events, latest, earliest, participants}: Props = $props() const {url, h, events, latest, earliest, participants}: Props = $props()
</script> </script>
<Button class="card2 bg-alt" onclick={() => goToEvent(earliest)}> <Button class="card2 bg-alt" onclick={() => goToEvent(earliest)}>
@@ -28,9 +28,9 @@
<ProfileCircle pubkey={earliest.pubkey} size={10} /> <ProfileCircle pubkey={earliest.pubkey} size={10} />
<div class="min-w-0 flex-1"> <div class="min-w-0 flex-1">
<div class="flex items-center gap-2 text-sm opacity-70"> <div class="flex items-center gap-2 text-sm opacity-70">
{#if room} {#if h}
<span class="truncate font-medium text-blue-400"> <span class="truncate font-medium text-blue-400">
#{displayChannel(url, room)} #{displayChannel(url, h)}
</span> </span>
<span class="opacity-50"></span> <span class="opacity-50"></span>
{/if} {/if}
+6 -6
View File
@@ -22,8 +22,8 @@
goto(makeRoomPath(url, selection), {replaceState: true}) goto(makeRoomPath(url, selection), {replaceState: true})
} }
const toggleRoom = (room: string) => { const toggleRoom = (h: string) => {
selection = room === selection ? "" : room selection = h === selection ? "" : h
} }
let selection = $state("") let selection = $state("")
@@ -39,13 +39,13 @@
{/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.room)} {#each $channelsByUrl.get(url) || [] as channel (channel.h)}
<button <button
type="button" type="button"
class="btn" class="btn"
class:btn-neutral={selection !== channel.room} class:btn-neutral={selection !== channel.h}
class:btn-primary={selection === channel.room} class:btn-primary={selection === channel.h}
onclick={() => toggleRoom(channel.room)}> onclick={() => toggleRoom(channel.h)}>
#<ChannelName {...channel} /> #<ChannelName {...channel} />
</button> </button>
{/each} {/each}
+4 -4
View File
@@ -20,7 +20,7 @@
const {url, event, showRoom, showActivity}: Props = $props() const {url, event, showRoom, showActivity}: Props = $props()
const path = makeGoalPath(url, event.id) const path = makeGoalPath(url, event.id)
const room = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
const deleteReaction = async (event: TrustedEvent) => const deleteReaction = async (event: TrustedEvent) =>
@@ -31,9 +31,9 @@
</script> </script>
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if room && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, room)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {room} {url} /> Posted in #<ChannelName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
+4 -4
View File
@@ -20,10 +20,10 @@
type Props = { type Props = {
url: string url: string
room?: string h?: string
} }
const {url, room}: Props = $props() const {url, h}: Props = $props()
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
@@ -64,8 +64,8 @@
tags.push(PROTECTED) tags.push(PROTECTED)
} }
if (room) { if (h) {
tags.push(["h", room]) tags.push(["h", h])
} }
publishThunk({ publishThunk({
+3 -3
View File
@@ -17,7 +17,7 @@
const {url, event}: Props = $props() const {url, event}: Props = $props()
const summary = getTagValue("summary", event.tags) const summary = getTagValue("summary", event.tags)
const room = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
</script> </script>
<Link class="col-2 card2 bg-alt w-full cursor-pointer" href={makeGoalPath(url, event.id)}> <Link class="col-2 card2 bg-alt w-full cursor-pointer" href={makeGoalPath(url, event.id)}>
@@ -32,8 +32,8 @@
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row"> <div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
<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 room} {#if h}
in <ChannelLink {url} {room} /> in <ChannelLink {url} {h} />
{/if} {/if}
</span> </span>
<GoalActions showActivity {url} {event} /> <GoalActions showActivity {url} {event} />
+4 -4
View File
@@ -216,8 +216,8 @@
<div class="h-2"></div> <div class="h-2"></div>
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader> <SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
{/if} {/if}
{#each $userRooms as room, i (room)} {#each $userRooms as h, i (h)}
<MenuSpaceRoomItem {replaceState} notify {url} {room} /> <MenuSpaceRoomItem {replaceState} notify {url} {h} />
{/each} {/each}
{#if $otherRooms.length > 0} {#if $otherRooms.length > 0}
<div class="h-2"></div> <div class="h-2"></div>
@@ -229,8 +229,8 @@
{/if} {/if}
</SecondaryNavHeader> </SecondaryNavHeader>
{/if} {/if}
{#each $otherRooms as room, i (room)} {#each $otherRooms as h, i (h)}
<MenuSpaceRoomItem {replaceState} {url} {room} /> <MenuSpaceRoomItem {replaceState} {url} {h} />
{/each} {/each}
{#if $canCreateRoom} {#if $canCreateRoom}
<SecondaryNavItem {replaceState} onclick={addRoom}> <SecondaryNavItem {replaceState} onclick={addRoom}>
+4 -4
View File
@@ -6,19 +6,19 @@
interface Props { interface Props {
url: any url: any
room: any h: any
notify?: boolean notify?: boolean
replaceState?: boolean replaceState?: boolean
} }
const {url, room, notify = false, replaceState = false}: Props = $props() const {url, h, notify = false, replaceState = false}: Props = $props()
const path = makeRoomPath(url, room) const path = makeRoomPath(url, h)
</script> </script>
<SecondaryNavItem <SecondaryNavItem
href={path} href={path}
{replaceState} {replaceState}
notification={notify ? $notifications.has(path) : false}> notification={notify ? $notifications.has(path) : false}>
<ChannelNameWithImage {url} {room} /> <ChannelNameWithImage {url} {h} />
</SecondaryNavItem> </SecondaryNavItem>
+5 -5
View File
@@ -19,13 +19,13 @@
type Props = { type Props = {
url: string url: string
room: string h: string
} }
const {url, room}: Props = $props() const {url, h}: Props = $props()
const channel = deriveChannel(url, room) const channel = deriveChannel(url, h)
const initialValues = $channel ? readRoomMeta($channel.event) : makeRoomMeta({h: room}) const initialValues = $channel ? readRoomMeta($channel.event) : makeRoomMeta({h})
const back = () => history.back() const back = () => history.back()
@@ -37,7 +37,7 @@
message: message:
"This room will no longer be accessible to space members, and all messages posted to it will be deleted.", "This room will no longer be accessible to space members, and all messages posted to it will be deleted.",
confirm: async () => { confirm: async () => {
const thunk = deleteRoom(url, makeRoomMeta({h: room})) const thunk = deleteRoom(url, makeRoomMeta({h}))
const message = await waitForThunkError(thunk) const message = await waitForThunkError(thunk)
if (message) { if (message) {
+5 -2
View File
@@ -113,7 +113,10 @@
{#if imagePreview} {#if imagePreview}
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class="text-sm opacity-75">Selected:</span> <span class="text-sm opacity-75">Selected:</span>
<img src={imagePreview} alt="Room icon preview" class="h-5 w-5 rounded-lg object-cover" /> <img
src={imagePreview}
alt="Room icon preview"
class="h-5 w-5 rounded-lg object-cover" />
</div> </div>
{:else if selectedIcon} {:else if selectedIcon}
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@@ -161,7 +164,7 @@
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-bordered flex w-full items-center gap-2">
<input bind:value={values.description} class="grow" type="text" /> <input bind:value={values.about} class="grow" type="text" />
</label> </label>
{/snippet} {/snippet}
</FieldInline> </FieldInline>
+4 -4
View File
@@ -19,8 +19,8 @@
const {url, event, showRoom, showActivity}: Props = $props() const {url, event, showRoom, showActivity}: Props = $props()
const h = getTagValue("h", event.tags)
const path = makeThreadPath(url, event.id) const path = makeThreadPath(url, event.id)
const room = getTagValue("h", event.tags)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
const deleteReaction = async (event: TrustedEvent) => const deleteReaction = async (event: TrustedEvent) =>
@@ -31,9 +31,9 @@
</script> </script>
<div class="flex flex-grow flex-wrap justify-end gap-2"> <div class="flex flex-grow flex-wrap justify-end gap-2">
{#if room && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, room)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
Posted in #<ChannelName {room} {url} /> Posted in #<ChannelName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
+4 -4
View File
@@ -18,10 +18,10 @@
type Props = { type Props = {
url: string url: string
room?: string h?: string
} }
const {url, room}: Props = $props() const {url, h}: Props = $props()
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
@@ -57,8 +57,8 @@
tags.push(PROTECTED) tags.push(PROTECTED)
} }
if (room) { if (h) {
tags.push(["h", room]) tags.push(["h", h])
} }
publishThunk({ publishThunk({
+3 -3
View File
@@ -17,7 +17,7 @@
const {url, event}: Props = $props() const {url, event}: Props = $props()
const title = getTagValue("title", event.tags) const title = getTagValue("title", event.tags)
const room = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
</script> </script>
<Link class="col-2 card2 bg-alt w-full cursor-pointer" href={makeThreadPath(url, event.id)}> <Link class="col-2 card2 bg-alt w-full cursor-pointer" href={makeThreadPath(url, event.id)}>
@@ -38,8 +38,8 @@
<span class="whitespace-nowrap py-1 text-sm opacity-75"> <span class="whitespace-nowrap py-1 text-sm opacity-75">
Posted by Posted by
<ProfileLink pubkey={event.pubkey} {url} /> <ProfileLink pubkey={event.pubkey} {url} />
{#if room} {#if h}
in <ChannelLink {url} {room} /> in <ChannelLink {url} {h} />
{/if} {/if}
</span> </span>
<ThreadActions showActivity {url} {event} /> <ThreadActions showActivity {url} {event} />
+4 -4
View File
@@ -191,11 +191,11 @@ export const removeSpaceMembership = async (url: string) => {
return publishThunk({event, relays}) return publishThunk({event, relays})
} }
export const addRoomMembership = async (url: string, room: string) => { export const addRoomMembership = async (url: string, h: string) => {
const list = get(userGroupSelections) || makeList({kind: ROOMS}) const list = get(userGroupSelections) || makeList({kind: ROOMS})
const newTags = [ const newTags = [
["r", url], ["r", url],
["group", room, url], ["group", h, url],
] ]
const event = await addToListPublicly(list, ...newTags).reconcile(nip44EncryptToSelf) const event = await addToListPublicly(list, ...newTags).reconcile(nip44EncryptToSelf)
const relays = uniq([...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)]) const relays = uniq([...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)])
@@ -203,9 +203,9 @@ export const addRoomMembership = async (url: string, room: string) => {
return publishThunk({event, relays}) return publishThunk({event, relays})
} }
export const removeRoomMembership = async (url: string, room: string) => { export const removeRoomMembership = async (url: string, h: string) => {
const list = get(userGroupSelections) || makeList({kind: ROOMS}) const list = get(userGroupSelections) || makeList({kind: ROOMS})
const pred = (t: string[]) => equals(["group", room, url], t.slice(0, 3)) const pred = (t: string[]) => equals(["group", h, url], t.slice(0, 3))
const event = await removeFromListByPredicate(list, pred).reconcile(nip44EncryptToSelf) const event = await removeFromListByPredicate(list, pred).reconcile(nip44EncryptToSelf)
const relays = uniq([url, ...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)]) const relays = uniq([url, ...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)])
+33 -36
View File
@@ -537,7 +537,7 @@ export const messages = deriveEvents(repository, {filters: [{kinds: [MESSAGE]}]}
export type Channel = { export type Channel = {
id: string id: string
url: string url: string
room: string h: string
name: string name: string
event: TrustedEvent event: TrustedEvent
closed: boolean closed: boolean
@@ -546,7 +546,7 @@ export type Channel = {
about?: string about?: string
} }
export const makeChannelId = (url: string, room: string) => `${url}'${room}` export const makeChannelId = (url: string, h: string) => `${url}'${h}`
export const splitChannelId = (id: string) => id.split("'") export const splitChannelId = (id: string) => id.split("'")
@@ -562,17 +562,17 @@ export const channels = derived(
for (const url of $getUrlsForEvent(event.id)) { for (const url of $getUrlsForEvent(event.id)) {
if (event.kind === ROOM_META) { if (event.kind === ROOM_META) {
const meta = fromPairs(event.tags) const meta = fromPairs(event.tags)
const room = meta.d const h = meta.d
if (room) { if (h) {
const id = makeChannelId(url, room) const id = makeChannelId(url, h)
result.set(id, { result.set(id, {
id, id,
url, url,
room, h,
event, event,
name: meta.name || room, name: meta.name || h,
closed: Boolean(getTag("closed", event.tags)), closed: Boolean(getTag("closed", event.tags)),
private: Boolean(getTag("private", event.tags)), private: Boolean(getTag("private", event.tags)),
picture: meta.picture, picture: meta.picture,
@@ -582,8 +582,8 @@ export const channels = derived(
} }
if (event.kind === ROOM_DELETE) { if (event.kind === ROOM_DELETE) {
for (const room of getTagValues("h", event.tags)) { for (const h of getTagValues("h", event.tags)) {
result.delete(makeChannelId(url, room)) result.delete(makeChannelId(url, h))
} }
} }
} }
@@ -604,24 +604,21 @@ export const {
store: channels, store: channels,
getKey: channel => channel.id, getKey: channel => channel.id,
load: async (id: string) => { load: async (id: string) => {
const [url, room] = splitChannelId(id) const [url, h] = splitChannelId(id)
await load({ await load({
relays: [url], relays: [url],
filters: [{kinds: [ROOM_META], "#d": [room]}], filters: [{kinds: [ROOM_META], "#d": [h]}],
}) })
}, },
}) })
export const deriveChannel = (url: string, room: string) => _deriveChannel(makeChannelId(url, room)) export const deriveChannel = (url: string, h: string) => _deriveChannel(makeChannelId(url, h))
export const loadChannel = (url: string, room: string) => _loadChannel(makeChannelId(url, room)) export const displayChannel = (url: string, h: string) =>
channelsById.get().get(makeChannelId(url, h))?.name || h
export const displayChannel = (url: string, room: string) => export const roomComparator = (url: string) => (h: string) => displayChannel(url, h).toLowerCase()
channelsById.get().get(makeChannelId(url, room))?.name || room
export const roomComparator = (url: string) => (room: string) =>
displayChannel(url, room).toLowerCase()
// User space/room selections // User space/room selections
@@ -685,9 +682,9 @@ export const getSpaceRoomsFromGroupSelections = (
) => { ) => {
const rooms: string[] = [] const rooms: string[] = []
for (const [_, room, relay] of getGroupTags(getListTags($groupSelections))) { for (const [_, h, relay] of getGroupTags(getListTags($groupSelections))) {
if (url === relay) { if (url === relay) {
rooms.push(room) rooms.push(h)
} }
} }
@@ -707,9 +704,9 @@ export const deriveUserRooms = (url: string) =>
derived([userGroupSelections, channelsById], ([$userGroupSelections, $channelsById]) => { derived([userGroupSelections, channelsById], ([$userGroupSelections, $channelsById]) => {
const rooms: string[] = [] const rooms: string[] = []
for (const room of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) { for (const h of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) {
if ($channelsById.has(makeChannelId(url, room))) { if ($channelsById.has(makeChannelId(url, h))) {
rooms.push(room) rooms.push(h)
} }
} }
@@ -720,9 +717,9 @@ export const deriveOtherRooms = (url: string) =>
derived([deriveUserRooms(url), channelsByUrl], ([$userRooms, $channelsByUrl]) => { derived([deriveUserRooms(url), channelsByUrl], ([$userRooms, $channelsByUrl]) => {
const rooms: string[] = [] const rooms: string[] = []
for (const {room} of $channelsByUrl.get(url) || []) { for (const {h} of $channelsByUrl.get(url) || []) {
if (!$userRooms.includes(room)) { if (!$userRooms.includes(h)) {
rooms.push(room) rooms.push(h)
} }
} }
@@ -765,11 +762,11 @@ export const deriveSpaceMembers = (url: string) =>
}, },
) )
export const deriveRoomMembers = (url: string, room: string) => export const deriveRoomMembers = (url: string, h: string) =>
derived( derived(
deriveEventsForUrl(url, [ deriveEventsForUrl(url, [
{kinds: [ROOM_MEMBERS], "#d": [room]}, {kinds: [ROOM_MEMBERS], "#d": [h]},
{kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [room]}, {kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [h]},
]), ]),
$events => { $events => {
const membersEvent = $events.find(spec({kind: ROOM_MEMBERS})) const membersEvent = $events.find(spec({kind: ROOM_MEMBERS}))
@@ -800,8 +797,8 @@ export const deriveRoomMembers = (url: string, room: string) =>
}, },
) )
export const deriveRoomAdmins = (url: string, room: string) => export const deriveRoomAdmins = (url: string, h: string) =>
derived(deriveEventsForUrl(url, [{kinds: [ROOM_ADMINS], "#d": [room]}]), $events => { derived(deriveEventsForUrl(url, [{kinds: [ROOM_ADMINS], "#d": [h]}]), $events => {
const adminsEvent = first($events) const adminsEvent = first($events)
if (adminsEvent) { if (adminsEvent) {
@@ -847,12 +844,12 @@ export const deriveUserSpaceMembershipStatus = (url: string) =>
}, },
) )
export const deriveUserRoomMembershipStatus = (url: string, room: string) => export const deriveUserRoomMembershipStatus = (url: string, h: string) =>
derived( derived(
[ [
pubkey, pubkey,
deriveRoomMembers(url, room), deriveRoomMembers(url, h),
deriveEventsForUrl(url, [{kinds: [ROOM_JOIN, ROOM_LEAVE], "#h": [room]}]), deriveEventsForUrl(url, [{kinds: [ROOM_JOIN, ROOM_LEAVE], "#h": [h]}]),
], ],
([$pubkey, $members, $events]) => { ([$pubkey, $members, $events]) => {
const isMember = $members.includes($pubkey) const isMember = $members.includes($pubkey)
@@ -885,8 +882,8 @@ export const deriveUserCanCreateRoom = (url: string) =>
}, },
) )
export const deriveUserIsRoomAdmin = (url: string, room: string) => export const deriveUserIsRoomAdmin = (url: string, h: string) =>
derived([pubkey, deriveRoomAdmins(url, room)], ([$pubkey, $admins]) => $admins.includes($pubkey!)) derived([pubkey, deriveRoomAdmins(url, h)], ([$pubkey, $admins]) => $admins.includes($pubkey!))
// Other utils // Other utils
+12 -12
View File
@@ -150,7 +150,7 @@ const syncUserSpaceMembership = (url: string) => {
return () => controller.abort() return () => controller.abort()
} }
const syncUserRoomMembership = (url: string, room: string) => { const syncUserRoomMembership = (url: string, h: string) => {
const $pubkey = pubkey.get() const $pubkey = pubkey.get()
const controller = new AbortController() const controller = new AbortController()
@@ -162,7 +162,7 @@ const syncUserRoomMembership = (url: string, room: string) => {
{ {
kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER],
"#p": [$pubkey], "#p": [$pubkey],
"#h": [room], "#h": [h],
}, },
], ],
}) })
@@ -187,11 +187,11 @@ const syncUserData = () => {
keys.add(url) keys.add(url)
for (const room of getSpaceRoomsFromGroupSelections(url, $l)) { for (const h of getSpaceRoomsFromGroupSelections(url, $l)) {
const key = `${url}'${room}` const key = `${url}'${h}`
if (!unsubscribersByKey.has(key)) { if (!unsubscribersByKey.has(key)) {
unsubscribersByKey.set(key, syncUserRoomMembership(url, room)) unsubscribersByKey.set(key, syncUserRoomMembership(url, h))
} }
keys.add(key) keys.add(key)
@@ -328,16 +328,16 @@ const syncSpaces = () => {
// Chat // Chat
const syncRoomChat = (url: string, room: string) => { const syncRoomChat = (url: string, h: string) => {
const controller = new AbortController() const controller = new AbortController()
pullAndListen({ pullAndListen({
relays: [url], relays: [url],
signal: controller.signal, signal: controller.signal,
filters: [ filters: [
{kinds: [ROOM_ADMINS, ROOM_MEMBERS], "#d": [room]}, {kinds: [ROOM_ADMINS, ROOM_MEMBERS], "#d": [h]},
{kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [room]}, {kinds: [ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [h]},
{kinds: [MESSAGE], "#h": [room]}, {kinds: [MESSAGE], "#h": [h]},
], ],
}) })
@@ -355,11 +355,11 @@ const syncRooms = () => {
// Add new subscriptions, depending on whether nip 29 is supported // Add new subscriptions, depending on whether nip 29 is supported
for (const url of getRelayTagValues(getListTags($l))) { for (const url of getRelayTagValues(getListTags($l))) {
if (hasNip29($relaysByUrl.get(url))) { if (hasNip29($relaysByUrl.get(url))) {
for (const room of getSpaceRoomsFromGroupSelections(url, $l)) { for (const h of getSpaceRoomsFromGroupSelections(url, $l)) {
const key = `${url}'${room}` const key = `${url}'${h}`
if (!unsubscribersByKey.has(key)) { if (!unsubscribersByKey.has(key)) {
newUnsubscribersByKey.set(key, syncRoomChat(url, room)) newUnsubscribersByKey.set(key, syncRoomChat(url, h))
} }
keys.add(key) keys.add(key)
+3 -3
View File
@@ -171,10 +171,10 @@ export const notifications = derived(
} }
if (hasNip29($relaysByUrl.get(url))) { if (hasNip29($relaysByUrl.get(url))) {
for (const room of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) { for (const h of getSpaceRoomsFromGroupSelections(url, $userGroupSelections)) {
const roomPath = makeRoomPath(url, room) const roomPath = makeRoomPath(url, h)
const latestEvent = allMessages.find( const latestEvent = allMessages.find(
e => $getUrlsForEvent(e.id).includes(url) && e.tags.find(spec(["h", room])), e => $getUrlsForEvent(e.id).includes(url) && e.tags.find(spec(["h", h])),
) )
if (hasNotification(roomPath, latestEvent)) { if (hasNotification(roomPath, latestEvent)) {
+4 -4
View File
@@ -52,7 +52,7 @@ export const makeSpacePath = (url: string, ...extra: (string | undefined)[]) =>
export const makeChatPath = (pubkeys: string[]) => `/chat/${makeChatId(pubkeys)}` export const makeChatPath = (pubkeys: string[]) => `/chat/${makeChatId(pubkeys)}`
export const makeRoomPath = (url: string, room: string) => `/spaces/${encodeRelay(url)}/${room}` export const makeRoomPath = (url: string, h: string) => `/spaces/${encodeRelay(url)}/${h}`
export const makeSpaceChatPath = (url: string) => makeRoomPath(url, "chat") export const makeSpaceChatPath = (url: string) => makeRoomPath(url, "chat")
@@ -103,7 +103,7 @@ export const getEventPath = async (event: TrustedEvent, urls: string[]) => {
return makeChatPath([event.pubkey, ...getPubkeyTagValues(event.tags)]) return makeChatPath([event.pubkey, ...getPubkeyTagValues(event.tags)])
} }
const room = getTagValue(ROOM, event.tags) const h = getTagValue(ROOM, event.tags)
if (urls.length > 0) { if (urls.length > 0) {
const url = urls[0] const url = urls[0]
@@ -121,7 +121,7 @@ export const getEventPath = async (event: TrustedEvent, urls: string[]) => {
} }
if (event.kind === MESSAGE) { if (event.kind === MESSAGE) {
return room ? makeRoomPath(url, room) : makeSpacePath(url, "chat") return h ? makeRoomPath(url, h) : makeSpacePath(url, "chat")
} }
const kind = event.tags.find(nthEq(0, "K"))?.[1] const kind = event.tags.find(nthEq(0, "K"))?.[1]
@@ -141,7 +141,7 @@ export const getEventPath = async (event: TrustedEvent, urls: string[]) => {
} }
if (parseInt(kind) === MESSAGE) { if (parseInt(kind) === MESSAGE) {
return room ? makeRoomPath(url, room) : makeSpacePath(url, "chat") return h ? makeRoomPath(url, h) : makeSpacePath(url, "chat")
} }
} }
} }
@@ -63,26 +63,26 @@
import {pushToast} from "@app/util/toast" import {pushToast} from "@app/util/toast"
import {pushModal} from "@app/util/modal" import {pushModal} from "@app/util/modal"
const {room, relay} = $page.params as MakeNonOptional<typeof $page.params> const {h, relay} = $page.params as MakeNonOptional<typeof $page.params>
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, room) const channel = deriveChannel(url, h)
const shouldProtect = canEnforceNip70(url) const shouldProtect = canEnforceNip70(url)
const userRooms = deriveUserRooms(url) const userRooms = deriveUserRooms(url)
const userIsAdmin = deriveUserIsRoomAdmin(url, room) const userIsAdmin = deriveUserIsRoomAdmin(url, h)
const isFavorite = $derived($userRooms.includes(room)) const isFavorite = $derived($userRooms.includes(h))
const membershipStatus = deriveUserRoomMembershipStatus(url, room) const membershipStatus = deriveUserRoomMembershipStatus(url, h)
const addFavorite = () => addRoomMembership(url, room) const addFavorite = () => addRoomMembership(url, h)
const removeFavorite = () => removeRoomMembership(url, room) const removeFavorite = () => removeRoomMembership(url, h)
const join = async () => { const join = async () => {
joining = true joining = true
try { try {
const message = await waitForThunkError(joinRoom(url, makeRoomMeta({h: room}))) const message = await waitForThunkError(joinRoom(url, makeRoomMeta({h})))
if (message && !message.startsWith("duplicate:")) { if (message && !message.startsWith("duplicate:")) {
return pushToast({theme: "error", message}) return pushToast({theme: "error", message})
@@ -98,7 +98,7 @@
const leave = async () => { const leave = async () => {
leaving = true leaving = true
try { try {
const message = await waitForThunkError(leaveRoom(url, makeRoomMeta({h: room}))) const message = await waitForThunkError(leaveRoom(url, makeRoomMeta({h})))
if (message && !message.startsWith("duplicate:")) { if (message && !message.startsWith("duplicate:")) {
pushToast({theme: "error", message}) pushToast({theme: "error", message})
@@ -126,7 +126,7 @@
} }
const onSubmit = async ({content, tags}: EventContent) => { const onSubmit = async ({content, tags}: EventContent) => {
tags.push(["h", room]) tags.push(["h", h])
if (await shouldProtect) { if (await shouldProtect) {
tags.push(PROTECTED) tags.push(PROTECTED)
@@ -270,7 +270,7 @@
const feed = makeFeed({ const feed = makeFeed({
url, url,
element: element!, element: element!,
filters: [{kinds: [...MESSAGE_KINDS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [room]}], filters: [{kinds: [...MESSAGE_KINDS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [h]}],
onExhausted: () => { onExhausted: () => {
loadingEvents = false loadingEvents = false
}, },
@@ -297,7 +297,7 @@
} }
} }
const startEdit = () => pushModal(RoomEdit, {url, room}) const startEdit = () => pushModal(RoomEdit, {url, h})
onMount(() => { onMount(() => {
const observer = new ResizeObserver(() => { const observer = new ResizeObserver(() => {
@@ -334,7 +334,7 @@
{/snippet} {/snippet}
{#snippet title()} {#snippet title()}
<strong class="ellipsize"> <strong class="ellipsize">
<ChannelName {url} {room} /> <ChannelName {url} {h} />
</strong> </strong>
{/snippet} {/snippet}
{#snippet action()} {#snippet action()}
@@ -486,7 +486,7 @@
{#key eventToEdit} {#key eventToEdit}
<ChannelCompose <ChannelCompose
{url} {url}
{room} {h}
{onSubmit} {onSubmit}
{onEditPrevious} {onEditPrevious}
content={eventToEdit?.content} content={eventToEdit?.content}
@@ -21,7 +21,7 @@
const conversations = derived(messages, $messages => { const conversations = derived(messages, $messages => {
const convs = [] const convs = []
for (const [room, messages] of groupBy(e => getTagValue("h", e.tags), $messages).entries()) { for (const [h, messages] of groupBy(e => getTagValue("h", e.tags), $messages).entries()) {
const avgTime = avg(overlappingPairs(messages).map(([a, b]) => a.created_at - b.created_at)) const avgTime = avg(overlappingPairs(messages).map(([a, b]) => a.created_at - b.created_at))
const groups: TrustedEvent[][] = [] const groups: TrustedEvent[][] = []
const group: TrustedEvent[] = [] const group: TrustedEvent[] = []
@@ -52,7 +52,7 @@
const earliest = last(events)! const earliest = last(events)!
const participants = uniq(events.map(msg => msg.pubkey)) const participants = uniq(events.map(msg => msg.pubkey))
convs.push({room, events, latest, earliest, participants}) convs.push({h, events, latest, earliest, participants})
} }
} }
@@ -96,10 +96,10 @@
{#if $messages.length > 0} {#if $messages.length > 0}
{@const events = $messages.slice(0, 1)} {@const events = $messages.slice(0, 1)}
{@const event = events[0]} {@const event = events[0]}
{@const room = getTagValue("h", event.tags)} {@const h = getTagValue("h", event.tags)}
<ConversationCard <ConversationCard
{h}
{url} {url}
{room}
{events} {events}
latest={event} latest={event}
earliest={event} earliest={event}
@@ -110,8 +110,8 @@
</div> </div>
{/if} {/if}
{:else} {:else}
{#each $conversations.slice(0, limit) as { room, events, latest, earliest, participants } (latest.id)} {#each $conversations.slice(0, limit) as { h, events, latest, earliest, participants } (latest.id)}
<ConversationCard {url} {room} {events} {latest} {earliest} {participants} /> <ConversationCard {h} {url} {events} {latest} {earliest} {participants} />
{/each} {/each}
{/if} {/if}
</PageContent> </PageContent>