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");