scroll up to unload messages

This commit is contained in:
supertiger1234 2019-08-19 10:20:50 +01:00
parent 9603901214
commit d5dbd19488
8 changed files with 152 additions and 43 deletions

52
package-lock.json generated
View file

@ -2792,7 +2792,8 @@
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
"dev": true
"dev": true,
"optional": true
},
"coa": {
"version": "2.0.2",
@ -5026,7 +5027,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -5047,12 +5049,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5067,17 +5071,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -5194,7 +5201,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -5206,6 +5214,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -5220,6 +5229,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -5227,12 +5237,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -5251,6 +5263,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5331,7 +5344,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -5343,6 +5357,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -5428,7 +5443,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -5464,6 +5480,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -5483,6 +5500,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -5526,12 +5544,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@ -6934,6 +6954,7 @@
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true,
"optional": true,
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
@ -9064,7 +9085,8 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true
"dev": true,
"optional": true
},
"prepend-http": {
"version": "2.0.0",
@ -9783,7 +9805,8 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
"dev": true
"dev": true,
"optional": true
},
"rx-lite-aggregates": {
"version": "4.0.8",
@ -11336,6 +11359,7 @@
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"dev": true,
"optional": true,
"requires": {
"prelude-ls": "~1.1.2"
}

View file

@ -1,9 +1,9 @@
<template>
<div ref="msg-logs" class="message-logs" @scroll="scrollEvent" @resize="onResize">
<div class="load-more-button" v-if="!noMoreLoadMore && selectedChannelMessages.length >= 50">
<spinner :size="30" v-if="loadingMore" />
<div class="text" v-if="!loadingMore" @click="loadMoreMessages">Load more</div>
<div ref="msg-logs" class="message-logs" @scroll.passive="scrollEvent" @resize="onResize">
<div class="load-more-button" v-if="loadMoreTop.show && selectedChannelMessages.length >= 50">
<spinner :size="30" v-if="loadMoreTop.loading" />
<div class="text" v-if="!loadMoreTop.loading" @click="loadMoreMessages">Load more</div>
</div>
<message
class="message-container"
@ -24,7 +24,10 @@
:timeEdited="msg.timeEdited"
/>
<uploadsQueue v-if="uploadQueue !== undefined" :queue="uploadQueue"/>
<div class="load-more-button" v-if="loadMoreBottom.show && selectedChannelMessages.length >= 50">
<spinner :size="30" v-if="!loadMoreTop.loading" />
<div class="text" v-if="!loadMoreBottom.loading">Load more</div>
</div>
</div>
</template>
@ -51,9 +54,14 @@ export default {
scrolledDown: true,
scrolledTop: false,
//load more messages
loadingMore: false,
noMoreLoadMore: false,
loadMoreTop: {
show: true,
loading: false
},
loadMoreBottom: {
show: false,
loading: false,
},
selectedChannelID: null,
currentScrollTopPos: null
};
@ -73,40 +81,89 @@ export default {
if (!element) return;
element.scrollTop = pos || element.scrollHeight;
},
unloadTopMessages(){
if (this.selectedChannelMessages && this.selectedChannelMessages.length >= 100)
this.$store.dispatch('unloadTopMessages', {channelID: this.selectedChannelID});
},
unloadBottomMessages(){
if (this.selectedChannelMessages && this.selectedChannelMessages.length >= 100)
this.$store.dispatch('unloadBottomMessages', {channelID: this.selectedChannelID});
},
onResize(dimentions) {
this.scrollDown();
},
async loadMoreMessages() {
if (this.loadMoreTop.loading) return;
const msgLogs = this.$refs['msg-logs'];
const scrollTop = msgLogs.scrollTop;
const scrollHeight = msgLogs.scrollHeight;
const continueMessageID = this.selectedChannelMessages[0].messageID;
this.loadingMore = true
this.$set(this.loadMoreTop, 'loading', true);
const {ok, result, error} = await messagesService.get(this.selectedChannelID, continueMessageID)
if (ok) {
if (!result.data.messages.length) {
this.loadingMore = false;
this.noMoreLoadMore = true;
this.$set(this.loadMoreTop, 'loading', false);
this.$set(this.loadMoreTop, 'show', false);
return;
}
this.$store.dispatch('addMessages', result.data.messages)
this.$nextTick(_ => {
this.loadingMore = false;
this.$set(this.loadMoreTop, 'loading', false);
msgLogs.scrollTop = msgLogs.scrollHeight - scrollHeight;
})
}
},
async loadBottomMessages() {
if (this.loadMoreBottom.loading) return;
const msgLogs = this.$refs['msg-logs'];
const scrollTop = msgLogs.scrollTop;
const scrollHeight = msgLogs.scrollHeight;
const beforeMessageID = this.selectedChannelMessages[this.selectedChannelMessages.length - 1].messageID;
this.$set(this.loadMoreBottom, 'loading', true);
const {ok, result, error} = await messagesService.get(this.selectedChannelID, null, beforeMessageID)
if (ok) {
if (!result.data.messages.length) {
this.$set(this.loadMoreBottom, 'loading', false);
this.$set(this.loadMoreBottom, 'show', false);
return;
}
this.$store.dispatch('addMessagesBefore', result.data.messages)
this.$nextTick(_ => {
this.$set(this.loadMoreBottom, 'loading', false);
this.scrolledDown = false;
msgLogs.scrollTop = scrollTop
this.$set(this.loadMoreBottom, 'show', true);
})
}
},
scrolledUpEvent() {
this.loadMoreMessages();
const msgLogs = this.$refs['msg-logs'];
const scrollTop = msgLogs.scrollTop;
const scrollHeight = msgLogs.scrollHeight;
this.unloadBottomMessages();
this.$set(this.loadMoreBottom, 'show', true);
this.$nextTick(_ => {
msgLogs.scrollTop = msgLogs.scrollHeight - scrollHeight;
if (this.loadMoreTop.show)
this.loadMoreMessages();
})
},
scrolledDownEvent(){
this.noMoreLoadMore = false;
this.unloadTopMessages()
},
unloadTopMessages(){
if (this.selectedChannelMessages && this.selectedChannelMessages.length)
this.$store.dispatch('unloadTopMessages', {channelID: this.selectedChannelID});
this.$nextTick(_ => {
if (this.loadMoreBottom.show)
this.loadBottomMessages();
this.$set(this.loadMoreTop, 'show', true);
})
},
backToBottomEvent() {
this.scrollDown({force: true});
@ -130,14 +187,17 @@ export default {
beforeDestroy() {
this.$store.dispatch("setEditMessage", null);
this.$store.dispatch('changeScrollPosition',{ channelID: this.selectedChannelID, pos: this.currentScrollTopPos });
this.$store.dispatch('changeScrollPosition',{
channelID: this.selectedChannelID,
pos: !this.scrolledDown ? this.currentScrollTopPos : null
});
bus.$off('backToBottom', this.backToBottomEvent);
bus.$off('scrollDown', this.scrollDown)
},
watch: {
selectedChannelMessages(newMessages, oldMessages){
this.noMoreLoadMore = false;
this.$set(this.loadMoreTop, 'show', true);
const msgLogs = this.$refs['msg-logs'];
this.$nextTick(function () {
this.scrollDown();

View file

@ -9,9 +9,9 @@
<spinner />
</div>
<message-logs v-else-if="selectedChannelID && selectedChannelMessages" :key="selectedChannelID" />
<div class="no-channel-selected" v-if="!selectedChannelID ">
<div class="material-icons">chat</div>
<div class="message">Select a person to message!</div>
<div class="no-channel-selected" v-if="!selectedChannelID">
<div class="material-icons">{{type === 0 ? 'chat' : type === 1 ? 'forum' : 'question'}}</div>
<div class="message">{{type === 0 ? 'Select a person to message!' : type === 1 ?'Selected a server!' : "wot"}}</div>
</div>
<div class="chat-input-area" v-if="selectedChannelID">
<div style="position: relative;">
@ -86,6 +86,7 @@ const emojiPanel = () => import("@/components/app/EmojiPanels/emojiPanel.vue");
const EditPanel = () => import("@/components/app/EditPanel.vue");
export default {
props: ['type'], // type 0: dm; type 1: server
components: {
Spinner,
TypingStatus,

View file

@ -7,7 +7,7 @@
class="left-panel"
/>
</transition>
<message-panel />
<message-panel :type="0"/>
</div>
</template>

View file

@ -7,7 +7,7 @@
class="left-panel"
/>
</transition>
<message-panel />
<message-panel :type="1" />
<transition :name="$mq !== 'desktop' ? 'slide-right' : 'none'">
<members-list
v-if="selectedServerID && (($mq === 'members_panel' || $mq === 'mobile') && showMembersPanel || ($mq === 'desktop'))"

View file

@ -2,8 +2,8 @@ import {instance, wrapper} from './Api';
import filesize from "filesize";
export default {
// TODO: add ?continue=id
get ( channelID, continueMessageID ) {
return wrapper(instance().get(`messages/channels/${channelID}${continueMessageID ? '?continue=' + continueMessageID : ''}`));
get ( channelID, continueMessageID, beforeMessageID ) {
return wrapper(instance().get(`messages/channels/${channelID}${continueMessageID ? '?continue=' + continueMessageID : beforeMessageID ? '?before=' + beforeMessageID : '' }`));
},
delete ( messageID, channelID ) {
return wrapper(instance().delete(`messages/${messageID}/channels/${channelID}`));

View file

@ -86,6 +86,14 @@ const actions = {
context.commit('messages', {messages: join, channelID});
},
addMessagesBefore(context, messagesArr){
const channelID = messagesArr[0].channelID;
const messages = context.state.messages[channelID];
const join = [ ...messages, ...messagesArr, ];
context.commit('messages', {messages: join, channelID});
},
replaceMessage(context, data) {
context.commit("replaceMessage", data);
},
@ -112,8 +120,14 @@ const actions = {
context.commit('changeScrollPosition', {channelID, pos})
},
unloadTopMessages(context, {channelID}) {
const messages = [...[], ...context.state.messages[channelID]];
const unloaded = messages.splice(50)
context.commit('messages', {channelID, messages: unloaded})
},
unloadBottomMessages(context, {channelID}) {
const messages = context.state.messages[channelID];
const unloaded = messages.slice(Math.max(messages.length - 50, 0))
const unloaded = messages.slice(0, -50)
context.commit('messages', {channelID, messages: unloaded})
}
};

View file

@ -14,13 +14,23 @@
const config = [
{
version: 6.4,
title: "Scrolling up should be smoother!",
shortTitle: "",
date: "19/08/2019",
headColor: "rgba(25, 130, 255, 0.77)",
new: [
'Scrolling up should be smoother now as messages below get unloaded.'
]
},
{
version: 6.3,
title: "Performance Improvements!",
shortTitle: "",
date: "18/08/2019",
headColor: "rgba(25, 130, 255, 0.77)",
msg: "I finally managed to find out why the chat is choppy when scrolling. The rotated emote is the cause. In this update, emotes only appear only when hovering over the profile picture."
msg: "I finally managed to find out why the chat is choppy when scrolling. The rotated emote is the cause. In this update, emotes only appear when hovering over the profile picture."
},
{