2015-11-26 16:38:56 +00:00
|
|
|
/*
|
2016-01-07 04:06:39 +00:00
|
|
|
Copyright 2015, 2016 OpenMarket Ltd
|
2015-11-26 16:38:56 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2017-07-01 13:58:46 +00:00
|
|
|
import React from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
2017-10-25 17:17:33 +00:00
|
|
|
import classNames from 'classnames';
|
2015-11-26 16:38:56 +00:00
|
|
|
|
2017-07-01 13:58:46 +00:00
|
|
|
import sdk from '../../../index';
|
|
|
|
import dis from '../../../dispatcher';
|
2015-11-26 16:38:56 +00:00
|
|
|
|
2017-10-25 17:17:33 +00:00
|
|
|
import UserSettingsStore from '../../../UserSettingsStore';
|
|
|
|
|
2015-11-26 16:38:56 +00:00
|
|
|
module.exports = React.createClass({
|
|
|
|
displayName: 'VideoView',
|
|
|
|
|
2016-02-23 15:46:27 +00:00
|
|
|
propTypes: {
|
|
|
|
// maxHeight style attribute for the video element
|
|
|
|
maxHeight: React.PropTypes.number,
|
|
|
|
|
|
|
|
// a callback which is called when the user clicks on the video div
|
|
|
|
onClick: React.PropTypes.func,
|
|
|
|
|
|
|
|
// a callback which is called when the video element is resized due to
|
|
|
|
// a change in video metadata
|
|
|
|
onResize: React.PropTypes.func,
|
|
|
|
},
|
|
|
|
|
2016-01-06 15:17:58 +00:00
|
|
|
componentDidMount: function() {
|
|
|
|
this.dispatcherRef = dis.register(this.onAction);
|
|
|
|
},
|
|
|
|
|
|
|
|
componentWillUnmount: function() {
|
|
|
|
dis.unregister(this.dispatcherRef);
|
2015-11-26 16:38:56 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
getRemoteVideoElement: function() {
|
|
|
|
return ReactDOM.findDOMNode(this.refs.remote);
|
|
|
|
},
|
|
|
|
|
|
|
|
getRemoteAudioElement: function() {
|
2016-08-31 20:50:46 +00:00
|
|
|
// this needs to be somewhere at the top of the DOM which
|
|
|
|
// always exists to avoid audio interruptions.
|
|
|
|
// Might as well just use DOM.
|
2017-07-01 13:58:46 +00:00
|
|
|
const remoteAudioElement = document.getElementById("remoteAudio");
|
2016-09-01 12:58:26 +00:00
|
|
|
if (!remoteAudioElement) {
|
2017-07-01 13:58:46 +00:00
|
|
|
console.error("Failed to find remoteAudio element - cannot play audio!"
|
|
|
|
+ "You need to add an <audio/> to the DOM.");
|
2016-09-01 12:58:26 +00:00
|
|
|
}
|
|
|
|
return remoteAudioElement;
|
2015-11-26 16:38:56 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
getLocalVideoElement: function() {
|
|
|
|
return ReactDOM.findDOMNode(this.refs.local);
|
|
|
|
},
|
|
|
|
|
|
|
|
setContainer: function(c) {
|
|
|
|
this.container = c;
|
|
|
|
},
|
|
|
|
|
|
|
|
onAction: function(payload) {
|
|
|
|
switch (payload.action) {
|
2017-07-01 13:58:46 +00:00
|
|
|
case 'video_fullscreen': {
|
2015-11-26 16:38:56 +00:00
|
|
|
if (!this.container) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-01 13:58:46 +00:00
|
|
|
const element = this.container;
|
2015-11-26 16:38:56 +00:00
|
|
|
if (payload.fullscreen) {
|
2017-07-01 13:58:46 +00:00
|
|
|
const requestMethod = (
|
2015-11-26 16:38:56 +00:00
|
|
|
element.requestFullScreen ||
|
|
|
|
element.webkitRequestFullScreen ||
|
|
|
|
element.mozRequestFullScreen ||
|
|
|
|
element.msRequestFullscreen
|
|
|
|
);
|
|
|
|
requestMethod.call(element);
|
2017-07-01 13:58:46 +00:00
|
|
|
} else {
|
|
|
|
const exitMethod = (
|
2015-11-26 16:38:56 +00:00
|
|
|
document.exitFullscreen ||
|
|
|
|
document.mozCancelFullScreen ||
|
|
|
|
document.webkitExitFullscreen ||
|
|
|
|
document.msExitFullscreen
|
|
|
|
);
|
|
|
|
if (exitMethod) {
|
|
|
|
exitMethod.call(document);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-07-01 13:58:46 +00:00
|
|
|
}
|
2015-11-26 16:38:56 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2017-07-01 13:58:46 +00:00
|
|
|
const VideoFeed = sdk.getComponent('voip.VideoFeed');
|
2016-02-23 15:46:27 +00:00
|
|
|
|
|
|
|
// if we're fullscreen, we don't want to set a maxHeight on the video element.
|
2017-07-01 13:58:46 +00:00
|
|
|
const fullscreenElement = (document.fullscreenElement ||
|
2016-02-23 15:46:27 +00:00
|
|
|
document.mozFullScreenElement ||
|
|
|
|
document.webkitFullscreenElement);
|
2017-07-01 13:58:46 +00:00
|
|
|
const maxVideoHeight = fullscreenElement ? null : this.props.maxHeight;
|
2017-10-25 17:17:33 +00:00
|
|
|
const localVideoFeedClasses = classNames("mx_VideoView_localVideoFeed",
|
|
|
|
{"mx_VideoView_localVideoFeed_flipped": UserSettingsStore.getSyncedSetting}
|
|
|
|
);
|
2015-11-26 16:38:56 +00:00
|
|
|
return (
|
2017-09-28 10:21:06 +00:00
|
|
|
<div className="mx_VideoView" ref={this.setContainer} onClick={this.props.onClick}>
|
2015-11-26 16:38:56 +00:00
|
|
|
<div className="mx_VideoView_remoteVideoFeed">
|
2016-02-23 15:46:27 +00:00
|
|
|
<VideoFeed ref="remote" onResize={this.props.onResize}
|
|
|
|
maxHeight={maxVideoHeight} />
|
2015-11-26 16:38:56 +00:00
|
|
|
</div>
|
2017-10-25 17:17:33 +00:00
|
|
|
<div className={localVideoFeedClasses}>
|
2017-09-28 10:21:06 +00:00
|
|
|
<VideoFeed ref="local" />
|
2015-11-26 16:38:56 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2017-07-01 13:58:46 +00:00
|
|
|
},
|
2015-11-26 16:38:56 +00:00
|
|
|
});
|