diff --git a/app/javascript/sdk/IFrameHelper.js b/app/javascript/sdk/IFrameHelper.js
index 3ab1ba1f5..ffe2e75b4 100644
--- a/app/javascript/sdk/IFrameHelper.js
+++ b/app/javascript/sdk/IFrameHelper.js
@@ -19,6 +19,8 @@ import {
setBubbleText,
addUnreadClass,
removeUnreadClass,
+ addArticleViewClass,
+ removeArticleViewClass,
} from './bubbleHelpers';
import { isWidgetColorLighter } from 'shared/helpers/colorHelper';
import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper';
@@ -268,6 +270,10 @@ export const IFrameHelper = {
},
resetUnreadMode: () => removeUnreadClass(),
+
+ expandWidget: () => addArticleViewClass(),
+ collapseWidget: () => removeArticleViewClass(),
+
handleNotificationDot: event => {
if (window.$chatwoot.hideMessageBubble) {
return;
diff --git a/app/javascript/sdk/bubbleHelpers.js b/app/javascript/sdk/bubbleHelpers.js
index c53323e27..e46dbee5a 100644
--- a/app/javascript/sdk/bubbleHelpers.js
+++ b/app/javascript/sdk/bubbleHelpers.js
@@ -110,3 +110,13 @@ export const removeUnreadClass = () => {
const holderEl = document.querySelector('.woot-widget-holder');
removeClasses(holderEl, 'has-unread-view');
};
+
+export const addArticleViewClass = () => {
+ const holderEl = document.querySelector('.woot-widget-holder');
+ addClasses(holderEl, 'has-article-view');
+};
+
+export const removeArticleViewClass = () => {
+ const holderEl = document.querySelector('.woot-widget-holder');
+ removeClasses(holderEl, 'has-article-view');
+};
diff --git a/app/javascript/sdk/sdk.js b/app/javascript/sdk/sdk.js
index 095fe80ca..44473c8c8 100644
--- a/app/javascript/sdk/sdk.js
+++ b/app/javascript/sdk/sdk.js
@@ -7,11 +7,13 @@ export const SDK_CSS = `
.woot-widget-holder {
box-shadow: 0 5px 40px rgba(0, 0, 0, .16);
opacity: 1;
- will-change: transform, opacity;
+ will-change: transform, opacity, width, height;
transform: translateY(0);
overflow: hidden !important;
position: fixed !important;
- transition: opacity 0.2s linear, transform 0.25s linear;
+ transition: opacity 0.2s linear, transform 0.25s linear,
+ width 0.3s cubic-bezier(0.4, 0, 0.2, 1),
+ height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 2147483000 !important;
}
@@ -287,6 +289,12 @@ export const SDK_CSS = `
min-height: 250px !important;
width: 400px !important;
}
+
+ .woot-widget-holder.has-article-view {
+ width: min(640px, max(0px, -20px + 100dvw)) !important;
+ height: calc(100% - 125px) !important;
+ max-height: none !important;
+ }
}
.woot-hidden {
diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue
index 0d456fa83..c5ed2f9cc 100755
--- a/app/javascript/widget/App.vue
+++ b/app/javascript/widget/App.vue
@@ -81,6 +81,15 @@ export default {
document.documentElement.dir = value ? 'rtl' : 'ltr';
},
},
+ '$route.name'(routeName, previousRouteName) {
+ // Expansion is driven by the rendered portal page (see the
+ // 'portalPageLoaded' handler) so the widget only widens for article pages.
+ // Here we just collapse when leaving the article view, since the iframe is
+ // torn down then and can no longer signal.
+ if (this.isIFrame && previousRouteName === 'article-viewer') {
+ IFrameHelper.sendMessage({ event: 'collapseWidget' });
+ }
+ },
},
mounted() {
const { websiteToken, locale, widgetColor } = window.chatwootWebChannel;
@@ -342,6 +351,10 @@ export default {
this.setColorScheme(message.darkMode);
} else if (message.event === 'open-article') {
this.openArticle(message.slug);
+ } else if (message.event === 'portalPageLoaded') {
+ IFrameHelper.sendMessage({
+ event: message.isArticle ? 'expandWidget' : 'collapseWidget',
+ });
} else if (message.event === 'toggle-open') {
this.$store.dispatch('appConfig/toggleWidgetOpen', message.isOpen);
diff --git a/app/views/layouts/_portal_scripts.html.erb b/app/views/layouts/_portal_scripts.html.erb
index b1479cace..ef04f5ec7 100644
--- a/app/views/layouts/_portal_scripts.html.erb
+++ b/app/views/layouts/_portal_scripts.html.erb
@@ -88,6 +88,19 @@ html.light {
tocHeader: '<%= I18n.t('public_portal.toc_header') %>'
};
+<% if @is_plain_layout_enabled %>
+
+<% end %>
<% if @portal.channel_web_widget.present? && !@is_plain_layout_enabled %>