@microsoft/omnichannel-chat-widget 1.7.7-main.bdac0a6 → 1.7.7

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 (26) hide show
  1. package/lib/cjs/common/Constants.js +1 -0
  2. package/lib/cjs/common/utils.js +14 -2
  3. package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
  4. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
  5. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
  6. package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  7. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
  8. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +1 -3
  9. package/lib/cjs/plugins/createChatTranscript.js +5 -1
  10. package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
  11. package/lib/esm/common/Constants.js +1 -0
  12. package/lib/esm/common/utils.js +11 -1
  13. package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
  14. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
  15. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
  16. package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
  17. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
  18. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +1 -3
  19. package/lib/esm/plugins/createChatTranscript.js +5 -1
  20. package/lib/esm/plugins/newMessageEventHandler.js +2 -2
  21. package/lib/types/common/Constants.d.ts +1 -0
  22. package/lib/types/common/facades/FacadeChatSDK.d.ts +1 -1
  23. package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -0
  24. package/lib/types/common/utils.d.ts +1 -0
  25. package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +1 -0
  26. package/package.json +2 -2
@@ -132,6 +132,7 @@ class HtmlClassNames {}
132
132
  exports.HtmlClassNames = HtmlClassNames;
133
133
  _defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
134
134
  _defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
135
+ _defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
135
136
  class HtmlElementSelectors {}
136
137
  exports.HtmlElementSelectors = HtmlElementSelectors;
137
138
  _defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
6
+ exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
7
+ exports.getDeviceType = getDeviceType;
8
+ exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = void 0;
7
9
  var _Constants = require("./Constants");
8
10
  var _TelemetryConstants = require("./telemetry/TelemetryConstants");
9
11
  var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
@@ -479,4 +481,14 @@ const setOcUserAgent = chatSDK => {
479
481
  }
480
482
  }
481
483
  };
482
- exports.setOcUserAgent = setOcUserAgent;
484
+ exports.setOcUserAgent = setOcUserAgent;
485
+ function getDeviceType() {
486
+ const userAgent = navigator.userAgent.toLowerCase();
487
+ if (/android/.test(userAgent)) {
488
+ return "android";
489
+ } else if (/iphone|ipad|ipod/.test(userAgent)) {
490
+ return "ios";
491
+ } else {
492
+ return "standard";
493
+ }
494
+ }
@@ -11,6 +11,8 @@ var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontro
11
11
  var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
12
12
  var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
13
13
  var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
14
+ var _createReducer = require("../../../contexts/createReducer");
15
+ var _LiveChatWidgetActionType = require("../../../contexts/common/LiveChatWidgetActionType");
14
16
  const isInternetConnected = async () => {
15
17
  try {
16
18
  const response = await fetch(_Constants.Constants.internetConnectionTestUrl);
@@ -23,18 +25,22 @@ const isInternetConnected = async () => {
23
25
  const createInternetConnectionChangeHandler = async state => {
24
26
  const handler = async () => {
25
27
  const connected = await isInternetConnected();
28
+ const inMemoryState = (0, _createReducer.executeReducer)(state, {
29
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
30
+ payload: null
31
+ });
26
32
  if (!connected) {
27
- var _state$domainStates, _state$domainStates$m;
33
+ var _inMemoryState$domain, _inMemoryState$domain2;
28
34
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.WARN, {
29
35
  Event: _TelemetryConstants.TelemetryEvent.NetworkDisconnected
30
36
  });
31
- _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.InternetConnection, (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$m = _state$domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
37
+ _NotificationHandler.NotificationHandler.notifyError(_NotificationScenarios.NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
32
38
  } else {
33
- var _state$domainStates2, _state$domainStates2$;
39
+ var _inMemoryState$domain3, _inMemoryState$domain4;
34
40
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.WARN, {
35
41
  Event: _TelemetryConstants.TelemetryEvent.NetworkReconnected
36
42
  });
37
- _NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.InternetConnection, (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.middlewareLocalizedTexts) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
43
+ _NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
38
44
  _omnichannelChatComponents.BroadcastService.postMessage({
39
45
  eventName: _TelemetryConstants.BroadcastEvent.NetworkReconnected
40
46
  });
@@ -145,11 +145,6 @@ const PreChatSurveyPaneStateful = props => {
145
145
  }
146
146
  }
147
147
  }
148
- // Move focus to the first button
149
- const firstElement = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
150
- if (firstElement && firstElement[0]) {
151
- firstElement[0].focus();
152
- }
153
148
  _TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
154
149
  Event: _TelemetryConstants.TelemetryEvent.PrechatSurveyLoaded
155
150
  });
@@ -158,6 +153,16 @@ const PreChatSurveyPaneStateful = props => {
158
153
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
159
154
  });
160
155
  }, []);
