Merge pull request #1318 from thelounge/xpaw/infinite-scroll

Automatically load history when scrolling upwards
This commit is contained in:
Jérémie Astori 2017-09-01 19:45:49 -04:00 committed by GitHub
commit 77e9cb65d5
3 changed files with 36 additions and 2 deletions

View File

@ -12,6 +12,13 @@ const condensed = require("./condensed");
const chat = $("#chat"); const chat = $("#chat");
const sidebar = $("#sidebar"); const sidebar = $("#sidebar");
require("intersection-observer");
const historyObserver = window.IntersectionObserver ?
new window.IntersectionObserver(loadMoreHistory, {
root: chat.get(0)
}) : null;
module.exports = { module.exports = {
appendMessage, appendMessage,
buildChannelMessages, buildChannelMessages,
@ -145,6 +152,10 @@ function renderChannel(data) {
if (data.type === "channel") { if (data.type === "channel") {
renderChannelUsers(data); renderChannelUsers(data);
} }
if (historyObserver) {
historyObserver.observe(chat.find("#chan-" + data.id + " .show-more").get(0));
}
} }
function renderChannelMessages(data) { function renderChannelMessages(data) {
@ -220,3 +231,19 @@ function renderNetworks(data) {
utils.toggleNotificationMarkers(true); utils.toggleNotificationMarkers(true);
} }
} }
function loadMoreHistory(entries) {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
var target = $(entry.target).find(".show-more-button");
if (target.attr("disabled")) {
return;
}
target.click();
});
}

View File

@ -12,7 +12,7 @@ socket.on("more", function(data) {
// get the scrollable wrapper around messages // get the scrollable wrapper around messages
const scrollable = chan.closest(".chat"); const scrollable = chan.closest(".chat");
const heightOld = chan.height(); const heightOld = chan.height() - scrollable.scrollTop();
// If there are no more messages to show, just hide the button and do nothing else // If there are no more messages to show, just hide the button and do nothing else
if (!data.messages.length) { if (!data.messages.length) {
@ -38,7 +38,13 @@ socket.on("more", function(data) {
// restore scroll position // restore scroll position
const position = chan.height() - heightOld; const position = chan.height() - heightOld;
scrollable.scrollTop(position); scrollable.finish().scrollTop(position);
// We have to do this hack due to smooth scrolling in browsers,
// as scrollTop does not apply correctly
if (window.requestAnimationFrame) {
window.requestAnimationFrame(() => scrollable.scrollTop(position));
}
if (data.messages.length !== 100) { if (data.messages.length !== 100) {
scrollable.find(".show-more").removeClass("show"); scrollable.find(".show-more").removeClass("show");

View File

@ -73,6 +73,7 @@
"fuzzy": "0.1.3", "fuzzy": "0.1.3",
"handlebars": "4.0.10", "handlebars": "4.0.10",
"handlebars-loader": "1.6.0", "handlebars-loader": "1.6.0",
"intersection-observer": "0.4.2",
"jquery": "3.2.1", "jquery": "3.2.1",
"jquery-textcomplete": "1.8.4", "jquery-textcomplete": "1.8.4",
"jquery-ui": "1.12.1", "jquery-ui": "1.12.1",