diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 26c2c6a1bc..c622a7d769 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1064,17 +1064,23 @@ module.exports = React.createClass({ // a maxHeight on the underlying remote video tag. var auxPanelMaxHeight; if (this.refs.callView) { - // XXX: don't understand why we have to call findDOMNode here in react 0.14 - it should already be a DOM node. - var video = ReactDOM.findDOMNode(this.refs.callView.refs.video.refs.remote); + var video = this.refs.callView.getVideoView().getRemoteVideoElement(); // header + footer + status + give us at least 100px of scrollback at all times. - auxPanelMaxHeight = window.innerHeight - (83 + 72 + 36 + 100); + auxPanelMaxHeight = window.innerHeight - + (83 + 72 + + sdk.getComponent('rooms.MessageComposer').MAX_HEIGHT + + 100); // XXX: this is a bit of a hack and might possibly cause the video to push out the page anyway // but it's better than the video going missing entirely if (auxPanelMaxHeight < 50) auxPanelMaxHeight = 50; video.style.maxHeight = auxPanelMaxHeight + "px"; + + // the above might have made the video panel resize itself, so now + // we need to tell the gemini panel to adapt. + this.onChildResize(); } }, @@ -1109,6 +1115,15 @@ module.exports = React.createClass({ }); }, + onChildResize: function() { + // When the video or the message composer resizes, the scroll panel + // also changes size. Work around GeminiScrollBar fail by telling it + // about it. This also ensures that the scroll offset is updated. + if (this.refs.messagePanel) { + this.refs.messagePanel.forceUpdate(); + } + }, + render: function() { var RoomHeader = sdk.getComponent('rooms.RoomHeader'); var MessageComposer = sdk.getComponent('rooms.MessageComposer'); @@ -1299,7 +1314,7 @@ module.exports = React.createClass({ if (canSpeak) { messageComposer = } @@ -1402,7 +1417,8 @@ module.exports = React.createClass({ } /> { fileDropTarget }
- + { conferenceCallNotification } { aux }
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 083cee46a2..f2894bd6b3 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -65,8 +65,17 @@ function mdownToHtml(mdown) { module.exports = React.createClass({ displayName: 'MessageComposer', + statics: { + // the height we limit the composer to + MAX_HEIGHT: 100, + }, + propTypes: { - tabComplete: React.PropTypes.any + tabComplete: React.PropTypes.any, + + // a callback which is called when the height of the composer is + // changed due to a change in content. + onResize: React.PropTypes.function, }, componentWillMount: function() { @@ -237,13 +246,15 @@ module.exports = React.createClass({ // scrollHeight is at least equal to clientHeight, so we have to // temporarily crimp clientHeight to 0 to get an accurate scrollHeight value this.refs.textarea.style.height = "0px"; - var newHeight = this.refs.textarea.scrollHeight < 100 ? this.refs.textarea.scrollHeight : 100; + var newHeight = Math.min(this.refs.textarea.scrollHeight, + this.constructor.MAX_HEIGHT); this.refs.textarea.style.height = Math.ceil(newHeight) + "px"; - if (this.props.roomView) { - // kick gemini-scrollbar to re-layout - this.props.roomView.forceUpdate(); - } this.oldScrollHeight = this.refs.textarea.scrollHeight; + + if (this.props.onResize) { + // kick gemini-scrollbar to re-layout + this.props.onResize(); + } }, onKeyUp: function(ev) { diff --git a/src/components/views/voip/CallView.js b/src/components/views/voip/CallView.js index bc82556163..98bad37467 100644 --- a/src/components/views/voip/CallView.js +++ b/src/components/views/voip/CallView.js @@ -33,6 +33,12 @@ var MatrixClientPeg = require("../../../MatrixClientPeg"); 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 + onResize: React.PropTypes.function, + }, + componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); if (this.props.room) { @@ -97,7 +103,7 @@ 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 e4833dba9f..88d1b50cce 100644 --- a/src/components/views/voip/VideoFeed.js +++ b/src/components/views/voip/VideoFeed.js @@ -21,9 +21,29 @@ var React = require('react'); module.exports = React.createClass({ displayName: 'VideoFeed', + propTypes: { + // a callback which is called when the video element is resized + // due to a change in video metadata + onResize: React.PropTypes.function, + }, + + componentDidMount() { + this.refs.vid.addEventListener('resize', this.onResize); + }, + + componentWillUnmount() { + this.refs.vid.removeEventListener('resize', this.onResize); + }, + + onResize: function(e) { + if(this.props.onResize) { + this.props.onResize(e); + } + }, + render: function() { return ( -