fix: reliable speaking indicator via direct store writes + polling safety net
Eliminate double-state architecture (useState → useEffect bridge → store) that lost speaking events due to React 18 batching. ActiveSpeakersChanged now writes speakingParticipantIds directly to voiceStore; 200ms poll catches missed SDK events. Each VoiceUser subscribes to its own identity via fine-grained selector for minimal re-renders. Also adds connection quality indicator and ConnectionInfoPopover.
This commit is contained in:
@@ -93,12 +93,10 @@ export function AppLayout() {
|
||||
|
||||
const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId);
|
||||
const activeDmCall = useVoiceStore((s) => s.activeDmCall);
|
||||
const setParticipants = useVoiceStore((s) => s.setParticipants);
|
||||
const {
|
||||
connect: connectVoice,
|
||||
connectDm: connectDmVoice,
|
||||
disconnect: disconnectVoice,
|
||||
participants: voiceParticipants,
|
||||
isConnected: isVoiceConnected,
|
||||
isConnecting: isVoiceConnecting,
|
||||
connectedChannelId,
|
||||
@@ -107,11 +105,6 @@ export function AppLayout() {
|
||||
// Initialize WebSocket
|
||||
const { isConnected: isWsConnected } = useWebSocket();
|
||||
|
||||
// Sync participants to store
|
||||
useEffect(() => {
|
||||
setParticipants(voiceParticipants);
|
||||
}, [voiceParticipants, setParticipants]);
|
||||
|
||||
// Track the last channel we attempted to connect to, to prevent effect loops
|
||||
const lastAttemptedRef = React.useRef<string | null>(null);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user