@microsoft/omnichannel-chat-widget 1.8.7 → 2.0.0-main.5ebd4eb

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 (251) hide show
  1. package/README.md +52 -5
  2. package/lib/cjs/common/Constants.js +5 -0
  3. package/lib/cjs/common/facades/FacadeChatSDK.js +234 -9
  4. package/lib/cjs/common/telemetry/TelemetryConstants.js +19 -0
  5. package/lib/cjs/common/telemetry/TelemetryManager.js +6 -1
  6. package/lib/cjs/common/telemetry/loggers/appInsightsLogger.js +2 -3
  7. package/lib/cjs/common/telemetry/sanitizeSasInPayload.js +91 -0
  8. package/lib/cjs/common/utils.js +93 -17
  9. package/lib/cjs/components/callingcontainerstateful/CallingContainerStateful.js +16 -6
  10. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +20 -10
  11. package/lib/cjs/components/citationpanestateful/CitationDim.js +2 -3
  12. package/lib/cjs/components/citationpanestateful/CitationPaneStateful.js +27 -5
  13. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +23 -3
  14. package/lib/cjs/components/dimlayer/DimLayer.js +1 -3
  15. package/lib/cjs/components/draggable/DraggableChatWidget.js +35 -15
  16. package/lib/cjs/components/draggable/DraggableEventEmitter.js +10 -1
  17. package/lib/cjs/components/draggable/DraggableEventReceiver.js +1 -3
  18. package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +54 -17
  19. package/lib/cjs/components/errorboundary/ErrorBoundary.js +4 -12
  20. package/lib/cjs/components/footerstateful/FooterStateful.js +18 -9
  21. package/lib/cjs/components/footerstateful/audionotificationstateful/AudioNotificationStateful.js +2 -4
  22. package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +4 -6
  23. package/lib/cjs/components/headerstateful/HeaderStateful.js +24 -12
  24. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +27 -4
  25. package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/HiddenAdaptiveCardActivitySubscriber.js +5 -11
  26. package/lib/cjs/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  27. package/lib/cjs/components/livechatwidget/common/PersistentConversationHandler.js +11 -4
  28. package/lib/cjs/components/livechatwidget/common/authHelper.js +44 -4
  29. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +98 -5
  30. package/lib/cjs/components/livechatwidget/common/endChat.js +12 -9
  31. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +182 -1
  32. package/lib/cjs/components/livechatwidget/common/recoveryEligibilityTelemetry.js +60 -0
  33. package/lib/cjs/components/livechatwidget/common/startChat.js +31 -14
  34. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +160 -21
  35. package/lib/cjs/components/loadingpanestateful/LoadingPaneStateful.js +16 -11
  36. package/lib/cjs/components/notificationpanestateful/NotificationPaneStateful.js +19 -12
  37. package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +13 -6
  38. package/lib/cjs/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +28 -5
  39. package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +12 -5
  40. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +105 -11
  41. package/lib/cjs/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +12 -1
  42. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +17 -7
  43. package/lib/cjs/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +16 -7
  44. package/lib/cjs/components/startchaterrorpanestateful/StartChatErrorPaneStateful.js +10 -2
  45. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +154 -29
  46. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +10 -0
  47. package/lib/cjs/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +115 -10
  48. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
  49. package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -1
  50. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  51. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  52. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +3 -1
  53. package/lib/cjs/components/webchatcontainerstateful/common/utils/citationA11y.js +195 -0
  54. package/lib/cjs/components/webchatcontainerstateful/interfaces/IWebChatAction.js +17 -1
  55. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +27 -4
  56. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/adaptermiddlewares/formatTagsEgressMiddleware.js +1 -3
  57. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/adaptermiddlewares/formatTagsIngressMiddleware.js +1 -3
  58. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +180 -190
  59. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +3 -5
  60. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +22 -6
  61. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +12 -23
  62. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +27 -35
  63. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +199 -0
  64. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/Attachment.js +29 -15
  65. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/avatarMiddleware.js +5 -12
  66. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +1 -1
  67. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  68. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  69. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
  70. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/groupActivitiesMiddleware.js +5 -8
  71. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +6 -4
  72. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.js +6 -4
  73. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +14 -12
  74. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +16 -14
  75. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +18 -30
  76. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +10 -2
  77. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/toastMiddleware.js +1 -3
  78. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/typingIndicatorMiddleware.js +16 -12
  79. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentProcessingMiddleware.js +6 -6
  80. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +83 -0
  81. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +36 -8
  82. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +5 -1
  83. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +10 -7
  84. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +4 -0
  85. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +6 -4
  86. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +5 -1
  87. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +7 -7
  88. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/gifUploadMiddleware.js +10 -14
  89. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware.js +6 -4
  90. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +13 -10
  91. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +57 -11
  92. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator.js +6 -4
  93. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware.js +25 -30
  94. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +10 -7
  95. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +6 -4
  96. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
  97. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +2 -4
  98. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +5 -0
  99. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +17 -1
  100. package/lib/cjs/contexts/createReducer.js +15 -0
  101. package/lib/cjs/controller/componentController.js +13 -1
  102. package/lib/cjs/hooks/useWindowDimensions.js +13 -5
  103. package/lib/cjs/package.json +1 -0
  104. package/lib/cjs/plugins/createChatTranscript.js +3 -4
  105. package/lib/cjs/plugins/newMessageEventHandler.js +20 -3
  106. package/lib/esm/common/Constants.js +5 -0
  107. package/lib/esm/common/facades/FacadeChatSDK.js +235 -10
  108. package/lib/esm/common/telemetry/TelemetryConstants.js +19 -0
  109. package/lib/esm/common/telemetry/TelemetryManager.js +6 -1
  110. package/lib/esm/common/telemetry/loggers/appInsightsLogger.js +2 -3
  111. package/lib/esm/common/telemetry/sanitizeSasInPayload.js +84 -0
  112. package/lib/esm/common/utils.js +88 -14
  113. package/lib/esm/components/callingcontainerstateful/CallingContainerStateful.js +15 -5
  114. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +19 -9
  115. package/lib/esm/components/citationpanestateful/CitationDim.js +2 -3
  116. package/lib/esm/components/citationpanestateful/CitationPaneStateful.js +26 -4
  117. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +22 -2
  118. package/lib/esm/components/dimlayer/DimLayer.js +1 -3
  119. package/lib/esm/components/draggable/DraggableChatWidget.js +34 -14
  120. package/lib/esm/components/draggable/DraggableEventEmitter.js +10 -1
  121. package/lib/esm/components/draggable/DraggableEventReceiver.js +1 -3
  122. package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +54 -17
  123. package/lib/esm/components/errorboundary/ErrorBoundary.js +4 -12
  124. package/lib/esm/components/footerstateful/FooterStateful.js +17 -8
  125. package/lib/esm/components/footerstateful/audionotificationstateful/AudioNotificationStateful.js +2 -4
  126. package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +4 -6
  127. package/lib/esm/components/headerstateful/HeaderStateful.js +22 -10
  128. package/lib/esm/components/livechatwidget/LiveChatWidget.js +27 -4
  129. package/lib/esm/components/livechatwidget/common/ActivitySubscriber/HiddenAdaptiveCardActivitySubscriber.js +5 -11
  130. package/lib/esm/components/livechatwidget/common/ChatWidgetEvents.js +1 -0
  131. package/lib/esm/components/livechatwidget/common/PersistentConversationHandler.js +11 -4
  132. package/lib/esm/components/livechatwidget/common/authHelper.js +44 -4
  133. package/lib/esm/components/livechatwidget/common/createMarkdown.js +98 -5
  134. package/lib/esm/components/livechatwidget/common/endChat.js +12 -9
  135. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +182 -1
  136. package/lib/esm/components/livechatwidget/common/recoveryEligibilityTelemetry.js +52 -0
  137. package/lib/esm/components/livechatwidget/common/startChat.js +31 -14
  138. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +159 -20
  139. package/lib/esm/components/loadingpanestateful/LoadingPaneStateful.js +14 -9
  140. package/lib/esm/components/notificationpanestateful/NotificationPaneStateful.js +17 -10
  141. package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +12 -5
  142. package/lib/esm/components/postchatloadingpanestateful/PostChatLoadingPaneStateful.js +28 -5
  143. package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +11 -4
  144. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +105 -11
  145. package/lib/esm/components/prechatsurveypanestateful/common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps.js +12 -1
  146. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +16 -6
  147. package/lib/esm/components/reconnectchatpanestateful/ReconnectChatPaneStateful.js +15 -6
  148. package/lib/esm/components/startchaterrorpanestateful/StartChatErrorPaneStateful.js +9 -1
  149. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +154 -29
  150. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +10 -0
  151. package/lib/esm/components/webchatcontainerstateful/common/activityConverters/convertPersistentChatHistoryMessageToActivity.js +115 -10
  152. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts.js +3 -0
  153. package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -1
  154. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultAdaptiveCardStyles.js +3 -1
  155. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +2 -2
  156. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +3 -1
  157. package/lib/esm/components/webchatcontainerstateful/common/utils/citationA11y.js +188 -0
  158. package/lib/esm/components/webchatcontainerstateful/interfaces/IWebChatAction.js +10 -1
  159. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/WebChatEventSubscribers.js +27 -4
  160. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/adaptermiddlewares/formatTagsEgressMiddleware.js +1 -3
  161. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/adaptermiddlewares/formatTagsIngressMiddleware.js +1 -3
  162. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.js +180 -190
  163. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LoadInlineBannerActivity.js +3 -5
  164. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.js +19 -4
  165. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityStatusMiddleware.js +12 -23
  166. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +27 -32
  167. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.js +193 -0
  168. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/Attachment.js +28 -14
  169. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/avatarMiddleware.js +5 -12
  170. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware.js +1 -1
  171. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultAvatarTextStyles.js +1 -1
  172. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.js +8 -3
  173. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultTimestampRetryStyles.js +8 -1
  174. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/groupActivitiesMiddleware.js +5 -8
  175. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +6 -4
  176. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.js +6 -4
  177. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +13 -11
  178. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/HistoryMessageTimestamp.js +15 -13
  179. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/NotDeliveredTimestamp.js +17 -27
  180. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/SendingTimestamp.js +9 -1
  181. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/toastMiddleware.js +1 -3
  182. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/typingIndicatorMiddleware.js +16 -10
  183. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentProcessingMiddleware.js +6 -6
  184. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.js +77 -0
  185. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.js +36 -8
  186. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +5 -2
  187. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +10 -7
  188. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +4 -0
  189. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +6 -4
  190. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +5 -1
  191. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.js +7 -7
  192. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/gifUploadMiddleware.js +10 -14
  193. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware.js +6 -4
  194. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +13 -10
  195. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.js +57 -11
  196. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator.js +6 -4
  197. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware.js +25 -31
  198. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +10 -7
  199. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +6 -4
  200. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.js +55 -1
  201. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger.js +2 -4
  202. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +5 -0
  203. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +17 -1
  204. package/lib/esm/contexts/createReducer.js +15 -0
  205. package/lib/esm/controller/componentController.js +13 -1
  206. package/lib/esm/hooks/useWindowDimensions.js +13 -5
  207. package/lib/esm/plugins/createChatTranscript.js +3 -4
  208. package/lib/esm/plugins/newMessageEventHandler.js +20 -3
  209. package/lib/types/common/Constants.d.ts +4 -0
  210. package/lib/types/common/facades/FacadeChatSDK.d.ts +29 -0
  211. package/lib/types/common/facades/types/IFacadeChatSDKInput.d.ts +3 -1
  212. package/lib/types/common/telemetry/TelemetryConstants.d.ts +15 -2
  213. package/lib/types/common/telemetry/sanitizeSasInPayload.d.ts +24 -0
  214. package/lib/types/common/utils.d.ts +3 -1
  215. package/lib/types/components/livechatwidget/common/ChatWidgetEvents.d.ts +2 -1
  216. package/lib/types/components/livechatwidget/common/authHelper.d.ts +9 -2
  217. package/lib/types/components/livechatwidget/common/recoveryEligibilityTelemetry.d.ts +17 -0
  218. package/lib/types/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.d.ts +6 -0
  219. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +1 -1
  220. package/lib/types/components/webchatcontainerstateful/common/utils/citationA11y.d.ts +1 -0
  221. package/lib/types/components/webchatcontainerstateful/interfaces/IAdaptiveCardStyles.d.ts +1 -0
  222. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatAction.d.ts +16 -1
  223. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +7 -0
  224. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activities/LazyLoadActivity.d.ts +14 -38
  225. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/activityMiddleware.d.ts +2 -0
  226. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachments/AdaptiveCardAccessibilityWrapper.d.ts +18 -0
  227. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/defaultStyles/defaultSystemMessageStyles.d.ts +3 -0
  228. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.d.ts +2 -4
  229. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware.d.ts +2 -4
  230. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentProcessingMiddleware.d.ts +2 -4
  231. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentSentAnnouncementMiddleware.d.ts +10 -0
  232. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware.d.ts +2 -4
  233. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +2 -2
  234. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.d.ts +2 -4
  235. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +2 -2
  236. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.d.ts +2 -4
  237. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +2 -2
  238. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware.d.ts +2 -4
  239. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/gifUploadMiddleware.d.ts +2 -4
  240. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware.d.ts +2 -4
  241. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.d.ts +2 -4
  242. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/localizedStringsBotInitialsMiddleware.d.ts +2 -4
  243. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator.d.ts +2 -4
  244. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware.d.ts +2 -4
  245. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +2 -2
  246. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.d.ts +2 -4
  247. package/lib/types/components/webchatcontainerstateful/webchatcontroller/notification/NotificationHandler.d.ts +7 -0
  248. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  249. package/lib/types/contexts/common/ILiveChatWidgetLocalizedTexts.d.ts +17 -0
  250. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +2 -1
  251. package/package.json +71 -57
