@envive-ai/react-widgets-v3 0.3.38 → 0.3.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CXIntegration/implementations/useFreshChatUnifiedCXButton.cjs +76 -0
- package/dist/CXIntegration/implementations/useFreshChatUnifiedCXButton.js +75 -0
- package/dist/CXIntegration/implementations/useHelpScoutUnifiedCXButton.cjs +110 -25
- package/dist/CXIntegration/implementations/useHelpScoutUnifiedCXButton.js +110 -25
- package/dist/CXIntegration/implementations/useTalkdeskUnifiedCXButton.cjs +12 -6
- package/dist/CXIntegration/implementations/useTalkdeskUnifiedCXButton.js +12 -6
- package/dist/CXIntegration/types.cjs +1 -0
- package/dist/CXIntegration/types.js +1 -0
- package/dist/CXIntegration/utils/functions.cjs +2 -0
- package/dist/CXIntegration/utils/functions.js +2 -0
- package/dist/debug/chatEmbed.cjs +1 -1
- package/dist/debug/chatEmbed.js +1 -1
- package/dist/debug/reportIssue.cjs +1 -1
- package/dist/debug/reportIssue.js +1 -1
- package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
- package/dist/hocs/withBaseWidget/withBaseWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SearchResults/SearchResults.d.ts +2 -2
- package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.ts +2 -2
- package/dist/packages/widgets/dist/SuggestionBar/SuggestionBar.d.ts +2 -2
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.cjs +6 -6
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.js +6 -6
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.cjs +4 -4
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
- package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.js +4 -4
- package/dist/widgets/FloatingChatWidget/FloatingChatOverlay.cjs +3 -0
- package/dist/widgets/FloatingChatWidget/FloatingChatOverlay.js +3 -0
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +3 -3
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.ts +2 -2
- package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +3 -3
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.cjs +1 -1
- package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.js +1 -1
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.cts +2 -2
- package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +3 -3
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
- package/dist/widgets/ProductCardWidget/ProductCardWidget.js +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.cjs +5 -5
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
- package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.js +5 -5
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.cjs +3 -3
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.js +3 -3
- package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.ts +2 -2
- package/dist/widgets/SocialProofWidget/SocialProofWidget.cjs +6 -6
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
- package/dist/widgets/SocialProofWidget/SocialProofWidget.js +6 -6
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.cjs +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
- package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.js +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
- package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.ts +2 -2
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.cjs +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.ts +3 -3
- package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.js +3 -3
- package/dist/widgets/dist/SearchResults/SearchResults.d.cts +2 -2
- package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
- package/dist/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.cts +2 -2
- package/dist/widgets/dist/SuggestionBar/SuggestionBar.d.cts +2 -2
- package/dist/widgets/hooks/useGetWidgetStatus.cjs +1 -1
- package/dist/widgets/hooks/useGetWidgetStatus.js +1 -1
- package/dist/widgets/utils/functions.cjs +1 -1
- package/dist/widgets/utils/functions.js +1 -1
- package/package.json +1 -1
- package/src/CXIntegration/implementations/useFreshChatUnifiedCXButton.ts +132 -0
- package/src/CXIntegration/implementations/useHelpScoutUnifiedCXButton.ts +184 -54
- package/src/CXIntegration/implementations/useTalkdeskUnifiedCXButton.ts +12 -5
- package/src/CXIntegration/types.ts +1 -0
- package/src/CXIntegration/utils/functions.ts +4 -0
- package/src/widgets/FloatingChatWidget/FloatingChatOverlay.tsx +3 -0
|
@@ -1,102 +1,232 @@
|
|
|
1
1
|
import { SelectorFactory } from '@envive-ai/react-hooks/application/utils';
|
|
2
2
|
import { useElementObserver } from '@envive-ai/react-hooks/hooks/ElementObserver';
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
3
4
|
import { FLOATING_BUTTON_ID } from '../../widgets/FloatingChatWidget/constants';
|
|
4
5
|
import { CustomerServiceImplProps, UnifiedCXButton } from '../types';
|
|
5
6
|
|
|
6
7
|
const BEACON_CONTAINER_ID = 'beacon-container';
|
|
8
|
+
const FAB_BUTTON_SELECTOR = '.BeaconFabButtonFrame';
|
|
9
|
+
const BEACON_WIDGET_SELECTOR = '.BeaconContainer';
|
|
10
|
+
// HelpScout's container may render the widget either as a styled `.BeaconContainer` or
|
|
11
|
+
// (e.g. in the "Instant Answers" view) inside an iframe. We treat either as "open".
|
|
12
|
+
const BEACON_OPEN_CHILD_SELECTOR = '.BeaconContainer, iframe, [class*="Beacon"][class*="ontainer"]';
|
|
7
13
|
|
|
8
14
|
interface UseHelpScoutUnifiedCXButtonProps extends CustomerServiceImplProps {}
|
|
9
15
|
|
|
16
|
+
type BeaconApi = (command: string, ...args: unknown[]) => void;
|
|
17
|
+
|
|
18
|
+
const getBeaconApi = (): BeaconApi | undefined => {
|
|
19
|
+
const beacon = (window as unknown as { Beacon?: BeaconApi }).Beacon;
|
|
20
|
+
return typeof beacon === 'function' ? beacon : undefined;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const getBeaconContainer = (): HTMLElement | null => document.getElementById(BEACON_CONTAINER_ID);
|
|
24
|
+
|
|
25
|
+
const getFabButton = (): HTMLElement | null => {
|
|
26
|
+
return (getBeaconContainer()?.querySelector(FAB_BUTTON_SELECTOR) as HTMLElement) ?? null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const getFloatingButtonEl = (): HTMLElement | null => document.getElementById(FLOATING_BUTTON_ID);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Detects whether the HelpScout beacon is currently visible/open.
|
|
33
|
+
* We use multiple signals because HelpScout has different "views"
|
|
34
|
+
* (chat, instant answers) that may use different class names.
|
|
35
|
+
*/
|
|
36
|
+
const isBeaconCurrentlyOpen = (): boolean => {
|
|
37
|
+
const container = getBeaconContainer();
|
|
38
|
+
if (!container) return false;
|
|
39
|
+
|
|
40
|
+
// Signal 1: a `.BeaconContainer` exists with an enter-* class
|
|
41
|
+
const beaconWidget = container.querySelector(BEACON_WIDGET_SELECTOR);
|
|
42
|
+
if (beaconWidget) {
|
|
43
|
+
const cl = beaconWidget.classList;
|
|
44
|
+
if (
|
|
45
|
+
cl.contains('BeaconContainer-enter-done') ||
|
|
46
|
+
cl.contains('BeaconContainer-enter-active') ||
|
|
47
|
+
cl.contains('BeaconContainer-enter')
|
|
48
|
+
) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (
|
|
52
|
+
cl.contains('BeaconContainer-exit') ||
|
|
53
|
+
cl.contains('BeaconContainer-exit-active') ||
|
|
54
|
+
cl.contains('BeaconContainer-exit-done')
|
|
55
|
+
) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Signal 2: any non-FAB visible child in the container means the panel is rendered
|
|
61
|
+
const children = Array.from(container.children);
|
|
62
|
+
return children.some(child => {
|
|
63
|
+
if (child.matches(FAB_BUTTON_SELECTOR)) return false;
|
|
64
|
+
const rect = (child as HTMLElement).getBoundingClientRect();
|
|
65
|
+
return rect.width > 50 && rect.height > 50;
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Force-hides the Envive floating button via direct DOM manipulation. This is a
|
|
71
|
+
* safety net for cases where React state alone doesn't unmount the element fast
|
|
72
|
+
* enough (or at all), so we never get a flash of the floating button on top of
|
|
73
|
+
* the merchant's CX UI.
|
|
74
|
+
*/
|
|
75
|
+
const forceHideFloatingButton = () => {
|
|
76
|
+
const el = getFloatingButtonEl();
|
|
77
|
+
if (el) el.style.display = 'none';
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Restores the Envive floating button display, letting React's render logic take
|
|
82
|
+
* over again.
|
|
83
|
+
*/
|
|
84
|
+
const forceShowFloatingButton = () => {
|
|
85
|
+
const el = getFloatingButtonEl();
|
|
86
|
+
if (el && el.style.display === 'none') el.style.display = '';
|
|
87
|
+
};
|
|
88
|
+
|
|
10
89
|
export const useHelpScoutUnifiedCXButton = ({
|
|
11
90
|
onSwitchToAgent,
|
|
91
|
+
onCXClose,
|
|
12
92
|
suppressMerchantButton,
|
|
13
93
|
}: UseHelpScoutUnifiedCXButtonProps): UnifiedCXButton => {
|
|
14
94
|
const beaconContainer = useElementObserver(SelectorFactory.id(BEACON_CONTAINER_ID));
|
|
15
95
|
const enviveFloatingButton = useElementObserver(SelectorFactory.id(FLOATING_BUTTON_ID));
|
|
16
96
|
|
|
97
|
+
// Track previous open state so we only fire onCXClose on a real open→closed
|
|
98
|
+
// transition, not on initial render or during the open animation.
|
|
99
|
+
const wasOpenRef = useRef(false);
|
|
100
|
+
|
|
101
|
+
// Keep latest callbacks/flags in refs so the Beacon API effect can read them
|
|
102
|
+
// without re-binding listeners on every render.
|
|
103
|
+
const onCXCloseRef = useRef(onCXClose);
|
|
104
|
+
const suppressMerchantButtonRef = useRef(suppressMerchantButton);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
onCXCloseRef.current = onCXClose;
|
|
107
|
+
suppressMerchantButtonRef.current = suppressMerchantButton;
|
|
108
|
+
}, [onCXClose, suppressMerchantButton]);
|
|
109
|
+
|
|
110
|
+
const handleBeaconOpened = () => {
|
|
111
|
+
wasOpenRef.current = true;
|
|
112
|
+
// Always force-hide the Envive floating button when the merchant CX opens.
|
|
113
|
+
// This is the safety net regardless of suppressMerchantButton.
|
|
114
|
+
forceHideFloatingButton();
|
|
115
|
+
if (suppressMerchantButtonRef.current) {
|
|
116
|
+
const fabButton = getFabButton();
|
|
117
|
+
if (fabButton) fabButton.style.display = '';
|
|
118
|
+
enviveFloatingButton.hide();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const handleBeaconClosed = () => {
|
|
123
|
+
if (!wasOpenRef.current) return;
|
|
124
|
+
wasOpenRef.current = false;
|
|
125
|
+
onCXCloseRef.current?.();
|
|
126
|
+
forceShowFloatingButton();
|
|
127
|
+
if (suppressMerchantButtonRef.current) {
|
|
128
|
+
const fabButton = getFabButton();
|
|
129
|
+
if (fabButton) fabButton.style.display = 'none';
|
|
130
|
+
enviveFloatingButton.show();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
17
134
|
const toggle = () => {
|
|
18
135
|
onSwitchToAgent();
|
|
136
|
+
// Force hide BEFORE opening HelpScout so there's no flash of the floating
|
|
137
|
+
// button next to the merchant's CX panel.
|
|
138
|
+
wasOpenRef.current = true;
|
|
139
|
+
forceHideFloatingButton();
|
|
140
|
+
if (suppressMerchantButton) {
|
|
141
|
+
enviveFloatingButton.hide();
|
|
142
|
+
}
|
|
19
143
|
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
(
|
|
144
|
+
const beacon = getBeaconApi();
|
|
145
|
+
if (beacon) {
|
|
146
|
+
beacon('open');
|
|
23
147
|
} else {
|
|
24
|
-
// Fallback:
|
|
25
|
-
const
|
|
26
|
-
const fabButton = container?.querySelector('.BeaconFabButtonFrame') as HTMLElement;
|
|
148
|
+
// Fallback: find and click the FAB button
|
|
149
|
+
const fabButton = getFabButton();
|
|
27
150
|
if (fabButton) {
|
|
28
151
|
fabButton.style.display = '';
|
|
29
152
|
fabButton.click();
|
|
30
153
|
}
|
|
31
154
|
}
|
|
32
|
-
|
|
33
|
-
if (suppressMerchantButton) {
|
|
34
|
-
enviveFloatingButton.hide();
|
|
35
|
-
}
|
|
36
155
|
};
|
|
37
156
|
|
|
38
157
|
const isHelpScoutButtonEnabled = () => {
|
|
39
|
-
|
|
40
|
-
const beaconContainerEl = document.getElementById('beacon-container');
|
|
158
|
+
const beaconContainerEl = getBeaconContainer();
|
|
41
159
|
if (!beaconContainerEl) return false;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const fabButton = beaconContainerEl.querySelector('.BeaconFabButtonFrame');
|
|
45
|
-
const hasBeaconAPI = typeof (window as any).Beacon !== 'undefined';
|
|
46
|
-
|
|
160
|
+
const fabButton = beaconContainerEl.querySelector(FAB_BUTTON_SELECTOR);
|
|
161
|
+
const hasBeaconAPI = !!getBeaconApi();
|
|
47
162
|
return !!(fabButton || hasBeaconAPI);
|
|
48
163
|
};
|
|
49
164
|
|
|
50
165
|
const isSwitchEnabled = () => isHelpScoutButtonEnabled();
|
|
51
166
|
|
|
52
|
-
//
|
|
167
|
+
// Use the official HelpScout Beacon API events for the most reliable open/close
|
|
168
|
+
// detection. We use empty deps + refs so this binds exactly once per mount, not
|
|
169
|
+
// every render — important because the Beacon listener registry doesn't dedupe.
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const beacon = getBeaconApi();
|
|
172
|
+
if (!beacon) return undefined;
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
beacon('on', 'open', handleBeaconOpened);
|
|
176
|
+
beacon('on', 'close', handleBeaconClosed);
|
|
177
|
+
} catch {
|
|
178
|
+
// Beacon may not be initialized yet — the MutationObserver fallback will
|
|
179
|
+
// still detect the open/close transitions below.
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return () => {
|
|
183
|
+
try {
|
|
184
|
+
beacon('off', 'open', handleBeaconOpened);
|
|
185
|
+
beacon('off', 'close', handleBeaconClosed);
|
|
186
|
+
} catch {
|
|
187
|
+
// ignore — beacon may already be torn down
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
191
|
+
}, []);
|
|
192
|
+
|
|
193
|
+
// Hide the merchant's FAB button when the beacon container is added. Do NOT
|
|
194
|
+
// blindly re-show the Envive floating button here — if `Beacon('open')` creates
|
|
195
|
+
// the container in response to a "live support" click, this would un-hide the
|
|
196
|
+
// floating button the user just hid via toggle().
|
|
53
197
|
beaconContainer.onAdd(() => {
|
|
54
198
|
if (suppressMerchantButton) {
|
|
55
|
-
const fabButton =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
199
|
+
const fabButton = getFabButton();
|
|
200
|
+
if (fabButton) fabButton.style.display = 'none';
|
|
201
|
+
}
|
|
202
|
+
// If the beacon happens to mount in an already-open state, treat it like a
|
|
203
|
+
// proper open transition so the floating button is hidden.
|
|
204
|
+
if (isBeaconCurrentlyOpen()) {
|
|
205
|
+
handleBeaconOpened();
|
|
206
|
+
} else if (suppressMerchantButton) {
|
|
61
207
|
enviveFloatingButton.show();
|
|
62
208
|
}
|
|
63
209
|
});
|
|
64
210
|
|
|
65
|
-
//
|
|
66
|
-
//
|
|
211
|
+
// MutationObserver fallback for cases where the Beacon API events don't fire
|
|
212
|
+
// (older Beacon versions, opened via direct DOM manipulation, etc.). The logic
|
|
213
|
+
// here is broader than just checking enter/exit classes because the "Instant
|
|
214
|
+
// Answers" view can use different DOM markers.
|
|
67
215
|
beaconContainer.onChange(el => {
|
|
68
|
-
if (el
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const { classList } = beaconWidget;
|
|
75
|
-
|
|
76
|
-
// When beacon is open (has enter-done class)
|
|
77
|
-
if (
|
|
78
|
-
classList.contains('BeaconContainer-enter-done') ||
|
|
79
|
-
classList.contains('BeaconContainer-enter-active')
|
|
80
|
-
) {
|
|
81
|
-
fabButton.style.display = '';
|
|
82
|
-
enviveFloatingButton.hide();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// When beacon is closed (has exit class)
|
|
86
|
-
if (
|
|
87
|
-
classList.contains('BeaconContainer-exit') ||
|
|
88
|
-
classList.contains('BeaconContainer-exit-active')
|
|
89
|
-
) {
|
|
90
|
-
fabButton.style.display = 'none';
|
|
91
|
-
enviveFloatingButton.show();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
216
|
+
if (!el) return;
|
|
217
|
+
const open = isBeaconCurrentlyOpen();
|
|
218
|
+
if (open && !wasOpenRef.current) {
|
|
219
|
+
handleBeaconOpened();
|
|
220
|
+
} else if (!open && wasOpenRef.current) {
|
|
221
|
+
handleBeaconClosed();
|
|
94
222
|
}
|
|
95
223
|
});
|
|
96
224
|
|
|
97
|
-
// Cleanup when container is removed
|
|
225
|
+
// Cleanup when the entire container is removed.
|
|
98
226
|
beaconContainer.onRemove(() => {
|
|
99
|
-
if (
|
|
227
|
+
if (wasOpenRef.current) {
|
|
228
|
+
handleBeaconClosed();
|
|
229
|
+
} else if (suppressMerchantButton) {
|
|
100
230
|
enviveFloatingButton.show();
|
|
101
231
|
}
|
|
102
232
|
});
|
|
@@ -7,6 +7,7 @@ interface UseTalkdeskUnifiedCXButtonProps extends CustomerServiceImplProps {}
|
|
|
7
7
|
|
|
8
8
|
export const useTalkdeskUnifiedCXButton = ({
|
|
9
9
|
onSwitchToAgent,
|
|
10
|
+
onCXClose,
|
|
10
11
|
suppressMerchantButton,
|
|
11
12
|
}: UseTalkdeskUnifiedCXButtonProps): UnifiedCXButton => {
|
|
12
13
|
const talkdeskButton = useElementObserver(SelectorFactory.id('talkdesk-chat-widget-trigger'));
|
|
@@ -62,25 +63,31 @@ export const useTalkdeskUnifiedCXButton = ({
|
|
|
62
63
|
|
|
63
64
|
// Track widget visibility changes
|
|
64
65
|
talkdeskWidget.onChange(el => {
|
|
65
|
-
if (el
|
|
66
|
+
if (el) {
|
|
66
67
|
const ariaHidden = el.getAttribute('aria-hidden');
|
|
67
68
|
|
|
68
69
|
// Widget is open (aria-hidden="false")
|
|
69
70
|
if (ariaHidden === 'false') {
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
if (suppressMerchantButton) {
|
|
72
|
+
talkdeskButton.show();
|
|
73
|
+
enviveFloatingButton.hide();
|
|
74
|
+
}
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
// Widget is closed (aria-hidden="true")
|
|
75
78
|
if (ariaHidden === 'true') {
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
onCXClose?.();
|
|
80
|
+
if (suppressMerchantButton) {
|
|
81
|
+
talkdeskButton.hide();
|
|
82
|
+
enviveFloatingButton.show();
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
});
|
|
81
87
|
|
|
82
88
|
// Cleanup when container is removed
|
|
83
89
|
talkdeskContainer.onRemove(() => {
|
|
90
|
+
onCXClose?.();
|
|
84
91
|
if (suppressMerchantButton) {
|
|
85
92
|
talkdeskButton.hide();
|
|
86
93
|
enviveFloatingButton.show();
|
|
@@ -13,6 +13,7 @@ import { useKustomerUnifiedCXButton } from '../implementations/useKustomerUnifie
|
|
|
13
13
|
import { useHelpScoutUnifiedCXButton } from '../implementations/useHelpScoutUnifiedCXButton';
|
|
14
14
|
import { useTalkdeskUnifiedCXButton } from '../implementations/useTalkdeskUnifiedCXButton';
|
|
15
15
|
import { useEightByEightUnifiedCXButton } from '../implementations/useEightByEightUnifiedCXButton';
|
|
16
|
+
import { useFreshChatUnifiedCXButton } from '../implementations/useFreshChatUnifiedCXButton';
|
|
16
17
|
import { useDefaultUnifiedCXButton } from '../implementations/useDefaultUnifiedCXButton';
|
|
17
18
|
|
|
18
19
|
export const findCustomerServiceImpl = (
|
|
@@ -57,6 +58,9 @@ export const findCustomerServiceImpl = (
|
|
|
57
58
|
if (provider === CustomerServiceType.eightByEight) {
|
|
58
59
|
return useEightByEightUnifiedCXButton;
|
|
59
60
|
}
|
|
61
|
+
if (provider === CustomerServiceType.freshchat) {
|
|
62
|
+
return useFreshChatUnifiedCXButton;
|
|
63
|
+
}
|
|
60
64
|
|
|
61
65
|
return useDefaultUnifiedCXButton;
|
|
62
66
|
};
|