diff options
author | Marco Ambrosini <marcoambrosini@pm.me> | 2020-01-08 17:31:46 +0300 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2020-01-08 19:24:28 +0300 |
commit | ca1243182b121f53970f29d0c688ea2ae601b28d (patch) | |
tree | 5124a7246679e1102e6a79b35d23236c4f45d282 /src | |
parent | 6ef2d3f2b8877414463d485249f7b4745c3f2f65 (diff) |
Add scroll to bottom feature when receiving new messages
Signed-off-by: Marco Ambrosini <marcoambrosini@pm.me>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/MessagesList/MessagesList.vue | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/components/MessagesList/MessagesList.vue b/src/components/MessagesList/MessagesList.vue index a61b4cb4d..9ab7e2549 100644 --- a/src/components/MessagesList/MessagesList.vue +++ b/src/components/MessagesList/MessagesList.vue @@ -31,6 +31,7 @@ the Vue virtual scroll list component, whose docs you can find [here.](https://g <!-- size and remain refer to the amount and initial height of the items that are outside of the viewport --> <div + v-scroll="handleScroll" class="scroller"> <MessagesGroup v-for="item of messagesGroupedByAuthor" @@ -85,6 +86,8 @@ export default { * when quickly switching to a new conversation. */ cancelFetchMessages: () => {}, + + isScrolledToBottom: true, } }, @@ -130,6 +133,17 @@ export default { } return groups }, + /** + * In order for the state of the component to be sticky, the browser window must be + * active and the div .scroller must be scrolled to the bottom. + * When isSticky is true, as new messages are appended to the list, the div .scroller + * automatically scrolls down to the last message, if it's false, new messages are + * appended but the scrolling position is not altered. + * @returns {boolean} + */ + isSticky() { + return this.isScrolledToBottom && this.$store.getters.windowIsVisible() + }, }, /** @@ -314,6 +328,11 @@ export default { messages.data.ocs.data.forEach(message => { this.$store.dispatch('processMessage', message) }) + // Scroll to the last message if sticky + if (this.isSticky) { + this.scrollToBottom() + } + // Recursive call this.getNewMessages() } catch (exception) { if (exception.response) { @@ -337,6 +356,20 @@ export default { this.$store.dispatch('deleteMessage', event.message) }, /** + * When the div is scrolled, this method checks if it's been scrolled to the + * bottom. + */ + handleScroll() { + const scrollOffset = document.querySelector('.scroller').scrollHeight - document.querySelector('.scroller').scrollTop + const elementHeight = document.querySelector('.scroller').clientHeight + const tolerance = 3 + if (scrollOffset < elementHeight + tolerance && scrollOffset > elementHeight - tolerance) { + this.isScrolledToBottom = true + } else { + this.isScrolledToBottom = false + } + }, + /** * Scrolls to the bottom of the list. */ scrollToBottom() { |