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 ( -