Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
345
research/chatwoot/app/javascript/sdk/IFrameHelper.js
Normal file
345
research/chatwoot/app/javascript/sdk/IFrameHelper.js
Normal file
@@ -0,0 +1,345 @@
|
||||
import Cookies from 'js-cookie';
|
||||
import {
|
||||
addClasses,
|
||||
loadCSS,
|
||||
removeClasses,
|
||||
onLocationChangeListener,
|
||||
} from './DOMHelpers';
|
||||
import {
|
||||
body,
|
||||
widgetHolder,
|
||||
createBubbleHolder,
|
||||
createBubbleIcon,
|
||||
bubbleSVG,
|
||||
chatBubble,
|
||||
closeBubble,
|
||||
bubbleHolder,
|
||||
onClickChatBubble,
|
||||
onBubbleClick,
|
||||
setBubbleText,
|
||||
addUnreadClass,
|
||||
removeUnreadClass,
|
||||
} from './bubbleHelpers';
|
||||
import { isWidgetColorLighter } from 'shared/helpers/colorHelper';
|
||||
import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper';
|
||||
import {
|
||||
CHATWOOT_ERROR,
|
||||
CHATWOOT_POSTBACK,
|
||||
CHATWOOT_READY,
|
||||
} from '../widget/constants/sdkEvents';
|
||||
import { SET_USER_ERROR } from '../widget/constants/errorTypes';
|
||||
import { getUserCookieName, setCookieWithDomain } from './cookieHelpers';
|
||||
import {
|
||||
getAlertAudio,
|
||||
initOnEvents,
|
||||
} from 'shared/helpers/AudioNotificationHelper';
|
||||
import { isFlatWidgetStyle } from './settingsHelper';
|
||||
import { popoutChatWindow } from '../widget/helpers/popoutHelper';
|
||||
import addHours from 'date-fns/addHours';
|
||||
|
||||
const updateAuthCookie = (cookieContent, baseDomain = '') =>
|
||||
setCookieWithDomain('cw_conversation', cookieContent, {
|
||||
baseDomain,
|
||||
});
|
||||
|
||||
const updateCampaignReadStatus = baseDomain => {
|
||||
const expireBy = addHours(new Date(), 1);
|
||||
setCookieWithDomain('cw_snooze_campaigns_till', Number(expireBy), {
|
||||
expires: expireBy,
|
||||
baseDomain,
|
||||
});
|
||||
};
|
||||
|
||||
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.id = 'cw-widget-holder';
|
||||
widgetHolder.dataset.turboPermanent = true;
|
||||
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, { type: 'widget', alertTone: 'ding' }).then(() =>
|
||||
initOnEvents.forEach(event => {
|
||||
document.removeEventListener(
|
||||
event,
|
||||
IFrameHelper.setupAudioListeners,
|
||||
false
|
||||
);
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
events: {
|
||||
loaded: message => {
|
||||
updateAuthCookie(message.config.authToken, window.$chatwoot.baseDomain);
|
||||
window.$chatwoot.hasLoaded = true;
|
||||
const campaignsSnoozedTill = Cookies.get('cw_snooze_campaigns_till');
|
||||
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,
|
||||
showUnreadMessagesDialog: window.$chatwoot.showUnreadMessagesDialog,
|
||||
campaignsSnoozedTill,
|
||||
welcomeTitle: window.$chatwoot.welcomeTitle,
|
||||
welcomeDescription: window.$chatwoot.welcomeDescription,
|
||||
availableMessage: window.$chatwoot.availableMessage,
|
||||
unavailableMessage: window.$chatwoot.unavailableMessage,
|
||||
enableFileUpload: window.$chatwoot.enableFileUpload,
|
||||
enableEmojiPicker: window.$chatwoot.enableEmojiPicker,
|
||||
enableEndConversation: window.$chatwoot.enableEndConversation,
|
||||
});
|
||||
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());
|
||||
}
|
||||
},
|
||||
onEvent({ eventIdentifier: eventName, data }) {
|
||||
dispatchWindowEvent({ eventName, data });
|
||||
},
|
||||
setBubbleLabel(message) {
|
||||
setBubbleText(window.$chatwoot.launcherTitle || message.label);
|
||||
},
|
||||
|
||||
setAuthCookie({ data: { widgetAuthToken } }) {
|
||||
updateAuthCookie(widgetAuthToken, window.$chatwoot.baseDomain);
|
||||
},
|
||||
|
||||
setCampaignReadOn() {
|
||||
updateCampaignReadStatus(window.$chatwoot.baseDomain);
|
||||
},
|
||||
|
||||
postback(data) {
|
||||
dispatchWindowEvent({
|
||||
eventName: CHATWOOT_POSTBACK,
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
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);
|
||||
onClickChatBubble();
|
||||
},
|
||||
toggleCloseButton: () => {
|
||||
let isMobile = false;
|
||||
if (window.matchMedia('(max-width: 668px)').matches) {
|
||||
isMobile = true;
|
||||
}
|
||||
IFrameHelper.sendMessage('toggle-close-button', { isMobile });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user