mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-08 20:09:19 +00:00
fix logic for earpiece quick switcher to be based on switching target
(also show quick switcher if headphones are connected)
This commit is contained in:
@@ -312,7 +312,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
const showHeader = useObservableEagerState(vm.showHeader$);
|
const showHeader = useObservableEagerState(vm.showHeader$);
|
||||||
const showFooter = useObservableEagerState(vm.showFooter$);
|
const showFooter = useObservableEagerState(vm.showFooter$);
|
||||||
const earpieceMode = useObservableEagerState(vm.earpieceMode$);
|
const earpieceMode = useObservableEagerState(vm.earpieceMode$);
|
||||||
const toggleEarpieceMode = useObservableEagerState(vm.toggleEarpieceMode$);
|
const audioOutputSwitcher = useObservableEagerState(vm.audioOutputSwitcher$);
|
||||||
const switchCamera = useSwitchCamera(vm.localVideo$);
|
const switchCamera = useSwitchCamera(vm.localVideo$);
|
||||||
|
|
||||||
// Ideally we could detect taps by listening for click events and checking
|
// Ideally we could detect taps by listening for click events and checking
|
||||||
@@ -457,27 +457,26 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
|
|
||||||
useAppBarSecondaryButton(
|
useAppBarSecondaryButton(
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
if (toggleEarpieceMode === null) return null;
|
if (audioOutputSwitcher === null) return null;
|
||||||
const Icon = earpieceMode ? VolumeOnSolidIcon : EarpieceIcon;
|
const isEarpieceTarget = audioOutputSwitcher.targetOutput === "earpiece";
|
||||||
|
const Icon = isEarpieceTarget ? EarpieceIcon : VolumeOnSolidIcon;
|
||||||
|
const label = isEarpieceTarget
|
||||||
|
? t("settings.devices.earpiece")
|
||||||
|
: t("settings.devices.loudspeaker");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip label={label}>
|
||||||
label={
|
|
||||||
earpieceMode
|
|
||||||
? t("settings.devices.earpiece")
|
|
||||||
: t("settings.devices.loudspeaker")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
toggleEarpieceMode();
|
audioOutputSwitcher.switch();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon />
|
<Icon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}, [t, earpieceMode, toggleEarpieceMode]),
|
}, [t, audioOutputSwitcher]),
|
||||||
);
|
);
|
||||||
|
|
||||||
useAppBarHidden(!showHeader);
|
useAppBarHidden(!showHeader);
|
||||||
@@ -789,7 +788,7 @@ export const InCallView: FC<InCallViewProps> = ({
|
|||||||
<ReactionsAudioRenderer vm={vm} muted={muteAllAudio} />
|
<ReactionsAudioRenderer vm={vm} muted={muteAllAudio} />
|
||||||
<EarpieceOverlay
|
<EarpieceOverlay
|
||||||
show={earpieceMode}
|
show={earpieceMode}
|
||||||
onBackToVideoPressed={toggleEarpieceMode}
|
onBackToVideoPressed={audioOutputSwitcher?.switch}
|
||||||
/>
|
/>
|
||||||
<ReactionsOverlay vm={vm} />
|
<ReactionsOverlay vm={vm} />
|
||||||
{footer}
|
{footer}
|
||||||
|
|||||||
@@ -1261,29 +1261,36 @@ export class CallViewModel extends ViewModel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to toggle between the earpiece and the loudspeaker.
|
* Callback to toggle between the earpiece and the loudspeaker.
|
||||||
|
*
|
||||||
|
* This will be `null` in case the target does not exist in the list
|
||||||
|
* of available audio outputs.
|
||||||
*/
|
*/
|
||||||
public readonly toggleEarpieceMode$: Observable<(() => void) | null> =
|
public readonly audioOutputSwitcher$: Observable<{
|
||||||
combineLatest(
|
targetOutput: "earpiece" | "speaker";
|
||||||
[
|
switch: () => void;
|
||||||
this.mediaDevices.audioOutput.available$,
|
} | null> = combineLatest(
|
||||||
this.mediaDevices.audioOutput.selected$,
|
[
|
||||||
],
|
this.mediaDevices.audioOutput.available$,
|
||||||
(available, selected) => {
|
this.mediaDevices.audioOutput.selected$,
|
||||||
const selectionType = selected && available.get(selected.id)?.type;
|
],
|
||||||
if (!(selectionType === "speaker" || selectionType === "earpiece"))
|
(available, selected) => {
|
||||||
return null;
|
const selectionType = selected && available.get(selected.id)?.type;
|
||||||
|
|
||||||
const newSelectionType =
|
// If we are in any output mode other than spaeker switch to speaker.
|
||||||
selectionType === "speaker" ? "earpiece" : "speaker";
|
const newSelectionType =
|
||||||
const newSelection = [...available].find(
|
selectionType === "speaker" ? "earpiece" : "speaker";
|
||||||
([, d]) => d.type === newSelectionType,
|
const newSelection = [...available].find(
|
||||||
);
|
([, d]) => d.type === newSelectionType,
|
||||||
if (newSelection === undefined) return null;
|
);
|
||||||
|
if (newSelection === undefined) return null;
|
||||||
|
|
||||||
const [id] = newSelection;
|
const [id] = newSelection;
|
||||||
return () => this.mediaDevices.audioOutput.select(id);
|
return {
|
||||||
},
|
targetOutput: newSelectionType,
|
||||||
);
|
switch: () => this.mediaDevices.audioOutput.select(id),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
public readonly reactions$ = this.reactionsSubject$.pipe(
|
public readonly reactions$ = this.reactionsSubject$.pipe(
|
||||||
map((v) =>
|
map((v) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user