From 70d41ffcdda51f48389e67d93f05de3a3892aa7b Mon Sep 17 00:00:00 2001 From: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com> Date: Sat, 14 Aug 2021 08:40:29 +0530 Subject: [PATCH] fix: Smoothens out opening animation for widget (#2789) --- app/javascript/sdk/IFrameHelper.js | 32 +++++++++++----------- app/javascript/sdk/sdk.js | 8 +++--- app/javascript/widget/App.vue | 37 +++++++++++++++++++++++--- app/javascript/widget/views/Unread.vue | 2 +- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index 979fc6c83..ec00e0280 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -97,6 +97,15 @@ export const IFrameHelper = { } }); }, + + setFrameHeightToFitContent: (extraHeight, isFixedHeight) => { + const iframe = IFrameHelper.getAppFrame(); + const updatedIframeHeight = isFixedHeight ? `${extraHeight}px` : '100%'; + + if (iframe) + iframe.setAttribute('style', `height: ${updatedIframeHeight} !important`); + }, + events: { loaded: message => { Cookies.set('cw_conversation', message.config.authToken, { @@ -169,6 +178,13 @@ export const IFrameHelper = { } }, + updateIframeHeight: message => { + const { extraHeight = 0, isFixedHeight } = message; + if (!extraHeight) return; + + IFrameHelper.setFrameHeightToFitContent(extraHeight, isFixedHeight); + }, + resetUnreadMode: () => { IFrameHelper.sendMessage('unset-unread-view'); IFrameHelper.events.removeUnreadClass(); @@ -178,22 +194,6 @@ export const IFrameHelper = { const holderEl = document.querySelector('.woot-widget-holder'); removeClass(holderEl, 'has-unread-view'); }, - - updateIframeHeight: message => { - setTimeout(() => { - const iframe = IFrameHelper.getAppFrame(); - const scrollableMessageHeight = - iframe.contentWindow.document.querySelector('.unread-messages') - .scrollHeight + 40; - const updatedIframeHeight = message.isFixedHeight - ? `${scrollableMessageHeight}px` - : '100%'; - iframe.setAttribute( - 'style', - `height: ${updatedIframeHeight} !important` - ); - }, 100); - }, }, pushEvent: eventName => { IFrameHelper.sendMessage('push-event', { eventName }); diff --git a/app/javascript/sdk/sdk.js b/app/javascript/sdk/sdk.js index f9e02eb22..75024e4c6 100644 --- a/app/javascript/sdk/sdk.js +++ b/app/javascript/sdk/sdk.js @@ -1,10 +1,11 @@ export const SDK_CSS = `.woot-widget-holder { box-shadow: 0 5px 40px rgba(0, 0, 0, .16) !important; opacity: 1; + will-change: transform, opacity; + transform: translateY(0); overflow: hidden !important; position: fixed !important; - transition-duration: 0.5s, 0.5s; - transition-property: opacity, bottom; + transition: opacity 0.2s linear, transform 0.25s linear; z-index: 2147483000 !important; } @@ -111,7 +112,8 @@ export const SDK_CSS = `.woot-widget-holder { } .woot--hide { - bottom: -20000px !important; + bottom: -100vh; + transform: translateY(40px); top: unset !important; opacity: 0; visibility: hidden !important; diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 4eb8e108e..659082c18 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -59,6 +59,16 @@ export default { activeCampaign() { this.setCampaignView(); }, + showUnreadView(newVal) { + if (newVal) { + this.setIframeHeight(this.isMobile); + } + }, + showCampaignView(newVal) { + if (newVal) { + this.setIframeHeight(this.isMobile); + } + }, }, mounted() { const { websiteToken, locale } = window.chatwootWebChannel; @@ -98,9 +108,13 @@ export default { }); }, setIframeHeight(isFixedHeight) { - IFrameHelper.sendMessage({ - event: 'updateIframeHeight', - isFixedHeight, + this.$nextTick(() => { + const extraHeight = this.getExtraSpaceToscroll(); + IFrameHelper.sendMessage({ + event: 'updateIframeHeight', + isFixedHeight, + extraHeight, + }); }); }, setLocale(locale) { @@ -256,6 +270,23 @@ export default { }, }); }, + getExtraSpaceToscroll: () => { + // This function calculates the extra space needed for the view to + // accomodate the height of close button + height of + // read messages button. So that scrollbar won't appear + const unreadMessageWrap = document.querySelector('.unread-messages'); + const unreadCloseWrap = document.querySelector('.close-unread-wrap'); + const readViewWrap = document.querySelector('.open-read-view-wrap'); + + if (!unreadMessageWrap) return 0; + + // 24px to compensate the paddings + let extraHeight = 24 + unreadMessageWrap.scrollHeight; + if (unreadCloseWrap) extraHeight += unreadCloseWrap.scrollHeight; + if (readViewWrap) extraHeight += readViewWrap.scrollHeight; + + return extraHeight; + }, }, }; diff --git a/app/javascript/widget/views/Unread.vue b/app/javascript/widget/views/Unread.vue index e45a4f2b4..c21f3d803 100644 --- a/app/javascript/widget/views/Unread.vue +++ b/app/javascript/widget/views/Unread.vue @@ -23,7 +23,7 @@ /> -