@microsoft/omnichannel-chat-widget 1.7.6 → 1.7.7-main.262d750
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 +3 -0
- package/lib/cjs/common/facades/FacadeChatSDK.js +62 -19
- package/lib/cjs/common/utils.js +14 -2
- package/lib/cjs/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +4 -3
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +27 -22
- package/lib/cjs/components/livechatwidget/interfaces/ISendBox.js +1 -0
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
- package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +13 -1
- package/lib/cjs/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- package/lib/cjs/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/cjs/plugins/createChatTranscript.js +5 -1
- package/lib/esm/common/Constants.js +3 -0
- package/lib/esm/common/facades/FacadeChatSDK.js +62 -19
- package/lib/esm/common/utils.js +11 -1
- package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js +15 -0
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +4 -3
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +28 -22
- package/lib/esm/components/livechatwidget/interfaces/ISendBox.js +1 -0
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -13
- package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +10 -5
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +15 -3
- package/lib/esm/components/webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps.js +2 -0
- package/lib/esm/components/webchatcontainerstateful/common/defaultStyles/defaultWebChatStyles.js +1 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer.js +3 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +15 -2
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.js +9 -10
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware.js +3 -1
- package/lib/esm/plugins/createChatTranscript.js +5 -1
- package/lib/types/common/Constants.d.ts +3 -0
- package/lib/types/common/facades/FacadeChatSDK.d.ts +2 -0
- package/lib/types/common/utils.d.ts +1 -0
- package/lib/types/components/livechatwidget/common/createMarkdown.d.ts +1 -1
- package/lib/types/components/livechatwidget/interfaces/ISendBox.d.ts +12 -0
- package/lib/types/components/webchatcontainerstateful/interfaces/IWebChatContainerStatefulProps.d.ts +5 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware.d.ts +1 -1
- package/package.json +2 -2
|
@@ -22,8 +22,9 @@ const convertTextToHtmlNode = text => {
|
|
|
22
22
|
if (!text) return "";
|
|
23
23
|
const element = document.createElement(_Constants.HtmlAttributeNames.div);
|
|
24
24
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
text = _dompurify.default.sanitize(text, {
|
|
26
|
+
ADD_ATTR: ["target"]
|
|
27
|
+
});
|
|
27
28
|
element.innerHTML = text;
|
|
28
29
|
} catch (e) {
|
|
29
30
|
const errorMessage = `Failed to purify and set innertHTML with text: ${text}`;
|
|
@@ -39,7 +40,7 @@ const convertTextToHtmlNode = text => {
|
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
-
const processHTMLText = (action, text) => {
|
|
43
|
+
const processHTMLText = (action, text, honorsTargetInHTMLLinks) => {
|
|
43
44
|
const htmlNode = convertTextToHtmlNode(text);
|
|
44
45
|
const aNodes = htmlNode.getElementsByTagName(_Constants.HtmlAttributeNames.aTagName);
|
|
45
46
|
if ((aNodes === null || aNodes === void 0 ? void 0 : aNodes.length) > 0) {
|
|
@@ -52,8 +53,8 @@ const processHTMLText = (action, text) => {
|
|
|
52
53
|
continue;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
// Add target to 'a' node if target is missing or
|
|
56
|
-
if (!aNode.target ||
|
|
56
|
+
// Add target to 'a' node if target is missing or if honorsTargetInHTMLLinks is false
|
|
57
|
+
if (!aNode.target || !honorsTargetInHTMLLinks) {
|
|
57
58
|
aNode.target = _Constants.Constants.blank;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -69,9 +70,6 @@ const processHTMLText = (action, text) => {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
-
action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
|
|
75
73
|
} catch (e) {
|
|
76
74
|
let errorMessage = "Failed to apply action: ";
|
|
77
75
|
try {
|
|
@@ -88,11 +86,12 @@ const processHTMLText = (action, text) => {
|
|
|
88
86
|
});
|
|
89
87
|
}
|
|
90
88
|
}
|
|
89
|
+
action = (0, _simpleUpdateIn.default)(action, [_Constants.Constants.payload, _Constants.Constants.activity, _Constants.Constants.text], () => htmlNode.innerHTML);
|
|
91
90
|
return action;
|
|
92
91
|
};
|
|
93
92
|
|
|
94
93
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
|
95
|
-
const htmlTextMiddleware = _ref => {
|
|
94
|
+
const htmlTextMiddleware = honorsTargetInHTMLLinks => _ref => {
|
|
96
95
|
let {
|
|
97
96
|
dispatch
|
|
98
97
|
} = _ref;
|
|
@@ -102,7 +101,7 @@ const htmlTextMiddleware = _ref => {
|
|
|
102
101
|
var _action$payload, _action$payload$activ;
|
|
103
102
|
const text = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : (_action$payload$activ = _action$payload.activity) === null || _action$payload$activ === void 0 ? void 0 : _action$payload$activ.text;
|
|
104
103
|
if (text) {
|
|
105
|
-
action = processHTMLText(action, text);
|
|
104
|
+
action = processHTMLText(action, text, honorsTargetInHTMLLinks ?? false);
|
|
106
105
|
}
|
|
107
106
|
} catch (e) {
|
|
108
107
|
let errorMessage = "Failed to validate action.";
|
|
@@ -26,7 +26,9 @@ const sanitizationMiddleware = _ref => {
|
|
|
26
26
|
var _action$payload;
|
|
27
27
|
let text = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.text;
|
|
28
28
|
if (text) {
|
|
29
|
-
text = _dompurify.default.sanitize(text
|
|
29
|
+
text = _dompurify.default.sanitize(text, {
|
|
30
|
+
ADD_ATTR: ["target"]
|
|
31
|
+
}) ?? " ";
|
|
30
32
|
}
|
|
31
33
|
} catch (e) {
|
|
32
34
|
const copyDataForTelemetry = {
|
|
@@ -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
|
|
@@ -92,6 +92,8 @@ _defineProperty(Constants, "Zero", "zero");
|
|
|
92
92
|
_defineProperty(Constants, "Title", "title");
|
|
93
93
|
_defineProperty(Constants, "Target", "target");
|
|
94
94
|
_defineProperty(Constants, "Blank", "_blank");
|
|
95
|
+
_defineProperty(Constants, "TargetSelf", "_self");
|
|
96
|
+
_defineProperty(Constants, "TargetTop", "_top");
|
|
95
97
|
_defineProperty(Constants, "TargetRelationship", "rel");
|
|
96
98
|
_defineProperty(Constants, "TargetRelationshipAttributes", "noopener noreferrer");
|
|
97
99
|
// Markdown icons
|
|
@@ -120,6 +122,7 @@ _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
|
|
|
120
122
|
export class HtmlClassNames {}
|
|
121
123
|
_defineProperty(HtmlClassNames, "webChatBannerCloseButton", "webchat__toast__dismissButton");
|
|
122
124
|
_defineProperty(HtmlClassNames, "webChatBannerExpandButton", "webchat__toaster__expandIcon");
|
|
125
|
+
_defineProperty(HtmlClassNames, "webChatHistoryContainer", "webchat__basic-transcript");
|
|
123
126
|
export class HtmlElementSelectors {}
|
|
124
127
|
_defineProperty(HtmlElementSelectors, "sendBoxSelector", "textarea[data-id=\"webchat-sendbox-input\"]");
|
|
125
128
|
export class HtmlAttributeNames {}
|
|
@@ -58,32 +58,75 @@ export class FacadeChatSDK {
|
|
|
58
58
|
|
|
59
59
|
// compare expiration time with current time
|
|
60
60
|
if (now > this.expiration) {
|
|
61
|
-
console.
|
|
61
|
+
console.error("Token is expired", now, this.expiration, now > this.expiration);
|
|
62
62
|
return true;
|
|
63
63
|
}
|
|
64
64
|
return false;
|
|
65
65
|
}
|
|
66
|
+
enforceBase64Encoding(payload) {
|
|
67
|
+
//base64url when present, switches the "-" and "_" characters with "+" and "/"
|
|
68
|
+
const base64Payload = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
69
|
+
// since base64 encoding requires padding, we need to add padding to the payload
|
|
70
|
+
return base64Payload.padEnd(base64Payload.length + (4 - base64Payload.length % 4) % 4, "=");
|
|
71
|
+
}
|
|
72
|
+
extractExpFromToken(token) {
|
|
73
|
+
const tokenParts = token.split(".");
|
|
74
|
+
const last3digits = token.slice(-3);
|
|
75
|
+
|
|
76
|
+
// token must have 3 parts as JWT format
|
|
77
|
+
if (tokenParts.length !== 3) {
|
|
78
|
+
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
79
|
+
Event: TelemetryEvent.NewTokenFailed,
|
|
80
|
+
Description: "Invalid token format",
|
|
81
|
+
ExceptionDetails: {
|
|
82
|
+
message: "Invalid token format, must be in JWT format",
|
|
83
|
+
token: last3digits
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
throw new Error("Invalid token format, must be in JWT format");
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const payload = this.enforceBase64Encoding(tokenParts[1]);
|
|
90
|
+
// decode payload
|
|
91
|
+
const decodedPayload = atob(payload);
|
|
92
|
+
const jsonPayload = JSON.parse(decodedPayload);
|
|
93
|
+
// check if exp is present in payload
|
|
94
|
+
if (jsonPayload) {
|
|
95
|
+
if (jsonPayload.exp) {
|
|
96
|
+
return jsonPayload.exp;
|
|
97
|
+
}
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
101
|
+
Event: TelemetryEvent.NewTokenFailed,
|
|
102
|
+
Description: "Invalid token payload",
|
|
103
|
+
ExceptionDetails: {
|
|
104
|
+
message: "Token payload is not valid JSON",
|
|
105
|
+
token: last3digits
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
throw new Error("Invalid token payload, payload is not valid JSON");
|
|
109
|
+
} catch (e) {
|
|
110
|
+
console.error("Failed to decode token", e);
|
|
111
|
+
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
112
|
+
Event: TelemetryEvent.NewTokenFailed,
|
|
113
|
+
Description: "Failed to decode token",
|
|
114
|
+
ExceptionDetails: {
|
|
115
|
+
message: "Failed to decode token",
|
|
116
|
+
token: last3digits
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
throw new Error("Failed to decode token");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
66
122
|
async setToken(token) {
|
|
67
123
|
// token must be not null, and must be new
|
|
68
124
|
if (!isNullOrEmptyString(token) && token !== this.token) {
|
|
69
|
-
|
|
125
|
+
const last3digits = token.slice(-3);
|
|
70
126
|
const instant = Math.floor(Date.now() / 1000);
|
|
71
127
|
this.token = token;
|
|
72
|
-
// decompose token
|
|
73
|
-
const tokenParts = (_this$token = this.token) === null || _this$token === void 0 ? void 0 : _this$token.split(".");
|
|
74
|
-
if (!tokenParts || tokenParts.length <= 1) {
|
|
75
|
-
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
76
|
-
Event: TelemetryEvent.NewTokenFailed,
|
|
77
|
-
Description: "Invalid token format",
|
|
78
|
-
ExceptionDetails: "Token must be in JWT format"
|
|
79
|
-
});
|
|
80
|
-
throw new Error("Invalid token format, must be in JWT format");
|
|
81
|
-
}
|
|
82
|
-
// decode token
|
|
83
|
-
const tokenDecoded = JSON.parse(atob(tokenParts[1]));
|
|
84
128
|
// calculate expiration time
|
|
85
|
-
this.expiration = this.convertExpiration(
|
|
86
|
-
|
|
129
|
+
this.expiration = this.convertExpiration(this.extractExpFromToken(token) || 0);
|
|
87
130
|
// this is a control , in case the getAuthToken function returns same token
|
|
88
131
|
if (this.expiration > 0 && this.expiration < instant) {
|
|
89
132
|
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
@@ -91,10 +134,11 @@ export class FacadeChatSDK {
|
|
|
91
134
|
Description: "New token is already expired",
|
|
92
135
|
ExceptionDetails: {
|
|
93
136
|
"Instant": instant,
|
|
94
|
-
"Expiration": this.expiration
|
|
137
|
+
"Expiration": this.expiration,
|
|
138
|
+
"Token": last3digits
|
|
95
139
|
}
|
|
96
140
|
});
|
|
97
|
-
throw new Error(
|
|
141
|
+
throw new Error(`New token is already expired, with epoch time ${this.expiration} , last 3 digits of token: ${last3digits}`);
|
|
98
142
|
}
|
|
99
143
|
}
|
|
100
144
|
}
|
|
@@ -158,7 +202,6 @@ export class FacadeChatSDK {
|
|
|
158
202
|
};
|
|
159
203
|
} else {
|
|
160
204
|
var _ring$error, _ring$error2;
|
|
161
|
-
console.error("Failed to get token", ring);
|
|
162
205
|
TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
|
|
163
206
|
Event: TelemetryEvent.NewTokenFailed,
|
|
164
207
|
Description: (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
|
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
|
+
}
|
package/lib/esm/components/footerstateful/downloadtranscriptstateful/DownloadTranscriptStateful.js
CHANGED
|
@@ -8,6 +8,8 @@ import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcon
|
|
|
8
8
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
9
9
|
import createChatTranscript from "../../../plugins/createChatTranscript";
|
|
10
10
|
import { executeReducer } from "../../../contexts/createReducer";
|
|
11
|
+
import { uuidv4 } from "@microsoft/omnichannel-chat-sdk";
|
|
12
|
+
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
11
13
|
const processDisplayName = displayName => {
|
|
12
14
|
// if displayname matches "teamsvisitor:<some alphanumeric string>", we replace it with "Customer"
|
|
13
15
|
const displayNameRegex = ".+:.+";
|
|
@@ -161,11 +163,24 @@ export const downloadTranscript = async (facadeChatSDK, downloadTranscriptProps,
|
|
|
161
163
|
// Need to keep existing live chat context for scenarios when transcript is downloaded after endchat
|
|
162
164
|
let liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.liveChatContext;
|
|
163
165
|
if (!liveChatContext) {
|
|
166
|
+
var _inMemoryState$appSta;
|
|
164
167
|
const inMemoryState = executeReducer(state, {
|
|
165
168
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
166
169
|
payload: null
|
|
167
170
|
});
|
|
168
171
|
liveChatContext = inMemoryState.domainStates.liveChatContext;
|
|
172
|
+
if ((inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.conversationState) !== ConversationState.Active && !liveChatContext) {
|
|
173
|
+
var _state$domainStates2;
|
|
174
|
+
const chatToken = (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.chatToken) || inMemoryState.domainStates.chatToken;
|
|
175
|
+
if (chatToken && Object.keys(chatToken).length > 0) {
|
|
176
|
+
liveChatContext = {
|
|
177
|
+
chatToken: chatToken,
|
|
178
|
+
requestId: chatToken.requestId || uuidv4()
|
|
179
|
+
};
|
|
180
|
+
} else {
|
|
181
|
+
liveChatContext = await (facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.getCurrentLiveChatContext());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
169
184
|
}
|
|
170
185
|
let data = await (facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.getLiveChatTranscript({
|
|
171
186
|
liveChatContext
|
|
@@ -5,7 +5,7 @@ import { defaultMarkdownLocalizedTexts } from "../../webchatcontainerstateful/co
|
|
|
5
5
|
import { addSlackMarkdownIt } from "./helpers/markdownHelper";
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
-
export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
|
|
8
|
+
export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab) => {
|
|
9
9
|
let markdown;
|
|
10
10
|
if (!disableMarkdownMessageFormatting) {
|
|
11
11
|
markdown = new MarkdownIt(Constants.Default, {
|
|
@@ -39,10 +39,11 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
|
|
|
39
39
|
const targetAttrIndex = tokens[idx].attrIndex(Constants.Target);
|
|
40
40
|
// Put a transparent pixel instead of the "open in new window" icon, so developers can easily modify the icon in CSS.
|
|
41
41
|
const TRANSPARENT_GIF = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
42
|
+
const targetValue = opensMarkdownLinksInSameTab ? Constants.TargetTop : Constants.Blank;
|
|
42
43
|
if (~targetAttrIndex) {
|
|
43
|
-
tokens[idx].attrs[targetAttrIndex][1] =
|
|
44
|
+
tokens[idx].attrs[targetAttrIndex][1] = targetValue;
|
|
44
45
|
} else {
|
|
45
|
-
tokens[idx].attrPush([Constants.Target,
|
|
46
|
+
tokens[idx].attrPush([Constants.Target, targetValue]);
|
|
46
47
|
}
|
|
47
48
|
const relAttrIndex = tokens[idx].attrIndex(Constants.TargetRelationship);
|
|
48
49
|
if (~relAttrIndex) {
|
|
@@ -31,10 +31,11 @@ import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroll
|
|
|
31
31
|
import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
|
|
32
32
|
import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
|
|
33
33
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
34
|
+
import { Constants } from "../../../common/Constants";
|
|
34
35
|
|
|
35
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
37
|
export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
37
|
-
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _state$domainStates$l4, _state$domainStates$l5, _props$
|
|
38
|
+
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _state$domainStates$l4, _state$domainStates$l5, _props$webChatContain11, _props$webChatContain12, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain13, _props$webChatContain14, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain15, _props$webChatContain16, _defaultWebChatContai, _props$webChatContain17, _props$webChatContain18, _props$webChatContain19, _props$webChatContain20, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain21, _props$webChatContain22, _defaultWebChatContai2, _props$webChatContain23, _props$webChatContain24, _defaultWebChatContai3, _props$webChatContain25, _props$webChatContain26;
|
|
38
39
|
// Add a hook to make all links open a new window
|
|
39
40
|
postDomPurifyActivities();
|
|
40
41
|
const localizedTexts = {
|
|
@@ -44,12 +45,14 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
44
45
|
const hyperlinkTextOverride = ((_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hyperlinkTextOverride) ?? defaultWebChatContainerStatefulProps.hyperlinkTextOverride;
|
|
45
46
|
const disableNewLineMarkdownSupport = ((_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.disableNewLineMarkdownSupport) ?? defaultWebChatContainerStatefulProps.disableNewLineMarkdownSupport;
|
|
46
47
|
const disableMarkdownMessageFormatting = ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.disableMarkdownMessageFormatting) ?? defaultWebChatContainerStatefulProps.disableMarkdownMessageFormatting;
|
|
48
|
+
const opensMarkdownLinksInSameTab = (_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.opensMarkdownLinksInSameTab;
|
|
49
|
+
const honorsTargetInHTMLLinks = (_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.honorsTargetInHTMLLinks;
|
|
47
50
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
48
|
-
const markdown = createMarkdown(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport);
|
|
51
|
+
const markdown = createMarkdown(disableMarkdownMessageFormatting, disableNewLineMarkdownSupport, opensMarkdownLinksInSameTab);
|
|
49
52
|
// Initialize Web Chat's redux store
|
|
50
53
|
let webChatStore = WebChatStoreLoader.store;
|
|
51
54
|
if (!webChatStore) {
|
|
52
|
-
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$
|
|
55
|
+
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
53
56
|
const conversationEndCallback = async () => {
|
|
54
57
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
58
|
const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
|
|
@@ -81,18 +84,18 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
81
84
|
};
|
|
82
85
|
webChatStore = createStore({},
|
|
83
86
|
//initial state
|
|
84
|
-
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
87
|
+
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
85
88
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
-
...(((_props$
|
|
89
|
+
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
87
90
|
WebChatStoreLoader.store = webChatStore;
|
|
88
91
|
}
|
|
89
92
|
const hyperlinkTextOverrideRenderer = new HyperlinkTextOverrideRenderer(hyperlinkTextOverride);
|
|
90
93
|
const markdownRenderers = [hyperlinkTextOverrideRenderer];
|
|
91
94
|
const renderMarkdown = text => {
|
|
92
|
-
var _props$
|
|
93
|
-
if ((_props$
|
|
94
|
-
var _props$
|
|
95
|
-
text = (_props$
|
|
95
|
+
var _props$webChatContain8, _props$webChatContain9;
|
|
96
|
+
if ((_props$webChatContain8 = props.webChatContainerProps) !== null && _props$webChatContain8 !== void 0 && (_props$webChatContain9 = _props$webChatContain8.webChatProps) !== null && _props$webChatContain9 !== void 0 && _props$webChatContain9.renderMarkdown) {
|
|
97
|
+
var _props$webChatContain10;
|
|
98
|
+
text = (_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatProps.renderMarkdown(text);
|
|
96
99
|
} else {
|
|
97
100
|
const render = disableMarkdownMessageFormatting ? markdown.renderInline.bind(markdown) : markdown.render.bind(markdown);
|
|
98
101
|
text = render(text);
|
|
@@ -102,16 +105,19 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
102
105
|
});
|
|
103
106
|
const config = {
|
|
104
107
|
FORBID_TAGS: ["form", "button", "script", "div", "input"],
|
|
105
|
-
FORBID_ATTR: ["action"]
|
|
108
|
+
FORBID_ATTR: ["action"],
|
|
109
|
+
ADD_ATTR: ["target"]
|
|
106
110
|
};
|
|
107
111
|
text = DOMPurify.sanitize(text, config);
|
|
108
112
|
return text;
|
|
109
113
|
};
|
|
110
114
|
function postDomPurifyActivities() {
|
|
111
115
|
DOMPurify.addHook("afterSanitizeAttributes", function (node) {
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
node.setAttribute(
|
|
116
|
+
const target = node.getAttribute(Constants.Target);
|
|
117
|
+
if (target === Constants.TargetSelf) {
|
|
118
|
+
node.setAttribute(Constants.Target, Constants.TargetTop);
|
|
119
|
+
} else if (!target) {
|
|
120
|
+
node.setAttribute(Constants.Target, Constants.Blank);
|
|
115
121
|
}
|
|
116
122
|
});
|
|
117
123
|
}
|
|
@@ -121,18 +127,18 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
121
127
|
dir: state.domainStates.globalDir,
|
|
122
128
|
locale: changeLanguageCodeFormatForWebChat(getLocaleStringFromId((_state$domainStates$l4 = state.domainStates.liveChatConfig) === null || _state$domainStates$l4 === void 0 ? void 0 : (_state$domainStates$l5 = _state$domainStates$l4.ChatWidgetLanguage) === null || _state$domainStates$l5 === void 0 ? void 0 : _state$domainStates$l5.msdyn_localeid)),
|
|
123
129
|
store: webChatStore,
|
|
124
|
-
activityMiddleware: (_props$
|
|
125
|
-
attachmentMiddleware: (_props$
|
|
126
|
-
activityStatusMiddleware: (_props$
|
|
127
|
-
toastMiddleware: (_props$
|
|
130
|
+
activityMiddleware: (_props$webChatContain11 = props.webChatContainerProps) !== null && _props$webChatContain11 !== void 0 && (_props$webChatContain12 = _props$webChatContain11.renderingMiddlewareProps) !== null && _props$webChatContain12 !== void 0 && _props$webChatContain12.disableActivityMiddleware ? undefined : createActivityMiddleware(renderMarkdown, (_state$domainStates$r = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r === void 0 ? void 0 : _state$domainStates$r.systemMessageStyleProps, (_state$domainStates$r2 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r2 === void 0 ? void 0 : _state$domainStates$r2.userMessageStyleProps),
|
|
131
|
+
attachmentMiddleware: (_props$webChatContain13 = props.webChatContainerProps) !== null && _props$webChatContain13 !== void 0 && (_props$webChatContain14 = _props$webChatContain13.renderingMiddlewareProps) !== null && _props$webChatContain14 !== void 0 && _props$webChatContain14.disableAttachmentMiddleware ? undefined : createAttachmentMiddleware(((_state$domainStates$r3 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r3 === void 0 ? void 0 : (_state$domainStates$r4 = _state$domainStates$r3.attachmentProps) === null || _state$domainStates$r4 === void 0 ? void 0 : _state$domainStates$r4.enableInlinePlaying) ?? defaultAttachmentProps.enableInlinePlaying),
|
|
132
|
+
activityStatusMiddleware: (_props$webChatContain15 = props.webChatContainerProps) !== null && _props$webChatContain15 !== void 0 && (_props$webChatContain16 = _props$webChatContain15.renderingMiddlewareProps) !== null && _props$webChatContain16 !== void 0 && _props$webChatContain16.disableActivityStatusMiddleware ? undefined : (_defaultWebChatContai = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai === void 0 ? void 0 : _defaultWebChatContai.activityStatusMiddleware,
|
|
133
|
+
toastMiddleware: (_props$webChatContain17 = props.webChatContainerProps) !== null && _props$webChatContain17 !== void 0 && (_props$webChatContain18 = _props$webChatContain17.renderingMiddlewareProps) !== null && _props$webChatContain18 !== void 0 && _props$webChatContain18.disableToastMiddleware ? undefined : createToastMiddleware(props.notificationPaneProps, endChat),
|
|
128
134
|
renderMarkdown,
|
|
129
|
-
avatarMiddleware: (_props$
|
|
130
|
-
groupActivitiesMiddleware: (_props$
|
|
131
|
-
typingIndicatorMiddleware: (_props$
|
|
135
|
+
avatarMiddleware: (_props$webChatContain19 = props.webChatContainerProps) !== null && _props$webChatContain19 !== void 0 && (_props$webChatContain20 = _props$webChatContain19.renderingMiddlewareProps) !== null && _props$webChatContain20 !== void 0 && _props$webChatContain20.disableAvatarMiddleware ? undefined : createAvatarMiddleware((_state$domainStates$r5 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r5 === void 0 ? void 0 : _state$domainStates$r5.avatarStyleProps, (_state$domainStates$r6 = state.domainStates.renderingMiddlewareProps) === null || _state$domainStates$r6 === void 0 ? void 0 : _state$domainStates$r6.avatarTextStyleProps),
|
|
136
|
+
groupActivitiesMiddleware: (_props$webChatContain21 = props.webChatContainerProps) !== null && _props$webChatContain21 !== void 0 && (_props$webChatContain22 = _props$webChatContain21.renderingMiddlewareProps) !== null && _props$webChatContain22 !== void 0 && _props$webChatContain22.disableGroupActivitiesMiddleware ? undefined : (_defaultWebChatContai2 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai2 === void 0 ? void 0 : _defaultWebChatContai2.groupActivitiesMiddleware,
|
|
137
|
+
typingIndicatorMiddleware: (_props$webChatContain23 = props.webChatContainerProps) !== null && _props$webChatContain23 !== void 0 && (_props$webChatContain24 = _props$webChatContain23.renderingMiddlewareProps) !== null && _props$webChatContain24 !== void 0 && _props$webChatContain24.disableTypingIndicatorMiddleware ? undefined : (_defaultWebChatContai3 = defaultWebChatContainerStatefulProps.webChatProps) === null || _defaultWebChatContai3 === void 0 ? void 0 : _defaultWebChatContai3.typingIndicatorMiddleware,
|
|
132
138
|
onTelemetry: createWebChatTelemetry(),
|
|
133
|
-
cardActionMiddleware: createCardActionMiddleware(((_props$
|
|
139
|
+
cardActionMiddleware: createCardActionMiddleware(((_props$webChatContain25 = props.webChatContainerProps) === null || _props$webChatContain25 === void 0 ? void 0 : _props$webChatContain25.botMagicCode) || undefined),
|
|
134
140
|
sendTypingIndicator: true,
|
|
135
|
-
...((_props$
|
|
141
|
+
...((_props$webChatContain26 = props.webChatContainerProps) === null || _props$webChatContain26 === void 0 ? void 0 : _props$webChatContain26.webChatProps)
|
|
136
142
|
};
|
|
137
143
|
return webChatProps;
|
|
138
144
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -56,7 +56,7 @@ import useChatContextStore from "../../../hooks/useChatContextStore";
|
|
|
56
56
|
import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
|
|
57
57
|
let uiTimer;
|
|
58
58
|
export const LiveChatWidgetStateful = props => {
|
|
59
|
-
var _props$webChatContain, _props$styleProps, _props$controlProps, _props$controlProps3, _state$appStates7, _props$
|
|
59
|
+
var _props$webChatContain, _props$styleProps, _props$webChatContain2, _props$webChatContain3, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain7, _state$appStates14, _props$webChatContain9, _props$webChatContain10, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain11, _props$webChatContain12, _props$webChatContain13, _props$webChatContain14, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
|
|
60
60
|
useEffect(() => {
|
|
61
61
|
uiTimer = createTimer();
|
|
62
62
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -86,6 +86,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
86
86
|
|
|
87
87
|
//Scrollbar styles
|
|
88
88
|
const scrollbarProps = Object.assign({}, defaultScrollBarProps, props === null || props === void 0 ? void 0 : props.scrollBarProps);
|
|
89
|
+
const sendBoxTextArea = props === null || props === void 0 ? void 0 : (_props$webChatContain2 = props.webChatContainerProps) === null || _props$webChatContain2 === void 0 ? void 0 : (_props$webChatContain3 = _props$webChatContain2.sendBoxTextBox) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.textarea;
|
|
89
90
|
|
|
90
91
|
// In case the broadcast channel is already initialized elsewhere; One tab can only hold 1 instance
|
|
91
92
|
if ((props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.skipBroadcastChannelInit) !== true) {
|
|
@@ -605,8 +606,8 @@ export const LiveChatWidgetStateful = props => {
|
|
|
605
606
|
});
|
|
606
607
|
}
|
|
607
608
|
if (state.appStates.conversationState === ConversationState.InActive) {
|
|
608
|
-
var _props$
|
|
609
|
-
if ((props === null || props === void 0 ? void 0 : (_props$
|
|
609
|
+
var _props$webChatContain4, _props$webChatContain5;
|
|
610
|
+
if ((props === null || props === void 0 ? void 0 : (_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : (_props$webChatContain5 = _props$webChatContain4.renderingMiddlewareProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.hideSendboxOnConversationEnd) !== false) {
|
|
610
611
|
setWebChatStyles(styles => {
|
|
611
612
|
return {
|
|
612
613
|
...styles,
|
|
@@ -650,12 +651,12 @@ export const LiveChatWidgetStateful = props => {
|
|
|
650
651
|
}
|
|
651
652
|
}, [state.appStates.unreadMessageCount]);
|
|
652
653
|
useEffect(() => {
|
|
653
|
-
var _props$
|
|
654
|
+
var _props$webChatContain6;
|
|
654
655
|
setWebChatStyles({
|
|
655
656
|
...webChatStyles,
|
|
656
|
-
...((_props$
|
|
657
|
+
...((_props$webChatContain6 = props.webChatContainerProps) === null || _props$webChatContain6 === void 0 ? void 0 : _props$webChatContain6.webChatStyles)
|
|
657
658
|
});
|
|
658
|
-
}, [(_props$
|
|
659
|
+
}, [(_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.webChatStyles]);
|
|
659
660
|
useEffect(() => {
|
|
660
661
|
//Confirmation pane dismissing through OK option, so proceed with end chat
|
|
661
662
|
if (state.domainStates.confirmationState === ConfirmationState.Ok) {
|
|
@@ -754,12 +755,12 @@ export const LiveChatWidgetStateful = props => {
|
|
|
754
755
|
|
|
755
756
|
// if props state gets updates we need to update the renderingMiddlewareProps in the state
|
|
756
757
|
useEffect(() => {
|
|
757
|
-
var _props$
|
|
758
|
+
var _props$webChatContain8;
|
|
758
759
|
dispatch({
|
|
759
760
|
type: LiveChatWidgetActionType.SET_RENDERING_MIDDLEWARE_PROPS,
|
|
760
|
-
payload: (_props$
|
|
761
|
+
payload: (_props$webChatContain8 = props.webChatContainerProps) === null || _props$webChatContain8 === void 0 ? void 0 : _props$webChatContain8.renderingMiddlewareProps
|
|
761
762
|
});
|
|
762
|
-
}, [(_props$
|
|
763
|
+
}, [(_props$webChatContain9 = props.webChatContainerProps) === null || _props$webChatContain9 === void 0 ? void 0 : _props$webChatContain9.renderingMiddlewareProps]);
|
|
763
764
|
useEffect(() => {
|
|
764
765
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
765
766
|
Event: TelemetryEvent.UXLivechatwidgetCompleted,
|
|
@@ -801,7 +802,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
801
802
|
const webChatProps = initWebChatComposer(props, state, dispatch, facadeChatSDK, endChatRelay);
|
|
802
803
|
const downloadTranscriptProps = createDownloadTranscriptProps(props.downloadTranscriptProps, {
|
|
803
804
|
...(defaultWebChatContainerStatefulProps === null || defaultWebChatContainerStatefulProps === void 0 ? void 0 : defaultWebChatContainerStatefulProps.webChatStyles),
|
|
804
|
-
...((_props$
|
|
805
|
+
...((_props$webChatContain10 = props.webChatContainerProps) === null || _props$webChatContain10 === void 0 ? void 0 : _props$webChatContain10.webChatStyles)
|
|
805
806
|
}, props.webChatContainerProps);
|
|
806
807
|
const livechatProps = {
|
|
807
808
|
...props,
|
|
@@ -859,13 +860,16 @@ export const LiveChatWidgetStateful = props => {
|
|
|
859
860
|
height: .75em;
|
|
860
861
|
margin-left: .25em;
|
|
861
862
|
}
|
|
862
|
-
|
|
863
|
+
${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
|
|
864
|
+
textarea.webchat__send-box-text-box__html-text-area {
|
|
865
|
+
min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight};
|
|
866
|
+
}`}
|
|
863
867
|
`), /*#__PURE__*/React.createElement(DraggableChatWidget, chatWidgetDraggableConfig, /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
|
|
864
868
|
userID: userID,
|
|
865
869
|
styleOptions: {
|
|
866
870
|
...webChatStyles,
|
|
867
|
-
bubbleBackground: ((_props$
|
|
868
|
-
bubbleTextColor: ((_props$
|
|
871
|
+
bubbleBackground: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.adaptiveCardStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.background) ?? defaultAdaptiveCardStyles.background,
|
|
872
|
+
bubbleTextColor: ((_props$webChatContain13 = props.webChatContainerProps) === null || _props$webChatContain13 === void 0 ? void 0 : (_props$webChatContain14 = _props$webChatContain13.adaptiveCardStyles) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.color) ?? defaultAdaptiveCardStyles.color
|
|
869
873
|
},
|
|
870
874
|
directLine: directLine
|
|
871
875
|
}), /*#__PURE__*/React.createElement(Stack, {
|
|
@@ -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;
|
|
@@ -9,6 +9,8 @@ export const defaultWebChatContainerStatefulProps = {
|
|
|
9
9
|
containerStyles: defaultWebChatStatefulContainerStyles,
|
|
10
10
|
disableNewLineMarkdownSupport: false,
|
|
11
11
|
disableMarkdownMessageFormatting: false,
|
|
12
|
+
opensMarkdownLinksInSameTab: false,
|
|
13
|
+
honorsTargetInHTMLLinks: false,
|
|
12
14
|
hyperlinkTextOverride: false,
|
|
13
15
|
directLine: new MockAdapter(),
|
|
14
16
|
adaptiveCardStyles: defaultAdaptiveCardStyles
|