Deduplicate and optimize 'keep to bottom'

This commit is contained in:
Pavel Djundik 2018-07-12 14:14:15 +03:00 committed by Pavel Djundik
parent a5625ba203
commit b982623aaa
2 changed files with 42 additions and 26 deletions

View File

@ -69,7 +69,9 @@
<span v-else>Show older messages</span> <span v-else>Show older messages</span>
</button> </button>
</div> </div>
<MessageList :channel="channel"/> <MessageList
:channel="channel"
@keepScrollPosition="keepScrollPosition"/>
</div> </div>
<ChatUserList <ChatUserList
v-if="channel.type === 'channel'" v-if="channel.type === 'channel'"
@ -119,19 +121,7 @@ export default {
}, },
watch: { watch: {
"channel.messages"() { "channel.messages"() {
const el = this.$refs.chat; this.keepScrollPosition();
if (!el) {
return;
}
if (el.scrollHeight - el.scrollTop - el.offsetHeight > 30) {
return;
}
this.$nextTick(() => {
el.scrollTop = el.scrollHeight;
});
}, },
}, },
created() { created() {
@ -141,7 +131,7 @@ export default {
} }
if (window.IntersectionObserver) { if (window.IntersectionObserver) {
this.historyObserver = new window.IntersectionObserver(loadMoreHistory, { this.historyObserver = new window.IntersectionObserver(this.onLoadButtonObserved, {
root: this.$refs.chat, root: this.$refs.chat,
}); });
} }
@ -173,10 +163,7 @@ export default {
lastId: lastMessage, lastId: lastMessage,
}); });
}, },
}, onLoadButtonObserved(entries) {
};
function loadMoreHistory(entries) {
entries.forEach((entry) => { entries.forEach((entry) => {
if (!entry.isIntersecting) { if (!entry.isIntersecting) {
return; return;
@ -184,5 +171,30 @@ function loadMoreHistory(entries) {
entry.target.click(); entry.target.click();
}); });
} },
keepScrollPosition() {
// If we are already waiting for the next tick to force scroll position,
// we have no reason to perform more checks and set it again in the next tick
if (this.isWaitingForNextTick) {
return;
}
const el = this.$refs.chat;
if (!el) {
return;
}
if (el.scrollHeight - el.scrollTop - el.offsetHeight > 30) {
return;
}
this.isWaitingForNextTick = true;
this.$nextTick(() => {
this.isWaitingForNextTick = false;
el.scrollTop = el.scrollHeight;
});
},
},
};
</script> </script>

View File

@ -138,6 +138,9 @@ export default {
const options = require("../js/options"); const options = require("../js/options");
this.$set(this.link, "canDisplay", this.link.type !== "loading" && options.shouldOpenMessagePreview(this.link.type)); this.$set(this.link, "canDisplay", this.link.type !== "loading" && options.shouldOpenMessagePreview(this.link.type));
// parent 1 - message - parent 2 - messagelist
this.$parent.$parent.$emit("keepScrollPosition");
if (this.link.type !== "link") { if (this.link.type !== "link") {
return; return;
} }
@ -152,7 +155,8 @@ export default {
}, },
methods: { methods: {
onPreviewReady() { onPreviewReady() {
// TODO: Instead of forcing scroll position, wait for image to load before showing it
this.$parent.$parent.$emit("keepScrollPosition");
}, },
onMoreClick() { onMoreClick() {
this.isContentShown = !this.isContentShown; this.isContentShown = !this.isContentShown;