156
+
157
+ // Set focus to the first element
158
+ (0, _react.useEffect)(() => {
159
+ if (!state.appStates.isMinimized) {
160
+ const firstElement = (0, _utils.findAllFocusableElement)(`#${controlProps.id}`);
161
+ if (firstElement && firstElement[0]) {
162
+ firstElement[0].focus();
163
+ }
164
+ }
165
+ }, [state.appStates.isMinimized]);
161
166
  return /*#__PURE__*/_react.default.createElement(_omnichannelChatComponents.PreChatSurveyPane, {
162
167
  controlProps: controlProps,
163
168
  styleProps: styleProps
@@ -83,7 +83,12 @@ const WebChatContainerStateful = props => {
83
83
  };
84
84
  (0, _react2.useEffect)(() => {
85
85
  var _props$webChatContain, _props$webChatContain2;
86
- (0, _utils.setFocusOnSendBox)();
86
+ if ((0, _utils.getDeviceType)() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
87
+ const chatHistoryElement = document.querySelector(`.${_Constants.HtmlClassNames.webChatHistoryContainer}`);
88
+ if (chatHistoryElement) {
89
+ chatHistoryElement.setAttribute(_Constants.HtmlAttributeNames.ariaLabel, webChatContainerProps.webChatHistoryMobileAccessibilityLabel);
90
+ }
91
+ }
87
92
  dispatch({
88
93
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
89
94
  payload: webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.renderingMiddlewareProps
@@ -164,6 +169,13 @@ const WebChatContainerStateful = props => {
164
169
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
165
170
  });
166
171
  }, []);
172
+
173
+ // Set focus to the sendbox
174
+ (0, _react2.useEffect)(() => {
175
+ if (!state.appStates.isMinimized) {
176
+ (0, _utils.setFocusOnSendBox)();
177
+ }
178
+ }, [state.appStates.isMinimized]);
167
179
  return /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("style", null, `
168
180
  .webchat__stacked-layout__content .ac-pushButton {
169
181
  cursor: pointer;
@@ -60,6 +60,6 @@ const defaultWebChatStyles = {
60
60
  "</3": "💔",
61
61
  "<\\3": "💔"
62
62
  },
63
- uploadMultiple: false
63
+ sendAttachmentOn: "attach"
64
64
  };
65
65
  exports.defaultWebChatStyles = defaultWebChatStyles;
@@ -31,15 +31,28 @@ const DeliveredTimestamp = _ref => {
31
31
  timestamp
32
32
  }
33
33
  } = args;
34
+ const getTimeElement = timestamp => {
35
+ const timeString = (0, _utils.getTimestampHourMinute)(timestamp);
36
+ const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
37
+
38
+ // For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
39
+ // make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
40
+ if (dir === "rtl" && isAmPmFormat) {
41
+ return /*#__PURE__*/_react.default.createElement("span", {
42
+ dir: "ltr"
43
+ }, (0, _utils.getTimestampHourMinute)(timestamp));
44
+ }
45
+ return timeString;
46
+ };
34
47
  return /*#__PURE__*/_react.default.createElement(_react2.Stack, {
35
48
  style: contentStyles,
36
49
  dir: dir
37
50
  }, role === _DirectLineSenderRole.DirectLineSenderRole.Bot && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
38
51
  dir: dir,
39
52
  "aria-hidden": "false"
40
- }, name, " - ", (0, _utils.getTimestampHourMinute)(timestamp))), role === _DirectLineSenderRole.DirectLineSenderRole.User && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
53
+ }, name, " - ", getTimeElement(timestamp))), role === _DirectLineSenderRole.DirectLineSenderRole.User && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", {
41
54
  "aria-hidden": "false",
42
55
  dir: dir
43
- }, " ", (0, _utils.getTimestampHourMinute)(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
56
+ }, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
44
57
  };
45
58
  exports.DeliveredTimestamp = DeliveredTimestamp;
@@ -70,9 +70,6 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
70
70
  }
71
71
  }
72
72
  }
73
-
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
- action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
76
73
  } catch (e) {
77
74
  let errorMessage = "Failed to apply action: ";
78
75
  try {
@@ -89,6 +86,7 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
89
86
  });
90
87
  }
91
88
  }
89
+ action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
92
90
  return action;
93
91
  };
94
92
 
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _utils = require("../common/utils");
8
8
  var _defaultLibraryScripts = _interopRequireDefault(require("../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts"));
9
+ var _dompurify = _interopRequireDefault(require("dompurify"));
9
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
12
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
@@ -674,7 +675,10 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
674
675
  reader.readAsDataURL(blob);
675
676
  });
676
677
  };
677
- let messages = transcriptMessages;
678
+ let messages = transcriptMessages.filter(message => {
679
+ message.content = _dompurify.default.sanitize(message.content);
680
+ return message.content.length > 0;
681
+ });
678
682
  if (renderAttachments) {
679
683
  messages = await Promise.all(transcriptMessages.map(async message => {
680
684
  // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -89,7 +89,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
89
89
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
90
90
  Event: _TelemetryConstants.TelemetryEvent.MessageReceived,
91
91
  Description: "New message received",
92
- Data: payload
92
+ CustomProperties: payload
93
93
  });
94
94
  } else {
95
95
  if (!isHistoryMessageReceivedEventRasied) {
@@ -97,7 +97,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
97
97
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
98
98
  Event: _TelemetryConstants.TelemetryEvent.RehydrateMessageReceived,
99
99
  Description: "History message received",
100
- Data: payload
100
+ CustomProperties: payload
101
101
  });
102
102
  }
103
103
  }
@@ -122,6 +122,7 @@ _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
122
122
  export class HtmlClassNames {}
123
123
  _defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
124
124
  _defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
125
+ _defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
125
126
  export class HtmlElementSelectors {}
126
127
  _defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
127
128
  export class HtmlAttributeNames {}
@@ -440,4 +440,14 @@ export const setOcUserAgent = chatSDK => {
440
440
  console.warn(error);
441
441
  }
442
442
  }
443
- };
443
+ };
444
+ export function getDeviceType() {
445
+ const userAgent = navigator.userAgent.toLowerCase();
446
+ if (/android/.test(userAgent)) {
447
+ return "android";
448
+ } else if (/iphone|ipad|ipod/.test(userAgent)) {
449
+ return "ios";
450
+ } else {
451
+ return "standard";
452
+ }
453
+ }
@@ -5,6 +5,8 @@ import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontr
5
5
  import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
6
6
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
7
7
  import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
8
+ import { executeReducer } from "../../../contexts/createReducer";
9
+ import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
8
10
  const isInternetConnected = async () => {
9
11
  try {
10
12
  const response = await fetch(Constants.internetConnectionTestUrl);
@@ -17,18 +19,22 @@ const isInternetConnected = async () => {
17
19
  export const createInternetConnectionChangeHandler = async state => {
18
20
  const handler = async () => {
19
21
  const connected = await isInternetConnected();
22
+ const inMemoryState = executeReducer(state, {
23
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
24
+ payload: null
25
+ });
20
26
  if (!connected) {
21
- var _state$domainStates, _state$domainStates$m;
27
+ var _inMemoryState$domain, _inMemoryState$domain2;
22
28
  TelemetryHelper.logActionEvent(LogLevel.WARN, {
23
29
  Event: TelemetryEvent.NetworkDisconnected
24
30
  });
25
- NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$m = _state$domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
31
+ NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
26
32
  } else {
27
- var _state$domainStates2, _state$domainStates2$;
33
+ var _inMemoryState$domain3, _inMemoryState$domain4;
28
34
  TelemetryHelper.logActionEvent(LogLevel.WARN, {
29
35
  Event: TelemetryEvent.NetworkReconnected
30
36
  });
31
- NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.middlewareLocalizedTexts) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
37
+ NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
32
38
  BroadcastService.postMessage({
33
39
  eventName: BroadcastEvent.NetworkReconnected
34
40
  });
@@ -136,11 +136,6 @@ export const PreChatSurveyPaneStateful = props => {
136
136
  }
137
137
  }
138
138
  }
139
- // Move focus to the first button
140
- const firstElement = findAllFocusableElement(`#${controlProps.id}`);
141
- if (firstElement && firstElement[0]) {
142
- firstElement[0].focus();
143
- }
144
139
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
145
140
  Event: TelemetryEvent.PrechatSurveyLoaded
146
141
  });
@@ -149,6 +144,16 @@ export const PreChatSurveyPaneStateful = props => {
149
144
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
150
145
  });
151
146
  }, []);
