@paramms/chat-widget 1.6.3 → 1.7.0
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/chatlist.d.ts +4 -0
- package/dist/chatlist2.js +406 -353
- package/dist/chatlist2.js.map +1 -1
- package/dist/embed-lite.js +3 -3
- package/dist/embed-lite.js.map +1 -1
- package/dist/embed.d.ts +3 -0
- package/dist/embed.js +3 -3
- package/dist/embed.js.map +1 -1
- package/dist/i18n.d.ts +41 -0
- package/dist/index.d.ts +8 -13
- package/dist/index.js +389 -370
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +7 -3
- package/dist/react.js +322 -312
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var Be = Object.defineProperty;
|
|
2
|
-
var $e = (t, e,
|
|
3
|
-
var C = (t, e,
|
|
4
|
-
import { l as Re, b as ve, p as Me, r as Ae,
|
|
5
|
-
import { h as
|
|
6
|
-
import { P as
|
|
7
|
-
import { e as
|
|
8
|
-
import { E2ESession as
|
|
9
|
-
const
|
|
2
|
+
var $e = (t, e, d) => e in t ? Be(t, e, { enumerable: !0, configurable: !0, writable: !0, value: d }) : t[e] = d;
|
|
3
|
+
var C = (t, e, d) => $e(t, typeof e != "symbol" ? e + "" : e, d);
|
|
4
|
+
import { l as Re, b as ve, p as Me, r as Ae, c as qe, a as Ne, m as Oe } from "./chatlist2.js";
|
|
5
|
+
import { h as ut } from "./chatlist2.js";
|
|
6
|
+
import { P as De, C as He, b as _e } from "./outbox.js";
|
|
7
|
+
import { e as ft } from "./outbox.js";
|
|
8
|
+
import { E2ESession as Ue, extractX3DHInit as Fe } from "./e2e.js";
|
|
9
|
+
const We = `
|
|
10
10
|
.ocw { ${Re("ocw")}
|
|
11
11
|
position:relative;
|
|
12
12
|
display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
|
|
@@ -197,30 +197,47 @@ const Fe = `
|
|
|
197
197
|
.ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
|
|
198
198
|
.ocw-translation { margin-top:6px; padding-top:6px; border-top:1px solid var(--ocw-line); font-size:13px; line-height:1.45; }
|
|
199
199
|
.ocw-translation::before { content:'🌐 '; opacity:.75; }
|
|
200
|
-
`, ke = "objectchat-widget-styles",
|
|
201
|
-
function
|
|
200
|
+
`, ke = "objectchat-widget-styles", Ge = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Ke = 400, Ve = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
201
|
+
function Ye() {
|
|
202
202
|
if (typeof document > "u" || document.getElementById(ke)) return;
|
|
203
203
|
const t = document.createElement("style");
|
|
204
|
-
t.id = ke, t.textContent =
|
|
204
|
+
t.id = ke, t.textContent = We, document.head.appendChild(t);
|
|
205
205
|
}
|
|
206
206
|
const Ce = "ocw-webfont";
|
|
207
|
-
function
|
|
207
|
+
function Xe() {
|
|
208
208
|
if (typeof document > "u" || document.getElementById(Ce)) return;
|
|
209
209
|
const t = document.createElement("link");
|
|
210
210
|
t.id = Ce, t.rel = "stylesheet", t.href = "https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700&family=Nunito:wght@400;500;600;700&display=swap", document.head.appendChild(t);
|
|
211
211
|
}
|
|
212
|
-
function n(t, e,
|
|
213
|
-
const
|
|
214
|
-
return e && (
|
|
212
|
+
function n(t, e, d) {
|
|
213
|
+
const s = document.createElement(t);
|
|
214
|
+
return e && (s.className = e), d !== void 0 && (s.textContent = d), s;
|
|
215
|
+
}
|
|
216
|
+
function Qe(t, e) {
|
|
217
|
+
const d = /(https?:\/\/[^\s]+)/g;
|
|
218
|
+
let s = 0, c = null, h;
|
|
219
|
+
for (; (h = d.exec(e)) !== null; ) {
|
|
220
|
+
if (h.index > s) {
|
|
221
|
+
const a = document.createTextNode(e.slice(s, h.index));
|
|
222
|
+
t.append(a), c ?? (c = a);
|
|
223
|
+
}
|
|
224
|
+
let y = h[0], l = "";
|
|
225
|
+
const u = /[).,!?;:]+$/.exec(y);
|
|
226
|
+
u && (l = u[0], y = y.slice(0, -l.length));
|
|
227
|
+
const x = document.createElement("a");
|
|
228
|
+
x.href = y, x.target = "_blank", x.rel = "noopener noreferrer", x.textContent = y, x.style.cssText = "color:inherit;text-decoration:underline;word-break:break-all", t.append(x), l && t.append(document.createTextNode(l)), s = h.index + h[0].length;
|
|
229
|
+
}
|
|
230
|
+
const b = document.createTextNode(e.slice(s));
|
|
231
|
+
return t.append(b), c ?? (c = b), c;
|
|
215
232
|
}
|
|
216
|
-
function
|
|
233
|
+
function Je(t) {
|
|
217
234
|
try {
|
|
218
235
|
return new Date(t).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
219
236
|
} catch {
|
|
220
237
|
return "";
|
|
221
238
|
}
|
|
222
239
|
}
|
|
223
|
-
function
|
|
240
|
+
function re(t) {
|
|
224
241
|
var e;
|
|
225
242
|
switch (t.kind) {
|
|
226
243
|
case "text":
|
|
@@ -237,9 +254,9 @@ function se(t) {
|
|
|
237
254
|
return `📅 ${t.title} — ${new Date(t.startIso).toLocaleString()}`;
|
|
238
255
|
}
|
|
239
256
|
}
|
|
240
|
-
class
|
|
257
|
+
class Ze {
|
|
241
258
|
/** Last seq the guest has seen per conversationId — used to compute unread badges. */
|
|
242
|
-
constructor(e,
|
|
259
|
+
constructor(e, d, s, c = {}) {
|
|
243
260
|
C(this, "scroll");
|
|
244
261
|
C(this, "chips");
|
|
245
262
|
C(this, "typing");
|
|
@@ -274,58 +291,58 @@ class Qe {
|
|
|
274
291
|
/** Whether the subject card (server Subject entity, mount config fallback)
|
|
275
292
|
* has been built — built once when data first arrives. */
|
|
276
293
|
C(this, "subjectBuilt", !1);
|
|
277
|
-
var z, O, T, _,
|
|
278
|
-
this.root = e, this.me =
|
|
279
|
-
const
|
|
280
|
-
|
|
294
|
+
var z, O, T, _, r, i, v, f, m, k, S;
|
|
295
|
+
this.root = e, this.me = d, this.h = s, this.cfg = c, Ye(), c.webfont !== !1 && Xe(), e.replaceChildren(), e.classList.add("ocw"), c.accent && e.style.setProperty("--ocw-accent", c.accent);
|
|
296
|
+
const h = c.accent2 ?? c.accent;
|
|
297
|
+
h && e.style.setProperty("--ocw-accent2", h), this.cfgAccent2 = c.accent2, e.dataset.theme = c.theme ?? "light";
|
|
281
298
|
const b = n("div", "ocw-head");
|
|
282
299
|
if (this.h.onBack) {
|
|
283
|
-
const
|
|
284
|
-
|
|
300
|
+
const w = n("button", "ocw-back", "‹");
|
|
301
|
+
w.type = "button", w.setAttribute("aria-label", "Back"), w.addEventListener("click", () => this.h.onBack()), b.append(w);
|
|
285
302
|
}
|
|
286
|
-
const y = ((z =
|
|
287
|
-
y.trim() && (
|
|
288
|
-
const
|
|
289
|
-
this.headerName = n("div", "ocw-head-name", ((T =
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
for (const
|
|
293
|
-
const I = n("button", void 0,
|
|
303
|
+
const y = ((z = c.subject) == null ? void 0 : z.ownerLabel) ?? ((O = c.subject) == null ? void 0 : O.title) ?? "", l = n("div", "ocw-avatar");
|
|
304
|
+
y.trim() && (l.textContent = y.trim()[0].toUpperCase(), b.append(l));
|
|
305
|
+
const u = n("div", "ocw-head-main");
|
|
306
|
+
this.headerName = n("div", "ocw-head-name", ((T = c.subject) == null ? void 0 : T.ownerLabel) ?? ((_ = c.subject) == null ? void 0 : _.title) ?? ""), u.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", u.append(this.headStatus), (r = c.subject) != null && r.subtitle && u.append(n("div", "ocw-head-meta", c.subject.subtitle)), b.append(u), this.statusBadge = n("span", "ocw-badge", ((i = c.subject) == null ? void 0 : i.status) ?? ""), (v = c.subject) != null && v.status || (this.statusBadge.style.display = "none"), b.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", b.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", b.append(this.connStatus), b.append(n("button", "ocw-menu", "⋯")), this.chips = n("div", "ocw-chiprow"), this.scroll = n("div", "ocw-scroll"), this.subjectCard = n("div", "ocw-subject"), this.typing = n("div", "ocw-typing");
|
|
307
|
+
const x = n("div", "ocw-typing-bubble");
|
|
308
|
+
x.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(x), this.quick = n("div", "ocw-quick");
|
|
309
|
+
for (const w of c.quickReplies ?? []) {
|
|
310
|
+
const I = n("button", void 0, w);
|
|
294
311
|
I.addEventListener("click", () => {
|
|
295
|
-
this.h.onSend(
|
|
312
|
+
this.h.onSend(w), this.quick.style.display = "none";
|
|
296
313
|
}), this.quick.append(I);
|
|
297
314
|
}
|
|
298
|
-
this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
const j = (
|
|
302
|
-
j ? (
|
|
303
|
-
var
|
|
304
|
-
this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((N) => N.senderRole === "guest") ? (I = (
|
|
305
|
-
}), this.input.addEventListener("keydown", (
|
|
306
|
-
|
|
315
|
+
this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((f = c.i18n) == null ? void 0 : f.placeholder) ?? "Message…";
|
|
316
|
+
const a = n("button", "ocw-sendbtn");
|
|
317
|
+
a.type = "button";
|
|
318
|
+
const j = (m = c.i18n) == null ? void 0 : m.send;
|
|
319
|
+
j ? (a.textContent = j, a.classList.add("ocw-sendbtn-label"), a.setAttribute("aria-label", j)) : (a.innerHTML = Ve, a.setAttribute("aria-label", "Send message")), a.disabled = !0, this.sendBtn = a, a.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
|
|
320
|
+
var w, I;
|
|
321
|
+
this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((N) => N.senderRole === "guest") ? (I = (w = this.h).onDeflectQuery) == null || I.call(w, this.input.value) : this.hideDeflection();
|
|
322
|
+
}), this.input.addEventListener("keydown", (w) => {
|
|
323
|
+
w.isComposing || w.keyCode === 229 || (w.key === "Enter" && !w.shiftKey ? (w.preventDefault(), this.flushSend()) : this.signalTyping());
|
|
307
324
|
});
|
|
308
325
|
const R = n("button", "ocw-attach", "📎");
|
|
309
326
|
R.title = "Attach image or file";
|
|
310
327
|
const E = document.createElement("input");
|
|
311
328
|
E.type = "file", E.accept = "image/*,.pdf,.txt,.doc,.docx", E.style.display = "none", R.addEventListener("click", () => E.click()), E.addEventListener("change", () => {
|
|
312
|
-
var
|
|
313
|
-
(
|
|
329
|
+
var w;
|
|
330
|
+
(w = E.files) != null && w[0] && this.h.onAttach && this.h.onAttach(E.files[0]), E.value = "";
|
|
314
331
|
});
|
|
315
332
|
const A = n("div", "ocw-input");
|
|
316
|
-
A.append(R, E, this.input,
|
|
333
|
+
A.append(R, E, this.input, a);
|
|
317
334
|
const P = n("div", "ocw-footer");
|
|
318
|
-
((k =
|
|
335
|
+
((k = c.i18n) == null ? void 0 : k.poweredBy) !== void 0 ? P.textContent = c.i18n.poweredBy : P.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = P, this.reopenBtn = n("button", "ocw-reopen", ((S = this.cfg.i18n) == null ? void 0 : S.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
|
|
319
336
|
this.reopenBtn.style.display = "none";
|
|
320
|
-
const
|
|
321
|
-
|
|
337
|
+
const w = this.root.querySelector(".ocw-input textarea");
|
|
338
|
+
w == null || w.focus();
|
|
322
339
|
}), e.append(b, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, A, this.reopenBtn, this.footer);
|
|
323
|
-
const B = (
|
|
324
|
-
e.classList.toggle("ocw-compact",
|
|
340
|
+
const B = (w) => {
|
|
341
|
+
e.classList.toggle("ocw-compact", w > 0 && w < Ke);
|
|
325
342
|
};
|
|
326
|
-
B(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((
|
|
343
|
+
B(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((w) => {
|
|
327
344
|
var N;
|
|
328
|
-
const I = ((N =
|
|
345
|
+
const I = ((N = w[0]) == null ? void 0 : N.contentRect.width) ?? e.clientWidth;
|
|
329
346
|
B(I);
|
|
330
347
|
}), this.compactObserver.observe(e));
|
|
331
348
|
}
|
|
@@ -335,13 +352,13 @@ class Qe {
|
|
|
335
352
|
}
|
|
336
353
|
/** Registers a cleanup fn removed on destroy() to prevent listener leaks. */
|
|
337
354
|
setScrollCleanup(e) {
|
|
338
|
-
var
|
|
339
|
-
(
|
|
355
|
+
var d;
|
|
356
|
+
(d = this.scrollCleanup) == null || d.call(this), this.scrollCleanup = e;
|
|
340
357
|
}
|
|
341
358
|
/** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */
|
|
342
359
|
destroy() {
|
|
343
|
-
var e,
|
|
344
|
-
(e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (
|
|
360
|
+
var e, d;
|
|
361
|
+
(e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (d = this.compactObserver) == null || d.disconnect(), this.compactObserver = null;
|
|
345
362
|
}
|
|
346
363
|
flushSend() {
|
|
347
364
|
this.hideDeflection();
|
|
@@ -367,37 +384,37 @@ class Qe {
|
|
|
367
384
|
render(e) {
|
|
368
385
|
var E, A, P, B, z, O, T, _;
|
|
369
386
|
if (this.storeRef = e, e.accent && (this.root.style.setProperty("--ocw-accent", e.accent), this.root.style.setProperty("--ocw-accent2", this.cfgAccent2 ?? e.accent)), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
|
|
370
|
-
const
|
|
371
|
-
|
|
387
|
+
const r = (E = this.cfg.subject) == null ? void 0 : E.ownerLabel;
|
|
388
|
+
r && (this.headerName.textContent = r);
|
|
372
389
|
}
|
|
373
390
|
this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
|
|
374
|
-
const
|
|
375
|
-
this.chips.style.display =
|
|
376
|
-
for (const
|
|
377
|
-
const
|
|
391
|
+
const d = e.visibleActions();
|
|
392
|
+
this.chips.style.display = d.length ? "flex" : "none";
|
|
393
|
+
for (const r of d) this.chips.append(this.chipEl(r));
|
|
394
|
+
const s = this.scroll.scrollHeight, c = this.scroll.scrollTop;
|
|
378
395
|
if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
|
|
379
|
-
const
|
|
380
|
-
|
|
396
|
+
const r = n("div", "ocw-load-more");
|
|
397
|
+
r.textContent = "↑ Loading earlier messages…", r.style.pointerEvents = "none", this.scroll.append(r);
|
|
381
398
|
}
|
|
382
|
-
let
|
|
399
|
+
let h = 0, b = null;
|
|
383
400
|
const y = [...e.messages()];
|
|
384
|
-
for (let
|
|
385
|
-
const i = y[
|
|
386
|
-
this.scroll.append(this.messageEl(i, e, v,
|
|
401
|
+
for (let r = 0; r < y.length; r++) {
|
|
402
|
+
const i = y[r], v = i.senderRole !== "system" && i.senderId !== this.me && !i.internal && i.senderId !== b;
|
|
403
|
+
this.scroll.append(this.messageEl(i, e, v, r === y.length - 1)), i.senderRole !== "system" && (b = i.senderId), i.senderId !== this.me && i.seq > h && (h = i.seq);
|
|
387
404
|
}
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
this.typing.classList.toggle("active",
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
const
|
|
394
|
-
if (!!((A = e.preChat) != null && A.enabled) && !this.preChatDone && !
|
|
405
|
+
c > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + c : this.scroll.scrollTop = this.scroll.scrollHeight, h > 0 && this.h.onReadUpTo(h);
|
|
406
|
+
const l = [...e.typing];
|
|
407
|
+
this.typing.classList.toggle("active", l.length > 0);
|
|
408
|
+
const u = this.typing.querySelector(".ocw-typing-bubble");
|
|
409
|
+
u && u.setAttribute("aria-label", l.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
|
|
410
|
+
const x = e.messages().some((r) => r.senderRole === "guest");
|
|
411
|
+
if (!!((A = e.preChat) != null && A.enabled) && !this.preChatDone && !x && (e.preChat.showWhen !== "offline" || e.offline))
|
|
395
412
|
this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (P = this.root.querySelector(".ocw-input")) == null || P.style.setProperty("display", "none");
|
|
396
413
|
else {
|
|
397
414
|
if (this.preChatPanel.style.display = "none", e.offline) {
|
|
398
415
|
this.awayNotice.firstChild || this.awayNotice.append(n("span", "ocw-away-icon", "🌙"), n("span", "", ""));
|
|
399
|
-
const
|
|
400
|
-
|
|
416
|
+
const r = this.awayNotice.lastChild;
|
|
417
|
+
r.textContent = e.offlineMessage || ((B = this.cfg.i18n) == null ? void 0 : B.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
|
|
401
418
|
} else
|
|
402
419
|
this.awayNotice.style.display = "none";
|
|
403
420
|
(z = this.root.querySelector(".ocw-input")) == null || z.style.removeProperty("display");
|
|
@@ -406,69 +423,69 @@ class Qe {
|
|
|
406
423
|
this.h.onCsat && !this.csatSubmitted && j.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
|
|
407
424
|
const R = j.includes(e.state);
|
|
408
425
|
if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((O = this.cfg.i18n) == null ? void 0 : O.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((T = this.cfg.i18n) == null ? void 0 : T.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", R && e.messages().length > 0) {
|
|
409
|
-
const
|
|
410
|
-
this.scroll.append(
|
|
426
|
+
const r = n("div", "ocw-resolved-note", `— ${((_ = this.cfg.i18n) == null ? void 0 : _.resolved) ?? "Marked as resolved"} —`);
|
|
427
|
+
this.scroll.append(r), this.reopenBtn.style.display = "block";
|
|
411
428
|
} else
|
|
412
429
|
this.reopenBtn.style.display = "none";
|
|
413
430
|
}
|
|
414
|
-
setConnStatus(e,
|
|
431
|
+
setConnStatus(e, d) {
|
|
415
432
|
if (e === "open") {
|
|
416
433
|
this.connStatus.style.display = "none";
|
|
417
434
|
return;
|
|
418
435
|
}
|
|
419
436
|
this.connStatus.style.display = "";
|
|
420
|
-
const
|
|
421
|
-
this.connStatus.className = `ocw-conn-status${
|
|
437
|
+
const s = e === "error";
|
|
438
|
+
this.connStatus.className = `ocw-conn-status${s ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = s ? `⚠ ${d ?? "Chat unavailable"}` : e === "reconnecting" ? d ?? "↻ reconnecting…" : "● connecting…";
|
|
422
439
|
}
|
|
423
440
|
buildPreChatPanel(e) {
|
|
424
|
-
var
|
|
441
|
+
var l;
|
|
425
442
|
this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(n("div", "ocw-prechat-title", e.title ?? "Before we start…"));
|
|
426
|
-
const
|
|
427
|
-
for (const
|
|
428
|
-
const
|
|
429
|
-
|
|
443
|
+
const d = n("div", "ocw-offline-form"), s = {};
|
|
444
|
+
for (const u of e.fields ?? ["name", "email"]) {
|
|
445
|
+
const x = n("input", "ocw-offline-input");
|
|
446
|
+
x.type = u === "email" ? "email" : u === "phone" ? "tel" : "text", x.placeholder = u === "name" ? "Your name" : u === "email" ? "Your email" : "Your phone number", s[u] = x, d.append(x);
|
|
430
447
|
}
|
|
431
|
-
let
|
|
432
|
-
if ((
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
for (const
|
|
437
|
-
const
|
|
438
|
-
|
|
448
|
+
let c = null;
|
|
449
|
+
if ((l = e.topics) != null && l.length) {
|
|
450
|
+
c = n("select", void 0);
|
|
451
|
+
const u = document.createElement("option");
|
|
452
|
+
u.value = "", u.textContent = "What is this about?", c.append(u);
|
|
453
|
+
for (const x of e.topics) {
|
|
454
|
+
const a = document.createElement("option");
|
|
455
|
+
a.value = x, a.textContent = x, c.append(a);
|
|
439
456
|
}
|
|
440
|
-
|
|
457
|
+
d.append(c);
|
|
441
458
|
}
|
|
442
|
-
let
|
|
459
|
+
let h = null, b = null;
|
|
443
460
|
if (e.callbackOption) {
|
|
444
|
-
const
|
|
445
|
-
|
|
461
|
+
const u = n("label", "ocw-prechat-cb");
|
|
462
|
+
h = document.createElement("input"), h.type = "checkbox", u.append(h, document.createTextNode("📞 Request a call back")), d.append(u), s.phone || (b = n("input", "ocw-offline-input"), b.type = "tel", b.placeholder = "Phone number for the call", b.style.display = "none", h.addEventListener("change", () => b.style.setProperty("display", h.checked ? "block" : "none")), d.append(b));
|
|
446
463
|
}
|
|
447
464
|
const y = n("button", "ocw-offline-submit", "Start chat");
|
|
448
465
|
y.type = "button", y.addEventListener("click", () => {
|
|
449
466
|
var j, R, E, A, P, B, z;
|
|
450
|
-
const
|
|
451
|
-
if (
|
|
452
|
-
|
|
467
|
+
const u = (j = s.email) == null ? void 0 : j.value.trim();
|
|
468
|
+
if (s.email && (!u || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(u))) {
|
|
469
|
+
s.email.focus();
|
|
453
470
|
return;
|
|
454
471
|
}
|
|
455
|
-
const
|
|
456
|
-
if (
|
|
457
|
-
(E =
|
|
472
|
+
const x = !!(h != null && h.checked), a = (((R = s.phone) == null ? void 0 : R.value) ?? (b == null ? void 0 : b.value) ?? "").trim();
|
|
473
|
+
if (x && !a) {
|
|
474
|
+
(E = s.phone ?? b) == null || E.focus();
|
|
458
475
|
return;
|
|
459
476
|
}
|
|
460
|
-
if (
|
|
461
|
-
|
|
477
|
+
if (c && ((A = e.topics) != null && A.length) && !c.value) {
|
|
478
|
+
c.focus();
|
|
462
479
|
return;
|
|
463
480
|
}
|
|
464
481
|
y.disabled = !0, this.completePreChat(), (z = (B = this.h).onPreChat) == null || z.call(B, {
|
|
465
|
-
...(P =
|
|
466
|
-
...
|
|
467
|
-
...
|
|
468
|
-
...
|
|
469
|
-
...
|
|
482
|
+
...(P = s.name) != null && P.value.trim() ? { name: s.name.value.trim() } : {},
|
|
483
|
+
...u ? { email: u } : {},
|
|
484
|
+
...a ? { phone: a } : {},
|
|
485
|
+
...c != null && c.value ? { topic: c.value } : {},
|
|
486
|
+
...x ? { callback: !0 } : {}
|
|
470
487
|
});
|
|
471
|
-
}),
|
|
488
|
+
}), d.append(y), this.preChatPanel.append(d);
|
|
472
489
|
}
|
|
473
490
|
/** Mark pre-chat complete (submitted now or in a previous session). */
|
|
474
491
|
completePreChat() {
|
|
@@ -478,9 +495,9 @@ class Qe {
|
|
|
478
495
|
showDeflection(e) {
|
|
479
496
|
if (!e.length) return this.hideDeflection();
|
|
480
497
|
this.deflectPanel.replaceChildren(), this.deflectPanel.append(n("div", "ocw-deflect-hint", "Instant answers — tap to expand"));
|
|
481
|
-
for (const
|
|
482
|
-
const
|
|
483
|
-
|
|
498
|
+
for (const d of e.slice(0, 3)) {
|
|
499
|
+
const s = n("button", "ocw-deflect-card");
|
|
500
|
+
s.append(n("div", "ocw-deflect-q", d.title), n("div", "ocw-deflect-a", d.answer)), s.addEventListener("click", () => s.classList.toggle("open")), this.deflectPanel.append(s);
|
|
484
501
|
}
|
|
485
502
|
this.deflectPanel.style.display = "flex";
|
|
486
503
|
}
|
|
@@ -489,266 +506,266 @@ class Qe {
|
|
|
489
506
|
}
|
|
490
507
|
buildCsatPanel() {
|
|
491
508
|
this.csatPanel.replaceChildren(), this.csatPanel.append(n("div", "ocw-csat-title", "How did we do?"));
|
|
492
|
-
const e = n("div", "ocw-csat-stars"),
|
|
493
|
-
for (let
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
var
|
|
497
|
-
this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${
|
|
498
|
-
}),
|
|
509
|
+
const e = n("div", "ocw-csat-stars"), d = [];
|
|
510
|
+
for (let s = 1; s <= 5; s++) {
|
|
511
|
+
const c = n("button", "ocw-csat-star", "★");
|
|
512
|
+
c.dataset.score = String(s), c.addEventListener("mouseenter", () => d.forEach((h, b) => h.classList.toggle("lit", b < s))), c.addEventListener("mouseleave", () => d.forEach((h) => h.classList.remove("lit"))), c.addEventListener("click", () => {
|
|
513
|
+
var h, b;
|
|
514
|
+
this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (b = (h = this.h).onCsat) == null || b.call(h, s);
|
|
515
|
+
}), d.push(c), e.append(c);
|
|
499
516
|
}
|
|
500
517
|
this.csatPanel.append(e);
|
|
501
518
|
}
|
|
502
519
|
buildSubjectCard(e) {
|
|
503
520
|
if (this.subjectBuilt) return;
|
|
504
|
-
const
|
|
505
|
-
if (!
|
|
506
|
-
this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title",
|
|
507
|
-
const
|
|
508
|
-
if (
|
|
509
|
-
else for (const y of (
|
|
510
|
-
|
|
511
|
-
const b = (
|
|
521
|
+
const d = e.subject, s = this.cfg.subject, c = (d == null ? void 0 : d.title) ?? (s == null ? void 0 : s.title);
|
|
522
|
+
if (!c) return;
|
|
523
|
+
this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", c)), s != null && s.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", s.subtitle));
|
|
524
|
+
const h = n("div", "ocw-tags");
|
|
525
|
+
if (d) for (const [y, l] of Object.entries(d.fields)) h.append(n("span", "ocw-tag", `${y}: ${l}`));
|
|
526
|
+
else for (const y of (s == null ? void 0 : s.tags) ?? []) h.append(n("span", "ocw-tag", y));
|
|
527
|
+
h.childNodes.length && this.subjectCard.append(h);
|
|
528
|
+
const b = (d == null ? void 0 : d.state) ?? (s == null ? void 0 : s.status);
|
|
512
529
|
b && (this.statusBadge.textContent = b, this.statusBadge.style.display = "inline-flex");
|
|
513
530
|
}
|
|
514
531
|
chipEl(e) {
|
|
515
|
-
const
|
|
516
|
-
return
|
|
517
|
-
var
|
|
518
|
-
e.confirm && !await this.confirm(e.label) || ((
|
|
519
|
-
}),
|
|
532
|
+
const d = n("button", "ocw-chip", e.icon ? `${e.icon} ${e.label}` : e.label);
|
|
533
|
+
return d.dataset.actionId = e.id, d.addEventListener("click", async () => {
|
|
534
|
+
var s;
|
|
535
|
+
e.confirm && !await this.confirm(e.label) || ((s = e.input) != null && s.length ? this.openForm(e) : this.h.onInvoke(e.id));
|
|
536
|
+
}), d;
|
|
520
537
|
}
|
|
521
538
|
/** In-widget confirmation modal (replaces window.confirm). */
|
|
522
539
|
confirm(e) {
|
|
523
|
-
return new Promise((
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
540
|
+
return new Promise((d) => {
|
|
541
|
+
const s = n("div", "ocw-modal"), c = n("div", "ocw-modal-card");
|
|
542
|
+
c.append(n("div", "ocw-modal-title", e)), c.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
|
|
543
|
+
const h = n("div", "ocw-modal-actions"), b = n("button", "ocw-modal-cancel", "Cancel"), y = n("button", "ocw-modal-ok", "Confirm"), l = (u) => {
|
|
544
|
+
s.remove(), d(u);
|
|
528
545
|
};
|
|
529
|
-
b.addEventListener("click", () =>
|
|
530
|
-
|
|
531
|
-
}),
|
|
546
|
+
b.addEventListener("click", () => l(!1)), y.addEventListener("click", () => l(!0)), s.addEventListener("click", (u) => {
|
|
547
|
+
u.target === s && l(!1);
|
|
548
|
+
}), h.append(b, y), c.append(h), s.append(c), this.root.append(s), y.focus();
|
|
532
549
|
});
|
|
533
550
|
}
|
|
534
551
|
/** Inline form for a form-effect action: typed inputs (date picker, number,
|
|
535
552
|
* text) rendered above the composer — no browser prompts. */
|
|
536
553
|
openForm(e) {
|
|
537
|
-
var y,
|
|
554
|
+
var y, l;
|
|
538
555
|
this.formHost.replaceChildren();
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
const
|
|
542
|
-
for (const
|
|
543
|
-
const
|
|
544
|
-
if (
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
for (const j of
|
|
556
|
+
const d = n("div", "ocw-form");
|
|
557
|
+
d.append(n("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
|
|
558
|
+
const s = /* @__PURE__ */ new Map();
|
|
559
|
+
for (const u of e.input ?? []) {
|
|
560
|
+
const x = n("label", "ocw-form-row");
|
|
561
|
+
if (x.append(n("span", "ocw-form-lbl", u.label)), u.type === "select" && ((y = u.options) != null && y.length)) {
|
|
562
|
+
const a = n("select", "ocw-form-input");
|
|
563
|
+
u.required || a.append(n("option", void 0, "— select —"));
|
|
564
|
+
for (const j of u.options) {
|
|
548
565
|
const R = n("option");
|
|
549
|
-
R.value = j, R.textContent = j,
|
|
566
|
+
R.value = j, R.textContent = j, a.append(R);
|
|
550
567
|
}
|
|
551
|
-
|
|
568
|
+
u.required && (a.required = !0), x.append(a), s.set(u.name, a);
|
|
552
569
|
} else {
|
|
553
|
-
const
|
|
554
|
-
|
|
570
|
+
const a = n("input", "ocw-form-input");
|
|
571
|
+
a.type = u.type === "number" ? "number" : u.type === "date" ? "datetime-local" : "text", u.required && (a.required = !0), x.append(a), s.set(u.name, a);
|
|
555
572
|
}
|
|
556
|
-
|
|
573
|
+
d.append(x);
|
|
557
574
|
}
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
const
|
|
561
|
-
for (const [
|
|
562
|
-
if (
|
|
563
|
-
|
|
575
|
+
const c = n("div", "ocw-form-actions"), h = n("button", "ocw-form-cancel", "Cancel"), b = n("button", "ocw-form-submit", "Send");
|
|
576
|
+
h.addEventListener("click", () => this.formHost.replaceChildren()), b.addEventListener("click", () => {
|
|
577
|
+
const u = {};
|
|
578
|
+
for (const [x, a] of s) {
|
|
579
|
+
if (a.required && !a.value) {
|
|
580
|
+
a.style.borderColor = "#e5484d";
|
|
564
581
|
return;
|
|
565
582
|
}
|
|
566
|
-
|
|
583
|
+
u[x] = a.type === "number" ? Number(a.value) : a.value;
|
|
567
584
|
}
|
|
568
|
-
this.formHost.replaceChildren(), this.h.onInvoke(e.id,
|
|
569
|
-
}),
|
|
585
|
+
this.formHost.replaceChildren(), this.h.onInvoke(e.id, u);
|
|
586
|
+
}), c.append(h, b), d.append(c), this.formHost.append(d), (l = s.values().next().value) == null || l.focus();
|
|
570
587
|
}
|
|
571
|
-
messageEl(e,
|
|
588
|
+
messageEl(e, d, s = !1, c = !1) {
|
|
572
589
|
var R, E, A, P, B, z, O, T, _;
|
|
573
590
|
if (e.senderRole === "system") {
|
|
574
|
-
const
|
|
575
|
-
return
|
|
591
|
+
const r = n("div", "ocw-sys");
|
|
592
|
+
return r.textContent = e.deletedAt ? "message deleted" : re(e.content), r;
|
|
576
593
|
}
|
|
577
|
-
const
|
|
578
|
-
if (
|
|
579
|
-
const
|
|
580
|
-
|
|
594
|
+
const h = e.senderId === this.me, b = !!e.internal, y = n("div", `ocw-row ${b ? "ocw-note mine" : h ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`), l = n("div");
|
|
595
|
+
if (s) {
|
|
596
|
+
const r = e.senderRole === "bot" ? ((R = this.cfg.i18n) == null ? void 0 : R.aiAssistant) ?? "AI Assistant" : ((E = this.cfg.subject) == null ? void 0 : E.ownerLabel) ?? ((A = this.cfg.subject) == null ? void 0 : A.title) ?? "Support";
|
|
597
|
+
l.append(n("div", "ocw-msg-sender", r));
|
|
581
598
|
}
|
|
582
|
-
const
|
|
599
|
+
const u = n("div", "ocw-bubble-wrap");
|
|
583
600
|
if (e.replyToId) {
|
|
584
|
-
const
|
|
585
|
-
|
|
601
|
+
const r = n("div", "ocw-reply-to", "↩ replying to a message");
|
|
602
|
+
r.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", l.append(r);
|
|
586
603
|
}
|
|
587
|
-
const
|
|
588
|
-
let
|
|
589
|
-
if (e.deletedAt)
|
|
604
|
+
const x = n("div", "ocw-bubble");
|
|
605
|
+
let a = null;
|
|
606
|
+
if (e.deletedAt) x.append(n("span", "ocw-deleted", "message deleted"));
|
|
590
607
|
else if (e.content.kind === "attachment") {
|
|
591
|
-
const
|
|
592
|
-
if ((P =
|
|
608
|
+
const r = e.content;
|
|
609
|
+
if ((P = r.mime) != null && P.startsWith("image/")) {
|
|
593
610
|
const i = document.createElement("img");
|
|
594
|
-
i.src =
|
|
595
|
-
} else if ((B =
|
|
611
|
+
i.src = r.url, i.alt = r.name ?? "image", i.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", i.addEventListener("click", () => window.open(r.url, "_blank")), x.append(i);
|
|
612
|
+
} else if ((B = r.mime) != null && B.startsWith("video/")) {
|
|
596
613
|
const i = document.createElement("video");
|
|
597
|
-
i.src =
|
|
614
|
+
i.src = r.url, i.controls = !0, i.style.cssText = "max-width:240px;max-height:180px;border-radius:10px;display:block", x.append(i);
|
|
598
615
|
} else {
|
|
599
616
|
const i = document.createElement("a");
|
|
600
|
-
i.href =
|
|
617
|
+
i.href = r.url, i.target = "_blank", i.rel = "noopener", i.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", i.append(n("span", void 0, "📄"), n("span", void 0, r.name ?? "file")), x.append(i);
|
|
601
618
|
}
|
|
602
619
|
} else if (e.content.kind === "appointment") {
|
|
603
|
-
const
|
|
604
|
-
i.append(n("div", "ocw-appt-title", `📅 ${
|
|
605
|
-
const v = n("div", "ocw-appt-links"),
|
|
606
|
-
|
|
607
|
-
const
|
|
608
|
-
|
|
620
|
+
const r = e.content, i = n("div", "ocw-appt");
|
|
621
|
+
i.append(n("div", "ocw-appt-title", `📅 ${r.title}`)), i.append(n("div", "ocw-appt-time", new Date(r.startIso).toLocaleString() + " – " + new Date(r.endIso).toLocaleTimeString())), r.location && i.append(n("div", "ocw-appt-loc", `📍 ${r.location}`)), r.description && i.append(n("div", "ocw-appt-desc", r.description));
|
|
622
|
+
const v = n("div", "ocw-appt-links"), f = document.createElement("a");
|
|
623
|
+
f.href = r.googleUrl, f.target = "_blank", f.rel = "noopener", f.className = "ocw-appt-btn", f.textContent = "📅 Add to Google Calendar";
|
|
624
|
+
const m = document.createElement("a");
|
|
625
|
+
m.href = r.icalUrl, m.download = `${r.title}.ics`, m.className = "ocw-appt-btn ocw-appt-btn-sec", m.textContent = "🍎 Apple / iCal", v.append(f, m), i.append(v), x.append(i);
|
|
609
626
|
} else
|
|
610
|
-
|
|
611
|
-
if (
|
|
612
|
-
const
|
|
613
|
-
|
|
627
|
+
a = Qe(x, re(e.content)), e.editedAt && x.append(n("span", "ocw-edited", "(edited)"));
|
|
628
|
+
if (u.append(x), c && !e.deletedAt && e.content.kind === "text" && ((z = e.content.quickReplies) != null && z.length)) {
|
|
629
|
+
const r = n("div", "ocw-flow-choices");
|
|
630
|
+
r.style.cssText = "display:flex;flex-wrap:wrap;gap:6px;margin-top:6px";
|
|
614
631
|
for (const i of e.content.quickReplies) {
|
|
615
632
|
const v = n("button", "ocw-flow-choice", i);
|
|
616
633
|
v.type = "button", v.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:var(--ocw-bg,#fff);color:inherit;border-radius:14px;padding:5px 12px;font:inherit;font-size:13px;cursor:pointer", v.addEventListener("click", () => {
|
|
617
|
-
|
|
618
|
-
}),
|
|
634
|
+
r.querySelectorAll("button").forEach((f) => f.disabled = !0), r.style.opacity = "0.5", this.h.onSend(i);
|
|
635
|
+
}), r.append(v);
|
|
619
636
|
}
|
|
620
|
-
|
|
637
|
+
u.append(r);
|
|
621
638
|
}
|
|
622
|
-
if (!
|
|
623
|
-
const
|
|
624
|
-
if (
|
|
639
|
+
if (!h && !b && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && a) {
|
|
640
|
+
const r = e.content.text;
|
|
641
|
+
if (r.trim()) {
|
|
625
642
|
const i = n("button", "ocw-translate-btn", "🌐");
|
|
626
643
|
i.type = "button", i.title = "Translate";
|
|
627
644
|
const v = n("div", "ocw-translation");
|
|
628
|
-
v.style.display = "none",
|
|
629
|
-
const
|
|
645
|
+
v.style.display = "none", x.append(v);
|
|
646
|
+
const f = (S) => {
|
|
630
647
|
v.textContent = S, v.style.display = "", this.showingTranslation.add(e.id), i.textContent = "↩", i.title = "Show original";
|
|
631
|
-
},
|
|
648
|
+
}, m = () => {
|
|
632
649
|
v.style.display = "none", this.showingTranslation.delete(e.id), i.textContent = "🌐", i.title = "Translate";
|
|
633
650
|
};
|
|
634
651
|
i.addEventListener("click", (S) => {
|
|
635
652
|
if (S.stopPropagation(), this.showingTranslation.has(e.id)) {
|
|
636
|
-
|
|
653
|
+
m();
|
|
637
654
|
return;
|
|
638
655
|
}
|
|
639
|
-
const
|
|
640
|
-
if (
|
|
641
|
-
|
|
656
|
+
const w = this.translationCache.get(e.id);
|
|
657
|
+
if (w !== void 0) {
|
|
658
|
+
f(w);
|
|
642
659
|
return;
|
|
643
660
|
}
|
|
644
|
-
i.textContent = "⏳", this.h.onTranslate(
|
|
661
|
+
i.textContent = "⏳", this.h.onTranslate(r).then((I) => {
|
|
645
662
|
if (I === null) {
|
|
646
663
|
i.textContent = "⚠️", i.title = "Translation unavailable", setTimeout(() => {
|
|
647
664
|
i.textContent = "🌐", i.title = "Translate";
|
|
648
665
|
}, 1500);
|
|
649
666
|
return;
|
|
650
667
|
}
|
|
651
|
-
this.translationCache.set(e.id, I),
|
|
668
|
+
this.translationCache.set(e.id, I), f(I);
|
|
652
669
|
});
|
|
653
|
-
}),
|
|
670
|
+
}), u.append(i);
|
|
654
671
|
const k = this.translationCache.get(e.id);
|
|
655
|
-
this.showingTranslation.has(e.id) && k !== void 0 &&
|
|
672
|
+
this.showingTranslation.has(e.id) && k !== void 0 && f(k);
|
|
656
673
|
}
|
|
657
674
|
}
|
|
658
|
-
if (
|
|
659
|
-
const
|
|
675
|
+
if (h && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
|
|
676
|
+
const r = n("div", "ocw-msg-menu");
|
|
660
677
|
if (this.h.onEdit) {
|
|
661
678
|
const i = n("button", void 0, "✏️");
|
|
662
679
|
i.title = "Edit", i.addEventListener("click", (v) => {
|
|
663
680
|
v.stopPropagation();
|
|
664
|
-
const
|
|
665
|
-
|
|
681
|
+
const f = re(e.content), m = document.createElement("textarea");
|
|
682
|
+
m.value = f, m.rows = Math.min(4, Math.ceil(f.length / 40) + 1), m.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:var(--ocw-card);color:#1c1b1a;box-sizing:border-box";
|
|
666
683
|
const k = n("button", "ocw-form-submit", "Save");
|
|
667
684
|
k.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
|
|
668
685
|
const S = n("button", "ocw-form-cancel", "Cancel");
|
|
669
686
|
S.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
|
|
670
|
-
const
|
|
671
|
-
|
|
687
|
+
const w = n("div");
|
|
688
|
+
w.style.cssText = "display:flex;gap:6px;justify-content:flex-end", w.append(S, k);
|
|
672
689
|
const I = n("div");
|
|
673
|
-
I.append(
|
|
674
|
-
const N = () =>
|
|
690
|
+
I.append(m, w), x.replaceChildren(I), m.focus(), m.select();
|
|
691
|
+
const N = () => x.replaceChildren(a ?? document.createTextNode(f));
|
|
675
692
|
S.addEventListener("click", N), k.addEventListener("click", () => {
|
|
676
|
-
const D =
|
|
677
|
-
D && D !==
|
|
678
|
-
}),
|
|
693
|
+
const D = m.value.trim();
|
|
694
|
+
D && D !== f && this.h.onEdit(e.id, D), N();
|
|
695
|
+
}), m.addEventListener("keydown", (D) => {
|
|
679
696
|
D.key === "Enter" && !D.shiftKey && (D.preventDefault(), k.click()), D.key === "Escape" && N();
|
|
680
697
|
});
|
|
681
|
-
}),
|
|
698
|
+
}), r.append(i);
|
|
682
699
|
}
|
|
683
700
|
if (this.h.onDelete) {
|
|
684
701
|
const i = n("button", "del", "🗑");
|
|
685
702
|
i.title = "Delete", i.addEventListener("click", (v) => {
|
|
686
703
|
v.stopPropagation(), this.h.onDelete(e.id);
|
|
687
|
-
}),
|
|
704
|
+
}), r.append(i);
|
|
688
705
|
}
|
|
689
|
-
|
|
706
|
+
u.append(r);
|
|
690
707
|
}
|
|
691
|
-
if (
|
|
692
|
-
const
|
|
693
|
-
if (
|
|
708
|
+
if (l.append(u), e.senderRole === "bot" && !e.deletedAt && e.seq > 0 && e.content.kind === "text") {
|
|
709
|
+
const r = e.content.citations;
|
|
710
|
+
if (r != null && r.length) {
|
|
694
711
|
const i = n("div", "ocw-cites");
|
|
695
|
-
i.style.cssText = "margin-top:4px;font-size:11px;color:var(--ocw-mut,#667)", i.textContent = `${((O = this.cfg.i18n) == null ? void 0 : O.sources) ?? "Sources"}: ${
|
|
712
|
+
i.style.cssText = "margin-top:4px;font-size:11px;color:var(--ocw-mut,#667)", i.textContent = `${((O = this.cfg.i18n) == null ? void 0 : O.sources) ?? "Sources"}: ${r.map((v) => v.source).join(", ")}`, l.append(i);
|
|
696
713
|
}
|
|
697
714
|
if (this.h.onReact) {
|
|
698
715
|
const i = n("div", "ocw-bot-feedback");
|
|
699
716
|
i.style.cssText = "display:flex;gap:6px;margin-top:4px";
|
|
700
|
-
const v = (
|
|
701
|
-
const k = n("button", "ocw-fb-btn",
|
|
702
|
-
k.type = "button", k.title =
|
|
717
|
+
const v = (f, m) => {
|
|
718
|
+
const k = n("button", "ocw-fb-btn", f);
|
|
719
|
+
k.type = "button", k.title = m, k.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:transparent;border-radius:12px;padding:1px 8px;font-size:12px;cursor:pointer;opacity:.7";
|
|
703
720
|
const S = () => {
|
|
704
|
-
var
|
|
705
|
-
return !!((I = (
|
|
721
|
+
var w, I;
|
|
722
|
+
return !!((I = (w = e.reactions) == null ? void 0 : w[f]) != null && I.includes(this.me));
|
|
706
723
|
};
|
|
707
724
|
return S() && (k.style.opacity = "1"), k.addEventListener("click", () => {
|
|
708
|
-
var
|
|
709
|
-
(I = (
|
|
725
|
+
var w, I;
|
|
726
|
+
(I = (w = this.h).onReact) == null || I.call(w, e.id, f, S()), k.style.opacity = "1";
|
|
710
727
|
}), k;
|
|
711
728
|
};
|
|
712
|
-
i.append(v("👍", ((T = this.cfg.i18n) == null ? void 0 : T.helpful) ?? "Helpful"), v("👎", ((_ = this.cfg.i18n) == null ? void 0 : _.notHelpful) ?? "Not helpful")),
|
|
729
|
+
i.append(v("👍", ((T = this.cfg.i18n) == null ? void 0 : T.helpful) ?? "Helpful"), v("👎", ((_ = this.cfg.i18n) == null ? void 0 : _.notHelpful) ?? "Not helpful")), l.append(i);
|
|
713
730
|
}
|
|
714
731
|
}
|
|
715
732
|
if (this.h.onReact && !e.deletedAt && e.seq > 0) {
|
|
716
|
-
const
|
|
733
|
+
const r = n("div", "ocw-react-wrap"), i = n("div", "ocw-react");
|
|
717
734
|
if (e.reactions && Object.keys(e.reactions).length)
|
|
718
|
-
for (const [
|
|
719
|
-
const S = n("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${
|
|
735
|
+
for (const [m, k] of Object.entries(e.reactions)) {
|
|
736
|
+
const S = n("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${m} ${k.length}`);
|
|
720
737
|
S.addEventListener("click", () => {
|
|
721
|
-
var
|
|
722
|
-
return (I = (
|
|
738
|
+
var w, I;
|
|
739
|
+
return (I = (w = this.h).onReact) == null ? void 0 : I.call(w, e.id, m, k.includes(this.me));
|
|
723
740
|
}), i.append(S);
|
|
724
741
|
}
|
|
725
|
-
const v = n("button", "ocw-react-btn", "+"),
|
|
726
|
-
for (const
|
|
727
|
-
const k = n("button", void 0,
|
|
742
|
+
const v = n("button", "ocw-react-btn", "+"), f = n("div", "ocw-react-picker");
|
|
743
|
+
for (const m of Ge) {
|
|
744
|
+
const k = n("button", void 0, m);
|
|
728
745
|
k.addEventListener("click", (S) => {
|
|
729
746
|
var I, N, D, X;
|
|
730
747
|
S.stopPropagation();
|
|
731
|
-
const
|
|
732
|
-
(X = (D = this.h).onReact) == null || X.call(D, e.id,
|
|
733
|
-
}),
|
|
748
|
+
const w = (N = (I = e.reactions) == null ? void 0 : I[m]) == null ? void 0 : N.includes(this.me);
|
|
749
|
+
(X = (D = this.h).onReact) == null || X.call(D, e.id, m, !!w), f.style.display = "none";
|
|
750
|
+
}), f.append(k);
|
|
734
751
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
const k =
|
|
738
|
-
|
|
739
|
-
|
|
752
|
+
f.style.display = "none", v.addEventListener("click", (m) => {
|
|
753
|
+
m.stopPropagation();
|
|
754
|
+
const k = f.style.display === "none";
|
|
755
|
+
f.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
|
|
756
|
+
f.style.display = "none";
|
|
740
757
|
}, { once: !0 });
|
|
741
|
-
}), i.append(v),
|
|
742
|
-
} else e.reactions && Object.keys(e.reactions).length &&
|
|
743
|
-
const j = n("div", "ocw-time ocw-meta",
|
|
744
|
-
if (
|
|
745
|
-
const
|
|
746
|
-
j.append(
|
|
758
|
+
}), i.append(v), r.append(i, f), l.append(r);
|
|
759
|
+
} else e.reactions && Object.keys(e.reactions).length && l.append(n("div", "ocw-react", Object.entries(e.reactions).map(([r, i]) => `${r}${i.length}`).join(" ")));
|
|
760
|
+
const j = n("div", "ocw-time ocw-meta", Je(e.ts));
|
|
761
|
+
if (h && e.status) {
|
|
762
|
+
const r = n("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, et(e.status));
|
|
763
|
+
j.append(r);
|
|
747
764
|
}
|
|
748
|
-
return
|
|
765
|
+
return h && e.seq > 0 && d.lastReadByOthers >= e.seq && j.append(n("span", "ocw-seen", " · Seen")), l.append(j), y.append(l), y;
|
|
749
766
|
}
|
|
750
767
|
}
|
|
751
|
-
function
|
|
768
|
+
function et(t) {
|
|
752
769
|
switch (t) {
|
|
753
770
|
case "read":
|
|
754
771
|
return "✓✓";
|
|
@@ -765,7 +782,7 @@ function Ie(t) {
|
|
|
765
782
|
return `relay-launcher::${t.profileId}::${t.subjectId ?? ""}`;
|
|
766
783
|
}
|
|
767
784
|
let Y = null;
|
|
768
|
-
function
|
|
785
|
+
function tt() {
|
|
769
786
|
if (Y && Y.state !== "closed") return Y;
|
|
770
787
|
try {
|
|
771
788
|
return Y = new AudioContext(), Y;
|
|
@@ -773,18 +790,18 @@ function Ze() {
|
|
|
773
790
|
return null;
|
|
774
791
|
}
|
|
775
792
|
}
|
|
776
|
-
function
|
|
793
|
+
function lt(t) {
|
|
777
794
|
var e;
|
|
778
795
|
(e = F.get(t)) == null || e.close(), F.delete(t);
|
|
779
796
|
}
|
|
780
|
-
function
|
|
797
|
+
function nt(t) {
|
|
781
798
|
const e = t.el;
|
|
782
|
-
let
|
|
783
|
-
const
|
|
784
|
-
|
|
799
|
+
let d = null, s = null, c = !1;
|
|
800
|
+
const h = () => {
|
|
801
|
+
d == null || d.close(), d = null, s == null || s.close(), s = null, e.innerHTML = "";
|
|
785
802
|
};
|
|
786
803
|
function b() {
|
|
787
|
-
|
|
804
|
+
c || (h(), s = Oe({
|
|
788
805
|
el: e,
|
|
789
806
|
url: t.url,
|
|
790
807
|
...t.apiUrl ? { apiUrl: t.apiUrl } : {},
|
|
@@ -795,40 +812,42 @@ function et(t) {
|
|
|
795
812
|
...t.accent ? { accent: t.accent } : {},
|
|
796
813
|
...t.theme ? { theme: t.theme } : {},
|
|
797
814
|
...t.webfont === !1 ? { webfont: !1 } : {},
|
|
798
|
-
|
|
815
|
+
...t.locale ? { locale: t.locale } : {},
|
|
816
|
+
...t.i18n ? { i18n: t.i18n } : {},
|
|
817
|
+
onSelect: (l) => y(l)
|
|
799
818
|
}));
|
|
800
819
|
}
|
|
801
|
-
function y(
|
|
802
|
-
if (
|
|
803
|
-
|
|
804
|
-
const { subjectId:
|
|
805
|
-
|
|
820
|
+
function y(l) {
|
|
821
|
+
if (c) return;
|
|
822
|
+
h();
|
|
823
|
+
const { subjectId: u, kind: x, peerId: a, ...j } = t;
|
|
824
|
+
d = ot({
|
|
806
825
|
...j,
|
|
807
826
|
inbox: !1,
|
|
808
827
|
launcher: !1,
|
|
809
828
|
el: e,
|
|
810
|
-
...
|
|
811
|
-
...
|
|
812
|
-
...
|
|
829
|
+
...l.profileId ? { profileId: l.profileId } : {},
|
|
830
|
+
...l.subjectId ? { subjectId: l.subjectId } : {},
|
|
831
|
+
...l.kind === "direct" && l.peerId ? { kind: "direct", peerId: l.peerId } : {},
|
|
813
832
|
onBack: b
|
|
814
833
|
});
|
|
815
834
|
}
|
|
816
835
|
return b(), { close() {
|
|
817
|
-
|
|
836
|
+
c = !0, h();
|
|
818
837
|
} };
|
|
819
838
|
}
|
|
820
|
-
function
|
|
839
|
+
function ot(t) {
|
|
821
840
|
var de, pe, ue, he, fe, we, be, xe;
|
|
822
|
-
if (t.inbox) return
|
|
841
|
+
if (t.inbox) return nt(t);
|
|
823
842
|
F.has(t.el) && (F.get(t.el).close(), F.delete(t.el)), t.launcher && ((de = ne.get(Ie(t))) == null || de.close());
|
|
824
843
|
const e = Me();
|
|
825
|
-
let
|
|
826
|
-
const
|
|
827
|
-
let
|
|
828
|
-
const
|
|
829
|
-
let
|
|
844
|
+
let d, s = !1;
|
|
845
|
+
const c = t.token ?? t.userId ?? e, h = c !== e ? e : void 0, { wsUrl: b, httpBase: y } = Ae(t.url, t.apiUrl);
|
|
846
|
+
let l = new He(c);
|
|
847
|
+
const u = t.subjectId ? `${c}::${t.subjectId}` : c, x = new De(u);
|
|
848
|
+
let a, j = !1, R = null, E = null, A = null, P = null;
|
|
830
849
|
!t.launcher && !t.el.style.height && t.el.clientHeight === 0 && (t.el.style.width = t.el.style.width || "100%", t.el.style.height = "600px");
|
|
831
|
-
for (const o of
|
|
850
|
+
for (const o of x.load()) l.addOptimistic(o.clientMsgId, o.content);
|
|
832
851
|
let B = null, z = null, O = 0, T = !t.launcher;
|
|
833
852
|
if (t.launcher) {
|
|
834
853
|
const p = (t.position ?? "bottom-right").includes("right");
|
|
@@ -893,7 +912,7 @@ function tt(t) {
|
|
|
893
912
|
return !1;
|
|
894
913
|
}
|
|
895
914
|
}, Pe = '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', me = () => {
|
|
896
|
-
const $ = te != null && te.title ? te :
|
|
915
|
+
const $ = te != null && te.title ? te : l.launcherMessage ?? void 0;
|
|
897
916
|
if (!(!!($ != null && $.title) && !T && !Le())) {
|
|
898
917
|
L && (L.remove(), L = null);
|
|
899
918
|
return;
|
|
@@ -963,9 +982,9 @@ function tt(t) {
|
|
|
963
982
|
}
|
|
964
983
|
const _ = () => {
|
|
965
984
|
T || (O++, z && (z.textContent = String(O), z.style.display = "flex"));
|
|
966
|
-
},
|
|
985
|
+
}, r = () => {
|
|
967
986
|
try {
|
|
968
|
-
const o =
|
|
987
|
+
const o = tt();
|
|
969
988
|
if (!o) return;
|
|
970
989
|
o.state === "suspended" && o.resume().catch(() => {
|
|
971
990
|
});
|
|
@@ -976,44 +995,44 @@ function tt(t) {
|
|
|
976
995
|
}, i = [], v = (o) => {
|
|
977
996
|
for (; i.length; ) {
|
|
978
997
|
const p = i.shift();
|
|
979
|
-
|
|
998
|
+
x.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), f.send({ type: "send", conversationId: o, clientMsgId: p.clientMsgId, content: p.content });
|
|
980
999
|
}
|
|
981
1000
|
};
|
|
982
|
-
let
|
|
983
|
-
const
|
|
1001
|
+
let f;
|
|
1002
|
+
const m = new Ue(`ocw-e2e-${t.profileId}`);
|
|
984
1003
|
let k = !1;
|
|
985
|
-
const S = [],
|
|
1004
|
+
const S = [], w = [];
|
|
986
1005
|
let I = !1;
|
|
987
1006
|
const N = (o, p) => {
|
|
988
|
-
|
|
989
|
-
|
|
1007
|
+
m.sealText(p).then((g) => {
|
|
1008
|
+
a && f.send({ type: "send", conversationId: a, clientMsgId: o, content: g });
|
|
990
1009
|
});
|
|
991
1010
|
}, D = (o, p, g) => {
|
|
992
|
-
|
|
993
|
-
|
|
1011
|
+
m.sealText(p, g).then((M) => {
|
|
1012
|
+
a && f.send({ type: "send", conversationId: a, clientMsgId: o, content: M });
|
|
994
1013
|
});
|
|
995
1014
|
}, X = () => {
|
|
996
1015
|
for (; S.length; ) {
|
|
997
1016
|
const o = S.shift();
|
|
998
1017
|
N(o.clientMsgId, o.text);
|
|
999
1018
|
}
|
|
1000
|
-
for (;
|
|
1001
|
-
const o =
|
|
1019
|
+
for (; w.length; ) {
|
|
1020
|
+
const o = w.shift();
|
|
1002
1021
|
N(o.clientMsgId, o.text);
|
|
1003
1022
|
}
|
|
1004
1023
|
}, Te = (o) => {
|
|
1005
|
-
|
|
1006
|
-
}, Se = t.i18n
|
|
1024
|
+
f.send({ type: "fetchPrekey", targetUserId: o });
|
|
1025
|
+
}, Se = qe(t.locale, t.i18n), Ee = ["ar", "he", "fa", "ur"], ze = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
|
|
1007
1026
|
Ee.includes(ze) && !t.el.dir && (t.el.dir = "rtl", t.el.style.fontFamily = t.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
|
|
1008
|
-
const
|
|
1027
|
+
const se = `oc_prechat_${t.profileId}_${c.slice(-8)}`, q = new Ze(t.el, c, {
|
|
1009
1028
|
onSend(o) {
|
|
1010
1029
|
const p = `cm_${Math.random().toString(36).slice(2)}`, g = { kind: "text", text: o };
|
|
1011
|
-
|
|
1030
|
+
l.addOptimistic(p, g), q.render(l), l.e2e ? m.ready ? N(p, o) : I ? w.push({ clientMsgId: p, text: o }) : (S.push({ clientMsgId: p, text: o }), l.assignedAgentId && Te(l.assignedAgentId)) : a ? (x.add({ clientMsgId: p, content: g, ts: Date.now() }), f.send({ type: "send", conversationId: a, clientMsgId: p, content: g })) : i.push({ clientMsgId: p, content: g });
|
|
1012
1031
|
},
|
|
1013
1032
|
async onAttach(o) {
|
|
1014
|
-
if (!
|
|
1033
|
+
if (!a) return;
|
|
1015
1034
|
const p = `${y}/upload?name=${encodeURIComponent(o.name)}`, g = `cm_${Math.random().toString(36).slice(2)}`;
|
|
1016
|
-
|
|
1035
|
+
l.addOptimistic(g, { kind: "text", text: `📎 Uploading ${o.name}…` }), q.render(l);
|
|
1017
1036
|
try {
|
|
1018
1037
|
const M = await fetch(p, {
|
|
1019
1038
|
method: "POST",
|
|
@@ -1022,28 +1041,28 @@ function tt(t) {
|
|
|
1022
1041
|
// requires an Authorization header, and the verifier accepts an
|
|
1023
1042
|
// anonymous id as a guest; keying off opts.token alone meant anonymous
|
|
1024
1043
|
// visitors (the common case) sent no auth and every upload 401'd.
|
|
1025
|
-
headers: { "content-type": o.type, authorization: `Bearer ${
|
|
1044
|
+
headers: { "content-type": o.type, authorization: `Bearer ${c}` },
|
|
1026
1045
|
body: o
|
|
1027
1046
|
});
|
|
1028
1047
|
if (!M.ok) throw new Error(`Upload failed: ${M.status}`);
|
|
1029
1048
|
const { url: K, name: V, mime: J, size: Z } = await M.json();
|
|
1030
|
-
|
|
1049
|
+
l.addOptimistic(g, { kind: "attachment", url: K, name: V, mime: J, size: Z }), q.render(l), f.send({ type: "send", conversationId: a, clientMsgId: g, content: { kind: "attachment", url: K, name: V, mime: J, size: Z } });
|
|
1031
1050
|
} catch (M) {
|
|
1032
|
-
|
|
1051
|
+
l.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${M.message}` }), q.render(l);
|
|
1033
1052
|
}
|
|
1034
1053
|
},
|
|
1035
1054
|
onInvoke(o, p) {
|
|
1036
|
-
|
|
1055
|
+
a && f.send({ type: "invoke", conversationId: a, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
|
|
1037
1056
|
},
|
|
1038
1057
|
onTyping(o, p) {
|
|
1039
|
-
|
|
1058
|
+
a && f.send({ type: "typing", conversationId: a, isTyping: o, ...p ? { preview: p } : {} });
|
|
1040
1059
|
},
|
|
1041
1060
|
onPreChat(o) {
|
|
1042
1061
|
try {
|
|
1043
|
-
localStorage.setItem(
|
|
1062
|
+
localStorage.setItem(se, "1");
|
|
1044
1063
|
} catch {
|
|
1045
1064
|
}
|
|
1046
|
-
|
|
1065
|
+
f.send({
|
|
1047
1066
|
type: "open",
|
|
1048
1067
|
profileId: t.profileId,
|
|
1049
1068
|
...t.subjectId ? { subjectId: t.subjectId } : {},
|
|
@@ -1057,46 +1076,46 @@ function tt(t) {
|
|
|
1057
1076
|
}
|
|
1058
1077
|
});
|
|
1059
1078
|
const p = o.callback ? `📞 Call-back requested${o.phone ? `: ${o.phone}` : ""}${o.topic ? ` — ${o.topic}` : ""}` : o.topic ? `Topic: ${o.topic}` : "";
|
|
1060
|
-
p &&
|
|
1079
|
+
p && a && !l.e2e && f.send({ type: "send", conversationId: a, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
|
|
1061
1080
|
},
|
|
1062
1081
|
...((pe = t.features) == null ? void 0 : pe.deflection) !== !1 ? {
|
|
1063
1082
|
onDeflectQuery(o) {
|
|
1064
|
-
if (
|
|
1065
|
-
clearTimeout(
|
|
1083
|
+
if (s) return;
|
|
1084
|
+
clearTimeout(d);
|
|
1066
1085
|
const p = o.trim();
|
|
1067
1086
|
if (p.length < 3) {
|
|
1068
1087
|
q.hideDeflection();
|
|
1069
1088
|
return;
|
|
1070
1089
|
}
|
|
1071
|
-
|
|
1090
|
+
d = setTimeout(() => {
|
|
1072
1091
|
fetch(`${y}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => q.showDeflection(g.articles ?? [])).catch(() => q.hideDeflection());
|
|
1073
1092
|
}, 350);
|
|
1074
1093
|
}
|
|
1075
1094
|
} : {},
|
|
1076
1095
|
onReadUpTo(o) {
|
|
1077
|
-
|
|
1096
|
+
a && f.send({ type: "read", conversationId: a, seq: o });
|
|
1078
1097
|
},
|
|
1079
1098
|
onLoadMore() {
|
|
1080
|
-
if (!
|
|
1081
|
-
const o =
|
|
1082
|
-
o &&
|
|
1099
|
+
if (!a || !l.e2e) return;
|
|
1100
|
+
const o = l.messages()[0];
|
|
1101
|
+
o && f.send({ type: "history", conversationId: a, beforeSeq: o.seq, limit: 20 });
|
|
1083
1102
|
},
|
|
1084
1103
|
onEdit(o, p) {
|
|
1085
|
-
|
|
1104
|
+
a && f.send({ type: "edit", conversationId: a, messageId: o, content: { kind: "text", text: p } });
|
|
1086
1105
|
},
|
|
1087
1106
|
onDelete(o) {
|
|
1088
|
-
|
|
1107
|
+
a && f.send({ type: "delete", conversationId: a, messageId: o });
|
|
1089
1108
|
},
|
|
1090
1109
|
...((ue = t.features) == null ? void 0 : ue.reactions) !== !1 ? {
|
|
1091
1110
|
onReact(o, p, g) {
|
|
1092
|
-
|
|
1111
|
+
a && f.send({ type: "react", conversationId: a, messageId: o, emoji: p, remove: g });
|
|
1093
1112
|
}
|
|
1094
1113
|
} : {},
|
|
1095
1114
|
...((he = t.features) == null ? void 0 : he.csat) !== !1 ? {
|
|
1096
1115
|
onCsat(o) {
|
|
1097
|
-
|
|
1116
|
+
a && fetch(`${y}/conversations/${a}/csat`, {
|
|
1098
1117
|
method: "POST",
|
|
1099
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${
|
|
1118
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${c}` },
|
|
1100
1119
|
body: JSON.stringify({ score: o })
|
|
1101
1120
|
}).catch(() => {
|
|
1102
1121
|
});
|
|
@@ -1107,7 +1126,7 @@ function tt(t) {
|
|
|
1107
1126
|
try {
|
|
1108
1127
|
const p = await fetch(`${y}/translate`, {
|
|
1109
1128
|
method: "POST",
|
|
1110
|
-
headers: { "content-type": "application/json", authorization: `Bearer ${
|
|
1129
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${c}` },
|
|
1111
1130
|
body: JSON.stringify({ text: o, targetLang: t.translateLang })
|
|
1112
1131
|
});
|
|
1113
1132
|
if (!p.ok) return null;
|
|
@@ -1130,7 +1149,7 @@ function tt(t) {
|
|
|
1130
1149
|
i18n: Se
|
|
1131
1150
|
});
|
|
1132
1151
|
try {
|
|
1133
|
-
localStorage.getItem(
|
|
1152
|
+
localStorage.getItem(se) && q.completePreChat();
|
|
1134
1153
|
} catch {
|
|
1135
1154
|
}
|
|
1136
1155
|
const le = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
|
|
@@ -1145,7 +1164,7 @@ function tt(t) {
|
|
|
1145
1164
|
// server-derived and owner-keyed, so passing it as subjectId from the
|
|
1146
1165
|
// NON-owner side would find-or-create a junk duplicate thread.
|
|
1147
1166
|
...t.kind === "direct" && t.peerId ? { kind: "direct", peerId: t.peerId } : t.subjectId ? { subjectId: t.subjectId } : {},
|
|
1148
|
-
...
|
|
1167
|
+
...h ? { linkFrom: h } : {},
|
|
1149
1168
|
...le ? { userInfo: le } : {},
|
|
1150
1169
|
...typeof location < "u" ? { pageUrl: location.href } : {},
|
|
1151
1170
|
...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
|
|
@@ -1154,79 +1173,79 @@ function tt(t) {
|
|
|
1154
1173
|
...(be = t.subject) != null && be.title ? { subjectTitle: t.subject.title } : {},
|
|
1155
1174
|
...(xe = t.subject) != null && xe.subtitle ? { subjectMeta: t.subject.subtitle } : {}
|
|
1156
1175
|
};
|
|
1157
|
-
|
|
1176
|
+
f = new _e({
|
|
1158
1177
|
...t.refreshToken ? { refreshToken: t.refreshToken } : {},
|
|
1159
1178
|
url: b,
|
|
1160
|
-
token:
|
|
1179
|
+
token: c,
|
|
1161
1180
|
open: je,
|
|
1162
|
-
getCursor: () =>
|
|
1181
|
+
getCursor: () => l.highestSeq(),
|
|
1163
1182
|
onStatusChange: (o, p) => q.setConnStatus(o, p),
|
|
1164
1183
|
onFrame(o) {
|
|
1165
1184
|
if (o.type === "opened") {
|
|
1166
|
-
if (
|
|
1185
|
+
if (a = o.conversation.id, !j) {
|
|
1167
1186
|
j = !0;
|
|
1168
|
-
for (const p of
|
|
1169
|
-
|
|
1187
|
+
for (const p of x.load())
|
|
1188
|
+
f.send({ type: "send", conversationId: a, clientMsgId: p.clientMsgId, content: p.content });
|
|
1170
1189
|
}
|
|
1171
|
-
|
|
1190
|
+
Ne(b, c, a, l, q, y), i.length && v(a);
|
|
1172
1191
|
}
|
|
1173
|
-
if (o.type === "ack" &&
|
|
1174
|
-
o.bundle && (I = !0,
|
|
1175
|
-
const g = [...S.splice(0), ...
|
|
1192
|
+
if (o.type === "ack" && x.remove(o.clientMsgId), o.type === "prekeyBundle") {
|
|
1193
|
+
o.bundle && (I = !0, m.x3dhSendTo(o.bundle).then((p) => {
|
|
1194
|
+
const g = [...S.splice(0), ...w.splice(0)];
|
|
1176
1195
|
for (const M of g) D(M.clientMsgId, M.text, p);
|
|
1177
|
-
q.render(
|
|
1196
|
+
q.render(l);
|
|
1178
1197
|
}));
|
|
1179
1198
|
return;
|
|
1180
1199
|
}
|
|
1181
|
-
if (o.type === "message" &&
|
|
1182
|
-
const p =
|
|
1183
|
-
if (p && !
|
|
1184
|
-
|
|
1185
|
-
await
|
|
1200
|
+
if (o.type === "message" && l.e2e) {
|
|
1201
|
+
const p = Fe(o.message.content);
|
|
1202
|
+
if (p && !m.ready) {
|
|
1203
|
+
m.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK, p.x3dhOTP).then(async () => {
|
|
1204
|
+
await m.openFrame(o), l.apply(o), q.render(l);
|
|
1186
1205
|
});
|
|
1187
1206
|
return;
|
|
1188
1207
|
}
|
|
1189
1208
|
}
|
|
1190
1209
|
if (o.type === "peerkey") {
|
|
1191
|
-
|
|
1192
|
-
X(), q.render(
|
|
1210
|
+
m.onPeerKey(o.key).then(() => {
|
|
1211
|
+
X(), q.render(l);
|
|
1193
1212
|
});
|
|
1194
1213
|
return;
|
|
1195
1214
|
}
|
|
1196
1215
|
(async () => {
|
|
1197
|
-
if (
|
|
1216
|
+
if (l.e2e && await m.openFrame(o), l.apply(o), o.type === "manifest") {
|
|
1198
1217
|
P == null || P();
|
|
1199
1218
|
const p = o.botName;
|
|
1200
1219
|
p && q.setBotName(p);
|
|
1201
1220
|
}
|
|
1202
|
-
if (o.type === "message" && o.message.senderId !==
|
|
1221
|
+
if (o.type === "message" && o.message.senderId !== c && !o.message.internal && (_(), r()), l.e2e && a && !k) {
|
|
1203
1222
|
k = !0;
|
|
1204
|
-
const p = await
|
|
1205
|
-
|
|
1206
|
-
const g = await
|
|
1207
|
-
|
|
1223
|
+
const p = await m.initX3DH();
|
|
1224
|
+
f.send({ type: "uploadPrekeys", ...p });
|
|
1225
|
+
const g = await m.begin();
|
|
1226
|
+
f.send({ type: "pubkey", conversationId: a, key: g });
|
|
1208
1227
|
}
|
|
1209
|
-
q.render(
|
|
1228
|
+
q.render(l);
|
|
1210
1229
|
})();
|
|
1211
1230
|
}
|
|
1212
|
-
}),
|
|
1231
|
+
}), f.connect(), q.render(l);
|
|
1213
1232
|
const G = t.launcher ? Ie(t) : null, Q = { close: () => {
|
|
1214
|
-
|
|
1233
|
+
s = !0, clearTimeout(d), f.close(), B == null || B.remove(), q.destroy(), R && E && R.removeEventListener("change", E), A && (document.removeEventListener("keydown", A), A = null), F.delete(t.el), G && ne.get(G) === Q && ne.delete(G);
|
|
1215
1234
|
} };
|
|
1216
1235
|
return F.set(t.el, Q), G && ne.set(G, Q), Q;
|
|
1217
1236
|
}
|
|
1218
1237
|
export {
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1238
|
+
He as ChatStore,
|
|
1239
|
+
_e as ConnectionManager,
|
|
1240
|
+
Ue as E2ESession,
|
|
1241
|
+
De as PersistentOutbox,
|
|
1242
|
+
Ze as Renderer,
|
|
1243
|
+
ft as asConversationId,
|
|
1244
|
+
Fe as extractX3DHInit,
|
|
1245
|
+
ut as httpBaseFromWsUrl,
|
|
1246
|
+
ot as mount,
|
|
1228
1247
|
Ae as resolveRelayUrls,
|
|
1229
|
-
|
|
1230
|
-
|
|
1248
|
+
Ne as restoreHistory,
|
|
1249
|
+
lt as unmount
|
|
1231
1250
|
};
|
|
1232
1251
|
//# sourceMappingURL=index.js.map
|