export default function DeviceSwitcher()

in src/components/DeviceSwitcher.tsx [15:152]


export default function DeviceSwitcher() {
  const chime: ChimeSdkWrapper | null = useContext(getChimeContext());
  const translate = useTranslate();
  const deviceSwitcherState = useDevices();
  const video = useRef<HTMLVideoElement>(null);

  // eslint-disable-next-line prettier/prettier
  const changed = (selected: DeviceType, existing: DeviceType | undefined | null): boolean =>
    (!existing || selected.value !== existing.value);

  useEffect(() => {
    if (
      video.current &&
      chime?.deviceController &&
      chime?.currentVideoInputDevice
    ) {
      // If this finishes too late, it will happen after our cleanup, and
      // we will have a spurious video indicator. The SDK should return a promise.
      chime.deviceController?.startVideoPreviewForVideoInput(video.current!);
    }
  }, [deviceSwitcherState, video]);

  useEffect(() => {
    return () => {
      if (!chime) {
        return;
      }

      const videoElement = video.current;
      const deviceController = chime.deviceController;

      if (videoElement && deviceController) {
        console.log('Stopping video preview.');
        deviceController.stopVideoPreviewForVideoInput(videoElement);
      }
    };
  }, []);

  return (
    <div className={cx('deviceContainer')}>
      <div className={cx('deviceList')}>
        <div className={cx('form-label')}>
          {translate('DressingRoom.inputAudioLabel')}
        </div>
        <Dropdown
          className={cx('dropdown')}
          controlClassName={cx('control')}
          placeholderClassName={cx('placeholder')}
          menuClassName={cx('menu')}
          arrowClassName={cx('arrow')}
          value={deviceSwitcherState.currentAudioInputDevice || undefined}
          options={
            deviceSwitcherState.audioInputDevices || ([] as DeviceType[])
          }
          disabled={
            !deviceSwitcherState.audioInputDevices ||
            !deviceSwitcherState.audioInputDevices.length
          }
          onChange={async (selectedDevice: DeviceType) => {
            // eslint-disable-next-line prettier/prettier
            if (changed(selectedDevice, deviceSwitcherState.currentAudioInputDevice)) {
              await chime?.chooseAudioInputDevice(selectedDevice);
            }
          }}
          placeholder={
            deviceSwitcherState.currentAudioInputDevice
              ? translate('DeviceSwitcher.noAudioInputPlaceholder')
              : ''
          }
        />

        <div className={cx('form-label')}>
          {translate('DressingRoom.ouputAudioLabel')}
        </div>
        <Dropdown
          className={cx('dropdown')}
          controlClassName={cx('control')}
          placeholderClassName={cx('placeholder')}
          menuClassName={cx('menu')}
          arrowClassName={cx('arrow')}
          value={deviceSwitcherState.currentAudioOutputDevice || undefined}
          options={
            deviceSwitcherState.audioOutputDevices || ([] as DeviceType[])
          }
          disabled={
            !deviceSwitcherState.audioOutputDevices ||
            !deviceSwitcherState.audioOutputDevices.length
          }
          onChange={async (selectedDevice: DeviceType) => {
            // eslint-disable-next-line prettier/prettier
            if (!chime?.browserBehavior.supportsSetSinkId()) {
              return;
            }

            if (changed(selectedDevice, deviceSwitcherState.currentAudioOutputDevice)) {
              await chime?.chooseAudioOutputDevice(selectedDevice);
            }
          }}
          placeholder={
            deviceSwitcherState.currentAudioOutputDevice
              ? translate('DeviceSwitcher.noAudioOutputPlaceholder')
              : ''
          }
        />
        <div className={cx('form-label')}>
          {translate('DressingRoom.inputVideoLabel')}
        </div>
        <Dropdown
          className={cx('dropdown')}
          controlClassName={cx('control')}
          placeholderClassName={cx('placeholder')}
          menuClassName={cx('menu')}
          arrowClassName={cx('arrow')}
          value={deviceSwitcherState.currentVideoInputDevice || undefined}
          options={
            deviceSwitcherState.videoInputDevices || ([] as DeviceType[])
          }
          disabled={
            !deviceSwitcherState.videoInputDevices ||
            !deviceSwitcherState.videoInputDevices.length
          }
          onChange={async (selectedDevice: DeviceType) => {
            // eslint-disable-next-line prettier/prettier
            if (changed(selectedDevice, deviceSwitcherState.currentVideoInputDevice)) {
              await chime?.chooseVideoInputDevice(selectedDevice);
            }
          }}
          placeholder={
            deviceSwitcherState.currentVideoInputDevice
              ? translate('DeviceSwitcher.noVideoInputPlaceholder')
              : ''
          }
        />
      </div>
      <video className={cx('videoPreview')} ref={video}></video>
    </div>
  );
}