@microsoft/omnichannel-chat-widget 0.1.0-main.886e5cf → 0.1.0-main.8cded52

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.
Files changed (75) hide show
  1. package/lib/cjs/common/Constants.js +2 -0
  2. package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
  3. package/lib/cjs/common/utils.js +20 -7
  4. package/lib/cjs/components/headerstateful/HeaderStateful.js +2 -1
  5. package/lib/cjs/components/livechatwidget/common/ActivityStreamHandler.js +44 -0
  6. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +23 -0
  7. package/lib/cjs/components/livechatwidget/{interfaces/IAuthProps.js → common/ActivitySubscriber/IActivitySubscriber.js} +0 -0
  8. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +39 -0
  9. package/lib/cjs/components/livechatwidget/common/ChatAdapterShim.js +70 -0
  10. package/lib/cjs/components/livechatwidget/common/Deferred.js +42 -0
  11. package/lib/cjs/components/livechatwidget/common/createAdapter.js +13 -1
  12. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +31 -30
  13. package/lib/cjs/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -5
  14. package/lib/cjs/components/livechatwidget/common/endChat.js +3 -3
  15. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +4 -0
  16. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +23 -15
  17. package/lib/cjs/components/livechatwidget/common/shareObservable.js +45 -0
  18. package/lib/cjs/components/livechatwidget/common/startChat.js +71 -24
  19. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +86 -41
  20. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +1 -1
  21. package/lib/cjs/components/webchatcontainerstateful/common/mockchatsdk.js +2 -0
  22. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  23. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  24. package/lib/cjs/contexts/createReducer.js +8 -0
  25. package/lib/esm/common/Constants.js +2 -0
  26. package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
  27. package/lib/esm/common/utils.js +14 -5
  28. package/lib/esm/components/headerstateful/HeaderStateful.js +2 -1
  29. package/lib/esm/components/livechatwidget/common/ActivityStreamHandler.js +34 -0
  30. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.js +14 -0
  31. package/lib/esm/components/livechatwidget/{interfaces/IAuthProps.js → common/ActivitySubscriber/IActivitySubscriber.js} +0 -0
  32. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.js +29 -0
  33. package/lib/esm/components/livechatwidget/common/ChatAdapterShim.js +59 -0
  34. package/lib/esm/components/livechatwidget/common/Deferred.js +33 -0
  35. package/lib/esm/components/livechatwidget/common/createAdapter.js +12 -2
  36. package/lib/esm/components/livechatwidget/common/createMarkdown.js +31 -30
  37. package/lib/esm/components/livechatwidget/common/defaultProps/dummyDefaultProps.js +2 -5
  38. package/lib/esm/components/livechatwidget/common/endChat.js +3 -3
  39. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +4 -0
  40. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +24 -17
  41. package/lib/esm/components/livechatwidget/common/shareObservable.js +38 -0
  42. package/lib/esm/components/livechatwidget/common/startChat.js +68 -26
  43. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +85 -43
  44. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +1 -1
  45. package/lib/esm/components/webchatcontainerstateful/common/mockchatsdk.js +2 -0
  46. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  47. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  48. package/lib/esm/contexts/createReducer.js +8 -0
  49. package/lib/types/common/Constants.d.ts +1 -0
  50. package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -0
  51. package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -1
  52. package/lib/types/common/utils.d.ts +5 -4
  53. package/lib/types/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.d.ts +1 -1
  54. package/lib/types/components/headerstateful/interfaces/IHeaderStatefulParams.d.ts +2 -1
  55. package/lib/types/components/livechatwidget/common/ActivityStreamHandler.d.ts +14 -0
  56. package/lib/types/components/livechatwidget/common/ActivitySubscriber/DefaultActivitySubscriber.d.ts +5 -0
  57. package/lib/types/components/livechatwidget/common/ActivitySubscriber/IActivitySubscriber.d.ts +6 -0
  58. package/lib/types/components/livechatwidget/common/ActivitySubscriber/PauseActivitySubscriber.d.ts +7 -0
  59. package/lib/types/components/livechatwidget/common/ChatAdapterShim.d.ts +7 -0
  60. package/lib/types/components/livechatwidget/common/Deferred.d.ts +9 -0
  61. package/lib/types/components/livechatwidget/common/endChat.d.ts +1 -1
  62. package/lib/types/components/livechatwidget/common/reconnectChatHelper.d.ts +5 -5
  63. package/lib/types/components/livechatwidget/common/setPostChatContextAndLoadSurvey.d.ts +1 -1
  64. package/lib/types/components/livechatwidget/common/shareObservable.d.ts +1 -0
  65. package/lib/types/components/livechatwidget/common/startChat.d.ts +3 -3
  66. package/lib/types/components/livechatwidget/common/startProactiveChat.d.ts +1 -1
  67. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetControlProps.d.ts +1 -0
  68. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +1 -2
  69. package/lib/types/components/webchatcontainerstateful/common/mockchatsdk.d.ts +1 -0
  70. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +1 -1
  71. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/avatarMiddleware.d.ts +1 -1
  72. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  73. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  74. package/package.json +4 -3
  75. package/lib/types/components/livechatwidget/interfaces/IAuthProps.d.ts +0 -4
@@ -8,19 +8,23 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
8
8
  import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
9
9
  import { createAdapter } from "./createAdapter";
10
10
  import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
11
- import { createTimer, getStateFromCache, isUndefinedOrEmpty } from "../../../common/utils";
11
+ import { createTimer, getStateFromCache, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
12
12
  import { getReconnectIdForAuthenticatedChat, handleRedirectUnauthenticatedReconnectChat } from "./reconnectChatHelper";
13
13
  import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
14
14
  import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
15
15
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ import { ActivityStreamHandler } from "./ActivityStreamHandler"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+
17
18
  let optionalParams = {}; // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
19
 
20
+ let widgetInstanceId; // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+
19
22
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
20
- var _props$reconnectChatP;
23
+ var _props$controlProps, _props$reconnectChatP;
21
24
 
22
25
  optionalParams = {}; //Resetting to ensure no stale values
23
- // Can connect to existing chat session
26
+
27
+ widgetInstanceId = props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.widgetInstanceId; // Can connect to existing chat session
24
28
 
25
29
  if (await canConnectToExistingChat(props, chatSDK, state, dispatch, setAdapter)) {
26
30
  return;
@@ -30,7 +34,7 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
30
34
  if ((_props$reconnectChatP = props.reconnectChatPaneProps) !== null && _props$reconnectChatP !== void 0 && _props$reconnectChatP.reconnectId) {
31
35
  var _props$reconnectChatP2, _props$reconnectChatP3;
32
36
 
33
- await handleRedirectUnauthenticatedReconnectChat(chatSDK, props.authProps, dispatch, setAdapter, initStartChat, (_props$reconnectChatP2 = props.reconnectChatPaneProps) === null || _props$reconnectChatP2 === void 0 ? void 0 : _props$reconnectChatP2.reconnectId, (_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.redirectInSameWindow);
37
+ await handleRedirectUnauthenticatedReconnectChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, initStartChat, (_props$reconnectChatP2 = props.reconnectChatPaneProps) === null || _props$reconnectChatP2 === void 0 ? void 0 : _props$reconnectChatP2.reconnectId, (_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.redirectInSameWindow);
34
38
  return;
35
39
  } // Getting reconnectId for authenticated chat
36
40
 
@@ -47,19 +51,17 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
47
51
  payload: ConversationState.ReconnectChat
48
52
  });
49
53
  return;
50
- } // Set custom context params
51
-
54
+ } // Setting Proactive chat settings
52
55
 
