Skip to content

Commit 9f84a5c

Browse files
committed
Deprecate old naming and introduce new words
1 parent 4eb8674 commit 9f84a5c

File tree

6 files changed

+50
-23
lines changed

6 files changed

+50
-23
lines changed

docs/controls.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ A few aspects of Element Call's interface can be controlled through a global API
1010

1111
## Audio output devices
1212

13-
These functions must be used in conjunction with the `controlledMediaDevices` URL parameter in order to have any effect.
13+
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.
1414

15-
- `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.
15+
- `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.
1616
It flags the device that should be used if the user selects earpiece mode. This should be the main stereo loudspeaker of the device.
17-
- `controls.onOutputDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output.
18-
- `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.
19-
- `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.
20-
- `showNativeOutputDevicePicker: (() => void) | undefined`. Callback called whenever the user presses the output button in the settings menu.
17+
- `controls.onAudioDeviceSelect: ((id: string) => void) | undefined` Callback called whenever the user or application selects a new audio output.
18+
- `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.
19+
- `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.
20+
- `showNativeAudioDevicePicker: (() => void) | undefined`. Callback called whenever the user presses the output button in the settings menu.
2121
This button is only shown on iOS. (`userAgent.includes("iPhone")`)

src/controls.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ export interface Controls {
1111
canEnterPip(): boolean;
1212
enablePip(): void;
1313
disablePip(): void;
14+
/** @deprecated use setAvailableAudioDevices instead*/
1415
setAvailableOutputDevices(devices: OutputDevice[]): void;
16+
setAvailableAudioDevices(devices: OutputDevice[]): void;
17+
/** @deprecated use setAudioDevice instead*/
1518
setOutputDevice(id: string): void;
19+
setAudioDevice(id: string): void;
20+
/** @deprecated use onAudioDeviceSelect instead*/
1621
onOutputDeviceSelect?: (id: string) => void;
22+
onAudioDeviceSelect?: (id: string) => void;
23+
/** @deprecated use setAudioEnabled instead*/
1724
setOutputEnabled(enabled: boolean): void;
25+
setAudioEnabled(enabled: boolean): void;
26+
/** @deprecated use showNativeAudioDevicePicker instead*/
1827
showNativeOutputDevicePicker?: () => void;
28+
showNativeAudioDevicePicker?: () => void;
1929
}
2030

2131
export interface OutputDevice {
@@ -43,7 +53,7 @@ export const outputDevice$ = new BehaviorSubject<string | undefined>(undefined);
4353
*
4454
* This should also be used to display a darkened overlay screen letting the user know that audio is muted.
4555
*/
46-
export const setOutputEnabled$ = new Subject<boolean>();
56+
export const setAudioEnabled$ = new Subject<boolean>();
4757

4858
window.controls = {
4959
canEnterPip(): boolean {
@@ -57,17 +67,28 @@ window.controls = {
5767
if (!setPipEnabled$.observed) throw new Error("No call is running");
5868
setPipEnabled$.next(false);
5969
},
60-
setAvailableOutputDevices(devices: OutputDevice[]): void {
70+
setAvailableAudioDevices(devices: OutputDevice[]): void {
6171
availableOutputDevices$.next(devices);
6272
},
63-
setOutputDevice(id: string): void {
73+
setAudioDevice(id: string): void {
6474
outputDevice$.next(id);
6575
},
66-
setOutputEnabled(enabled: boolean): void {
67-
if (!setOutputEnabled$.observed)
76+
setAudioEnabled(enabled: boolean): void {
77+
if (!setAudioEnabled$.observed)
6878
throw new Error(
69-
"Output controls are disabled. No setOutputEnabled$ observer",
79+
"Output controls are disabled. No setAudioEnabled$ observer",
7080
);
71-
setOutputEnabled$.next(enabled);
81+
setAudioEnabled$.next(enabled);
82+
},
83+
84+
// wrappers for the deprecated controls fields
85+
setOutputEnabled(enabled: boolean): void {
86+
this.setAudioEnabled(enabled);
87+
},
88+
setAvailableOutputDevices(devices: OutputDevice[]): void {
89+
this.setAvailableAudioDevices(devices);
90+
},
91+
setOutputDevice(id: string): void {
92+
this.setAudioDevice(id);
7293
},
7394
};

src/livekit/MediaDevicesContext.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,11 @@ function useControlledOutput(): MediaDeviceHandle {
367367
// This information is probably only of interest if the earpiece mode has been
368368
// selected - for example, Element X iOS listens to this to determine whether it
369369
// should enable the proximity sensor.
370-
if (selectedId) window.controls.onOutputDeviceSelect?.(selectedId);
370+
if (selectedId) {
371+
window.controls.onAudioDeviceSelect?.(selectedId);
372+
// Call deprecated method for backwards compatibility.
373+
window.controls.onOutputDeviceSelect?.(selectedId);
374+
}
371375
setAsEarpiece(selectedId === EARPIECE_CONFIG_ID);
372376
}, [selectedId]);
373377

src/settings/SettingsModal.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export const SettingsModal: FC<Props> = ({
133133
<Button
134134
onClick={(e): void => {
135135
e.preventDefault();
136+
window.controls.showNativeAudioDevicePicker?.();
137+
// call deprecated method for backwards compatibility.
136138
window.controls.showNativeOutputDevicePicker?.();
137139
}}
138140
>

src/state/MuteAllAudioModel.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Please see LICENSE in the repository root for full details.
88
import { test, vi } from "vitest";
99
import { expect } from "vitest";
1010

11-
import { setOutputEnabled$ } from "../controls";
11+
import { setAudioEnabled$ } from "../controls";
1212
import { muteAllAudio as muteAllAudioSetting } from "../settings/settings";
1313
import { muteAllAudio$ } from "./MuteAllAudioModel";
1414

@@ -18,19 +18,19 @@ test("muteAllAudio$", () => {
1818
valueMock(value);
1919
});
2020

21-
setOutputEnabled$.next(false);
22-
setOutputEnabled$.next(true);
21+
setAudioEnabled$.next(false);
22+
setAudioEnabled$.next(true);
2323
muteAllAudioSetting.setValue(false);
2424
muteAllAudioSetting.setValue(true);
25-
setOutputEnabled$.next(false);
25+
setAudioEnabled$.next(false);
2626

2727
muteAllAudio.unsubscribe();
2828

2929
expect(valueMock).toHaveBeenCalledTimes(6);
3030
expect(valueMock).toHaveBeenNthCalledWith(1, false); // startWith([false, muteAllAudioSetting.getValue()]);
31-
expect(valueMock).toHaveBeenNthCalledWith(2, true); // setOutputEnabled$.next(false);
32-
expect(valueMock).toHaveBeenNthCalledWith(3, false); // setOutputEnabled$.next(true);
31+
expect(valueMock).toHaveBeenNthCalledWith(2, true); // setAudioEnabled$.next(false);
32+
expect(valueMock).toHaveBeenNthCalledWith(3, false); // setAudioEnabled$.next(true);
3333
expect(valueMock).toHaveBeenNthCalledWith(4, false); // muteAllAudioSetting.setValue(false);
3434
expect(valueMock).toHaveBeenNthCalledWith(5, true); // muteAllAudioSetting.setValue(true);
35-
expect(valueMock).toHaveBeenNthCalledWith(6, true); // setOutputEnabled$.next(false);
35+
expect(valueMock).toHaveBeenNthCalledWith(6, true); // setAudioEnabled$.next(false);
3636
});

src/state/MuteAllAudioModel.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ Please see LICENSE in the repository root for full details.
77

88
import { combineLatest, startWith } from "rxjs";
99

10-
import { setOutputEnabled$ } from "../controls";
10+
import { setAudioEnabled$ } from "../controls";
1111
import { muteAllAudio as muteAllAudioSetting } from "../settings/settings";
1212

1313
/**
1414
* This can transition into sth more complete: `GroupCallViewModel.ts`
1515
*/
1616
export const muteAllAudio$ = combineLatest(
17-
[setOutputEnabled$.pipe(startWith(true)), muteAllAudioSetting.value$],
17+
[setAudioEnabled$.pipe(startWith(true)), muteAllAudioSetting.value$],
1818
(outputEnabled, settingsMute) => !outputEnabled || settingsMute,
1919
);

0 commit comments

Comments
 (0)