@microsoft/omnichannel-chat-widget 1.8.4-main.cbab5fc → 1.8.4-main.cc63f01

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 (143) hide show
  1. package/README.md +13 -3
  2. package/lib/cjs/common/Constants.js +5 -0
  3. package/lib/cjs/common/facades/FacadeChatSDK.js +235 -9
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +14 -0
  5. package/lib/cjs/common/telemetry/TelemetryManager.js +6 -1
  6. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +7 -7
  7. package/lib/cjs/common/telemetry/sanitizeSasInPayload.js +82 -0
  8. package/lib/cjs/common/utils/xssUtils.js +23 -51
  9. package/lib/cjs/common/utils.js +106 -17
  10. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +8 -1
  11. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +12 -1
  12. package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +36 -13
  13. package/lib/cjs/components/errorboundary/ErrorBoundary.js +2 -1
  14. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +9 -1
  15. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +23 -6
  16. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  17. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +9 -0
  18. package/lib/cjs/components/livechatwidget/common/authHelper.js +44 -4
  19. package/lib/cjs/components/livechatwidget/common/createAdapter.js +3 -2
  20. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +98 -5
  21. package/lib/cjs/components/livechatwidget/common/endChat.js +6 -0
  22. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +186 -1
  23. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +36 -4
  24. package/lib/cjs/components/livechatwidget/common/startChat.js +31 -14
  25. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +124 -5
  26. package/lib/cjs/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +15 -3
  27. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +7 -4
  28. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +68 -2
  29. package/lib/cjs/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
  30. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +0 -1
  31. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +157 -34
  32. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +10 -0
  33. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +117 -16
  34. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
  35. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -1
  36. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +5 -1
  37. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  38. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +3 -1
  39. package/lib/cjs/components/webchatcontainerstateful/common/utils/citationA11y.js +195 -0
  40. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +13 -2
  41. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +160 -167
  42. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +27 -8
  43. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +2 -1
  44. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +203 -0
  45. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  46. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  47. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
  48. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +5 -13
  49. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +81 -0
  50. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +29 -1
  51. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +52 -8
  52. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
  53. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +1 -0
  54. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +17 -1
  55. package/lib/cjs/contexts/createReducer.js +15 -0
  56. package/lib/cjs/controller/componentController.js +13 -1
  57. package/lib/cjs/plugins/newMessageEventHandler.js +20 -3
  58. package/lib/esm/common/Constants.js +5 -0
  59. package/lib/esm/common/facades/FacadeChatSDK.js +236 -10
  60. package/lib/esm/common/telemetry/TelemetryConstants.js +14 -0
  61. package/lib/esm/common/telemetry/TelemetryManager.js +6 -1
  62. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +7 -7
  63. package/lib/esm/common/telemetry/sanitizeSasInPayload.js +75 -0
  64. package/lib/esm/common/utils/xssUtils.js +23 -51
  65. package/lib/esm/common/utils.js +99 -14
  66. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +8 -1
  67. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +12 -1
  68. package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +37 -14
  69. package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -2
  70. package/lib/esm/components/livechatwidget/LiveChatWidget.js +9 -1
  71. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +23 -6
  72. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  73. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +9 -0
  74. package/lib/esm/components/livechatwidget/common/authHelper.js +44 -4
  75. package/lib/esm/components/livechatwidget/common/createAdapter.js +3 -2
  76. package/lib/esm/components/livechatwidget/common/createMarkdown.js +98 -5
  77. package/lib/esm/components/livechatwidget/common/endChat.js +6 -0
  78. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +186 -1
  79. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +33 -2
  80. package/lib/esm/components/livechatwidget/common/startChat.js +31 -14
  81. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +125 -6
  82. package/lib/esm/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +16 -4
  83. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +7 -4
  84. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +69 -3
  85. package/lib/esm/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +2 -1
  86. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +1 -2
  87. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +158 -35
  88. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +10 -0
  89. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +117 -16
  90. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
  91. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -1
  92. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +5 -1
  93. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  94. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +3 -1
  95. package/lib/esm/components/webchatcontainerstateful/common/utils/citationA11y.js +188 -0
  96. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +13 -2
  97. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +160 -171
  98. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +24 -6
  99. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +2 -1
  100. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +195 -0
  101. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  102. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  103. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
  104. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +5 -13
  105. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +74 -0
  106. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +29 -1
  107. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +1 -0
  108. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +52 -8
  109. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
  110. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +1 -0
  111. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +17 -1
  112. package/lib/esm/contexts/createReducer.js +15 -0
  113. package/lib/esm/controller/componentController.js +13 -1
  114. package/lib/esm/plugins/newMessageEventHandler.js +20 -3
  115. package/lib/types/common/Constants.d.ts +4 -0
  116. package/lib/types/common/facades/FacadeChatSDK.d.ts +29 -0
  117. package/lib/types/common/facades/types/IFacadeChatSDKInput.d.ts +3 -1
  118. package/lib/types/common/telemetry/TelemetryConstants.d.ts +14 -2
  119. package/lib/types/common/telemetry/sanitizeSasInPayload.d.ts +24 -0
  120. package/lib/types/common/utils/xssUtils.d.ts +5 -21
  121. package/lib/types/common/utils.d.ts +12 -2
  122. package/lib/types/components/errorboundary/ErrorBoundary.d.ts +1 -1
  123. package/lib/types/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.d.ts +1 -0
  124. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +2 -1
  125. package/lib/types/components/livechatwidget/common/authHelper.d.ts +9 -2
  126. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +11 -0
  127. package/lib/types/components/livechatwidget/interfaces/IBotAuthActivitySubscriberOptionalParams.d.ts +1 -0
  128. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +1 -1
  129. package/lib/types/components/webchatcontainerstateful/common/utils/citationA11y.d.ts +1 -0
  130. package/lib/types/components/webchatcontainerstateful/interfaces/IAdaptiveCardStyles.d.ts +3 -0
  131. package/lib/types/components/webchatcontainerstateful/interfaces/IBotAuthConfig.d.ts +7 -0
  132. package/lib/types/components/webchatcontainerstateful/interfaces/IExtendedChatConffig.d.ts +1 -1
  133. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +7 -0
  134. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +14 -38
  135. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -0
  136. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.d.ts +18 -0
  137. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.d.ts +3 -0
  138. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.d.ts +12 -0
  139. package/lib/types/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.d.ts +7 -0
  140. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  141. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +17 -0
  142. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  143. package/package.json +37 -9
