From 151a9994bae48b7f0d2988221cc46809fdf673d0 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 24 Mar 2016 00:13:32 +0000 Subject: [PATCH 1/5] WIP fix for image load popping --- src/components/structures/MessagePanel.js | 15 +++----- src/components/structures/RoomView.js | 6 +++- src/components/structures/ScrollPanel.js | 12 ++++++- src/components/views/messages/MImageBody.js | 39 ++++++++++++++++----- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 66e2daddd5..b67ed5fd4b 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -16,6 +16,7 @@ limitations under the License. var React = require('react'); var ReactDOM = require("react-dom"); +var dis = require("../../dispatcher"); var sdk = require('../../index'); /* (almost) stateless UI component which builds the event tiles in the room timeline. @@ -301,8 +302,7 @@ module.exports = React.createClass({ ref={this._collectEventNode.bind(this, eventId)} data-scroll-token={scrollToken}> + last={last} isSelectedEvent={highlight} /> ); @@ -368,14 +368,8 @@ module.exports = React.createClass({ this.eventNodes[eventId] = node; }, - - // once images in the events load, make the scrollPanel check the - // scroll offsets. - _onImageLoad: function() { - var scrollPanel = this.refs.scrollPanel; - if (scrollPanel) { - scrollPanel.checkScroll(); - } + onResize: function() { + dis.dispatch({ action: 'timeline_resize' }); }, render: function() { @@ -392,6 +386,7 @@ module.exports = React.createClass({ return ( diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3f4a666c56..ca347b99f6 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -485,6 +485,10 @@ module.exports = React.createClass({ } }, + onSearchResultsResize: function() { + dis.dispatch({ action: 'timeline_resize' }); + }, + onSearchResultsFillRequest: function(backwards) { if (!backwards) return q(false); @@ -1361,7 +1365,7 @@ module.exports = React.createClass({ if (this.state.searchResults) { searchResultsPanel = ( + onFillRequest={ this.onSearchResultsFillRequest } onResize={ this.onSearchResultsResize }>
  • {this.getSearchResultTiles()}
    diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 874078456e..bea870818f 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -94,6 +94,11 @@ module.exports = React.createClass({ */ onScroll: React.PropTypes.func, + /* onResize: a callback which is called whenever the Gemini scroll + * panel is resized + */ + onResize: React.PropTypes.func, + /* className: classnames to add to the top-level div */ className: React.PropTypes.string, @@ -181,6 +186,11 @@ module.exports = React.createClass({ this.checkFillState(); }, + onResize: function() { + this.props.onResize(); + this.checkScroll(); + }, + // after an update to the contents of the panel, check that the scroll is // where it ought to be, and set off pagination requests if necessary. checkScroll: function() { @@ -481,7 +491,7 @@ module.exports = React.createClass({ // reflect the fact that we don't necessarily contain a list of messages. // it's not obvious why we have a separate div and ol anyway. return (
      diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index b60098295a..6e46bf01e4 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -105,24 +105,45 @@ module.exports = React.createClass({ return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600); }, + componentDidMount: function() { + this.dispatcherRef = dis.register(this.onAction); + this.fixupHeight(); + }, + + componentWillUnmount: function() { + dis.unregister(this.dispatcherRef); + }, + + onAction: function(payload) { + if (payload.action === "timeline_resize") { + this.fixupHeight(); + } + }, + + fixupHeight: function() { + var content = this.props.mxEvent.getContent(); + + var thumbHeight = null; + var timelineWidth = this._body.offsetWidth; + var maxHeight = 600*timelineWidth/800; + + //console.log("trying to fit image into timelineWidth of " + this._body.offsetWidth + " or " + this._body.clientWidth); + if (content.info) thumbHeight = this.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); + this._image.style.height = thumbHeight + "px"; + }, + render: function() { var TintableSvg = sdk.getComponent("elements.TintableSvg"); var content = this.props.mxEvent.getContent(); var cli = MatrixClientPeg.get(); - var thumbHeight = null; - if (content.info) thumbHeight = this.thumbHeight(content.info.w, content.info.h, 800, 600); - - var imgStyle = {}; - if (thumbHeight) imgStyle['maxHeight'] = thumbHeight; - var thumbUrl = this._getThumbUrl(); if (thumbUrl) { return ( - + this._body = c}> - {content.body} this._image = c} + alt={content.body} onMouseEnter={this.onImageEnter} onMouseLeave={this.onImageLeave} onLoad={this.props.onImageLoad} /> From 5bd0303ddaaca017bcfa75b944ead103080f2587 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 24 Mar 2016 01:12:51 +0000 Subject: [PATCH 2/5] make it work, seemingly --- src/components/structures/MessagePanel.js | 2 +- src/components/structures/ScrollPanel.js | 1 + src/components/views/messages/MImageBody.js | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index b67ed5fd4b..aaa00934cb 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -369,7 +369,7 @@ module.exports = React.createClass({ }, onResize: function() { - dis.dispatch({ action: 'timeline_resize' }); + dis.dispatch({ action: 'timeline_resize' }, true); }, render: function() { diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index bea870818f..ddec81c107 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -189,6 +189,7 @@ module.exports = React.createClass({ onResize: function() { this.props.onResize(); this.checkScroll(); + this.refs.geminiPanel.forceUpdate(); }, // after an update to the contents of the panel, check that the scroll is diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 6e46bf01e4..04559ce4fe 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -125,7 +125,8 @@ module.exports = React.createClass({ var thumbHeight = null; var timelineWidth = this._body.offsetWidth; - var maxHeight = 600*timelineWidth/800; + var maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px. + // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box //console.log("trying to fit image into timelineWidth of " + this._body.offsetWidth + " or " + this._body.clientWidth); if (content.info) thumbHeight = this.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); From 8b67a1059d1a40b3286fed17ebdbb3e8d327de94 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Thu, 24 Mar 2016 02:14:16 +0000 Subject: [PATCH 3/5] oops, forgot a sync dispatch on onSearchResultsResize --- src/components/structures/RoomView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index ca347b99f6..1c1b0ede40 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -486,7 +486,7 @@ module.exports = React.createClass({ }, onSearchResultsResize: function() { - dis.dispatch({ action: 'timeline_resize' }); + dis.dispatch({ action: 'timeline_resize' }, true); }, onSearchResultsFillRequest: function(backwards) { From c227b2279b367185a34eea772df364f68e263a08 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 24 Mar 2016 16:58:27 +0000 Subject: [PATCH 4/5] Minor fixes to image sizing * use string refs instead of callback funcs * Add a null-guard in case we don't have an image --- src/components/views/messages/MImageBody.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 04559ce4fe..02ccfbd107 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -121,16 +121,21 @@ module.exports = React.createClass({ }, fixupHeight: function() { + if (!this.refs.image) { + return; + } + var content = this.props.mxEvent.getContent(); var thumbHeight = null; - var timelineWidth = this._body.offsetWidth; + var timelineWidth = this.refs.body.offsetWidth; var maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px. // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box - //console.log("trying to fit image into timelineWidth of " + this._body.offsetWidth + " or " + this._body.clientWidth); + //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); if (content.info) thumbHeight = this.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); - this._image.style.height = thumbHeight + "px"; + this.refs.image.style.height = thumbHeight + "px"; + console.log("Imageheight now", thumbHeight); }, render: function() { @@ -141,9 +146,9 @@ module.exports = React.createClass({ var thumbUrl = this._getThumbUrl(); if (thumbUrl) { return ( - this._body = c}> + - this._image = c} + {content.body} Date: Tue, 29 Mar 2016 00:46:51 +0100 Subject: [PATCH 5/5] Add warning if fixupHeight fails, and remove overzealous logging --- src/components/views/messages/MImageBody.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js index 02ccfbd107..ff05cf8609 100644 --- a/src/components/views/messages/MImageBody.js +++ b/src/components/views/messages/MImageBody.js @@ -122,6 +122,7 @@ module.exports = React.createClass({ fixupHeight: function() { if (!this.refs.image) { + console.warn("Refusing to fix up height on MImageBody with no image element"); return; } @@ -135,7 +136,7 @@ module.exports = React.createClass({ //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth); if (content.info) thumbHeight = this.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight); this.refs.image.style.height = thumbHeight + "px"; - console.log("Imageheight now", thumbHeight); + // console.log("Image height now", thumbHeight); }, render: function() {