diff --git a/src/component-index.js b/src/component-index.js
index 5a37a98913..3399ac9157 100644
--- a/src/component-index.js
+++ b/src/component-index.js
@@ -70,6 +70,7 @@ module.exports.components['views.messages.TextualEvent'] = require('./components
module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody');
module.exports.components['views.room_settings.AliasSettings'] = require('./components/views/room_settings/AliasSettings');
module.exports.components['views.room_settings.ColorSettings'] = require('./components/views/room_settings/ColorSettings');
+module.exports.components['views.rooms.AuxPanel'] = require('./components/views/rooms/AuxPanel');
module.exports.components['views.rooms.EntityTile'] = require('./components/views/rooms/EntityTile');
module.exports.components['views.rooms.EventTile'] = require('./components/views/rooms/EventTile');
module.exports.components['views.rooms.InviteMemberList'] = require('./components/views/rooms/InviteMemberList');
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 856ab955a4..48a94c6adf 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -15,7 +15,6 @@ limitations under the License.
*/
// TODO: This component is enormous! There's several things which could stand-alone:
-// - Aux component
// - Search results component
// - Drag and drop
// - File uploading - uploadFile()
@@ -106,6 +105,8 @@ module.exports = React.createClass({
// the end of the live timeline. It has the effect of hiding the
// 'scroll to bottom' knob, among a couple of other things.
atEndOfLiveTimeline: true,
+
+ auxPanelMaxHeight: undefined,
}
},
@@ -1294,14 +1295,6 @@ module.exports = React.createClass({
});
},
- onConferenceNotificationClick: function() {
- dis.dispatch({
- action: 'place_call',
- type: "video",
- room_id: this.props.roomId
- });
- },
-
// jump down to the bottom of this room, where new events are arriving
jumpToLiveTimeline: function() {
// if we can't forward-paginate the existing timeline, then there
@@ -1386,25 +1379,10 @@ module.exports = React.createClass({
// but it's better than the video going missing entirely
if (auxPanelMaxHeight < 50) auxPanelMaxHeight = 50;
- if (this.refs.callView) {
- var fullscreenElement =
- (document.fullscreenElement ||
- document.mozFullScreenElement ||
- document.webkitFullscreenElement);
- if (!fullscreenElement) {
- var video = this.refs.callView.getVideoView().getRemoteVideoElement();
- video.style.maxHeight = auxPanelMaxHeight + "px";
- }
- }
-
- // we need to do this for general auxPanels too
- if (this.refs.auxPanel) {
- this.refs.auxPanel.style.maxHeight = auxPanelMaxHeight + "px";
- }
-
- // the above might have made the aux panel resize itself, so now
- // we need to tell the gemini panel to adapt.
- this.onChildResize();
+ // we may need to resize the gemini panel after changing the aux panel
+ // size, so add a callback to onChildResize.
+ this.setState({auxPanelMaxHeight: auxPanelMaxHeight},
+ this.onChildResize);
},
onFullscreenClick: function() {
@@ -1438,11 +1416,6 @@ module.exports = React.createClass({
});
},
- onCallViewResize: function() {
- this.onChildResize();
- this.onResize();
- },
-
onChildResize: function() {
// When the video or the message composer resizes, the scroll panel
// also changes size. Work around GeminiScrollBar fail by telling it
@@ -1464,8 +1437,8 @@ module.exports = React.createClass({
render: function() {
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
var MessageComposer = sdk.getComponent('rooms.MessageComposer');
- var CallView = sdk.getComponent("voip.CallView");
var RoomSettings = sdk.getComponent("rooms.RoomSettings");
+ var AuxPanel = sdk.getComponent("rooms.AuxPanel");
var SearchBar = sdk.getComponent("rooms.SearchBar");
var ScrollPanel = sdk.getComponent("structures.ScrollPanel");
var TintableSvg = sdk.getComponent("elements.TintableSvg");
@@ -1607,28 +1580,16 @@ module.exports = React.createClass({
);
}
- var conferenceCallNotification = null;
- if (this.state.displayConfCallNotification) {
- var supportedText;
- if (!MatrixClientPeg.get().supportsVoip()) {
- supportedText = " (unsupported)";
- }
- conferenceCallNotification = (
-
- Ongoing conference call {supportedText}
-
- );
- }
-
- var fileDropTarget = null;
- if (this.state.draggingFile) {
- fileDropTarget =
-
-
- Drop file here to upload
-
-
;
- }
+ var auxPanel = (
+
+ { aux }
+
+ );
var messageComposer, searchInfo;
var canSpeak = (
@@ -1759,13 +1720,7 @@ module.exports = React.createClass({
onLeaveClick={
(myMember && myMember.membership === "join") ? this.onLeaveClick : null
} />
-
- { fileDropTarget }
-
- { conferenceCallNotification }
- { aux }
-
+ { auxPanel }
{ messagePanel }
{ searchResultsPanel }
diff --git a/src/components/views/rooms/AuxPanel.js b/src/components/views/rooms/AuxPanel.js
new file mode 100644
index 0000000000..49c7dfc6e5
--- /dev/null
+++ b/src/components/views/rooms/AuxPanel.js
@@ -0,0 +1,104 @@
+/*
+Copyright 2015, 2016 OpenMarket Ltd
+
+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.
+*/
+
+var React = require('react');
+var MatrixClientPeg = require("../../../MatrixClientPeg");
+var sdk = require('../../../index');
+var dis = require("../../../dispatcher");
+
+module.exports = React.createClass({
+ displayName: 'AuxPanel',
+
+ propTypes: {
+ // js-sdk room object
+ room: React.PropTypes.object.isRequired,
+
+ // Conference Handler implementation
+ conferenceHandler: React.PropTypes.object,
+
+ // set to true to show the file drop target
+ draggingFile: React.PropTypes.bool,
+
+ // set to true to show the 'active conf call' banner
+ displayConfCallNotification: React.PropTypes.bool,
+
+ // maxHeight attribute for the aux panel and the video
+ // therein
+ maxHeight: React.PropTypes.number,
+
+ // a callback which is called when the video element in a voip call is
+ // resized due to a change in video metadata
+ onCallViewVideoResize: React.PropTypes.func,
+ },
+
+ onConferenceNotificationClick: function() {
+ dis.dispatch({
+ action: 'place_call',
+ type: "video",
+ room_id: this.props.room.roomId,
+ });
+ },
+
+ render: function() {
+ var CallView = sdk.getComponent("voip.CallView");
+ var TintableSvg = sdk.getComponent("elements.TintableSvg");
+
+ var fileDropTarget = null;
+ if (this.props.draggingFile) {
+ fileDropTarget = (
+
+
+
+
+ Drop file here to upload
+
+
+ );
+ }
+
+ var conferenceCallNotification = null;
+ if (this.props.displayConfCallNotification) {
+ var supportedText;
+ if (!MatrixClientPeg.get().supportsVoip()) {
+ supportedText = " (unsupported)";
+ }
+ conferenceCallNotification = (
+
+ Ongoing conference call {supportedText}
+
+ );
+ }
+
+ var callView = (
+
+ );
+
+ return (
+
+ { fileDropTarget }
+ { callView }
+ { conferenceCallNotification }
+ { this.props.children }
+
+ );
+ },
+});
diff --git a/src/components/views/voip/CallView.js b/src/components/views/voip/CallView.js
index 5958c2b278..13abcb7f9d 100644
--- a/src/components/views/voip/CallView.js
+++ b/src/components/views/voip/CallView.js
@@ -19,38 +19,32 @@ var CallHandler = require("../../../CallHandler");
var sdk = require('../../../index');
var MatrixClientPeg = require("../../../MatrixClientPeg");
-/*
- * State vars:
- * this.state.call = MatrixCall|null
- *
- * Props:
- * this.props.room = Room (JS SDK)
- * this.props.ConferenceHandler = A Conference Handler implementation
- * Must have a function signature:
- * getConferenceCallForRoom(roomId: string): MatrixCall
- */
-
module.exports = React.createClass({
displayName: 'CallView',
propTypes: {
- // a callback which is called when the video within the callview
- // due to a change in video metadata
+ // js-sdk room object
+ room: React.PropTypes.object.isRequired,
+
+ // A Conference Handler implementation
+ // Must have a function signature:
+ // getConferenceCallForRoom(roomId: string): MatrixCall
+ ConferenceHandler: React.PropTypes.object,
+
+ // maxHeight style attribute for the video panel
+ maxVideoHeight: 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 within the callview is
+ // resized due to a change in video metadata
onResize: React.PropTypes.func,
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
- if (this.props.room) {
- this.showCall(this.props.room.roomId);
- }
- else {
- // XXX: why would we ever not have a this.props.room?
- var call = CallHandler.getAnyActiveCall();
- if (call) {
- this.showCall(call.roomId);
- }
- }
+ this.showCall(this.props.room.roomId);
},
componentWillUnmount: function() {
@@ -103,7 +97,10 @@ module.exports = React.createClass({
render: function(){
var VideoView = sdk.getComponent('voip.VideoView');
return (
-
+
);
}
});
diff --git a/src/components/views/voip/VideoFeed.js b/src/components/views/voip/VideoFeed.js
index c4a65d1145..0b8d0b20fc 100644
--- a/src/components/views/voip/VideoFeed.js
+++ b/src/components/views/voip/VideoFeed.js
@@ -22,6 +22,9 @@ module.exports = React.createClass({
displayName: 'VideoFeed',
propTypes: {
+ // maxHeight style attribute for the video element
+ maxHeight: React.PropTypes.number,
+
// a callback which is called when the video element is resized
// due to a change in video metadata
onResize: React.PropTypes.func,
@@ -43,7 +46,7 @@ module.exports = React.createClass({
render: function() {
return (
-