diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index f3ccbfc0..b7eebd6d 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -169,6 +169,15 @@ function mergeChannelData(oldChannels, newChannels) { continue; } + // Server sends total count of messages in memory, we compare it to amount of messages + // on the client, and decide whether theres more messages to load from server + if (key === "totalMessages") { + currentChannel.moreHistoryAvailable = + channel.totalMessages > currentChannel.messages.length; + + continue; + } + // Reconnection only sends new messages, so merge it on the client // Only concat if server sent us less than 100 messages so we don't introduce gaps if (key === "messages" && currentChannel.messages && channel.messages.length < 100) { diff --git a/client/js/socket-events/more.js b/client/js/socket-events/more.js index dc2d1ec2..2a5547e9 100644 --- a/client/js/socket-events/more.js +++ b/client/js/socket-events/more.js @@ -10,7 +10,8 @@ socket.on("more", function(data) { return; } - channel.channel.moreHistoryAvailable = data.moreHistoryAvailable; + channel.channel.moreHistoryAvailable = + data.totalMessages > channel.channel.messages.length + data.messages.length; channel.channel.messages.unshift(...data.messages); vueApp.$nextTick(() => { diff --git a/client/js/vue.js b/client/js/vue.js index fea5d622..2477e80f 100644 --- a/client/js/vue.js +++ b/client/js/vue.js @@ -78,6 +78,9 @@ function initChannel(channel) { channel.scrolledToBottom = true; channel.editTopic = false; + channel.moreHistoryAvailable = channel.totalMessages > channel.messages.length; + delete channel.totalMessages; + if (channel.type === "channel") { channel.usersOutdated = true; } diff --git a/src/client.js b/src/client.js index fcdef3ee..b6316dff 100644 --- a/src/client.js +++ b/src/client.js @@ -448,7 +448,7 @@ Client.prototype.more = function(data) { return { chan: chan.id, messages: messages, - moreHistoryAvailable: index > 100, + totalMessages: chan.messages.length, }; }; diff --git a/src/models/chan.js b/src/models/chan.js index 8a41eae9..4a8da52d 100644 --- a/src/models/chan.js +++ b/src/models/chan.js @@ -177,7 +177,6 @@ Chan.prototype.getFilteredClone = function(lastActiveChannel, lastMessage) { // When reconnecting, always send up to 100 messages to prevent message gaps on the client // See https://github.com/thelounge/thelounge/issues/1883 newChannel[prop] = this[prop].filter((m) => m.id > lastMessage).slice(-100); - newChannel.moreHistoryAvailable = this[prop].length > 100; } else { // If channel is active, send up to 100 last messages, for all others send just 1 // Client will automatically load more messages whenever needed based on last seen messages @@ -185,8 +184,9 @@ Chan.prototype.getFilteredClone = function(lastActiveChannel, lastMessage) { lastActiveChannel === true || this.id === lastActiveChannel ? 100 : 1; newChannel[prop] = this[prop].slice(-messagesToSend); - newChannel.moreHistoryAvailable = this[prop].length > messagesToSend; } + + newChannel.totalMessages = this[prop].length; } else { newChannel[prop] = this[prop]; } @@ -261,7 +261,7 @@ Chan.prototype.loadMessages = function(client, network) { client.emit("more", { chan: this.id, messages: messages.slice(-100), - moreHistoryAvailable: messages.length > 100, + totalMessages: messages.length, }); if (network.irc.network.cap.isEnabled("znc.in/playback")) { diff --git a/test/models/chan.js b/test/models/chan.js index 3c44474b..de01c698 100644 --- a/test/models/chan.js +++ b/test/models/chan.js @@ -213,7 +213,7 @@ describe("Chan", function() { "id", "key", "messages", - "moreHistoryAvailable", + "totalMessages", "name", "state", "topic",