Files
jitsi-meet/react/features/web-hid/middleware.ts
Hristo Terezov 2514617417 fix: Make all middleware functions sync.
Some middleware functions are declared as async. This wraps next(action) in Promise which will delay the execution of actions and also dispatch will return the its result always as a Promise.
2024-07-25 07:17:16 -05:00

146 lines
4.1 KiB
TypeScript

import { IStore } from '../app/types';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
import { getWebHIDFeatureConfig } from '../base/config/functions.web';
import { SET_AUDIO_MUTED } from '../base/media/actionTypes';
import { isAudioMuted } from '../base/media/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { CLOSE_HID_DEVICE, REQUEST_HID_DEVICE } from './actionTypes';
import { initDeviceInfo } from './actions';
import {
attachHidEventListeners,
getWebHidInstance,
handleUpdateHidDevice,
isDeviceHidSupported,
removeHidEventListeners
} from './functions';
import logger from './logger';
import { COMMANDS, IDeviceInfo } from './types';
/**
* A listener for initialising the webhid device.
*/
let initDeviceListener: (e: any) => void;
/**
* A listener for updating the webhid device.
*/
let updateDeviceListener: (e: any) => void;
/**
* The redux middleware for {@link WebHid}.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register((store: IStore) => next => action => {
const { dispatch, getState } = store;
if (!getWebHIDFeatureConfig(getState())) {
return next(action);
}
switch (action.type) {
case APP_WILL_MOUNT: {
const hidManager = getWebHidInstance();
if (!hidManager.isSupported()) {
logger.warn('HID is not supported');
break;
}
const _initDeviceListener = (e: CustomEvent<{ deviceInfo: IDeviceInfo; }>) =>
dispatch(initDeviceInfo(e.detail.deviceInfo));
const _updateDeviceListener
= (e: CustomEvent<{ actionResult: { eventName: string; }; deviceInfo: IDeviceInfo; }>) =>
handleUpdateHidDevice(dispatch, e);
initDeviceListener = _initDeviceListener;
updateDeviceListener = _updateDeviceListener;
hidManager.listenToConnectedHid();
attachHidEventListeners(initDeviceListener, updateDeviceListener);
break;
}
case APP_WILL_UNMOUNT: {
const hidManager = getWebHidInstance();
if (!isDeviceHidSupported()) {
break;
}
removeHidEventListeners(initDeviceListener, updateDeviceListener);
hidManager.close();
break;
}
case CLOSE_HID_DEVICE: {
const hidManager = getWebHidInstance();
// cleanup event handlers when hid device is removed from Settings.
removeHidEventListeners(initDeviceListener, updateDeviceListener);
hidManager.close();
break;
}
case REQUEST_HID_DEVICE: {
_onRequestHIDDevice(store);
break;
}
case SET_AUDIO_MUTED: {
const hidManager = getWebHidInstance();
if (!isDeviceHidSupported()) {
break;
}
hidManager.sendDeviceReport({ command: action.muted ? COMMANDS.MUTE_ON : COMMANDS.MUTE_OFF });
break;
}
}
return next(action);
});
/**
* Handles HID device requests.
*
* @param {IStore} store - The redux store.
* @returns {Promise}
*/
async function _onRequestHIDDevice(store: IStore) {
const { dispatch } = store;
const hidManager = getWebHidInstance();
const availableDevices = await hidManager.requestHidDevices();
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
if (!availableDevices || !availableDevices.length) {
logger.info('HID device not available');
return;
}
const _initDeviceListener = (e: CustomEvent<{ deviceInfo: IDeviceInfo; }>) =>
dispatch(initDeviceInfo(e.detail.deviceInfo));
const _updateDeviceListener
= (e: CustomEvent<{ actionResult: { eventName: string; }; deviceInfo: IDeviceInfo; }>) => {
handleUpdateHidDevice(dispatch, e);
};
initDeviceListener = _initDeviceListener;
updateDeviceListener = _updateDeviceListener;
attachHidEventListeners(initDeviceListener, updateDeviceListener);
await hidManager.listenToConnectedHid();
// sync headset to mute if participant is already muted.
if (isAudioMuted(store.getState())) {
hidManager.sendDeviceReport({ command: COMMANDS.MUTE_ON });
}
}