@paramms/chat-widget 1.0.34 โ†’ 1.0.36

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/index.d.ts CHANGED
@@ -47,6 +47,10 @@ export interface MountOptions {
47
47
  subject?: WidgetConfig['subject'];
48
48
  quickReplies?: string[];
49
49
  accent?: string;
50
+ /** Stack navigation: when set, the chatroom header shows a back chevron that
51
+ * calls this. Used by `<ChatApp>` so tapping a conversation opens the room and
52
+ * the back arrow returns to the list โ€” native-app style. */
53
+ onBack?: () => void;
50
54
  /** If set, shows a ๐ŸŒ translate button on incoming messages that translates
51
55
  * them into this language (ISO code or language name) via the server's
52
56
  * /translate endpoint. Omit to disable the feature. */
package/dist/index.js CHANGED
@@ -74,6 +74,8 @@ const oe = "objectchat-widget-styles", Ce = ["๐Ÿ‘", "โค๏ธ", "๐Ÿ˜‚", "๐Ÿ˜ฎ", "
74
74
  [dir="rtl"] .ocw-input { flex-direction:row-reverse; }
75
75
  [dir="rtl"] .mine .ocw-meta { text-align:left; }
76
76
  .ocw-head { display:flex; align-items:center; gap:10px; padding:12px 14px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); }
77
+ .ocw-back { flex:none; width:30px; height:30px; margin:-2px -2px -2px -4px; border:none; background:none; color:var(--ocw-ink); font-size:26px; line-height:1; cursor:pointer; border-radius:50%; display:flex; align-items:center; justify-content:center; }
78
+ .ocw-back:hover { background:var(--ocw-bg); }
77
79
  .ocw-avatar { width:34px; height:34px; border-radius:50%; background:#ffe9d6; display:flex; align-items:center; justify-content:center; font-size:17px; flex:none; }
78
80
  .ocw-head-main { flex:1; min-width:0; }
79
81
  .ocw-head-name { font-weight:700; font-size:15px; }
@@ -294,58 +296,63 @@ class Ee {
294
296
  y(this, "translationCache", /* @__PURE__ */ new Map());
295
297
  y(this, "showingTranslation", /* @__PURE__ */ new Set());
296
298
  y(this, "subjectBuilt", !1);
297
- var g, h, I, T, $, A, z, P, k;
299
+ var m, h, I, T, $, A, P, z, k;
298
300
  this.root = e, this.me = i, this.h = s, this.cfg = a, Ie(), e.replaceChildren(), e.classList.add("ocw"), a.accent && e.style.setProperty("--ocw-accent", a.accent);
299
- const c = t("div", "ocw-head"), f = t("div", "ocw-avatar");
300
- if ((g = a.userInfo) != null && g.avatar) {
301
- const m = document.createElement("img");
302
- m.src = a.userInfo.avatar, m.alt = a.userInfo.name ?? "You", m.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", f.append(m);
301
+ const c = t("div", "ocw-head");
302
+ if (this.h.onBack) {
303
+ const x = t("button", "ocw-back", "โ€น");
304
+ x.type = "button", x.setAttribute("aria-label", "Back"), x.addEventListener("click", () => this.h.onBack()), c.append(x);
305
+ }
306
+ const f = t("div", "ocw-avatar");
307
+ if ((m = a.userInfo) != null && m.avatar) {
308
+ const x = document.createElement("img");
309
+ x.src = a.userInfo.avatar, x.alt = a.userInfo.name ?? "You", x.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", f.append(x);
303
310
  } else
304
311
  f.textContent = (h = a.userInfo) != null && h.name ? a.userInfo.name[0].toUpperCase() : "๐Ÿง‘";
305
312
  c.append(f);
306
313
  const b = t("div", "ocw-head-main");
307
- this.headerName = t("div", "ocw-head-name", ((I = a.subject) == null ? void 0 : I.ownerLabel) ?? ((T = a.subject) == null ? void 0 : T.title) ?? ""), b.append(this.headerName), ($ = a.subject) != null && $.subtitle && b.append(t("div", "ocw-head-meta", a.subject.subtitle)), c.append(b), this.statusBadge = t("span", "ocw-badge", ((A = a.subject) == null ? void 0 : A.status) ?? ""), (z = a.subject) != null && z.status || (this.statusBadge.style.display = "none"), c.append(this.statusBadge), this.e2eBadge = t("span", "ocw-e2e", "๐Ÿ”’ E2E"), this.e2eBadge.style.display = "none", c.append(this.e2eBadge), this.connStatus = t("span", "ocw-conn-status"), this.connStatus.style.display = "none", c.append(this.connStatus), this.cobrowseBtn = t("button", "ocw-menu ocw-cobrowse-btn", "๐Ÿ–"), this.cobrowseBtn.title = "Shared whiteboard โ€” draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
314
+ this.headerName = t("div", "ocw-head-name", ((I = a.subject) == null ? void 0 : I.ownerLabel) ?? ((T = a.subject) == null ? void 0 : T.title) ?? ""), b.append(this.headerName), ($ = a.subject) != null && $.subtitle && b.append(t("div", "ocw-head-meta", a.subject.subtitle)), c.append(b), this.statusBadge = t("span", "ocw-badge", ((A = a.subject) == null ? void 0 : A.status) ?? ""), (P = a.subject) != null && P.status || (this.statusBadge.style.display = "none"), c.append(this.statusBadge), this.e2eBadge = t("span", "ocw-e2e", "๐Ÿ”’ E2E"), this.e2eBadge.style.display = "none", c.append(this.e2eBadge), this.connStatus = t("span", "ocw-conn-status"), this.connStatus.style.display = "none", c.append(this.connStatus), this.cobrowseBtn = t("button", "ocw-menu ocw-cobrowse-btn", "๐Ÿ–"), this.cobrowseBtn.title = "Shared whiteboard โ€” draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
308
315
  this.cobrowseActive = !this.cobrowseActive, this.updateCobrowseUI();
309
316
  }), c.append(this.cobrowseBtn), c.append(t("button", "ocw-menu", "โ‹ฏ")), this.chips = t("div", "ocw-chiprow"), this.scroll = t("div", "ocw-scroll"), this.subjectCard = t("div", "ocw-subject"), this.typing = t("div", "ocw-typing");
310
317
  const d = t("div", "ocw-typing-bubble");
311
318
  d.append(t("div", "ocw-typing-dot"), t("div", "ocw-typing-dot"), t("div", "ocw-typing-dot")), this.typing.append(t("div", "ocw-dot", "๐Ÿง‘"), d), this.quick = t("div", "ocw-quick");
312
- for (const m of a.quickReplies ?? []) {
313
- const S = t("button", void 0, m);
319
+ for (const x of a.quickReplies ?? []) {
320
+ const S = t("button", void 0, x);
314
321
  S.addEventListener("click", () => {
315
- this.h.onSend(m), this.quick.style.display = "none";
322
+ this.h.onSend(x), this.quick.style.display = "none";
316
323
  }), this.quick.append(S);
317
324
  }
318
325
  this.formHost = t("div", "ocw-form-host"), this.csatPanel = t("div", "ocw-csat"), this.csatPanel.style.display = "none", this.offlinePanel = t("div", "ocw-offline"), this.offlinePanel.style.display = "none", this.preChatPanel = t("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = t("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = t("textarea", void 0), this.input.rows = 1, this.input.placeholder = "Messageโ€ฆ";
319
- const w = t("button", "ocw-sendbtn", ((P = a.i18n) == null ? void 0 : P.send) ?? "โžค");
326
+ const w = t("button", "ocw-sendbtn", ((z = a.i18n) == null ? void 0 : z.send) ?? "โžค");
320
327
  w.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
321
- var m, S;
322
- this.storeRef && !this.storeRef.messages().some((B) => B.senderRole === "guest") ? (S = (m = this.h).onDeflectQuery) == null || S.call(m, this.input.value) : this.hideDeflection();
323
- }), this.input.addEventListener("keydown", (m) => {
324
- m.isComposing || m.keyCode === 229 || (m.key === "Enter" && !m.shiftKey ? (m.preventDefault(), this.flushSend()) : this.signalTyping());
328
+ var x, S;
329
+ this.storeRef && !this.storeRef.messages().some((B) => B.senderRole === "guest") ? (S = (x = this.h).onDeflectQuery) == null || S.call(x, this.input.value) : this.hideDeflection();
330
+ }), this.input.addEventListener("keydown", (x) => {
331
+ x.isComposing || x.keyCode === 229 || (x.key === "Enter" && !x.shiftKey ? (x.preventDefault(), this.flushSend()) : this.signalTyping());
325
332
  });
326
333
  const v = t("button", "ocw-attach", "๐Ÿ“Ž");
327
334
  v.title = "Attach image or file";
328
335
  const r = document.createElement("input");
329
336
  r.type = "file", r.accept = "image/*,.pdf,.txt,.doc,.docx", r.style.display = "none", v.addEventListener("click", () => r.click()), r.addEventListener("change", () => {
330
- var m;
331
- (m = r.files) != null && m[0] && this.h.onAttach && this.h.onAttach(r.files[0]), r.value = "";
337
+ var x;
338
+ (x = r.files) != null && x[0] && this.h.onAttach && this.h.onAttach(r.files[0]), r.value = "";
332
339
  });
333
340
  const u = t("div", "ocw-input");
334
341
  u.append(v, r, this.input, w);
335
342
  const l = t("div", "ocw-footer");
336
343
  ((k = a.i18n) == null ? void 0 : k.poweredBy) !== void 0 ? l.textContent = a.i18n.poweredBy : l.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = l, e.append(c, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, this.preChatPanel, this.deflectPanel, u, this.footer), this.cobrowseCanvas = t("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = t("div", "ocw-cobrowse-toolbar");
337
- for (const m of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
344
+ for (const x of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
338
345
  const S = t("button", "ocw-cobrowse-swatch");
339
- S.style.background = m, S.type = "button", m === this.cobrowseColor && S.classList.add("sel"), S.addEventListener("click", () => {
340
- this.cobrowseColor = m;
346
+ S.style.background = x, S.type = "button", x === this.cobrowseColor && S.classList.add("sel"), S.addEventListener("click", () => {
347
+ this.cobrowseColor = x;
341
348
  for (const B of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) B.classList.remove("sel");
342
349
  S.classList.add("sel");
343
350
  }), this.cobrowseToolbar.append(S);
344
351
  }
345
352
  const C = t("button", "ocw-cobrowse-clear", "Clear");
346
353
  C.addEventListener("click", () => {
347
- var m, S;
348
- return (S = (m = this.h).onAnnotateClear) == null ? void 0 : S.call(m);
354
+ var x, S;
355
+ return (S = (x = this.h).onAnnotateClear) == null ? void 0 : S.call(x);
349
356
  }), this.cobrowseToolbar.append(C), this.cobrowseHint = t("div", "ocw-cobrowse-hint", "๐Ÿ– Draw to point things out โ€” visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
350
357
  }
351
358
  /** Returns the scroll container so history.ts can attach scroll listeners. */
@@ -377,7 +384,7 @@ class Ee {
377
384
  this.h.onTyping(!0, e), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
378
385
  }
379
386
  render(e) {
380
- var r, u, l, C, g;
387
+ var r, u, l, C, m;
381
388
  if (this.storeRef = e, this.cobrowseBtn.classList.toggle("show", !!e.subject), !e.subject && this.cobrowseActive && (this.cobrowseActive = !1, this.updateCobrowseUI()), this.cobrowseActive && e.annotationVersion !== this.lastAnnotationVersion && (this.lastAnnotationVersion = e.annotationVersion, this.resizeCobrowseCanvas(), this.redrawCobrowse()), e.accent && this.root.style.setProperty("--ocw-accent", e.accent), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
382
389
  const h = (r = this.cfg.subject) == null ? void 0 : r.ownerLabel;
383
390
  h && (this.headerName.textContent = h);
@@ -400,7 +407,7 @@ class Ee {
400
407
  const b = this.typing.querySelector(".ocw-typing-bubble");
401
408
  b && b.setAttribute("aria-label", f.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
402
409
  const d = e.messages().some((h) => h.senderRole === "guest");
403
- !!((u = e.preChat) != null && u.enabled) && !this.preChatDone && !d && (e.preChat.showWhen !== "offline" || e.offline) ? (this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.offlinePanel.style.display = "none", (l = this.root.querySelector(".ocw-input")) == null || l.style.setProperty("display", "none")) : (this.preChatPanel.style.display = "none", e.offline ? (this.offlinePanel.style.display === "none" && this.buildOfflinePanel(e.offlineMessage), this.offlinePanel.style.display = "block", (C = this.root.querySelector(".ocw-input")) == null || C.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (g = this.root.querySelector(".ocw-input")) == null || g.style.removeProperty("display")));
410
+ !!((u = e.preChat) != null && u.enabled) && !this.preChatDone && !d && (e.preChat.showWhen !== "offline" || e.offline) ? (this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.offlinePanel.style.display = "none", (l = this.root.querySelector(".ocw-input")) == null || l.style.setProperty("display", "none")) : (this.preChatPanel.style.display = "none", e.offline ? (this.offlinePanel.style.display === "none" && this.buildOfflinePanel(e.offlineMessage), this.offlinePanel.style.display = "block", (C = this.root.querySelector(".ocw-input")) == null || C.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (m = this.root.querySelector(".ocw-input")) == null || m.style.removeProperty("display")));
404
411
  const v = ["resolved", "closed", "sold", "issued", "checked_out"];
405
412
  this.h.onCsat && !this.csatSubmitted && v.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
406
413
  }
@@ -456,7 +463,7 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
456
463
  }
457
464
  const b = t("button", "ocw-offline-submit", "Start chat");
458
465
  b.addEventListener("click", () => {
459
- var u, l, C, g, h, I, T;
466
+ var u, l, C, m, h, I, T;
460
467
  const w = (u = s.email) == null ? void 0 : u.value.trim();
461
468
  if (s.email && (!w || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(w))) {
462
469
  s.email.focus();
@@ -467,7 +474,7 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
467
474
  (C = s.phone ?? f) == null || C.focus();
468
475
  return;
469
476
  }
470
- if (a && ((g = e.topics) != null && g.length) && !a.value) {
477
+ if (a && ((m = e.topics) != null && m.length) && !a.value) {
471
478
  a.focus();
472
479
  return;
473
480
  }
@@ -656,10 +663,10 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
656
663
  } else if (e.content.kind === "appointment") {
657
664
  const u = e.content, l = t("div", "ocw-appt");
658
665
  l.append(t("div", "ocw-appt-title", `๐Ÿ“… ${u.title}`)), l.append(t("div", "ocw-appt-time", new Date(u.startIso).toLocaleString() + " โ€“ " + new Date(u.endIso).toLocaleTimeString())), u.location && l.append(t("div", "ocw-appt-loc", `๐Ÿ“ ${u.location}`)), u.description && l.append(t("div", "ocw-appt-desc", u.description));
659
- const C = t("div", "ocw-appt-links"), g = document.createElement("a");
660
- g.href = u.googleUrl, g.target = "_blank", g.rel = "noopener", g.className = "ocw-appt-btn", g.textContent = "๐Ÿ“… Add to Google Calendar";
666
+ const C = t("div", "ocw-appt-links"), m = document.createElement("a");
667
+ m.href = u.googleUrl, m.target = "_blank", m.rel = "noopener", m.className = "ocw-appt-btn", m.textContent = "๐Ÿ“… Add to Google Calendar";
661
668
  const h = document.createElement("a");
662
- h.href = u.icalUrl, h.download = `${u.title}.ics`, h.className = "ocw-appt-btn ocw-appt-btn-sec", h.textContent = "๐ŸŽ Apple / iCal", C.append(g, h), l.append(C), d.append(l);
669
+ h.href = u.icalUrl, h.download = `${u.title}.ics`, h.className = "ocw-appt-btn ocw-appt-btn-sec", h.textContent = "๐ŸŽ Apple / iCal", C.append(m, h), l.append(C), d.append(l);
663
670
  } else
664
671
  w = document.createTextNode(W(e.content)), d.append(w), e.editedAt && d.append(t("span", "ocw-edited", "(edited)"));
665
672
  if (b.append(d), !s && !a && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && w) {
@@ -671,9 +678,9 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
671
678
  this.showingTranslation.delete(e.id), w.textContent = u, l.textContent = "๐ŸŒ", l.title = "Translate";
672
679
  return;
673
680
  }
674
- const g = this.translationCache.get(e.id);
675
- if (g !== void 0) {
676
- this.showingTranslation.add(e.id), w.textContent = g, l.textContent = "โ†ฉ", l.title = "Show original";
681
+ const m = this.translationCache.get(e.id);
682
+ if (m !== void 0) {
683
+ this.showingTranslation.add(e.id), w.textContent = m, l.textContent = "โ†ฉ", l.title = "Show original";
677
684
  return;
678
685
  }
679
686
  l.textContent = "โณ", this.h.onTranslate(u).then((h) => {
@@ -694,8 +701,8 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
694
701
  const l = t("button", void 0, "โœ๏ธ");
695
702
  l.title = "Edit", l.addEventListener("click", (C) => {
696
703
  C.stopPropagation();
697
- const g = W(e.content), h = document.createElement("textarea");
698
- h.value = g, h.rows = Math.min(4, Math.ceil(g.length / 40) + 1), h.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";
704
+ const m = W(e.content), h = document.createElement("textarea");
705
+ h.value = m, h.rows = Math.min(4, Math.ceil(m.length / 40) + 1), h.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";
699
706
  const I = t("button", "ocw-form-submit", "Save");
700
707
  I.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
701
708
  const T = t("button", "ocw-form-cancel", "Cancel");
@@ -704,12 +711,12 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
704
711
  $.style.cssText = "display:flex;gap:6px;justify-content:flex-end", $.append(T, I);
705
712
  const A = t("div");
706
713
  A.append(h, $), d.replaceChildren(A), h.focus(), h.select();
707
- const z = () => d.replaceChildren(w ?? document.createTextNode(g));
708
- T.addEventListener("click", z), I.addEventListener("click", () => {
709
- const P = h.value.trim();
710
- P && P !== g && this.h.onEdit(e.id, P), z();
711
- }), h.addEventListener("keydown", (P) => {
712
- P.key === "Enter" && !P.shiftKey && (P.preventDefault(), I.click()), P.key === "Escape" && z();
714
+ const P = () => d.replaceChildren(w ?? document.createTextNode(m));
715
+ T.addEventListener("click", P), I.addEventListener("click", () => {
716
+ const z = h.value.trim();
717
+ z && z !== m && this.h.onEdit(e.id, z), P();
718
+ }), h.addEventListener("keydown", (z) => {
719
+ z.key === "Enter" && !z.shiftKey && (z.preventDefault(), I.click()), z.key === "Escape" && P();
713
720
  });
714
721
  }), u.append(l);
715
722
  }
@@ -731,31 +738,31 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
731
738
  return (A = ($ = this.h).onReact) == null ? void 0 : A.call($, e.id, h, I.includes(this.me));
732
739
  }), l.append(T);
733
740
  }
734
- const C = t("button", "ocw-react-btn", "๏ผ‹"), g = t("div", "ocw-react-picker");
741
+ const C = t("button", "ocw-react-btn", "๏ผ‹"), m = t("div", "ocw-react-picker");
735
742
  for (const h of Ce) {
736
743
  const I = t("button", void 0, h);
737
744
  I.addEventListener("click", (T) => {
738
- var A, z, P, k;
745
+ var A, P, z, k;
739
746
  T.stopPropagation();
740
- const $ = (z = (A = e.reactions) == null ? void 0 : A[h]) == null ? void 0 : z.includes(this.me);
741
- (k = (P = this.h).onReact) == null || k.call(P, e.id, h, !!$), g.style.display = "none";
742
- }), g.append(I);
747
+ const $ = (P = (A = e.reactions) == null ? void 0 : A[h]) == null ? void 0 : P.includes(this.me);
748
+ (k = (z = this.h).onReact) == null || k.call(z, e.id, h, !!$), m.style.display = "none";
749
+ }), m.append(I);
743
750
  }
744
- g.style.display = "none", C.addEventListener("click", (h) => {
745
- h.stopPropagation(), g.style.display = g.style.display === "none" ? "flex" : "none";
751
+ m.style.display = "none", C.addEventListener("click", (h) => {
752
+ h.stopPropagation(), m.style.display = m.style.display === "none" ? "flex" : "none";
746
753
  }), document.addEventListener("click", () => {
747
- g.style.display = "none";
748
- }, { once: !0 }), l.append(C), u.append(l, g), f.append(u);
754
+ m.style.display = "none";
755
+ }, { once: !0 }), l.append(C), u.append(l, m), f.append(u);
749
756
  } else e.reactions && Object.keys(e.reactions).length && f.append(t("div", "ocw-react", Object.entries(e.reactions).map(([u, l]) => `${u}${l.length}`).join(" ")));
750
757
  const v = t("div", "ocw-time ocw-meta", Se(e.ts));
751
758
  if (s && e.status) {
752
- const u = t("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Pe(e.status));
759
+ const u = t("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, ze(e.status));
753
760
  v.append(u);
754
761
  }
755
762
  return s && e.seq > 0 && i.lastReadByOthers >= e.seq && v.append(t("span", "ocw-seen", " ยท Seen")), f.append(v), c.append(f), c;
756
763
  }
757
764
  }
758
- function Pe(o) {
765
+ function ze(o) {
759
766
  switch (o) {
760
767
  case "read":
761
768
  return "โœ“โœ“";
@@ -786,12 +793,12 @@ function Be(o) {
786
793
  let r, u = !1, l = null, C = null;
787
794
  !o.launcher && !o.el.style.height && o.el.clientHeight === 0 && (o.el.style.width = o.el.style.width || "100%", o.el.style.height = "600px");
788
795
  for (const n of v.load()) d.addOptimistic(n.clientMsgId, n.content);
789
- let g = null, h = null, I = 0, T = !o.launcher;
796
+ let m = null, h = null, I = 0, T = !o.launcher;
790
797
  if (o.launcher) {
791
798
  const p = (o.position ?? "bottom-right").includes("right");
792
- g = document.createElement("div"), g.style.cssText = `position:fixed;${p ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${p ? "flex-end" : "flex-start"};gap:12px`;
793
- const x = document.createElement("div"), E = typeof window < "u" ? window.matchMedia("(max-width: 479px)") : null, O = (q) => {
794
- x.style.cssText = q ? [
799
+ m = document.createElement("div"), m.style.cssText = `position:fixed;${p ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${p ? "flex-end" : "flex-start"};gap:12px`;
800
+ const g = document.createElement("div"), E = typeof window < "u" ? window.matchMedia("(max-width: 479px)") : null, O = (q) => {
801
+ g.style.cssText = q ? [
795
802
  "position:fixed",
796
803
  "inset:0",
797
804
  "width:100%",
@@ -822,7 +829,7 @@ function Be(o) {
822
829
  };
823
830
  O((E == null ? void 0 : E.matches) ?? !1);
824
831
  const N = (q) => O(q.matches);
825
- E == null || E.addEventListener("change", N), l = E, C = N, o.el.style.cssText = "width:100%;height:100%;overflow:hidden", x.append(o.el);
832
+ E == null || E.addEventListener("change", N), l = E, C = N, o.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(o.el);
826
833
  const L = document.createElement("button");
827
834
  L.style.cssText = [
828
835
  "width:56px;height:56px;border-radius:50%",
@@ -835,12 +842,12 @@ function Be(o) {
835
842
  L.style.transform = "scale(1.08)";
836
843
  }, L.onmouseleave = () => {
837
844
  L.style.transform = "scale(1)";
838
- }, h = document.createElement("span"), h.style.cssText = "position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center", L.append(h), g.append(x, L), document.body.append(g);
845
+ }, h = document.createElement("span"), h.style.cssText = "position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center", L.append(h), m.append(g, L), document.body.append(m);
839
846
  const _ = (q) => {
840
- q ? (x.style.display = "flex", requestAnimationFrame(() => {
841
- x.style.opacity = "1", x.style.transform = "scale(1)";
842
- })) : (x.style.opacity = "0", x.style.transform = "scale(.95)", setTimeout(() => {
843
- T || (x.style.display = "none");
847
+ q ? (g.style.display = "flex", requestAnimationFrame(() => {
848
+ g.style.opacity = "1", g.style.transform = "scale(1)";
849
+ })) : (g.style.opacity = "0", g.style.transform = "scale(.95)", setTimeout(() => {
850
+ T || (g.style.display = "none");
844
851
  }, 180));
845
852
  };
846
853
  L.addEventListener("click", () => {
@@ -853,27 +860,27 @@ function Be(o) {
853
860
  T || (I++, h && (h.textContent = String(I), h.style.display = "flex"));
854
861
  }, A = () => {
855
862
  try {
856
- const n = new AudioContext(), p = n.createOscillator(), x = n.createGain();
857
- p.connect(x), x.connect(n.destination), p.frequency.setValueAtTime(880, n.currentTime), p.frequency.exponentialRampToValueAtTime(440, n.currentTime + 0.15), x.gain.setValueAtTime(0.3, n.currentTime), x.gain.exponentialRampToValueAtTime(1e-3, n.currentTime + 0.3), p.start(), p.stop(n.currentTime + 0.3);
863
+ const n = new AudioContext(), p = n.createOscillator(), g = n.createGain();
864
+ p.connect(g), g.connect(n.destination), p.frequency.setValueAtTime(880, n.currentTime), p.frequency.exponentialRampToValueAtTime(440, n.currentTime + 0.15), g.gain.setValueAtTime(0.3, n.currentTime), g.gain.exponentialRampToValueAtTime(1e-3, n.currentTime + 0.3), p.start(), p.stop(n.currentTime + 0.3);
858
865
  } catch {
859
866
  }
860
- }, z = [], P = (n) => {
861
- for (; z.length; ) {
862
- const p = z.shift();
867
+ }, P = [], z = (n) => {
868
+ for (; P.length; ) {
869
+ const p = P.shift();
863
870
  v.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), k.send({ type: "send", conversationId: n, clientMsgId: p.clientMsgId, content: p.content });
864
871
  }
865
872
  };
866
873
  let k;
867
- const m = new me(`ocw-e2e-${o.profileId}`);
874
+ const x = new me(`ocw-e2e-${o.profileId}`);
868
875
  let S = !1;
869
876
  const B = [], D = [];
870
877
  let Y = !1;
871
878
  const F = (n, p) => {
872
- m.sealText(p).then((x) => {
873
- r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: x });
879
+ x.sealText(p).then((g) => {
880
+ r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: g });
874
881
  });
875
- }, ie = (n, p, x) => {
876
- m.sealText(p, x).then((E) => {
882
+ }, ie = (n, p, g) => {
883
+ x.sealText(p, g).then((E) => {
877
884
  r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: E });
878
885
  });
879
886
  }, se = () => {
@@ -891,13 +898,13 @@ function Be(o) {
891
898
  ce.includes(le) && !o.el.dir && (o.el.dir = "rtl", o.el.style.fontFamily = o.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
892
899
  const K = new ke(), V = `oc_prechat_${o.profileId}_${a.slice(-8)}`, j = new Ee(o.el, a, {
893
900
  onSend(n) {
894
- const p = `cm_${Math.random().toString(36).slice(2)}`, x = { kind: "text", text: n };
895
- d.addOptimistic(p, x), j.render(d), d.e2e ? m.ready ? F(p, n) : Y ? D.push({ clientMsgId: p, text: n }) : (B.push({ clientMsgId: p, text: n }), d.assignedAgentId && ae(d.assignedAgentId)) : r ? (v.add({ clientMsgId: p, content: x, ts: Date.now() }), k.send({ type: "send", conversationId: r, clientMsgId: p, content: x })) : z.push({ clientMsgId: p, content: x });
901
+ const p = `cm_${Math.random().toString(36).slice(2)}`, g = { kind: "text", text: n };
902
+ d.addOptimistic(p, g), j.render(d), d.e2e ? x.ready ? F(p, n) : Y ? D.push({ clientMsgId: p, text: n }) : (B.push({ clientMsgId: p, text: n }), d.assignedAgentId && ae(d.assignedAgentId)) : r ? (v.add({ clientMsgId: p, content: g, ts: Date.now() }), k.send({ type: "send", conversationId: r, clientMsgId: p, content: g })) : P.push({ clientMsgId: p, content: g });
896
903
  },
897
904
  async onAttach(n) {
898
905
  if (!r) return;
899
- const p = `${b}/upload?name=${encodeURIComponent(n.name)}`, x = `cm_${Math.random().toString(36).slice(2)}`;
900
- d.addOptimistic(x, { kind: "text", text: `๐Ÿ“Ž Uploading ${n.name}โ€ฆ` }), j.render(d);
906
+ const p = `${b}/upload?name=${encodeURIComponent(n.name)}`, g = `cm_${Math.random().toString(36).slice(2)}`;
907
+ d.addOptimistic(g, { kind: "text", text: `๐Ÿ“Ž Uploading ${n.name}โ€ฆ` }), j.render(d);
901
908
  try {
902
909
  const E = await fetch(p, {
903
910
  method: "POST",
@@ -906,9 +913,9 @@ function Be(o) {
906
913
  });
907
914
  if (!E.ok) throw new Error(`Upload failed: ${E.status}`);
908
915
  const { url: O, name: N, mime: L, size: _ } = await E.json();
909
- k.send({ type: "send", conversationId: r, clientMsgId: x, content: { kind: "attachment", url: O, name: N, mime: L, size: _ } });
916
+ k.send({ type: "send", conversationId: r, clientMsgId: g, content: { kind: "attachment", url: O, name: N, mime: L, size: _ } });
910
917
  } catch (E) {
911
- d.addOptimistic(x, { kind: "text", text: `โš ๏ธ Upload failed: ${E.message}` }), j.render(d);
918
+ d.addOptimistic(g, { kind: "text", text: `โš ๏ธ Upload failed: ${E.message}` }), j.render(d);
912
919
  }
913
920
  },
914
921
  onInvoke(n, p) {
@@ -947,7 +954,7 @@ function Be(o) {
947
954
  return;
948
955
  }
949
956
  i = setTimeout(() => {
950
- fetch(`${b}/kb/search?profileId=${encodeURIComponent(o.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((x) => x.ok ? x.json() : { articles: [] }).then((x) => j.showDeflection(x.articles ?? [])).catch(() => j.hideDeflection());
957
+ fetch(`${b}/kb/search?profileId=${encodeURIComponent(o.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => j.showDeflection(g.articles ?? [])).catch(() => j.hideDeflection());
951
958
  }, 350);
952
959
  },
953
960
  onReadUpTo(n) {
@@ -964,8 +971,8 @@ function Be(o) {
964
971
  onDelete(n) {
965
972
  r && k.send({ type: "delete", conversationId: r, messageId: n });
966
973
  },
967
- onReact(n, p, x) {
968
- r && k.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: x });
974
+ onReact(n, p, g) {
975
+ r && k.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: g });
969
976
  },
970
977
  onCsat(n) {
971
978
  r && fetch(`${b}/conversations/${r}/csat`, {
@@ -990,13 +997,14 @@ function Be(o) {
990
997
  body: JSON.stringify({ text: n, targetLang: o.translateLang })
991
998
  });
992
999
  if (!p.ok) return null;
993
- const { translated: x } = await p.json();
994
- return x;
1000
+ const { translated: g } = await p.json();
1001
+ return g;
995
1002
  } catch {
996
1003
  return null;
997
1004
  }
998
1005
  }
999
- } : {}
1006
+ } : {},
1007
+ ...o.onBack ? { onBack: o.onBack } : {}
1000
1008
  }, {
1001
1009
  ...o.subject ? { subject: o.subject } : {},
1002
1010
  ...o.quickReplies ? { quickReplies: o.quickReplies } : {},
@@ -1043,45 +1051,45 @@ function Be(o) {
1043
1051
  for (const p of v.load())
1044
1052
  k.send({ type: "send", conversationId: r, clientMsgId: p.clientMsgId, content: p.content });
1045
1053
  }
1046
- we(f, a, r, d, j, b), z.length && P(r);
1054
+ we(f, a, r, d, j, b), P.length && z(r);
1047
1055
  }
1048
1056
  if (n.type === "ack" && v.remove(n.clientMsgId), n.type === "prekeyBundle") {
1049
- n.bundle && (Y = !0, m.x3dhSendTo(n.bundle).then((p) => {
1050
- const x = [...B.splice(0), ...D.splice(0)];
1051
- for (const E of x) ie(E.clientMsgId, E.text, p);
1057
+ n.bundle && (Y = !0, x.x3dhSendTo(n.bundle).then((p) => {
1058
+ const g = [...B.splice(0), ...D.splice(0)];
1059
+ for (const E of g) ie(E.clientMsgId, E.text, p);
1052
1060
  j.render(d);
1053
1061
  }));
1054
1062
  return;
1055
1063
  }
1056
1064
  if (n.type === "message" && d.e2e) {
1057
1065
  const p = ye(n.message.content);
1058
- if (p && !m.ready) {
1059
- m.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1060
- await m.openFrame(n), d.apply(n), j.render(d);
1066
+ if (p && !x.ready) {
1067
+ x.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1068
+ await x.openFrame(n), d.apply(n), j.render(d);
1061
1069
  });
1062
1070
  return;
1063
1071
  }
1064
1072
  }
1065
1073
  if (n.type === "peerkey") {
1066
- m.onPeerKey(n.key).then(() => {
1074
+ x.onPeerKey(n.key).then(() => {
1067
1075
  se(), j.render(d);
1068
1076
  });
1069
1077
  return;
1070
1078
  }
1071
1079
  (async () => {
1072
- if (d.e2e && await m.openFrame(n), d.apply(n), n.type === "message" && n.message.senderId !== a && !n.message.internal && ($(), A()), d.e2e && r && !S) {
1080
+ if (d.e2e && await x.openFrame(n), d.apply(n), n.type === "message" && n.message.senderId !== a && !n.message.internal && ($(), A()), d.e2e && r && !S) {
1073
1081
  S = !0;
1074
- const p = await m.initX3DH();
1082
+ const p = await x.initX3DH();
1075
1083
  k.send({ type: "uploadPrekeys", ...p });
1076
- const x = await m.begin();
1077
- k.send({ type: "pubkey", conversationId: r, key: x });
1084
+ const g = await x.begin();
1085
+ k.send({ type: "pubkey", conversationId: r, key: g });
1078
1086
  }
1079
1087
  j.render(d);
1080
1088
  })();
1081
1089
  }
1082
1090
  }), k.connect(), j.render(d);
1083
1091
  const M = o.launcher ? ne(o) : null, H = { close: () => {
1084
- s = !0, clearTimeout(i), k.close(), g == null || g.remove(), j.destroy(), K.destroy(), l && C && l.removeEventListener("change", C), R.delete(o.el), M && U.get(M) === H && U.delete(M);
1092
+ s = !0, clearTimeout(i), k.close(), m == null || m.remove(), j.destroy(), K.destroy(), l && C && l.removeEventListener("change", C), R.delete(o.el), M && U.get(M) === H && U.delete(M);
1085
1093
  } };
1086
1094
  return R.set(o.el, H), M && U.set(M, H), H;
1087
1095
  }