@@ -20,6 +20,7 @@ var _createAdapter = require("./createAdapter");
20
20
  var _newMessageEventHandler = require("../../../plugins/newMessageEventHandler");
21
21
  var _FirstMessageTrackerFromBot = require("../../../firstresponselatency/FirstMessageTrackerFromBot");
22
22
  var _liveChatConfigUtils = require("./liveChatConfigUtils");
23
+ var _authHelper = require("./authHelper");
23
24
  var _setPostChatContextAndLoadSurvey = require("./setPostChatContextAndLoadSurvey");
24
25
  var _persistentChatHelper = require("./persistentChatHelper");
25
26
  var _updateSessionDataForTelemetry = require("./updateSessionDataForTelemetry");
@@ -65,7 +66,7 @@ const prepareStartChat = async (props, facadeChatSDK, state, dispatch, setAdapte
65
66
  exports.prepareStartChat = prepareStartChat;
66
67
  const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState, state, props) => {
67
68
  var _props$preChatSurveyP, _props$preChatSurveyP2, _props$controlProps, _state$domainStates, _state$domainStates$l, _state$domainStates$l2, _state$appStates2;
68
- // This reset needs to be done before to load prechat, because the conversation state changes from close to prechat
69
+ // Reset before loading prechat to avoid starting chat with previous requestId
69
70
  if ((state === null || state === void 0 ? void 0 : state.appStates.conversationState) === _ConversationState.ConversationState.Closed) {
70
71
  // Preventive reset to avoid starting chat with previous requestId which could potentially cause problems
71
72
  (0, _endChat.chatSDKStateCleanUp)(facadeChatSDK.getChatSDK());
@@ -199,7 +200,7 @@ const initStartChat = async (facadeChatSDK, dispatch, setAdapter, state, props,
199
200
  });
200
201
  }
