mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-04 05:37:22 +00:00
Deprecate old naming and introduce new words
This commit is contained in:
@@ -10,12 +10,12 @@ A few aspects of Element Call's interface can be controlled through a global API
|
||||
|
||||
## Audio output devices
|
||||
|
||||
These functions must be used in conjunction with the `controlledMediaDevices` URL parameter in order to have any effect.
|
||||
On mobile platforms (iOS, Android), web views do not reliably support selecting audio output devices such as the main speaker, earpiece, or headset. To address this limitation, the following functions allow the hosting application (e.g., Element Web, Element X) to manage audio devices via exposed JavaScript interfaces. These functions must be enabled using the URL parameter `controlledAudioDevices` to take effect.
|
||||
|
||||
- `controls.setAvailableOutputDevices(devices: { id: string, name: string, forEarpiece?: boolean, isEarpiece?: boolean isSpeaker?: boolean, isExternalHeadset?, boolean; }[]): void` Sets the list of available audio outputs. `forEarpiece` is used on iOS only.
|
||||
- `controls.setAvailableAudioDevices(devices: { id: string, name: string, forEarpiece?: boolean, isEarpiece?: boolean isSpeaker?: boolean, isExternalHeadset?, boolean; }[]): void` Sets the list of available audio outputs. `forEarpiece` is used on iOS only.
|
||||
It flags the device that should be used if the user selects earpiece mode. This should be the main stereo loudspeaker of the device.
|
||||
- `controls.onOutputDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output.
|
||||
- `controls.setOutputDevice(id: string): void` Sets the selected audio device in Element Call's menu. This should be used if the OS decides to automatically switch to Bluetooth, for example.
|
||||
- `controls.setOutputEnabled(enabled: boolean)` Enables/disables all audio output from the application. This can be useful for temporarily pausing audio while the controlling application is switching output devices. Output is enabled by default.
|
||||
- `showNativeOutputDevicePicker: (() => void) | undefined`. Callback called whenever the user presses the output button in the settings menu.
|
||||
- `controls.onAudioDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output.
|
||||
- `controls.setAudioDevice(id: string): void` Sets the selected audio device in Element Call's menu. This should be used if the OS decides to automatically switch to Bluetooth, for example.
|
||||
- `controls.setAudioEnabled(enabled: boolean)` Enables/disables all audio output from the application. This can be useful for temporarily pausing audio while the controlling application is switching output devices. Output is enabled by default.
|
||||
- `showNativeAudioDevicePicker: (() => void) | undefined`. Callback called whenever the user presses the output button in the settings menu.
|
||||
This button is only shown on iOS. (`userAgent.includes("iPhone")`)
|
||||
|
||||
@@ -11,11 +11,21 @@ export interface Controls {
|
||||
canEnterPip(): boolean;
|
||||
enablePip(): void;
|
||||
disablePip(): void;
|
||||
/** @deprecated use setAvailableAudioDevices instead*/
|
||||
setAvailableOutputDevices(devices: OutputDevice[]): void;
|
||||
setAvailableAudioDevices(devices: OutputDevice[]): void;
|
||||
/** @deprecated use setAudioDevice instead*/
|
||||
setOutputDevice(id: string): void;
|
||||
setAudioDevice(id: string): void;
|
||||
/** @deprecated use onAudioDeviceSelect instead*/
|
||||
onOutputDeviceSelect?: (id: string) => void;
|
||||
onAudioDeviceSelect?: (id: string) => void;
|
||||
/** @deprecated use setAudioEnabled instead*/
|
||||
setOutputEnabled(enabled: boolean): void;
|
||||
setAudioEnabled(enabled: boolean): void;
|
||||
/** @deprecated use showNativeAudioDevicePicker instead*/
|
||||
showNativeOutputDevicePicker?: () => void;
|
||||
showNativeAudioDevicePicker?: () => void;
|
||||
}
|
||||
|
||||
export interface OutputDevice {
|
||||
@@ -43,7 +53,7 @@ export const outputDevice$ = new BehaviorSubject<string | undefined>(undefined);
|
||||
*
|
||||
* This should also be used to display a darkened overlay screen letting the user know that audio is muted.
|
||||
*/
|
||||
export const setOutputEnabled$ = new Subject<boolean>();
|
||||
export const setAudioEnabled$ = new Subject<boolean>();
|
||||
|
||||
window.controls = {
|
||||
canEnterPip(): boolean {
|
||||
@@ -57,17 +67,28 @@ window.controls = {
|
||||
if (!setPipEnabled$.observed) throw new Error("No call is running");
|
||||
setPipEnabled$.next(false);
|
||||
},
|
||||
setAvailableOutputDevices(devices: OutputDevice[]): void {
|
||||
setAvailableAudioDevices(devices: OutputDevice[]): void {
|
||||
availableOutputDevices$.next(devices);
|
||||
},
|
||||
setOutputDevice(id: string): void {
|
||||
setAudioDevice(id: string): void {
|
||||
outputDevice$.next(id);
|
||||
},
|
||||
setOutputEnabled(enabled: boolean): void {
|
||||
if (!setOutputEnabled$.observed)
|
||||
setAudioEnabled(enabled: boolean): void {
|
||||
if (!setAudioEnabled$.observed)
|
||||
throw new Error(
|
||||
"Output controls are disabled. No setOutputEnabled$ observer",
|
||||
"Output controls are disabled. No setAudioEnabled$ observer",
|
||||
);
|
||||
setOutputEnabled$.next(enabled);
|
||||
setAudioEnabled$.next(enabled);
|
||||
},
|
||||
|
||||
// wrappers for the deprecated controls fields
|
||||
setOutputEnabled(enabled: boolean): void {
|
||||
this.setAudioEnabled(enabled);
|
||||
},
|
||||
setAvailableOutputDevices(devices: OutputDevice[]): void {
|
||||
this.setAvailableAudioDevices(devices);
|
||||
},
|
||||
setOutputDevice(id: string): void {
|
||||
this.setAudioDevice(id);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -367,7 +367,11 @@ function useControlledOutput(): MediaDeviceHandle {
|
||||
// This information is probably only of interest if the earpiece mode has been
|
||||
// selected - for example, Element X iOS listens to this to determine whether it
|
||||
// should enable the proximity sensor.
|
||||
if (selectedId) window.controls.onOutputDeviceSelect?.(selectedId);
|
||||
if (selectedId) {
|
||||
window.controls.onAudioDeviceSelect?.(selectedId);
|
||||
// Call deprecated method for backwards compatibility.
|
||||
window.controls.onOutputDeviceSelect?.(selectedId);
|
||||
}
|
||||
setAsEarpiece(selectedId === EARPIECE_CONFIG_ID);
|
||||
}, [selectedId]);
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ export const SettingsModal: FC<Props> = ({
|
||||
<Button
|
||||
onClick={(e): void => {
|
||||
e.preventDefault();
|
||||
window.controls.showNativeAudioDevicePicker?.();
|
||||
// call deprecated method for backwards compatibility.
|
||||
window.controls.showNativeOutputDevicePicker?.();
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -8,7 +8,7 @@ Please see LICENSE in the repository root for full details.
|
||||
import { test, vi } from "vitest";
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { setOutputEnabled$ } from "../controls";
|
||||
import { setAudioEnabled$ } from "../controls";
|
||||
import { muteAllAudio as muteAllAudioSetting } from "../settings/settings";
|
||||
import { muteAllAudio$ } from "./MuteAllAudioModel";
|
||||
|
||||
@@ -18,19 +18,19 @@ test("muteAllAudio$", () => {
|
||||
valueMock(value);
|
||||
});
|
||||
|
||||
setOutputEnabled$.next(false);
|
||||
setOutputEnabled$.next(true);
|
||||
setAudioEnabled$.next(false);
|
||||
setAudioEnabled$.next(true);
|
||||
muteAllAudioSetting.setValue(false);
|
||||
muteAllAudioSetting.setValue(true);
|
||||
setOutputEnabled$.next(false);
|
||||
setAudioEnabled$.next(false);
|
||||
|
||||
muteAllAudio.unsubscribe();
|
||||
|
||||
expect(valueMock).toHaveBeenCalledTimes(6);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(1, false); // startWith([false, muteAllAudioSetting.getValue()]);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(2, true); // setOutputEnabled$.next(false);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(3, false); // setOutputEnabled$.next(true);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(2, true); // setAudioEnabled$.next(false);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(3, false); // setAudioEnabled$.next(true);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(4, false); // muteAllAudioSetting.setValue(false);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(5, true); // muteAllAudioSetting.setValue(true);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(6, true); // setOutputEnabled$.next(false);
|
||||
expect(valueMock).toHaveBeenNthCalledWith(6, true); // setAudioEnabled$.next(false);
|
||||
});
|
||||
|
||||
@@ -7,13 +7,13 @@ Please see LICENSE in the repository root for full details.
|
||||
|
||||
import { combineLatest, startWith } from "rxjs";
|
||||
|
||||
import { setOutputEnabled$ } from "../controls";
|
||||
import { setAudioEnabled$ } from "../controls";
|
||||
import { muteAllAudio as muteAllAudioSetting } from "../settings/settings";
|
||||
|
||||
/**
|
||||
* This can transition into sth more complete: `GroupCallViewModel.ts`
|
||||
*/
|
||||
export const muteAllAudio$ = combineLatest(
|
||||
[setOutputEnabled$.pipe(startWith(true)), muteAllAudioSetting.value$],
|
||||
[setAudioEnabled$.pipe(startWith(true)), muteAllAudioSetting.value$],
|
||||
(outputEnabled, settingsMute) => !outputEnabled || settingsMute,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user