ref(device-selection): set audio output sink id after receiving ref (#4066)

The Audio.js setRef callback does not behave like react ref callback
in that the former will not have fired before componentDidMount
but the later will have. So for audio output preview, trying to set
sink id on mount will no-op because it does not have a ref yet to
Audio.js, possibly leading to audio output previews playing on
the default speaker device. This generally has not been a user
visible problem due to coincidence; other re-renders necessary
by the parent of audio output preview will have triggered
componentDidUpdates on the audio out preview, which would then
set the sink id on the Audio.js ref it should have received
by then.
This commit is contained in:
virtuacoplenny 2019-04-08 10:38:06 -07:00 committed by GitHub
parent e7812c7d84
commit 7a677ead93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 29 deletions

View File

@ -42,19 +42,8 @@ class AudioOutputPreview extends Component<Props> {
this._audioElement = null;
this._audioElementReady = this._audioElementReady.bind(this);
this._onClick = this._onClick.bind(this);
this._setAudioElement = this._setAudioElement.bind(this);
}
/**
* Sets the target output device on the component's audio element after
* initial render.
*
* @inheritdoc
* @returns {void}
*/
componentDidMount() {
this._setAudioSink();
}
/**
@ -81,12 +70,28 @@ class AudioOutputPreview extends Component<Props> {
{ this.props.t('deviceSelection.testAudio') }
</a>
<Audio
setRef = { this._setAudioElement }
setRef = { this._audioElementReady }
src = { TEST_SOUND_PATH } />
</div>
);
}
_audioElementReady: (Object) => void;
/**
* Sets the instance variable for the component's audio element so it can be
* accessed directly.
*
* @param {Object} element - The DOM element for the component's audio.
* @private
* @returns {void}
*/
_audioElementReady(element: Object) {
this._audioElement = element;
this._setAudioSink();
}
_onClick: () => void;
/**
@ -97,21 +102,7 @@ class AudioOutputPreview extends Component<Props> {
*/
_onClick() {
this._audioElement
&& this._audioElement.play();
}
_setAudioElement: (Object) => void;
/**
* Sets the instance variable for the component's audio element so it can be
* accessed directly.
*
* @param {Object} element - The DOM element for the component's audio.
* @private
* @returns {void}
*/
_setAudioElement(element: Object) {
this._audioElement = element;
&& this._audioElement.play();
}
/**
@ -122,7 +113,7 @@ class AudioOutputPreview extends Component<Props> {
*/
_setAudioSink() {
this._audioElement
&& this._audioElement.setSinkId(this.props.deviceId);
&& this._audioElement.setSinkId(this.props.deviceId);
}
}