@@ -1,5 +1,11 @@
1
1
  var _LazyLoadHandler;
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
4
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
5
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
8
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
3
9
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
4
10
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
5
11
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -44,10 +50,6 @@ import { createTimer } from "../../../../../../common/utils";
44
50
  import dispatchCustomEvent from "../../../../../../common/utils/dispatchCustomEvent";
45
51
  import SecureEventBus from "../../../../../../common/utils/SecureEventBus";
46
52
 
47
- /*
48
- * Interface defining the state of a scroll operation
49
- * Used to track and verify scroll actions for reliability
50
- */
51
53
  /**
52
54
  * LazyLoadHandler - Static class managing all lazy loading functionality
53
55
  *
@@ -109,6 +111,7 @@ let LazyLoadHandler = /*#__PURE__*/function () {
109
111
  key: "directReset",
110
112
  value: function directReset() {
111
113
  LazyLoadHandler.resetPending = true;
114
+ LazyLoadHandler.initialLoadComplete = false; // New session — next batch is an initial load
112
115
  LazyLoadHandler.setHasMoreHistoryAvailable(true);
113
116
  LazyLoadHandler.unmount();
114
117
  }
@@ -184,9 +187,8 @@ let LazyLoadHandler = /*#__PURE__*/function () {
184
187
  */
185
188
  const setupObserver = () => {
186
189
  // Find the scroll container using multiple strategies
187
- const {
188
- container: scrollContainer
189
- } = LazyLoadHandler.findScrollContainer();
190
+ const _LazyLoadHandler$find = LazyLoadHandler.findScrollContainer(),
191
+ scrollContainer = _LazyLoadHandler$find.container;
190
192
  if (!scrollContainer) {
191
193
  // Schedule retry with faster timeout for better responsiveness
192
194
  const timeoutId = window.setTimeout(() => {
@@ -308,10 +310,9 @@ let LazyLoadHandler = /*#__PURE__*/function () {
308
310
  key: "executeImmediateScrollFeedback",
309
311
  value: function executeImmediateScrollFeedback() {
310
312
  // Find container and validate scrollability
311
- const {
312
- container,
313
- isScrollable
314
- } = LazyLoadHandler.findScrollContainer();
313
+ const _LazyLoadHandler$find2 = LazyLoadHandler.findScrollContainer(),
314
+ container = _LazyLoadHandler$find2.container,
315
+ isScrollable = _LazyLoadHandler$find2.isScrollable;
315
316
  if (container && isScrollable) {
316
317
  const currentScrollTop = container.scrollTop;
317
318
  const immediateScrollTarget = currentScrollTop + 20; // Small immediate scroll for feedback
@@ -383,9 +384,8 @@ let LazyLoadHandler = /*#__PURE__*/function () {
383
384
  if (!targetElement) {
384
385
  return;
385
386
  }
386
- const {
387
- container
388
- } = LazyLoadHandler.findScrollContainer();
387
+ const _LazyLoadHandler$find3 = LazyLoadHandler.findScrollContainer(),
388
+ container = _LazyLoadHandler$find3.container;
389
389
  if (!container) {
390
390
  return;
391
391
  }
@@ -402,7 +402,7 @@ let LazyLoadHandler = /*#__PURE__*/function () {
402
402
  targetRect.left < containerRect.right &&
403
403
  // Target left is before container right
404
404
  targetRect.right > containerRect.left // Target right is after container left
405
- ;
405
+ ;
406
406
  if (isVisible) {
407
407
  LazyLoadHandler.handleImmediateScrollRequest();
408
408
  }
@@ -410,16 +410,15 @@ let LazyLoadHandler = /*#__PURE__*/function () {
410
410
 
411
411
  /**
412
412
  * Main lazy load trigger handler
413
- *
413
+ *
414
414
  * This is the core method that executes when the trigger element becomes visible.
415
415
  * It coordinates the entire lazy loading process:
416
- *
416
+ *
417
417
  * 1. Sets flags to prevent concurrent operations
418
- * 2. Dispatches event to fetch more chat history
419
- * 3. Waits for content to load
420
- * 4. Executes scroll adjustment to maintain user position
421
- *
422
- * Timing: Uses 300ms delay to allow content loading before scroll adjustment
418
+ * 2. Captures scroll state BEFORE content loads (for height-delta anchoring)
419
+ * 3. Dispatches event to fetch more chat history
420
+ *
421
+ * Scroll anchoring is triggered by HISTORY_BATCH_LOADED event (not a blind timeout).
423
422
  */
424
423
  }, {
425
424
  key: "handleLazyLoadTrigger",
@@ -433,138 +432,58 @@ let LazyLoadHandler = /*#__PURE__*/function () {
433
432
  LazyLoadHandler.pendingScrollAction = true; // Block new scroll actions
434
433
  LazyLoadHandler.paused = true; // Pause intersection observer
435
434
 
435
+ // Capture scroll geometry BEFORE new content loads — used for height-delta anchoring
436
+ const _LazyLoadHandler$find4 = LazyLoadHandler.findScrollContainer(),
437
+ container = _LazyLoadHandler$find4.container,
438
+ isScrollable = _LazyLoadHandler$find4.isScrollable;
439
+ if (container && isScrollable) {
440
+ LazyLoadHandler.preLoadScrollHeight = container.scrollHeight;
441
+ LazyLoadHandler.preLoadScrollTop = container.scrollTop;
442
+ }
443
+ LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadTriggerFired, "Lazy load trigger fired — fetching history");
444
+
436
445
  // Dispatch custom event to trigger chat history fetching
437
- // This event is handled by other parts of the chat system
438
446
  dispatchCustomEvent(ChatWidgetEvents.FETCH_PERSISTENT_CHAT_HISTORY);
439
-
440
- // Wait for content to load before performing scroll adjustment
441
- // 200ms provides good balance between responsiveness and content loading
442
- const timeoutId = window.setTimeout(() => {
443
- LazyLoadHandler.retryTimeouts.delete(timeoutId);
444
- LazyLoadHandler.executeReliableScroll();
445
- }, 200); // Reduced from 300ms to 200ms for faster response
446
- LazyLoadHandler.retryTimeouts.add(timeoutId);
447
447
  }
448
448
 
449
449
  /**
450
- * Executes reliable scroll with validation and retry logic
451
- *
452
- * This method implements a robust scroll system that:
453
- * 1. Finds and validates the scroll container
454
- * 2. Calculates target scroll position (current + 35px)
455
- * 3. Sets up scroll state for tracking and retries
456
- * 4. Initiates the scroll attempt process
457
- *
458
- * If no suitable container is found, schedules a retry.
450
+ * Applies height-delta scroll anchoring after new history content is prepended.
451
+ *
452
+ * When content is added above the viewport, the browser keeps scrollTop constant
453
+ * but the content shifts down — making the viewport drift upward.
454
+ * Fix: scrollTop = savedScrollTop + (newScrollHeight - savedScrollHeight)
455
+ * This keeps the user looking at the same content they had before.
459
456
  */
460
457
  }, {
461
- key: "executeReliableScroll",
462
- value: function executeReliableScroll() {
463
- // Guard: Don't execute scroll if no more history is available
464
- if (!LazyLoadHandler.hasMoreHistoryAvailable) {
465
- LazyLoadHandler.finishScrollAction();
466
- return;
467
- }
468
-
469
- // Find container using multiple fallback strategies
470
- const {
471
- container,
472
- isScrollable
473
- } = LazyLoadHandler.findScrollContainer();
458
+ key: "applyScrollAnchor",
459
+ value: function applyScrollAnchor() {
460
+ const _LazyLoadHandler$find5 = LazyLoadHandler.findScrollContainer(),
461
+ container = _LazyLoadHandler$find5.container,
462
+ isScrollable = _LazyLoadHandler$find5.isScrollable;
474
463
  if (!container || !isScrollable) {
475
- LazyLoadHandler.scheduleScrollRetry();
476
- return;
477
- }
478
-
479
- // Calculate scroll positions
480
- const initialScrollTop = container.scrollTop;
481
- const targetScrollTop = initialScrollTop + 35; // 35px down to maintain position
482
-
483
- // Set up scroll state for tracking and retries
484
- LazyLoadHandler.scrollState = {
485
- container,
486
- initialScrollTop,
487
- targetScrollTop,
488
- attemptCount: 0,
489
- maxAttempts: 5 // Allow up to 5 retry attempts
490
- };
491
-
492
- // Begin the scroll attempt process
493
- LazyLoadHandler.attemptScroll();
494
- }
495
-
496
- /**
497
- * Attempts to perform scroll with verification and retry logic
498
- *
499
- * This method implements a sophisticated scroll system:
500
- *
501
- * 1. Uses requestAnimationFrame for smooth execution
502
- * 2. Performs the scroll operation
503
- * 3. Verifies scroll actually occurred (5px tolerance)
504
- * 4. Retries with exponential backoff if failed
505
- * 5. Continues operation after max attempts
506
- *
507
- * The two-frame approach ensures scroll is applied and then verified
508
- * after the browser has had time to process the scroll change.
509
- */
510
- }, {
511
- key: "attemptScroll",
512
- value: function attemptScroll() {
513
- // Guard: Don't attempt scroll if no more history is available
514
- if (!LazyLoadHandler.hasMoreHistoryAvailable) {
515
464
  LazyLoadHandler.finishScrollAction();
516
465
  return;
517
466
  }
518
- if (!LazyLoadHandler.scrollState) {
519
- LazyLoadHandler.finishScrollAction();
520
- return;
467
+ const newScrollHeight = container.scrollHeight;
468
+ const heightDelta = newScrollHeight - LazyLoadHandler.preLoadScrollHeight;
469
+ if (heightDelta > 0) {
470
+ container.scrollTop = LazyLoadHandler.preLoadScrollTop + heightDelta;
521
471
  }
522
-
523
- // Extract current scroll state
524
- const {
525
- container,
526
- targetScrollTop,
527
- attemptCount,
528
- maxAttempts
529
- } = LazyLoadHandler.scrollState;
530
- LazyLoadHandler.scrollState.attemptCount++;
531
-
532
- // Perform scroll using requestAnimationFrame for smooth execution
533
- // Frame 1: Apply the scroll
534
- requestAnimationFrame(() => {
535
- // Double-check history availability before applying scroll
536
- if (!LazyLoadHandler.hasMoreHistoryAvailable) {
537
- LazyLoadHandler.finishScrollAction();
538
- return;
539
- }
540
- if (container) {
541
- container.scrollTop = targetScrollTop;
542
- }
543
-
544
- // Frame 2: Verify scroll occurred after browser has processed the change
545
- requestAnimationFrame(() => {
546
- // Triple-check history availability before verification
547
- if (!LazyLoadHandler.hasMoreHistoryAvailable) {
548
- LazyLoadHandler.finishScrollAction();
549
- return;
550
- }
551
- const actualScrollTop = container ? container.scrollTop : 0;
552
- const scrollSucceeded = Math.abs(actualScrollTop - targetScrollTop) < 5; // 5px tolerance for success
553
-
554
- if (scrollSucceeded) {
555
- LazyLoadHandler.finishScrollAction();
556
- } else if (attemptCount < maxAttempts) {
557
- // Retry with exponential backoff (100ms * attempt number)
558
- const timeoutId = window.setTimeout(() => {
559
- LazyLoadHandler.retryTimeouts.delete(timeoutId);
560
- LazyLoadHandler.attemptScroll();
561
- }, 100 * attemptCount); // Exponential backoff
562
- LazyLoadHandler.retryTimeouts.add(timeoutId);
563
- } else {
564
- LazyLoadHandler.finishScrollAction();
472
+ try {
473
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
474
+ Event: TelemetryEvent.LCWLazyLoadScrollAnchorApplied,
475
+ Description: "Scroll anchor applied after history batch",
476
+ CustomProperties: {
477
+ heightDelta,
478
+ preLoadScrollHeight: LazyLoadHandler.preLoadScrollHeight,
479
+ newScrollHeight,
480
+ newScrollTop: container.scrollTop
565
481
  }
566
482
  });
567
- });
483
+ } catch {
484
+ // Silent fail — don't break scroll anchoring for telemetry issues
485
+ }
486
+ LazyLoadHandler.finishScrollAction();
568
487
  }
569
488
 
570
489
  /**
@@ -578,7 +497,6 @@ let LazyLoadHandler = /*#__PURE__*/function () {
578
497
  key: "finishScrollAction",
579
498
  value: function finishScrollAction() {
580
499
  // Clean up scroll tracking state
581
- LazyLoadHandler.scrollState = null;
582
500
  LazyLoadHandler.pendingScrollAction = false;
583
501
 
584
502
  // Schedule unpause and reset with delay for content stabilization
@@ -590,33 +508,9 @@ let LazyLoadHandler = /*#__PURE__*/function () {
590
508
  LazyLoadHandler.retryTimeouts.add(timeoutId);
591
509
  }
592
510
 
593
- /**
594
- * Schedules retry for failed scroll operations
595
- *
596
- * Used when scroll container is not available or scrollable.
597
- * Provides a longer delay to allow container to become ready.
598
- */
599
- }, {
600
- key: "scheduleScrollRetry",
601
- value: function scheduleScrollRetry() {
602
- // Don't schedule retry if no more history is available
603
- if (!LazyLoadHandler.hasMoreHistoryAvailable) {
604
- LazyLoadHandler.finishScrollAction();
605
- return;
606
- }
607
- const timeoutId = window.setTimeout(() => {
608
- LazyLoadHandler.retryTimeouts.delete(timeoutId);
609
- // Only retry if we're still in a pending scroll action state and have more history
610
- if (LazyLoadHandler.pendingScrollAction && LazyLoadHandler.hasMoreHistoryAvailable) {
611
- LazyLoadHandler.executeReliableScroll();
612
- }
613
- }, 1000); // 1 second delay for container readiness
614
- LazyLoadHandler.retryTimeouts.add(timeoutId);
615
- }
616
-
617
511
  /**
618
512
  * Schedules observer reset for next lazy load cycle
619
- *
513
+ *
620
514
  * After a lazy load operation completes, the observer needs to be reset
621
515
  * to detect the next time the user scrolls to the top.
622
516
  */
@@ -734,7 +628,7 @@ let LazyLoadHandler = /*#__PURE__*/function () {
734
628
  }, {
735
629
  key: "moveScrollDown",
736
630
  value: function moveScrollDown() {
737
- LazyLoadHandler.executeReliableScroll();
631
+ LazyLoadHandler.applyScrollAnchor();
738
632
  }
739
633
 
740
634
  /**
@@ -774,6 +668,9 @@ let LazyLoadHandler = /*#__PURE__*/function () {
774
668
  }, {
775
669
  key: "handleNoMoreHistoryAvailable",
776
670
  value: function handleNoMoreHistoryAvailable() {
671
+ if (!LazyLoadHandler.initialLoadComplete) {
672
+ LazyLoadHandler.initialLoadComplete = true;
673
+ }
777
674
  LazyLoadHandler.setHasMoreHistoryAvailable(false);
778
675
  LazyLoadHandler.paused = true;
779
676
  LazyLoadHandler.pendingScrollAction = false; // Reset this to prevent stuck states
@@ -791,9 +688,6 @@ let LazyLoadHandler = /*#__PURE__*/function () {
791
688
  LazyLoadHandler.observer.disconnect();
792
689
  LazyLoadHandler.observer = null;
793
690
  }
794
-
795
- // Clear scroll state
796
- LazyLoadHandler.scrollState = null;
797
691
  }
798
692
 
799
693
  /**
@@ -815,6 +709,8 @@ let LazyLoadHandler = /*#__PURE__*/function () {
815
709
  LazyLoadHandler.setHasMoreHistoryAvailable(true); // Reset history availability flag
816
710
  LazyLoadHandler.initializationQueue = []; // Clear action queue
817
711
  LazyLoadHandler.resetPending = false; // Clear pending reset flag
712
+ // Note: initialLoadComplete is NOT reset here — it persists across observer cycles.
713
+ // It's only reset on new chat sessions (directReset / PersistentConversationReset).
818
714
 
819
715
  // Reinitialize with faster timing for better responsiveness
820
716
  const timeoutId = window.setTimeout(() => {
@@ -854,8 +750,9 @@ let LazyLoadHandler = /*#__PURE__*/function () {
854
750
  LazyLoadHandler.initialized = false;
855
751
  LazyLoadHandler.paused = false;
856
752
  LazyLoadHandler.pendingScrollAction = false;
857
- LazyLoadHandler.scrollState = null;
858
753
  LazyLoadHandler.isReady = false;
754
+ LazyLoadHandler.preLoadScrollHeight = 0;
755
+ LazyLoadHandler.preLoadScrollTop = 0;
859
756
  LazyLoadHandler.initializationQueue = [];
860
757
  // Note: Don't reset resetPending here as it needs to persist across unmount/mount cycles
861
758
  }
@@ -911,9 +808,13 @@ _defineProperty(LazyLoadHandler, "paused", false);
911
808
  // Temporary disable flag
912
809
  _defineProperty(LazyLoadHandler, "observer", null);
913
810
  // The intersection observer instance
914
- // Scroll operation state
915
- _defineProperty(LazyLoadHandler, "scrollState", null);
916
- // Current scroll operation tracking
811
+ // Scroll anchoring state (height-delta approach)
812
+ _defineProperty(LazyLoadHandler, "preLoadScrollHeight", 0);
813
+ // scrollHeight before content loads
814
+ _defineProperty(LazyLoadHandler, "preLoadScrollTop", 0);
815
+ // scrollTop before content loads
816
+ _defineProperty(LazyLoadHandler, "initialLoadComplete", false);
817
+ // Tracks if the first batch has loaded
917
818
  _defineProperty(LazyLoadHandler, "pendingScrollAction", false);
918
819
  // Prevents concurrent scroll operations (public for event handlers)
919
820
  // Timeout and queue management
@@ -926,6 +827,7 @@ _defineProperty(LazyLoadHandler, "initTimer", createTimer());
926
827
  _defineProperty(LazyLoadHandler, "resetEventListener", BroadcastService.getMessageByEventName(BroadcastEvent.PersistentConversationReset).subscribe(() => {
927
828
  _LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadReset, "LazyLoad reset triggered");
928
829
  _LazyLoadHandler.resetPending = true;
830
+ _LazyLoadHandler.initialLoadComplete = false; // New session — next batch is an initial load
929
831
  _LazyLoadHandler.setHasMoreHistoryAvailable(true); // Reset this immediately so activityMiddleware doesn't block rendering
930
832
  _LazyLoadHandler.unmount(); // Clean up current state immediately
931
833
  }));
@@ -937,7 +839,10 @@ _defineProperty(LazyLoadHandler, "initializationQueue", []);
937
839
  // History availability state
938
840
  _defineProperty(LazyLoadHandler, "hasMoreHistoryAvailable", true);
939
841
  const LazyLoadActivity = props => {
940
- const [hasMoreHistory, setHasMoreHistory] = useState(LazyLoadHandler.hasMoreHistoryAvailable);
842
+ const _useState = useState(LazyLoadHandler.hasMoreHistoryAvailable),
843
+ _useState2 = _slicedToArray(_useState, 2),
844
+ hasMoreHistory = _useState2[0],
845
+ setHasMoreHistory = _useState2[1];
941
846
  useEffect(() => {
942
847
  LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadActivityMounted, "LazyLoadActivity component mounted");
943
848
 
@@ -949,19 +854,11 @@ const LazyLoadActivity = props => {
949
854
  setHasMoreHistory(false);
950
855
  };
951
856
 
952
- // Event listener for HISTORY_LOAD_ERROR - hides banner temporarily without disabling future loads
857
+ // Event listener for HISTORY_LOAD_ERROR dismiss banner on any error
953
858
  const handleHistoryLoadError = () => {
954
- // Temporarily hide the banner by pausing, but keep hasMoreHistory true to allow retry
955
- LazyLoadHandler.paused = true;
956
- LazyLoadHandler.pendingScrollAction = false;
957
-
958
- // Re-enable after a delay to allow retry on next scroll
959
- // Note: This timeout is intentionally not tracked as it's scoped to the component lifecycle
960
- window.setTimeout(() => {
961
- LazyLoadHandler.paused = false;
962
- }, 2000); // 2 second delay before allowing retry
963
-
964
- LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadHistoryError, "History load error - will retry on next scroll");
859
+ LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadHistoryError, `History load error - dismissing banner. initialLoadComplete: ${LazyLoadHandler.initialLoadComplete}`);
860
+ LazyLoadHandler.handleNoMoreHistoryAvailable();
861
+ setHasMoreHistory(false);
965
862
  };
966
863
 
967
864
  // Event listener for PersistentConversationReset to sync React state
@@ -972,6 +869,95 @@ const LazyLoadActivity = props => {
972
869
  setHasMoreHistory(true);
973
870
  };
974
871
 
872
+ // Event listener for HISTORY_BATCH_LOADED — applies scroll anchoring after batch is processed
873
+ const handleBatchLoaded = () => {
874
+ LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadBatchReceived, `Batch received — initialLoadComplete: ${LazyLoadHandler.initialLoadComplete}`);
875
+ if (!LazyLoadHandler.initialLoadComplete) {
876
+ // Initial load: use the same height-delta scroll anchoring as subsequent loads.
877
+ // This keeps the user at their current position while history is prepended above.
878
+ LazyLoadHandler.initialLoadComplete = true;
879
+ LazyLoadHandler.pendingScrollAction = false;
880
+ try {
881
+ const _LazyLoadHandler$find6 = LazyLoadHandler.findScrollContainer(),
882
+ container = _LazyLoadHandler$find6.container;
883
+ if (container) {
884
+ const savedScrollTop = container.scrollTop;
885
+ const savedScrollHeight = container.scrollHeight;
886
+
887
+ // Freeze viewport while React renders new content above
888
+ container.style.overflow = "hidden";
889
+ let framesRemaining = 6;
890
+ const anchorScroll = () => {
891
+ const newScrollHeight = container.scrollHeight;
892
+ const heightDelta = newScrollHeight - savedScrollHeight;
893
+ if (heightDelta > 0) {
894
+ container.scrollTop = savedScrollTop + heightDelta;
895
+ }
896
+ framesRemaining--;
897
+ if (framesRemaining > 0) {
898
+ requestAnimationFrame(anchorScroll);
899
+ } else {
900
+ container.style.overflow = "";
901
+ LazyLoadHandler.paused = false;
902
+ LazyLoadHandler.scheduleReset();
903
+ }
904
+ };
905
+ requestAnimationFrame(anchorScroll);
906
+ } else {
907
+ LazyLoadHandler.paused = false;
908
+ LazyLoadHandler.scheduleReset();
909
+ }
910
+ } catch {
911
+ LazyLoadHandler.paused = false;
912
+ LazyLoadHandler.scheduleReset();
913
+ }
914
+ LazyLoadHandler.logLifecycleEvent(TelemetryEvent.LCWLazyLoadInitialLoadComplete, "Initial history load complete — scroll anchored to current position");
915
+ return;
916
+ }
917
+ // Pagination: apply height-delta scroll anchoring repeatedly across frames.
918
+ //
919
+ // react-scroll-to-bottom uses useEffect + rAF to auto-scroll to bottom when new content
920
+ // arrives. This fires at unpredictable timing relative to our callbacks, so a single
921
+ // scrollTop assignment gets overridden intermittently.
922
+ //
923
+ // Fix: re-apply the correct scrollTop across several animation frames. After a few frames,
924
+ // react-scroll-to-bottom detects the user is NOT at the bottom (sticky=false) and stops
925
+ // auto-scrolling. We also temporarily freeze overflow to prevent visible flicker.
926
+ try {
927
+ const _LazyLoadHandler$find7 = LazyLoadHandler.findScrollContainer(),
928
+ container = _LazyLoadHandler$find7.container;
929
+ if (container) {
930
+ // Re-capture scrollTop — user may have scrolled during the API fetch
931
+ const savedScrollTop = container.scrollTop;
932
+ const savedScrollHeight = LazyLoadHandler.preLoadScrollHeight;
933
+
934
+ // Freeze viewport to prevent visible flicker between competing scroll positions
935
+ container.style.overflow = "hidden";
936
+ let framesRemaining = 6; // ~100ms at 60fps — enough for react-scroll-to-bottom to settle
937
+ const anchorScroll = () => {
938
+ const newScrollHeight = container.scrollHeight;
939
+ const heightDelta = newScrollHeight - savedScrollHeight;
940
+ if (heightDelta > 0) {
941
+ container.scrollTop = savedScrollTop + heightDelta;
942
+ }
943
+ framesRemaining--;
944
+ if (framesRemaining > 0) {
945
+ requestAnimationFrame(anchorScroll);
946
+ } else {
947
+ // All frames applied — restore overflow and finish
948
+ container.style.overflow = "";
949
+ LazyLoadHandler.finishScrollAction();
950
+ }
951
+ };
952
+ requestAnimationFrame(anchorScroll);
953
+ } else {
954
+ LazyLoadHandler.finishScrollAction();
955
+ }
956
+ } catch {
957
+ LazyLoadHandler.finishScrollAction();
958
+ }
959
+ };
960
+
975
961
  // Add secure event listener for no more history signal
976
962
  const eventBus = SecureEventBus.getInstance();
977
963
  const unsubscribeNoMoreHistory = eventBus.subscribe(ChatWidgetEvents.NO_MORE_HISTORY_AVAILABLE, handleNoMoreHistory);
@@ -979,6 +965,9 @@ const LazyLoadActivity = props => {
979
965
  // Add event listener for history load errors
980
966
  const unsubscribeHistoryError = eventBus.subscribe(ChatWidgetEvents.HISTORY_LOAD_ERROR, handleHistoryLoadError);
981
967
 
968
+ // Add event listener for history batch loaded
969
+ const unsubscribeBatchLoaded = eventBus.subscribe(ChatWidgetEvents.HISTORY_BATCH_LOADED, handleBatchLoaded);
970
+
982
971
  // Add event listener for persistent conversation reset
983
972
  const resetSubscription = BroadcastService.getMessageByEventName(BroadcastEvent.PersistentConversationReset).subscribe(handlePersistentConversationReset);
984
973
 
@@ -996,6 +985,7 @@ const LazyLoadActivity = props => {
996
985
  return () => {
997
986
  unsubscribeNoMoreHistory();
998
987
  unsubscribeHistoryError();
988
+ unsubscribeBatchLoaded();
999
989
  resetSubscription.unsubscribe();
1000
990
  };
1001
991
  }
@@ -1033,9 +1023,8 @@ const LazyLoadActivity = props => {
1033
1023
  };
1034
1024
 
1035
1025
  // Find container and attach scroll listener
1036
- const {
1037
- container
1038
- } = LazyLoadHandler.findScrollContainer();
1026
+ const _LazyLoadHandler$find8 = LazyLoadHandler.findScrollContainer(),
1027
+ container = _LazyLoadHandler$find8.container;
1039
1028
  if (container) {
1040
1029
  container.addEventListener("scroll", handleScroll, {
1041
1030
  passive: true
@@ -1049,6 +1038,7 @@ const LazyLoadActivity = props => {
1049
1038
  // Remove event listeners
1050
1039
  unsubscribeNoMoreHistory();
1051
1040
  unsubscribeHistoryError();
1041
+ unsubscribeBatchLoaded();
1052
1042
  resetSubscription.unsubscribe();
1053
1043
  if (container) {
1054
1044
  container.removeEventListener("scroll", handleScroll);
@@ -3,11 +3,9 @@ import { defaultInlineBannerStyle } from "../defaultStyles/defaultInLineBannerSt
3
3
  import { defaultMiddlewareLocalizedTexts } from "../../../../common/defaultProps/defaultMiddlewareLocalizedTexts";
4
4
  import { mergeStyles } from "@fluentui/merge-styles";
5
5
  const LoadInlineBannerActivity = _ref => {
6
- let {
7
- webChatContainerProps,
8
- persistentChatHistory,
9
- id
10
- } = _ref;
6
+ let webChatContainerProps = _ref.webChatContainerProps,
7
+ persistentChatHistory = _ref.persistentChatHistory,
8
+ id = _ref.id;
11
9
  const localizedTexts = useMemo(() => ({
12
10
  ...defaultMiddlewareLocalizedTexts,
13
11
  ...(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.localizedTexts)
@@ -47,7 +47,16 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
47
47
  if ((_card$activity5 = card.activity) !== null && _card$activity5 !== void 0 && (_card$activity5 = _card$activity5.channelData) !== null && _card$activity5 !== void 0 && _card$activity5.clientmessageid && ((_card$nextVisibleActi = card.nextVisibleActivity) === null || _card$nextVisibleActi === void 0 || (_card$nextVisibleActi = _card$nextVisibleActi.channelData) === null || _card$nextVisibleActi === void 0 ? void 0 : _card$nextVisibleActi.clientmessageid) === ((_card$activity6 = card.activity) === null || _card$activity6 === void 0 || (_card$activity6 = _card$activity6.channelData) === null || _card$activity6 === void 0 ? void 0 : _card$activity6.clientmessageid) || (_card$activity7 = card.activity) !== null && _card$activity7 !== void 0 && _card$activity7.messageid && ((_card$nextVisibleActi2 = card.nextVisibleActivity) === null || _card$nextVisibleActi2 === void 0 ? void 0 : _card$nextVisibleActi2.messageid) === ((_card$activity8 = card.activity) === null || _card$activity8 === void 0 ? void 0 : _card$activity8.messageid)) {
48
48
  return () => false;
49
49
  }
50
- card.activity.text = renderMarkdown(card.activity.text);
50
+
51
+ // Render latest text on every pass. We deliberately do NOT cache the pre-render text
52
+ // (removed post-PR #895), because:
53
+ // 1. card.activity.text is no longer mutated (renderedHtml is a local variable), so
54
+ // exponential <br> growth from repeated markdown rendering is not possible.
55
+ // 2. Caching the first-seen text prevents edited system messages (same id, updated
56
+ // text/version) from ever re-rendering with the latest content.
57
+ // renderMarkdown sanitizes the HTML using DOMPurify with allowlist-based configuration
58
+ // See initWebChatComposer.ts for sanitization details
59
+ const renderedHtml = renderMarkdown(card.activity.text);
51
60
  // eslint-disable-next-line react/display-name
52
61
  return () => /*#__PURE__*/React.createElement("div", {
53
62
  key: card.activity.id,
@@ -55,7 +64,7 @@ const handleSystemMessage = (next, args, card, renderMarkdown, systemMessageStyl
55
64
  "aria-hidden": "false",
56
65
  className: Constants.markDownSystemMessageClass,
57
66
  dangerouslySetInnerHTML: {
58
- __html: card.activity.text
67
+ __html: renderedHtml
59
68
  }
60
69
  });
61
70
  };
@@ -75,7 +84,7 @@ export const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps
75
84
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
76
85
  args[_key] = arguments[_key];
77
86
  }
78
- const [card] = args;
87
+ const card = args[0];
79
88
  if (card.activity) {
80
89
  var _card$activity$from;
81
90
  if (((_card$activity$from = card.activity.from) === null || _card$activity$from === void 0 ? void 0 : _card$activity$from.role) === DirectLineSenderRole.Channel) {
@@ -124,7 +133,7 @@ export const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps
124
133
  if (isTagIncluded(card, Constants.conversationDividerTag)) {
125
134
  const conversationDividerLabel = (localizedTexts === null || localizedTexts === void 0 ? void 0 : localizedTexts.CONVERSATION_DIVIDER_ARIA_LABEL) || defaultMiddlewareLocalizedTexts.CONVERSATION_DIVIDER_ARIA_LABEL;
126
135
  // Pass the computed localized text to the divider component
127
- return /*#__PURE__*/React.createElement(ConversationDividerActivity, {
136
+ return () => /*#__PURE__*/React.createElement(ConversationDividerActivity, {
128
137
  dividerActivityAriaLabel: conversationDividerLabel
129
138
  });
130
139
  }
@@ -147,4 +156,10 @@ export const createActivityMiddleware = (renderMarkdown, systemMessageStyleProps
147
156
  }
148
157
  }
149
158
  return next(...args);
159
+ };
160
+
161
+ /** Clear module-level caches. Call on conversation end / chat close. */
162
+ export const resetActivityMiddlewareCache = () => {
163
+ loggedSystemMessages.length = 0;
164
+ lastRenderedAt = 0;
150
165
  };