fix: leave and reconnect sound randomly playing, also fix leave sound when muting
This commit is contained in:
@@ -15,3 +15,4 @@ export const DEFAULT_MAX_USERS = 50;
|
||||
export const DEFAULT_AUDIO_BITRATE_KBPS = 96;
|
||||
export const DEFAULT_VOLUME = 100;
|
||||
export const SEARCH_DEBOUNCE_MS = 300;
|
||||
export const RECONNECT_SOUND_GRACE_MS = 15_000;
|
||||
|
||||
@@ -64,7 +64,7 @@ import {
|
||||
} from '../../shared-kernel';
|
||||
import { NotificationAudioService, AppSound } from '../../core/services/notification-audio.service';
|
||||
import { hasRoomBanForUser } from '../../core/helpers/room-ban.helpers';
|
||||
import { ROOM_URL_PATTERN } from '../../core/constants';
|
||||
import { RECONNECT_SOUND_GRACE_MS, ROOM_URL_PATTERN } from '../../core/constants';
|
||||
import { VoiceSessionFacade } from '../../domains/voice-session';
|
||||
import {
|
||||
findRoomMember,
|
||||
@@ -190,6 +190,12 @@ export class RoomsEffects {
|
||||
* preventing false join/leave sounds during state refreshes.
|
||||
*/
|
||||
private knownVoiceUsers = new Set<string>();
|
||||
/**
|
||||
* When a user leaves (e.g. socket drops), record the timestamp so
|
||||
* that a rapid re-join (reconnect) does not trigger a false
|
||||
* join/leave sound within {@link RECONNECT_SOUND_GRACE_MS}.
|
||||
*/
|
||||
private recentlyLeftVoiceTimestamps = new Map<string, number>();
|
||||
private roomNavigationRequestVersion = 0;
|
||||
private latestNavigatedRoomId: string | null = null;
|
||||
|
||||
@@ -1287,6 +1293,10 @@ export class RoomsEffects {
|
||||
: undefined;
|
||||
|
||||
if (!remainingServerIds || remainingServerIds.length === 0) {
|
||||
if (this.knownVoiceUsers.has(signalingMessage.oderId)) {
|
||||
this.recentlyLeftVoiceTimestamps.set(signalingMessage.oderId, Date.now());
|
||||
}
|
||||
|
||||
this.knownVoiceUsers.delete(signalingMessage.oderId);
|
||||
}
|
||||
|
||||
@@ -1452,13 +1462,20 @@ export class RoomsEffects {
|
||||
const nowConnected = vs.isConnected ?? false;
|
||||
const wasKnown = this.knownVoiceUsers.has(userId);
|
||||
const wasInCurrentVoiceRoom = this.isSameVoiceRoom(existingUser?.voiceState, currentUser?.voiceState);
|
||||
const isInCurrentVoiceRoom = this.isSameVoiceRoom(vs, currentUser?.voiceState);
|
||||
// Merge with existing state so partial updates (e.g. mute toggle
|
||||
// that omits roomId/serverId) don't look like a room change.
|
||||
const mergedVoiceState = { ...existingUser?.voiceState, ...vs };
|
||||
const isInCurrentVoiceRoom = this.isSameVoiceRoom(mergedVoiceState, currentUser?.voiceState);
|
||||
|
||||
if (weAreInVoice) {
|
||||
if (((!wasKnown && isInCurrentVoiceRoom) || (userExists && !wasInCurrentVoiceRoom && isInCurrentVoiceRoom)) && nowConnected) {
|
||||
this.audioService.play(AppSound.Joining);
|
||||
} else if (wasInCurrentVoiceRoom && !isInCurrentVoiceRoom) {
|
||||
this.audioService.play(AppSound.Leave);
|
||||
const isReconnect = this.consumeRecentLeave(userId);
|
||||
|
||||
if (!isReconnect) {
|
||||
if (((!wasKnown && isInCurrentVoiceRoom) || (userExists && !wasInCurrentVoiceRoom && isInCurrentVoiceRoom)) && nowConnected) {
|
||||
this.audioService.play(AppSound.Joining);
|
||||
} else if (wasInCurrentVoiceRoom && !isInCurrentVoiceRoom) {
|
||||
this.audioService.play(AppSound.Leave);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1630,6 +1647,31 @@ export class RoomsEffects {
|
||||
&& voiceState.serverId === currentUserVoiceState.serverId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` and cleans up the entry if the given user left
|
||||
* recently enough to be considered a reconnect. Also prunes any
|
||||
* stale entries older than the grace window.
|
||||
*/
|
||||
private consumeRecentLeave(userId: string): boolean {
|
||||
const now = Date.now();
|
||||
|
||||
// Prune stale entries while iterating.
|
||||
for (const [id, ts] of this.recentlyLeftVoiceTimestamps) {
|
||||
if (now - ts > RECONNECT_SOUND_GRACE_MS) {
|
||||
this.recentlyLeftVoiceTimestamps.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
const leaveTs = this.recentlyLeftVoiceTimestamps.get(userId);
|
||||
|
||||
if (leaveTs !== undefined && now - leaveTs <= RECONNECT_SOUND_GRACE_MS) {
|
||||
this.recentlyLeftVoiceTimestamps.delete(userId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private resolveRoom(roomId: string | undefined, currentRoom: Room | null, savedRooms: Room[]): Room | null {
|
||||
if (!roomId)
|
||||
return currentRoom;
|
||||
|
||||
Reference in New Issue
Block a user