diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 190ad1f4..8348053f 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -71,7 +71,7 @@ import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStor import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; import { playersStore } from "../../Stores/PlayersStore"; import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; -import { userIsAdminStore, userIsJitsiDominantSpeakerStore } from "../../Stores/GameStore"; +import { jitsiParticipantsCountStore, userIsAdminStore, userIsJitsiDominantSpeakerStore } from "../../Stores/GameStore"; import { contactPageStore } from "../../Stores/MenuStore"; import type { WasCameraUpdatedEvent } from "../../Api/Events/WasCameraUpdatedEvent"; import { audioManagerFileStore } from "../../Stores/AudioManagerStore"; @@ -179,6 +179,7 @@ export class GameScene extends DirtyScene { private followUsersColorStoreUnsubscribe!: Unsubscriber; private currentPlayerGroupIdStoreUnsubscribe!: Unsubscriber; private userIsJitsiDominantSpeakerStoreUnsubscriber!: Unsubscriber; + private jitsiParticipantsCountStoreUnsubscriber!: Unsubscriber; private biggestAvailableAreaStoreUnsubscribe!: () => void; MapUrlFile: string; @@ -222,6 +223,8 @@ export class GameScene extends DirtyScene { private firstCameraUpdateSent: boolean = false; private showVoiceIndicatorChangeMessageSent: boolean = false; private currentPlayerGroupId?: number; + private jitsiDominantSpeaker: boolean = false; + private jitsiParticipantsCount: number = 0; public readonly superLoad: SuperLoaderPlugin; constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) { @@ -667,10 +670,16 @@ export class GameScene extends DirtyScene { this.userIsJitsiDominantSpeakerStoreUnsubscriber = userIsJitsiDominantSpeakerStore.subscribe( (dominantSpeaker) => { - this.tryChangeShowVoiceIndicatorState(dominantSpeaker); + this.jitsiDominantSpeaker = dominantSpeaker; + this.tryChangeShowVoiceIndicatorState(this.jitsiDominantSpeaker && this.jitsiParticipantsCount > 1); } ); + this.jitsiParticipantsCountStoreUnsubscriber = jitsiParticipantsCountStore.subscribe((participantsCount) => { + this.jitsiParticipantsCount = participantsCount; + this.tryChangeShowVoiceIndicatorState(this.jitsiDominantSpeaker && this.jitsiParticipantsCount > 1); + }); + this.emoteUnsubscribe = emoteStore.subscribe((emote) => { if (emote) { this.CurrentPlayer?.playEmote(emote.url); diff --git a/front/src/Stores/GameStore.ts b/front/src/Stores/GameStore.ts index ddab3f66..3e7e8cbd 100644 --- a/front/src/Stores/GameStore.ts +++ b/front/src/Stores/GameStore.ts @@ -8,4 +8,6 @@ export const userIsAdminStore = writable(false); export const userIsJitsiDominantSpeakerStore = writable(false); +export const jitsiParticipantsCountStore = writable(0); + export const limitMapStore = writable(false); diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 885f6971..3d17b5b8 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -4,7 +4,7 @@ import { requestedCameraState, requestedMicrophoneState } from "../Stores/MediaS import { get } from "svelte/store"; import CancelablePromise from "cancelable-promise"; import { gameManager } from "../Phaser/Game/GameManager"; -import { userIsJitsiDominantSpeakerStore } from "../Stores/GameStore"; +import { jitsiParticipantsCountStore, userIsJitsiDominantSpeakerStore } from "../Stores/GameStore"; interface jitsiConfigInterface { startWithAudioMuted: boolean; @@ -129,6 +129,7 @@ class JitsiFactory { private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); private dominantSpeakerChangedCallback = this.onDominantSpeakerChanged.bind(this); + private participantsCountChangeCallback = this.onParticipantsCountChange.bind(this); private jitsiScriptLoaded: boolean = false; /** @@ -203,11 +204,15 @@ class JitsiFactory { this.jitsiApi.addListener("videoConferenceJoined", () => { this.jitsiApi?.executeCommand("displayName", playerName); + this.updateParticipantsCountStore(); }); this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback); this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback); this.jitsiApi.addListener("dominantSpeakerChanged", this.dominantSpeakerChangedCallback); + this.jitsiApi.addListener("participantJoined", this.participantsCountChangeCallback); + this.jitsiApi.addListener("participantLeft", this.participantsCountChangeCallback); + this.jitsiApi.addListener("participantKickedOut", this.participantsCountChangeCallback); }); cancel(() => { @@ -243,6 +248,7 @@ class JitsiFactory { public destroy() { userIsJitsiDominantSpeakerStore.set(false); + jitsiParticipantsCountStore.set(0); if (!this.jitsiApi) { return; } @@ -274,6 +280,15 @@ class JitsiFactory { ); } + private onParticipantsCountChange(): void { + this.updateParticipantsCountStore(); + } + + private updateParticipantsCountStore(): void { + //@ts-ignore + jitsiParticipantsCountStore.set(this.jitsiApi?.getParticipantsInfo().length ?? 0); + } + private getCurrentParticipantId( participants: { displayName: string; participantId: string }[] ): string | undefined {