@paramms/chat-widget 1.0.35 โ 1.0.37
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/README.md +9 -1
- package/dist/chatlist.js +102 -62
- package/dist/chatlist.js.map +1 -1
- package/dist/codec.js +1135 -0
- package/dist/codec.js.map +1 -0
- package/dist/core.js +14 -14
- package/dist/core.js.map +1 -1
- package/dist/embed.js +4 -2
- package/dist/embed.js.map +1 -1
- package/dist/hooks.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +111 -98
- package/dist/index.js.map +1 -1
- package/dist/outbox.js +170 -1210
- package/dist/outbox.js.map +1 -1
- package/dist/protocol/frames.d.ts +5 -0
- package/dist/react.d.ts +9 -2
- package/dist/react.js +320 -294
- package/dist/react.js.map +1 -1
- package/dist/renderer.d.ts +5 -0
- package/package.json +1 -1
- package/dist/uid.js +0 -91
- package/dist/uid.js.map +0 -1
package/dist/hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState as d, useEffect as R, useRef as $, useSyncExternalStore as w, useMemo as h } from "react";
|
|
2
2
|
import { RelayClient as C } from "./core.js";
|
|
3
|
-
import { r as b, p as U } from "./
|
|
3
|
+
import { r as b, p as U } from "./codec.js";
|
|
4
4
|
function T(e) {
|
|
5
5
|
var c;
|
|
6
6
|
const l = `${e.url}|${e.token ?? ""}|${e.profileId}|${e.subjectId ?? ""}|${e.kind ?? ""}|${e.peerId ?? ""}`, o = $(null);
|
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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var pe = Object.defineProperty;
|
|
2
2
|
var he = (o, e, i) => e in o ? pe(o, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : o[e] = i;
|
|
3
3
|
var y = (o, e, i) => he(o, typeof e != "symbol" ? e + "" : e, i);
|
|
4
|
-
import { p as fe, r as ue, a as we } from "./
|
|
5
|
-
import { h as Me } from "./
|
|
4
|
+
import { p as fe, r as ue, a as we } from "./codec.js";
|
|
5
|
+
import { h as Me } from "./codec.js";
|
|
6
6
|
import { P as be, C as xe, b as ge } from "./outbox.js";
|
|
7
7
|
import { e as He } from "./outbox.js";
|
|
8
8
|
import { E2ESession as me, extractX3DHInit as ye } from "./e2e.js";
|
|
@@ -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
|
|
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")
|
|
300
|
-
if (
|
|
301
|
-
const
|
|
302
|
-
|
|
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) ?? ""), (
|
|
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
|
|
313
|
-
const S = t("button", void 0,
|
|
319
|
+
for (const x of a.quickReplies ?? []) {
|
|
320
|
+
const S = t("button", void 0, x);
|
|
314
321
|
S.addEventListener("click", () => {
|
|
315
|
-
this.h.onSend(
|
|
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", ((
|
|
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
|
|
322
|
-
this.storeRef && !this.storeRef.messages().some((B) => B.senderRole === "guest") ? (S = (
|
|
323
|
-
}), this.input.addEventListener("keydown", (
|
|
324
|
-
|
|
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
|
|
331
|
-
(
|
|
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
|
|
344
|
+
for (const x of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
|
|
338
345
|
const S = t("button", "ocw-cobrowse-swatch");
|
|
339
|
-
S.style.background =
|
|
340
|
-
this.cobrowseColor =
|
|
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
|
|
348
|
-
return (S = (
|
|
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,
|
|
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", (
|
|
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,
|
|
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 && ((
|
|
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"),
|
|
660
|
-
|
|
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(
|
|
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
|
|
675
|
-
if (
|
|
676
|
-
this.showingTranslation.add(e.id), w.textContent =
|
|
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
|
|
698
|
-
h.value =
|
|
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
|
|
708
|
-
T.addEventListener("click",
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
}), h.addEventListener("keydown", (
|
|
712
|
-
|
|
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", "๏ผ"),
|
|
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,
|
|
745
|
+
var A, P, z, k;
|
|
739
746
|
T.stopPropagation();
|
|
740
|
-
const $ = (
|
|
741
|
-
(k = (
|
|
742
|
-
}),
|
|
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
|
-
|
|
745
|
-
h.stopPropagation(),
|
|
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
|
-
|
|
748
|
-
}, { once: !0 }), l.append(C), u.append(l,
|
|
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" : ""}`,
|
|
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
|
|
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
|
|
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
|
-
|
|
793
|
-
const
|
|
794
|
-
|
|
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",
|
|
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),
|
|
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 ? (
|
|
841
|
-
|
|
842
|
-
})) : (
|
|
843
|
-
T || (
|
|
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(),
|
|
857
|
-
p.connect(
|
|
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
|
-
},
|
|
861
|
-
for (;
|
|
862
|
-
const p =
|
|
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
|
|
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
|
-
|
|
873
|
-
r && k.send({ type: "send", conversationId: r, clientMsgId: n, content:
|
|
879
|
+
x.sealText(p).then((g) => {
|
|
880
|
+
r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: g });
|
|
874
881
|
});
|
|
875
|
-
}, ie = (n, p,
|
|
876
|
-
|
|
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,24 +898,29 @@ 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)}`,
|
|
895
|
-
d.addOptimistic(p,
|
|
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)}`,
|
|
900
|
-
d.addOptimistic(
|
|
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",
|
|
904
|
-
|
|
911
|
+
// Use the resolved connection token (a signed JWT, an explicit userId,
|
|
912
|
+
// or the anonymous persistent uid) โ NOT just opts.token. The server
|
|
913
|
+
// requires an Authorization header, and the verifier accepts an
|
|
914
|
+
// anonymous id as a guest; keying off opts.token alone meant anonymous
|
|
915
|
+
// visitors (the common case) sent no auth and every upload 401'd.
|
|
916
|
+
headers: { "content-type": n.type, authorization: `Bearer ${a}` },
|
|
905
917
|
body: n
|
|
906
918
|
});
|
|
907
919
|
if (!E.ok) throw new Error(`Upload failed: ${E.status}`);
|
|
908
920
|
const { url: O, name: N, mime: L, size: _ } = await E.json();
|
|
909
|
-
k.send({ type: "send", conversationId: r, clientMsgId:
|
|
921
|
+
k.send({ type: "send", conversationId: r, clientMsgId: g, content: { kind: "attachment", url: O, name: N, mime: L, size: _ } });
|
|
910
922
|
} catch (E) {
|
|
911
|
-
d.addOptimistic(
|
|
923
|
+
d.addOptimistic(g, { kind: "text", text: `โ ๏ธ Upload failed: ${E.message}` }), j.render(d);
|
|
912
924
|
}
|
|
913
925
|
},
|
|
914
926
|
onInvoke(n, p) {
|
|
@@ -947,7 +959,7 @@ function Be(o) {
|
|
|
947
959
|
return;
|
|
948
960
|
}
|
|
949
961
|
i = setTimeout(() => {
|
|
950
|
-
fetch(`${b}/kb/search?profileId=${encodeURIComponent(o.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((
|
|
962
|
+
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
963
|
}, 350);
|
|
952
964
|
},
|
|
953
965
|
onReadUpTo(n) {
|
|
@@ -964,8 +976,8 @@ function Be(o) {
|
|
|
964
976
|
onDelete(n) {
|
|
965
977
|
r && k.send({ type: "delete", conversationId: r, messageId: n });
|
|
966
978
|
},
|
|
967
|
-
onReact(n, p,
|
|
968
|
-
r && k.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove:
|
|
979
|
+
onReact(n, p, g) {
|
|
980
|
+
r && k.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: g });
|
|
969
981
|
},
|
|
970
982
|
onCsat(n) {
|
|
971
983
|
r && fetch(`${b}/conversations/${r}/csat`, {
|
|
@@ -990,13 +1002,14 @@ function Be(o) {
|
|
|
990
1002
|
body: JSON.stringify({ text: n, targetLang: o.translateLang })
|
|
991
1003
|
});
|
|
992
1004
|
if (!p.ok) return null;
|
|
993
|
-
const { translated:
|
|
994
|
-
return
|
|
1005
|
+
const { translated: g } = await p.json();
|
|
1006
|
+
return g;
|
|
995
1007
|
} catch {
|
|
996
1008
|
return null;
|
|
997
1009
|
}
|
|
998
1010
|
}
|
|
999
|
-
} : {}
|
|
1011
|
+
} : {},
|
|
1012
|
+
...o.onBack ? { onBack: o.onBack } : {}
|
|
1000
1013
|
}, {
|
|
1001
1014
|
...o.subject ? { subject: o.subject } : {},
|
|
1002
1015
|
...o.quickReplies ? { quickReplies: o.quickReplies } : {},
|
|
@@ -1043,45 +1056,45 @@ function Be(o) {
|
|
|
1043
1056
|
for (const p of v.load())
|
|
1044
1057
|
k.send({ type: "send", conversationId: r, clientMsgId: p.clientMsgId, content: p.content });
|
|
1045
1058
|
}
|
|
1046
|
-
we(f, a, r, d, j, b),
|
|
1059
|
+
we(f, a, r, d, j, b), P.length && z(r);
|
|
1047
1060
|
}
|
|
1048
1061
|
if (n.type === "ack" && v.remove(n.clientMsgId), n.type === "prekeyBundle") {
|
|
1049
|
-
n.bundle && (Y = !0,
|
|
1050
|
-
const
|
|
1051
|
-
for (const E of
|
|
1062
|
+
n.bundle && (Y = !0, x.x3dhSendTo(n.bundle).then((p) => {
|
|
1063
|
+
const g = [...B.splice(0), ...D.splice(0)];
|
|
1064
|
+
for (const E of g) ie(E.clientMsgId, E.text, p);
|
|
1052
1065
|
j.render(d);
|
|
1053
1066
|
}));
|
|
1054
1067
|
return;
|
|
1055
1068
|
}
|
|
1056
1069
|
if (n.type === "message" && d.e2e) {
|
|
1057
1070
|
const p = ye(n.message.content);
|
|
1058
|
-
if (p && !
|
|
1059
|
-
|
|
1060
|
-
await
|
|
1071
|
+
if (p && !x.ready) {
|
|
1072
|
+
x.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
|
|
1073
|
+
await x.openFrame(n), d.apply(n), j.render(d);
|
|
1061
1074
|
});
|
|
1062
1075
|
return;
|
|
1063
1076
|
}
|
|
1064
1077
|
}
|
|
1065
1078
|
if (n.type === "peerkey") {
|
|
1066
|
-
|
|
1079
|
+
x.onPeerKey(n.key).then(() => {
|
|
1067
1080
|
se(), j.render(d);
|
|
1068
1081
|
});
|
|
1069
1082
|
return;
|
|
1070
1083
|
}
|
|
1071
1084
|
(async () => {
|
|
1072
|
-
if (d.e2e && await
|
|
1085
|
+
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
1086
|
S = !0;
|
|
1074
|
-
const p = await
|
|
1087
|
+
const p = await x.initX3DH();
|
|
1075
1088
|
k.send({ type: "uploadPrekeys", ...p });
|
|
1076
|
-
const
|
|
1077
|
-
k.send({ type: "pubkey", conversationId: r, key:
|
|
1089
|
+
const g = await x.begin();
|
|
1090
|
+
k.send({ type: "pubkey", conversationId: r, key: g });
|
|
1078
1091
|
}
|
|
1079
1092
|
j.render(d);
|
|
1080
1093
|
})();
|
|
1081
1094
|
}
|
|
1082
1095
|
}), k.connect(), j.render(d);
|
|
1083
1096
|
const M = o.launcher ? ne(o) : null, H = { close: () => {
|
|
1084
|
-
s = !0, clearTimeout(i), k.close(),
|
|
1097
|
+
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
1098
|
} };
|
|
1086
1099
|
return R.set(o.el, H), M && U.set(M, H), H;
|
|
1087
1100
|
}
|