Merge pull request #850 from t3chguy/webrtc_settings
webrtc config electron
This commit is contained in:
commit
ec433907f0
4 changed files with 200 additions and 0 deletions
|
@ -22,6 +22,7 @@ import UserSettingsStore from '../../UserSettingsStore';
|
|||
import KeyCode from '../../KeyCode';
|
||||
import Notifier from '../../Notifier';
|
||||
import PageTypes from '../../PageTypes';
|
||||
import CallMediaHandler from '../../CallMediaHandler';
|
||||
import sdk from '../../index';
|
||||
import dis from '../../dispatcher';
|
||||
|
||||
|
@ -79,6 +80,8 @@ export default React.createClass({
|
|||
// RoomView.getScrollState()
|
||||
this._scrollStateMap = {};
|
||||
|
||||
CallMediaHandler.loadDevices();
|
||||
|
||||
document.addEventListener('keydown', this._onKeyDown);
|
||||
this._matrixClient.on("accountData", this.onAccountData);
|
||||
},
|
||||
|
|
|
@ -24,6 +24,7 @@ const dis = require("../../dispatcher");
|
|||
const q = require('q');
|
||||
const packageJson = require('../../../package.json');
|
||||
const UserSettingsStore = require('../../UserSettingsStore');
|
||||
const CallMediaHandler = require('../../CallMediaHandler');
|
||||
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
const Email = require('../../email');
|
||||
const AddThreepid = require('../../AddThreepid');
|
||||
|
@ -176,6 +177,7 @@ module.exports = React.createClass({
|
|||
email_add_pending: false,
|
||||
vectorVersion: undefined,
|
||||
rejectingInvites: false,
|
||||
mediaDevices: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -196,6 +198,8 @@ module.exports = React.createClass({
|
|||
});
|
||||
}
|
||||
|
||||
this._refreshMediaDevices();
|
||||
|
||||
// Bulk rejecting invites:
|
||||
// /sync won't have had time to return when UserSettings re-renders from state changes, so getRooms()
|
||||
// will still return rooms with invites. To get around this, add a listener for
|
||||
|
@ -257,6 +261,20 @@ module.exports = React.createClass({
|
|||
this.setState({ electron_settings: settings });
|
||||
},
|
||||
|
||||
_refreshMediaDevices: function() {
|
||||
q().then(() => {
|
||||
return CallMediaHandler.getDevices();
|
||||
}).then((mediaDevices) => {
|
||||
// console.log("got mediaDevices", mediaDevices, this._unmounted);
|
||||
if (this._unmounted) return;
|
||||
this.setState({
|
||||
mediaDevices,
|
||||
activeAudioInput: this._localSettings['webrtc_audioinput'],
|
||||
activeVideoInput: this._localSettings['webrtc_videoinput'],
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_refreshFromServer: function() {
|
||||
const self = this;
|
||||
q.all([
|
||||
|
@ -883,6 +901,110 @@ module.exports = React.createClass({
|
|||
</div>;
|
||||
},
|
||||
|
||||
_mapWebRtcDevicesToSpans: function(devices) {
|
||||
return devices.map((device) => <span key={device.deviceId}>{device.label}</span>);
|
||||
},
|
||||
|
||||
_setAudioInput: function(deviceId) {
|
||||
this.setState({activeAudioInput: deviceId});
|
||||
CallMediaHandler.setAudioInput(deviceId);
|
||||
},
|
||||
|
||||
_setVideoInput: function(deviceId) {
|
||||
this.setState({activeVideoInput: deviceId});
|
||||
CallMediaHandler.setVideoInput(deviceId);
|
||||
},
|
||||
|
||||
_requestMediaPermissions: function(event) {
|
||||
const getUserMedia = (
|
||||
window.navigator.getUserMedia || window.navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia
|
||||
);
|
||||
if (getUserMedia) {
|
||||
return getUserMedia.apply(window.navigator, [
|
||||
{ video: true, audio: true },
|
||||
this._refreshMediaDevices,
|
||||
function() {
|
||||
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t('No media permissions'),
|
||||
description: _t('You may need to manually permit Riot to access your microphone/webcam'),
|
||||
});
|
||||
},
|
||||
]);
|
||||
}
|
||||
},
|
||||
|
||||
_renderWebRtcSettings: function() {
|
||||
if (this.state.mediaDevices === false) {
|
||||
return <div>
|
||||
<h3>{_t('VoIP')}</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
<p className="mx_UserSettings_link" onClick={this._requestMediaPermissions}>
|
||||
{_t('Missing Media Permissions, click here to request.')}
|
||||
</p>
|
||||
</div>
|
||||
</div>;
|
||||
} else if (!this.state.mediaDevices) return;
|
||||
|
||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||
|
||||
let microphoneDropdown = <p>{_t('No Microphones detected')}</p>;
|
||||
let webcamDropdown = <p>{_t('No Webcams detected')}</p>;
|
||||
|
||||
const defaultOption = {
|
||||
deviceId: '',
|
||||
label: _t('Default Device'),
|
||||
};
|
||||
|
||||
const audioInputs = this.state.mediaDevices.audioinput.slice(0);
|
||||
if (audioInputs.length > 0) {
|
||||
let defaultInput = '';
|
||||
if (!audioInputs.some((input) => input.deviceId === 'default')) {
|
||||
audioInputs.unshift(defaultOption);
|
||||
} else {
|
||||
defaultInput = 'default';
|
||||
}
|
||||
|
||||
microphoneDropdown = <div>
|
||||
<h4>{_t('Microphone')}</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeAudioInput || defaultInput}
|
||||
onOptionChange={this._setAudioInput}>
|
||||
{this._mapWebRtcDevicesToSpans(audioInputs)}
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
||||
const videoInputs = this.state.mediaDevices.videoinput.slice(0);
|
||||
if (videoInputs.length > 0) {
|
||||
let defaultInput = '';
|
||||
if (!videoInputs.some((input) => input.deviceId === 'default')) {
|
||||
videoInputs.unshift(defaultOption);
|
||||
} else {
|
||||
defaultInput = 'default';
|
||||
}
|
||||
|
||||
webcamDropdown = <div>
|
||||
<h4>{_t('Camera')}</h4>
|
||||
<Dropdown
|
||||
className="mx_UserSettings_webRtcDevices_dropdown"
|
||||
value={this.state.activeVideoInput || defaultInput}
|
||||
onOptionChange={this._setVideoInput}>
|
||||
{this._mapWebRtcDevicesToSpans(videoInputs)}
|
||||
</Dropdown>
|
||||
</div>;
|
||||
}
|
||||
|
||||
return <div>
|
||||
<h3>{_t('VoIP')}</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
{microphoneDropdown}
|
||||
{webcamDropdown}
|
||||
</div>
|
||||
</div>;
|
||||
},
|
||||
|
||||
_showSpoiler: function(event) {
|
||||
const target = event.target;
|
||||
target.innerHTML = target.getAttribute('data-spoiler');
|
||||
|
@ -1080,6 +1202,7 @@ module.exports = React.createClass({
|
|||
|
||||
{this._renderUserInterfaceSettings()}
|
||||
{this._renderLabs()}
|
||||
{this._renderWebRtcSettings()}
|
||||
{this._renderDevicesPanel()}
|
||||
{this._renderCryptoInfo()}
|
||||
{this._renderBulkOptions()}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue