@locdo.tech/botiq-chat-sdk 0.7.0 → 0.8.1
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/sdk/index.js +1 -1
- package/dist/sdk/{npm-ClWjnXje.js → npm-BkpJFZG8.js} +414 -234
- package/dist/sdk/react.js +1 -1
- package/dist/sdk/vue.js +1 -1
- package/package.json +2 -2
|
@@ -283,7 +283,7 @@ async function k(e, t, n, r, i) {
|
|
|
283
283
|
};
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
async function
|
|
286
|
+
async function A(e, t, n, r, i, a, o, s) {
|
|
287
287
|
try {
|
|
288
288
|
let c = D.getDefinitions(), l = await fetch(`${e}/widget/chat`, {
|
|
289
289
|
method: "POST",
|
|
@@ -327,16 +327,16 @@ async function ee(e, t, n, r, i, a, o, s) {
|
|
|
327
327
|
};
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
|
-
var
|
|
330
|
+
var j = {
|
|
331
331
|
messages: [],
|
|
332
332
|
hasMore: !1
|
|
333
333
|
};
|
|
334
|
-
function
|
|
334
|
+
function M(e) {
|
|
335
335
|
if (!e || typeof e != "object") return !1;
|
|
336
336
|
let t = e;
|
|
337
337
|
return typeof t.id == "string" && (t.role === "user" || t.role === "assistant") && typeof t.content == "string";
|
|
338
338
|
}
|
|
339
|
-
async function
|
|
339
|
+
async function N(e, t, n, r, i, a) {
|
|
340
340
|
try {
|
|
341
341
|
let o = new URLSearchParams({
|
|
342
342
|
sessionId: n,
|
|
@@ -351,26 +351,112 @@ async function j(e, t, n, r, i, a) {
|
|
|
351
351
|
},
|
|
352
352
|
referrerPolicy: "no-referrer-when-downgrade"
|
|
353
353
|
});
|
|
354
|
-
if (!s.ok) return
|
|
354
|
+
if (!s.ok) return j;
|
|
355
355
|
let c = await s.json();
|
|
356
356
|
return {
|
|
357
|
-
messages: Array.isArray(c.messages) ? c.messages.filter(
|
|
357
|
+
messages: Array.isArray(c.messages) ? c.messages.filter(M) : [],
|
|
358
358
|
hasMore: c.hasMore === !0,
|
|
359
359
|
escalated: c.escalated === !0
|
|
360
360
|
};
|
|
361
361
|
} catch {
|
|
362
|
-
return
|
|
362
|
+
return j;
|
|
363
363
|
}
|
|
364
364
|
}
|
|
365
|
-
function
|
|
366
|
-
return
|
|
365
|
+
function P(e, t, n, r, i) {
|
|
366
|
+
return N(e, t, n, void 0, r, i);
|
|
367
367
|
}
|
|
368
|
-
function
|
|
369
|
-
return
|
|
368
|
+
function ee(e, t, n, r, i, a) {
|
|
369
|
+
return N(e, t, n, r, i, a);
|
|
370
|
+
}
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region src/core/stream.ts
|
|
373
|
+
async function te(e) {
|
|
374
|
+
if (typeof ReadableStream > "u") return A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
|
|
375
|
+
let t = D.getDefinitions(), n = {
|
|
376
|
+
sessionId: e.sessionId,
|
|
377
|
+
message: e.message,
|
|
378
|
+
history: e.history,
|
|
379
|
+
...t.length ? { availableActions: t } : {},
|
|
380
|
+
...e.visitorId ? { visitorId: e.visitorId } : {},
|
|
381
|
+
...e.attachments?.length ? { attachments: e.attachments } : {}
|
|
382
|
+
}, r;
|
|
383
|
+
try {
|
|
384
|
+
r = await fetch(`${e.apiUrl}/widget/chat/stream`, {
|
|
385
|
+
method: "POST",
|
|
386
|
+
headers: {
|
|
387
|
+
"Content-Type": "application/json",
|
|
388
|
+
"X-Api-Key": e.apiKey,
|
|
389
|
+
...e.visitorId ? { "X-Visitor-Id": e.visitorId } : {}
|
|
390
|
+
},
|
|
391
|
+
referrerPolicy: "no-referrer-when-downgrade",
|
|
392
|
+
body: JSON.stringify(n)
|
|
393
|
+
});
|
|
394
|
+
} catch {
|
|
395
|
+
return A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
|
|
396
|
+
}
|
|
397
|
+
if (!r.ok) return r.status === 401 ? {
|
|
398
|
+
reply: e.strings.errorAuth,
|
|
399
|
+
error: !0
|
|
400
|
+
} : r.status === 403 ? {
|
|
401
|
+
reply: e.strings.errorForbidden,
|
|
402
|
+
error: !0
|
|
403
|
+
} : r.status === 429 ? {
|
|
404
|
+
reply: e.strings.errorQuota,
|
|
405
|
+
error: !0
|
|
406
|
+
} : A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
|
|
407
|
+
if (!r.body) return {
|
|
408
|
+
reply: e.strings.errorMessage,
|
|
409
|
+
error: !0
|
|
410
|
+
};
|
|
411
|
+
try {
|
|
412
|
+
return await ne(r.body, e);
|
|
413
|
+
} catch {
|
|
414
|
+
return {
|
|
415
|
+
reply: e.strings.errorMessage,
|
|
416
|
+
error: !0
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function ne(e, t) {
|
|
421
|
+
let n = e.getReader(), r = new TextDecoder(), i = "", a = "", o = null;
|
|
422
|
+
outer: for (;;) {
|
|
423
|
+
let { done: e, value: s } = await n.read();
|
|
424
|
+
if (e) break;
|
|
425
|
+
i += r.decode(s, { stream: !0 });
|
|
426
|
+
let c = i.split("\n");
|
|
427
|
+
i = c.pop() ?? "";
|
|
428
|
+
for (let e of c) {
|
|
429
|
+
if (!e.startsWith("data: ")) continue;
|
|
430
|
+
let n = e.slice(6).trim();
|
|
431
|
+
if (!n) continue;
|
|
432
|
+
let r;
|
|
433
|
+
try {
|
|
434
|
+
r = JSON.parse(n);
|
|
435
|
+
} catch {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (r.type === "token") {
|
|
439
|
+
let e = String(r.delta ?? "");
|
|
440
|
+
e && (a += e, t.onToken(e));
|
|
441
|
+
} else if (r.type === "done") {
|
|
442
|
+
o = r;
|
|
443
|
+
break outer;
|
|
444
|
+
} else if (r.type === "error") return {
|
|
445
|
+
reply: t.strings.errorMessage,
|
|
446
|
+
error: !0
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if (!o) throw Error("SSE stream ended without done event");
|
|
451
|
+
return {
|
|
452
|
+
reply: a || t.strings.errorMessage,
|
|
453
|
+
pageAction: o.pageAction,
|
|
454
|
+
blocks: o.blocks
|
|
455
|
+
};
|
|
370
456
|
}
|
|
371
457
|
//#endregion
|
|
372
458
|
//#region src/core/state.ts
|
|
373
|
-
var
|
|
459
|
+
var F = {
|
|
374
460
|
messages: [],
|
|
375
461
|
isLoading: !1,
|
|
376
462
|
isOpen: !1,
|
|
@@ -383,34 +469,34 @@ var N = {
|
|
|
383
469
|
pendingAttachment: null,
|
|
384
470
|
isUploading: !1,
|
|
385
471
|
uploadError: null
|
|
386
|
-
},
|
|
387
|
-
function
|
|
388
|
-
return
|
|
472
|
+
}, I = /* @__PURE__ */ new Set();
|
|
473
|
+
function L() {
|
|
474
|
+
return F;
|
|
389
475
|
}
|
|
390
|
-
function
|
|
391
|
-
Object.assign(
|
|
476
|
+
function R(e) {
|
|
477
|
+
Object.assign(F, e);
|
|
392
478
|
let t = {
|
|
393
|
-
...
|
|
394
|
-
messages: [...
|
|
395
|
-
conversations: [...
|
|
479
|
+
...F,
|
|
480
|
+
messages: [...F.messages],
|
|
481
|
+
conversations: [...F.conversations]
|
|
396
482
|
};
|
|
397
|
-
|
|
483
|
+
I.forEach((e) => e(t));
|
|
398
484
|
}
|
|
399
485
|
function re(e) {
|
|
400
|
-
return
|
|
486
|
+
return I.add(e), () => I.delete(e);
|
|
401
487
|
}
|
|
402
488
|
//#endregion
|
|
403
489
|
//#region src/core/upload.ts
|
|
404
|
-
var
|
|
490
|
+
var z = new Set([
|
|
405
491
|
"image/jpeg",
|
|
406
492
|
"image/png",
|
|
407
493
|
"image/webp"
|
|
408
|
-
]),
|
|
409
|
-
function oe(e) {
|
|
410
|
-
return L.has(e);
|
|
411
|
-
}
|
|
494
|
+
]), B = 25 * 1024 * 1024, ie = 5 * 1024 * 1024, V = 1600, ae = .85, oe = .65;
|
|
412
495
|
function se(e) {
|
|
413
|
-
return
|
|
496
|
+
return z.has(e);
|
|
497
|
+
}
|
|
498
|
+
function ce(e) {
|
|
499
|
+
return se(e.type) ? e.size > B ? {
|
|
414
500
|
ok: !1,
|
|
415
501
|
error: "Image too large (max 25 MB before compression)."
|
|
416
502
|
} : { ok: !0 } : {
|
|
@@ -418,25 +504,25 @@ function se(e) {
|
|
|
418
504
|
error: "Unsupported image type. Please use JPEG, PNG, or WebP."
|
|
419
505
|
};
|
|
420
506
|
}
|
|
421
|
-
function
|
|
507
|
+
function le(e, t) {
|
|
422
508
|
let n = Math.max(e, t);
|
|
423
|
-
if (n <=
|
|
509
|
+
if (n <= V) return {
|
|
424
510
|
width: e,
|
|
425
511
|
height: t
|
|
426
512
|
};
|
|
427
|
-
let r =
|
|
513
|
+
let r = V / n;
|
|
428
514
|
return {
|
|
429
515
|
width: Math.floor(e * r),
|
|
430
516
|
height: Math.floor(t * r)
|
|
431
517
|
};
|
|
432
518
|
}
|
|
433
|
-
function
|
|
434
|
-
let t =
|
|
519
|
+
function ue(e) {
|
|
520
|
+
let t = ce(e);
|
|
435
521
|
return t.ok ? new Promise((t, n) => {
|
|
436
522
|
let r = new Image(), i = URL.createObjectURL(e);
|
|
437
523
|
r.onload = () => {
|
|
438
524
|
URL.revokeObjectURL(i);
|
|
439
|
-
let { width: a, height: o } =
|
|
525
|
+
let { width: a, height: o } = le(r.naturalWidth, r.naturalHeight), s = document.createElement("canvas");
|
|
440
526
|
s.width = a, s.height = o;
|
|
441
527
|
let c = s.getContext("2d");
|
|
442
528
|
if (!c) {
|
|
@@ -450,7 +536,7 @@ function le(e) {
|
|
|
450
536
|
n(/* @__PURE__ */ Error("Canvas toBlob returned null"));
|
|
451
537
|
return;
|
|
452
538
|
}
|
|
453
|
-
if (e.size <=
|
|
539
|
+
if (e.size <= ie) {
|
|
454
540
|
t({
|
|
455
541
|
blob: e,
|
|
456
542
|
mimeType: l
|
|
@@ -462,7 +548,7 @@ function le(e) {
|
|
|
462
548
|
n(/* @__PURE__ */ Error("Canvas toBlob (fallback quality) returned null"));
|
|
463
549
|
return;
|
|
464
550
|
}
|
|
465
|
-
if (e.size >
|
|
551
|
+
if (e.size > ie) {
|
|
466
552
|
n(/* @__PURE__ */ Error("Image too large after compression (> 5 MB). Try a smaller image."));
|
|
467
553
|
return;
|
|
468
554
|
}
|
|
@@ -470,8 +556,8 @@ function le(e) {
|
|
|
470
556
|
blob: e,
|
|
471
557
|
mimeType: l
|
|
472
558
|
});
|
|
473
|
-
}, l,
|
|
474
|
-
}, l,
|
|
559
|
+
}, l, oe);
|
|
560
|
+
}, l, ae);
|
|
475
561
|
}, r.onerror = () => {
|
|
476
562
|
URL.revokeObjectURL(i), n(/* @__PURE__ */ Error("Failed to load image"));
|
|
477
563
|
}, r.src = i;
|
|
@@ -479,7 +565,7 @@ function le(e) {
|
|
|
479
565
|
}
|
|
480
566
|
//#endregion
|
|
481
567
|
//#region src/core/styles.ts
|
|
482
|
-
var
|
|
568
|
+
var de = {
|
|
483
569
|
inter: {
|
|
484
570
|
url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
|
|
485
571
|
family: "'Inter', system-ui, -apple-system, sans-serif"
|
|
@@ -506,16 +592,16 @@ function H(e, t) {
|
|
|
506
592
|
let n = t.angle ?? 135;
|
|
507
593
|
return t.type === "linear" ? `linear-gradient(${n}deg, ${t.from}, ${t.to})` : `radial-gradient(circle, ${t.from}, ${t.to})`;
|
|
508
594
|
}
|
|
509
|
-
function
|
|
595
|
+
function fe(e) {
|
|
510
596
|
return e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\\[0-9a-fA-F]{1,6}\s?/g, "x").replace(/@import\b[^;]*;?/gi, "").replace(/url\s*\(\s*["']?\s*(?!data:)[^)]*["']?\s*\)/gi, "url(\"\")").replace(/expression\s*\(/gi, "expression_(").replace(/javascript\s*:/gi, "blocked:").replace(/-moz-binding\s*:/gi, "").replace(/\bbehavior\s*:/gi, "");
|
|
511
597
|
}
|
|
512
|
-
function
|
|
598
|
+
function pe(e) {
|
|
513
599
|
let t = e?.bubbleOpen ?? "none", n = e?.typingIndicator ?? "dots-bounce";
|
|
514
600
|
return [t === "fade" ? "@keyframes biq-open-fade { from { opacity: 0; } to { opacity: 1; } }\n.chat-window.open { animation: biq-open-fade .22s ease forwards; }" : t === "slide-up" ? "@keyframes biq-open-slide { from { opacity: 0; transform: scale(1) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-slide .25s cubic-bezier(.22,1,.36,1) forwards; }" : t === "bounce" ? "@keyframes biq-open-bounce { 0% { opacity: 0; transform: scale(.85) translateY(8px); } 60% { transform: scale(1.03) translateY(-3px); } 100% { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-bounce .35s cubic-bezier(.34,1.56,.64,1) forwards; }" : "", n === "dots-pulse" ? "@keyframes biq-pulse { 0%, 100% { opacity: 0.3; transform: scale(1); } 50% { opacity: 1; transform: scale(1.3); } }\n.typing span { animation: biq-pulse 1.2s infinite ease-in-out; }" : n === "bar" ? ".typing { gap: 3px; align-items: flex-end; }\n.typing span { width: 3px; height: 14px; border-radius: 2px; animation: biq-bar 1s infinite ease-in-out; }\n.typing span:nth-child(1) { animation-delay: 0s; }\n.typing span:nth-child(2) { animation-delay: .15s; height: 20px; }\n.typing span:nth-child(3) { animation-delay: .3s; }\n@keyframes biq-bar { 0%, 100% { transform: scaleY(.4); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }" : ""].filter(Boolean).join("\n");
|
|
515
601
|
}
|
|
516
|
-
var
|
|
517
|
-
function
|
|
518
|
-
let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c =
|
|
602
|
+
var me = "\n/* ── Rich Blocks ─────────────────────────── */\n.biq-blocks {\n margin-top: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-width: 100%;\n}\n\n/* ── Shared button style ─────────────────── */\n.biq-btn {\n display: inline-block;\n padding: 7px 14px;\n border-radius: 18px;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: filter .15s, opacity .15s;\n text-decoration: none;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n line-height: 1.3;\n white-space: nowrap;\n}\n.biq-btn:hover { filter: brightness(1.15); }\n.biq-btn--send { background: #F97316; color: #fff; }\n.biq-btn--send:hover { filter: brightness(0.9); }\n.biq-btn--url { background: transparent; color: #F97316; }\n.biq-btn--page_action { border-style: dashed; }\n\n/* ── Card ────────────────────────────────── */\n.biq-card {\n background: #1A1A1A;\n border: 1px solid #2D2D2D;\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n text-decoration: none;\n color: inherit;\n transition: border-color .15s;\n}\n.biq-card--link:hover { border-color: #F97316; }\n\n.biq-card-img {\n width: 100%;\n max-height: 160px;\n object-fit: cover;\n display: block;\n}\n\n.biq-card-title {\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n padding: 10px 12px 2px;\n line-height: 1.3;\n}\n\n.biq-card-subtitle {\n font-size: 12px;\n color: #9CA3AF;\n padding: 0 12px 6px;\n line-height: 1.4;\n}\n\n.biq-card-price {\n font-size: 14px;\n font-weight: 600;\n color: #F97316;\n padding: 4px 12px 8px;\n}\n\n.biq-card-btns {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 10px 10px;\n}\n\n/* ── Carousel ────────────────────────────── */\n.biq-carousel {\n display: flex;\n flex-direction: row;\n gap: 10px;\n overflow-x: auto;\n padding-bottom: 4px;\n scrollbar-width: thin;\n scrollbar-color: #2D2D2D transparent;\n /* Snap cards into position on scroll */\n scroll-snap-type: x mandatory;\n}\n.biq-carousel::-webkit-scrollbar { height: 4px; }\n.biq-carousel::-webkit-scrollbar-track { background: transparent; }\n.biq-carousel::-webkit-scrollbar-thumb { background: #2D2D2D; border-radius: 2px; }\n\n.biq-carousel .biq-card {\n flex: 0 0 200px;\n scroll-snap-align: start;\n max-width: 200px;\n}\n\n/* ── Quick Replies ───────────────────────── */\n.biq-quick-replies {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n\n.biq-qr-pill {\n padding: 5px 14px;\n border-radius: 20px;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n transition: background .15s, color .15s;\n white-space: nowrap;\n}\n.biq-qr-pill:hover { background: #F97316; color: #fff; }\n\n/* ── Buttons block ───────────────────────── */\n.biq-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n", he = "\n.botiq-confirm-overlay { position:absolute; inset:0; background:rgba(0,0,0,.7);\n display:flex; align-items:center; justify-content:center; z-index:999; }\n.botiq-confirm-dialog { background:#1A1A1A; border:1px solid #2D2D2D; border-radius:12px;\n padding:16px; max-width:320px; color:#fff; font-size:14px; }\n.botiq-confirm-header { font-weight:600; margin-bottom:8px; }\n.botiq-confirm-reason { color:#9CA3AF; margin-bottom:8px; }\n.botiq-confirm-params { background:#0a0a0a; padding:8px; border-radius:6px; font-size:12px;\n max-height:120px; overflow:auto; white-space:pre-wrap; }\n.botiq-confirm-actions { display:flex; gap:8px; margin-top:12px; }\n.botiq-confirm-yes { flex:1; padding:8px 12px; border-radius:6px; border:none;\n background:#F97316; color:#fff; cursor:pointer; }\n.botiq-confirm-yes[data-risk=\"high\"] { background:#DC2626; }\n.botiq-confirm-no { flex:1; padding:8px 12px; border-radius:6px; background:transparent;\n border:1px solid #2D2D2D; color:#fff; cursor:pointer; }\n.botiq-confirm-countdown { margin-top:8px; font-size:12px; color:#9CA3AF; }\n";
|
|
603
|
+
function ge(e) {
|
|
604
|
+
let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c = de[r] ?? de.inter, l = n.buttonShape === "square" ? "14px" : "50%", u = n.position === "bottom-left" ? "right: auto; left: 24px;" : "right: 24px;", d = n.position === "bottom-left" ? "bottom left" : "bottom right", f = n.position === "bottom-left" ? "right: auto; left: 0;" : "right: 0;", p = n.fillHeight ? `min(${n.height}px, calc(100dvh - 48px))` : `${n.height}px`, m = H(t.primary, i), h = H(t.header, i), g = H(t.userBubble, i), _ = t.primary.length === 4 ? "#" + t.primary[1].repeat(2) + t.primary[2].repeat(2) + t.primary[3].repeat(2) : t.primary, v = s ? ".botiq-badge { display: none !important; }" : "";
|
|
519
605
|
return `
|
|
520
606
|
@import url('${c.url}');
|
|
521
607
|
|
|
@@ -533,6 +619,7 @@ function me(e) {
|
|
|
533
619
|
--color-bg: ${t.background};
|
|
534
620
|
--color-text: ${t.text};
|
|
535
621
|
--color-input-bg: ${t.inputBackground};
|
|
622
|
+
--hover-bg: ${_}1A;
|
|
536
623
|
--gray-50: #1A1A1A;
|
|
537
624
|
--gray-100: #222222;
|
|
538
625
|
--gray-200: #2D2D2D;
|
|
@@ -670,6 +757,9 @@ function me(e) {
|
|
|
670
757
|
}
|
|
671
758
|
.close-btn:hover { background: rgba(255,255,255,.25); }
|
|
672
759
|
|
|
760
|
+
/* Home view: hero banner acts as the header — hide the persistent header bar */
|
|
761
|
+
.chat-window[data-view="home"] .chat-header { display: none; }
|
|
762
|
+
|
|
673
763
|
/* ── Chat body + panels ─────────────────── */
|
|
674
764
|
.chat-body { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
|
|
675
765
|
|
|
@@ -690,12 +780,17 @@ function me(e) {
|
|
|
690
780
|
border: none;
|
|
691
781
|
color: var(--gray-400);
|
|
692
782
|
font: inherit;
|
|
693
|
-
font-size:
|
|
694
|
-
padding: 10px;
|
|
783
|
+
font-size: 11px;
|
|
784
|
+
padding: 8px 10px 10px;
|
|
695
785
|
cursor: pointer;
|
|
696
786
|
transition: color .15s;
|
|
787
|
+
display: flex;
|
|
788
|
+
flex-direction: column;
|
|
789
|
+
align-items: center;
|
|
790
|
+
gap: 3px;
|
|
697
791
|
}
|
|
698
792
|
|
|
793
|
+
.nav-btn svg { width: 18px; height: 18px; fill: currentColor; }
|
|
699
794
|
.nav-btn:hover { color: var(--color-text); }
|
|
700
795
|
.nav-btn.active { color: var(--color-primary); }
|
|
701
796
|
|
|
@@ -716,7 +811,7 @@ function me(e) {
|
|
|
716
811
|
font: inherit;
|
|
717
812
|
}
|
|
718
813
|
|
|
719
|
-
.msg-list-item:hover { background: var(--
|
|
814
|
+
.msg-list-item:hover { background: var(--hover-bg); }
|
|
720
815
|
|
|
721
816
|
.msg-list-avatar {
|
|
722
817
|
flex-shrink: 0;
|
|
@@ -777,35 +872,84 @@ function me(e) {
|
|
|
777
872
|
|
|
778
873
|
.msg-list-new:hover { background: var(--color-primary); color: #fff; }
|
|
779
874
|
|
|
780
|
-
/* ── Home panel
|
|
781
|
-
.home-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
875
|
+
/* ── Home panel hero banner ─────────────── */
|
|
876
|
+
.home-hero {
|
|
877
|
+
background: var(--color-primary);
|
|
878
|
+
padding: 22px 18px 20px;
|
|
879
|
+
flex-shrink: 0;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.home-hero-row {
|
|
883
|
+
display: flex;
|
|
884
|
+
align-items: center;
|
|
885
|
+
gap: 12px;
|
|
886
|
+
margin-bottom: 14px;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.home-hero-avatar {
|
|
890
|
+
width: 48px;
|
|
891
|
+
height: 48px;
|
|
892
|
+
border-radius: 50%;
|
|
893
|
+
overflow: hidden;
|
|
894
|
+
flex-shrink: 0;
|
|
895
|
+
background: rgba(255,255,255,.2);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.home-hero-name {
|
|
899
|
+
font-weight: 700;
|
|
900
|
+
font-size: 15px;
|
|
901
|
+
color: #fff;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.home-hero-status {
|
|
905
|
+
font-size: 12px;
|
|
906
|
+
color: rgba(255,255,255,.8);
|
|
907
|
+
margin-top: 2px;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.home-hero-greeting {
|
|
911
|
+
font-size: 15px;
|
|
912
|
+
line-height: 1.5;
|
|
913
|
+
color: rgba(255,255,255,.92);
|
|
786
914
|
}
|
|
787
915
|
|
|
916
|
+
.home-hero-close {
|
|
917
|
+
width: 30px;
|
|
918
|
+
height: 30px;
|
|
919
|
+
border-radius: 50%;
|
|
920
|
+
background: rgba(255,255,255,.15);
|
|
921
|
+
border: none;
|
|
922
|
+
cursor: pointer;
|
|
923
|
+
color: #fff;
|
|
924
|
+
font-size: 18px;
|
|
925
|
+
display: flex;
|
|
926
|
+
align-items: center;
|
|
927
|
+
justify-content: center;
|
|
928
|
+
flex-shrink: 0;
|
|
929
|
+
margin-left: auto;
|
|
930
|
+
transition: background .15s;
|
|
931
|
+
}
|
|
932
|
+
.home-hero-close:hover { background: rgba(255,255,255,.25); }
|
|
933
|
+
|
|
934
|
+
/* ── Home panel CTA ─────────────────────── */
|
|
788
935
|
.home-start {
|
|
789
|
-
margin:
|
|
936
|
+
margin: 14px 18px;
|
|
790
937
|
padding: 14px;
|
|
791
938
|
border-radius: 12px;
|
|
792
939
|
border: 1.5px solid var(--color-primary);
|
|
793
940
|
background: transparent;
|
|
794
941
|
color: var(--color-primary);
|
|
795
|
-
text-align:
|
|
942
|
+
text-align: center;
|
|
796
943
|
cursor: pointer;
|
|
797
944
|
font: inherit;
|
|
798
945
|
font-size: 14px;
|
|
799
|
-
font-weight:
|
|
946
|
+
font-weight: 600;
|
|
947
|
+
width: calc(100% - 36px);
|
|
800
948
|
transition: background .15s, color .15s;
|
|
801
949
|
}
|
|
802
950
|
|
|
803
951
|
.home-start:hover { background: var(--color-primary); color: #fff; }
|
|
804
952
|
|
|
805
|
-
.home-status { margin: 8px 18px; font-size: 12px; }
|
|
806
|
-
.home-status--online { color: #16A34A; }
|
|
807
|
-
.home-status--offline { color: var(--gray-400); }
|
|
808
|
-
|
|
809
953
|
/* ── Home recent conversations ──────────────── */
|
|
810
954
|
.home-recent-label {
|
|
811
955
|
margin: 16px 18px 6px;
|
|
@@ -830,7 +974,7 @@ function me(e) {
|
|
|
830
974
|
text-align: left;
|
|
831
975
|
}
|
|
832
976
|
|
|
833
|
-
.home-recent-item:hover { background: var(--
|
|
977
|
+
.home-recent-item:hover { background: var(--hover-bg); }
|
|
834
978
|
|
|
835
979
|
.home-recent-avatar {
|
|
836
980
|
flex-shrink: 0;
|
|
@@ -1117,9 +1261,11 @@ function me(e) {
|
|
|
1117
1261
|
color: var(--color-text);
|
|
1118
1262
|
opacity: 0.4;
|
|
1119
1263
|
text-decoration: none;
|
|
1120
|
-
|
|
1264
|
+
padding: 5px 0 7px;
|
|
1121
1265
|
letter-spacing: 0.02em;
|
|
1122
1266
|
transition: opacity .15s;
|
|
1267
|
+
background: var(--color-bg);
|
|
1268
|
+
border-top: 1px solid var(--gray-100);
|
|
1123
1269
|
}
|
|
1124
1270
|
.botiq-badge:hover { opacity: 0.85; }
|
|
1125
1271
|
.botiq-badge-name { font-weight: 600; color: var(--color-primary); }
|
|
@@ -1250,11 +1396,11 @@ function me(e) {
|
|
|
1250
1396
|
}
|
|
1251
1397
|
.emoji-item:hover { background: var(--gray-100); }
|
|
1252
1398
|
|
|
1253
|
-
${
|
|
1254
|
-
${
|
|
1255
|
-
${o ?
|
|
1256
|
-
${
|
|
1257
|
-
${
|
|
1399
|
+
${v}
|
|
1400
|
+
${pe(a)}
|
|
1401
|
+
${o ? fe(o) : ""}
|
|
1402
|
+
${he}
|
|
1403
|
+
${me}
|
|
1258
1404
|
@media (max-width: 480px) {
|
|
1259
1405
|
:host { bottom: 0; right: 0; left: 0; }
|
|
1260
1406
|
.chat-window {
|
|
@@ -1282,7 +1428,7 @@ function W(e, t, n) {
|
|
|
1282
1428
|
let a = new Date(e);
|
|
1283
1429
|
return `${U(a.getHours())}:${U(a.getMinutes())}`;
|
|
1284
1430
|
}
|
|
1285
|
-
function
|
|
1431
|
+
function _e(e, t, n) {
|
|
1286
1432
|
let r = (e) => {
|
|
1287
1433
|
let t = new Date(e);
|
|
1288
1434
|
return new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime();
|
|
@@ -1297,7 +1443,7 @@ function he(e, t, n) {
|
|
|
1297
1443
|
function G(e) {
|
|
1298
1444
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1299
1445
|
}
|
|
1300
|
-
function
|
|
1446
|
+
function ve(e, t, n, r = "") {
|
|
1301
1447
|
let i = `<button class="msg-list-new" type="button">+ ${G(t.newConversation)}</button>`;
|
|
1302
1448
|
return e.length === 0 ? `<div class="msg-list-empty">${G(t.noConversations)}</div>${i}` : `<div class="msg-list">${e.map((e) => {
|
|
1303
1449
|
let i = e.lastMessageAt ? Date.parse(e.lastMessageAt) : n, a = Number.isFinite(i) ? W(i, n, "vi") : "", o = e.escalated ? `<span class="msg-list-badge">${G(t.waitingForHuman)}</span>` : "";
|
|
@@ -1311,8 +1457,8 @@ function ge(e, t, n, r = "") {
|
|
|
1311
1457
|
</button>`;
|
|
1312
1458
|
}).join("")}</div>${i}`;
|
|
1313
1459
|
}
|
|
1314
|
-
function
|
|
1315
|
-
let a = e.status
|
|
1460
|
+
function ye(e, t, n = [], r = "", i = Date.now()) {
|
|
1461
|
+
let a = e.status === "offline" ? t.statusPaused : t.statusOnline, o = G(e.design.content.greeting || t.homeGreeting), s = "";
|
|
1316
1462
|
if (n.length > 0) {
|
|
1317
1463
|
let e = n.slice(0, 3).map((e) => {
|
|
1318
1464
|
let t = e.lastMessageAt ? Date.parse(e.lastMessageAt) : i, n = Number.isFinite(t) ? W(t, i, "vi") : "";
|
|
@@ -1325,18 +1471,27 @@ function _e(e, t, n = [], r = "", i = Date.now()) {
|
|
|
1325
1471
|
<span class="home-recent-time">${G(n)}</span>
|
|
1326
1472
|
</button>`;
|
|
1327
1473
|
}).join("");
|
|
1328
|
-
|
|
1474
|
+
s = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
|
|
1329
1475
|
}
|
|
1330
1476
|
return `
|
|
1331
|
-
<div class="home-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1477
|
+
<div class="home-hero">
|
|
1478
|
+
<div class="home-hero-row">
|
|
1479
|
+
${r ? `<div class="home-hero-avatar">${r}</div>` : ""}
|
|
1480
|
+
<div>
|
|
1481
|
+
<div class="home-hero-name">${G(e.name)}</div>
|
|
1482
|
+
<div class="home-hero-status">● ${G(a)}</div>
|
|
1483
|
+
</div>
|
|
1484
|
+
<button class="home-hero-close" type="button" aria-label="${G(t.ariaCloseChat)}">×</button>
|
|
1485
|
+
</div>
|
|
1486
|
+
<div class="home-hero-greeting">${o}</div>
|
|
1487
|
+
</div>
|
|
1488
|
+
<button class="home-start" type="button">${G(t.startConversation)}</button>
|
|
1489
|
+
${s}
|
|
1335
1490
|
`;
|
|
1336
1491
|
}
|
|
1337
1492
|
//#endregion
|
|
1338
1493
|
//#region src/core/assets.ts
|
|
1339
|
-
var
|
|
1494
|
+
var be = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAABL8SURBVHhe7ZsJjJzlecchbZo2aRPwScFAfM29s3N9M9/cO7O7c+zOzr0ze8ze3tN7+1yvD8Be29iYmEIrlaIaRIIIDW1URRE9BFFpAlXLYZNKxFLVVL1Q0yZSgCJhw7963u/7Zr95dyCtuuuDzCP99V0z7/c8v/d5nvedlX3LLTWrWc1qVrOa1axmNatZzWpWs5rV7Jrbc8899/nz588bz5w5lz219ODCyROnHz3xwNLTS8dPPk868cDSN5aOn3rs5ImTB8+ePps7f/a8kb7Dj/NLZadPn/7yw2cfzj146syF+48ev7y4cARHD9+PI4v3Y3HhGBYOHMHB/YeZ6Hxx4SiOLN7HRM+P37d0+cGTDz557sy5LI3Fj/+ZtVOnTpkeuO/4+YMHFv9l4cBh7NtzEOOjUxjqH2XaNTCG0V2TGB+ZqtDY8BSGB8fLn5kYnca++YM4uH8RCweP/PPJE6cfOXXqlJl/32fGji0c0y7sO3xhz9z+D/fM7cNg/whKnf3oLQ1goG8XgzI8OIGRoQmMDU8yQGoRRHpGIpCDfSPoLQ2yMYYGRjE/tw/zM3uvHjp45OtLS0tG/v03rU1NTf3azNSeY3PTe9/bPTaDrmIvujv6WPB9PUPo7x1iAIf6RxgYBZIaIsEb3bW7DI+ADfYPo793Fxujt3uAjdtZ7MXu8VnMz+7/YHZ679LRo0e/wPtzU9n09B7b9O7Zv6Xy6yz0oJjvZvAoa3q6COBgGSABoSxUAJIImqJy9g1IZUzfGSCAJQIoZSKNXcx1sffQBExOzL5GPvB+3RQ2MznXMzEy+T4FmM90opDrYhApSFJP1wD6SssAJYgj5R6nZJtypHskBq+Xsm+oDI/GUgB2tJfQnu1EPtPBnk+MTb1HvvD+3dA2NDB6aHhwjEHLporsSFlBwSklLGXhAAPQryrlwb5h1t+URUUtus/g9SxnHo1BojGVLKf3tec6kU23o5DvxMjQOMZ2TSzyft6QNrxr9ORA3zDSyTzSbXnk0kWWERQUiYdIEJjKPVHKRkkSTDoSOJICTp15JBqT4JUBZjuRyxSQTuaQbsti18AoxkcnTvH+3lDW1z1wiMoymcgg1ZZFJtmObKrAykmBqGSiUsrlTOwaRG+nBKbcG1lW0nEX+glc13LGKeDUmaeGR++kDMykcswX8kmaoMEF3u8bwrqKPYXO9h5EG1vR1ppGKpllWZhJFiogKoFS0JQ1TB29KJX60dXXh+7eXvSVBtDXJfW4vt5B9HUPse1Odx+JVnAJXHdHb0XZkug9DF6qgEwqzzKQACZaUog2taK7SOMPdvH+X1cbHBzT5DPFd5vDcYQCzcxZmvF0W45loZKJfDkX20ssGzs6SuiZHcGhb5/D4h+fRc/MMHo6B9DDsmwA3V396JsewaFvncXit8+hd24EnR0ErlSeEBqXlW26KMFLtpfh0YS2xNoQDkYQCbegmO/6YHRg9MbYdB8+fPjWYrbj1baWNBr8TQxgrDmBttZMGaKUiZUQmQgkZWVXF/Y+dRzP4q/xLL6P2SfuR0dXCd2FHlBWd3T3YP6J++Xnr2DPUyfYdwpZaSJYyWaLrOdR1mWo/yZzSCYIXopNKPlEvjXQBMfTBPGN4eHhX+XjueaWS7XvJ4fJOZphOjY2RJGIp5BoTaEtkVZlYx6Z1DLIHJVbuohidzeOfedRPIOXmQ49/xDae7pQJEAEuFTCoefP4Rn8Fb6Bl3H0O4+gUOpELlVkyqYLcr+TwEnwMuXMIzWFYmUfaaJpQgvZwlE+nmtqXV1d9yQT2fcbZefUijTFmeM0+xSIsrBIZSWVNgs82Y5csYiFZ8/gj/AqvolXsP/pk8h3dqI93YF26p0dndj/9Ck8hx/gObyKhW+eQa5QRKZNag9sxZfBKSVLao0nEY+2IdIotRa1aJKzyfwHvcXebXxc18xSsfSTidhy6apFM01NuyWSRGssJWXkCph5ZBM5ZDM5DB3cjYffeBoPvf4U+vaOIJstIJ8qIk/Zmi+i78A4zv7dUzh38WkMHBxnGZdKZNk4yipLGU/Q6D0MXqSN+aBUhrpKyOe2eArplvTX+biuiRXTRV1rtO0KD46f5VikFbFIggXTEpVhqkHKMPPtRRT6Syj0lZDPFWUwUtlTZuXzBRT7Sij0lpDPFpCkHitnGo1HE9QSS6Il2oZ4NIFocytiza3MBzU8NcxQIIJELHm1I9dh4ONbc0tGk48RkGrZR/cUNYYiiDS2sEyIM5AJVtosUygr4ykkW9JIxtNIxlIsKwhMknonbYeofyYySBL0ljR7rmRzIpZCK0GLSdlGYxM0ah/NjTEGT/GD95EU9DexCkk0t/0+H9+aWmtr623RUOw/ww1SQ66moK+xLLZ9aIoj0hxHtLmFiTKTMoV6VDyaKquFoMSpf2XkYxoJOo+l0UoZHJUWBZIETIJGY0rg4mgOxxAKNpffrwBUw1w+jyASiv00H4nczse5ZhYNRUuxphYE/MuQqingDTPRuVLSTaEoyw4GtKkFsWYKOMoUCccQoWck7pzARCi7GCwJmAKNJobGbApHyyWrvPcXKeBtRLw5gUQ0UeLjXDOLNMS+RZvmgK+6kzy08j2vCmQ4hnCoBa3hRizmgvidTjce7RDxWId0lM7l66KI0zkRuxN+JMMNDCoBpzFIjSEZnJx1PDz+mlckFAfFxMe5JhYMBr8U8jf/O5tlzklFSo+hoJpDcVYq6ucK3FAwgmRDED+aswEHtwD77gH23V1de+/Cu/s0+LNddpSa3Ky3hoPRilVV7YcakPp5NaDMF3/jOxQbH++qW5O3yRUiIBw8vzcEn6eB7fTJIb8nxKQGR5/x05Gesc+H0R704PKkAZheh6tT6/Hx1HpgdgMwS8d1kmZux8dT69hnsP+38b1RC7IBLys/STS2pIr3eUIsK5vCcTaZbBWWS1zxjfnvkya9Kdjk4uNddQv5Gsdo5n0EwxdmonOvpwHBQBMags3lez5fSDqqVH7mDcPjDiLnE/D2pJFBuzq9CT+b3Yofjunxw3ED3pow4K1xPS5P6vDh/N24OrMeH0+uw0cHtuNYmwCv6IdHBueTx6WJUeAp7yO/1D6Qj8xP1QSHQzGE/c0jfLyrbgFv+HebGuNlJ0hlcP5GBAKNCIckwIoILg/S6w3BLQaR9TlkgOuBuU24OFGHkq8eKa+AlMeJjMeBos+KCx0WXN17Lz6aXA/suwPPdNkQcLrh8TbC7105Pv/+srzSkfksr8ThQDOaG1sQEIOP8vGuunnFhj+lMqC0L8+0XJIk1msCTSy7KhxfIQIYQNYn4EcEcGYDML8Br4+bEXW74HAF4RLDcLpCEJ0+DIft+K/ZHcD0BmDvHXi+x4yg0wXR0wivJ1gVVrVr2vtRxnrdDcxvusdKmGJyh/6Ej3fVTRS8rxBANnvl1VXqJUqjJufKjisg6R6dl5/JAL2UgQap781vxGvjZsRddricfojOAIPncbiwJ2rFe3u3Sb1w/914vGiFV3DD7Qmz3suDoglUJlE5p/vUE6nfsd4XkERQqYS97uDLfLyrbi6H96KyqioLBS8WgIdgBeEVq8hNQTVAdEkAWQayhWMjLk8asZQw475WG44lrDjaasVDaQsu7TYBc5vZovLOvAFDITvcTj88YgN8bLzliaJzmhyl/yl9l+6x566A5Kt8nzKwIRiBKPhe4+NddRMdvrcIIA9NLWVlI0cJmHJURNceMcgyTA3wyvQmXJm9Ex/uuRdXSHvpKG9t5jfjo+kN+MncDpxM1KHB6YLHtTweP0l0j1UH9WW5Qsg3Bt0VYNAVfwPUegLNEB2eN/h4V90Em+dSyC/t9MvySNmoOEoBKBmqDo6BU6CWAdIqLJUwAWQ9bm6dLFpYZE2vw8ezG/DOrBaPpOvQLArwurxsIfJQZlUByN7lCsIjQ1P7vGLSCaDzGmSg0+75G6UJM8kwqFypKZNzEhy/5Bj1StpGuBvY7Lvl7KOjyxlARgXw6sxG/HRuG94cNeLNMRNeH6ejAW+NavCTOY1UwjMbcOXAVjyUsSIguOCSx1OASdkdYOO7XVTiQend8rXUhyth03P6WeoSvK/y8a66OazCC6z5+hvL+0CPpwEupw+iyw9RDLAjXZNY3/E0sCOJfYYpAKczgDQB3C0vInMb8ca4GQWPFTFRQNwtoEUUkHQ7MNtkwdu79fiYZeQ6/Hhah4JfkN6hgsdAqd5FPa5ib6rScglLG2nR4X6Bj3fVzW51XmCbYMoyGQZb6VQQFXDKc+W6AqBIAP1Is1VYXkTmNuL18ToGzy74IAheCM4ABMGPgEPAH7Sb2U86TK5je8KFVgdcggeu8qQsS3lXtQlUn1O20qLj94Qh2NxP8vGuujlt4gKVKjnAgAmSqAzoPpWHsh+ka3Uw5SyV5RQIoFMqYcoseR8YE52wOfwMnCAQQNrKOPF7+Xpg3xb2awQHvoqTaTucDg+cVQCq38e/V5ECkrKWStlush/g4111c5jFBPU3UaR9mp/1NQWiIrrnk/sc7eOo9/DOU1DLAPXSL5H5TXhzwoyC14K424kWD0lAm9uB8SYL/p5tZTbho6nbcWXfVhygDHR45D1j9Xfw96oCpGQQfLAZzRE+3lU303bTXVaz432WVaoMJLkc3orzimu5JypyOqlEfUh5aBtDPXAj26b8bHY73hw34tKEERfHTbg4YcKlcQP+g36FzN+Jq5PSLxb6Dv3cozEo+GrvYf5xKt8niPKRVnK71fVzl9G4iY93Tcxqtv/AS82ay7xPgsfDFR107YPD4UXC48Tl3XpgZj2uTm2Q/xpTRfSXmKnbGbz/PqDHfQkb3A6RARSF6hPF+1VNbGcgBmCrs3+fj3PNzGYWDrMXC/4KWMo5n4krn0lHu92NqCjg8pxV+nvgXlK1vwVK99+d347XxkxYTNgQEJxwOtxwyuP9fwDS0awzH+HjXDOzGqw6m1m4yhwmGDIQRU7BIzV3Jq8kWi0FOvdIzwUPHA43fIIL+xMufC1vw7mcDeeyNjycs0vKSjqXseJE0obRJgeaXQJcNhGCw83Gk7KZy3a+rD+lIgigo955lWLi41xTsxisL9LLpcXAC6fdUwGQApRA0bUMVZbyTGByw2ZzwWF1QbCpJcpywWmXzilj7XYPHHbKPPeK7OazqzLrV8IkyBSD1Wh7iY9vzc1qtGZEuwSHgPxv5CAQ6nsCQRAh2D0MDAPk8MBmdzPRucPhgd0hn9vdLGtJCsBPk3pSq8rphWAVYdSas3x8a26ZTOZzFqPtEmVgGZBDXAGJrpV7K87ZZ6SMVD+rJuV5tc+os7siy1XtYrmlLN+jrU+9wXrxlltu+Rwf3zWxOo0lSTPI+pkqQF52KlEW+Mpn1cQDU4+hjFMBUVgJXAHL3ysDd3pZ26jT1CX5uK6p1est36XNrJ0Lks7t1LfYUX1/+Z5aPLBqY9A5/5llqJWZqgbGP6cjLUAmrfnP+XiuudXtrPuq1WT/OfXCZUCVoJaB8Pp0iPznlQXLZqXPr8xSNTz+Xvm+w8X6Z32d7X2z1ryTj+e6mHmnucducbImT8FVygm7zSmfi3Lw0lHRCpgWSQ6rWD63Wl3lFX35O58+Cfwz6bkbNosA3U7DMB/HdTWD1vSYQw5qGYx0tFoIIIGUgloJuRKqAs1W72RiAOsFBlQ9STwo9fUnP3NCrzU8zvt/I9itRn3ddylIJUAJ3HImLkOtzEDKrorPyuAEm5uJzq1mGSBdc1lbCUudmeospO2SCJPeRH/z+xXe+RvCTJtNXzTqzS+VwdQ7YakXGByS+vyTZCPJwGgfR6Jz5Zqelz/7CRm8QgSS7fdM3zOZTF/k/b6hTKfTfcmgNfwFBUpOKzCUUlRfVxOVqgKs3P9keMp5eawq4JTv2NUALQIMWtMLuttuW/t/+7IaptPpPq/XGp60mO3MeZtZgvZ/lQKcla5VhKXOUX7GgFMmyuXPxGApkyFBtJht0O3Q/KH/Ri3bTzOdRjdXZ6j7gAUqZ94vEkEiWErGKQCV7FsBUMlai9weWHaK7JlJX/eBUWOc4f26qUy3XWfVa/Qv1tfZpIAVCHUSLHVWKQAJlnrxUJe+GiAPXylrS70NBo3hxe33bL85/6trNTNoDf0GrfHt+jorrHJJW2RgCkT1Od/v1M9XlLJZKlmL2QqdVndZp9EM8e//TNgdd9zxG5odmnG91vBGnbEe1noHKz+bauHgAarPy6DZfalcLfUOmAxm6HWGN3Ua3fjmzZtv7FV2lexWzbZtMcNO3RN6reEfDHoT6owWWM0SUALG9pO0kqt+kRC8+jo76kxWGPRm2hD/k3aH5sLWe7a2XLe/qFxv27Jlyxd23HWvc+s9Wye0O7SP63fq/1KzQ3tJu1P3j3qt8V91Wv2/aXZqf6zdqb2k1ehf0mzXXNh277aZrVu2em+7WbYl18MIrOYrX/nNrV/+8m/deeedv84/r1nNalazmtWsZjWrWc1qVrNfXvsfj+EYlqVWv8UAAAAASUVORK5CYII=";
|
|
1340
1495
|
//#endregion
|
|
1341
1496
|
//#region src/core/history-pager.ts
|
|
1342
1497
|
function K() {
|
|
@@ -1346,24 +1501,24 @@ function K() {
|
|
|
1346
1501
|
cursorReady: !1
|
|
1347
1502
|
};
|
|
1348
1503
|
}
|
|
1349
|
-
function
|
|
1504
|
+
function xe(e) {
|
|
1350
1505
|
return {
|
|
1351
1506
|
oldestCursor: e.messages[0]?.id ?? null,
|
|
1352
1507
|
hasMore: e.hasMore,
|
|
1353
1508
|
cursorReady: e.messages.length > 0
|
|
1354
1509
|
};
|
|
1355
1510
|
}
|
|
1356
|
-
function
|
|
1511
|
+
function Se(e, t) {
|
|
1357
1512
|
return {
|
|
1358
1513
|
oldestCursor: t.messages[0]?.id ?? e.oldestCursor,
|
|
1359
1514
|
hasMore: t.hasMore,
|
|
1360
1515
|
cursorReady: e.cursorReady
|
|
1361
1516
|
};
|
|
1362
1517
|
}
|
|
1363
|
-
function
|
|
1518
|
+
function Ce(e, t) {
|
|
1364
1519
|
return e.cursorReady && e.hasMore && !t && e.oldestCursor !== null;
|
|
1365
1520
|
}
|
|
1366
|
-
function
|
|
1521
|
+
function we(e, t, n) {
|
|
1367
1522
|
return e + (n - t);
|
|
1368
1523
|
}
|
|
1369
1524
|
//#endregion
|
|
@@ -1371,7 +1526,7 @@ function Se(e, t, n) {
|
|
|
1371
1526
|
function q(e) {
|
|
1372
1527
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1373
1528
|
}
|
|
1374
|
-
function
|
|
1529
|
+
function Te(e, t) {
|
|
1375
1530
|
let n = t.labels?.confirm ?? "Đồng ý", r = t.labels?.cancel ?? "Huỷ", i = t.labels?.countdownPrefix ?? "Tự động xác nhận sau ", a = t.labels?.countdownSuffix ?? "s…";
|
|
1376
1531
|
return new Promise((o) => {
|
|
1377
1532
|
let s = document.createElement("div");
|
|
@@ -1401,15 +1556,15 @@ function Ce(e, t) {
|
|
|
1401
1556
|
}
|
|
1402
1557
|
//#endregion
|
|
1403
1558
|
//#region src/core/emoji.ts
|
|
1404
|
-
function
|
|
1559
|
+
function Ee(e, t) {
|
|
1405
1560
|
let n = e.selectionStart ?? e.value.length, r = e.selectionEnd ?? e.value.length;
|
|
1406
1561
|
e.value = e.value.slice(0, n) + t + e.value.slice(r), e.selectionStart = e.selectionEnd = n + t.length, e.dispatchEvent(new Event("input", { bubbles: !0 }));
|
|
1407
1562
|
}
|
|
1408
1563
|
var J = null;
|
|
1409
|
-
async function
|
|
1564
|
+
async function De() {
|
|
1410
1565
|
return J || (J = (await import("./emoji-data-DWiYsBZI.js")).EMOJIS, J);
|
|
1411
1566
|
}
|
|
1412
|
-
function
|
|
1567
|
+
function Oe(e) {
|
|
1413
1568
|
let t = document.createElement("button");
|
|
1414
1569
|
t.type = "button", t.className = "emoji-btn", t.setAttribute("aria-label", "Emoji"), t.textContent = "🙂";
|
|
1415
1570
|
let n = document.createElement("div");
|
|
@@ -1417,7 +1572,7 @@ function Ee(e) {
|
|
|
1417
1572
|
let r = !1;
|
|
1418
1573
|
return t.addEventListener("click", async () => {
|
|
1419
1574
|
if (!r) {
|
|
1420
|
-
let t = await
|
|
1575
|
+
let t = await De();
|
|
1421
1576
|
for (let r of t) {
|
|
1422
1577
|
let t = document.createElement("button");
|
|
1423
1578
|
t.type = "button", t.className = "emoji-item", t.textContent = r, t.addEventListener("click", () => {
|
|
@@ -1440,7 +1595,7 @@ function Y(e) {
|
|
|
1440
1595
|
function X(e) {
|
|
1441
1596
|
return /^https?:\/\//i.test(e) ? e : "";
|
|
1442
1597
|
}
|
|
1443
|
-
function
|
|
1598
|
+
function ke(e) {
|
|
1444
1599
|
let t = Y(e.label), n = Y(e.value), r = Y(e.action);
|
|
1445
1600
|
if (e.action === "url") {
|
|
1446
1601
|
let n = X(e.value);
|
|
@@ -1448,51 +1603,51 @@ function De(e) {
|
|
|
1448
1603
|
}
|
|
1449
1604
|
return `<button class="biq-btn biq-btn--${r}" type="button" data-action="${r}" data-value="${n}">${t}</button>`;
|
|
1450
1605
|
}
|
|
1451
|
-
function
|
|
1606
|
+
function Ae(e) {
|
|
1452
1607
|
let t = `${e.imageUrl ? (() => {
|
|
1453
1608
|
let t = X(e.imageUrl);
|
|
1454
1609
|
return t ? `<img class="biq-card-img" src="${Y(t)}" alt="" loading="lazy" />` : "";
|
|
1455
|
-
})() : ""}${`<div class="biq-card-title">${Y(e.title)}</div>`}${e.subtitle ? `<div class="biq-card-subtitle">${Y(e.subtitle)}</div>` : ""}${e.price ? `<div class="biq-card-price">${Y(e.price)}</div>` : ""}${e.buttons && e.buttons.length > 0 ? `<div class="biq-card-btns">${e.buttons.map(
|
|
1610
|
+
})() : ""}${`<div class="biq-card-title">${Y(e.title)}</div>`}${e.subtitle ? `<div class="biq-card-subtitle">${Y(e.subtitle)}</div>` : ""}${e.price ? `<div class="biq-card-price">${Y(e.price)}</div>` : ""}${e.buttons && e.buttons.length > 0 ? `<div class="biq-card-btns">${e.buttons.map(ke).join("")}</div>` : ""}`;
|
|
1456
1611
|
if (e.url) {
|
|
1457
1612
|
let n = X(e.url);
|
|
1458
1613
|
if (n) return `<a class="biq-card biq-card--link" href="${Y(n)}" target="_blank" rel="noopener noreferrer">${t}</a>`;
|
|
1459
1614
|
}
|
|
1460
1615
|
return `<div class="biq-card">${t}</div>`;
|
|
1461
1616
|
}
|
|
1462
|
-
function
|
|
1463
|
-
return `<div class="biq-carousel">${e.cards.map(
|
|
1617
|
+
function je(e) {
|
|
1618
|
+
return `<div class="biq-carousel">${e.cards.map(Ae).join("")}</div>`;
|
|
1464
1619
|
}
|
|
1465
|
-
function
|
|
1620
|
+
function Me(e) {
|
|
1466
1621
|
return `<div class="biq-quick-replies">${e.replies.map((e) => {
|
|
1467
1622
|
let t = Y(e.label);
|
|
1468
1623
|
return `<button class="biq-qr-pill" type="button" data-qr="1" data-value="${Y(e.value)}">${t}</button>`;
|
|
1469
1624
|
}).join("")}</div>`;
|
|
1470
1625
|
}
|
|
1471
|
-
function
|
|
1472
|
-
return `<div class="biq-buttons">${e.buttons.map(
|
|
1626
|
+
function Ne(e) {
|
|
1627
|
+
return `<div class="biq-buttons">${e.buttons.map(ke).join("")}</div>`;
|
|
1473
1628
|
}
|
|
1474
|
-
function
|
|
1629
|
+
function Pe(e) {
|
|
1475
1630
|
return !e || e.length === 0 ? "" : e.map((e) => {
|
|
1476
1631
|
switch (e.type) {
|
|
1477
|
-
case "card": return
|
|
1478
|
-
case "carousel": return
|
|
1479
|
-
case "quick_replies": return
|
|
1480
|
-
case "buttons": return
|
|
1632
|
+
case "card": return Ae(e);
|
|
1633
|
+
case "carousel": return je(e);
|
|
1634
|
+
case "quick_replies": return Me(e);
|
|
1635
|
+
case "buttons": return Ne(e);
|
|
1481
1636
|
default: return "";
|
|
1482
1637
|
}
|
|
1483
1638
|
}).join("");
|
|
1484
1639
|
}
|
|
1485
1640
|
//#endregion
|
|
1486
1641
|
//#region src/core/ui.ts
|
|
1487
|
-
var
|
|
1488
|
-
function
|
|
1489
|
-
if (!e || e.type === "icon") return
|
|
1642
|
+
var Fe = "https://bot-q-frontend.vercel.app/", Ie = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z\"/>\n</svg>", Le = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>\n</svg>", Re = `<img src="${be}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" />`, ze = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/>\n</svg>", Be = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2zm-2 10H6v-2h12v2zm0-3H6V7h12v2z\"/>\n</svg>", Ve = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"/>\n</svg>", He = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"/></svg>", Ue = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z\"/></svg>";
|
|
1643
|
+
function We(e) {
|
|
1644
|
+
if (!e || e.type === "icon") return Re;
|
|
1490
1645
|
if (e.type === "emoji") return `<span style="font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%">${Z(e.value)}</span>`;
|
|
1491
1646
|
if (e.type === "initials") {
|
|
1492
1647
|
let t = e.bgColor ?? "#F97316";
|
|
1493
1648
|
return `<div style="width:100%;height:100%;border-radius:50%;background:${/^#[0-9A-Fa-f]{3,6}$/.test(t) ? t : "#F97316"};display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff">${Z(e.value.slice(0, 2).toUpperCase())}</div>`;
|
|
1494
1649
|
}
|
|
1495
|
-
return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` :
|
|
1650
|
+
return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : Re;
|
|
1496
1651
|
}
|
|
1497
1652
|
function Z(e) {
|
|
1498
1653
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -1501,27 +1656,27 @@ function Q(e) {
|
|
|
1501
1656
|
let t = [];
|
|
1502
1657
|
return e = e.replace(/`([^`]+)`/g, (e, n) => (t.push(`<code>${n}</code>`), `\x00CODE${t.length - 1}\x00`)), e = e.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>"), e = e.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), e = e.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>"), e = e.replace(/~~(.+?)~~/g, "<del>$1</del>"), e = e.replace(/__(.+?)__/g, "<strong>$1</strong>"), e = e.replace(/(^|\s)_(?!_)(.+?)_(?!_)(?=\s|$)/g, "$1<em>$2</em>"), e = e.replace(/\[([^\]]+)\]\(([^()]*(?:\([^()]*\))*[^()]*)\)/g, (e, t, n) => /^https?:\/\//.test(n) ? `<a href="${n}" target="_blank" rel="noopener noreferrer">${t}</a>` : t), e = e.replace(/\x00CODE(\d+)\x00/g, (e, n) => t[Number(n)]), e;
|
|
1503
1658
|
}
|
|
1504
|
-
function
|
|
1659
|
+
function Ge(e) {
|
|
1505
1660
|
return /^\|[\s\-:|]+\|$/.test(e);
|
|
1506
1661
|
}
|
|
1507
|
-
function
|
|
1662
|
+
function Ke(e) {
|
|
1508
1663
|
return e.replace(/^\|/, "").replace(/\|$/, "").split("|").map((e) => e.trim());
|
|
1509
1664
|
}
|
|
1510
|
-
function
|
|
1665
|
+
function qe(e, t) {
|
|
1511
1666
|
return e ? `<div class="handoff-banner">⏳ ${Z(t.waitingForHuman)}</div>` : "";
|
|
1512
1667
|
}
|
|
1513
|
-
function
|
|
1668
|
+
function Je(e) {
|
|
1514
1669
|
return e <= 0 ? "" : `<span class="unread-badge">${e > 9 ? "9+" : String(e)}</span>`;
|
|
1515
1670
|
}
|
|
1516
|
-
function
|
|
1671
|
+
function Ye(e) {
|
|
1517
1672
|
let t = Z(e).replace(/\x00/g, "").split("\n"), n = [], r = 0;
|
|
1518
1673
|
for (; r < t.length;) {
|
|
1519
1674
|
let e = t[r].trim();
|
|
1520
1675
|
if (e.startsWith("|") && e.endsWith("|")) {
|
|
1521
1676
|
let e = [];
|
|
1522
1677
|
for (; r < t.length && t[r].trim().startsWith("|") && t[r].trim().endsWith("|");) e.push(t[r].trim()), r++;
|
|
1523
|
-
let i = e.findIndex(
|
|
1524
|
-
a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" +
|
|
1678
|
+
let i = e.findIndex(Ge), a = i > 0 ? e.slice(0, i) : [], o = i >= 0 ? e.slice(i + 1) : e, s = "<table>";
|
|
1679
|
+
a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" + Ke(e).map((e) => `<th>${Q(e)}</th>`).join("") + "</tr>").join("") + "</thead>"), o.length > 0 && (s += "<tbody>" + o.map((e) => "<tr>" + Ke(e).map((e) => `<td>${Q(e)}</td>`).join("") + "</tr>").join("") + "</tbody>"), s += "</table>", n.push(s);
|
|
1525
1680
|
continue;
|
|
1526
1681
|
}
|
|
1527
1682
|
if (/^-{3,}$/.test(e)) {
|
|
@@ -1555,41 +1710,41 @@ function Ge(e) {
|
|
|
1555
1710
|
for (; n.length > 0 && n[n.length - 1] === "<br>";) n.pop();
|
|
1556
1711
|
return n.join("");
|
|
1557
1712
|
}
|
|
1558
|
-
function
|
|
1713
|
+
function Xe(e, t) {
|
|
1559
1714
|
let { strings: n, content: r, botName: i, lang: a, now: o, contactInfo: s, richMessages: c } = t;
|
|
1560
1715
|
if (e.messages.length === 0 && !e.isLoading) {
|
|
1561
1716
|
let e = r.suggestionChips.length > 0 ? `<div class="chips">${r.suggestionChips.map((e) => `<button class="chip">${Z(e)}</button>`).join("")}</div>` : "";
|
|
1562
1717
|
return `
|
|
1563
1718
|
<div class="empty-state">
|
|
1564
|
-
${
|
|
1719
|
+
${Be}
|
|
1565
1720
|
<span class="greeting">${Z(r.greeting || n.defaultGreeting)}</span>
|
|
1566
1721
|
${e}
|
|
1567
1722
|
</div>
|
|
1568
1723
|
`;
|
|
1569
1724
|
}
|
|
1570
1725
|
let l = "", u = e.messages.map((e) => {
|
|
1571
|
-
let t = e.ts ?? o, r =
|
|
1726
|
+
let t = e.ts ?? o, r = _e(t, o, a), u = r === l ? "" : `<div class="day-sep"><span>${Z(r)}</span></div>`;
|
|
1572
1727
|
l = r;
|
|
1573
|
-
let d = e.role === "assistant" ?
|
|
1728
|
+
let d = e.role === "assistant" ? Ye(e.content) : Z(e.content), f = e.role === "assistant" && !e.error ? `<div class="msg-meta">${Z(i)} · ${Z(W(t, o, a))}</div>` : "", p = e.error ? `<button class="retry-btn" type="button">↻ ${Z(n.retry)}</button>` : "", m = e.error && s ? `<div class="msg-contact">${Z(s)}</div>` : "", h = c && e.role === "assistant" && !e.error && e.blocks && e.blocks.length > 0 ? `<div class="biq-blocks">${Pe(e.blocks)}</div>` : "";
|
|
1574
1729
|
return `${u}<div class="${`message ${e.role}${e.error ? " error" : ""}`}"><div class="message-bubble">${d}</div>${p}${m}${f}${h}</div>`;
|
|
1575
1730
|
}).join(""), d = e.loadingOlder ? "<div class=\"typing\"><span></span><span></span><span></span></div>" : "", f = e.isLoading ? "<div class=\"typing\"><span></span><span></span><span></span></div>" : "";
|
|
1576
1731
|
return d + u + f;
|
|
1577
1732
|
}
|
|
1578
|
-
function
|
|
1579
|
-
let { name: i, design: a } = t, o, s, c, l, u, d, f, p, m, h, g, _, v = null, y = null, b = null, { content: x } = a, S = t.imageInput === !0, C =
|
|
1733
|
+
function Ze(e, t, n, r) {
|
|
1734
|
+
let { name: i, design: a } = t, o, s, c, l, u, d, f, p, m, h, g, _, v = null, y = null, b = null, { content: x } = a, S = t.imageInput === !0, C = We(a.avatar), w = null;
|
|
1580
1735
|
function T(e) {
|
|
1581
1736
|
e.setAttribute("data-position", a.layout.position), o = e.attachShadow({ mode: "closed" });
|
|
1582
1737
|
let w = document.createElement("style");
|
|
1583
|
-
w.textContent =
|
|
1584
|
-
<span class="icon-chat">${
|
|
1585
|
-
<span class="icon-close">${
|
|
1738
|
+
w.textContent = ge(a), o.appendChild(w), s = document.createElement("button"), s.className = "bubble", s.setAttribute("aria-label", n.ariaOpenChat), s.innerHTML = `
|
|
1739
|
+
<span class="icon-chat">${Ie}</span>
|
|
1740
|
+
<span class="icon-close">${Le}</span>
|
|
1586
1741
|
<span class="unread-badge-slot"></span>
|
|
1587
1742
|
`, s.addEventListener("click", () => r.onToggle()), o.appendChild(s), c = document.createElement("div"), c.className = "chat-window", c.setAttribute("role", "dialog"), c.setAttribute("aria-label", `${i} chat`), c.innerHTML = `
|
|
1588
1743
|
<div class="chat-header">
|
|
1589
|
-
<div class="avatar">${
|
|
1744
|
+
<div class="avatar">${We(a.avatar)}</div>
|
|
1590
1745
|
<div class="header-text">
|
|
1591
1746
|
<span class="bot-name">${Z(i)}</span>
|
|
1592
|
-
<span class="bot-status">${Z(n.statusOnline)}</span>
|
|
1747
|
+
<span class="bot-status">${Z(t.status === "offline" ? n.statusPaused : n.statusOnline)}</span>
|
|
1593
1748
|
</div>
|
|
1594
1749
|
<button class="close-btn" aria-label="${Z(n.ariaCloseChat)}">×</button>
|
|
1595
1750
|
</div>
|
|
@@ -1602,7 +1757,7 @@ function qe(e, t, n, r) {
|
|
|
1602
1757
|
<div class="chat-footer">
|
|
1603
1758
|
<div class="attach-preview-slot"></div>
|
|
1604
1759
|
<div class="input-row">
|
|
1605
|
-
${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${
|
|
1760
|
+
${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${Ve}</button>` : ""}
|
|
1606
1761
|
<textarea
|
|
1607
1762
|
class="input"
|
|
1608
1763
|
placeholder="${Z(x.placeholder || n.inputPlaceholder)}"
|
|
@@ -1611,20 +1766,22 @@ function qe(e, t, n, r) {
|
|
|
1611
1766
|
aria-label="Message input"
|
|
1612
1767
|
></textarea>
|
|
1613
1768
|
<button class="send-btn" aria-label="${Z(n.ariaSendMessage)}">
|
|
1614
|
-
${
|
|
1769
|
+
${ze}
|
|
1615
1770
|
</button>
|
|
1616
1771
|
</div>
|
|
1617
|
-
<a class="botiq-badge" href="${Ne}" target="_blank" rel="noopener noreferrer">
|
|
1618
|
-
${Z(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
|
|
1619
|
-
</a>
|
|
1620
1772
|
</div>
|
|
1621
1773
|
</div>
|
|
1622
1774
|
</div>
|
|
1623
1775
|
<div class="bottom-nav">
|
|
1624
|
-
<button class="nav-btn" data-view="home"
|
|
1625
|
-
<button class="nav-btn" data-view="messages"
|
|
1776
|
+
<button class="nav-btn" data-view="home">${He}<span>${Z(n.navHome)}</span></button>
|
|
1777
|
+
<button class="nav-btn" data-view="messages">${Ue}<span>${Z(n.navMessages)}</span></button>
|
|
1626
1778
|
</div>
|
|
1627
|
-
|
|
1779
|
+
<a class="botiq-badge" href="${Fe}" target="_blank" rel="noopener noreferrer">
|
|
1780
|
+
${Z(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
|
|
1781
|
+
</a>
|
|
1782
|
+
`, c.querySelector(".close-btn").addEventListener("click", () => r.onToggle()), l = c.querySelector(".panel-home"), u = c.querySelector(".panel-messages"), d = c.querySelector(".panel-conversation"), l.innerHTML = ye(t, n, [], C), l.querySelector(".home-hero-close")?.addEventListener("click", () => {
|
|
1783
|
+
r.onToggle();
|
|
1784
|
+
}), l.querySelector(".home-start")?.addEventListener("click", () => {
|
|
1628
1785
|
r.onNewConversation();
|
|
1629
1786
|
}), f = c.querySelector(".nav-btn[data-view=\"home\"]"), p = c.querySelector(".nav-btn[data-view=\"messages\"]"), c.querySelectorAll(".nav-btn").forEach((e) => {
|
|
1630
1787
|
e.addEventListener("click", () => {
|
|
@@ -1642,8 +1799,8 @@ function qe(e, t, n, r) {
|
|
|
1642
1799
|
}), g.addEventListener("keydown", (e) => {
|
|
1643
1800
|
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), E());
|
|
1644
1801
|
}), _.addEventListener("click", E);
|
|
1645
|
-
let D = c.querySelector(".input-row"), { button: O, panel: k } =
|
|
1646
|
-
|
|
1802
|
+
let D = c.querySelector(".input-row"), { button: O, panel: k } = Oe((e) => {
|
|
1803
|
+
Ee(g, e), g.focus();
|
|
1647
1804
|
});
|
|
1648
1805
|
D.insertBefore(O, _), c.querySelector(".chat-footer").appendChild(k), y = c.querySelector(".attach-preview-slot"), S && (v = c.querySelector(".attach-btn"), v && (b = document.createElement("input"), b.type = "file", b.accept = "image/jpeg,image/png,image/webp", b.style.display = "none", b.setAttribute("aria-hidden", "true"), o.appendChild(b), v.addEventListener("click", () => {
|
|
1649
1806
|
b?.click();
|
|
@@ -1658,7 +1815,7 @@ function qe(e, t, n, r) {
|
|
|
1658
1815
|
}
|
|
1659
1816
|
function D(e) {
|
|
1660
1817
|
let a = m.scrollHeight - m.scrollTop - m.clientHeight < 80, o = m.scrollTop, s = m.scrollHeight;
|
|
1661
|
-
m.innerHTML =
|
|
1818
|
+
m.innerHTML = Xe(e, {
|
|
1662
1819
|
strings: n,
|
|
1663
1820
|
content: x,
|
|
1664
1821
|
botName: i,
|
|
@@ -1696,12 +1853,12 @@ function qe(e, t, n, r) {
|
|
|
1696
1853
|
n && (n.style.display = "none");
|
|
1697
1854
|
}
|
|
1698
1855
|
});
|
|
1699
|
-
}), a ? m.scrollTop = m.scrollHeight : m.scrollTop =
|
|
1856
|
+
}), a ? m.scrollTop = m.scrollHeight : m.scrollTop = we(o, s, m.scrollHeight);
|
|
1700
1857
|
}
|
|
1701
1858
|
function O(e) {
|
|
1702
1859
|
e.isOpen ? (c.classList.add("open"), s.classList.add("open"), s.setAttribute("aria-label", n.ariaCloseChat), e.view === "conversation" && requestAnimationFrame(() => g.focus())) : (c.classList.remove("open"), s.classList.remove("open"), s.setAttribute("aria-label", n.ariaOpenChat));
|
|
1703
1860
|
let i = s.querySelector(".unread-badge-slot");
|
|
1704
|
-
if (i && (i.innerHTML =
|
|
1861
|
+
if (i && (i.innerHTML = Je(e.unreadCount)), _.disabled = e.isLoading || e.isUploading, y && S) if (e.pendingAttachment) {
|
|
1705
1862
|
let t = e.pendingAttachment, i = e.isUploading, a = e.uploadError;
|
|
1706
1863
|
y.innerHTML = `
|
|
1707
1864
|
<div class="attach-preview">
|
|
@@ -1721,7 +1878,9 @@ function qe(e, t, n, r) {
|
|
|
1721
1878
|
if (c.dataset.view = e.view, l.classList.toggle("active", e.view === "home"), u.classList.toggle("active", e.view === "messages"), d.classList.toggle("active", e.view === "conversation"), f.classList.toggle("active", e.view === "home"), p.classList.toggle("active", e.view === "messages"), e.view === "home" && e.conversations !== w) {
|
|
1722
1879
|
w = e.conversations;
|
|
1723
1880
|
let i = Date.now();
|
|
1724
|
-
l.innerHTML =
|
|
1881
|
+
l.innerHTML = ye(t, n, e.conversations, C, i), l.querySelector(".home-hero-close")?.addEventListener("click", () => {
|
|
1882
|
+
r.onToggle();
|
|
1883
|
+
}), l.querySelector(".home-start")?.addEventListener("click", () => {
|
|
1725
1884
|
r.onNewConversation();
|
|
1726
1885
|
}), l.querySelectorAll(".home-recent-item").forEach((e) => {
|
|
1727
1886
|
e.addEventListener("click", () => {
|
|
@@ -1730,7 +1889,7 @@ function qe(e, t, n, r) {
|
|
|
1730
1889
|
});
|
|
1731
1890
|
});
|
|
1732
1891
|
}
|
|
1733
|
-
e.view === "conversation" && (D(e), h.innerHTML =
|
|
1892
|
+
e.view === "conversation" && (D(e), h.innerHTML = qe(e.escalated, n)), e.view === "messages" && (u.innerHTML = ve(e.conversations, n, Date.now(), C), u.querySelectorAll(".msg-list-item").forEach((e) => {
|
|
1734
1893
|
e.addEventListener("click", () => {
|
|
1735
1894
|
let t = e.dataset.session;
|
|
1736
1895
|
t && r.onOpenConversation(t);
|
|
@@ -1740,7 +1899,7 @@ function qe(e, t, n, r) {
|
|
|
1740
1899
|
}));
|
|
1741
1900
|
}
|
|
1742
1901
|
function k(e) {
|
|
1743
|
-
return
|
|
1902
|
+
return Te(o, {
|
|
1744
1903
|
...e,
|
|
1745
1904
|
labels: {
|
|
1746
1905
|
confirm: n.confirmYes,
|
|
@@ -1758,7 +1917,7 @@ function qe(e, t, n, r) {
|
|
|
1758
1917
|
}
|
|
1759
1918
|
//#endregion
|
|
1760
1919
|
//#region src/i18n/vi.ts
|
|
1761
|
-
var
|
|
1920
|
+
var Qe = {
|
|
1762
1921
|
statusOnline: "Trực tuyến",
|
|
1763
1922
|
statusPaused: "Tạm ngừng",
|
|
1764
1923
|
navHome: "Trang chủ",
|
|
@@ -1799,7 +1958,7 @@ var Je = {
|
|
|
1799
1958
|
imageUploadTooLarge: "Ảnh quá lớn (tối đa 5 MB sau khi nén).",
|
|
1800
1959
|
imageUploadRateLimit: "Gửi quá nhanh. Vui lòng thử lại.",
|
|
1801
1960
|
imageUploadError: "Tải ảnh thất bại. Vui lòng thử lại."
|
|
1802
|
-
},
|
|
1961
|
+
}, $e = {
|
|
1803
1962
|
statusOnline: "Online",
|
|
1804
1963
|
statusPaused: "Paused",
|
|
1805
1964
|
navHome: "Home",
|
|
@@ -1843,20 +2002,20 @@ var Je = {
|
|
|
1843
2002
|
};
|
|
1844
2003
|
//#endregion
|
|
1845
2004
|
//#region src/i18n/index.ts
|
|
1846
|
-
function
|
|
1847
|
-
return e === "en" ?
|
|
2005
|
+
function et(e) {
|
|
2006
|
+
return e === "en" ? $e : Qe;
|
|
1848
2007
|
}
|
|
1849
2008
|
//#endregion
|
|
1850
2009
|
//#region src/core/declarative-executor.ts
|
|
1851
|
-
var
|
|
1852
|
-
function
|
|
2010
|
+
var tt = /^[a-zA-Z0-9_-]*$/;
|
|
2011
|
+
function nt(e, t) {
|
|
1853
2012
|
return e.replace(/\{([a-zA-Z][a-zA-Z0-9_]*)\}/g, (e, n) => {
|
|
1854
2013
|
let r = t[n], i = r == null ? "" : String(r);
|
|
1855
|
-
if (!
|
|
2014
|
+
if (!tt.test(i)) throw Error(`Unsafe param value for "${n}"`);
|
|
1856
2015
|
return i;
|
|
1857
2016
|
});
|
|
1858
2017
|
}
|
|
1859
|
-
function
|
|
2018
|
+
function rt(e, t) {
|
|
1860
2019
|
let n = typeof location < "u" ? location.origin : "https://placeholder.local", r, i;
|
|
1861
2020
|
try {
|
|
1862
2021
|
r = new URL(e, n), i = new URL(t.replace(/\{[a-zA-Z][a-zA-Z0-9_]*\}/g, "x"), n);
|
|
@@ -1866,10 +2025,10 @@ function $e(e, t) {
|
|
|
1866
2025
|
if (!/^https?:$/.test(r.protocol)) throw Error("Navigation must be http(s)");
|
|
1867
2026
|
if (r.origin !== i.origin) throw Error("Navigation origin not allowed");
|
|
1868
2027
|
}
|
|
1869
|
-
async function
|
|
2028
|
+
async function it(e, t) {
|
|
1870
2029
|
let n = e.config;
|
|
1871
2030
|
if (e.operation === "click") {
|
|
1872
|
-
let e =
|
|
2031
|
+
let e = nt(String(n.selectorTemplate ?? ""), t), r = document.querySelector(e);
|
|
1873
2032
|
if (!r) throw Error(`No element for selector: ${e}`);
|
|
1874
2033
|
r.click();
|
|
1875
2034
|
return;
|
|
@@ -1884,15 +2043,15 @@ async function et(e, t) {
|
|
|
1884
2043
|
return;
|
|
1885
2044
|
}
|
|
1886
2045
|
if (e.operation === "navigate") {
|
|
1887
|
-
let e = String(n.urlTemplate ?? ""), r =
|
|
1888
|
-
|
|
2046
|
+
let e = String(n.urlTemplate ?? ""), r = nt(e, t);
|
|
2047
|
+
rt(r, e), location.assign(r);
|
|
1889
2048
|
return;
|
|
1890
2049
|
}
|
|
1891
2050
|
throw Error(`Unknown operation: ${String(e.operation)}`);
|
|
1892
2051
|
}
|
|
1893
2052
|
//#endregion
|
|
1894
2053
|
//#region src/core/page-action-executor.ts
|
|
1895
|
-
async function
|
|
2054
|
+
async function at(e, t) {
|
|
1896
2055
|
let n = t.registry.get(e.actionName);
|
|
1897
2056
|
if (!n) return {
|
|
1898
2057
|
status: "unknown",
|
|
@@ -1917,26 +2076,26 @@ async function tt(e, t) {
|
|
|
1917
2076
|
//#endregion
|
|
1918
2077
|
//#region src/builds/npm/index.ts
|
|
1919
2078
|
var $ = 10;
|
|
1920
|
-
function
|
|
1921
|
-
if (D.setDeclarativeRunner(
|
|
2079
|
+
function ot(e) {
|
|
2080
|
+
if (D.setDeclarativeRunner(it), typeof window < "u" && (window.botiq = window.botiq ?? {}, window.botiq.registerActions = (e) => D.register(e)), !e.apiKey) return console.warn("[BotIQ] apiKey is required"), () => void 0;
|
|
1922
2081
|
let t = p(e);
|
|
1923
2082
|
y();
|
|
1924
2083
|
let n = t.apiKey.slice(-16), r = C(), i = b(n), a = x(n, i);
|
|
1925
|
-
|
|
2084
|
+
R({
|
|
1926
2085
|
messages: a,
|
|
1927
2086
|
view: "home",
|
|
1928
2087
|
currentSessionId: i
|
|
1929
2088
|
});
|
|
1930
2089
|
let o = K(), s = document.createElement("div");
|
|
1931
2090
|
document.body.appendChild(s);
|
|
1932
|
-
let c = () => void 0, l = !1, u =
|
|
2091
|
+
let c = () => void 0, l = !1, u = et(void 0), d = null, m = null, h = null, g = null;
|
|
1933
2092
|
function _() {
|
|
1934
2093
|
g ||= setTimeout(async () => {
|
|
1935
|
-
if (g = null, !(!
|
|
1936
|
-
let e = await
|
|
1937
|
-
e.messages.length > 0 &&
|
|
2094
|
+
if (g = null, !(!L().escalated || !L().isOpen)) try {
|
|
2095
|
+
let e = await P(t.apiUrl, t.apiKey, L().currentSessionId, $, r);
|
|
2096
|
+
e.messages.length > 0 && R({ messages: e.messages.map(M) }), R({ escalated: e.escalated === !0 });
|
|
1938
2097
|
} catch {} finally {
|
|
1939
|
-
|
|
2098
|
+
L().escalated && L().isOpen && _();
|
|
1940
2099
|
}
|
|
1941
2100
|
}, 1e4);
|
|
1942
2101
|
}
|
|
@@ -1946,23 +2105,23 @@ function nt(e) {
|
|
|
1946
2105
|
console.warn("[BotIQ] Widget not authorised on this origin — skipped mount"), s.remove();
|
|
1947
2106
|
return;
|
|
1948
2107
|
}
|
|
1949
|
-
h = e, u =
|
|
1950
|
-
let n =
|
|
1951
|
-
onSend:
|
|
1952
|
-
onToggle:
|
|
1953
|
-
onScrollTop:
|
|
1954
|
-
onRetry:
|
|
2108
|
+
h = e, u = et(e.widgetLanguage), e.pageActions?.length && D.seed(e.pageActions);
|
|
2109
|
+
let n = Ze(t, e, u, {
|
|
2110
|
+
onSend: ae,
|
|
2111
|
+
onToggle: le,
|
|
2112
|
+
onScrollTop: ne,
|
|
2113
|
+
onRetry: oe,
|
|
1955
2114
|
onNavigate: E,
|
|
1956
|
-
onOpenConversation:
|
|
2115
|
+
onOpenConversation: j,
|
|
1957
2116
|
onNewConversation: A,
|
|
1958
2117
|
onAttachImage: ie,
|
|
1959
|
-
onRemoveAttachment:
|
|
1960
|
-
onBlockPageAction:
|
|
2118
|
+
onRemoveAttachment: V,
|
|
2119
|
+
onBlockPageAction: se
|
|
1961
2120
|
});
|
|
1962
|
-
d = n, n.mount(s), c = re((e) => n.update(e)), n.update(
|
|
1963
|
-
if (
|
|
2121
|
+
d = n, n.mount(s), c = re((e) => n.update(e)), n.update(L()), e.proactive?.enabled && (m = setTimeout(() => {
|
|
2122
|
+
if (L().isOpen) return;
|
|
1964
2123
|
let t = w();
|
|
1965
|
-
|
|
2124
|
+
R({
|
|
1966
2125
|
messages: [{
|
|
1967
2126
|
role: "assistant",
|
|
1968
2127
|
content: e.proactive.message,
|
|
@@ -1970,7 +2129,7 @@ function nt(e) {
|
|
|
1970
2129
|
}],
|
|
1971
2130
|
view: "conversation",
|
|
1972
2131
|
currentSessionId: t,
|
|
1973
|
-
unreadCount:
|
|
2132
|
+
unreadCount: L().unreadCount + 1
|
|
1974
2133
|
});
|
|
1975
2134
|
}, e.proactive.delayMs ?? 8e3)), a.length > 0 && N(i);
|
|
1976
2135
|
});
|
|
@@ -1979,31 +2138,31 @@ function nt(e) {
|
|
|
1979
2138
|
if (!v) {
|
|
1980
2139
|
v = !0;
|
|
1981
2140
|
try {
|
|
1982
|
-
|
|
2141
|
+
R({ conversations: await O(t.apiUrl, t.apiKey, r) });
|
|
1983
2142
|
} finally {
|
|
1984
2143
|
v = !1;
|
|
1985
2144
|
}
|
|
1986
2145
|
}
|
|
1987
2146
|
}
|
|
1988
2147
|
function E(e) {
|
|
1989
|
-
|
|
2148
|
+
R({ view: e }), (e === "home" || e === "messages") && T();
|
|
1990
2149
|
}
|
|
1991
2150
|
function A() {
|
|
1992
|
-
|
|
2151
|
+
R({
|
|
1993
2152
|
view: "conversation",
|
|
1994
2153
|
currentSessionId: w(),
|
|
1995
2154
|
messages: [],
|
|
1996
2155
|
escalated: !1
|
|
1997
2156
|
}), o = K();
|
|
1998
2157
|
}
|
|
1999
|
-
function
|
|
2000
|
-
|
|
2158
|
+
function j(e) {
|
|
2159
|
+
R({
|
|
2001
2160
|
view: "conversation",
|
|
2002
2161
|
currentSessionId: e,
|
|
2003
2162
|
messages: x(n, e)
|
|
2004
2163
|
}), o = K(), N(e);
|
|
2005
2164
|
}
|
|
2006
|
-
function
|
|
2165
|
+
function M(e) {
|
|
2007
2166
|
let t = Date.parse(e.createdAt);
|
|
2008
2167
|
return {
|
|
2009
2168
|
role: e.role,
|
|
@@ -2013,44 +2172,65 @@ function nt(e) {
|
|
|
2013
2172
|
};
|
|
2014
2173
|
}
|
|
2015
2174
|
async function N(e) {
|
|
2016
|
-
let n = await
|
|
2017
|
-
n.messages.length > 0 && (o =
|
|
2175
|
+
let n = await P(t.apiUrl, t.apiKey, e, $, r);
|
|
2176
|
+
L().currentSessionId === e && (n.messages.length > 0 && (o = xe(n), R({ messages: n.messages.map(M) })), R({ escalated: n.escalated === !0 }), L().escalated && _());
|
|
2018
2177
|
}
|
|
2019
|
-
async function
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2178
|
+
async function ne() {
|
|
2179
|
+
if (Ce(o, L().loadingOlder)) {
|
|
2180
|
+
R({ loadingOlder: !0 });
|
|
2022
2181
|
try {
|
|
2023
|
-
let e =
|
|
2024
|
-
n.messages.length > 0 &&
|
|
2182
|
+
let e = L().currentSessionId, n = await ee(t.apiUrl, t.apiKey, e, o.oldestCursor, $);
|
|
2183
|
+
n.messages.length > 0 && R({ messages: [...n.messages.map(M), ...L().messages] }), o = Se(o, n);
|
|
2025
2184
|
} finally {
|
|
2026
|
-
|
|
2185
|
+
R({ loadingOlder: !1 });
|
|
2027
2186
|
}
|
|
2028
2187
|
}
|
|
2029
2188
|
}
|
|
2030
|
-
let
|
|
2189
|
+
let F = "", I = null, z = null;
|
|
2031
2190
|
async function B(e, i, a) {
|
|
2032
|
-
let o =
|
|
2033
|
-
|
|
2191
|
+
let o = L().currentSessionId, s = x(n, o).length === 0 && L().messages.filter((e) => e.role === "user").length === 1;
|
|
2192
|
+
R({ isLoading: !0 });
|
|
2034
2193
|
try {
|
|
2035
2194
|
let c = i && a ? [{
|
|
2036
2195
|
url: i,
|
|
2037
2196
|
mimeType: a
|
|
2038
|
-
}] : void 0, l = await
|
|
2197
|
+
}] : void 0, l = await te({
|
|
2198
|
+
apiUrl: t.apiUrl,
|
|
2199
|
+
apiKey: t.apiKey,
|
|
2200
|
+
sessionId: o,
|
|
2201
|
+
message: e,
|
|
2202
|
+
history: L().messages.filter((e) => !e.error && !e.streaming),
|
|
2203
|
+
strings: u,
|
|
2204
|
+
visitorId: r,
|
|
2205
|
+
attachments: c,
|
|
2206
|
+
onToken(e) {
|
|
2207
|
+
let t = L().messages, n = t[t.length - 1];
|
|
2208
|
+
n?.role === "assistant" && n.streaming ? R({ messages: [...t.slice(0, -1), {
|
|
2209
|
+
...n,
|
|
2210
|
+
content: n.content + e
|
|
2211
|
+
}] }) : R({ messages: [...t, {
|
|
2212
|
+
role: "assistant",
|
|
2213
|
+
content: e,
|
|
2214
|
+
ts: Date.now(),
|
|
2215
|
+
streaming: !0
|
|
2216
|
+
}] });
|
|
2217
|
+
}
|
|
2218
|
+
}), f = L().messages.filter((e) => !e.streaming), p = {
|
|
2039
2219
|
role: "assistant",
|
|
2040
2220
|
content: l.reply,
|
|
2041
2221
|
ts: Date.now(),
|
|
2042
2222
|
...l.error ? { error: !0 } : {},
|
|
2043
2223
|
...h?.richMessages && l.blocks?.length ? { blocks: l.blocks } : {}
|
|
2044
2224
|
};
|
|
2045
|
-
if (
|
|
2046
|
-
messages: [...
|
|
2225
|
+
if (R({
|
|
2226
|
+
messages: [...f, p],
|
|
2047
2227
|
isLoading: !1
|
|
2048
|
-
}), l.error || S(n, o, [
|
|
2049
|
-
|
|
2228
|
+
}), l.error || S(n, o, [p]), !l.error && s && T(), l.error || P(t.apiUrl, t.apiKey, o, $, r).then((e) => {
|
|
2229
|
+
R({ escalated: e.escalated === !0 }), L().escalated && _();
|
|
2050
2230
|
}), !l.error && l.pageAction && d) {
|
|
2051
2231
|
let e = d;
|
|
2052
2232
|
try {
|
|
2053
|
-
let t = await
|
|
2233
|
+
let t = await at(l.pageAction, {
|
|
2054
2234
|
registry: D,
|
|
2055
2235
|
confirm: (t) => e.confirmAction(t)
|
|
2056
2236
|
});
|
|
@@ -2060,7 +2240,7 @@ function nt(e) {
|
|
|
2060
2240
|
content: t.status === "executed" ? u.actionDone : t.status === "cancelled" ? u.actionCancelled : t.status === "unknown" ? `⚠ ${t.message ?? u.actionUnavailable}` : `⚠ ${t.message ?? u.actionError}`,
|
|
2061
2241
|
ts: Date.now()
|
|
2062
2242
|
};
|
|
2063
|
-
|
|
2243
|
+
R({ messages: [...L().messages, r] }), S(n, o, [r]);
|
|
2064
2244
|
} catch {
|
|
2065
2245
|
if (!d) return;
|
|
2066
2246
|
let e = {
|
|
@@ -2068,23 +2248,23 @@ function nt(e) {
|
|
|
2068
2248
|
content: u.actionError,
|
|
2069
2249
|
ts: Date.now()
|
|
2070
2250
|
};
|
|
2071
|
-
|
|
2251
|
+
R({ messages: [...L().messages, e] }), S(n, o, [e]);
|
|
2072
2252
|
}
|
|
2073
2253
|
}
|
|
2074
2254
|
} catch {
|
|
2075
|
-
|
|
2255
|
+
R({ isLoading: !1 });
|
|
2076
2256
|
}
|
|
2077
2257
|
}
|
|
2078
2258
|
async function ie(e) {
|
|
2079
|
-
let t =
|
|
2259
|
+
let t = ce(e);
|
|
2080
2260
|
if (!t.ok) {
|
|
2081
|
-
|
|
2261
|
+
R({ uploadError: t.error });
|
|
2082
2262
|
return;
|
|
2083
2263
|
}
|
|
2084
|
-
|
|
2264
|
+
R({ uploadError: null });
|
|
2085
2265
|
try {
|
|
2086
|
-
let { blob: t, mimeType: n } = await
|
|
2087
|
-
r && URL.revokeObjectURL(r.previewUrl),
|
|
2266
|
+
let { blob: t, mimeType: n } = await ue(e), r = L().pendingAttachment;
|
|
2267
|
+
r && URL.revokeObjectURL(r.previewUrl), R({
|
|
2088
2268
|
pendingAttachment: {
|
|
2089
2269
|
blob: t,
|
|
2090
2270
|
previewUrl: URL.createObjectURL(t),
|
|
@@ -2093,51 +2273,51 @@ function nt(e) {
|
|
|
2093
2273
|
uploadError: null
|
|
2094
2274
|
});
|
|
2095
2275
|
} catch {
|
|
2096
|
-
|
|
2276
|
+
R({ uploadError: u.imageUploadError });
|
|
2097
2277
|
}
|
|
2098
2278
|
}
|
|
2099
|
-
function
|
|
2100
|
-
let e =
|
|
2101
|
-
e && URL.revokeObjectURL(e.previewUrl),
|
|
2279
|
+
function V() {
|
|
2280
|
+
let e = L().pendingAttachment;
|
|
2281
|
+
e && URL.revokeObjectURL(e.previewUrl), R({
|
|
2102
2282
|
pendingAttachment: null,
|
|
2103
2283
|
uploadError: null
|
|
2104
2284
|
});
|
|
2105
2285
|
}
|
|
2106
|
-
async function
|
|
2107
|
-
if (
|
|
2108
|
-
let i =
|
|
2286
|
+
async function ae(e) {
|
|
2287
|
+
if (L().isLoading || L().isUploading) return;
|
|
2288
|
+
let i = L().pendingAttachment;
|
|
2109
2289
|
if (!e && !i) return;
|
|
2110
|
-
|
|
2111
|
-
let a =
|
|
2290
|
+
R({ uploadError: null }), F = e, I = null, z = null;
|
|
2291
|
+
let a = L().currentSessionId, o = {
|
|
2112
2292
|
role: "user",
|
|
2113
2293
|
content: e,
|
|
2114
2294
|
ts: Date.now()
|
|
2115
2295
|
};
|
|
2116
|
-
if (
|
|
2117
|
-
|
|
2296
|
+
if (R({ messages: [...L().messages, o] }), S(n, a, [o]), i) {
|
|
2297
|
+
R({
|
|
2118
2298
|
isUploading: !0,
|
|
2119
2299
|
uploadError: null
|
|
2120
2300
|
});
|
|
2121
2301
|
let e = await k(t.apiUrl, t.apiKey, i.blob, r, u);
|
|
2122
|
-
if (
|
|
2123
|
-
|
|
2124
|
-
let t =
|
|
2125
|
-
|
|
2302
|
+
if (R({ isUploading: !1 }), !e.ok) {
|
|
2303
|
+
R({ uploadError: e.error });
|
|
2304
|
+
let t = L().messages;
|
|
2305
|
+
R({ messages: t.slice(0, -1) });
|
|
2126
2306
|
return;
|
|
2127
2307
|
}
|
|
2128
|
-
|
|
2308
|
+
I = e.url, z = i.mimeType, URL.revokeObjectURL(i.previewUrl), R({
|
|
2129
2309
|
pendingAttachment: null,
|
|
2130
2310
|
uploadError: null
|
|
2131
2311
|
});
|
|
2132
2312
|
}
|
|
2133
|
-
await B(e,
|
|
2313
|
+
await B(e, I ?? void 0, z ?? void 0);
|
|
2134
2314
|
}
|
|
2135
|
-
function
|
|
2136
|
-
if (
|
|
2137
|
-
let e =
|
|
2138
|
-
|
|
2315
|
+
function oe() {
|
|
2316
|
+
if (L().isLoading || !F) return;
|
|
2317
|
+
let e = L().messages;
|
|
2318
|
+
R({ messages: e.length > 0 && e[e.length - 1].error ? e.slice(0, -1) : e }), B(F, I ?? void 0, z ?? void 0);
|
|
2139
2319
|
}
|
|
2140
|
-
async function
|
|
2320
|
+
async function se(e) {
|
|
2141
2321
|
if (!d) return;
|
|
2142
2322
|
if (!D.has(e)) {
|
|
2143
2323
|
let e = {
|
|
@@ -2145,12 +2325,12 @@ function nt(e) {
|
|
|
2145
2325
|
content: `⚠ ${u.actionUnavailable}`,
|
|
2146
2326
|
ts: Date.now()
|
|
2147
2327
|
};
|
|
2148
|
-
|
|
2328
|
+
R({ messages: [...L().messages, e] });
|
|
2149
2329
|
return;
|
|
2150
2330
|
}
|
|
2151
2331
|
let t = d;
|
|
2152
2332
|
try {
|
|
2153
|
-
let n = await
|
|
2333
|
+
let n = await at({
|
|
2154
2334
|
actionName: e,
|
|
2155
2335
|
params: {},
|
|
2156
2336
|
reason: ""
|
|
@@ -2164,7 +2344,7 @@ function nt(e) {
|
|
|
2164
2344
|
content: n.status === "executed" ? u.actionDone : n.status === "cancelled" ? u.actionCancelled : n.status === "unknown" ? `⚠ ${n.message ?? u.actionUnavailable}` : `⚠ ${n.message ?? u.actionError}`,
|
|
2165
2345
|
ts: Date.now()
|
|
2166
2346
|
};
|
|
2167
|
-
|
|
2347
|
+
R({ messages: [...L().messages, r] });
|
|
2168
2348
|
} catch {
|
|
2169
2349
|
if (!d) return;
|
|
2170
2350
|
let e = {
|
|
@@ -2172,24 +2352,24 @@ function nt(e) {
|
|
|
2172
2352
|
content: u.actionError,
|
|
2173
2353
|
ts: Date.now()
|
|
2174
2354
|
};
|
|
2175
|
-
|
|
2355
|
+
R({ messages: [...L().messages, e] });
|
|
2176
2356
|
}
|
|
2177
2357
|
}
|
|
2178
|
-
function
|
|
2179
|
-
let e = !
|
|
2180
|
-
|
|
2358
|
+
function le() {
|
|
2359
|
+
let e = !L().isOpen, t = L().view;
|
|
2360
|
+
R({
|
|
2181
2361
|
isOpen: e,
|
|
2182
2362
|
...e ? { unreadCount: 0 } : {}
|
|
2183
2363
|
}), e && t === "home" && T();
|
|
2184
2364
|
}
|
|
2185
2365
|
return () => {
|
|
2186
2366
|
l = !0, d = null, c(), m && clearTimeout(m), g &&= (clearTimeout(g), null);
|
|
2187
|
-
let e =
|
|
2188
|
-
e && URL.revokeObjectURL(e.previewUrl),
|
|
2367
|
+
let e = L().pendingAttachment;
|
|
2368
|
+
e && URL.revokeObjectURL(e.previewUrl), R({
|
|
2189
2369
|
pendingAttachment: null,
|
|
2190
2370
|
uploadError: null
|
|
2191
2371
|
}), s.remove();
|
|
2192
2372
|
};
|
|
2193
2373
|
}
|
|
2194
2374
|
//#endregion
|
|
2195
|
-
export {
|
|
2375
|
+
export { ot as t };
|