From e45abebe3991557a292414c01706c4aebb9b016e Mon Sep 17 00:00:00 2001 From: Anubhav Jain Date: Fri, 18 Jun 2021 20:12:43 +0530 Subject: [PATCH] feat: Improve scrolling for last message on agent side (#2421) * Improve chat widget scrolling * refactor the class names to snake-case * refactor the scrollTop calculations to a helper * Add tests for scrollTopCalculationHelper Co-authored-by: Nithin David Thomas Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com> --- .../widgets/conversation/MessagesView.vue | 21 ++++++++++++++++++- .../helpers/scrollTopCalculationHelper.js | 18 ++++++++++++++++ .../specs/scrollTopCalculationHelper.spec.js | 18 ++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 app/javascript/dashboard/components/widgets/conversation/helpers/scrollTopCalculationHelper.js create mode 100644 app/javascript/dashboard/components/widgets/conversation/helpers/specs/scrollTopCalculationHelper.spec.js diff --git a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue index d825e4634..9b4de3651 100644 --- a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue +++ b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue @@ -56,6 +56,7 @@ @@ -72,6 +73,7 @@ @@ -106,6 +108,7 @@ import { getTypingUsersText } from '../../../helper/commons'; import { BUS_EVENTS } from 'shared/constants/busEvents'; import { REPLY_POLICY } from 'shared/constants/links'; import inboxMixin from 'shared/mixins/inboxMixin'; +import { calculateScrollTop } from './helpers/scrollTopCalculationHelper'; export default { components: { @@ -259,7 +262,23 @@ export default { this.conversationPanel.removeEventListener('scroll', this.handleScroll); }, scrollToBottom() { - this.conversationPanel.scrollTop = this.conversationPanel.scrollHeight; + let relevantMessages = []; + if (this.getUnreadCount > 0) { + // capturing only the unread messages + relevantMessages = this.conversationPanel.querySelectorAll( + '.message--unread' + ); + } else { + // capturing last message from the messages list + relevantMessages = Array.from( + this.conversationPanel.querySelectorAll('.message--read') + ).slice(-1); + } + this.conversationPanel.scrollTop = calculateScrollTop( + this.conversationPanel.scrollHeight, + this.$el.scrollHeight, + relevantMessages + ); }, onToggleContactPanel() { this.$emit('contact-panel-toggle'); diff --git a/app/javascript/dashboard/components/widgets/conversation/helpers/scrollTopCalculationHelper.js b/app/javascript/dashboard/components/widgets/conversation/helpers/scrollTopCalculationHelper.js new file mode 100644 index 000000000..f588089c3 --- /dev/null +++ b/app/javascript/dashboard/components/widgets/conversation/helpers/scrollTopCalculationHelper.js @@ -0,0 +1,18 @@ +const totalMessageHeight = (total, element) => { + return total + element.scrollHeight; +}; + +export const calculateScrollTop = ( + conversationPanelHeight, + parentHeight, + relevantMessages +) => { + // add up scrollHeight of a `relevantMessages` + let combinedMessageScrollHeight = [...relevantMessages].reduce( + totalMessageHeight, + 0 + ); + return ( + conversationPanelHeight - combinedMessageScrollHeight - parentHeight / 2 + ); +}; diff --git a/app/javascript/dashboard/components/widgets/conversation/helpers/specs/scrollTopCalculationHelper.spec.js b/app/javascript/dashboard/components/widgets/conversation/helpers/specs/scrollTopCalculationHelper.spec.js new file mode 100644 index 000000000..03caf7560 --- /dev/null +++ b/app/javascript/dashboard/components/widgets/conversation/helpers/specs/scrollTopCalculationHelper.spec.js @@ -0,0 +1,18 @@ +import { calculateScrollTop } from '../scrollTopCalculationHelper'; + +describe('#calculateScrollTop', () => { + it('returns calculated value of the scrollTop property', () => { + class DOMElement { + constructor(scrollHeight) { + this.scrollHeight = scrollHeight; + } + } + let count = 3; + let relevantMessages = []; + while (count > 0) { + relevantMessages.push(new DOMElement(100)); + count -= 1; + } + expect(calculateScrollTop(1000, 300, relevantMessages)).toEqual(550); + }); +});