From ef850eda0fbcb8bf5e555cd8e3d8e55d92ca5665 Mon Sep 17 00:00:00 2001 From: Fayaz Ahmed <15716057+fayazara@users.noreply.github.com> Date: Fri, 6 May 2022 19:30:48 +0530 Subject: [PATCH] feat: Add the SDK method to programatically toggle live chat bubble (#4223) Co-authored-by: Pranav Raj S --- app/javascript/packs/sdk.js | 20 +++++++- app/javascript/sdk/IFrameHelper.js | 48 +++++++++---------- app/javascript/sdk/bubbleHelpers.js | 5 +- app/javascript/sdk/sdk.js | 4 ++ .../shared/constants/sharedFrameEvents.js | 1 + app/javascript/widget/App.vue | 6 +++ .../widget/store/modules/appConfig.js | 7 +++ .../modules/specs/appConfig/actions.spec.js | 7 +++ .../modules/specs/appConfig/mutations.spec.js | 8 ++++ app/javascript/widget/store/types.js | 1 + 10 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 app/javascript/shared/constants/sharedFrameEvents.js diff --git a/app/javascript/packs/sdk.js b/app/javascript/packs/sdk.js index b77b682dd..064033841 100755 --- a/app/javascript/packs/sdk.js +++ b/app/javascript/packs/sdk.js @@ -10,7 +10,8 @@ import { getUserCookieName, hasUserKeys, } from '../sdk/cookieHelpers'; - +import { addClass, removeClass } from '../sdk/DOMHelpers'; +import { SDK_SET_BUBBLE_VISIBILITY } from 'shared/constants/sharedFrameEvents'; const runSDK = ({ baseUrl, websiteToken }) => { if (window.$chatwoot) { return; @@ -36,6 +37,23 @@ const runSDK = ({ baseUrl, websiteToken }) => { IFrameHelper.events.toggleBubble(state); }, + toggleBubbleVisibility(visibility) { + let widgetElm = document.querySelector('.woot--bubble-holder'); + let widgetHolder = document.querySelector('.woot-widget-holder'); + if (visibility === 'hide') { + addClass(widgetHolder, 'woot-widget--without-bubble'); + addClass(widgetElm, 'woot-hidden'); + window.$chatwoot.hideMessageBubble = true; + } else if (visibility === 'show') { + removeClass(widgetElm, 'woot-hidden'); + removeClass(widgetHolder, 'woot-widget--without-bubble'); + window.$chatwoot.hideMessageBubble = false; + } + IFrameHelper.sendMessage(SDK_SET_BUBBLE_VISIBILITY, { + hideMessageBubble: window.$chatwoot.hideMessageBubble, + }); + }, + popoutChatWindow() { IFrameHelper.events.popoutChatWindow({ baseUrl: window.$chatwoot.baseUrl, diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index 3bc0973fe..9641a4226 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -175,9 +175,6 @@ export const IFrameHelper = { }, setBubbleLabel(message) { - if (window.$chatwoot.hideMessageBubble) { - return; - } setBubbleText(window.$chatwoot.launcherTitle || message.label); }, @@ -263,33 +260,32 @@ export const IFrameHelper = { if (IFrameHelper.getBubbleHolder().length) { return; } - createBubbleHolder(); + createBubbleHolder(window.$chatwoot.hideMessageBubble); onLocationChangeListener(); - if (!window.$chatwoot.hideMessageBubble) { - let className = 'woot-widget-bubble'; - let closeBtnClassName = `woot-elements--${window.$chatwoot.position} woot-widget-bubble woot--close woot--hide`; - if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) { - className += ' woot-widget-bubble--flat'; - closeBtnClassName += ' woot-widget-bubble--flat'; - } + let className = 'woot-widget-bubble'; + let closeBtnClassName = `woot-elements--${window.$chatwoot.position} woot-widget-bubble woot--close woot--hide`; - const chatIcon = createBubbleIcon({ - className, - src: bubbleImg, - target: chatBubble, - }); - - addClass(closeBubble, closeBtnClassName); - - chatIcon.style.background = widgetColor; - closeBubble.style.background = widgetColor; - - bubbleHolder.appendChild(chatIcon); - bubbleHolder.appendChild(closeBubble); - bubbleHolder.appendChild(createNotificationBubble()); - onClickChatBubble(); + if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) { + className += ' woot-widget-bubble--flat'; + closeBtnClassName += ' woot-widget-bubble--flat'; } + + const chatIcon = createBubbleIcon({ + className, + src: bubbleImg, + target: chatBubble, + }); + + addClass(closeBubble, closeBtnClassName); + + chatIcon.style.background = widgetColor; + closeBubble.style.background = widgetColor; + + bubbleHolder.appendChild(chatIcon); + bubbleHolder.appendChild(closeBubble); + bubbleHolder.appendChild(createNotificationBubble()); + onClickChatBubble(); }, toggleCloseButton: () => { let isMobile = false; diff --git a/app/javascript/sdk/bubbleHelpers.js b/app/javascript/sdk/bubbleHelpers.js index 18f8e2fbc..b1ef9110f 100644 --- a/app/javascript/sdk/bubbleHelpers.js +++ b/app/javascript/sdk/bubbleHelpers.js @@ -39,7 +39,10 @@ export const createBubbleIcon = ({ className, src, target }) => { return target; }; -export const createBubbleHolder = () => { +export const createBubbleHolder = hideMessageBubble => { + if (hideMessageBubble) { + addClass(bubbleHolder, 'woot-hidden'); + } addClass(bubbleHolder, 'woot--bubble-holder'); body.appendChild(bubbleHolder); }; diff --git a/app/javascript/sdk/sdk.js b/app/javascript/sdk/sdk.js index a13e36d0f..b4d198630 100644 --- a/app/javascript/sdk/sdk.js +++ b/app/javascript/sdk/sdk.js @@ -227,4 +227,8 @@ export const SDK_CSS = ` width: 400px !important; } } + +.woot-hidden { + display: none !important; +} `; diff --git a/app/javascript/shared/constants/sharedFrameEvents.js b/app/javascript/shared/constants/sharedFrameEvents.js new file mode 100644 index 000000000..6a1d1de9d --- /dev/null +++ b/app/javascript/shared/constants/sharedFrameEvents.js @@ -0,0 +1 @@ +export const SDK_SET_BUBBLE_VISIBILITY = 'sdk-set-bubble-visibility'; diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 723effb81..f31ba57ad 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -38,6 +38,9 @@ import { ON_CAMPAIGN_MESSAGE_CLICK, ON_UNREAD_MESSAGE_CLICK, } from './constants/widgetBusEvents'; + +import { SDK_SET_BUBBLE_VISIBILITY } from '../shared/constants/sharedFrameEvents'; + export default { name: 'App', components: { @@ -103,6 +106,7 @@ export default { 'setAppConfig', 'setReferrerHost', 'setWidgetColor', + 'setBubbleVisibility', ]), ...mapActions('conversation', ['fetchOldConversations', 'setUserLastSeen']), ...mapActions('campaign', [ @@ -285,6 +289,8 @@ export default { if (!message.isOpen) { this.resetCampaign(); } + } else if (message.event === SDK_SET_BUBBLE_VISIBILITY) { + this.setBubbleVisibility(message.hideMessageBubble); } }); }, diff --git a/app/javascript/widget/store/modules/appConfig.js b/app/javascript/widget/store/modules/appConfig.js index 319f86be4..91149a2c3 100644 --- a/app/javascript/widget/store/modules/appConfig.js +++ b/app/javascript/widget/store/modules/appConfig.js @@ -1,4 +1,5 @@ import { + SET_BUBBLE_VISIBILITY, SET_REFERRER_HOST, SET_WIDGET_APP_CONFIG, SET_WIDGET_COLOR, @@ -57,6 +58,9 @@ export const actions = { setReferrerHost({ commit }, referrerHost) { commit(SET_REFERRER_HOST, referrerHost); }, + setBubbleVisibility({ commit }, hideMessageBubble) { + commit(SET_BUBBLE_VISIBILITY, hideMessageBubble); + }, }; export const mutations = { @@ -76,6 +80,9 @@ export const mutations = { [SET_REFERRER_HOST]($state, referrerHost) { $state.referrerHost = referrerHost; }, + [SET_BUBBLE_VISIBILITY]($state, hideMessageBubble) { + $state.hideMessageBubble = hideMessageBubble; + }, }; export default { diff --git a/app/javascript/widget/store/modules/specs/appConfig/actions.spec.js b/app/javascript/widget/store/modules/specs/appConfig/actions.spec.js index 7a5f47e87..58441e0c8 100644 --- a/app/javascript/widget/store/modules/specs/appConfig/actions.spec.js +++ b/app/javascript/widget/store/modules/specs/appConfig/actions.spec.js @@ -11,6 +11,13 @@ describe('#actions', () => { }); }); + describe('#setBubbleVisibility', () => { + it('creates actions properly', () => { + actions.setBubbleVisibility({ commit }, false); + expect(commit.mock.calls).toEqual([['SET_BUBBLE_VISIBILITY', false]]); + }); + }); + describe('#setWidgetColor', () => { it('creates actions properly', () => { actions.setWidgetColor({ commit }, '#eaeaea'); diff --git a/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js b/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js index 77a8cb096..dc17014fc 100644 --- a/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js +++ b/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js @@ -9,6 +9,14 @@ describe('#mutations', () => { }); }); + describe('#SET_BUBBLE_VISIBILITY', () => { + it('sets bubble visibility properly', () => { + const state = { hideMessageBubble: false }; + mutations.SET_BUBBLE_VISIBILITY(state, true); + expect(state.hideMessageBubble).toEqual(true); + }); + }); + describe('#SET_WIDGET_COLOR', () => { it('sets widget color properly', () => { const state = { widgetColor: '' }; diff --git a/app/javascript/widget/store/types.js b/app/javascript/widget/store/types.js index b7d2da402..dca4d5dc9 100644 --- a/app/javascript/widget/store/types.js +++ b/app/javascript/widget/store/types.js @@ -5,3 +5,4 @@ export const SET_WIDGET_COLOR = 'SET_WIDGET_COLOR'; export const UPDATE_CONVERSATION_ATTRIBUTES = 'UPDATE_CONVERSATION_ATTRIBUTES'; export const TOGGLE_WIDGET_OPEN = 'TOGGLE_WIDGET_OPEN'; export const SET_REFERRER_HOST = 'SET_REFERRER_HOST'; +export const SET_BUBBLE_VISIBILITY = 'SET_BUBBLE_VISIBILITY';