From 45cd949c40d42b9a480c961f43d3764c95cfdddd Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Fri, 28 Aug 2020 17:39:46 +0530 Subject: [PATCH] feat: Add a popout option on webwidget (#1174) * feat: Add a popout option on webwidget --- app/javascript/packs/sdk.js | 1 + app/javascript/sdk/IFrameHelper.js | 1 + app/javascript/widget/App.vue | 147 ++++++++++-------- .../widget/assets/scss/_buttons.scss | 10 ++ app/javascript/widget/assets/scss/woot.scss | 33 +--- .../widget/components/ChatHeader.vue | 25 ++- .../widget/components/ChatHeaderExpanded.vue | 37 +++-- .../widget/components/HeaderActions.vue | 89 +++++++++++ app/javascript/widget/helpers/constants.js | 2 + .../helpers/specs/urlParamsHelper.spec.js | 32 +++- .../widget/helpers/specs/utils.spec.js | 42 +++++ .../widget/helpers/urlParamsHelper.js | 21 +++ app/javascript/widget/helpers/utils.js | 9 ++ app/javascript/widget/views/Home.vue | 6 + app/javascript/widget/views/Router.vue | 5 + app/views/widget_tests/index.html.erb | 3 +- docs/channels/website-sdk.md | 11 ++ 17 files changed, 347 insertions(+), 127 deletions(-) create mode 100644 app/javascript/widget/components/HeaderActions.vue create mode 100644 app/javascript/widget/helpers/specs/utils.spec.js diff --git a/app/javascript/packs/sdk.js b/app/javascript/packs/sdk.js index a57b83bb7..429a2ddf9 100755 --- a/app/javascript/packs/sdk.js +++ b/app/javascript/packs/sdk.js @@ -14,6 +14,7 @@ const runSDK = ({ baseUrl, websiteToken }) => { locale: chatwootSettings.locale, type: getBubbleView(chatwootSettings.type), launcherTitle: chatwootSettings.launcherTitle || '', + showPopoutButton: chatwootSettings.showPopoutButton || false, toggle() { IFrameHelper.events.toggleBubble(); diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index b868ef51f..b4244f751 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -99,6 +99,7 @@ export const IFrameHelper = { locale: window.$chatwoot.locale, position: window.$chatwoot.position, hideMessageBubble: window.$chatwoot.hideMessageBubble, + showPopoutButton: window.$chatwoot.showPopoutButton, }); IFrameHelper.onLoad({ widgetColor: message.config.channelConfig.widgetColor, diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index fb865d03e..c5cc2240c 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -11,6 +11,7 @@ :unread-message-count="unreadMessageCount" :is-left-aligned="isLeftAligned" :hide-message-bubble="hideMessageBubble" + :show-popout-button="showPopoutButton" /> @@ -21,6 +22,7 @@ import { setHeader } from 'widget/helpers/axios'; import { IFrameHelper } from 'widget/helpers/utils'; import Router from './views/Router'; +import { getLocale } from './helpers/urlParamsHelper'; export default { name: 'App', @@ -33,6 +35,7 @@ export default { isMobile: false, hideMessageBubble: false, widgetPosition: 'right', + showPopoutButton: false, }; }, computed: { @@ -49,74 +52,25 @@ export default { const isLeft = this.widgetPosition === 'left'; return isLeft; }, + isIFrame() { + return IFrameHelper.isIFrame(); + }, }, mounted() { const { websiteToken, locale } = window.chatwootWebChannel; this.setLocale(locale); - - if (IFrameHelper.isIFrame()) { - IFrameHelper.sendMessage({ - event: 'loaded', - config: { - authToken: window.authToken, - channelConfig: window.chatwootWebChannel, - }, - }); + if (this.isIFrame) { + this.registerListeners(); + this.sendLoadedEvent(); setHeader('X-Auth-Token', window.authToken); + } else { + setHeader('X-Auth-Token', window.authToken); + this.fetchOldConversations(); + this.fetchAvailableAgents(websiteToken); + this.setLocale(getLocale(window.location.search)); } - this.setWidgetColor(window.chatwootWebChannel); - - window.addEventListener('message', e => { - const wootPrefix = 'chatwoot-widget:'; - const isDataNotString = typeof e.data !== 'string'; - const isNotFromWoot = isDataNotString || e.data.indexOf(wootPrefix) !== 0; - - if (isNotFromWoot) return; - - const message = JSON.parse(e.data.replace(wootPrefix, '')); - if (message.event === 'config-set') { - this.setLocale(message.locale); - this.setBubbleLabel(); - this.setPosition(message.position); - this.fetchOldConversations().then(() => { - this.setUnreadView(); - }); - this.fetchAvailableAgents(websiteToken); - this.setHideMessageBubble(message.hideMessageBubble); - } else if (message.event === 'widget-visible') { - this.scrollConversationToBottom(); - } else if (message.event === 'set-current-url') { - window.refererURL = message.refererURL; - } else if (message.event === 'toggle-close-button') { - this.isMobile = message.showClose; - } else if (message.event === 'push-event') { - this.createWidgetEvents(message); - } else if (message.event === 'set-label') { - this.$store.dispatch('conversationLabels/create', message.label); - } else if (message.event === 'remove-label') { - this.$store.dispatch('conversationLabels/destroy', message.label); - } else if (message.event === 'set-user') { - this.$store.dispatch('contacts/update', message); - } else if (message.event === 'set-custom-attributes') { - this.$store.dispatch( - 'contacts/setCustomAttributes', - message.customAttributes - ); - } else if (message.event === 'delete-custom-attribute') { - this.$store.dispatch('contacts/setCustomAttributes', { - [message.customAttribute]: null, - }); - } else if (message.event === 'set-locale') { - this.setLocale(message.locale); - this.setBubbleLabel(); - } else if (message.event === 'set-unread-view') { - this.showUnreadView = true; - } else if (message.event === 'unset-unread-view') { - this.showUnreadView = false; - } - }); - this.$store.dispatch('conversationAttributes/get'); + this.setWidgetColor(window.chatwootWebChannel); this.registerUnreadEvents(); }, methods: { @@ -147,15 +101,23 @@ export default { this.hideMessageBubble = !!hideBubble; }, registerUnreadEvents() { - bus.$on('on-agent-message-recieved', () => this.setUnreadView()); + bus.$on('on-agent-message-recieved', () => { + if (!this.isIFrame) { + this.setUserLastSeen(); + } + this.setUnreadView(); + }); bus.$on('on-unread-view-clicked', () => { this.unsetUnreadView(); this.setUserLastSeen(); }); }, + setPopoutDisplay(showPopoutButton) { + this.showPopoutButton = showPopoutButton; + }, setUnreadView() { const { unreadMessageCount } = this; - if (IFrameHelper.isIFrame() && unreadMessageCount > 0) { + if (this.isIFrame && unreadMessageCount > 0) { IFrameHelper.sendMessage({ event: 'setUnreadMode', unreadMessageCount, @@ -163,7 +125,7 @@ export default { } }, unsetUnreadView() { - if (IFrameHelper.isIFrame()) { + if (this.isIFrame) { IFrameHelper.sendMessage({ event: 'resetUnreadMode' }); } }, @@ -176,6 +138,63 @@ export default { this.setUserLastSeen(); this.$store.dispatch('events/create', { name: eventName }); }, + registerListeners() { + const { websiteToken } = window.chatwootWebChannel; + window.addEventListener('message', e => { + if (!IFrameHelper.isAValidEvent(e)) { + return; + } + const message = IFrameHelper.getMessage(e); + if (message.event === 'config-set') { + this.setLocale(message.locale); + this.setBubbleLabel(); + this.setPosition(message.position); + this.fetchOldConversations().then(() => this.setUnreadView()); + this.setPopoutDisplay(message.showPopoutButton); + this.fetchAvailableAgents(websiteToken); + this.setHideMessageBubble(message.hideMessageBubble); + } else if (message.event === 'widget-visible') { + this.scrollConversationToBottom(); + } else if (message.event === 'set-current-url') { + window.refererURL = message.refererURL; + } else if (message.event === 'toggle-close-button') { + this.isMobile = message.showClose; + } else if (message.event === 'push-event') { + this.createWidgetEvents(message); + } else if (message.event === 'set-label') { + this.$store.dispatch('conversationLabels/create', message.label); + } else if (message.event === 'remove-label') { + this.$store.dispatch('conversationLabels/destroy', message.label); + } else if (message.event === 'set-user') { + this.$store.dispatch('contacts/update', message); + } else if (message.event === 'set-custom-attributes') { + this.$store.dispatch( + 'contacts/setCustomAttributes', + message.customAttributes + ); + } else if (message.event === 'delete-custom-attribute') { + this.$store.dispatch('contacts/setCustomAttributes', { + [message.customAttribute]: null, + }); + } else if (message.event === 'set-locale') { + this.setLocale(message.locale); + this.setBubbleLabel(); + } else if (message.event === 'set-unread-view') { + this.showUnreadView = true; + } else if (message.event === 'unset-unread-view') { + this.showUnreadView = false; + } + }); + }, + sendLoadedEvent() { + IFrameHelper.sendMessage({ + event: 'loaded', + config: { + authToken: window.authToken, + channelConfig: window.chatwootWebChannel, + }, + }); + }, }, }; diff --git a/app/javascript/widget/assets/scss/_buttons.scss b/app/javascript/widget/assets/scss/_buttons.scss index 441908c8f..840b0b40e 100755 --- a/app/javascript/widget/assets/scss/_buttons.scss +++ b/app/javascript/widget/assets/scss/_buttons.scss @@ -58,4 +58,14 @@ $button-border-width: 1px; &.block { width: 100%; } + + &.transparent { + background: transparent; + border: 0; + height: auto; + } + + &.compact { + padding: 0; + } } diff --git a/app/javascript/widget/assets/scss/woot.scss b/app/javascript/widget/assets/scss/woot.scss index ba6d93e23..2a24d8abb 100755 --- a/app/javascript/widget/assets/scss/woot.scss +++ b/app/javascript/widget/assets/scss/woot.scss @@ -11,6 +11,8 @@ html, body { font-family: $font-family; font-size: 10px; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; height: 100%; } @@ -18,36 +20,15 @@ body { height: 100%; } -.close-button { - cursor: pointer; - position: relative; - width: $space-two; - - &::before, - &::after { - background-color: $color-heading; - content: ' '; - height: $space-normal; - left: $space-small; - position: absolute; - top: $space-micro; - width: 2px; - } - - &::before { - transform: rotate(45deg); - } - - &::after { - transform: rotate(-45deg); - } -} - .is-mobile { - .header-wrap { + .actions { .close-button { display: block !important; } + + .new-window--button { + display: none !important; + } } } diff --git a/app/javascript/widget/components/ChatHeader.vue b/app/javascript/widget/components/ChatHeader.vue index 5143635a5..c84d05326 100644 --- a/app/javascript/widget/components/ChatHeader.vue +++ b/app/javascript/widget/components/ChatHeader.vue @@ -4,16 +4,18 @@ avatar

- + @@ -73,9 +70,5 @@ export default { width: 24px; margin-right: $space-small; } - - .close-button { - display: none; - } } diff --git a/app/javascript/widget/components/ChatHeaderExpanded.vue b/app/javascript/widget/components/ChatHeaderExpanded.vue index 5ef50129d..a31f6669e 100755 --- a/app/javascript/widget/components/ChatHeaderExpanded.vue +++ b/app/javascript/widget/components/ChatHeaderExpanded.vue @@ -1,7 +1,9 @@