diff --git a/static/js/message_list_view.js b/static/js/message_list_view.js index dd6b4816ca..3782233488 100644 --- a/static/js/message_list_view.js +++ b/static/js/message_list_view.js @@ -555,6 +555,12 @@ MessageListView.prototype = { var self = this; + // If we start with the message feed scrolled up (i.e. + // the bottom message is not visible), then we will respect + // the user's current position after rendering, rather + // than auto-scrolling. + var started_scrolled_up = message_viewport.is_scrolled_up(); + // The messages we are being asked to render are shared with between // all messages lists. To prevent having both list views overwriting // each others data we will make a new message object to add data to @@ -742,6 +748,9 @@ MessageListView.prototype = { } if (list === current_msg_list && messages_are_new) { + if (started_scrolled_up) { + return; + } var new_messages_height = self._new_messages_height(new_dom_elements); self._maybe_autoscroll(new_messages_height); } @@ -841,17 +850,6 @@ MessageListView.prototype = { scroll_amount = scroll_limit; } - // Let's work our way back to whether the user was already dealing - // with messages off the screen, in which case we shouldn't autoscroll. - var bottom_last_visible = last_visible.offset().top + last_visible.height(); - var bottom_old_last_visible = bottom_last_visible - new_messages_height; - var bottom_viewport = info.visible_top + info.visible_height; - - // Exit if the user was already past the bottom. - if (bottom_old_last_visible > bottom_viewport) { - return; - } - // Ok, we are finally ready to actually scroll. if (scroll_amount > 0) { message_viewport.system_initiated_animate_scroll(scroll_amount); diff --git a/static/js/message_viewport.js b/static/js/message_viewport.js index 807bc6ff64..e1b28365eb 100644 --- a/static/js/message_viewport.js +++ b/static/js/message_viewport.js @@ -65,6 +65,30 @@ exports.is_below_visible_bottom = function (offset) { return offset > exports.scrollTop() + exports.height() - $("#compose").height(); }; +exports.is_scrolled_up = function () { + // Let's determine whether the user was already dealing + // with messages off the screen, which can guide auto + // scrolling decisions. + var last_row = rows.last_visible(); + if (last_row.length === 0) { + return false; + } + + var offset = exports.offset_from_bottom(last_row); + + return offset > 0; +}; + +exports.offset_from_bottom = function (last_row) { + // A positive return value here means the last row is + // below the bottom of the feed (i.e. obscured by the compose + // box or even further below the bottom). + var message_bottom = last_row.offset().top + last_row.height(); + var info = exports.message_viewport_info(); + + return message_bottom - info.visible_bottom; +}; + exports.set_message_position = function (message_top, message_height, viewport_info, ratio) { // message_top = offset of the top of a message that you are positioning // message_height = height of the message that you are positioning