Chatwoot/app/javascript/widget/App.vue
2021-10-01 15:03:58 +05:30

338 lines
11 KiB
Vue
Executable file

<template>
<div
id="app"
class="woot-widget-wrap"
:class="{
'is-mobile': isMobile,
'is-widget-right': !isLeftAligned,
'is-bubble-hidden': isChatTriggerHidden,
}"
>
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
</div>
</template>
<script>
import { mapGetters, mapActions, mapMutations } from 'vuex';
import { setHeader } from 'widget/helpers/axios';
import { IFrameHelper, RNHelper } from 'widget/helpers/utils';
import { getLocale } from './helpers/urlParamsHelper';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { isEmptyObject } from 'widget/helpers/utils';
export default {
name: 'App',
data() {
return {
showUnreadView: false,
showCampaignView: false,
isMobile: false,
isChatTriggerHidden: false,
showPopoutButton: false,
isWebWidgetTriggered: false,
showConversationsPage: false,
activePage: '',
};
},
computed: {
...mapGetters({
widgetSettings: 'appConfig/getWidgetSettings',
messageCount: 'conversation/getMessageCount',
unreadMessageCount: 'conversation/getUnreadMessageCount',
campaigns: 'campaign/getCampaigns',
activeCampaign: 'campaign/getActiveCampaign',
}),
isLeftAligned() {
const isLeft = this.widgetPosition === 'left';
return isLeft;
},
isIFrame() {
return IFrameHelper.isIFrame();
},
isRNWebView() {
return RNHelper.isRNWebView();
},
},
watch: {
activeCampaign() {
this.setCampaignView();
},
showUnreadView(newVal) {
if (newVal) {
this.setIframeHeight(this.isMobile);
}
},
showCampaignView(newVal) {
if (newVal) {
this.setIframeHeight(this.isMobile);
}
},
},
mounted() {
const { websiteToken, locale } = window.chatwootWebChannel;
this.setLocale(locale);
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));
}
if (this.isRNWebView) {
this.registerListeners();
this.sendRNWebViewLoadedEvent();
}
this.fetchOrCreateContact();
this.fetchAllConversations();
this.$store.dispatch('conversationAttributes/getAttributes');
this.setWidgetColor(window.chatwootWebChannel);
this.registerUnreadEvents();
this.registerCampaignEvents();
},
methods: {
...mapActions('appConfig', ['setWidgetColor']),
...mapActions('conversation', ['fetchOldConversations', 'setUserLastSeen']),
...mapActions('campaign', ['initCampaigns', 'executeCampaign']),
...mapActions('agent', ['fetchAvailableAgents']),
...mapMutations('events', ['toggleOpen']),
scrollConversationToBottom() {
const container = this.$el.querySelector('.conversation-wrap');
container.scrollTop = container.scrollHeight;
},
setBubbleLabel() {
IFrameHelper.sendMessage({
event: 'setBubbleLabel',
label: this.$t('BUBBLE.LABEL'),
});
},
setIframeHeight(isFixedHeight) {
this.$nextTick(() => {
const extraHeight = this.getExtraSpaceToscroll();
IFrameHelper.sendMessage({
event: 'updateIframeHeight',
isFixedHeight,
extraHeight,
});
});
},
setLocale(locale) {
const { enabledLanguages } = window.chatwootWebChannel;
if (enabledLanguages.some(lang => lang.iso_639_1_code === locale)) {
this.$root.$i18n.locale = locale;
}
},
setPosition(position) {
const widgetPosition = position || 'right';
this.$store.dispatch('appConfig/setWidgetSettings', { widgetPosition });
},
setIsChatTriggerHidden(hideBubble) {
this.$store.dispatch('appConfig/setWidgetSettings', {
isChatTriggerHidden: !!hideBubble,
});
},
registerUnreadEvents() {
bus.$on('on-agent-message-recieved', () => {
if (!this.isIFrame) {
this.setUserLastSeen();
}
this.setUnreadView();
});
bus.$on('on-unread-view-clicked', () => {
this.unsetUnreadView();
this.setUserLastSeen();
});
},
registerCampaignEvents() {
bus.$on('on-campaign-view-clicked', campaignId => {
const { websiteToken } = window.chatwootWebChannel;
this.showCampaignView = false;
this.showUnreadView = false;
this.unsetUnreadView();
this.setUserLastSeen();
this.executeCampaign({ campaignId, websiteToken });
});
},
setPopoutDisplay(showPopoutButton) {
this.showPopoutButton = showPopoutButton;
},
setCampaignView() {
const { messageCount, activeCampaign } = this;
const isCampaignReadyToExecute =
!isEmptyObject(activeCampaign) &&
!messageCount &&
!this.isWebWidgetTriggered;
if (this.isIFrame && isCampaignReadyToExecute) {
this.showCampaignView = true;
IFrameHelper.sendMessage({
event: 'setCampaignMode',
});
this.setIframeHeight(this.isMobile);
}
},
setUnreadView() {
const { unreadMessageCount } = this;
if (this.isIFrame && unreadMessageCount > 0) {
IFrameHelper.sendMessage({
event: 'setUnreadMode',
unreadMessageCount,
});
this.setIframeHeight(this.isMobile);
}
},
unsetUnreadView() {
if (this.isIFrame) {
IFrameHelper.sendMessage({ event: 'resetUnreadMode' });
this.setIframeHeight();
}
},
createWidgetEvents(message) {
const { eventName } = message;
const isWidgetTriggerEvent = eventName === 'webwidget.triggered';
this.isWebWidgetTriggered = true;
if (
isWidgetTriggerEvent &&
(this.showUnreadView || this.showCampaignView)
) {
return;
}
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.setIsChatTriggerHidden(message.hideMessageBubble);
this.$store.dispatch('contacts/get');
} else if (message.event === 'widget-visible') {
this.scrollConversationToBottom();
} else if (message.event === 'change-url') {
const { referrerURL, referrerHost } = message;
this.initCampaigns({ currentURL: referrerURL, websiteToken });
window.referrerURL = referrerURL;
bus.$emit(BUS_EVENTS.SET_REFERRER_HOST, referrerHost);
} 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;
this.$router.replace('unread');
this.showCampaignView = false;
} else if (message.event === 'unset-unread-view') {
this.showUnreadView = false;
this.showCampaignView = false;
} else if (message.event === 'toggle-open') {
this.toggleOpen();
}
});
},
sendLoadedEvent() {
IFrameHelper.sendMessage({
event: 'loaded',
config: {
authToken: window.authToken,
channelConfig: window.chatwootWebChannel,
contactIdentifier: window.contactIdentifier,
},
});
},
sendRNWebViewLoadedEvent() {
RNHelper.sendMessage({
event: 'loaded',
config: {
authToken: window.authToken,
channelConfig: window.chatwootWebChannel,
contactIdentifier: window.contactIdentifier,
},
});
},
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;
},
fetchOrCreateContact() {
if (!window.contactIdentifier) {
this.$store
.dispatch('contactV2/create', {
inboxIdentifier: window.chatwootWebChannel.inboxIdentifier,
user: {},
})
.then(data => {
const { source_id: contactIdentifier } = data;
window.contactIdentifier = contactIdentifier;
this.sendLoadedEvent();
});
} else {
this.$store.dispatch('contactV2/get', {
inboxIdentifier: window.chatwootWebChannel.inboxIdentifier,
contactIdentifier: window.contactIdentifier,
});
}
},
fetchAllConversations() {
this.$store.dispatch('conversationV2/fetchAllConversations', {
inboxIdentifier: window.chatwootWebChannel.inboxIdentifier,
contactIdentifier: window.contactIdentifier,
});
},
setConvView() {
// this.showConversationsPage = true;
this.showCampaignView = false;
this.showUnreadView = false;
},
},
};
</script>
<style lang="scss">
@import '~widget/assets/scss/woot.scss';
</style>