@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.
- package/lib/cjs/common/Constants.js +1 -0
- package/lib/cjs/common/utils.js +14 -2
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +1 -3
- package/lib/cjs/plugins/createChatTranscript.js +5 -1
- package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
- package/lib/esm/common/Constants.js +1 -0
- package/lib/esm/common/utils.js +11 -1
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +10 -4
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +1 -3
- package/lib/esm/plugins/createChatTranscript.js +5 -1
- package/lib/esm/plugins/newMessageEventHandler.js +2 -2
- package/lib/types/common/Constants.d.ts +1 -0
- package/lib/types/common/facades/FacadeChatSDK.d.ts +1 -1
- package/lib/types/common/telemetry/TelemetryHelper.d.ts +1 -0
- package/lib/types/common/utils.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +1 -0
- 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\"]");
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
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
|
|
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, (
|
|
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
|
|
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, (
|
|
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.
|
|
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;
|
|
@@ -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, " - ", (
|
|
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
|
-
}, " ", (
|
|
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
|
-
|
|
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
|
-
|
|
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 {}
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -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
|
|
27
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
22
28
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
23
29
|
Event: TelemetryEvent.NetworkDisconnected
|
|
24
30
|
});
|
|
25
|
-
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (
|
|
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
|
|
33
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
28
34
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
29
35
|
Event: TelemetryEvent.NetworkReconnected
|
|
30
36
|
});
|
|
31
|
-
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (
|
|
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
|
-
|
|
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;
|
|
@@ -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, " - ",
|
|
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
|
-
}, " ",
|
|
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
|
-
|
|
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
|
-
|
|
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>;
|
|
@@ -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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/omnichannel-chat-widget",
|
|
3
|
-
"version": "1.7.7
|
|
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.
|
|
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",
|