53
- setCustomContextParams(props, chatSDK); // Setting Proactive chat settings
54
56
 
55
57
  const isProactiveChat = state.appStates.conversationState === ConversationState.ProactiveChat;
56
58
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat; //Setting PreChat and intiate chat
57
59
 
58
- setPreChatAndInitiateChat(chatSDK, props.authProps, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat);
60
+ setPreChatAndInitiateChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat);
59
61
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
62
 
61
63
 
62
- const setPreChatAndInitiateChat = async (chatSDK, authProps, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState) => {
64
+ const setPreChatAndInitiateChat = async (chatSDK, chatConfig, getAuthToken, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState) => {
63
65
  // Getting prechat Survey Context
64
66
  const parseToJson = false;
65
67
  const preChatSurveyResponse = await chatSDK.getPreChatSurvey(parseToJson);
@@ -82,11 +84,40 @@ const setPreChatAndInitiateChat = async (chatSDK, authProps, dispatch, setAdapte
82
84
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
83
85
  payload: ConversationState.Loading
84
86
  });
85
- await initStartChat(chatSDK, authProps, dispatch, setAdapter);
87
+ await initStartChat(chatSDK, chatConfig, getAuthToken, dispatch, setAdapter);
86
88
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
89
 
88
90
 
89
- const initStartChat = async (chatSDK, authProps, dispatch, setAdapter, params, persistedState) => {
91
+ const handleAuthentication = async (chatSDK, chatConfig, getAuthToken) => {
92
+ if (getAuthToken) {
93
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
94
+ Event: TelemetryEvent.GetAuthTokenCalled
95
+ });
96
+ let authClientFunction = undefined;
97
+
98
+ if (chatConfig !== null && chatConfig !== void 0 && chatConfig.LiveChatConfigAuthSettings) {
99
+ var _chatConfig$LiveChatC;
100
+
101
+ authClientFunction = (chatConfig === null || chatConfig === void 0 ? void 0 : (_chatConfig$LiveChatC = chatConfig.LiveChatConfigAuthSettings) === null || _chatConfig$LiveChatC === void 0 ? void 0 : _chatConfig$LiveChatC.msdyn_javascriptclientfunction) ?? undefined;
102
+ }
103
+
104
+ const token = await getAuthToken(authClientFunction);
105
+
106
+ if (!isNullOrEmptyString(token)) {
107
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
+ chatSDK.setAuthTokenProvider(async () => {
109
+ return token;
110
+ });
111
+ } else {
112
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
113
+ Event: TelemetryEvent.ReceivedNullOrEmptyToken
114
+ });
115
+ }
116
+ }
117
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
+
119
+
120
+ const initStartChat = async (chatSDK, chatConfig, getAuthToken, dispatch, setAdapter, params, persistedState) => {
90
121
  try {
91
122
  var _newAdapter$activity$, _TelemetryTimers$Widg;
92
123
 
@@ -109,14 +140,12 @@ const initStartChat = async (chatSDK, authProps, dispatch, setAdapter, params, p
109
140
  TelemetryTimers.WidgetLoadTimer = createTimer();
110
141
  TelemetryHelper.logSDKEvent(LogLevel.INFO, {
111
142
  Event: TelemetryEvent.StartChatSDKCall
112
- }); // Set optional params
143
+ }); // Set custom context params
113
144
 
145
+ setCustomContextParams(chatSDK);
114
146
  optionalParams = Object.assign({}, params, optionalParams); // set auth token to chat sdk before start chat
115
147
 
116
- if (authProps && authProps.setAuthTokenProviderToChatSdk) {
117
- await authProps.setAuthTokenProviderToChatSdk(chatSDK, authProps.authClientFunction);
118
- }
119
-
148
+ await handleAuthentication(chatSDK, chatConfig, getAuthToken);
120
149
  await chatSDK.startChat(optionalParams);
121
150
  isStartChatSuccessful = true;
122
151
  } catch (error) {
@@ -167,6 +196,7 @@ const initStartChat = async (chatSDK, authProps, dispatch, setAdapter, params, p
167
196
  await updateSessionDataForTelemetry(chatSDK, dispatch); // Set app state to Active
168
197
 
169
198
  if (isStartChatSuccessful) {
199
+ ActivityStreamHandler.uncork();
170
200
  dispatch({
171
201
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
172
202
  payload: ConversationState.Active
@@ -199,19 +229,20 @@ const initStartChat = async (chatSDK, authProps, dispatch, setAdapter, params, p
199
229
  }
200
230
  } finally {
201
231
  optionalParams = {};
232
+ widgetInstanceId = "";
202
233
  }
203
234
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
204
235
 
205
236
 
206
237
  const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdapter) => {
207
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _persistedState$domai6, _persistedState$appSt;
238
+ var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _props$controlProps2, _persistedState$domai6, _persistedState$appSt;
208
239
 
209
240
  // By pass this function in case of popout chat
210
241
  if (state.appStates.skipChatButtonRendering === true) {
211
242
  return false;
212
243
  }
213
244
 
214
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId); //Connect to only active chat session
245
+ const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.widgetInstanceId) ?? ""); //Connect to only active chat session
215
246
 
216
247
  if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai6 = persistedState.domainStates) === null || _persistedState$domai6 === void 0 ? void 0 : _persistedState$domai6.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt = persistedState.appStates) === null || _persistedState$appSt === void 0 ? void 0 : _persistedState$appSt.conversationState) === ConversationState.Active) {
217
248
  var _persistedState$domai7;
@@ -223,7 +254,7 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
223
254
  const optionalParams = {
224
255
  liveChatContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai7 = persistedState.domainStates) === null || _persistedState$domai7 === void 0 ? void 0 : _persistedState$domai7.liveChatContext
225
256
  };
226
- await initStartChat(chatSDK, props.authProps, dispatch, setAdapter, optionalParams, persistedState);
257
+ await initStartChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, optionalParams, persistedState);
227
258
  return true;
228
259
  } else {
229
260
  return false;
@@ -231,17 +262,28 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
231
262
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
263
 
233
264
 
234
- const setCustomContextParams = (props, chatSDK) => {
235
- var _chatSDK$omnichannelC3, _chatSDK$omnichannelC4, _props$chatConfig, _persistedState$domai8;
265
+ const setCustomContextParams = chatSDK => {
266
+ var _chatSDK$omnichannelC3, _chatSDK$omnichannelC4, _persistedState$domai8;
236
267
 
237
268
  // Add custom context only for unauthenticated chat
238
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.widgetId);
269
+ const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.widgetId, widgetInstanceId ?? "");
239
270
 
240
- if (!((_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && _props$chatConfig.LiveChatConfigAuthSettings) && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext)) {
241
- var _persistedState$domai9;
271
+ if (!isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai8 = persistedState.domainStates) === null || _persistedState$domai8 === void 0 ? void 0 : _persistedState$domai8.customContext)) {
272
+ var _persistedState$domai9, _persistedState$domai10;
273
+
274
+ if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai9 = persistedState.domainStates.liveChatConfig) !== null && _persistedState$domai9 !== void 0 && _persistedState$domai9.LiveChatConfigAuthSettings) {
275
+ const errorMessage = "Use of custom context with authenticated chat is deprecated. The chat would not go through.";
276
+ TelemetryHelper.logSDKEvent(LogLevel.WARN, {
277
+ Event: TelemetryEvent.StartChatMethodException,
278
+ ExceptionDetails: {
279
+ exception: errorMessage
280
+ }
281
+ });
282
+ throw new Error(errorMessage);
283
+ }
242
284
 
