2015-11-26 19:38:56 +03:00
|
|
|
/*
|
2016-01-07 07:06:39 +03:00
|
|
|
Copyright 2015, 2016 OpenMarket Ltd
|
2015-11-26 19:38:56 +03: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.
|
|
|
|
*/
|
|
|
|
|
2019-12-08 15:16:17 +03:00
|
|
|
import React, {createRef} from 'react';
|
2017-07-01 16:58:46 +03:00
|
|
|
import ReactDOM from 'react-dom';
|
2017-12-26 04:03:18 +03:00
|
|
|
import PropTypes from 'prop-types';
|
2019-09-06 20:37:43 +03:00
|
|
|
import createReactClass from 'create-react-class';
|
2017-10-25 20:17:33 +03:00
|
|
|
import classNames from 'classnames';
|
2015-11-26 19:38:56 +03:00
|
|
|
|
2017-07-01 16:58:46 +03:00
|
|
|
import sdk from '../../../index';
|
|
|
|
import dis from '../../../dispatcher';
|
2015-11-26 19:38:56 +03:00
|
|
|
|
2017-10-29 10:43:52 +03:00
|
|
|
import SettingsStore from "../../../settings/SettingsStore";
|
2017-10-25 20:17:33 +03:00
|
|
|
|
2018-09-11 13:31:24 +03:00
|
|
|
function getFullScreenElement() {
|
|
|
|
return (
|
|
|
|
document.fullscreenElement ||
|
|
|
|
document.mozFullScreenElement ||
|
|
|
|
document.webkitFullscreenElement ||
|
|
|
|
document.msFullscreenElement
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-09-06 20:37:43 +03:00
|
|
|
module.exports = createReactClass({
|
2015-11-26 19:38:56 +03:00
|
|
|
displayName: 'VideoView',
|
|
|
|
|
2016-02-23 18:46:27 +03:00
|
|
|
propTypes: {
|
|
|
|
// maxHeight style attribute for the video element
|
2017-12-26 04:03:18 +03:00
|
|
|
maxHeight: PropTypes.number,
|
2016-02-23 18:46:27 +03:00
|
|
|
|
|
|
|
// a callback which is called when the user clicks on the video div
|
2017-12-26 04:03:18 +03:00
|
|
|
onClick: PropTypes.func,
|
2016-02-23 18:46:27 +03:00
|
|
|
|
|
|
|
// a callback which is called when the video element is resized due to
|
|
|
|
// a change in video metadata
|
2017-12-26 04:03:18 +03:00
|
|
|
onResize: PropTypes.func,
|
2016-02-23 18:46:27 +03:00
|
|
|
},
|
|
|
|
|
2019-12-08 15:16:17 +03:00
|
|
|
UNSAFE_componentWillMount: function() {
|
|
|
|
this._local = createRef();
|
|
|
|
this._remote = createRef();
|
|
|
|
},
|
|
|
|
|
2016-01-06 18:17:58 +03:00
|
|
|
componentDidMount: function() {
|
|
|
|
this.dispatcherRef = dis.register(this.onAction);
|
|
|
|
},
|
|
|
|
|
|
|
|
componentWillUnmount: function() {
|
|
|
|
dis.unregister(this.dispatcherRef);
|
2015-11-26 19:38:56 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
getRemoteVideoElement: function() {
|
2019-12-08 15:16:17 +03:00
|
|
|
return ReactDOM.findDOMNode(this._remote.current);
|
2015-11-26 19:38:56 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
getRemoteAudioElement: function() {
|
2016-08-31 23:50:46 +03: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 16:58:46 +03:00
|
|
|
const remoteAudioElement = document.getElementById("remoteAudio");
|
2016-09-01 15:58:26 +03:00
|
|
|
if (!remoteAudioElement) {
|
2017-07-01 16:58:46 +03:00
|
|
|
console.error("Failed to find remoteAudio element - cannot play audio!"
|
|
|
|
+ "You need to add an <audio/> to the DOM.");
|
2016-09-01 15:58:26 +03:00
|
|
|
}
|
|
|
|
return remoteAudioElement;
|
2015-11-26 19:38:56 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
getLocalVideoElement: function() {
|
2019-12-08 15:16:17 +03:00
|
|
|
return ReactDOM.findDOMNode(this._local.current);
|
2015-11-26 19:38:56 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
setContainer: function(c) {
|
|
|
|
this.container = c;
|
|
|
|
},
|
|
|
|
|
|
|
|
onAction: function(payload) {
|
|
|
|
switch (payload.action) {
|
2017-07-01 16:58:46 +03:00
|
|
|
case 'video_fullscreen': {
|
2015-11-26 19:38:56 +03:00
|
|
|
if (!this.container) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-01 16:58:46 +03:00
|
|
|
const element = this.container;
|
2015-11-26 19:38:56 +03:00
|
|
|
if (payload.fullscreen) {
|
2017-07-01 16:58:46 +03:00
|
|
|
const requestMethod = (
|
2015-11-26 19:38:56 +03:00
|
|
|
element.requestFullScreen ||
|
|
|
|
element.webkitRequestFullScreen ||
|
|
|
|
element.mozRequestFullScreen ||
|
|
|
|
element.msRequestFullscreen
|
|
|
|
);
|
|
|
|
requestMethod.call(element);
|
2018-09-11 13:31:24 +03:00
|
|
|
} else if (getFullScreenElement()) {
|
2017-07-01 16:58:46 +03:00
|
|
|
const exitMethod = (
|
2015-11-26 19:38:56 +03:00
|
|
|
document.exitFullscreen ||
|
|
|
|
document.mozCancelFullScreen ||
|
|
|
|
document.webkitExitFullscreen ||
|
|
|
|
document.msExitFullscreen
|
|
|
|
);
|
|
|
|
if (exitMethod) {
|
|
|
|
exitMethod.call(document);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2017-07-01 16:58:46 +03:00
|
|
|
}
|
2015-11-26 19:38:56 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2017-07-01 16:58:46 +03:00
|
|
|
const VideoFeed = sdk.getComponent('voip.VideoFeed');
|
2016-02-23 18:46:27 +03:00
|
|
|
|
|
|
|
// if we're fullscreen, we don't want to set a maxHeight on the video element.
|
2018-09-11 13:31:24 +03:00
|
|
|
const maxVideoHeight = getFullScreenElement() ? null : this.props.maxHeight;
|
2017-10-25 20:17:33 +03:00
|
|
|
const localVideoFeedClasses = classNames("mx_VideoView_localVideoFeed",
|
2017-10-26 11:58:46 +03:00
|
|
|
{ "mx_VideoView_localVideoFeed_flipped":
|
2017-10-29 10:43:52 +03:00
|
|
|
SettingsStore.getValue('VideoView.flipVideoHorizontally'),
|
2017-10-26 11:58:46 +03:00
|
|
|
},
|
2017-10-25 20:17:33 +03:00
|
|
|
);
|
2015-11-26 19:38:56 +03:00
|
|
|
return (
|
2017-09-28 13:21:06 +03:00
|
|
|
<div className="mx_VideoView" ref={this.setContainer} onClick={this.props.onClick}>
|
2015-11-26 19:38:56 +03:00
|
|
|
<div className="mx_VideoView_remoteVideoFeed">
|
2019-12-08 15:16:17 +03:00
|
|
|
<VideoFeed ref={this._remote} onResize={this.props.onResize}
|
2016-02-23 18:46:27 +03:00
|
|
|
maxHeight={maxVideoHeight} />
|
2015-11-26 19:38:56 +03:00
|
|
|
</div>
|
2017-10-25 20:17:33 +03:00
|
|
|
<div className={localVideoFeedClasses}>
|
2019-12-08 15:16:17 +03:00
|
|
|
<VideoFeed ref={this._local} />
|
2015-11-26 19:38:56 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2017-07-01 16:58:46 +03:00
|
|
|
},
|
2015-11-26 19:38:56 +03:00
|
|
|
});
|