You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpeakerEntry.js 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // @flow
  2. import React, { Component } from 'react';
  3. import AudioSettingsEntry from './AudioSettingsEntry';
  4. import logger from '../../../logger';
  5. import TestButton from './TestButton';
  6. const TEST_SOUND_PATH = 'sounds/ring.wav';
  7. /**
  8. * The type of the React {@code Component} props of {@link SpeakerEntry}.
  9. */
  10. type Props = {
  11. /**
  12. * The text label for the entry.
  13. */
  14. children: React$Node,
  15. /**
  16. * Flag controlling the selection state of the entry.
  17. */
  18. isSelected: boolean,
  19. /**
  20. * The deviceId of the speaker.
  21. */
  22. deviceId: string,
  23. /**
  24. * Click handler for the component.
  25. */
  26. onClick: Function,
  27. };
  28. /**
  29. * Implements a React {@link Component} which displays an audio
  30. * output settings entry. The user can click and play a test sound.
  31. *
  32. * @extends Component
  33. */
  34. export default class SpeakerEntry extends Component<Props> {
  35. /**
  36. * A React ref to the HTML element containing the {@code audio} instance.
  37. */
  38. audioRef: Object;
  39. /**
  40. * Initializes a new {@code SpeakerEntry} instance.
  41. *
  42. * @param {Object} props - The read-only properties with which the new
  43. * instance is to be initialized.
  44. */
  45. constructor(props: Props) {
  46. super(props);
  47. this.audioRef = React.createRef();
  48. this._onTestButtonClick = this._onTestButtonClick.bind(this);
  49. this._onClick = this._onClick.bind(this);
  50. }
  51. _onClick: () => void;
  52. /**
  53. * Click handler for the entry.
  54. *
  55. * @returns {void}
  56. */
  57. _onClick() {
  58. this.props.onClick(this.props.deviceId);
  59. }
  60. _onTestButtonClick: Object => void;
  61. /**
  62. * Click handler for Test button.
  63. * Sets the current audio output id and plays a sound.
  64. *
  65. * @param {Object} e - The sythetic event.
  66. * @returns {void}
  67. */
  68. async _onTestButtonClick(e) {
  69. e.stopPropagation();
  70. try {
  71. await this.audioRef.current.setSinkId(this.props.deviceId);
  72. this.audioRef.current.play();
  73. } catch (err) {
  74. logger.log('Could not set sink id', err);
  75. }
  76. }
  77. /**
  78. * Implements React's {@link Component#render}.
  79. *
  80. * @inheritdoc
  81. */
  82. render() {
  83. const { children, isSelected, deviceId } = this.props;
  84. return (
  85. <div
  86. className = 'audio-preview-speaker'
  87. onClick = { this._onClick }>
  88. <AudioSettingsEntry
  89. isSelected = { isSelected }
  90. key = { deviceId }>
  91. {children}
  92. </AudioSettingsEntry>
  93. <TestButton onClick = { this._onTestButtonClick } />
  94. <audio
  95. preload = 'auto'
  96. ref = { this.audioRef }
  97. src = { TEST_SOUND_PATH } />
  98. </div>
  99. );
  100. }
  101. }