diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 5fe2aae471..5383cf15dc 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -631,9 +631,11 @@ module.exports = React.createClass({ } }, - _scrollDownIfAtBottom: function() { + _onTypingVisible: function() { const scrollPanel = this.refs.scrollPanel; - if (scrollPanel) { + if (scrollPanel && scrollPanel.getScrollState().stuckAtBottom) { + scrollPanel.blockShrinking(); + // scroll down if at bottom scrollPanel.checkScroll(); } }, @@ -666,7 +668,7 @@ module.exports = React.createClass({ let whoIsTyping; if (this.props.room) { - whoIsTyping = (); + whoIsTyping = (); } return ( diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index 0fdbc9a349..91a9f1ddfa 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -223,6 +223,8 @@ module.exports = React.createClass({ onResize: function() { this.props.onResize(); + // clear min-height as the height might have changed + this.clearBlockShrinking(); this.checkScroll(); if (this._gemScroll) this._gemScroll.forceUpdate(); }, @@ -372,6 +374,8 @@ module.exports = React.createClass({ } this._unfillDebouncer = setTimeout(() => { this._unfillDebouncer = null; + // if timeline shrinks, min-height should be cleared + this.clearBlockShrinking(); this.props.onUnfillRequest(backwards, markerScrollToken); }, UNFILL_REQUEST_DEBOUNCE_MS); } @@ -677,6 +681,27 @@ module.exports = React.createClass({ _collectGeminiScroll: function(gemScroll) { this._gemScroll = gemScroll; }, + /** + * Set the current height as the min height for the message list + * so the timeline cannot shrink. This is used to avoid + * jumping when the typing indicator gets replaced by a smaller message. + */ + blockShrinking: function() { + const messageList = this.refs.itemlist; + if (messageList) { + const currentHeight = messageList.clientHeight - 18; + messageList.style.minHeight = `${currentHeight}px`; + } + }, + /** + * Clear the previously set min height + */ + clearBlockShrinking: function() { + const messageList = this.refs.itemlist; + if (messageList) { + messageList.style.minHeight = null; + } + }, render: function() { const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");