diff --git a/src/state/CallViewModel.test.ts b/src/state/CallViewModel.test.ts index 14214407..d262eaea 100644 --- a/src/state/CallViewModel.test.ts +++ b/src/state/CallViewModel.test.ts @@ -224,6 +224,9 @@ test("screen sharing activates spotlight layout", () => { // sharing, then return to grid, then manually go into spotlight, and // remain in spotlight until we manually go back to grid const laytMarbles = "ab(cc)(dd)ae(bb)(ee)a 59979ms a"; + // Speaking indicators should always be shown except for when the active + // speaker is present in the spotlight + const showMarbles = "y----------ny---n---y"; withCallViewModel( helpers, @@ -273,6 +276,10 @@ test("screen sharing activates spotlight layout", () => { }, }, ); + expectObservable(vm.showSpeakingIndicators).toBe(showMarbles, { + y: true, + n: false, + }); }, ); }); diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index db2833b8..39453c60 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -744,7 +744,25 @@ export class CallViewModel extends ViewModel { } public showSpeakingIndicators: Observable = this.layout.pipe( - map((l) => l.type !== "one-on-one" && !l.type.startsWith("spotlight-")), + map((l) => { + switch (l.type) { + case "spotlight-landscape": + case "spotlight-portrait": + // If the spotlight is showing the active speaker, we can do without + // speaking indicators as they're a redundant visual cue. But if + // screen sharing feeds are in the spotlight we still need them. + return l.spotlight[0] instanceof ScreenShareViewModel; + // In expanded spotlight layout, the active speaker is always shown in + // the picture-in-picture tile so there is no need for speaking + // indicators. And in one-on-one layout there's no question as to who is + // speaking. + case "spotlight-expanded": + case "one-on-one": + return false; + default: + return true; + } + }), this.scope.state(), );