fix: perfect speaking ring circle and use real avatars/display names in voice tiles

Add flex to speaking ring wrapper divs in VoiceUser and PictureInPicture
to eliminate baseline descender space that made the ring oval. Extract
useVoiceParticipantMeta hook to resolve real display names and avatars
for voice participants instead of showing raw usernames with null avatars.
This commit is contained in:
Jannis Braun
2026-03-10 23:21:37 +01:00
parent a5c7bb6e9a
commit f82e721491
4 changed files with 55 additions and 8 deletions
@@ -0,0 +1,43 @@
import { useMemo } from 'react';
import { useSpaceStore } from '../stores/spaceStore';
import { parseFederatedUsername } from '../utils/identity';
import type { ParticipantInfo } from './useLiveKit';
/**
* Resolves display metadata (displayName, avatar) for a voice participant
* by looking up member data from the space/DM stores.
*
* Reactive — re-renders when member data changes (e.g. user updates avatar mid-call).
*/
export function useVoiceParticipantMeta(participant: ParticipantInfo) {
const members = useSpaceStore((s) => s.members);
const dmChannels = useSpaceStore((s) => s.dmChannels);
return useMemo(() => {
// 1. Try space members (primary — covers space voice channels)
const member = members.find(m => m.userId === participant.userId);
if (member?.user) {
const { baseName } = parseFederatedUsername(member.user.username);
return {
displayName: member.user.displayName ?? baseName,
avatar: member.user.avatar ?? null,
};
}
// 2. Fallback to DM channel members (covers DM calls)
for (const dm of dmChannels) {
const dmMember = dm.members?.find(m => m.id === participant.userId);
if (dmMember) {
const { baseName } = parseFederatedUsername(dmMember.username);
return {
displayName: dmMember.displayName ?? baseName,
avatar: dmMember.avatar ?? null,
};
}
}
// 3. Final fallback — parse username from LiveKit identity
const { baseName } = parseFederatedUsername(participant.username);
return { displayName: baseName, avatar: null };
}, [members, dmChannels, participant.userId, participant.username]);
}