feat: Implement voice and video calling features including participant tiles, screen sharing, and audio controls with associated UI components and sound assets.
All checks were successful
Build and Release / build-and-release (push) Successful in 13m4s
All checks were successful
Build and Release / build-and-release (push) Successful in 13m4s
This commit is contained in:
@@ -50,7 +50,7 @@ function playSoundUrl(url) {
|
||||
}
|
||||
|
||||
export const VoiceProvider = ({ children }) => {
|
||||
const { idle } = usePlatform();
|
||||
const { idle, voiceService } = usePlatform();
|
||||
const [activeChannelId, setActiveChannelId] = useState(null);
|
||||
const [activeChannelName, setActiveChannelName] = useState(null);
|
||||
const [connectionState, setConnectionState] = useState('disconnected');
|
||||
@@ -316,6 +316,8 @@ export const VoiceProvider = ({ children }) => {
|
||||
|
||||
setRoom(newRoom);
|
||||
setConnectionState('connected');
|
||||
// Start native foreground service for background voice on Android
|
||||
voiceService?.startService({ channelName, isMuted, isDeafened });
|
||||
// Play custom join sound if set, otherwise default
|
||||
if (myJoinSoundUrl) {
|
||||
playSoundUrl(myJoinSoundUrl);
|
||||
@@ -336,6 +338,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
setIsMuted(true);
|
||||
await newRoom.localParticipant.setMicrophoneEnabled(false);
|
||||
await convex.mutation(api.voiceState.updateState, { userId, isMuted: true });
|
||||
voiceService?.updateNotification({ isMuted: true });
|
||||
}
|
||||
|
||||
newRoom.on(RoomEvent.Disconnected, async (reason) => {
|
||||
@@ -364,6 +367,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
voiceService?.stopService();
|
||||
playSound('leave');
|
||||
setConnectionState('disconnected');
|
||||
setActiveChannelId(null);
|
||||
@@ -427,6 +431,30 @@ export const VoiceProvider = ({ children }) => {
|
||||
return () => clearInterval(interval);
|
||||
}, [activeChannelId, convex]);
|
||||
|
||||
// Handle notification action buttons (Android foreground service)
|
||||
useEffect(() => {
|
||||
if (!voiceService) return;
|
||||
const listener = voiceService.addNotificationActionListener((event) => {
|
||||
switch (event.action) {
|
||||
case 'disconnect':
|
||||
disconnectVoice();
|
||||
break;
|
||||
case 'toggleMute':
|
||||
toggleMute();
|
||||
break;
|
||||
case 'toggleDeafen':
|
||||
toggleDeafen();
|
||||
break;
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
if (listener && listener.remove) listener.remove();
|
||||
else if (listener && typeof listener.then === 'function') {
|
||||
listener.then(l => l?.remove?.());
|
||||
}
|
||||
};
|
||||
}, [voiceService, activeChannelId]);
|
||||
|
||||
// Detect when another user moves us to a different voice channel
|
||||
useEffect(() => {
|
||||
const myUserId = localStorage.getItem('userId');
|
||||
@@ -508,6 +536,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
// After server-side move, locally mute
|
||||
setIsMuted(true);
|
||||
if (room) room.localParticipant.setMicrophoneEnabled(false);
|
||||
voiceService?.updateNotification({ isMuted: true });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('AFK check failed:', e);
|
||||
@@ -691,6 +720,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
const disconnectVoice = () => {
|
||||
console.log('User manually disconnected voice');
|
||||
isDMCallRef.current = false;
|
||||
voiceService?.stopService();
|
||||
if (room) room.disconnect();
|
||||
};
|
||||
|
||||
@@ -702,6 +732,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
const nextState = !isMuted;
|
||||
setIsMuted(nextState);
|
||||
playSound(nextState ? 'mute' : 'unmute');
|
||||
voiceService?.updateNotification({ isMuted: nextState });
|
||||
if (room) {
|
||||
room.localParticipant.setMicrophoneEnabled(!nextState);
|
||||
}
|
||||
@@ -712,6 +743,7 @@ export const VoiceProvider = ({ children }) => {
|
||||
const nextState = !isDeafened;
|
||||
setIsDeafened(nextState);
|
||||
playSound(nextState ? 'deafen' : 'undeafen');
|
||||
voiceService?.updateNotification({ isDeafened: nextState });
|
||||
if (room && !isMuted) {
|
||||
room.localParticipant.setMicrophoneEnabled(!nextState);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user