147
+
148
+ // Set focus to the first element
149
+ useEffect(() => {
150
+ if (!state.appStates.isMinimized) {
151
+ const firstElement = findAllFocusableElement(`#${controlProps.id}`);
152
+ if (firstElement && firstElement[0]) {
153
+ firstElement[0].focus();
154
+ }
155
+ }
156
+ }, [state.appStates.isMinimized]);
152
157
  return /*#__PURE__*/React.createElement(PreChatSurveyPane, {
153
158
  controlProps: controlProps,
154
159
  styleProps: styleProps
@@ -3,10 +3,10 @@
3
3
  import { Stack } from "@fluentui/react";
4
4
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
5
5
  import React, { useEffect } from "react";
6
- import { createTimer, setFocusOnSendBox } from "../../common/utils";
6
+ import { createTimer, getDeviceType, setFocusOnSendBox } from "../../common/utils";
7
7
  import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
8
8
  import { Components } from "botframework-webchat";
9
- import { Constants } from "../../common/Constants";
9
+ import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
10
10
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
11
11
  import { NotificationHandler } from "./webchatcontroller/notification/NotificationHandler";
12
12
  import { NotificationScenarios } from "./webchatcontroller/enums/NotificationScenarios";
@@ -75,7 +75,12 @@ export const WebChatContainerStateful = props => {
75
75
  };
76
76
  useEffect(() => {
77
77
  var _props$webChatContain, _props$webChatContain2;
78
- setFocusOnSendBox();
78
+ if (getDeviceType() !== "standard" && (webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.webChatHistoryMobileAccessibilityLabel) !== undefined) {
79
+ const chatHistoryElement = document.querySelector(`.${HtmlClassNames.webChatHistoryContainer}`);
80
+ if (chatHistoryElement) {
81
+ chatHistoryElement.setAttribute(HtmlAttributeNames.ariaLabel, webChatContainerProps.webChatHistoryMobileAccessibilityLabel);
82
+ }
83
+ }
79
84
  dispatch({
80
85
  type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
81
86
  payload: webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : webChatContainerProps.renderingMiddlewareProps
@@ -156,6 +161,13 @@ export const WebChatContainerStateful = props => {
156
161
  ElapsedTimeInMilliseconds: uiTimer.milliSecondsElapsed
157
162
  });
158
163
  }, []);
164
+
165
+ // Set focus to the sendbox
166
+ useEffect(() => {
167
+ if (!state.appStates.isMinimized) {
168
+ setFocusOnSendBox();
169
+ }
170
+ }, [state.appStates.isMinimized]);
159
171
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("style", null, `
160
172
  .webchat__stacked-layout__content .ac-pushButton {
161
173
  cursor: pointer;
@@ -54,5 +54,5 @@ export const defaultWebChatStyles = {
54
54
  "</3": "💔",
55
55
  "<\\3": "💔"
56
56
  },
57
- uploadMultiple: false
57
+ sendAttachmentOn: "attach"
58
58
  };
@@ -25,14 +25,27 @@ export const DeliveredTimestamp = _ref => {
25
25
  timestamp
26
26
  }
27
27
  } = args;
28
+ const getTimeElement = timestamp => {
29
+ const timeString = getTimestampHourMinute(timestamp);
30
+ const isAmPmFormat = timeString.toLowerCase().includes("am") || timeString.toLowerCase().includes("pm");
31
+
32
+ // For clients that use languages that are written right-to-left, but still use AM/PM time format, we need to
33
+ // make sure the "rtl" direction doesn't produce "PM 1:23", but remains "1:23 PM"
34
+ if (dir === "rtl" && isAmPmFormat) {
35
+ return /*#__PURE__*/React.createElement("span", {
36
+ dir: "ltr"
37
+ }, getTimestampHourMinute(timestamp));
38
+ }
39
+ return timeString;
40
+ };
28
41
  return /*#__PURE__*/React.createElement(Stack, {
29
42
  style: contentStyles,
30
43
  dir: dir
31
44
  }, role === DirectLineSenderRole.Bot && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
32
45
  dir: dir,
33
46
  "aria-hidden": "false"
34
- }, name, " - ", getTimestampHourMinute(timestamp))), role === DirectLineSenderRole.User && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
47
+ }, name, " - ", getTimeElement(timestamp))), role === DirectLineSenderRole.User && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
35
48
  "aria-hidden": "false",
36
49
  dir: dir
37
- }, " ", getTimestampHourMinute(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
50
+ }, " ", getTimeElement(timestamp), " - ", ((_state$domainStates$m = state.domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_MESSAGE_DELIVERED) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_MESSAGE_DELIVERED)));
38
51
  };
@@ -64,9 +64,6 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
64
64
  }
65
65
  }
66
66
  }
67
-
68
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
- action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => htmlNode.innerHTML);
70
67
  } catch (e) {
71
68
  let errorMessage = "Failed to apply action: ";
72
69
  try {
@@ -83,6 +80,7 @@ const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
83
80
  });
84
81
  }
85
82
  }
83
+ action = updateIn(action, [Constants.payload, Constants.activity, Constants.text], () => htmlNode.innerHTML);
86
84
  return action;
87
85
  };
88
86
 
@@ -5,6 +5,7 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
5
5
 
6
6
  import { createFileAndDownload } from "../common/utils";
7
7
  import defaultLibraryScripts from "../components/footerstateful/downloadtranscriptstateful/common/defaultLibraryScripts";
8
+ import DOMPurify from "dompurify";
8
9
  class TranscriptHTMLBuilder {
9
10
  // eslint-disable-line @typescript-eslint/no-explicit-any
10
11
 
@@ -669,7 +670,10 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
669
670
  reader.readAsDataURL(blob);
670
671
  });
671
672
  };
672
- let messages = transcriptMessages;
673
+ let messages = transcriptMessages.filter(message => {
674
+ message.content = DOMPurify.sanitize(message.content);
675
+ return message.content.length > 0;
676
+ });
673
677
  if (renderAttachments) {
674
678
  messages = await Promise.all(transcriptMessages.map(async message => {
675
679
  // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -83,7 +83,7 @@ export const createOnNewAdapterActivityHandler = (chatId, userId) => {
83
83
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
84
84
  Event: TelemetryEvent.MessageReceived,
85
85
  Description: "New message received",
86
- Data: payload
86
+ CustomProperties: payload
87
87
  });
88
88
  } else {
89
89
  if (!isHistoryMessageReceivedEventRasied) {
@@ -91,7 +91,7 @@ export const createOnNewAdapterActivityHandler = (chatId, userId) => {
91
91
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
92
92
  Event: TelemetryEvent.RehydrateMessageReceived,
93
93
  Description: "History message received",
94
- Data: payload
94
+ CustomProperties: payload
95
95
  });
96
96
  }
97
97
  }
@@ -104,6 +104,7 @@ export declare class HtmlIdNames {
104
104
  export declare class HtmlClassNames {
105
105
  static readonly webChatBannerCloseButton = "webchat__toast__dismissButton";
106
106
  static readonly webChatBannerExpandButton = "webchat__toaster__expandIcon";
107
+ static readonly webChatHistoryContainer = "webchat__basic-transcript";
107
108
  }
108
109
  export declare class HtmlElementSelectors {
109
110
  static readonly sendBoxSelector = "textarea[data-id=\"webchat-sendbox-input\"]";
@@ -57,7 +57,7 @@ export declare class FacadeChatSDK {
57
57
  getCallingToken(): Promise<string>;
58
58
  getMessages(): Promise<IMessage[] | OmnichannelMessage[] | undefined>;
59
59
  getDataMaskingRules(): Promise<MaskingRules>;
60
- sendMessage(message: ChatSDKMessage): Promise<void>;
60
+ sendMessage(message: ChatSDKMessage): Promise<void | OmnichannelMessage>;
61
61
  onNewMessage(onNewMessageCallback: CallableFunction, optionalParams?: OnNewMessageOptionalParams): Promise<void>;
62
62
  sendTypingEvent(): Promise<void>;
63
63
  onTypingEvent(onTypingEventCallback: CallableFunction): Promise<void>;
@@ -12,6 +12,7 @@ export interface TelemetryEventWrapper {
12
12
  ExceptionDetails?: any;
13
13
  ElapsedTimeInMilliseconds?: number;
14
14
  Data?: any;
15
+ CustomProperties?: any;
15
16
  }
16
17
  export declare class TelemetryHelper {
17
18
  static callId: string;
@@ -46,3 +46,4 @@ export declare const createFileAndDownload: (fileName: string, blobData: string,
46
46
  export declare const formatTemplateString: (templateMessage: string, values: any) => string;
47
47
  export declare const parseLowerCaseString: (property: string | boolean | undefined) => string;
48
48
  export declare const setOcUserAgent: (chatSDK: any) => void;
49
+ export declare function getDeviceType(): string;
@@ -24,4 +24,5 @@ export interface IWebChatContainerStatefulProps {
24
24
  hyperlinkTextOverride?: boolean;
25
25
  adaptiveCardStyles?: IAdaptiveCardStyles;
26
26
  sendBoxTextBox?: ISendBox;
27
+ webChatHistoryMobileAccessibilityLabel?: string;
27
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.7.7-main.bdac0a6",
3
+ "version": "1.7.7",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -78,7 +78,7 @@
78
78
  "dependencies": {
79
79
  "@azure/core-tracing": "^1.2.0",
80
80
  "@microsoft/omnichannel-chat-components": "1.1.8",
81
- "@microsoft/omnichannel-chat-sdk": "^1.10.15",
81
+ "@microsoft/omnichannel-chat-sdk": "^1.10.17",
82
82
  "@opentelemetry/api": "^1.9.0",
83
83
  "abort-controller-es5": "^2.0.1",
84
84
  "dompurify": "^3.2.4",