243
285
  optionalParams = Object.assign({}, optionalParams, {
244
- customContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.customContext
286
+ customContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai10 = persistedState.domainStates) === null || _persistedState$domai10 === void 0 ? void 0 : _persistedState$domai10.customContext
245
287
  });
246
288
  }
247
289
  };
@@ -1,10 +1,10 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
3
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
4
- import { BroadcastService, decodeComponentString } from "@microsoft/omnichannel-chat-components";
4
+ import { BroadcastService, decodeComponentString, BroadcastServiceInitialize } from "@microsoft/omnichannel-chat-components";
5
5
  import { Stack } from "@fluentui/react";
6
6
  import React, { useEffect, useRef, useState } from "react";
7
- import { createTimer, getLocaleDirection, getStateFromCache, getWidgetCacheId, getWidgetEndChatEventName, isUndefinedOrEmpty } from "../../../common/utils";
7
+ import { createTimer, getBroadcastChannelName, getLocaleDirection, getStateFromCache, getWidgetCacheId, getWidgetEndChatEventName, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
8
8
  import { getReconnectIdForAuthenticatedChat, handleUnauthenticatedReconnectChat, startUnauthenticatedReconnectChat } from "../common/reconnectChatHelper";
9
9
  import { initStartChat, prepareStartChat, setPreChatAndInitiateChat } from "../common/startChat";
10
10
  import { shouldShowCallingContainer, shouldShowChatButton, shouldShowConfirmationPane, shouldShowEmailTranscriptPane, shouldShowHeader, shouldShowLoadingPane, shouldShowOutOfOfficeHoursPane, shouldShowPostChatLoadingPane, shouldShowPostChatSurveyPane, shouldShowPreChatSurveyPane, shouldShowProactiveChatPane, shouldShowReconnectChatPane, shouldShowWebChatContainer } from "../../../controller/componentController";
@@ -43,8 +43,10 @@ import { startProactiveChat } from "../common/startProactiveChat";
43
43
  import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
44
44
  import useChatContextStore from "../../../hooks/useChatContextStore";
45
45
  import useChatSDKStore from "../../../hooks/useChatSDKStore";
46
+ import { ActivityStreamHandler } from "../common/ActivityStreamHandler";
47
+ import { Constants } from "../../../common/Constants";
46
48
  export const LiveChatWidgetStateful = props => {
47
- var _props$webChatContain, _props$styleProps, _props$controlProps, _props$webChatContain3, _props$webChatContain4, _props$styleProps2, _props$controlProps5, _props$controlProps6, _props$componentOverr, _props$controlProps7, _props$componentOverr2, _props$controlProps8, _props$componentOverr3, _props$controlProps9, _props$componentOverr4, _props$controlProps10, _props$componentOverr5, _props$controlProps11, _props$componentOverr6, _props$controlProps12, _props$componentOverr7, _props$controlProps13, _props$controlProps14, _props$componentOverr8, _props$controlProps15, _props$componentOverr9, _props$controlProps16, _props$componentOverr10, _props$componentOverr11, _props$componentOverr12;
49
+ var _props$webChatContain, _props$styleProps, _props$controlProps, _props$webChatContain3, _props$webChatContain4, _props$styleProps2, _props$controlProps14, _props$controlProps15, _props$componentOverr, _props$controlProps16, _props$componentOverr2, _props$controlProps17, _props$componentOverr3, _props$controlProps18, _props$componentOverr4, _props$controlProps19, _props$componentOverr5, _props$controlProps20, _props$componentOverr6, _props$controlProps21, _props$componentOverr7, _props$controlProps22, _props$controlProps23, _props$componentOverr8, _props$controlProps24, _props$componentOverr9, _props$controlProps25, _props$componentOverr10, _props$componentOverr11, _props$componentOverr12;
48
50
 
49
51
  const [state, dispatch] = useChatContextStore(); // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
52
 
@@ -70,19 +72,13 @@ export const LiveChatWidgetStateful = props => {
70
72
  let widgetStateEventName = "";
71
73
 
72
74
  const initiateEndChatOnBrowserUnload = () => {
73
- var _chatSDK$omnichannelC, _chatSDK$omnichannelC2, _DataStoreManager$cli;
75
+ var _DataStoreManager$cli;
74
76
 
75
77
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
76
78
  Event: TelemetryEvent.BrowserUnloadEventStarted,
77
79
  Description: "Browser unload event received."
78
80
  });
79
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.widgetId); // End chat if the chat is still active and browser closed
80
-
81
- if (persistedState.appStates.conversationState === ConversationState.Active) {
82
- //Browser close scenario/no room for PCS/so just end chat and notify agent immidiately
83
- endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false);
84
- } // Clean local storage
85
-
81
+ endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false); // Clean local storage
86
82
 