201
202
  try {
202
- var _window$Microsoft, _window$Microsoft$Dyn, _window$Microsoft$Dyn2, _window$Microsoft$Dyn3;
203
+ var _window$Microsoft, _window$Microsoft$Dyn, _window$Microsoft$Dyn2, _window$Microsoft$Dyn3, _state$domainStates8;
203
204
  // Set custom context params
204
205
  await setCustomContextParams(state, props);
205
206
  const defaultOptionalParams = {
@@ -208,9 +209,25 @@ const initStartChat = async (facadeChatSDK, dispatch, setAdapter, state, props,
208
209
  portalContactId: (_window$Microsoft = window.Microsoft) === null || _window$Microsoft === void 0 ? void 0 : (_window$Microsoft$Dyn = _window$Microsoft.Dynamic365) === null || _window$Microsoft$Dyn === void 0 ? void 0 : (_window$Microsoft$Dyn2 = _window$Microsoft$Dyn.Portal) === null || _window$Microsoft$Dyn2 === void 0 ? void 0 : (_window$Microsoft$Dyn3 = _window$Microsoft$Dyn2.User) === null || _window$Microsoft$Dyn3 === void 0 ? void 0 : _window$Microsoft$Dyn3.contactId
209
210
  };
210
211
  const startChatOptionalParams = Object.assign({}, params, optionalParams, defaultOptionalParams);
212
+
213
+ // MID-AUTH: Add wasAuthenticated flag for reconnect scenarios
214
+ // Tells FacadeChatSDK whether the previous session was authenticated
215
+ // Used to detect auth transitions (Auth->Unauth) and decide whether to call authenticateChat
216
+ const midAuthEnabled = (0, _authHelper.isMidAuthEnabled)(state === null || state === void 0 ? void 0 : (_state$domainStates8 = state.domainStates) === null || _state$domainStates8 === void 0 ? void 0 : _state$domainStates8.liveChatConfig);
217
+ if (midAuthEnabled) {
218
+ var _state$appStates4, _persistedState$appSt;
219
+ const isUserAuthenticated = (state === null || state === void 0 ? void 0 : (_state$appStates4 = state.appStates) === null || _state$appStates4 === void 0 ? void 0 : _state$appStates4.isUserAuthenticated) === true || (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt = persistedState.appStates) === null || _persistedState$appSt === void 0 ? void 0 : _persistedState$appSt.isUserAuthenticated) === true;
220
+ startChatOptionalParams.wasAuthenticated = isUserAuthenticated;
221
+ }
222
+
211
223
  // startTime is used to determine if a message is history or new, better to be set before creating the adapter to get bandwidth
212
224
  const startTime = new Date().getTime();
213
225
  (0, _FirstMessageTrackerFromBot.createTrackingForFirstMessage)();
226
+
227
+ // FacadeChatSDK.startChat() handles:
228
+ // 1. tokenRing() - checks authentication, calls handleAuthentication() if needed
229
+ // 2. Mid-auth: If no token, sets deferInitialAuth=true for unauthenticated flow
230
+ // 3. Mid-auth: On reconnect with valid token, calls authenticateChat to upgrade conversation
214
231
  await facadeChatSDK.startChat(startChatOptionalParams);
215
232
  (0, _startChatErrorHandler.logStartChatComplete)();
216
233
  isStartChatSuccessful = true;
@@ -298,15 +315,15 @@ const createAdapterAndSubscribe = async (facadeChatSDK, dispatch, setAdapter, st
298
315
  };
299
316
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
317
  const canConnectToExistingChat = async (props, facadeChatSDK, state, dispatch, setAdapter) => {
301
- var _state$appStates4, _persistedState$domai6, _persistedState$appSt;
318
+ var _state$appStates5, _persistedState$domai6, _persistedState$appSt2;
302
319
  // By pass this function in case of popout chat
303
- if ((state === null || state === void 0 ? void 0 : (_state$appStates4 = state.appStates) === null || _state$appStates4 === void 0 ? void 0 : _state$appStates4.hideStartChatButton) === true) {
320
+ if ((state === null || state === void 0 ? void 0 : (_state$appStates5 = state.appStates) === null || _state$appStates5 === void 0 ? void 0 : _state$appStates5.hideStartChatButton) === true) {
304
321
  return false;
305
322
  }
306
323
  const persistedState = (0, _utils.getStateFromCache)((0, _utils.getWidgetCacheIdfromProps)(props));
307
324
 
308
325
  //Connect to only active chat session
309
- if (persistedState && !(0, _utils.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.ConversationState.Active) {
326
+ if (persistedState && !(0, _utils.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$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === _ConversationState.ConversationState.Active) {
310
327
  var _persistedState$domai7;
311
328
  dispatch({
312
329
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
@@ -323,11 +340,11 @@ const canConnectToExistingChat = async (props, facadeChatSDK, state, dispatch, s
323
340
 
324
341
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
325
342
  const setCustomContextParams = async (state, props) => {
326
- var _state$domainStates8, _persistedState$domai8;
327
- if (state !== null && state !== void 0 && (_state$domainStates8 = state.domainStates) !== null && _state$domainStates8 !== void 0 && _state$domainStates8.customContext) {
328
- var _state$domainStates9;
343
+ var _state$domainStates9, _persistedState$domai8;
344
+ if (state !== null && state !== void 0 && (_state$domainStates9 = state.domainStates) !== null && _state$domainStates9 !== void 0 && _state$domainStates9.customContext) {
345
+ var _state$domainStates10;
329
346
  optionalParams = Object.assign({}, optionalParams, {
330
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates9 = state.domainStates) === null || _state$domainStates9 === void 0 ? void 0 : _state$domainStates9.customContext))
347
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates10 = state.domainStates) === null || _state$domainStates10 === void 0 ? void 0 : _state$domainStates10.customContext))
331
348
  });
332
349
  return;
333
350
  }
@@ -360,9 +377,9 @@ const canStartPopoutChat = async props => {
360
377
  }
361
378
  popoutWidgetInstanceId = (0, _utils.getWidgetCacheIdfromProps)(props, true);
362
379
  if (!(0, _utils.isNullOrEmptyString)(popoutWidgetInstanceId)) {
363
- var _persistedState$domai9, _persistedState$appSt2;
380
+ var _persistedState$domai9, _persistedState$appSt3;
364
381
  const persistedState = (0, _utils.getStateFromCache)(popoutWidgetInstanceId);
365
- if (persistedState && !(0, _utils.isUndefinedOrEmpty)(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt2 = persistedState.appStates) === null || _persistedState$appSt2 === void 0 ? void 0 : _persistedState$appSt2.conversationState) === _ConversationState.ConversationState.Active) {
382
+ if (persistedState && !(0, _utils.isUndefinedOrEmpty)(persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai9 = persistedState.domainStates) === null || _persistedState$domai9 === void 0 ? void 0 : _persistedState$domai9.liveChatContext) && (persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$appSt3 = persistedState.appStates) === null || _persistedState$appSt3 === void 0 ? void 0 : _persistedState$appSt3.conversationState) === _ConversationState.ConversationState.Active) {
366
383
  // Initiate popout chat
367
384
  _omnichannelChatComponents.BroadcastService.postMessage({
368
385
  eventName: _TelemetryConstants.BroadcastEvent.InitiateStartChatInPopoutMode
@@ -375,9 +392,9 @@ const canStartPopoutChat = async props => {
375
392
 
376
393
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
377
394
  const checkIfConversationStillValid = async (facadeChatSDK, dispatch, state) => {
378
- var _state$domainStates10, _state$domainStates11, _state$domainStates12;
379
- const requestIdFromCache = (_state$domainStates10 = state.domainStates) === null || _state$domainStates10 === void 0 ? void 0 : (_state$domainStates11 = _state$domainStates10.liveChatContext) === null || _state$domainStates11 === void 0 ? void 0 : _state$domainStates11.requestId;
380
- const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates12 = state.domainStates) === null || _state$domainStates12 === void 0 ? void 0 : _state$domainStates12.liveChatContext;
395
+ var _state$domainStates11, _state$domainStates12, _state$domainStates13;
396
+ const requestIdFromCache = (_state$domainStates11 = state.domainStates) === null || _state$domainStates11 === void 0 ? void 0 : (_state$domainStates12 = _state$domainStates11.liveChatContext) === null || _state$domainStates12 === void 0 ? void 0 : _state$domainStates12.requestId;
397
+ const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates13 = state.domainStates) === null || _state$domainStates13 === void 0 ? void 0 : _state$domainStates13.liveChatContext;
381
398
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
399
  let conversationDetails = undefined;
383
400
  // Preserve current requestId
@@ -54,6 +54,7 @@ var _initConfirmationPropsComposer = require("../common/initConfirmationPropsCom
54
54
  var _initWebChatComposer = require("../common/initWebChatComposer");
55
55
  var _defaultCacheManager = require("../../../common/storage/default/defaultCacheManager");
56
56
  var _setPostChatContextAndLoadSurvey = require("../common/setPostChatContextAndLoadSurvey");
57
+ var _liveChatConfigUtils = require("../common/liveChatConfigUtils");
57
58
  var _startProactiveChat = require("../common/startProactiveChat");
58
59
  var _useChatAdapterStore = _interopRequireDefault(require("../../../hooks/useChatAdapterStore"));
59
60
  var _useChatContextStore = _interopRequireDefault(require("../../../hooks/useChatContextStore"));
@@ -65,7 +66,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
65
66
  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); }
66
67
  let uiTimer;
67
68
  const LiveChatWidgetStateful = props => {
68
- var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates8, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
69
+ var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates8, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _props$headerProps, _props$headerProps$co, _props$headerProps$co2, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
69
70
  (0, _react2.useEffect)(() => {
70
71
  uiTimer = (0, _utils.createTimer)();
71
72
  _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
@@ -736,7 +737,15 @@ const LiveChatWidgetStateful = props => {
736
737
  if (state.appStates.isMinimized) {
737
738
  _ActivityStreamHandler.ActivityStreamHandler.cork();
738
739
  } else {
739
- setTimeout(() => _ActivityStreamHandler.ActivityStreamHandler.uncork(), 500);
740
+ var _state$domainStates4;
741
+ const extendedChatConfig = state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : _state$domainStates4.liveChatConfig;
742
+ if ((0, _liveChatConfigUtils.shouldLoadPersistentChatHistory)(extendedChatConfig)) {
743
+ requestAnimationFrame(() => {
744
+ setTimeout(() => _ActivityStreamHandler.ActivityStreamHandler.uncork(), 500);
745
+ });
746
+ } else {
747
+ setTimeout(() => _ActivityStreamHandler.ActivityStreamHandler.uncork(), 500);
748
+ }
740
749
  }
741
750
  }, [state.appStates.isMinimized]);
742
751
 
@@ -814,7 +823,7 @@ const LiveChatWidgetStateful = props => {
814
823
 
815
824
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
816
825
  // Hence setting ConversationState to InActive will be done later in the post chat flows
817
- if (!isConversationalSurveyEnabled && (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta12 = inMemoryState.appStates) === null || _inMemoryState$appSta12 === void 0 ? void 0 : _inMemoryState$appSta12.conversationEndedBy) === _Constants.ConversationEndEntity.Agent || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta13 = inMemoryState.appStates) === null || _inMemoryState$appSta13 === void 0 ? void 0 : _inMemoryState$appSta13.conversationEndedBy) === _Constants.ConversationEndEntity.Bot) {
826
+ if (!isConversationalSurveyEnabled && ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta12 = inMemoryState.appStates) === null || _inMemoryState$appSta12 === void 0 ? void 0 : _inMemoryState$appSta12.conversationEndedBy) === _Constants.ConversationEndEntity.Agent || (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta13 = inMemoryState.appStates) === null || _inMemoryState$appSta13 === void 0 ? void 0 : _inMemoryState$appSta13.conversationEndedBy) === _Constants.ConversationEndEntity.Bot)) {
818
827
  dispatch({
819
828
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
820
829
  payload: _ConversationState.ConversationState.InActive
@@ -875,6 +884,37 @@ const LiveChatWidgetStateful = props => {
875
884
  }
876
885
  }, [state.appStates.chatDisconnectEventReceived]);
877
886
 
887
+ // Auth state change listeners (broadcast by FacadeChatSDK.startChat())
888
+ (0, _react2.useEffect)(() => {
889
+ const authSucceededSub = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.MidConversationAuthSucceeded).subscribe(msg => {
890
+ var _msg$payload15;
891
+ if (msg !== null && msg !== void 0 && (_msg$payload15 = msg.payload) !== null && _msg$payload15 !== void 0 && _msg$payload15.isAuthenticated) {
892
+ // Only store boolean flag, NOT the token - token is managed by FacadeChatSDK
893
+ dispatch({
894
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_USER_AUTHENTICATED,
895
+ payload: true
896
+ });
897
+ }
898
+ });
899
+
900
+ // Auth reset: only update the boolean flag here.
901
+ // We do NOT clear widget state/cache/adapter because this fires DURING startChat(),
902
+ // which will handle state transitions. FacadeChatSDK has already cleared SDK internals.
903
+ const authResetSub = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.MidConversationAuthReset).subscribe(msg => {
904
+ var _msg$payload16;
905
+ if ((msg === null || msg === void 0 ? void 0 : (_msg$payload16 = msg.payload) === null || _msg$payload16 === void 0 ? void 0 : _msg$payload16.isAuthenticated) === false) {
906
+ dispatch({
907
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_USER_AUTHENTICATED,
908
+ payload: false
909
+ });
910
+ }
911
+ });
912
+ return () => {
913
+ authSucceededSub.unsubscribe();
914
+ authResetSub.unsubscribe();
915
+ };
916
+ }, [dispatch]);
917
+
878
918
  // if props state gets updates we need to update the renderingMiddlewareProps in the state
879
919
  (0, _react2.useEffect)(() => {
880
920
  var _props$webChatContain16;
@@ -893,6 +933,25 @@ const LiveChatWidgetStateful = props => {
893
933
  }
894
934
  });
895
935
  }, []);
936
+
937
+ // Reliable browser close detection via visibilitychange + sendBeacon
938
+ // visibilitychange fires while the page is still alive (unlike beforeunload),
939
+ // so telemetry calls complete reliably. False positives (tab switch, minimize)
940
+ // are filtered in Kusto by checking if this is the last event in the session.
941
+ (0, _react2.useEffect)(() => {
942
+ const handleVisibilityChange = () => {
943
+ if (document.visibilityState === "hidden" && state.appStates.conversationState === _ConversationState.ConversationState.Active) {
944
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
945
+ Event: _TelemetryConstants.TelemetryEvent.BrowserTabHidden,
946
+ Description: "Browser tab hidden during active conversation"
947
+ });
948
+ }
949
+ };
950
+ document.addEventListener("visibilitychange", handleVisibilityChange);
951
+ return () => {
952
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
953
+ };
954
+ }, [state.appStates.conversationState]);
896
955
  const initiateEndChatOnBrowserUnload = () => {
897
956
  var _DataStoreManager$cli;
898
957
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
@@ -963,12 +1022,22 @@ const LiveChatWidgetStateful = props => {
963
1022
  // React to dynamic bot avatar initials updates from context
964
1023
  (0, _react2.useEffect)(() => {
965
1024
  if (state.domainStates.botAvatarInitials && state.domainStates.botAvatarInitials !== webChatStyles.botAvatarInitials) {
1025
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */
966
1026
  setWebChatStyles(styles => ({
967
1027
  ...styles,
968
1028
  botAvatarInitials: state.domainStates.botAvatarInitials
969
1029
  }));
970
1030
  }
971
1031
  }, [state.domainStates.botAvatarInitials]);
1032
+ const isWidgetOpen = !state.appStates.isMinimized && state.appStates.conversationState !== _ConversationState.ConversationState.Closed;
1033
+ const siblingAriaHiddenMapRef = (0, _react2.useRef)(new Map());
1034
+ (0, _react2.useEffect)(() => {
1035
+ const map = siblingAriaHiddenMapRef.current;
1036
+ (0, _utils.setAriaHiddenForSiblings)(widgetElementId, isWidgetOpen, map);
1037
+ return () => {
1038
+ (0, _utils.setAriaHiddenForSiblings)(widgetElementId, false, map);
1039
+ };
1040
+ }, [isWidgetOpen]);
972
1041
 
973
1042
  // WebChat's Composer can only be rendered if a directLine object is defined
974
1043
  return directLine && /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("style", null, `
@@ -1015,10 +1084,31 @@ const LiveChatWidgetStateful = props => {
1015
1084
  .webchat__basic-transcript__activity-markdown-body > :last-child {
1016
1085
  margin-bottom: 0px;
1017
1086
  }
1018
-
1087
+
1019
1088
  .webchat__basic-transcript__activity-markdown-body > :first-child {
1020
1089
  margin-top: 0px;
1021
1090
  }
1091
+
1092
+ /* Remove browser-default <p> margins inside system messages.
1093
+ Without this, each markdown paragraph adds ~1em top+bottom gap
1094
+ which causes the oversized line spacing visible on iOS Safari.
1095
+ Also disable iOS Safari's auto font-size scaling (-webkit-text-size-adjust)
1096
+ which inflates font sizes and causes line-height to grow over time
1097
+ when the layout is viewed in a narrow viewport. */
1098
+ .webchat__basic-transcript__activity-markdown-body {
1099
+ -webkit-text-size-adjust: 100%;
1100
+ text-size-adjust: 100%;
1101
+ }
1102
+
1103
+ .webchat__basic-transcript__activity-markdown-body p {
1104
+ margin-top: 0;
1105
+ margin-bottom: 4px;
1106
+ line-height: 1.4;
1107
+ }
1108
+
1109
+ .webchat__basic-transcript__activity-markdown-body p:last-child {
1110
+ margin-bottom: 0;
1111
+ }
1022
1112
 
1023
1113
  .webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
1024
1114
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
@@ -1026,6 +1116,32 @@ const LiveChatWidgetStateful = props => {
1026
1116
  margin-left: .25em;
1027
1117
  }
1028
1118
 
1119
+ /* ── iOS Safari: underline + number alignment fixes ────────────────
1120
+ 1. Position underlines below all glyphs (not at alphabetic baseline)
1121
+ so they never intersect numbers in links or auto-detected tel: hrefs.
1122
+ 2. Use a solid underline (skip-ink: none) so numbers aren't split by
1123
+ gaps the browser renders around descenders.
1124
+ 3. Prevent ::marker pseudo-element from inheriting text-decoration,
1125
+ which Safari applies to ol/ul counters causing them to appear
1126
+ underlined and misaligned.
1127
+ 4. Normalise ordered-list indentation across Safari/WebKit. */
1128
+ .webchat__basic-transcript__activity-markdown-body a {
1129
+ -webkit-text-underline-position: under;
1130
+ text-underline-position: under;
1131
+ text-decoration-skip-ink: none;
1132
+ -webkit-text-decoration-skip: none;
1133
+ }
1134
+
1135
+ .webchat__basic-transcript__activity-markdown-body ol li::marker,
1136
+ .webchat__basic-transcript__activity-markdown-body ul li::marker {
1137
+ text-decoration: none;
1138
+ }
1139
+
1140
+ .webchat__basic-transcript__activity-markdown-body ol {
1141
+ -webkit-padding-start: 1.5em;
1142
+ padding-inline-start: 1.5em;
1143
+ }
1144
+
1029
1145
  .webchat__link-definitions__header-text {
1030
1146
  color: ${bubbleBackground}
1031
1147
  }
@@ -1045,7 +1161,10 @@ const LiveChatWidgetStateful = props => {
1045
1161
  }), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
1046
1162
  id: widgetElementId,
1047
1163
  styles: generalStyles,
1048
- className: (_livechatProps$styleP = livechatProps.styleProps) === null || _livechatProps$styleP === void 0 ? void 0 : _livechatProps$styleP.className
1164
+ className: (_livechatProps$styleP = livechatProps.styleProps) === null || _livechatProps$styleP === void 0 ? void 0 : _livechatProps$styleP.className,
1165
+ role: isWidgetOpen ? "dialog" : undefined,
1166
+ "aria-modal": isWidgetOpen ? true : undefined,
1167
+ "aria-label": isWidgetOpen ? ((_props$headerProps = props.headerProps) === null || _props$headerProps === void 0 ? void 0 : (_props$headerProps$co = _props$headerProps.controlProps) === null || _props$headerProps$co === void 0 ? void 0 : (_props$headerProps$co2 = _props$headerProps$co.headerTitleProps) === null || _props$headerProps$co2 === void 0 ? void 0 : _props$headerProps$co2.text) ?? "Live Chat" : undefined
1049
1168
  }, !((_livechatProps$contro = livechatProps.controlProps) !== null && _livechatProps$contro !== void 0 && _livechatProps$contro.hideChatButton) && !((_livechatProps$contro2 = livechatProps.controlProps) !== null && _livechatProps$contro2 !== void 0 && _livechatProps$contro2.hideStartChatButton) && (0, _componentController.shouldShowChatButton)(state) && ((0, _omnichannelChatComponents.decodeComponentString)((_livechatProps$compon = livechatProps.componentOverrides) === null || _livechatProps$compon === void 0 ? void 0 : _livechatProps$compon.chatButton) || /*#__PURE__*/_react2.default.createElement(_ChatButtonStateful.default, {
1050
1169
  buttonProps: livechatProps.chatButtonProps,
1051
1170
  outOfOfficeButtonProps: livechatProps.outOfOfficeChatButtonProps,
@@ -16,13 +16,22 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
16
16
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
17
  let uiTimer;
18
18
  const PostChatLoadingPaneStateful = props => {
19
- var _props$styleProps;
19
+ var _props$controlProps, _props$styleProps;
20
+ const defaultSubtitleText = "Please take a moment to give us feedback about your chat experience. We are loading the survey for you now.";
21
+ const subtitleText = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.subtitleText) ?? defaultSubtitleText;
22
+ const [announcedSubtitleText, setAnnouncedSubtitleText] = (0, _react.useState)("");
20
23
  (0, _react.useEffect)(() => {
21
24
  uiTimer = (0, _utils.createTimer)();
22
25
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
23
26
  Event: _TelemetryConstants.TelemetryEvent.UXPostChatLoadingPaneStart
24
27
  });
25
28
  }, []);
29
+ (0, _react.useEffect)(() => {
30
+ const timeout = window.setTimeout(() => {
31
+ setAnnouncedSubtitleText(subtitleText);
32
+ }, 0);
33
+ return () => window.clearTimeout(timeout);
34
+ }, [subtitleText]);
26
35
  const [state] = (0, _useChatContextStore.default)();
27
36
  const generalStyleProps = Object.assign({}, _defaultgeneralPostChatLoadingPaneStyleProps.defaultGeneralPostChatLoadingPaneStyleProps, (_props$styleProps = props.styleProps) === null || _props$styleProps === void 0 ? void 0 : _props$styleProps.generalStyleProps);
28
37
  const styleProps = {
@@ -36,8 +45,11 @@ const PostChatLoadingPaneStateful = props => {
36
45
  hideTitle: true,
37
46
  hideSpinner: true,
38
47
  hideSpinnerText: true,
39
- subtitleText: "Please take a moment to give us feedback about your chat experience. We are loading the survey for you now.",
40
- ...props.controlProps
48
+ ...props.controlProps,
49
+ role: "status",
50
+ "aria-live": "polite",
51
+ "aria-atomic": "true",
52
+ subtitleText: announcedSubtitleText
41
53
  };
42
54
 
43
55
  // Move focus to the first button
@@ -31,7 +31,7 @@ const generateSurveyInviteLink = function (surveyInviteLink, isEmbed, locale, co
31
31
  return `${surveyInviteLink}&${surveyLinkParams.toString()}`;
32
32
  };
33
33
  const PostChatSurveyPaneStateful = props => {
34
- var _props$styleProps, _state$appStates, _props$controlProps;
34
+ var _props$styleProps, _state$appStates, _state$domainStates$p, _props$controlProps;
35
35
  (0, _react.useEffect)(() => {
36
36
  uiTimer = (0, _utils.createTimer)();
37
37
  _TelemetryHelper.TelemetryHelper.logLoadingEventToAllTelemetry(_TelemetryConstants.LogLevel.INFO, {
@@ -48,13 +48,15 @@ const PostChatSurveyPaneStateful = props => {
48
48
  });
49
49
  let surveyInviteLink = "";
50
50
  const surveyMode = (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.selectedSurveyMode) === _PostChatSurveyMode.PostChatSurveyMode.Embed;
51
- if (state.domainStates.postChatContext.botSurveyInviteLink &&
51
+ if ((_state$domainStates$p = state.domainStates.postChatContext) !== null && _state$domainStates$p !== void 0 && _state$domainStates$p.botSurveyInviteLink &&
52
52
  // Bot survey enabled
53
53
  state.appStates.postChatParticipantType === _Constants.ParticipantType.Bot) {
54
+ var _state$domainStates$p2, _state$domainStates$p3;
54
55
  // Only Bot has engaged
55
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.botSurveyInviteLink, surveyMode, state.domainStates.postChatContext.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
56
+ surveyInviteLink = generateSurveyInviteLink((_state$domainStates$p2 = state.domainStates.postChatContext) === null || _state$domainStates$p2 === void 0 ? void 0 : _state$domainStates$p2.botSurveyInviteLink, surveyMode, (_state$domainStates$p3 = state.domainStates.postChatContext) === null || _state$domainStates$p3 === void 0 ? void 0 : _state$domainStates$p3.botFormsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
56
57
  } else {
57
- surveyInviteLink = generateSurveyInviteLink(state.domainStates.postChatContext.surveyInviteLink, surveyMode, state.domainStates.postChatContext.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
58
+ var _state$domainStates$p4, _state$domainStates$p5;
59
+ surveyInviteLink = generateSurveyInviteLink((_state$domainStates$p4 = state.domainStates.postChatContext) === null || _state$domainStates$p4 === void 0 ? void 0 : _state$domainStates$p4.surveyInviteLink, surveyMode, (_state$domainStates$p5 = state.domainStates.postChatContext) === null || _state$domainStates$p5 === void 0 ? void 0 : _state$domainStates$p5.formsProLocale, props.isCustomerVoiceSurveyCompact ?? true, props.customerVoiceSurveyCorrelationId || "");
58
60
  }
59
61
  if (props.copilotSurveyContext) {
60
62
  surveyInviteLink = `${surveyInviteLink}&mcs_additionalcontext=${JSON.stringify(props.copilotSurveyContext)}`;
@@ -65,6 +67,7 @@ const PostChatSurveyPaneStateful = props => {
65
67
  };
66
68
  const controlProps = {
67
69
  id: "oc-lcw-postchatsurvey-pane",
70
+ title: "Post-chat survey",
68
71
  surveyURL: ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.surveyURL) ?? surveyInviteLink,
69
72
  ...props.controlProps
70
73
  };
@@ -20,6 +20,34 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
20
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
21
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
22
22
  let uiTimer;
23
+ const getFocusedElementAnnouncement = element => {
24
+ var _element$textContent;
25
+ const ariaLabel = element.getAttribute(_Constants.HtmlAttributeNames.ariaLabel);
26
+ if (ariaLabel) {
27
+ return ariaLabel.trim();
28
+ }
29
+ const ariaLabelledBy = element.getAttribute(_Constants.HtmlAttributeNames.ariaLabelledby);
30
+ if (ariaLabelledBy) {
31
+ const labelledByText = ariaLabelledBy.split(/\s+/).map(id => {
32
+ var _document$getElementB, _document$getElementB2;
33
+ return (_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : (_document$getElementB2 = _document$getElementB.textContent) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.trim();
34
+ }).filter(Boolean).join(" ");
35
+ if (labelledByText) {
36
+ return labelledByText;
37
+ }
38
+ }
39
+ if (element.id) {
40
+ const label = Array.from(document.querySelectorAll("label")).find(candidate => candidate.htmlFor === element.id || candidate.getAttribute("for") === element.id);
41
+ if (label !== null && label !== void 0 && label.textContent) {
42
+ return label.textContent.trim();
43
+ }
44
+ }
45
+ const parentLabel = element.closest("label");
46
+ if (parentLabel !== null && parentLabel !== void 0 && parentLabel.textContent) {
47
+ return parentLabel.textContent.trim();
48
+ }
49
+ return ((_element$textContent = element.textContent) === null || _element$textContent === void 0 ? void 0 : _element$textContent.trim()) ?? "";
50
+ };
23
51
 
24
52
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
53
  const PreChatSurveyPaneStateful = props => {
@@ -42,6 +70,8 @@ const PreChatSurveyPaneStateful = props => {
42
70
  surveyProps,
43
71
  initStartChat
44
72
  } = props;
73
+ const [preChatFocusAnnouncement, setPreChatFocusAnnouncement] = (0, _react.useState)("");
74
+ const liveRegionUpdateTimeout = (0, _react.useRef)();
45
75
  const generalStyleProps = Object.assign({}, _defaultGeneralPreChatSurveyPaneStyleProps.defaultGeneralPreChatSurveyPaneStyleProps, surveyProps === null || surveyProps === void 0 ? void 0 : (_surveyProps$stylePro = surveyProps.styleProps) === null || _surveyProps$stylePro === void 0 ? void 0 : _surveyProps$stylePro.generalStyleProps, {
46
76
  display: state.appStates.isMinimized ? "none" : ""
47
77
  });
@@ -128,6 +158,16 @@ const PreChatSurveyPaneStateful = props => {
128
158
  ...(surveyProps === null || surveyProps === void 0 ? void 0 : surveyProps.styleProps),
129
159
  generalStyleProps: generalStyleProps
130
160
  };
161
+ const announceFocusedElement = event => {
162
+ if (liveRegionUpdateTimeout.current) {
163
+ window.clearTimeout(liveRegionUpdateTimeout.current);
164
+ }
165
+ const announcement = getFocusedElementAnnouncement(event.target);
166
+ setPreChatFocusAnnouncement("");
167
+ liveRegionUpdateTimeout.current = window.setTimeout(() => {
168
+ setPreChatFocusAnnouncement(announcement);
169
+ }, 0);
170
+ };
131
171
  (0, _react.useEffect)(() => {
132
172
  // Set Aria-Label Attribute for Inputs
133
173
  const adaptiveCardElements = document.getElementsByClassName(_Constants.HtmlAttributeNames.adaptiveCardClassName);
@@ -175,10 +215,36 @@ const PreChatSurveyPaneStateful = props => {
175
215
  }
176
216
  }
177
217
  }, [state.appStates.isMinimized]);
178
- return /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.PreChatSurveyPane, {
218
+ (0, _react.useEffect)(() => () => {
219
+ if (liveRegionUpdateTimeout.current) {
220
+ window.clearTimeout(liveRegionUpdateTimeout.current);
221
+ }
222
+ }, []);
223
+ return /*#__PURE__*/_react.default.createElement("div", {
224
+ onFocusCapture: announceFocusedElement,
225
+ style: {
226
+ width: "100%",
227
+ height: "100%"
228
+ }
229
+ }, /*#__PURE__*/_react.default.createElement("div", {
230
+ role: "status",
231
+ "aria-live": "polite",
232
+ "aria-atomic": "true",
233
+ style: {
234
+ position: "absolute",
235
+ width: "1px",
236
+ height: "1px",
237
+ margin: "-1px",
238
+ padding: 0,
239
+ border: 0,
240
+ clip: "rect(0, 0, 0, 0)",
241
+ overflow: "hidden",
242
+ whiteSpace: "nowrap"
243
+ }
244
+ }, preChatFocusAnnouncement), /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.PreChatSurveyPane, {
179
245
  controlProps: controlProps,
180
246
  styleProps: styleProps
181
- });
247
+ }));
182
248
  };
183
249
  exports.PreChatSurveyPaneStateful = PreChatSurveyPaneStateful;
184
250
  var _default = PreChatSurveyPaneStateful;
@@ -12,6 +12,7 @@ const defaultGeneralPreChatSurveyPaneStyleProps = {
12
12
  borderColor: "#F1F1F1",
13
13
  overflowY: "auto",
14
14
  height: "inherit",
15
- width: "inherit"
15
+ width: "inherit",
16
+ overscrollBehavior: "none"
16
17
  };
17
18
  exports.defaultGeneralPreChatSurveyPaneStyleProps = defaultGeneralPreChatSurveyPaneStyleProps;
@@ -122,7 +122,6 @@ const ProactiveChatPaneStateful = props => {
122
122
  bodyTitleText: state.appStates.proactiveChatStates.proactiveChatBodyTitle ? state.appStates.proactiveChatStates.proactiveChatBodyTitle : proactiveChatProps === null || proactiveChatProps === void 0 ? void 0 : (_proactiveChatProps$c = proactiveChatProps.controlProps) === null || _proactiveChatProps$c === void 0 ? void 0 : _proactiveChatProps$c.bodyTitleText
123
123
  };
124
124
  (0, _react.useEffect)(() => {
125
- (0, _utils.setFocusOnElement)(document.getElementById(controlProps.id + "-startbutton"));
126
125
  _TelemetryManager.TelemetryTimers.ProactiveChatScreenTimer = (0, _utils.createTimer)();
127
126
  const timeoutEvent = setTimeout(() => {
128
127
  handleProactiveChatInviteTimeout();