Show the call view for a guild's voice channel too

It keyed on the session's bufferId, which a guild voice channel does not
have - it is its own channel with no text buffer behind it, so the panel
could only ever have appeared for one-to-one calls. Confirmed against a
live join: the session came back with bufferId null and a guildId, and
nothing mounted.

It now also matches on the guild, so the call shows on whatever channel
of that server is open. That is where Discord keeps it, and the only
place it could go without inventing a buffer for a channel that has
none.
This commit is contained in:
2026-08-28 17:51:51 -04:00
parent 4ad750178f
commit 2ae2ece968
+16 -2
View File
@@ -34,7 +34,22 @@ export function CallView({ bufferId }: { bufferId: string }): JSX.Element | null
const [speaking, setSpeaking] = useState<Record<string, number>>({})
const [folded, setFolded] = useState(false)
const session = sessions.find((s) => s.bufferId === bufferId)
/**
* The call this conversation should be showing.
*
* Two ways to match, because the two kinds of call are anchored
* differently. A one-to-one call belongs to the DM it is in, and shows on
* that conversation only. A guild's voice channel belongs to no text
* conversation at all - it is its own channel, with no buffer - so it shows
* on whatever channel of that guild is open, which is where Discord keeps
* it too and the only place it could go without inventing a buffer for it.
*/
const buffer = buffers.find((b) => b.id === bufferId)
const session = sessions.find(
(s) =>
s.bufferId === bufferId ||
(!!s.guildId && !!buffer?.groupId && buffer.groupId === `${s.accountId}|guild:${s.guildId}`)
)
const accountId = session?.accountId
const channelId = session?.channelId
@@ -91,7 +106,6 @@ export function CallView({ bufferId }: { bufferId: string }): JSX.Element | null
if (!session) return null
const buffer = buffers.find((b) => b.id === bufferId)
const talking = (m: VoiceMember): boolean =>
m.isSelf ? speaking.self !== undefined : (speaking[m.userId] ?? 0) > 0