87
83
  (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.removeData(widgetStateEventName, "localStorage"); //Dispose calling instance
88
84
 
@@ -97,8 +93,10 @@ export const LiveChatWidgetStateful = props => {
97
93
  };
98
94
 
99
95
  useEffect(() => {
100
- var _props$controlProps2, _props$controlProps3, _props$chatConfig, _props$chatConfig$Cha, _props$controlProps4, _props$reconnectChatP, _props$chatConfig2, _props$chatConfig2$Li;
96
+ var _chatSDK$omnichannelC, _props$controlProps2, _props$controlProps3, _props$controlProps4, _props$controlProps5, _props$controlProps7, _props$chatConfig, _props$chatConfig$Cha, _props$controlProps8, _props$reconnectChatP, _props$chatConfig2, _props$chatConfig2$Li;
101
97
 
98
+ const broadcastServiceChannelName = getBroadcastChannelName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC === void 0 ? void 0 : _chatSDK$omnichannelC.widgetId, ((_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.widgetInstanceId) ?? "");
99
+ BroadcastServiceInitialize(broadcastServiceChannelName);
102
100
  registerTelemetryLoggers(props, dispatch);
103
101
  createInternetConnectionChangeHandler();
104
102
  DataStoreManager.clientDataStore = props.contextDataStore ?? undefined;
@@ -108,12 +106,22 @@ export const LiveChatWidgetStateful = props => {
108
106
  });
109
107
  dispatch({
110
108
  type: LiveChatWidgetActionType.SET_SKIP_CHAT_BUTTON_RENDERING,
111
- payload: ((_props$controlProps2 = props.controlProps) === null || _props$controlProps2 === void 0 ? void 0 : _props$controlProps2.skipChatButtonRendering) || false
109
+ payload: ((_props$controlProps3 = props.controlProps) === null || _props$controlProps3 === void 0 ? void 0 : _props$controlProps3.skipChatButtonRendering) || false
112
110
  });
113
111
  dispatch({
114
112
  type: LiveChatWidgetActionType.SET_E2VV_ENABLED,
115
113
  payload: false
116
114
  });
115
+
116
+ if ((_props$controlProps4 = props.controlProps) !== null && _props$controlProps4 !== void 0 && _props$controlProps4.widgetInstanceId && !isNullOrEmptyString((_props$controlProps5 = props.controlProps) === null || _props$controlProps5 === void 0 ? void 0 : _props$controlProps5.widgetInstanceId)) {
117
+ var _props$controlProps6;
118
+
119
+ dispatch({
120
+ type: LiveChatWidgetActionType.SET_WIDGET_INSTANCE_ID,
121
+ payload: (_props$controlProps6 = props.controlProps) === null || _props$controlProps6 === void 0 ? void 0 : _props$controlProps6.widgetInstanceId
122
+ });
123
+ }
124
+
117
125
  initCallingSdk(chatSDK, setVoiceVideoCallingSDK).then(sdkCreated => {
118
126
  sdkCreated && dispatch({
119
127
  type: LiveChatWidgetActionType.SET_E2VV_ENABLED,
@@ -121,16 +129,16 @@ export const LiveChatWidgetStateful = props => {
121
129
  });
122
130
  }); // Initialize global dir
123
131
 
124
- const globalDir = ((_props$controlProps3 = props.controlProps) === null || _props$controlProps3 === void 0 ? void 0 : _props$controlProps3.dir) ?? getLocaleDirection((_props$chatConfig = props.chatConfig) === null || _props$chatConfig === void 0 ? void 0 : (_props$chatConfig$Cha = _props$chatConfig.ChatWidgetLanguage) === null || _props$chatConfig$Cha === void 0 ? void 0 : _props$chatConfig$Cha.msdyn_localeid);
132
+ const globalDir = ((_props$controlProps7 = props.controlProps) === null || _props$controlProps7 === void 0 ? void 0 : _props$controlProps7.dir) ?? getLocaleDirection((_props$chatConfig = props.chatConfig) === null || _props$chatConfig === void 0 ? void 0 : (_props$chatConfig$Cha = _props$chatConfig.ChatWidgetLanguage) === null || _props$chatConfig$Cha === void 0 ? void 0 : _props$chatConfig$Cha.msdyn_localeid);
125
133
  dispatch({
126
134
  type: LiveChatWidgetActionType.SET_GLOBAL_DIR,
127
135
  payload: globalDir
128
136
  });
129
137
 
130
- if (!((_props$controlProps4 = props.controlProps) !== null && _props$controlProps4 !== void 0 && _props$controlProps4.skipChatButtonRendering) && (_props$reconnectChatP = props.reconnectChatPaneProps) !== null && _props$reconnectChatP !== void 0 && _props$reconnectChatP.reconnectId) {
138
+ if (!((_props$controlProps8 = props.controlProps) !== null && _props$controlProps8 !== void 0 && _props$controlProps8.skipChatButtonRendering) && (_props$reconnectChatP = props.reconnectChatPaneProps) !== null && _props$reconnectChatP !== void 0 && _props$reconnectChatP.reconnectId) {
131
139
  var _props$reconnectChatP2;
132
140
 
133
- startUnauthenticatedReconnectChat(chatSDK, props.authProps, dispatch, setAdapter, (_props$reconnectChatP2 = props.reconnectChatPaneProps) === null || _props$reconnectChatP2 === void 0 ? void 0 : _props$reconnectChatP2.reconnectId, initStartChat);
141
+ startUnauthenticatedReconnectChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, (_props$reconnectChatP2 = props.reconnectChatPaneProps) === null || _props$reconnectChatP2 === void 0 ? void 0 : _props$reconnectChatP2.reconnectId, initStartChat);
134
142
  return;
135
143
  } // Check if auth settings enabled, do not connect to existing chat from cache during refresh/re-load
136
144
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -138,7 +146,7 @@ export const LiveChatWidgetStateful = props => {
138
146
 
139
147
  const isAuthenticationSettingsEnabled = (_props$chatConfig2 = props.chatConfig) !== null && _props$chatConfig2 !== void 0 && (_props$chatConfig2$Li = _props$chatConfig2.LiveChatConfigAuthSettings) !== null && _props$chatConfig2$Li !== void 0 && _props$chatConfig2$Li.msdyn_javascriptclientfunction ? true : false;
140
148
 
141
- if (!isAuthenticationSettingsEnabled) {
149
+ if (isAuthenticationSettingsEnabled === false) {
142
150
  var _state$domainStates;
143
151
 
144
152
  if (!isUndefinedOrEmpty((_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.liveChatContext) && state.appStates.conversationState === ConversationState.Active) {
@@ -147,7 +155,7 @@ export const LiveChatWidgetStateful = props => {
147
155
  const optionalParams = {
148
156
  liveChatContext: (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.liveChatContext
149
157
  };
150
- initStartChat(chatSDK, props.authProps, dispatch, setAdapter, optionalParams);
158
+ initStartChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, optionalParams);
151
159
  return;
152
160
  }
153
161
  } // All other case should show start chat button, skipChatButtonRendering will take care of it own
@@ -170,7 +178,7 @@ export const LiveChatWidgetStateful = props => {
170
178
  if ((_props$reconnectChatP3 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP3 !== void 0 && _props$reconnectChatP3.reconnectId && !state.appStates.reconnectId) {
171
179
  var _props$reconnectChatP4, _props$reconnectChatP5;
172
180
 
173
- handleUnauthenticatedReconnectChat(chatSDK, props.authProps, dispatch, setAdapter, (_props$reconnectChatP4 = props.reconnectChatPaneProps) === null || _props$reconnectChatP4 === void 0 ? void 0 : _props$reconnectChatP4.reconnectId, initStartChat, (_props$reconnectChatP5 = props.reconnectChatPaneProps) === null || _props$reconnectChatP5 === void 0 ? void 0 : _props$reconnectChatP5.redirectInSameWindow);
181
+ handleUnauthenticatedReconnectChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, (_props$reconnectChatP4 = props.reconnectChatPaneProps) === null || _props$reconnectChatP4 === void 0 ? void 0 : _props$reconnectChatP4.reconnectId, initStartChat, (_props$reconnectChatP5 = props.reconnectChatPaneProps) === null || _props$reconnectChatP5 === void 0 ? void 0 : _props$reconnectChatP5.redirectInSameWindow);
174
182
  } else {
175
183
  getReconnectIdForAuthenticatedChat(props, chatSDK).then(authReconnectId => {
176
184
  if (authReconnectId && !state.appStates.reconnectId) {
@@ -187,7 +195,7 @@ export const LiveChatWidgetStateful = props => {
187
195
  eventName: BroadcastEvent.StartChatSkippingChatButtonRendering
188
196
  };
189
197
  BroadcastService.postMessage(chatStartedSkippingChatButtonRendering);
190
- setPreChatAndInitiateChat(chatSDK, props.authProps, dispatch, setAdapter);
198
+ setPreChatAndInitiateChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter);
191
199
  }
192
200
  });
193
201
  }
@@ -195,7 +203,7 @@ export const LiveChatWidgetStateful = props => {
195
203
  }, [state.appStates.skipChatButtonRendering]); // useEffect for when skip chat button rendering
196
204
 
197
205
  useEffect(() => {
198
- var _chatSDK$omnichannelC7, _chatSDK$omnichannelC8;
206
+ var _chatSDK$omnichannelC6, _chatSDK$omnichannelC7, _props$controlProps11;
199
207
 
200
208
  // Add the custom context on receiving the SetCustomContext event
201
209
  BroadcastService.getMessageByEventName(BroadcastEvent.SetCustomContext).subscribe(msg => {
@@ -214,7 +222,7 @@ export const LiveChatWidgetStateful = props => {
214
222
  Description: "Start proactive chat event received."
215
223
  });
216
224
 
217
- if (canStartProactiveChat.current) {
225
+ if (canStartProactiveChat.current === true) {
218
226
  var _msg$payload, _msg$payload2, _msg$payload3;
219
227
 
220
228
  startProactiveChat(dispatch, msg === null || msg === void 0 ? void 0 : (_msg$payload = msg.payload) === null || _msg$payload === void 0 ? void 0 : _msg$payload.notificationConfig, msg === null || msg === void 0 ? void 0 : (_msg$payload2 = msg.payload) === null || _msg$payload2 === void 0 ? void 0 : _msg$payload2.enablePreChat, msg === null || msg === void 0 ? void 0 : (_msg$payload3 = msg.payload) === null || _msg$payload3 === void 0 ? void 0 : _msg$payload3.inNewWindow);
@@ -227,24 +235,36 @@ export const LiveChatWidgetStateful = props => {
227
235
  }); // Start chat from SDK Event
228
236
 
229
237
  BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(() => {
230
- var _chatSDK$omnichannelC3, _chatSDK$omnichannelC4;
238
+ var _chatSDK$omnichannelC2, _chatSDK$omnichannelC3, _props$controlProps9;
231
239
 
232
240
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
233
241
  Event: TelemetryEvent.StartChatEventRecevied,
234
242
  Description: "Start chat event received."
235
243
  });
236
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.widgetId);
244
+ const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC2 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC2 === void 0 ? void 0 : _chatSDK$omnichannelC2.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC3 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC3 === void 0 ? void 0 : _chatSDK$omnichannelC3.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps9 = props.controlProps) === null || _props$controlProps9 === void 0 ? void 0 : _props$controlProps9.widgetInstanceId) ?? ""); // Chat not found in cache
237
245
 
238
- if (persistedState && (persistedState.appStates.conversationState === ConversationState.Closed || persistedState.appStates.conversationState === ConversationState.InActive || persistedState.appStates.conversationState === ConversationState.Postchat)) {
239
- // Embedded mode
246
+ if (persistedState === undefined) {
240
247
  BroadcastService.postMessage({
241
248
  eventName: BroadcastEvent.ChatInitiated
242
249
  });
243
250
  prepareStartChat(props, chatSDK, state, dispatch, setAdapter);
244
- } else {
251
+ return;
252
+ } // Chat exist in cache
253
+
254
+
255
+ if (persistedState) {
245
256
  var _persistedState$domai, _persistedState$domai2, _persistedState$domai3, _persistedState$domai4;
246
257
 
247
- // Minimize to Maximize
258
+ // Only initiate new chat if widget state in cache in one of the followings
259
+ if (persistedState.appStates.conversationState === ConversationState.Closed || persistedState.appStates.conversationState === ConversationState.InActive || persistedState.appStates.conversationState === ConversationState.Postchat) {
260
+ BroadcastService.postMessage({
261
+ eventName: BroadcastEvent.ChatInitiated
262
+ });
263
+ prepareStartChat(props, chatSDK, state, dispatch, setAdapter);
264
+ return;
265
+ } // If minimized, maximize the chat
266
+
267
+
248
268
  dispatch({
249
269
  type: LiveChatWidgetActionType.SET_MINIMIZED,
250
270
  payload: false
@@ -261,10 +281,10 @@ export const LiveChatWidgetStateful = props => {
261
281
 
262
282
  BroadcastService.getMessageByEventName(BroadcastEvent.InitiateEndChat).subscribe(async () => {
263
283
  if (state.appStates.skipChatButtonRendering !== true) {
264
- var _chatSDK$omnichannelC5, _chatSDK$omnichannelC6;
284
+ var _chatSDK$omnichannelC4, _chatSDK$omnichannelC5, _props$controlProps10;
265
285
 
266
286
  // This is to ensure to get latest state from cache in multitab
267
- const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC5 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC5 === void 0 ? void 0 : _chatSDK$omnichannelC5.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC6 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC6 === void 0 ? void 0 : _chatSDK$omnichannelC6.widgetId);
287
+ const persistedState = getStateFromCache(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC4 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC4 === void 0 ? void 0 : _chatSDK$omnichannelC4.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC5 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC5 === void 0 ? void 0 : _chatSDK$omnichannelC5.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps10 = props.controlProps) === null || _props$controlProps10 === void 0 ? void 0 : _props$controlProps10.widgetInstanceId) ?? "");
268
288
 
269
289
  if (persistedState && persistedState.appStates.conversationState === ConversationState.Active) {
270
290
  prepareEndChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state);
@@ -284,9 +304,10 @@ export const LiveChatWidgetStateful = props => {
284
304
  initiateEndChatOnBrowserUnload();
285
305
  }); // Listen to end chat event from other tabs
286
306
 
287
- const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC7 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC7 === void 0 ? void 0 : _chatSDK$omnichannelC7.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC8 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC8 === void 0 ? void 0 : _chatSDK$omnichannelC8.widgetId);
307
+ const endChatEventName = getWidgetEndChatEventName(chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC6 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC6 === void 0 ? void 0 : _chatSDK$omnichannelC6.orgId, chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$omnichannelC7 = chatSDK.omnichannelConfig) === null || _chatSDK$omnichannelC7 === void 0 ? void 0 : _chatSDK$omnichannelC7.widgetId, ((_props$controlProps11 = props.controlProps) === null || _props$controlProps11 === void 0 ? void 0 : _props$controlProps11.widgetInstanceId) ?? "");
288
308
  BroadcastService.getMessageByEventName(endChatEventName).subscribe(async () => {
289
309
  endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, false, false, false);
310
+ return;
290
311
  }); // When conversation ended by agent
291
312
 
292
313
  if (state.appStates.conversationEndedByAgent) {
@@ -326,6 +347,12 @@ export const LiveChatWidgetStateful = props => {
326
347
  }, [state.appStates.conversationState, state.appStates.proactiveChatStates.proactiveChatInNewWindow]); // Reset the UnreadMessageCount when minimized is toggled and broadcast it.
327
348
 
328
349
  useEffect(() => {
350
+ if (state.appStates.isMinimized) {
351
+ ActivityStreamHandler.cork();
352
+ } else {
353
+ setTimeout(() => ActivityStreamHandler.uncork(), 500);
354
+ }
355
+
329
356
  currentMessageCountRef.current = -1;
330
357
  dispatch({
331
358
  type: LiveChatWidgetActionType.SET_UNREAD_MESSAGE_COUNT,
@@ -358,9 +385,24 @@ export const LiveChatWidgetStateful = props => {
358
385
  }, [(_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.webChatStyles]); // Publish chat widget state
359
386
 
360
387
  useEffect(() => {
361
- var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic;
388
+ var _props$controlProps12, _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic, _props$controlProps13;
389
+
390
+ // Only activate these windows events when conversation state is active and chat widget is in popout mode
391
+ // Ghost chat scenarios
392
+ if (state.appStates.conversationState === ConversationState.Active && ((_props$controlProps12 = props.controlProps) === null || _props$controlProps12 === void 0 ? void 0 : _props$controlProps12.skipChatButtonRendering) === true) {
393
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
394
+ window.onbeforeunload = function () {
395
+ const prompt = Constants.BrowserUnloadConfirmationMessage;
396
+ return prompt;
397
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
398
+
399
+
400
+ window.onunload = function () {
401
+ initiateEndChatOnBrowserUnload();
402
+ };
403
+ }
362
404
 
363
- widgetStateEventName = getWidgetCacheId(props === null || props === void 0 ? void 0 : (_props$chatSDK = props.chatSDK) === null || _props$chatSDK === void 0 ? void 0 : (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) === null || _props$chatSDK$omnich === void 0 ? void 0 : _props$chatSDK$omnich.orgId, props === null || props === void 0 ? void 0 : (_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.widgetId);
405
+ widgetStateEventName = getWidgetCacheId(props === null || props === void 0 ? void 0 : (_props$chatSDK = props.chatSDK) === null || _props$chatSDK === void 0 ? void 0 : (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) === null || _props$chatSDK$omnich === void 0 ? void 0 : _props$chatSDK$omnich.orgId, props === null || props === void 0 ? void 0 : (_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.widgetId, (props === null || props === void 0 ? void 0 : (_props$controlProps13 = props.controlProps) === null || _props$controlProps13 === void 0 ? void 0 : _props$controlProps13.widgetInstanceId) ?? "");
364
406
  const chatWidgetStateChangeEvent = {
365
407
  eventName: widgetStateEventName,
366
408
  payload: { ...state
@@ -373,7 +415,7 @@ export const LiveChatWidgetStateful = props => {
373
415
  const setPostChatContextRelay = () => setPostChatContextAndLoadSurvey(chatSDK, dispatch); // eslint-disable-next-line @typescript-eslint/no-explicit-any
374
416
 
375
417
 
376
- const endChatRelay = (adapter, skipEndChatSDK, skipCloseChat) => endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat); // eslint-disable-next-line @typescript-eslint/no-explicit-any
418
+ const endChatRelay = (adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab) => endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, skipEndChatSDK, skipCloseChat, postMessageToOtherTab); // eslint-disable-next-line @typescript-eslint/no-explicit-any
377
419
 
378
420
 
379
421
  const prepareEndChatRelay = (adapter, state) => prepareEndChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter, state);
@@ -381,7 +423,7 @@ export const LiveChatWidgetStateful = props => {
381
423
  const prepareStartChatRelay = () => prepareStartChat(props, chatSDK, state, dispatch, setAdapter); // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
424
 
383
425
 
384
- const initStartChatRelay = (optionalParams, persistedState) => initStartChat(chatSDK, props.authProps, dispatch, setAdapter, optionalParams, persistedState);
426
+ const initStartChatRelay = (optionalParams, persistedState) => initStartChat(chatSDK, props.chatConfig, props.getAuthToken, dispatch, setAdapter, optionalParams, persistedState);
385
427
 
386
428
  const confirmationPaneProps = initConfirmationPropsComposer(props);
387
429
  return /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
@@ -391,28 +433,28 @@ export const LiveChatWidgetStateful = props => {
391
433
  id: widgetElementId,
392
434
  styles: generalStyles,
393
435
  className: (_props$styleProps2 = props.styleProps) === null || _props$styleProps2 === void 0 ? void 0 : _props$styleProps2.className
394
- }, !((_props$controlProps5 = props.controlProps) !== null && _props$controlProps5 !== void 0 && _props$controlProps5.hideChatButton) && !((_props$controlProps6 = props.controlProps) !== null && _props$controlProps6 !== void 0 && _props$controlProps6.skipChatButtonRendering) && shouldShowChatButton(state) && (decodeComponentString((_props$componentOverr = props.componentOverrides) === null || _props$componentOverr === void 0 ? void 0 : _props$componentOverr.chatButton) || /*#__PURE__*/React.createElement(ChatButtonStateful, {
436
+ }, !((_props$controlProps14 = props.controlProps) !== null && _props$controlProps14 !== void 0 && _props$controlProps14.hideChatButton) && !((_props$controlProps15 = props.controlProps) !== null && _props$controlProps15 !== void 0 && _props$controlProps15.skipChatButtonRendering) && shouldShowChatButton(state) && (decodeComponentString((_props$componentOverr = props.componentOverrides) === null || _props$componentOverr === void 0 ? void 0 : _props$componentOverr.chatButton) || /*#__PURE__*/React.createElement(ChatButtonStateful, {
395
437
  buttonProps: props.chatButtonProps,
396
438
  outOfOfficeButtonProps: props.outOfOfficeChatButtonProps,
397
439
  startChat: prepareStartChatRelay
398
- })), !((_props$controlProps7 = props.controlProps) !== null && _props$controlProps7 !== void 0 && _props$controlProps7.hideProactiveChatPane) && shouldShowProactiveChatPane(state) && (decodeComponentString((_props$componentOverr2 = props.componentOverrides) === null || _props$componentOverr2 === void 0 ? void 0 : _props$componentOverr2.proactiveChatPane) || /*#__PURE__*/React.createElement(ProactiveChatPaneStateful, {
440
+ })), !((_props$controlProps16 = props.controlProps) !== null && _props$controlProps16 !== void 0 && _props$controlProps16.hideProactiveChatPane) && shouldShowProactiveChatPane(state) && (decodeComponentString((_props$componentOverr2 = props.componentOverrides) === null || _props$componentOverr2 === void 0 ? void 0 : _props$componentOverr2.proactiveChatPane) || /*#__PURE__*/React.createElement(ProactiveChatPaneStateful, {
399
441
  proactiveChatProps: props.proactiveChatPaneProps,
400
442
  startChat: prepareStartChatRelay
401
- })), !((_props$controlProps8 = props.controlProps) !== null && _props$controlProps8 !== void 0 && _props$controlProps8.hideHeader) && shouldShowHeader(state) && (decodeComponentString((_props$componentOverr3 = props.componentOverrides) === null || _props$componentOverr3 === void 0 ? void 0 : _props$componentOverr3.header) || /*#__PURE__*/React.createElement(HeaderStateful, {
443
+ })), !((_props$controlProps17 = props.controlProps) !== null && _props$controlProps17 !== void 0 && _props$controlProps17.hideHeader) && shouldShowHeader(state) && (decodeComponentString((_props$componentOverr3 = props.componentOverrides) === null || _props$componentOverr3 === void 0 ? void 0 : _props$componentOverr3.header) || /*#__PURE__*/React.createElement(HeaderStateful, {
402
444
  headerProps: props.headerProps,
403
445
  outOfOfficeHeaderProps: props.outOfOfficeHeaderProps,
404
446
  endChat: endChatRelay
405
- })), !((_props$controlProps9 = props.controlProps) !== null && _props$controlProps9 !== void 0 && _props$controlProps9.hideLoadingPane) && shouldShowLoadingPane(state) && (decodeComponentString((_props$componentOverr4 = props.componentOverrides) === null || _props$componentOverr4 === void 0 ? void 0 : _props$componentOverr4.loadingPane) || /*#__PURE__*/React.createElement(LoadingPaneStateful, props.loadingPaneProps)), !((_props$controlProps10 = props.controlProps) !== null && _props$controlProps10 !== void 0 && _props$controlProps10.hideOutOfOfficeHoursPane) && shouldShowOutOfOfficeHoursPane(state) && (decodeComponentString((_props$componentOverr5 = props.componentOverrides) === null || _props$componentOverr5 === void 0 ? void 0 : _props$componentOverr5.outOfOfficeHoursPane) || /*#__PURE__*/React.createElement(OutOfOfficeHoursPaneStateful, props.outOfOfficeHoursPaneProps)), !((_props$controlProps11 = props.controlProps) !== null && _props$controlProps11 !== void 0 && _props$controlProps11.hideReconnectChatPane) && shouldShowReconnectChatPane(state) && (decodeComponentString((_props$componentOverr6 = props.componentOverrides) === null || _props$componentOverr6 === void 0 ? void 0 : _props$componentOverr6.reconnectChatPane) || /*#__PURE__*/React.createElement(ReconnectChatPaneStateful, {
447
+ })), !((_props$controlProps18 = props.controlProps) !== null && _props$controlProps18 !== void 0 && _props$controlProps18.hideLoadingPane) && shouldShowLoadingPane(state) && (decodeComponentString((_props$componentOverr4 = props.componentOverrides) === null || _props$componentOverr4 === void 0 ? void 0 : _props$componentOverr4.loadingPane) || /*#__PURE__*/React.createElement(LoadingPaneStateful, props.loadingPaneProps)), !((_props$controlProps19 = props.controlProps) !== null && _props$controlProps19 !== void 0 && _props$controlProps19.hideOutOfOfficeHoursPane) && shouldShowOutOfOfficeHoursPane(state) && (decodeComponentString((_props$componentOverr5 = props.componentOverrides) === null || _props$componentOverr5 === void 0 ? void 0 : _props$componentOverr5.outOfOfficeHoursPane) || /*#__PURE__*/React.createElement(OutOfOfficeHoursPaneStateful, props.outOfOfficeHoursPaneProps)), !((_props$controlProps20 = props.controlProps) !== null && _props$controlProps20 !== void 0 && _props$controlProps20.hideReconnectChatPane) && shouldShowReconnectChatPane(state) && (decodeComponentString((_props$componentOverr6 = props.componentOverrides) === null || _props$componentOverr6 === void 0 ? void 0 : _props$componentOverr6.reconnectChatPane) || /*#__PURE__*/React.createElement(ReconnectChatPaneStateful, {
406
448
  reconnectChatProps: props.reconnectChatPaneProps,
407
449
  initStartChat: initStartChatRelay
408
- })), !((_props$controlProps12 = props.controlProps) !== null && _props$controlProps12 !== void 0 && _props$controlProps12.hidePreChatSurveyPane) && shouldShowPreChatSurveyPane(state) && (decodeComponentString((_props$componentOverr7 = props.componentOverrides) === null || _props$componentOverr7 === void 0 ? void 0 : _props$componentOverr7.preChatSurveyPane) || /*#__PURE__*/React.createElement(PreChatSurveyPaneStateful, {
450
+ })), !((_props$controlProps21 = props.controlProps) !== null && _props$controlProps21 !== void 0 && _props$controlProps21.hidePreChatSurveyPane) && shouldShowPreChatSurveyPane(state) && (decodeComponentString((_props$componentOverr7 = props.componentOverrides) === null || _props$componentOverr7 === void 0 ? void 0 : _props$componentOverr7.preChatSurveyPane) || /*#__PURE__*/React.createElement(PreChatSurveyPaneStateful, {
409
451
  surveyProps: props.preChatSurveyPaneProps,
410
452
  initStartChat: initStartChatRelay
411
- })), !((_props$controlProps13 = props.controlProps) !== null && _props$controlProps13 !== void 0 && _props$controlProps13.hideCallingContainer) && shouldShowCallingContainer(state) && /*#__PURE__*/React.createElement(CallingContainerStateful, _extends({
453
+ })), !((_props$controlProps22 = props.controlProps) !== null && _props$controlProps22 !== void 0 && _props$controlProps22.hideCallingContainer) && shouldShowCallingContainer(state) && /*#__PURE__*/React.createElement(CallingContainerStateful, _extends({
412
454
  voiceVideoCallingSdk: voiceVideoCallingSDK
413
- }, props.callingContainerProps)), !((_props$controlProps14 = props.controlProps) !== null && _props$controlProps14 !== void 0 && _props$controlProps14.hideWebChatContainer) && shouldShowWebChatContainer(state) && (decodeComponentString((_props$componentOverr8 = props.componentOverrides) === null || _props$componentOverr8 === void 0 ? void 0 : _props$componentOverr8.webChatContainer) || /*#__PURE__*/React.createElement(WebChatContainerStateful, props.webChatContainerProps)), !((_props$controlProps15 = props.controlProps) !== null && _props$controlProps15 !== void 0 && _props$controlProps15.hideConfirmationPane) && shouldShowConfirmationPane(state) && (decodeComponentString((_props$componentOverr9 = props.componentOverrides) === null || _props$componentOverr9 === void 0 ? void 0 : _props$componentOverr9.confirmationPane) || /*#__PURE__*/React.createElement(ConfirmationPaneStateful, _extends({}, confirmationPaneProps, {
455
+ }, props.callingContainerProps)), !((_props$controlProps23 = props.controlProps) !== null && _props$controlProps23 !== void 0 && _props$controlProps23.hideWebChatContainer) && shouldShowWebChatContainer(state) && (decodeComponentString((_props$componentOverr8 = props.componentOverrides) === null || _props$componentOverr8 === void 0 ? void 0 : _props$componentOverr8.webChatContainer) || /*#__PURE__*/React.createElement(WebChatContainerStateful, props.webChatContainerProps)), !((_props$controlProps24 = props.controlProps) !== null && _props$controlProps24 !== void 0 && _props$controlProps24.hideConfirmationPane) && shouldShowConfirmationPane(state) && (decodeComponentString((_props$componentOverr9 = props.componentOverrides) === null || _props$componentOverr9 === void 0 ? void 0 : _props$componentOverr9.confirmationPane) || /*#__PURE__*/React.createElement(ConfirmationPaneStateful, _extends({}, confirmationPaneProps, {
414
456
  setPostChatContext: setPostChatContextRelay,
415
457
  prepareEndChat: prepareEndChatRelay
416
- }))), !((_props$controlProps16 = props.controlProps) !== null && _props$controlProps16 !== void 0 && _props$controlProps16.hidePostChatLoadingPane) && shouldShowPostChatLoadingPane(state) && (decodeComponentString((_props$componentOverr10 = props.componentOverrides) === null || _props$componentOverr10 === void 0 ? void 0 : _props$componentOverr10.postChatLoadingPane) || /*#__PURE__*/React.createElement(PostChatLoadingPaneStateful, props.postChatLoadingPaneProps)), shouldShowPostChatSurveyPane(state) && (decodeComponentString((_props$componentOverr11 = props.componentOverrides) === null || _props$componentOverr11 === void 0 ? void 0 : _props$componentOverr11.postChatSurveyPane) || /*#__PURE__*/React.createElement(PostChatSurveyPaneStateful, _extends({}, props.postChatSurveyPaneProps, props.chatSDK))), createFooter(props, state), shouldShowEmailTranscriptPane(state) && (decodeComponentString((_props$componentOverr12 = props.componentOverrides) === null || _props$componentOverr12 === void 0 ? void 0 : _props$componentOverr12.emailTranscriptPane) || /*#__PURE__*/React.createElement(EmailTranscriptPaneStateful, props.emailTranscriptPane))));
458
+ }))), !((_props$controlProps25 = props.controlProps) !== null && _props$controlProps25 !== void 0 && _props$controlProps25.hidePostChatLoadingPane) && shouldShowPostChatLoadingPane(state) && (decodeComponentString((_props$componentOverr10 = props.componentOverrides) === null || _props$componentOverr10 === void 0 ? void 0 : _props$componentOverr10.postChatLoadingPane) || /*#__PURE__*/React.createElement(PostChatLoadingPaneStateful, props.postChatLoadingPaneProps)), shouldShowPostChatSurveyPane(state) && (decodeComponentString((_props$componentOverr11 = props.componentOverrides) === null || _props$componentOverr11 === void 0 ? void 0 : _props$componentOverr11.postChatSurveyPane) || /*#__PURE__*/React.createElement(PostChatSurveyPaneStateful, _extends({}, props.postChatSurveyPaneProps, props.chatSDK))), createFooter(props, state), shouldShowEmailTranscriptPane(state) && (decodeComponentString((_props$componentOverr12 = props.componentOverrides) === null || _props$componentOverr12 === void 0 ? void 0 : _props$componentOverr12.emailTranscriptPane) || /*#__PURE__*/React.createElement(EmailTranscriptPaneStateful, props.emailTranscriptPane))));
417
459
  };
418
460
  export default LiveChatWidgetStateful;
@@ -68,7 +68,7 @@ export const PreChatSurveyPaneStateful = props => {
68
68
  try {
69
69
  var _state$domainStates, _state$domainStates$t, _state$domainStates$t2, _persistedState$domai, _persistedState$appSt;
70
70
 
71
- const persistedState = getStateFromCache(((_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$t = _state$domainStates.telemetryInternalData) === null || _state$domainStates$t === void 0 ? void 0 : _state$domainStates$t.orgId) ?? "", ((_state$domainStates$t2 = state.domainStates.telemetryInternalData) === null || _state$domainStates$t2 === void 0 ? void 0 : _state$domainStates$t2.widgetId) ?? "");
71
+ const persistedState = getStateFromCache(((_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$t = _state$domainStates.telemetryInternalData) === null || _state$domainStates$t === void 0 ? void 0 : _state$domainStates$t.orgId) ?? "", ((_state$domainStates$t2 = state.domainStates.telemetryInternalData) === null || _state$domainStates$t2 === void 0 ? void 0 : _state$domainStates$t2.widgetId) ?? "", state.domainStates.widgetInstanceId ?? "");
72
72
  let optionalParams = {}; //Connect to Active chats and chat is not popout
73
73
 
74
74
  if (persistedState && !isUndefinedOrEmpty(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai = persistedState.domainStates) === null || _persistedState$domai === void 0 ? void 0 : _persistedState$domai.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt = persistedState.appStates) === null || _persistedState$appSt === void 0 ? void 0 : _persistedState$appSt.conversationState) === ConversationState.Active && !state.appStates.skipChatButtonRendering) {
@@ -4,6 +4,8 @@ import MockAdapter from "./mockadapter";
4
4
  export class MockChatSDK {
5
5
  constructor() {
6
6
  _defineProperty(this, "sleep", ms => new Promise(r => setTimeout(r, ms)));
7
+
8
+ _defineProperty(this, "isMockModeOn", true);
7
9
  }
8
10
 
9
11
  async startChat() {
@@ -34,4 +34,5 @@ export let LiveChatWidgetActionType;
34
34
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONTEXT"] = 30] = "SET_LIVE_CHAT_CONTEXT";
35
35
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_BOT_OAUTH_SIGNIN_ID"] = 31] = "SET_BOT_OAUTH_SIGNIN_ID";
36
36
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_SIZE"] = 32] = "SET_WIDGET_SIZE";
37
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_INSTANCE_ID"] = 33] = "SET_WIDGET_INSTANCE_ID";
37
38
  })(LiveChatWidgetActionType || (LiveChatWidgetActionType = {}));
@@ -20,7 +20,8 @@ export const getLiveChatWidgetContextInitialState = props => {
20
20
  globalDir: "ltr",
21
21
  liveChatContext: undefined,
22
22
  customContext: undefined,
23
- widgetSize: undefined
23
+ widgetSize: undefined,
24
+ widgetInstanceId: ""
24
25
  },
25
26
  appStates: {
26
27
  conversationState: ConversationState.Closed,
@@ -235,6 +235,14 @@ export const createReducer = () => {
235
235
  }
236
236
  };
237
237
 
238
+ case LiveChatWidgetActionType.SET_WIDGET_INSTANCE_ID:
239
+ return { ...state,
240
+ domainStates: { ...state.domainStates,
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
+ widgetInstanceId: action.payload
243
+ }
244
+ };
245
+
238
246
  default:
239
247
  return state;
240
248
  }
@@ -77,6 +77,7 @@ export declare class Constants {
77
77
  static readonly internetConnectionTestUrlText = "Omnichannel Connect Test";
78
78
  static readonly ChatWidgetStateChangedPrefix = "ChatWidgetStateChanged";
79
79
  static readonly PostChatLoadingDurationInMs = 2000;
80
+ static readonly BrowserUnloadConfirmationMessage = "Do you want to leave chat?";
80
81
  }
81
82
  export declare const Regex: {
82
83
  new (): {};
@@ -121,6 +121,8 @@ export declare enum TelemetryEvent {
121
121
  SuppressBotMagicCodeFailed = "SuppressBotMagicCodeFailed",
122
122
  GetConversationDetailsException = "GetConversationDetailsException",
123
123
  BrowserUnloadEventStarted = "BrowserUnloadEventStarted",
124
+ GetAuthTokenCalled = "GetAuthTokenCalled",
125
+ ReceivedNullOrEmptyToken = "ReceivedNullOrEmptyToken",
124
126
  ProcessingHTMLTextMiddlewareFailed = "ProcessingHTMLTextMiddlewareFailed",
125
127
  ProcessingSanitizationMiddlewareFailed = "ProcessingSanitizationMiddlewareFailed",
126
128
  FormatTagsMiddlewareJSONStringifyFailed = "FormatTagsMiddlewareJSONStringifyFailed",