diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js index 098171fe5..68bf83f50 100644 --- a/app/javascript/sdk/IFrameHelper.js +++ b/app/javascript/sdk/IFrameHelper.js @@ -3,7 +3,6 @@ import { wootOn, addClass, loadCSS, - removeClass, onLocationChangeListener, } from './DOMHelpers'; import { @@ -19,6 +18,8 @@ import { onClickChatBubble, onBubbleClick, setBubbleText, + addUnreadClass, + removeUnreadClass, } from './bubbleHelpers'; import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper'; @@ -171,8 +172,7 @@ export const IFrameHelper = { if (!isOpen && unreadMessageCount > 0) { IFrameHelper.sendMessage('set-unread-view'); onBubbleClick({ toggleValue }); - const holderEl = document.querySelector('.woot-widget-holder'); - addClass(holderEl, 'has-unread-view'); + addUnreadClass(); } }, @@ -181,8 +181,7 @@ export const IFrameHelper = { const toggleValue = true; if (!isOpen) { onBubbleClick({ toggleValue }); - const holderEl = document.querySelector('.woot-widget-holder'); - addClass(holderEl, 'has-unread-view'); + addUnreadClass(); } }, @@ -195,12 +194,7 @@ export const IFrameHelper = { resetUnreadMode: () => { IFrameHelper.sendMessage('unset-unread-view'); - IFrameHelper.events.removeUnreadClass(); - }, - - removeUnreadClass: () => { - const holderEl = document.querySelector('.woot-widget-holder'); - removeClass(holderEl, 'has-unread-view'); + removeUnreadClass(); }, closeChat: () => { diff --git a/app/javascript/sdk/bubbleHelpers.js b/app/javascript/sdk/bubbleHelpers.js index 101f76b5c..740d83733 100644 --- a/app/javascript/sdk/bubbleHelpers.js +++ b/app/javascript/sdk/bubbleHelpers.js @@ -1,4 +1,4 @@ -import { addClass, toggleClass, wootOn } from './DOMHelpers'; +import { addClass, removeClass, toggleClass, wootOn } from './DOMHelpers'; import { IFrameHelper } from './IFrameHelper'; import { BUBBLE_DESIGN } from './constants'; @@ -74,3 +74,13 @@ export const onBubbleClick = (props = {}) => { export const onClickChatBubble = () => { wootOn(bubbleHolder, 'click', onBubbleClick); }; + +export const addUnreadClass = () => { + const holderEl = document.querySelector('.woot-widget-holder'); + addClass(holderEl, 'has-unread-view'); +}; + +export const removeUnreadClass = () => { + const holderEl = document.querySelector('.woot-widget-holder'); + removeClass(holderEl, 'has-unread-view'); +}; diff --git a/app/javascript/shared/components/Branding.vue b/app/javascript/shared/components/Branding.vue index 6a284a6bd..faa212e9e 100644 --- a/app/javascript/shared/components/Branding.vue +++ b/app/javascript/shared/components/Branding.vue @@ -1,23 +1,27 @@ diff --git a/app/javascript/shared/constants/busEvents.js b/app/javascript/shared/constants/busEvents.js index f104dc992..0c496818f 100644 --- a/app/javascript/shared/constants/busEvents.js +++ b/app/javascript/shared/constants/busEvents.js @@ -1,5 +1,4 @@ export const BUS_EVENTS = { - SET_REFERRER_HOST: 'SET_REFERRER_HOST', SET_TWEET_REPLY: 'SET_TWEET_REPLY', SHOW_ALERT: 'SHOW_ALERT', START_NEW_CONVERSATION: 'START_NEW_CONVERSATION', diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 81c4efcb0..98be1b767 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -20,9 +20,11 @@ import configMixin from './mixins/configMixin'; import availabilityMixin from 'widget/mixins/availability'; import Router from './views/Router'; import { getLocale } from './helpers/urlParamsHelper'; -import { BUS_EVENTS } from 'shared/constants/busEvents'; import { isEmptyObject } from 'widget/helpers/utils'; - +import { + getExtraSpaceToScroll, + loadedEventConfig, +} from './helpers/IframeEventHelper'; export default { name: 'App', components: { @@ -99,7 +101,7 @@ export default { this.registerCampaignEvents(); }, methods: { - ...mapActions('appConfig', ['setWidgetColor']), + ...mapActions('appConfig', ['setWidgetColor', 'setReferrerHost']), ...mapActions('conversation', ['fetchOldConversations', 'setUserLastSeen']), ...mapActions('campaign', [ 'initCampaigns', @@ -120,7 +122,7 @@ export default { }, setIframeHeight(isFixedHeight) { this.$nextTick(() => { - const extraHeight = this.getExtraSpaceToscroll(); + const extraHeight = getExtraSpaceToScroll(); IFrameHelper.sendMessage({ event: 'updateIframeHeight', isFixedHeight, @@ -245,7 +247,7 @@ export default { isInBusinessHours: this.isInBusinessHours, }); window.referrerURL = referrerURL; - bus.$emit(BUS_EVENTS.SET_REFERRER_HOST, referrerHost); + this.setReferrerHost(referrerHost); } else if (message.event === 'toggle-close-button') { this.isMobile = message.showClose; } else if (message.event === 'push-event') { @@ -286,39 +288,10 @@ export default { }); }, sendLoadedEvent() { - IFrameHelper.sendMessage({ - event: 'loaded', - config: { - authToken: window.authToken, - channelConfig: window.chatwootWebChannel, - }, - }); + IFrameHelper.sendMessage(loadedEventConfig()); }, sendRNWebViewLoadedEvent() { - RNHelper.sendMessage({ - event: 'loaded', - config: { - authToken: window.authToken, - channelConfig: window.chatwootWebChannel, - }, - }); - }, - 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; + RNHelper.sendMessage(loadedEventConfig()); }, }, }; diff --git a/app/javascript/widget/helpers/IframeEventHelper.js b/app/javascript/widget/helpers/IframeEventHelper.js new file mode 100644 index 000000000..f09cb0f47 --- /dev/null +++ b/app/javascript/widget/helpers/IframeEventHelper.js @@ -0,0 +1,27 @@ +export const loadedEventConfig = () => { + return { + event: 'loaded', + config: { + authToken: window.authToken, + channelConfig: window.chatwootWebChannel, + }, + }; +}; + +export const 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/store/modules/appConfig.js b/app/javascript/widget/store/modules/appConfig.js index 47a7098cf..e04f868b3 100644 --- a/app/javascript/widget/store/modules/appConfig.js +++ b/app/javascript/widget/store/modules/appConfig.js @@ -1,23 +1,31 @@ -import { SET_WIDGET_COLOR } from '../types'; +import { SET_REFERRER_HOST, SET_WIDGET_COLOR } from '../types'; const state = { widgetColor: '', + referrerHost: '', }; -const getters = { +export const getters = { getWidgetColor: $state => $state.widgetColor, + getReferrerHost: $state => $state.referrerHost, }; -const actions = { +export const actions = { setWidgetColor({ commit }, data) { commit(SET_WIDGET_COLOR, data); }, + setReferrerHost({ commit }, referrerHost) { + commit(SET_REFERRER_HOST, referrerHost); + }, }; -const mutations = { +export const mutations = { [SET_WIDGET_COLOR]($state, data) { $state.widgetColor = data.widgetColor; }, + [SET_REFERRER_HOST]($state, referrerHost) { + $state.referrerHost = referrerHost; + }, }; 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 new file mode 100644 index 000000000..cf1366226 --- /dev/null +++ b/app/javascript/widget/store/modules/specs/appConfig/actions.spec.js @@ -0,0 +1,22 @@ +import { actions } from '../../appConfig'; + +const commit = jest.fn(); +describe('#actions', () => { + describe('#setReferrerHost', () => { + it('creates actions properly', () => { + actions.setReferrerHost({ commit }, 'www.chatwoot.com'); + expect(commit.mock.calls).toEqual([ + ['SET_REFERRER_HOST', 'www.chatwoot.com'], + ]); + }); + }); + + describe('#setWidgetColor', () => { + it('creates actions properly', () => { + actions.setWidgetColor({ commit }, { widgetColor: '#eaeaea' }); + expect(commit.mock.calls).toEqual([ + ['SET_WIDGET_COLOR', { widgetColor: '#eaeaea' }], + ]); + }); + }); +}); diff --git a/app/javascript/widget/store/modules/specs/appConfig/getters.spec.js b/app/javascript/widget/store/modules/specs/appConfig/getters.spec.js new file mode 100644 index 000000000..045933aa8 --- /dev/null +++ b/app/javascript/widget/store/modules/specs/appConfig/getters.spec.js @@ -0,0 +1,16 @@ +import { getters } from '../../appConfig'; + +describe('#getters', () => { + describe('#getWidgetColor', () => { + it('returns correct value', () => { + const state = { widgetColor: '#00bcd4' }; + expect(getters.getWidgetColor(state)).toEqual('#00bcd4'); + }); + }); + describe('#getReferrerHost', () => { + it('returns correct value', () => { + const state = { referrerHost: 'www.chatwoot.com' }; + expect(getters.getReferrerHost(state)).toEqual('www.chatwoot.com'); + }); + }); +}); diff --git a/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js b/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js new file mode 100644 index 000000000..f8d90bf26 --- /dev/null +++ b/app/javascript/widget/store/modules/specs/appConfig/mutations.spec.js @@ -0,0 +1,19 @@ +import { mutations } from '../../appConfig'; + +describe('#mutations', () => { + describe('#SET_REFERRER_HOST', () => { + it('sets referrer host properly', () => { + const state = { referrerHost: '' }; + mutations.SET_REFERRER_HOST(state, 'www.chatwoot.com'); + expect(state.referrerHost).toEqual('www.chatwoot.com'); + }); + }); + + describe('#SET_WIDGET_COLOR', () => { + it('sets widget color properly', () => { + const state = { widgetColor: '' }; + mutations.SET_WIDGET_COLOR(state, { widgetColor: '#00bcd4' }); + expect(state.widgetColor).toEqual('#00bcd4'); + }); + }); +}); diff --git a/app/javascript/widget/store/types.js b/app/javascript/widget/store/types.js index 0ade84403..a5ab12420 100644 --- a/app/javascript/widget/store/types.js +++ b/app/javascript/widget/store/types.js @@ -1,4 +1,6 @@ export const SET_WIDGET_COLOR = 'SET_WIDGET_COLOR'; +export const SET_REFERRER_HOST = 'SET_REFERRER_HOST'; + export const SET_CONVERSATION_ATTRIBUTES = 'SET_CONVERSATION_ATTRIBUTES'; export const UPDATE_CONVERSATION_ATTRIBUTES = 'UPDATE_CONVERSATION_ATTRIBUTES'; export const CLEAR_CONVERSATION_ATTRIBUTES = 'CLEAR_CONVERSATION_ATTRIBUTES';