feat: gesture-aware voice connection, remove AppLayout auto-connect
Replace the useEffect-based auto-connect pattern in AppLayout with direct connect/disconnect calls from user gesture contexts. This is required for iOS (AudioContext.resume + getUserMedia must happen in a gesture handler) and aligns with tightening autoplay policies on desktop browsers. Architecture: - voiceStore gains connectFn/disconnectFn refs, registered by AppLayout from the single useLiveKit() instance. - All voice join paths (ChannelSidebar, MobileSpacesScreen, MainContent, voice_moved WS handler) pass connectFn to joinVoiceChannel(). - All disconnect paths (VoiceControls, voiceActions, MobileVoiceFullScreen, MobileVoiceMiniBar, dm_call_ended/rejected WS handlers, ready handler) call disconnectFn() directly. - dm_call_accepted WS handler calls connectFn() to initiate the DM call LiveKit connection. - The 55-line auto-connect useEffect and lastAttemptedRef are removed.
This commit is contained in:
@@ -65,8 +65,17 @@ export function broadcastDeafenViaLiveKit(): void {
|
||||
* When switching from a channel on Instance A to one on Instance B,
|
||||
* this sends an explicit voice_leave to Instance A first so it
|
||||
* broadcasts a leave event and the client cleans up stale voice state.
|
||||
*
|
||||
* @param channelId The channel to join.
|
||||
* @param connectFn The LiveKit connect function, obtained from
|
||||
* `useVoiceStore.getState().connectFn`. When provided the
|
||||
* LiveKit connection is initiated directly within the
|
||||
* caller's gesture context (required on iOS).
|
||||
*/
|
||||
export function joinVoiceChannel(channelId: string): void {
|
||||
export function joinVoiceChannel(
|
||||
channelId: string,
|
||||
connectFn?: (channelId: string, isDm?: boolean) => Promise<void>,
|
||||
): void {
|
||||
const { currentVoiceChannelId, setCurrentVoiceChannel, addVoiceUser, removeVoiceUser } = useVoiceStore.getState();
|
||||
if (currentVoiceChannelId === channelId) return;
|
||||
|
||||
@@ -83,8 +92,16 @@ export function joinVoiceChannel(channelId: string): void {
|
||||
}
|
||||
|
||||
setCurrentVoiceChannel(channelId);
|
||||
// voice_join is now sent by useLiveKit after successful LiveKit connection
|
||||
// Optimistic: immediately show self in new channel (using origin-aware ID)
|
||||
const myNewId = getMyUserIdForOrigin(getChannelOrigin(channelId));
|
||||
if (myNewId) addVoiceUser(channelId, myNewId);
|
||||
|
||||
// Direct connection within gesture context
|
||||
if (connectFn) {
|
||||
connectFn(channelId).catch((err) => {
|
||||
console.error('[voice] Connection failed:', err);
|
||||
setCurrentVoiceChannel(null);
|
||||
if (myNewId) removeVoiceUser(channelId, myNewId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user