@eshal-bot/chat-widget 0.2.31 → 0.2.32
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/dist/{chat-widget-MarkdownRenderer-ozg8BpuC.esm.js → chat-widget-MarkdownRenderer-Cms5qxxI.esm.js} +1 -1
- package/dist/{chat-widget-index-DGutMRlI.esm.js → chat-widget-index-kV_zpR6R.esm.js} +4 -4
- package/dist/chat-widget.esm.js +1 -1
- package/dist/chat-widget.js +132 -11
- package/dist/chat-widget.min.js +6 -6
- package/dist/chat-widget.umd.js +8 -8
- package/package.json +1 -1
package/dist/chat-widget.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{S as default}from"./chat-widget-index-
|
|
1
|
+
export{S as default}from"./chat-widget-index-kV_zpR6R.esm.js";import"react";import"react-dom/client";import"react/jsx-runtime";import"react-dom";
|
package/dist/chat-widget.js
CHANGED
|
@@ -1177,7 +1177,7 @@
|
|
|
1177
1177
|
function lb(a, b) {
|
|
1178
1178
|
return null == a || "http://www.w3.org/1999/xhtml" === a ? kb(b) : "http://www.w3.org/2000/svg" === a && "foreignObject" === b ? "http://www.w3.org/1999/xhtml" : a;
|
|
1179
1179
|
}
|
|
1180
|
-
var mb,
|
|
1180
|
+
var mb$1,
|
|
1181
1181
|
nb = function (a) {
|
|
1182
1182
|
return "undefined" !== typeof MSApp && MSApp.execUnsafeLocalFunction ? function (b, c, d, e) {
|
|
1183
1183
|
MSApp.execUnsafeLocalFunction(function () {
|
|
@@ -1186,9 +1186,9 @@
|
|
|
1186
1186
|
} : a;
|
|
1187
1187
|
}(function (a, b) {
|
|
1188
1188
|
if ("http://www.w3.org/2000/svg" !== a.namespaceURI || "innerHTML" in a) a.innerHTML = b;else {
|
|
1189
|
-
mb = mb || document.createElement("div");
|
|
1190
|
-
mb.innerHTML = "<svg>" + b.valueOf().toString() + "</svg>";
|
|
1191
|
-
for (b = mb.firstChild; a.firstChild;) a.removeChild(a.firstChild);
|
|
1189
|
+
mb$1 = mb$1 || document.createElement("div");
|
|
1190
|
+
mb$1.innerHTML = "<svg>" + b.valueOf().toString() + "</svg>";
|
|
1191
|
+
for (b = mb$1.firstChild; a.firstChild;) a.removeChild(a.firstChild);
|
|
1192
1192
|
for (; b.firstChild;) a.appendChild(b.firstChild);
|
|
1193
1193
|
}
|
|
1194
1194
|
});
|
|
@@ -12080,11 +12080,43 @@
|
|
|
12080
12080
|
}
|
|
12081
12081
|
return fallbackIsRtl;
|
|
12082
12082
|
}
|
|
12083
|
+
|
|
12084
|
+
// A file the chat will not take is answered with a message from the agent,
|
|
12085
|
+
// as the other channels do, not with a warning chip under the composer. The
|
|
12086
|
+
// same wording and languages as the channels' lines
|
|
12087
|
+
// (backend channels/services/inboundAttachmentRejection.ts); other locales
|
|
12088
|
+
// read English. {max_mb}, {used_mb} and {types} are filled at the call site.
|
|
12089
|
+
const ATTACHMENT_REJECTION_TEXTS = {
|
|
12090
|
+
en: {
|
|
12091
|
+
attachmentLimitReached: "That file is too large. This chat can receive up to {max_mb} MB of files in total.",
|
|
12092
|
+
attachmentLimitReachedUsed: "That file is too large. This chat can receive up to {max_mb} MB of files in total, and {used_mb} MB is already used.",
|
|
12093
|
+
attachmentFileTooLarge: "Sorry, that file is too large. Files must be under {max_mb} MB.",
|
|
12094
|
+
attachmentTypeNotAllowed: "Sorry, we can't accept that type of file. You can send {types}."
|
|
12095
|
+
},
|
|
12096
|
+
ar: {
|
|
12097
|
+
attachmentLimitReached: "حجم الملف كبير جداً. يمكن لهذه المحادثة استقبال ملفات يصل مجموع حجمها إلى {max_mb} ميغابايت.",
|
|
12098
|
+
attachmentLimitReachedUsed: "حجم الملف كبير جداً. يمكن لهذه المحادثة استقبال ملفات يصل مجموع حجمها إلى {max_mb} ميغابايت، وقد تم استخدام {used_mb} ميغابايت.",
|
|
12099
|
+
attachmentFileTooLarge: "عذراً، حجم الملف كبير جداً. يجب أن يكون حجم الملف أقل من {max_mb} ميغابايت.",
|
|
12100
|
+
attachmentTypeNotAllowed: "عذراً، لا يمكننا استقبال هذا النوع من الملفات. يمكنك إرسال: {types}."
|
|
12101
|
+
},
|
|
12102
|
+
zh: {
|
|
12103
|
+
attachmentLimitReached: "文件过大。此聊天最多可接收共 {max_mb} MB 的文件。",
|
|
12104
|
+
attachmentLimitReachedUsed: "文件过大。此聊天最多可接收共 {max_mb} MB 的文件,目前已使用 {used_mb} MB。",
|
|
12105
|
+
attachmentFileTooLarge: "抱歉,文件过大。文件大小必须小于 {max_mb} MB。",
|
|
12106
|
+
attachmentTypeNotAllowed: "抱歉,无法接收此类文件。您可以发送:{types}。"
|
|
12107
|
+
},
|
|
12108
|
+
ja: {
|
|
12109
|
+
attachmentLimitReached: "ファイルが大きすぎます。このチャットで受け取れるファイルは合計 {max_mb} MB までです。",
|
|
12110
|
+
attachmentLimitReachedUsed: "ファイルが大きすぎます。このチャットで受け取れるファイルは合計 {max_mb} MB までで、すでに {used_mb} MB を使用しています。",
|
|
12111
|
+
attachmentFileTooLarge: "申し訳ありませんが、ファイルが大きすぎます。ファイルは {max_mb} MB 未満にしてください。",
|
|
12112
|
+
attachmentTypeNotAllowed: "申し訳ありませんが、この種類のファイルは受け付けていません。送信できるファイル: {types}"
|
|
12113
|
+
}
|
|
12114
|
+
};
|
|
12083
12115
|
function translate(locale, key) {
|
|
12084
12116
|
const normalized = normalizeLocale(locale);
|
|
12085
12117
|
const dict = DICTIONARIES[normalized] || EN;
|
|
12086
12118
|
const onboarding = ONBOARDING_PLACEHOLDERS[normalized];
|
|
12087
|
-
return onboarding?.[key] ?? dict[key] ?? A11Y_LABELS[normalized]?.[key] ?? ONBOARDING_PLACEHOLDERS.en[key] ?? A11Y_LABELS.en[key] ?? EN[key] ?? key;
|
|
12119
|
+
return onboarding?.[key] ?? dict[key] ?? A11Y_LABELS[normalized]?.[key] ?? ATTACHMENT_REJECTION_TEXTS[normalized]?.[key] ?? ONBOARDING_PLACEHOLDERS.en[key] ?? A11Y_LABELS.en[key] ?? ATTACHMENT_REJECTION_TEXTS.en[key] ?? EN[key] ?? key;
|
|
12088
12120
|
}
|
|
12089
12121
|
function createTranslator(locale) {
|
|
12090
12122
|
const normalized = normalizeLocale(locale);
|
|
@@ -18840,6 +18872,54 @@
|
|
|
18840
18872
|
});
|
|
18841
18873
|
};
|
|
18842
18874
|
|
|
18875
|
+
// A file the chat will not take (over the conversation's upload limit, over
|
|
18876
|
+
// the per-file cap, or a type it does not accept) is answered with a message
|
|
18877
|
+
// from the agent, as the other channels do, instead of a warning chip under
|
|
18878
|
+
// the composer.
|
|
18879
|
+
|
|
18880
|
+
/** The rejections answered with a message; anything else (a network failure) keeps its chip so it can be retried. */
|
|
18881
|
+
const MESSAGE_REJECTION_CODES = new Set(["size_exceeded", "file_too_large", "mime_not_allowed"]);
|
|
18882
|
+
|
|
18883
|
+
// The short names a customer knows, for "You can send PDF, JPG, PNG".
|
|
18884
|
+
const TYPE_LABELS = [["application/pdf", "PDF"], ["image/jpeg", "JPG"], ["image/png", "PNG"], ["image/gif", "GIF"], ["image/webp", "WEBP"], ["application/msword", "DOC"], ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", "DOCX"], ["application/vnd.ms-excel", "XLS"], ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "XLSX"], ["text/csv", "CSV"], ["text/plain", "TXT"]];
|
|
18885
|
+
function allowedTypesLabel(allowedMimes) {
|
|
18886
|
+
const allowed = new Set((allowedMimes || []).map(m => String(m).toLowerCase()));
|
|
18887
|
+
const labels = TYPE_LABELS.filter(([mime]) => allowed.has(mime)).map(([, label]) => label);
|
|
18888
|
+
return labels.join(", ");
|
|
18889
|
+
}
|
|
18890
|
+
const fill = (template, vars) => template.replace(/\{(\w+)\}/g, (_m, k) => vars[k] ?? "");
|
|
18891
|
+
const mb = bytes => {
|
|
18892
|
+
const v = Math.max(0, Number(bytes) || 0) / (1024 * 1024);
|
|
18893
|
+
return v >= 10 ? String(Math.round(v)) : String(Math.round(v * 10) / 10);
|
|
18894
|
+
};
|
|
18895
|
+
|
|
18896
|
+
/**
|
|
18897
|
+
* The agent's reply to a rejected file, in the widget's language.
|
|
18898
|
+
* `rejection`: { code, usedBytes } from useFileUpload; `config`: the upload
|
|
18899
|
+
* policy (fileUploadMaxSizeMB, fileUploadMaxFileMB, fileUploadAllowedMimes).
|
|
18900
|
+
*/
|
|
18901
|
+
function attachmentRejectionText(t, rejection, config = {}) {
|
|
18902
|
+
const maxMb = String(config.fileUploadMaxSizeMB ?? "");
|
|
18903
|
+
if (rejection.code === "mime_not_allowed") {
|
|
18904
|
+
const types = allowedTypesLabel(config.fileUploadAllowedMimes);
|
|
18905
|
+
return fill(t("attachmentTypeNotAllowed"), {
|
|
18906
|
+
types: types || "PDF"
|
|
18907
|
+
});
|
|
18908
|
+
}
|
|
18909
|
+
if (rejection.code === "file_too_large") {
|
|
18910
|
+
return fill(t("attachmentFileTooLarge"), {
|
|
18911
|
+
max_mb: String(config.fileUploadMaxFileMB ?? maxMb)
|
|
18912
|
+
});
|
|
18913
|
+
}
|
|
18914
|
+
const used = Number(rejection.usedBytes) || 0;
|
|
18915
|
+
return used > 0 ? fill(t("attachmentLimitReachedUsed"), {
|
|
18916
|
+
max_mb: maxMb,
|
|
18917
|
+
used_mb: mb(used)
|
|
18918
|
+
}) : fill(t("attachmentLimitReached"), {
|
|
18919
|
+
max_mb: maxMb
|
|
18920
|
+
});
|
|
18921
|
+
}
|
|
18922
|
+
|
|
18843
18923
|
/**
|
|
18844
18924
|
* useFileUpload - attachment upload flow for the production widget.
|
|
18845
18925
|
*
|
|
@@ -18875,7 +18955,11 @@
|
|
|
18875
18955
|
case "size_exceeded":
|
|
18876
18956
|
case "mime_not_allowed":
|
|
18877
18957
|
case "storage_unavailable":
|
|
18958
|
+
case "file_too_large":
|
|
18878
18959
|
return code;
|
|
18960
|
+
// The server's name for "over this conversation's upload limit".
|
|
18961
|
+
case "session_exceeded":
|
|
18962
|
+
return "size_exceeded";
|
|
18879
18963
|
default:
|
|
18880
18964
|
return "unknown";
|
|
18881
18965
|
}
|
|
@@ -19053,7 +19137,11 @@
|
|
|
19053
19137
|
config,
|
|
19054
19138
|
apiEndpoint,
|
|
19055
19139
|
authHeader,
|
|
19056
|
-
onError
|
|
19140
|
+
onError,
|
|
19141
|
+
// Called instead of showing an error chip when the chat will not take the
|
|
19142
|
+
// file (MESSAGE_REJECTION_CODES): { code, filename, size, usedBytes }. The
|
|
19143
|
+
// widget answers with a message from the agent, as the other channels do.
|
|
19144
|
+
onRejected
|
|
19057
19145
|
}) {
|
|
19058
19146
|
const [attachments, setAttachments] = reactExports.useState([]);
|
|
19059
19147
|
const inflightRef = reactExports.useRef(new Map());
|
|
@@ -19087,6 +19175,19 @@
|
|
|
19087
19175
|
} : a));
|
|
19088
19176
|
}, []);
|
|
19089
19177
|
const errorPatch = reactExports.useCallback((id, code, message) => {
|
|
19178
|
+
// The server refused the file for the conversation's policy: no chip,
|
|
19179
|
+
// the agent says so instead.
|
|
19180
|
+
if (onRejected && MESSAGE_REJECTION_CODES.has(code)) {
|
|
19181
|
+
const target = attachmentsRef.current.find(a => a.id === id);
|
|
19182
|
+
setAttachments(prev => prev.filter(a => a.id !== id));
|
|
19183
|
+
onRejected({
|
|
19184
|
+
code,
|
|
19185
|
+
filename: target?.filename,
|
|
19186
|
+
size: target?.size,
|
|
19187
|
+
usedBytes: Math.max(0, sessionBytesRef.current.bytes)
|
|
19188
|
+
});
|
|
19189
|
+
return;
|
|
19190
|
+
}
|
|
19090
19191
|
const patch = {
|
|
19091
19192
|
status: "error",
|
|
19092
19193
|
error: {
|
|
@@ -19103,7 +19204,7 @@
|
|
|
19103
19204
|
if (target && onError) onError(target);
|
|
19104
19205
|
return patched;
|
|
19105
19206
|
});
|
|
19106
|
-
}, [onError]);
|
|
19207
|
+
}, [onError, onRejected]);
|
|
19107
19208
|
const validateFile = reactExports.useCallback((file, currentCount) => {
|
|
19108
19209
|
if (!config?.fileUploadEnabled) {
|
|
19109
19210
|
return {
|
|
@@ -19343,6 +19444,15 @@
|
|
|
19343
19444
|
const currentCount = attachmentsRef.current.filter(a => a.status !== "error").length;
|
|
19344
19445
|
const check = validateFile(file, currentCount);
|
|
19345
19446
|
const id = nextId();
|
|
19447
|
+
if (!check.ok && onRejected && MESSAGE_REJECTION_CODES.has(check.code)) {
|
|
19448
|
+
onRejected({
|
|
19449
|
+
code: check.code,
|
|
19450
|
+
filename: file.name,
|
|
19451
|
+
size: file.size,
|
|
19452
|
+
usedBytes: Math.max(0, sessionBytesRef.current.bytes)
|
|
19453
|
+
});
|
|
19454
|
+
continue;
|
|
19455
|
+
}
|
|
19346
19456
|
if (!check.ok) {
|
|
19347
19457
|
const rejected = {
|
|
19348
19458
|
id,
|
|
@@ -19381,7 +19491,7 @@
|
|
|
19381
19491
|
sessionBytesRef.current.bytes += file.size;
|
|
19382
19492
|
void doUpload(id, file);
|
|
19383
19493
|
}
|
|
19384
|
-
}, [validateFile, doUpload, nextId, onError]);
|
|
19494
|
+
}, [validateFile, doUpload, nextId, onError, onRejected]);
|
|
19385
19495
|
const removeAttachment = reactExports.useCallback(id => {
|
|
19386
19496
|
const xhr = inflightRef.current.get(id);
|
|
19387
19497
|
if (xhr) {
|
|
@@ -19702,7 +19812,10 @@
|
|
|
19702
19812
|
chatFeatures,
|
|
19703
19813
|
apiEndpoint,
|
|
19704
19814
|
organizationId,
|
|
19705
|
-
conversationId
|
|
19815
|
+
conversationId,
|
|
19816
|
+
// Adds an agent message (useChatState.addAssistantMessage): a file the
|
|
19817
|
+
// chat will not take is answered this way, as on the other channels.
|
|
19818
|
+
onSynthesizeAssistantMessage
|
|
19706
19819
|
}) => {
|
|
19707
19820
|
const t = reactExports.useMemo(() => createTranslator(defaultLanguage), [defaultLanguage]);
|
|
19708
19821
|
const poweredByParts = reactExports.useMemo(() => getPoweredByParts(defaultLanguage), [defaultLanguage]);
|
|
@@ -19736,7 +19849,14 @@
|
|
|
19736
19849
|
conversationId,
|
|
19737
19850
|
config: uploadConfig,
|
|
19738
19851
|
apiEndpoint,
|
|
19739
|
-
authHeader: undefined
|
|
19852
|
+
authHeader: undefined,
|
|
19853
|
+
// Over the upload limit, over the per-file cap or a type the chat does
|
|
19854
|
+
// not take: a message from the agent, not a warning chip.
|
|
19855
|
+
onRejected: onSynthesizeAssistantMessage ? rejection => onSynthesizeAssistantMessage(attachmentRejectionText(t, rejection, {
|
|
19856
|
+
...uploadConfig,
|
|
19857
|
+
// The platform's per-file cap (backend CHAT_ATTACHMENT_PLATFORM_MAX_MB).
|
|
19858
|
+
fileUploadMaxFileMB: chatFeatures?.fileUploadMaxFileMB ?? 25
|
|
19859
|
+
})) : undefined
|
|
19740
19860
|
});
|
|
19741
19861
|
const fileInputRef = reactExports.useRef(null);
|
|
19742
19862
|
|
|
@@ -22500,6 +22620,7 @@
|
|
|
22500
22620
|
})]
|
|
22501
22621
|
})
|
|
22502
22622
|
}), !(onboardingActive && !onboardingCompleted) && /*#__PURE__*/jsxRuntimeExports.jsx(ChatInput, {
|
|
22623
|
+
onSynthesizeAssistantMessage: onSynthesizeAssistantMessage,
|
|
22503
22624
|
onStopGeneration: onStopGeneration,
|
|
22504
22625
|
inputValue: inputValue,
|
|
22505
22626
|
setInputValue: setInputValue,
|
|
@@ -22876,7 +22997,7 @@
|
|
|
22876
22997
|
* value by its own test (that constant sat at 0.1.113 while this package was
|
|
22877
22998
|
* at 0.2.2 precisely because nothing enforced it - EV-2431).
|
|
22878
22999
|
*/
|
|
22879
|
-
const WIDGET_VERSION = '0.2.
|
|
23000
|
+
const WIDGET_VERSION = '0.2.32';
|
|
22880
23001
|
|
|
22881
23002
|
/**
|
|
22882
23003
|
* API utility functions
|