310 lines
9.1 KiB
JavaScript
310 lines
9.1 KiB
JavaScript
import Cookies from 'js-cookie';
|
|
import {
|
|
addClasses,
|
|
loadCSS,
|
|
removeClasses,
|
|
onLocationChangeListener,
|
|
} from './DOMHelpers';
|
|
import {
|
|
body,
|
|
widgetHolder,
|
|
createBubbleHolder,
|
|
createBubbleIcon,
|
|
bubbleSVG,
|
|
chatBubble,
|
|
closeBubble,
|
|
bubbleHolder,
|
|
createNotificationBubble,
|
|
onClickChatBubble,
|
|
onBubbleClick,
|
|
setBubbleText,
|
|
addUnreadClass,
|
|
removeUnreadClass,
|
|
} from './bubbleHelpers';
|
|
import { isWidgetColorLighter } from 'shared/helpers/colorHelper';
|
|
import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper';
|
|
import { CHATWOOT_ERROR, CHATWOOT_READY } from '../widget/constants/sdkEvents';
|
|
import { SET_USER_ERROR } from '../widget/constants/errorTypes';
|
|
import { getUserCookieName } from './cookieHelpers';
|
|
import {
|
|
getAlertAudio,
|
|
initOnEvents,
|
|
} from 'shared/helpers/AudioNotificationHelper';
|
|
import { isFlatWidgetStyle } from './settingsHelper';
|
|
import { popoutChatWindow } from '../widget/helpers/popoutHelper';
|
|
|
|
const updateAuthCookie = cookieContent =>
|
|
Cookies.set('cw_conversation', cookieContent, {
|
|
expires: 365,
|
|
sameSite: 'Lax',
|
|
});
|
|
|
|
export const IFrameHelper = {
|
|
getUrl({ baseUrl, websiteToken }) {
|
|
return `${baseUrl}/widget?website_token=${websiteToken}`;
|
|
},
|
|
createFrame: ({ baseUrl, websiteToken }) => {
|
|
if (IFrameHelper.getAppFrame()) {
|
|
return;
|
|
}
|
|
|
|
loadCSS();
|
|
const iframe = document.createElement('iframe');
|
|
const cwCookie = Cookies.get('cw_conversation');
|
|
let widgetUrl = IFrameHelper.getUrl({ baseUrl, websiteToken });
|
|
if (cwCookie) {
|
|
widgetUrl = `${widgetUrl}&cw_conversation=${cwCookie}`;
|
|
}
|
|
iframe.src = widgetUrl;
|
|
iframe.allow =
|
|
'camera;microphone;fullscreen;display-capture;picture-in-picture;clipboard-write;';
|
|
iframe.id = 'chatwoot_live_chat_widget';
|
|
iframe.style.visibility = 'hidden';
|
|
|
|
let holderClassName = `woot-widget-holder woot--hide woot-elements--${window.$chatwoot.position}`;
|
|
if (window.$chatwoot.hideMessageBubble) {
|
|
holderClassName += ` woot-widget--without-bubble`;
|
|
}
|
|
if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) {
|
|
holderClassName += ` woot-widget-holder--flat`;
|
|
}
|
|
|
|
addClasses(widgetHolder, holderClassName);
|
|
widgetHolder.appendChild(iframe);
|
|
body.appendChild(widgetHolder);
|
|
IFrameHelper.initPostMessageCommunication();
|
|
IFrameHelper.initWindowSizeListener();
|
|
IFrameHelper.preventDefaultScroll();
|
|
},
|
|
getAppFrame: () => document.getElementById('chatwoot_live_chat_widget'),
|
|
getBubbleHolder: () => document.getElementsByClassName('woot--bubble-holder'),
|
|
sendMessage: (key, value) => {
|
|
const element = IFrameHelper.getAppFrame();
|
|
element.contentWindow.postMessage(
|
|
`chatwoot-widget:${JSON.stringify({ event: key, ...value })}`,
|
|
'*'
|
|
);
|
|
},
|
|
initPostMessageCommunication: () => {
|
|
window.onmessage = e => {
|
|
if (
|
|
typeof e.data !== 'string' ||
|
|
e.data.indexOf('chatwoot-widget:') !== 0
|
|
) {
|
|
return;
|
|
}
|
|
const message = JSON.parse(e.data.replace('chatwoot-widget:', ''));
|
|
if (typeof IFrameHelper.events[message.event] === 'function') {
|
|
IFrameHelper.events[message.event](message);
|
|
}
|
|
};
|
|
},
|
|
initWindowSizeListener: () => {
|
|
window.addEventListener('resize', () => IFrameHelper.toggleCloseButton());
|
|
},
|
|
preventDefaultScroll: () => {
|
|
widgetHolder.addEventListener('wheel', event => {
|
|
const deltaY = event.deltaY;
|
|
const contentHeight = widgetHolder.scrollHeight;
|
|
const visibleHeight = widgetHolder.offsetHeight;
|
|
const scrollTop = widgetHolder.scrollTop;
|
|
|
|
if (
|
|
(scrollTop === 0 && deltaY < 0) ||
|
|
(visibleHeight + scrollTop === contentHeight && deltaY > 0)
|
|
) {
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
},
|
|
|
|
setFrameHeightToFitContent: (extraHeight, isFixedHeight) => {
|
|
const iframe = IFrameHelper.getAppFrame();
|
|
const updatedIframeHeight = isFixedHeight ? `${extraHeight}px` : '100%';
|
|
|
|
if (iframe)
|
|
iframe.setAttribute('style', `height: ${updatedIframeHeight} !important`);
|
|
},
|
|
|
|
setupAudioListeners: () => {
|
|
const { baseUrl = '' } = window.$chatwoot;
|
|
getAlertAudio(baseUrl, 'widget').then(() =>
|
|
initOnEvents.forEach(event => {
|
|
document.removeEventListener(
|
|
event,
|
|
IFrameHelper.setupAudioListeners,
|
|
false
|
|
);
|
|
})
|
|
);
|
|
},
|
|
|
|
events: {
|
|
loaded: message => {
|
|
updateAuthCookie(message.config.authToken);
|
|
window.$chatwoot.hasLoaded = true;
|
|
IFrameHelper.sendMessage('config-set', {
|
|
locale: window.$chatwoot.locale,
|
|
position: window.$chatwoot.position,
|
|
hideMessageBubble: window.$chatwoot.hideMessageBubble,
|
|
showPopoutButton: window.$chatwoot.showPopoutButton,
|
|
widgetStyle: window.$chatwoot.widgetStyle,
|
|
darkMode: window.$chatwoot.darkMode,
|
|
});
|
|
IFrameHelper.onLoad({
|
|
widgetColor: message.config.channelConfig.widgetColor,
|
|
});
|
|
IFrameHelper.toggleCloseButton();
|
|
|
|
if (window.$chatwoot.user) {
|
|
IFrameHelper.sendMessage('set-user', window.$chatwoot.user);
|
|
}
|
|
|
|
window.playAudioAlert = () => {};
|
|
|
|
initOnEvents.forEach(e => {
|
|
document.addEventListener(e, IFrameHelper.setupAudioListeners, false);
|
|
});
|
|
|
|
if (!window.$chatwoot.resetTriggered) {
|
|
dispatchWindowEvent({ eventName: CHATWOOT_READY });
|
|
}
|
|
},
|
|
error: ({ errorType, data }) => {
|
|
dispatchWindowEvent({ eventName: CHATWOOT_ERROR, data: data });
|
|
|
|
if (errorType === SET_USER_ERROR) {
|
|
Cookies.remove(getUserCookieName());
|
|
}
|
|
},
|
|
|
|
setBubbleLabel(message) {
|
|
setBubbleText(window.$chatwoot.launcherTitle || message.label);
|
|
},
|
|
|
|
setAuthCookie({ data: { widgetAuthToken } }) {
|
|
updateAuthCookie(widgetAuthToken);
|
|
},
|
|
|
|
toggleBubble: state => {
|
|
let bubbleState = {};
|
|
if (state === 'open') {
|
|
bubbleState.toggleValue = true;
|
|
} else if (state === 'close') {
|
|
bubbleState.toggleValue = false;
|
|
}
|
|
|
|
onBubbleClick(bubbleState);
|
|
},
|
|
|
|
popoutChatWindow: ({ baseUrl, websiteToken, locale }) => {
|
|
const cwCookie = Cookies.get('cw_conversation');
|
|
window.$chatwoot.toggle('close');
|
|
popoutChatWindow(baseUrl, websiteToken, locale, cwCookie);
|
|
},
|
|
|
|
closeWindow: () => {
|
|
onBubbleClick({ toggleValue: false });
|
|
removeUnreadClass();
|
|
},
|
|
|
|
onBubbleToggle: isOpen => {
|
|
IFrameHelper.sendMessage('toggle-open', { isOpen });
|
|
if (isOpen) {
|
|
IFrameHelper.pushEvent('webwidget.triggered');
|
|
}
|
|
},
|
|
onLocationChange: ({ referrerURL, referrerHost }) => {
|
|
IFrameHelper.sendMessage('change-url', {
|
|
referrerURL,
|
|
referrerHost,
|
|
});
|
|
},
|
|
updateIframeHeight: message => {
|
|
const { extraHeight = 0, isFixedHeight } = message;
|
|
|
|
IFrameHelper.setFrameHeightToFitContent(extraHeight, isFixedHeight);
|
|
},
|
|
|
|
setUnreadMode: () => {
|
|
addUnreadClass();
|
|
onBubbleClick({ toggleValue: true });
|
|
},
|
|
|
|
resetUnreadMode: () => removeUnreadClass(),
|
|
handleNotificationDot: event => {
|
|
if (window.$chatwoot.hideMessageBubble) {
|
|
return;
|
|
}
|
|
|
|
const bubbleElement = document.querySelector('.woot-widget-bubble');
|
|
if (
|
|
event.unreadMessageCount > 0 &&
|
|
!bubbleElement.classList.contains('unread-notification')
|
|
) {
|
|
addClasses(bubbleElement, 'unread-notification');
|
|
} else if (event.unreadMessageCount === 0) {
|
|
removeClasses(bubbleElement, 'unread-notification');
|
|
}
|
|
},
|
|
|
|
closeChat: () => {
|
|
onBubbleClick({ toggleValue: false });
|
|
},
|
|
|
|
playAudio: () => {
|
|
window.playAudioAlert();
|
|
},
|
|
},
|
|
pushEvent: eventName => {
|
|
IFrameHelper.sendMessage('push-event', { eventName });
|
|
},
|
|
|
|
onLoad: ({ widgetColor }) => {
|
|
const iframe = IFrameHelper.getAppFrame();
|
|
iframe.style.visibility = '';
|
|
iframe.setAttribute('id', `chatwoot_live_chat_widget`);
|
|
|
|
if (IFrameHelper.getBubbleHolder().length) {
|
|
return;
|
|
}
|
|
createBubbleHolder(window.$chatwoot.hideMessageBubble);
|
|
onLocationChangeListener();
|
|
|
|
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';
|
|
}
|
|
|
|
if (isWidgetColorLighter(widgetColor)) {
|
|
className += ' woot-widget-bubble-color--lighter';
|
|
closeBtnClassName += ' woot-widget-bubble-color--lighter';
|
|
}
|
|
|
|
const chatIcon = createBubbleIcon({
|
|
className,
|
|
path: bubbleSVG,
|
|
target: chatBubble,
|
|
});
|
|
|
|
addClasses(closeBubble, closeBtnClassName);
|
|
|
|
chatIcon.style.background = widgetColor;
|
|
closeBubble.style.background = widgetColor;
|
|
|
|
bubbleHolder.appendChild(chatIcon);
|
|
bubbleHolder.appendChild(closeBubble);
|
|
bubbleHolder.appendChild(createNotificationBubble());
|
|
onClickChatBubble();
|
|
},
|
|
toggleCloseButton: () => {
|
|
let isMobile = false;
|
|
if (window.matchMedia('(max-width: 668px)').matches) {
|
|
isMobile = true;
|
|
}
|
|
IFrameHelper.sendMessage('toggle-close-button', { isMobile });
|
|
},
|
|
};
|