mirror of
https://github.com/vector-im/element-call.git
synced 2026-03-19 06:20:25 +00:00
selectedId == PreferredId for controlled output
This skips the usage of the useSelectedId hook that only really makes sense for non controlled audio. Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
@@ -44,10 +44,14 @@ export interface OutputDevice {
|
||||
export const setPipEnabled$ = new Subject<boolean>();
|
||||
// BehaviorSubject since the client might set this before we have subscribed (GroupCallView still in "loading" state)
|
||||
// We want the devices that have been set during loading to be available immediately once loaded.
|
||||
export const availableOutputDevices$ = new BehaviorSubject<OutputDevice[]>([]);
|
||||
export const controlledAvailableOutputDevices$ = new BehaviorSubject<
|
||||
OutputDevice[]
|
||||
>([]);
|
||||
// BehaviorSubject since the client might set this before we have subscribed (GroupCallView still in "loading" state)
|
||||
// We want the device that has been set during loading to be available immediately once loaded.
|
||||
export const outputDevice$ = new BehaviorSubject<string | undefined>(undefined);
|
||||
export const controlledAudioDevice$ = new BehaviorSubject<string | undefined>(
|
||||
undefined,
|
||||
);
|
||||
/**
|
||||
* This allows the os to mute the call if the user
|
||||
* presses the volume down button when it is at the minimum volume.
|
||||
@@ -75,10 +79,10 @@ window.controls = {
|
||||
setPipEnabled$.next(false);
|
||||
},
|
||||
setAvailableAudioDevices(devices: OutputDevice[]): void {
|
||||
availableOutputDevices$.next(devices);
|
||||
controlledAvailableOutputDevices$.next(devices);
|
||||
},
|
||||
setAudioDevice(id: string): void {
|
||||
outputDevice$.next(id);
|
||||
controlledAudioDevice$.next(id);
|
||||
},
|
||||
setAudioEnabled(enabled: boolean): void {
|
||||
if (!setAudioEnabled$.observed)
|
||||
|
||||
@@ -34,7 +34,10 @@ import {
|
||||
alwaysShowIphoneEarpiece as alwaysShowIphoneEarpieceSetting,
|
||||
type Setting,
|
||||
} from "../settings/settings";
|
||||
import { outputDevice$, availableOutputDevices$ } from "../controls";
|
||||
import {
|
||||
controlledAudioDevice$,
|
||||
controlledAvailableOutputDevices$,
|
||||
} from "../controls";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
|
||||
// This hardcoded id is used in EX ios! It can only be changed in coordination with
|
||||
@@ -331,9 +334,9 @@ export const MediaDevicesProvider: FC<Props> = ({ children }) => {
|
||||
function useControlledOutput(): MediaDeviceHandle {
|
||||
const { available } = useObservableEagerState(
|
||||
useObservable(() => {
|
||||
const outputDeviceData$ = availableOutputDevices$.pipe(
|
||||
const outputDeviceData$ = controlledAvailableOutputDevices$.pipe(
|
||||
map((devices) => {
|
||||
const deviceForEarpiece = devices.find((d) => d.forEarpiece);
|
||||
const hasDeviceForEarpiece = devices.find((d) => d.forEarpiece);
|
||||
const deviceMapTuple: [string, DeviceLabel][] = devices.map(
|
||||
({ id, name, isEarpiece, isSpeaker /*,isExternalHeadset*/ }) => {
|
||||
let deviceLabel: DeviceLabel = { type: "name", name };
|
||||
@@ -345,22 +348,22 @@ function useControlledOutput(): MediaDeviceHandle {
|
||||
);
|
||||
return {
|
||||
devicesMap: new Map<string, DeviceLabel>(deviceMapTuple),
|
||||
deviceForEarpiece,
|
||||
hasDeviceForEarpiece,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return combineLatest(
|
||||
[outputDeviceData$, iosDeviceMenu$],
|
||||
({ devicesMap, deviceForEarpiece }, iosShowEarpiece) => {
|
||||
({ devicesMap, hasDeviceForEarpiece }, iosShowEarpiece) => {
|
||||
let available = devicesMap;
|
||||
if (iosShowEarpiece && !!deviceForEarpiece) {
|
||||
if (iosShowEarpiece && !!hasDeviceForEarpiece) {
|
||||
available = new Map([
|
||||
...devicesMap.entries(),
|
||||
[EARPIECE_CONFIG_ID, { type: "earpiece" }],
|
||||
]);
|
||||
}
|
||||
return { available, deviceForEarpiece };
|
||||
return { available, deviceForEarpiece: hasDeviceForEarpiece };
|
||||
},
|
||||
);
|
||||
}),
|
||||
@@ -368,11 +371,11 @@ function useControlledOutput(): MediaDeviceHandle {
|
||||
|
||||
const [preferredId, setPreferredId] = useSetting(audioOutputSetting);
|
||||
|
||||
useSubscription(outputDevice$, (id) => {
|
||||
useSubscription(controlledAudioDevice$, (id) => {
|
||||
if (id) setPreferredId(id);
|
||||
});
|
||||
|
||||
const selectedId = useSelectedId(available, preferredId);
|
||||
// const selectedId = useSelectedId(available, preferredId);
|
||||
|
||||
const [asEarpiece, setAsEarpiece] = useState(false);
|
||||
|
||||
@@ -381,23 +384,23 @@ 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.onAudioDeviceSelect?.(selectedId);
|
||||
if (preferredId) {
|
||||
window.controls.onAudioDeviceSelect?.(preferredId);
|
||||
// Call deprecated method for backwards compatibility.
|
||||
window.controls.onOutputDeviceSelect?.(selectedId);
|
||||
window.controls.onOutputDeviceSelect?.(preferredId);
|
||||
}
|
||||
setAsEarpiece(selectedId === EARPIECE_CONFIG_ID);
|
||||
}, [selectedId]);
|
||||
setAsEarpiece(preferredId === EARPIECE_CONFIG_ID);
|
||||
}, [preferredId]);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
available: available,
|
||||
selectedId,
|
||||
selectedId: preferredId,
|
||||
selectedGroupId: undefined,
|
||||
select: setPreferredId,
|
||||
useAsEarpiece: asEarpiece,
|
||||
}),
|
||||
[available, selectedId, setPreferredId, asEarpiece],
|
||||
[available, preferredId, setPreferredId, asEarpiece],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,10 +99,14 @@ export function useLivekit(
|
||||
},
|
||||
audioCaptureDefaults: {
|
||||
...defaultLiveKitOptions.audioCaptureDefaults,
|
||||
deviceId: initialDevices.audioInput.selectedId,
|
||||
deviceId: controlledAudioDevices
|
||||
? undefined
|
||||
: initialDevices.audioInput.selectedId,
|
||||
},
|
||||
audioOutput: {
|
||||
deviceId: initialDevices.audioOutput.selectedId,
|
||||
deviceId: controlledAudioDevices
|
||||
? undefined
|
||||
: initialDevices.audioOutput.selectedId,
|
||||
},
|
||||
e2ee,
|
||||
};
|
||||
@@ -157,7 +161,7 @@ export function useLivekit(
|
||||
);
|
||||
|
||||
const connectionState = useECConnectionState(
|
||||
initialDevices.audioInput.selectedId,
|
||||
controlledAudioDevices ? undefined : initialDevices.audioInput.selectedId,
|
||||
initialMuteStates.audio.enabled,
|
||||
room,
|
||||
sfuConfig,
|
||||
|
||||
@@ -54,6 +54,7 @@ import {
|
||||
} from "../livekit/TrackProcessorContext";
|
||||
import { usePageTitle } from "../usePageTitle";
|
||||
import { useLatest } from "../useLatest";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
|
||||
interface Props {
|
||||
client: MatrixClient;
|
||||
@@ -99,6 +100,7 @@ export const LobbyView: FC<Props> = ({
|
||||
[muteStates],
|
||||
);
|
||||
|
||||
const { controlledAudioDevices } = useUrlParams();
|
||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||
const [settingsTab, setSettingsTab] = useState(defaultSettingsTab);
|
||||
|
||||
@@ -132,7 +134,11 @@ export const LobbyView: FC<Props> = ({
|
||||
// re-open the devices when they change (see below).
|
||||
const initialAudioOptions = useInitial(
|
||||
() =>
|
||||
muteStates.audio.enabled && { deviceId: devices.audioInput.selectedId },
|
||||
muteStates.audio.enabled && {
|
||||
deviceId: controlledAudioDevices
|
||||
? undefined
|
||||
: devices.audioInput.selectedId,
|
||||
},
|
||||
);
|
||||
|
||||
const { processor } = useTrackProcessor();
|
||||
@@ -148,13 +154,16 @@ export const LobbyView: FC<Props> = ({
|
||||
// which would cause the devices to be re-opened on the next render.
|
||||
audio: Object.assign({}, initialAudioOptions),
|
||||
video: muteStates.video.enabled && {
|
||||
deviceId: devices.videoInput.selectedId,
|
||||
deviceId: controlledAudioDevices
|
||||
? undefined
|
||||
: devices.videoInput.selectedId,
|
||||
processor: initialProcessor,
|
||||
},
|
||||
}),
|
||||
[
|
||||
initialAudioOptions,
|
||||
muteStates.video.enabled,
|
||||
controlledAudioDevices,
|
||||
devices.videoInput.selectedId,
|
||||
initialProcessor,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user