@paramms/chat-widget 1.0.43 → 1.0.45
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 +5 -4
- package/dist/chatlist.d.ts +2 -1
- package/dist/chatlist.js +137 -115
- package/dist/chatlist.js.map +1 -1
- package/dist/chatlist.styles.d.ts +1 -0
- package/dist/codec.js +191 -157
- package/dist/codec.js.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/e2e.d.ts +21 -2
- package/dist/e2e.js +50 -40
- package/dist/e2e.js.map +1 -1
- package/dist/embed-lite.js +242 -0
- package/dist/embed-lite.js.map +1 -0
- package/dist/embed.d.ts +8 -0
- package/dist/embed.js +87 -78
- package/dist/embed.js.map +1 -1
- package/dist/history.d.ts +7 -4
- package/dist/index.d.ts +20 -0
- package/dist/index.js +632 -723
- package/dist/index.js.map +1 -1
- package/dist/outbox.js +65 -75
- package/dist/outbox.js.map +1 -1
- package/dist/protocol/entities.d.ts +0 -11
- package/dist/protocol/frames.d.ts +1 -17
- package/dist/react.d.ts +13 -5
- package/dist/react.js +225 -211
- package/dist/react.js.map +1 -1
- package/dist/renderer.d.ts +14 -19
- package/dist/renderer.styles.d.ts +1 -0
- package/dist/store.d.ts +1 -5
- package/dist/theme-tokens.d.ts +4 -0
- package/package.json +2 -2
- package/dist/annotations.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -1,63 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { p as
|
|
5
|
-
import { h as
|
|
6
|
-
import { P as
|
|
7
|
-
import { e as
|
|
8
|
-
import { E2ESession as
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
constructor() {
|
|
12
|
-
y(this, "svg", null);
|
|
13
|
-
y(this, "timers", /* @__PURE__ */ new Set());
|
|
14
|
-
}
|
|
15
|
-
/** Feed every server frame; the overlay reacts to annotation frames only. */
|
|
16
|
-
apply(e) {
|
|
17
|
-
var i;
|
|
18
|
-
if (e.type === "annotation") this.draw(e.stroke);
|
|
19
|
-
else if (e.type === "annotation_clear") this.clear();
|
|
20
|
-
else if (e.type === "opened" && ((i = e.annotations) != null && i.length))
|
|
21
|
-
for (const s of e.annotations) this.draw(s);
|
|
22
|
-
}
|
|
23
|
-
ensureSvg() {
|
|
24
|
-
var i;
|
|
25
|
-
if ((i = this.svg) != null && i.isConnected) return this.svg;
|
|
26
|
-
const e = document.createElementNS(xe, "svg");
|
|
27
|
-
return e.setAttribute("data-relay-annotations", ""), e.setAttribute("aria-hidden", "true"), e.setAttribute(
|
|
28
|
-
"style",
|
|
29
|
-
"position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483000;"
|
|
30
|
-
), document.body.append(e), this.svg = e, e;
|
|
31
|
-
}
|
|
32
|
-
draw(e) {
|
|
33
|
-
var b;
|
|
34
|
-
if (typeof document > "u" || !((b = e.points) != null && b.length)) return;
|
|
35
|
-
const i = this.ensureSvg(), s = window.innerWidth, a = window.innerHeight, c = document.createElementNS(xe, "polyline");
|
|
36
|
-
c.setAttribute("points", e.points.map((d) => `${(d.x * s).toFixed(1)},${(d.y * a).toFixed(1)}`).join(" ")), c.setAttribute("fill", "none"), c.setAttribute("stroke", e.color || "#ff3b30"), c.setAttribute("stroke-width", String(e.width || 3)), c.setAttribute("stroke-linecap", "round"), c.setAttribute("stroke-linejoin", "round"), c.setAttribute("data-stroke-id", e.id), i.append(c);
|
|
37
|
-
const w = setTimeout(() => {
|
|
38
|
-
c.style.transition = "opacity 600ms", c.style.opacity = "0";
|
|
39
|
-
const d = setTimeout(() => {
|
|
40
|
-
c.remove(), this.timers.delete(d);
|
|
41
|
-
}, 650);
|
|
42
|
-
this.timers.add(d), this.timers.delete(w);
|
|
43
|
-
}, De);
|
|
44
|
-
this.timers.add(w);
|
|
45
|
-
}
|
|
46
|
-
clear() {
|
|
47
|
-
var e;
|
|
48
|
-
(e = this.svg) == null || e.replaceChildren();
|
|
49
|
-
}
|
|
50
|
-
destroy() {
|
|
51
|
-
var e;
|
|
52
|
-
for (const i of this.timers) clearTimeout(i);
|
|
53
|
-
this.timers.clear(), (e = this.svg) == null || e.remove(), this.svg = null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "😢", "🙏"], _e = 400, Fe = '<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>', Ue = `
|
|
57
|
-
.ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;
|
|
1
|
+
var Pe = Object.defineProperty;
|
|
2
|
+
var $e = (t, e, l) => e in t ? Pe(t, e, { enumerable: !0, configurable: !0, writable: !0, value: l }) : t[e] = l;
|
|
3
|
+
var T = (t, e, l) => $e(t, typeof e != "symbol" ? e + "" : e, l);
|
|
4
|
+
import { l as Be, b as ge, p as Me, r as Re, a as Ae } from "./codec.js";
|
|
5
|
+
import { h as rt } from "./codec.js";
|
|
6
|
+
import { P as qe, C as Ne, b as Oe } from "./outbox.js";
|
|
7
|
+
import { e as st } from "./outbox.js";
|
|
8
|
+
import { E2ESession as De, extractX3DHInit as He } from "./e2e.js";
|
|
9
|
+
const _e = `
|
|
10
|
+
.ocw { ${Be("ocw")}
|
|
58
11
|
position:relative;
|
|
59
12
|
display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
|
|
60
|
-
font-family
|
|
13
|
+
font-family:var(--ocw-fb); color:var(--ocw-ink); overflow:hidden; }
|
|
14
|
+
@media (prefers-color-scheme: dark) { .ocw:not([data-theme="light"]) { ${ge("ocw")} } }
|
|
15
|
+
.ocw[data-theme="dark"] { ${ge("ocw")} }
|
|
61
16
|
/* ── Responsive sizing ──────────────────────────────────────────────────────
|
|
62
17
|
* Sizing is driven by the WIDGET'S OWN width (ResizeObserver toggles
|
|
63
18
|
* .ocw-compact below 400px), not the viewport — so a widget embedded in a
|
|
@@ -79,38 +34,45 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
79
34
|
/* RTL support: when the host element has dir=rtl, flip layout direction */
|
|
80
35
|
[dir="rtl"] .ocw-row.mine { flex-direction:row; }
|
|
81
36
|
[dir="rtl"] .ocw-row.theirs { flex-direction:row-reverse; }
|
|
82
|
-
[dir="rtl"] .mine .ocw-bubble { border-bottom-right-radius:18px; border-bottom-left-radius:
|
|
83
|
-
[dir="rtl"] .theirs .ocw-bubble { border-bottom-left-radius:18px; border-bottom-right-radius:
|
|
37
|
+
[dir="rtl"] .mine .ocw-bubble { border-bottom-right-radius:18px; border-bottom-left-radius:4px; }
|
|
38
|
+
[dir="rtl"] .theirs .ocw-bubble { border-bottom-left-radius:18px; border-bottom-right-radius:4px; }
|
|
84
39
|
[dir="rtl"] .ocw-input { flex-direction:row-reverse; }
|
|
85
40
|
[dir="rtl"] .mine .ocw-meta { text-align:left; }
|
|
86
41
|
.ocw-head { display:flex; align-items:center; gap:10px; padding:12px 14px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); }
|
|
87
42
|
.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; }
|
|
88
43
|
.ocw-back:hover { background:var(--ocw-bg); }
|
|
89
|
-
.ocw-avatar { width:34px; height:34px; border-radius:50%; background
|
|
44
|
+
.ocw-avatar { width:34px; height:34px; border-radius:50%; background:var(--ocw-tint); color:var(--ocw-accent); font-family:var(--ocw-fh); font-weight:600; display:flex; align-items:center; justify-content:center; font-size:13px; flex:none; }
|
|
90
45
|
.ocw-head-main { flex:1; min-width:0; }
|
|
91
|
-
.ocw-head-name { font-weight:
|
|
46
|
+
.ocw-head-name { font-family:var(--ocw-fh); font-weight:600; font-size:15px; }
|
|
92
47
|
.ocw-head-meta { color:var(--ocw-mut); font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
93
|
-
.ocw-
|
|
94
|
-
.ocw-
|
|
95
|
-
.ocw-
|
|
48
|
+
.ocw-head-status { font-size:10.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
|
49
|
+
.ocw-head-status.online { color:#5cb37a; }
|
|
50
|
+
.ocw-head-status.away { color:#c98b2e; }
|
|
51
|
+
.ocw-msg-sender { font-size:10px; color:var(--ocw-mut); margin-bottom:2px; }
|
|
52
|
+
.ocw-resolved-note { text-align:center; font-size:10.5px; color:var(--ocw-mut); margin:6px 0 12px; }
|
|
53
|
+
.ocw-reopen { display:none; width:calc(100% - 32px); margin:0 16px 14px; height:40px; border:1.5px solid var(--ocw-accent); color:var(--ocw-accent); background:none; border-radius:20px; font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
|
|
54
|
+
.ocw-reopen:hover { background:var(--ocw-tint); }
|
|
55
|
+
.ocw-badge { font-size:11px; font-weight:600; color:#2f8a52; background:#eafaf0; border-radius:20px; padding:5px 12px; }
|
|
56
|
+
.ocw-e2e { font-size:11px; font-weight:700; color:var(--ocw-accent); background:var(--ocw-tint); border-radius:20px; padding:5px 12px; align-items:center; }
|
|
57
|
+
.ocw-menu { color:var(--ocw-mut); width:30px; height:30px; border-radius:50%; border:1px solid var(--ocw-line); background:var(--ocw-card); cursor:pointer; }
|
|
96
58
|
.ocw-chiprow { display:flex; gap:8px; padding:10px 12px; background:var(--ocw-card); border-bottom:1px solid var(--ocw-line); overflow-x:auto; }
|
|
97
|
-
.ocw-chip { flex:none; display:flex; align-items:center; gap:6px; border:
|
|
59
|
+
.ocw-chip { flex:none; display:flex; align-items:center; gap:6px; border:none; background:var(--ocw-tint); color:var(--ocw-accent); border-radius:999px; padding:7px 13px; font-size:12px; font-weight:600; cursor:pointer; white-space:nowrap; }
|
|
98
60
|
.ocw-chip:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
|
|
99
61
|
.ocw-scroll { flex:1; min-height:0; overflow-y:auto; padding:16px 14px; display:flex; flex-direction:column; gap:10px; }
|
|
100
|
-
.ocw-subject { background:var(--ocw-
|
|
101
|
-
.ocw-subject-title { font-weight:
|
|
102
|
-
.ocw-subject-sub { color:var(--ocw-mut); font-size:
|
|
62
|
+
.ocw-subject { background:var(--ocw-tint); border:none; border-radius:16px; padding:10px 12px; }
|
|
63
|
+
.ocw-subject-title { font-family:var(--ocw-fh); font-weight:600; font-size:13px; margin-bottom:2px; }
|
|
64
|
+
.ocw-subject-sub { color:var(--ocw-mut); font-size:10.5px; margin-bottom:6px; }
|
|
103
65
|
.ocw-tags { display:flex; flex-wrap:wrap; gap:6px; }
|
|
104
66
|
.ocw-tag { font-size:12px; color:#5b554e; background:#efeae3; border-radius:8px; padding:4px 10px; }
|
|
105
67
|
.ocw-row { display:flex; align-items:flex-end; gap:8px; max-width:86%; }
|
|
106
68
|
.ocw-row.mine { align-self:flex-end; flex-direction:row-reverse; }
|
|
107
69
|
.ocw-row.theirs { align-self:flex-start; }
|
|
108
|
-
.ocw-dot { width:26px; height:26px; border-radius:50%; background:var(--ocw-
|
|
109
|
-
.ocw-bubble { padding:10px 14px; border-radius:18px; font-size:
|
|
110
|
-
.theirs .ocw-bubble { background
|
|
111
|
-
.mine .ocw-bubble { background:var(--ocw-
|
|
70
|
+
.ocw-dot { width:26px; height:26px; border-radius:50%; background:var(--ocw-tint); color:var(--ocw-accent); font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; }
|
|
71
|
+
.ocw-bubble { padding:10px 14px; border-radius:18px; font-size:13.5px; line-height:1.45; word-wrap:break-word; max-width:80%; }
|
|
72
|
+
.theirs .ocw-bubble { background:var(--ocw-tint); border-bottom-left-radius:4px; }
|
|
73
|
+
.mine .ocw-bubble { background:var(--ocw-accent2); color:#fff; border-bottom-right-radius:4px; }
|
|
112
74
|
.ocw-sys { align-self:center; color:var(--ocw-mut); font-size:12.5px; font-style:italic; text-align:center; max-width:90%; }
|
|
113
|
-
.ocw-bot .ocw-bubble { background
|
|
75
|
+
.ocw-bot .ocw-bubble { background:var(--ocw-tint); }
|
|
114
76
|
.ocw-note .ocw-bubble { background:#fffbeb; border:1.5px dashed #f59e0b; color:#78350f; border-radius:12px !important; }
|
|
115
77
|
.ocw-note .ocw-bubble::before { content:'🔒 Note — '; font-size:11px; font-weight:700; color:#b45309; display:block; margin-bottom:3px; letter-spacing:.3px; }
|
|
116
78
|
.ocw-time { font-size:10.5px; color:var(--ocw-mut); margin-top:3px; }
|
|
@@ -121,20 +83,20 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
121
83
|
.ocw-deleted { font-style:italic; color:var(--ocw-mut); }
|
|
122
84
|
.ocw-edited { font-size:10px; color:var(--ocw-mut); margin-left:4px; }
|
|
123
85
|
.ocw-react { font-size:12px; margin-top:3px; display:flex; flex-wrap:wrap; gap:3px; }
|
|
124
|
-
.ocw-react-pill { display:inline-flex; align-items:center; gap:3px; border:1px solid
|
|
86
|
+
.ocw-react-pill { display:inline-flex; align-items:center; gap:3px; border:1px solid var(--ocw-line); border-radius:999px; padding:2px 7px; background:var(--ocw-card); font-size:12px; cursor:pointer; }
|
|
125
87
|
.ocw-react-pill:hover { border-color:var(--ocw-accent); }
|
|
126
88
|
.ocw-react-pill.mine { border-color:var(--ocw-accent); background:#fff8f5; }
|
|
127
89
|
.ocw-react-wrap { position:relative; }
|
|
128
90
|
.ocw-react-wrap:not(:hover) .ocw-react-picker { display:none; }
|
|
129
|
-
.ocw-react-picker { position:absolute; bottom:calc(100% + 4px); left:0; background
|
|
91
|
+
.ocw-react-picker { position:absolute; bottom:calc(100% + 4px); left:0; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; padding:6px 8px; box-shadow:0 4px 16px rgba(0,0,0,.12); display:flex; gap:4px; z-index:10; white-space:nowrap; }
|
|
130
92
|
.ocw-react-picker button { background:none; border:none; font-size:16px; cursor:pointer; padding:2px; border-radius:6px; }
|
|
131
|
-
.ocw-react-picker button:hover { background
|
|
132
|
-
.ocw-react-btn { background:none; border:1px solid
|
|
93
|
+
.ocw-react-picker button:hover { background:var(--ocw-bg); }
|
|
94
|
+
.ocw-react-btn { background:none; border:1px solid var(--ocw-line); border-radius:999px; padding:2px 7px; font-size:12px; cursor:pointer; color:var(--ocw-mut); }
|
|
133
95
|
.ocw-react-btn:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
|
|
134
96
|
.ocw-msg-menu { position:absolute; top:0; right:0; display:none; gap:3px; }
|
|
135
97
|
.ocw-row.mine:hover .ocw-msg-menu { display:flex; }
|
|
136
98
|
.ocw-row.theirs:hover .ocw-msg-menu { display:flex; left:0; right:auto; }
|
|
137
|
-
.ocw-msg-menu button { background
|
|
99
|
+
.ocw-msg-menu button { background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:6px; font-size:11px; padding:2px 6px; cursor:pointer; color:var(--ocw-mut); }
|
|
138
100
|
.ocw-msg-menu button:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
|
|
139
101
|
.ocw-msg-menu button.del:hover { border-color:#e74c3c; color:#e74c3c; }
|
|
140
102
|
.ocw-bubble-wrap { position:relative; }
|
|
@@ -146,25 +108,32 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
146
108
|
.ocw-appt-desc { font-size:12px; color:var(--ocw-mut); margin-bottom:10px; white-space:pre-wrap; }
|
|
147
109
|
.ocw-appt-links { display:flex; flex-direction:column; gap:6px; }
|
|
148
110
|
.ocw-appt-btn { display:block; text-align:center; padding:8px 12px; border-radius:8px; font-size:13px; font-weight:600; text-decoration:none; background:var(--ocw-accent); color:#fff; }
|
|
149
|
-
.ocw-appt-btn-sec { background
|
|
111
|
+
.ocw-appt-btn-sec { background:var(--ocw-card); color:var(--ocw-accent); border:1px solid var(--ocw-accent); }
|
|
150
112
|
.ocw-conn-status { font-size:10px; color:var(--ocw-mut); margin-left:4px; }
|
|
151
113
|
.ocw-conn-status.warn { color:#e67e22; }
|
|
152
114
|
.ocw-conn-status.err { color:#c0392b; font-weight:600; }
|
|
153
|
-
.ocw-load-more { display:block; width:100%; background:none; border:1px solid
|
|
115
|
+
.ocw-load-more { display:block; width:100%; background:none; border:1px solid var(--ocw-line); border-radius:10px; padding:6px 0; font-size:12px; color:var(--ocw-mut); cursor:pointer; margin-bottom:8px; }
|
|
154
116
|
.ocw-load-more:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
|
|
155
117
|
.ocw-away { margin:0 14px 8px; padding:9px 12px; background:#fff8e6; border:1px solid #f0e2bd; border-radius:10px; font-size:12px; color:#7a5c17; display:flex; gap:7px; align-items:flex-start; line-height:1.45; }
|
|
118
|
+
.ocw button:focus-visible, .ocw textarea:focus-visible, .ocw a:focus-visible, .ocw [tabindex]:focus-visible { outline:2px solid var(--ocw-accent); outline-offset:2px; border-radius:8px; }
|
|
119
|
+
.ocw-sendbtn:active { transform:scale(.92); }
|
|
120
|
+
.ocw-quick button:active, .ocw-chip:active { transform:scale(.97); }
|
|
121
|
+
@media (prefers-color-scheme: dark) { .ocw:not([data-theme="light"]) .ocw-away { background:#3a3018; border-color:#5a4a1f; color:#e8d9a8; } .ocw:not([data-theme="light"]) .ocw-note .ocw-bubble { background:#332b12; border-color:#7a5c17; color:#f0e2bd; } .ocw:not([data-theme="light"]) .ocw-note .ocw-bubble::before { color:#e0c060; } }
|
|
122
|
+
.ocw[data-theme="dark"] .ocw-away { background:#3a3018; border-color:#5a4a1f; color:#e8d9a8; }
|
|
123
|
+
.ocw[data-theme="dark"] .ocw-note .ocw-bubble { background:#332b12; border-color:#7a5c17; color:#f0e2bd; }
|
|
124
|
+
.ocw[data-theme="dark"] .ocw-note .ocw-bubble::before { color:#e0c060; }
|
|
156
125
|
.ocw-away-icon { flex:none; }
|
|
157
126
|
/* Shared form styles (used by the pre-chat panel; named for the retired offline form). */
|
|
158
127
|
.ocw-offline-form { display:flex; flex-direction:column; gap:8px; text-align:left; }
|
|
159
|
-
.ocw-offline-input { border:
|
|
160
|
-
.ocw-offline-input:focus { outline:none;
|
|
161
|
-
.ocw-offline-submit { background:var(--ocw-accent); color
|
|
162
|
-
.ocw-prechat { margin:
|
|
163
|
-
.ocw-prechat-title { font-weight:
|
|
164
|
-
.ocw-prechat select { border:
|
|
128
|
+
.ocw-offline-input { border:none; background:var(--ocw-tint); border-radius:14px; padding:10px 12px; font-size:13px; font-family:inherit; color:var(--ocw-ink); }
|
|
129
|
+
.ocw-offline-input:focus { outline:none; box-shadow:inset 0 0 0 1.5px var(--ocw-accent); }
|
|
130
|
+
.ocw-offline-submit { background:var(--ocw-accent); color:var(--ocw-onaccent); border:none; border-radius:20px; padding:11px; font-family:var(--ocw-fh); font-size:13.5px; font-weight:600; cursor:pointer; box-shadow:var(--ocw-shadow); }
|
|
131
|
+
.ocw-prechat { margin:16px; padding:0; background:none; border:none; }
|
|
132
|
+
.ocw-prechat-title { font-family:var(--ocw-fh); font-weight:600; font-size:20px; margin-bottom:10px; }
|
|
133
|
+
.ocw-prechat select { border:none; border-radius:14px; padding:10px 12px; font:inherit; font-size:13px; background:var(--ocw-tint); color:var(--ocw-ink); }
|
|
165
134
|
.ocw-prechat-cb { display:flex; align-items:center; gap:8px; font-size:13px; color:var(--ocw-ink); }
|
|
166
135
|
.ocw-deflect { margin:0 14px 8px; display:flex; flex-direction:column; gap:6px; }
|
|
167
|
-
.ocw-deflect-card { text-align:left; background
|
|
136
|
+
.ocw-deflect-card { text-align:left; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:12px; padding:10px 12px; font:inherit; font-size:13px; cursor:pointer; }
|
|
168
137
|
.ocw-deflect-card:hover { border-color:var(--ocw-accent); }
|
|
169
138
|
.ocw-deflect-q { font-weight:600; margin-bottom:2px; }
|
|
170
139
|
.ocw-deflect-a { color:var(--ocw-mut); font-size:12.5px; display:none; white-space:pre-wrap; }
|
|
@@ -177,7 +146,7 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
177
146
|
.ocw-csat-done { font-size:12px; color:var(--ocw-mut); margin-top:6px; }
|
|
178
147
|
|
|
179
148
|
.ocw-typing { min-height:22px; padding:0 16px 4px; display:flex; align-items:center; }
|
|
180
|
-
.ocw-typing-bubble { display:none; align-items:center; gap:3px; background
|
|
149
|
+
.ocw-typing-bubble { display:none; align-items:center; gap:3px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; border-bottom-left-radius:4px; padding:7px 12px; }
|
|
181
150
|
.ocw-typing.active .ocw-typing-bubble { display:flex; }
|
|
182
151
|
.ocw-typing-dot { width:6px; height:6px; border-radius:50%; background:var(--ocw-mut); animation:ocw-bounce 1.2s infinite ease-in-out; }
|
|
183
152
|
.ocw-typing-dot:nth-child(2) { animation-delay:.2s; }
|
|
@@ -185,20 +154,20 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
185
154
|
@keyframes ocw-bounce { 0%,60%,100%{transform:translateY(0)} 30%{transform:translateY(-5px)} }
|
|
186
155
|
.ocw-quick { display:flex; gap:8px; padding:8px 12px 6px; overflow-x:auto; scrollbar-width:none; flex-shrink:0; }
|
|
187
156
|
.ocw-quick::-webkit-scrollbar { display:none; }
|
|
188
|
-
.ocw-quick button { flex:none; border:
|
|
189
|
-
.ocw-quick button:hover {
|
|
157
|
+
.ocw-quick button { flex:none; border:none; background:var(--ocw-tint); border-radius:999px; padding:7px 14px; font-size:12px; font-weight:600; cursor:pointer; color:var(--ocw-accent); white-space:nowrap; transition:background .12s,color .12s; }
|
|
158
|
+
.ocw-quick button:hover { background:var(--ocw-accent); color:var(--ocw-onaccent); }
|
|
190
159
|
.ocw-form-host:empty { display:none; }
|
|
191
160
|
.ocw-form { margin:6px 12px 0; padding:12px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:14px; }
|
|
192
161
|
.ocw-form-title { font-weight:700; font-size:14px; margin-bottom:8px; }
|
|
193
162
|
.ocw-form-row { display:flex; flex-direction:column; gap:3px; margin-bottom:8px; }
|
|
194
163
|
.ocw-form-lbl { font-size:12px; color:var(--ocw-mut); }
|
|
195
|
-
.ocw-form-input { border:1px solid
|
|
164
|
+
.ocw-form-input { border:1px solid var(--ocw-line); border-radius:9px; padding:9px 11px; font:inherit; font-size:14px; outline:none; }
|
|
196
165
|
.ocw-form-input:focus { border-color:var(--ocw-accent); }
|
|
197
166
|
.ocw-form-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:4px; }
|
|
198
167
|
.ocw-form-cancel { background:none; border:none; color:var(--ocw-mut); font-size:13px; cursor:pointer; padding:8px 10px; }
|
|
199
168
|
.ocw-form-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:999px; padding:8px 18px; font-size:13px; font-weight:600; cursor:pointer; }
|
|
200
169
|
.ocw-modal { position:absolute; inset:0; background:rgba(20,18,16,.42); display:flex; align-items:center; justify-content:center; z-index:50; }
|
|
201
|
-
.ocw-modal-card { background
|
|
170
|
+
.ocw-modal-card { background:var(--ocw-card); border-radius:16px; padding:20px; width:78%; max-width:300px; box-shadow:0 14px 44px rgba(0,0,0,.22); }
|
|
202
171
|
.ocw-modal-title { font-weight:700; font-size:16px; margin-bottom:6px; }
|
|
203
172
|
.ocw-modal-body { color:var(--ocw-mut); font-size:14px; margin-bottom:16px; }
|
|
204
173
|
.ocw-modal-actions { display:flex; justify-content:flex-end; gap:8px; }
|
|
@@ -210,55 +179,42 @@ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "
|
|
|
210
179
|
.ocw-footer a:hover { color:var(--ocw-accent); }
|
|
211
180
|
.ocw-attach { background:none;border:none;cursor:pointer;font-size:18px;padding:4px 6px;opacity:.6;flex-none; }
|
|
212
181
|
.ocw-attach:hover { opacity:1; }
|
|
213
|
-
.ocw-input textarea { flex:1; min-width:0; resize:none; border:
|
|
214
|
-
.ocw-input textarea:focus {
|
|
182
|
+
.ocw-input textarea { flex:1; min-width:0; resize:none; border:none; border-radius:20px; padding:11px 16px; font:inherit; font-size:14px; line-height:1.4; background:var(--ocw-tint); outline:none; max-height:120px; overflow-y:auto; }
|
|
183
|
+
.ocw-input textarea:focus { box-shadow:inset 0 0 0 1.5px var(--ocw-accent); }
|
|
215
184
|
/* Send button auto-sizes to its label: the default is a fixed circle around an
|
|
216
185
|
* inline SVG; a TEXT label (i18n.send: "Send", "보내기", "Enviar"…) switches to
|
|
217
186
|
* .ocw-sendbtn-label — a pill whose width follows the text. A fixed 42px
|
|
218
187
|
* circle with 18px type overflowed the moment anyone localized the label. */
|
|
219
|
-
.ocw-sendbtn { min-width:
|
|
188
|
+
.ocw-sendbtn { min-width:38px; height:38px; border-radius:999px; border:none; background:var(--ocw-accent2); color:#fff; font:inherit; font-size:14px; font-weight:600; cursor:pointer; flex:none; display:flex; align-items:center; justify-content:center; padding:0; transition:opacity .15s, transform .1s; }
|
|
220
189
|
.ocw-sendbtn-label { padding:0 16px; white-space:nowrap; }
|
|
221
190
|
.ocw-sendbtn svg { width:19px; height:19px; display:block; }
|
|
222
191
|
.ocw-sendbtn:not(:disabled):hover { transform:scale(1.05); }
|
|
223
192
|
.ocw-sendbtn:not(:disabled):active { transform:scale(.96); }
|
|
224
193
|
.ocw-sendbtn:disabled { opacity:.5; cursor:default; }
|
|
225
194
|
.ocw-sendbtn:focus-visible, .ocw-back:focus-visible, .ocw-chip:focus-visible { outline:2px solid var(--ocw-accent); outline-offset:2px; }
|
|
226
|
-
.ocw-cobrowse-btn { display:none; }
|
|
227
|
-
.ocw-cobrowse-btn.show { display:inline-flex; }
|
|
228
|
-
.ocw-cobrowse-btn.on { color:var(--ocw-accent); border-color:var(--ocw-accent); }
|
|
229
|
-
.ocw-cobrowse-canvas { position:absolute; inset:0; z-index:40; touch-action:none; display:none; }
|
|
230
|
-
.ocw-cobrowse-canvas.active { display:block; cursor:crosshair; }
|
|
231
|
-
.ocw-cobrowse-toolbar { position:absolute; top:8px; right:8px; z-index:41; display:none; gap:6px; background:rgba(255,255,255,.92); border-radius:999px; padding:5px 8px; box-shadow:0 2px 10px rgba(0,0,0,.12); }
|
|
232
|
-
.ocw-cobrowse-toolbar.active { display:flex; align-items:center; }
|
|
233
|
-
.ocw-cobrowse-swatch { width:18px; height:18px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; }
|
|
234
|
-
.ocw-cobrowse-swatch.sel { border-color:#1c1b1a; }
|
|
235
|
-
.ocw-cobrowse-clear { background:none; border:1px solid #e3ded7; border-radius:999px; font-size:11px; padding:3px 8px; cursor:pointer; color:var(--ocw-mut); }
|
|
236
|
-
.ocw-cobrowse-clear:hover { border-color:#e74c3c; color:#e74c3c; }
|
|
237
|
-
.ocw-cobrowse-hint { position:absolute; bottom:8px; left:8px; z-index:41; font-size:11px; color:var(--ocw-mut); background:rgba(255,255,255,.9); border-radius:8px; padding:3px 8px; display:none; }
|
|
238
|
-
.ocw-cobrowse-hint.active { display:block; }
|
|
239
195
|
|
|
240
|
-
.ocw-translate-btn { position:absolute; bottom:2px; right:-26px; background
|
|
196
|
+
.ocw-translate-btn { position:absolute; bottom:2px; right:-26px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:50%; width:22px; height:22px; font-size:11px; cursor:pointer; color:var(--ocw-mut); display:flex; align-items:center; justify-content:center; opacity:0; transition:opacity .15s; padding:0; }
|
|
241
197
|
.ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }
|
|
242
198
|
.ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
|
|
243
199
|
.ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
|
|
244
|
-
|
|
245
|
-
function
|
|
246
|
-
if (typeof document > "u" || document.getElementById(
|
|
200
|
+
`, ye = "objectchat-widget-styles", Ue = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Fe = 400, We = '<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 Ge() {
|
|
202
|
+
if (typeof document > "u" || document.getElementById(ye)) return;
|
|
247
203
|
const t = document.createElement("style");
|
|
248
|
-
t.id =
|
|
204
|
+
t.id = ye, t.textContent = _e, document.head.appendChild(t);
|
|
249
205
|
}
|
|
250
|
-
function
|
|
251
|
-
const
|
|
252
|
-
return e && (
|
|
206
|
+
function n(t, e, l) {
|
|
207
|
+
const c = document.createElement(t);
|
|
208
|
+
return e && (c.className = e), l !== void 0 && (c.textContent = l), c;
|
|
253
209
|
}
|
|
254
|
-
function
|
|
210
|
+
function Ke(t) {
|
|
255
211
|
try {
|
|
256
212
|
return new Date(t).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
257
213
|
} catch {
|
|
258
214
|
return "";
|
|
259
215
|
}
|
|
260
216
|
}
|
|
261
|
-
function
|
|
217
|
+
function ae(t) {
|
|
262
218
|
var e;
|
|
263
219
|
switch (t.kind) {
|
|
264
220
|
case "text":
|
|
@@ -275,115 +231,101 @@ function ie(t) {
|
|
|
275
231
|
return `📅 ${t.title} — ${new Date(t.startIso).toLocaleString()}`;
|
|
276
232
|
}
|
|
277
233
|
}
|
|
278
|
-
class
|
|
234
|
+
class Ve {
|
|
279
235
|
/** Last seq the guest has seen per conversationId — used to compute unread badges. */
|
|
280
|
-
constructor(e,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
236
|
+
constructor(e, l, c, i = {}) {
|
|
237
|
+
T(this, "scroll");
|
|
238
|
+
T(this, "chips");
|
|
239
|
+
T(this, "typing");
|
|
240
|
+
T(this, "quick");
|
|
241
|
+
T(this, "formHost");
|
|
242
|
+
T(this, "csatPanel");
|
|
243
|
+
T(this, "awayNotice");
|
|
244
|
+
T(this, "headStatus");
|
|
245
|
+
T(this, "reopenBtn");
|
|
246
|
+
T(this, "preChatPanel");
|
|
247
|
+
T(this, "deflectPanel");
|
|
248
|
+
T(this, "preChatBuilt", !1);
|
|
249
|
+
T(this, "preChatDone", !1);
|
|
250
|
+
T(this, "footer");
|
|
251
|
+
T(this, "input");
|
|
252
|
+
T(this, "subjectCard");
|
|
253
|
+
T(this, "e2eBadge");
|
|
254
|
+
T(this, "statusBadge");
|
|
255
|
+
T(this, "headerName");
|
|
256
|
+
T(this, "connStatus");
|
|
257
|
+
T(this, "typingTimer", null);
|
|
258
|
+
T(this, "csatSubmitted", !1);
|
|
259
|
+
T(this, "sendBtn");
|
|
302
260
|
/** Container-driven responsive sizing — toggles .ocw-compact (see CSS note). */
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
y(this, "cobrowseToolbar");
|
|
308
|
-
y(this, "cobrowseHint");
|
|
309
|
-
y(this, "cobrowseActive", !1);
|
|
310
|
-
y(this, "cobrowseColor", "#f5713c");
|
|
311
|
-
y(this, "lastAnnotationVersion", -1);
|
|
312
|
-
y(this, "storeRef", null);
|
|
313
|
-
y(this, "scrollCleanup", null);
|
|
261
|
+
T(this, "compactObserver", null);
|
|
262
|
+
T(this, "storeRef", null);
|
|
263
|
+
T(this, "cfgAccent2");
|
|
264
|
+
T(this, "scrollCleanup", null);
|
|
314
265
|
// ── Live translation ──────────────────────────────────────────────────-
|
|
315
|
-
|
|
316
|
-
|
|
266
|
+
T(this, "translationCache", /* @__PURE__ */ new Map());
|
|
267
|
+
T(this, "showingTranslation", /* @__PURE__ */ new Set());
|
|
317
268
|
/** Whether the subject card (server Subject entity, mount config fallback)
|
|
318
269
|
* has been built — built once when data first arrives. */
|
|
319
|
-
|
|
320
|
-
var
|
|
321
|
-
this.root = e, this.me =
|
|
322
|
-
const
|
|
270
|
+
T(this, "subjectBuilt", !1);
|
|
271
|
+
var r, C, v, u, f, R, $, A, k, S, D;
|
|
272
|
+
this.root = e, this.me = l, this.h = c, this.cfg = i, Ge(), e.replaceChildren(), e.classList.add("ocw"), i.accent && e.style.setProperty("--ocw-accent", i.accent);
|
|
273
|
+
const x = i.accent2 ?? i.accent;
|
|
274
|
+
x && e.style.setProperty("--ocw-accent2", x), this.cfgAccent2 = i.accent2, i.theme && i.theme !== "auto" && (e.dataset.theme = i.theme);
|
|
275
|
+
const w = n("div", "ocw-head");
|
|
323
276
|
if (this.h.onBack) {
|
|
324
|
-
const g =
|
|
325
|
-
g.type = "button", g.setAttribute("aria-label", "Back"), g.addEventListener("click", () => this.h.onBack()),
|
|
277
|
+
const g = n("button", "ocw-back", "‹");
|
|
278
|
+
g.type = "button", g.setAttribute("aria-label", "Back"), g.addEventListener("click", () => this.h.onBack()), w.append(g);
|
|
326
279
|
}
|
|
327
|
-
const
|
|
328
|
-
if ((
|
|
280
|
+
const y = n("div", "ocw-avatar");
|
|
281
|
+
if ((r = i.userInfo) != null && r.avatar) {
|
|
329
282
|
const g = document.createElement("img");
|
|
330
|
-
g.src =
|
|
283
|
+
g.src = i.userInfo.avatar, g.alt = i.userInfo.name ?? "You", g.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", y.append(g);
|
|
331
284
|
} else
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
this.headerName =
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const S = o("button", void 0, g);
|
|
342
|
-
S.addEventListener("click", () => {
|
|
285
|
+
y.textContent = (C = i.userInfo) != null && C.name ? i.userInfo.name[0].toUpperCase() : "🧑";
|
|
286
|
+
w.append(y);
|
|
287
|
+
const p = n("div", "ocw-head-main");
|
|
288
|
+
this.headerName = n("div", "ocw-head-name", ((v = i.subject) == null ? void 0 : v.ownerLabel) ?? ((u = i.subject) == null ? void 0 : u.title) ?? ""), p.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", p.append(this.headStatus), (f = i.subject) != null && f.subtitle && p.append(n("div", "ocw-head-meta", i.subject.subtitle)), w.append(p), this.statusBadge = n("span", "ocw-badge", ((R = i.subject) == null ? void 0 : R.status) ?? ""), ($ = i.subject) != null && $.status || (this.statusBadge.style.display = "none"), w.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", w.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", w.append(this.connStatus), w.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");
|
|
289
|
+
const h = n("div", "ocw-typing-bubble");
|
|
290
|
+
h.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(n("div", "ocw-dot", "🧑"), h), this.quick = n("div", "ocw-quick");
|
|
291
|
+
for (const g of i.quickReplies ?? []) {
|
|
292
|
+
const N = n("button", void 0, g);
|
|
293
|
+
N.addEventListener("click", () => {
|
|
343
294
|
this.h.onSend(g), this.quick.style.display = "none";
|
|
344
|
-
}), this.quick.append(
|
|
295
|
+
}), this.quick.append(N);
|
|
345
296
|
}
|
|
346
|
-
this.formHost =
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
var g,
|
|
352
|
-
this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((
|
|
297
|
+
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 = ((A = i.i18n) == null ? void 0 : A.placeholder) ?? "Message…";
|
|
298
|
+
const b = n("button", "ocw-sendbtn");
|
|
299
|
+
b.type = "button";
|
|
300
|
+
const a = (k = i.i18n) == null ? void 0 : k.send;
|
|
301
|
+
a ? (b.textContent = a, b.classList.add("ocw-sendbtn-label"), b.setAttribute("aria-label", a)) : (b.innerHTML = We, b.setAttribute("aria-label", "Send message")), b.disabled = !0, this.sendBtn = b, b.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
|
|
302
|
+
var g, N;
|
|
303
|
+
this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((H) => H.senderRole === "guest") ? (N = (g = this.h).onDeflectQuery) == null || N.call(g, this.input.value) : this.hideDeflection();
|
|
353
304
|
}), this.input.addEventListener("keydown", (g) => {
|
|
354
305
|
g.isComposing || g.keyCode === 229 || (g.key === "Enter" && !g.shiftKey ? (g.preventDefault(), this.flushSend()) : this.signalTyping());
|
|
355
306
|
});
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
|
|
307
|
+
const P = n("button", "ocw-attach", "📎");
|
|
308
|
+
P.title = "Attach image or file";
|
|
309
|
+
const I = document.createElement("input");
|
|
310
|
+
I.type = "file", I.accept = "image/*,.pdf,.txt,.doc,.docx", I.style.display = "none", P.addEventListener("click", () => I.click()), I.addEventListener("change", () => {
|
|
360
311
|
var g;
|
|
361
|
-
(g =
|
|
312
|
+
(g = I.files) != null && g[0] && this.h.onAttach && this.h.onAttach(I.files[0]), I.value = "";
|
|
362
313
|
});
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
((
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}), this.cobrowseToolbar.append(S);
|
|
374
|
-
}
|
|
375
|
-
const m = o("button", "ocw-cobrowse-clear", "Clear");
|
|
376
|
-
m.addEventListener("click", () => {
|
|
377
|
-
var g, S;
|
|
378
|
-
return (S = (g = this.h).onAnnotateClear) == null ? void 0 : S.call(g);
|
|
379
|
-
}), this.cobrowseToolbar.append(m), this.cobrowseHint = o("div", "ocw-cobrowse-hint", "🖍 Draw to point things out — visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
|
|
380
|
-
const f = (g) => {
|
|
381
|
-
e.classList.toggle("ocw-compact", g > 0 && g < _e);
|
|
314
|
+
const M = n("div", "ocw-input");
|
|
315
|
+
M.append(P, I, this.input, b);
|
|
316
|
+
const j = n("div", "ocw-footer");
|
|
317
|
+
((S = i.i18n) == null ? void 0 : S.poweredBy) !== void 0 ? j.textContent = i.i18n.poweredBy : j.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = j, this.reopenBtn = n("button", "ocw-reopen", ((D = this.cfg.i18n) == null ? void 0 : D.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
|
|
318
|
+
this.reopenBtn.style.display = "none";
|
|
319
|
+
const g = this.root.querySelector(".ocw-input textarea");
|
|
320
|
+
g == null || g.focus();
|
|
321
|
+
}), e.append(w, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, M, this.reopenBtn, this.footer);
|
|
322
|
+
const d = (g) => {
|
|
323
|
+
e.classList.toggle("ocw-compact", g > 0 && g < Fe);
|
|
382
324
|
};
|
|
383
|
-
|
|
384
|
-
var
|
|
385
|
-
const
|
|
386
|
-
|
|
325
|
+
d(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((g) => {
|
|
326
|
+
var H;
|
|
327
|
+
const N = ((H = g[0]) == null ? void 0 : H.contentRect.width) ?? e.clientWidth;
|
|
328
|
+
d(N);
|
|
387
329
|
}), this.compactObserver.observe(e));
|
|
388
330
|
}
|
|
389
331
|
/** Returns the scroll container so history.ts can attach scroll listeners. */
|
|
@@ -392,13 +334,13 @@ class Ke {
|
|
|
392
334
|
}
|
|
393
335
|
/** Registers a cleanup fn removed on destroy() to prevent listener leaks. */
|
|
394
336
|
setScrollCleanup(e) {
|
|
395
|
-
var
|
|
396
|
-
(
|
|
337
|
+
var l;
|
|
338
|
+
(l = this.scrollCleanup) == null || l.call(this), this.scrollCleanup = e;
|
|
397
339
|
}
|
|
398
340
|
/** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */
|
|
399
341
|
destroy() {
|
|
400
|
-
var e,
|
|
401
|
-
(e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (
|
|
342
|
+
var e, l;
|
|
343
|
+
(e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (l = this.compactObserver) == null || l.disconnect(), this.compactObserver = null;
|
|
402
344
|
}
|
|
403
345
|
flushSend() {
|
|
404
346
|
this.hideDeflection();
|
|
@@ -418,101 +360,109 @@ class Ke {
|
|
|
418
360
|
this.h.onTyping(!0, e), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
|
|
419
361
|
}
|
|
420
362
|
render(e) {
|
|
421
|
-
var
|
|
422
|
-
if (this.storeRef = e,
|
|
423
|
-
const f = (
|
|
363
|
+
var I, M, j, d, r, C, v, u;
|
|
364
|
+
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) {
|
|
365
|
+
const f = (I = this.cfg.subject) == null ? void 0 : I.ownerLabel;
|
|
424
366
|
f && (this.headerName.textContent = f);
|
|
425
367
|
}
|
|
426
368
|
this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
|
|
427
|
-
const
|
|
428
|
-
this.chips.style.display =
|
|
429
|
-
for (const f of
|
|
430
|
-
const
|
|
369
|
+
const l = e.visibleActions();
|
|
370
|
+
this.chips.style.display = l.length ? "flex" : "none";
|
|
371
|
+
for (const f of l) this.chips.append(this.chipEl(f));
|
|
372
|
+
const c = this.scroll.scrollHeight, i = this.scroll.scrollTop;
|
|
431
373
|
if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
|
|
432
|
-
const f =
|
|
374
|
+
const f = n("div", "ocw-load-more");
|
|
433
375
|
f.textContent = "↑ Loading earlier messages…", f.style.pointerEvents = "none", this.scroll.append(f);
|
|
434
376
|
}
|
|
435
|
-
let
|
|
436
|
-
for (const f of e.messages())
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
this.
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
377
|
+
let x = 0, w = null;
|
|
378
|
+
for (const f of e.messages()) {
|
|
379
|
+
const R = f.senderRole !== "system" && f.senderId !== this.me && !f.internal && f.senderId !== w;
|
|
380
|
+
this.scroll.append(this.messageEl(f, e, R)), f.senderRole !== "system" && (w = f.senderId), f.senderId !== this.me && f.seq > x && (x = f.seq);
|
|
381
|
+
}
|
|
382
|
+
i > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - c + i : this.scroll.scrollTop = this.scroll.scrollHeight, x > 0 && this.h.onReadUpTo(x);
|
|
383
|
+
const y = [...e.typing];
|
|
384
|
+
this.typing.classList.toggle("active", y.length > 0);
|
|
385
|
+
const p = this.typing.querySelector(".ocw-typing-bubble");
|
|
386
|
+
p && p.setAttribute("aria-label", y.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
|
|
387
|
+
const h = e.messages().some((f) => f.senderRole === "guest");
|
|
388
|
+
if (!!((M = e.preChat) != null && M.enabled) && !this.preChatDone && !h && (e.preChat.showWhen !== "offline" || e.offline))
|
|
389
|
+
this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (j = this.root.querySelector(".ocw-input")) == null || j.style.setProperty("display", "none");
|
|
446
390
|
else {
|
|
447
391
|
if (this.preChatPanel.style.display = "none", e.offline) {
|
|
448
|
-
this.awayNotice.firstChild || this.awayNotice.append(
|
|
392
|
+
this.awayNotice.firstChild || this.awayNotice.append(n("span", "ocw-away-icon", "🌙"), n("span", "", ""));
|
|
449
393
|
const f = this.awayNotice.lastChild;
|
|
450
|
-
f.textContent = e.offlineMessage || ((
|
|
394
|
+
f.textContent = e.offlineMessage || ((d = this.cfg.i18n) == null ? void 0 : d.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
|
|
451
395
|
} else
|
|
452
396
|
this.awayNotice.style.display = "none";
|
|
453
|
-
(
|
|
397
|
+
(r = this.root.querySelector(".ocw-input")) == null || r.style.removeProperty("display");
|
|
454
398
|
}
|
|
455
|
-
const
|
|
456
|
-
this.h.onCsat && !this.csatSubmitted &&
|
|
399
|
+
const a = ["resolved", "closed", "sold", "issued", "checked_out"];
|
|
400
|
+
this.h.onCsat && !this.csatSubmitted && a.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
|
|
401
|
+
const P = a.includes(e.state);
|
|
402
|
+
if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((C = this.cfg.i18n) == null ? void 0 : C.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((v = this.cfg.i18n) == null ? void 0 : v.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", P && e.messages().length > 0) {
|
|
403
|
+
const f = n("div", "ocw-resolved-note", `— ${((u = this.cfg.i18n) == null ? void 0 : u.resolved) ?? "Marked as resolved"} —`);
|
|
404
|
+
this.scroll.append(f), this.reopenBtn.style.display = "block";
|
|
405
|
+
} else
|
|
406
|
+
this.reopenBtn.style.display = "none";
|
|
457
407
|
}
|
|
458
|
-
setConnStatus(e,
|
|
408
|
+
setConnStatus(e, l) {
|
|
459
409
|
if (e === "open") {
|
|
460
410
|
this.connStatus.style.display = "none";
|
|
461
411
|
return;
|
|
462
412
|
}
|
|
463
413
|
this.connStatus.style.display = "";
|
|
464
|
-
const
|
|
465
|
-
this.connStatus.className = `ocw-conn-status${
|
|
414
|
+
const c = e === "error";
|
|
415
|
+
this.connStatus.className = `ocw-conn-status${c ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = c ? `⚠ ${l ?? "Chat unavailable"}` : e === "reconnecting" ? l ?? "↻ reconnecting…" : "● connecting…";
|
|
466
416
|
}
|
|
467
417
|
buildPreChatPanel(e) {
|
|
468
|
-
var
|
|
469
|
-
this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(
|
|
470
|
-
const
|
|
418
|
+
var p;
|
|
419
|
+
this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(n("div", "ocw-prechat-title", e.title ?? "Before we start…"));
|
|
420
|
+
const l = n("div", "ocw-offline-form"), c = {};
|
|
471
421
|
for (const h of e.fields ?? ["name", "email"]) {
|
|
472
|
-
const
|
|
473
|
-
|
|
422
|
+
const b = n("input", "ocw-offline-input");
|
|
423
|
+
b.type = h === "email" ? "email" : h === "phone" ? "tel" : "text", b.placeholder = h === "name" ? "Your name" : h === "email" ? "Your email" : "Your phone number", c[h] = b, l.append(b);
|
|
474
424
|
}
|
|
475
|
-
let
|
|
476
|
-
if ((
|
|
477
|
-
|
|
425
|
+
let i = null;
|
|
426
|
+
if ((p = e.topics) != null && p.length) {
|
|
427
|
+
i = n("select", void 0);
|
|
478
428
|
const h = document.createElement("option");
|
|
479
|
-
h.value = "", h.textContent = "What is this about?",
|
|
480
|
-
for (const
|
|
481
|
-
const
|
|
482
|
-
|
|
429
|
+
h.value = "", h.textContent = "What is this about?", i.append(h);
|
|
430
|
+
for (const b of e.topics) {
|
|
431
|
+
const a = document.createElement("option");
|
|
432
|
+
a.value = b, a.textContent = b, i.append(a);
|
|
483
433
|
}
|
|
484
|
-
|
|
434
|
+
l.append(i);
|
|
485
435
|
}
|
|
486
|
-
let
|
|
436
|
+
let x = null, w = null;
|
|
487
437
|
if (e.callbackOption) {
|
|
488
|
-
const h =
|
|
489
|
-
|
|
438
|
+
const h = n("label", "ocw-prechat-cb");
|
|
439
|
+
x = document.createElement("input"), x.type = "checkbox", h.append(x, document.createTextNode("📞 Request a call back")), l.append(h), c.phone || (w = n("input", "ocw-offline-input"), w.type = "tel", w.placeholder = "Phone number for the call", w.style.display = "none", x.addEventListener("change", () => w.style.setProperty("display", x.checked ? "block" : "none")), l.append(w));
|
|
490
440
|
}
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
var
|
|
494
|
-
const h = (
|
|
495
|
-
if (
|
|
496
|
-
|
|
441
|
+
const y = n("button", "ocw-offline-submit", "Start chat");
|
|
442
|
+
y.type = "button", y.addEventListener("click", () => {
|
|
443
|
+
var P, I, M, j, d, r, C;
|
|
444
|
+
const h = (P = c.email) == null ? void 0 : P.value.trim();
|
|
445
|
+
if (c.email && (!h || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(h))) {
|
|
446
|
+
c.email.focus();
|
|
497
447
|
return;
|
|
498
448
|
}
|
|
499
|
-
const
|
|
500
|
-
if (
|
|
501
|
-
(
|
|
449
|
+
const b = !!(x != null && x.checked), a = (((I = c.phone) == null ? void 0 : I.value) ?? (w == null ? void 0 : w.value) ?? "").trim();
|
|
450
|
+
if (b && !a) {
|
|
451
|
+
(M = c.phone ?? w) == null || M.focus();
|
|
502
452
|
return;
|
|
503
453
|
}
|
|
504
|
-
if (
|
|
505
|
-
|
|
454
|
+
if (i && ((j = e.topics) != null && j.length) && !i.value) {
|
|
455
|
+
i.focus();
|
|
506
456
|
return;
|
|
507
457
|
}
|
|
508
|
-
|
|
509
|
-
...(
|
|
458
|
+
y.disabled = !0, this.completePreChat(), (C = (r = this.h).onPreChat) == null || C.call(r, {
|
|
459
|
+
...(d = c.name) != null && d.value.trim() ? { name: c.name.value.trim() } : {},
|
|
510
460
|
...h ? { email: h } : {},
|
|
511
|
-
...
|
|
512
|
-
...
|
|
513
|
-
...
|
|
461
|
+
...a ? { phone: a } : {},
|
|
462
|
+
...i != null && i.value ? { topic: i.value } : {},
|
|
463
|
+
...b ? { callback: !0 } : {}
|
|
514
464
|
});
|
|
515
|
-
}),
|
|
465
|
+
}), l.append(y), this.preChatPanel.append(l);
|
|
516
466
|
}
|
|
517
467
|
/** Mark pre-chat complete (submitted now or in a previous session). */
|
|
518
468
|
completePreChat() {
|
|
@@ -521,10 +471,10 @@ class Ke {
|
|
|
521
471
|
/** KB deflection results ("was this your question?") above the composer. */
|
|
522
472
|
showDeflection(e) {
|
|
523
473
|
if (!e.length) return this.hideDeflection();
|
|
524
|
-
this.deflectPanel.replaceChildren(), this.deflectPanel.append(
|
|
525
|
-
for (const
|
|
526
|
-
const
|
|
527
|
-
|
|
474
|
+
this.deflectPanel.replaceChildren(), this.deflectPanel.append(n("div", "ocw-deflect-hint", "Instant answers — tap to expand"));
|
|
475
|
+
for (const l of e.slice(0, 3)) {
|
|
476
|
+
const c = n("button", "ocw-deflect-card");
|
|
477
|
+
c.append(n("div", "ocw-deflect-q", l.title), n("div", "ocw-deflect-a", l.answer)), c.addEventListener("click", () => c.classList.toggle("open")), this.deflectPanel.append(c);
|
|
528
478
|
}
|
|
529
479
|
this.deflectPanel.style.display = "flex";
|
|
530
480
|
}
|
|
@@ -532,264 +482,221 @@ class Ke {
|
|
|
532
482
|
this.deflectPanel.style.display = "none", this.deflectPanel.replaceChildren();
|
|
533
483
|
}
|
|
534
484
|
buildCsatPanel() {
|
|
535
|
-
this.csatPanel.replaceChildren(), this.csatPanel.append(
|
|
536
|
-
const e =
|
|
537
|
-
for (let
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
var
|
|
541
|
-
this.csatSubmitted = !0, this.csatPanel.replaceChildren(
|
|
542
|
-
}),
|
|
485
|
+
this.csatPanel.replaceChildren(), this.csatPanel.append(n("div", "ocw-csat-title", "How did we do?"));
|
|
486
|
+
const e = n("div", "ocw-csat-stars"), l = [];
|
|
487
|
+
for (let c = 1; c <= 5; c++) {
|
|
488
|
+
const i = n("button", "ocw-csat-star", "★");
|
|
489
|
+
i.dataset.score = String(c), i.addEventListener("mouseenter", () => l.forEach((x, w) => x.classList.toggle("lit", w < c))), i.addEventListener("mouseleave", () => l.forEach((x) => x.classList.remove("lit"))), i.addEventListener("click", () => {
|
|
490
|
+
var x, w;
|
|
491
|
+
this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${c}★ rating!`)), (w = (x = this.h).onCsat) == null || w.call(x, c);
|
|
492
|
+
}), l.push(i), e.append(i);
|
|
543
493
|
}
|
|
544
494
|
this.csatPanel.append(e);
|
|
545
495
|
}
|
|
546
|
-
// ── Co-browsing (shared whiteboard) ──────────────────────────────────────
|
|
547
|
-
updateCobrowseUI() {
|
|
548
|
-
this.cobrowseCanvas.classList.toggle("active", this.cobrowseActive), this.cobrowseToolbar.classList.toggle("active", this.cobrowseActive), this.cobrowseHint.classList.toggle("active", this.cobrowseActive), this.cobrowseBtn.classList.toggle("on", this.cobrowseActive), this.cobrowseActive && (this.resizeCobrowseCanvas(), this.redrawCobrowse());
|
|
549
|
-
}
|
|
550
|
-
resizeCobrowseCanvas() {
|
|
551
|
-
this.cobrowseCanvas.width = this.root.clientWidth || 1, this.cobrowseCanvas.height = this.root.clientHeight || 1;
|
|
552
|
-
}
|
|
553
|
-
/** Draw a stroke whose points are normalized to 0..1, scaled to the current
|
|
554
|
-
* canvas size — so strokes line up across different viewport sizes. */
|
|
555
|
-
drawStroke(e) {
|
|
556
|
-
const i = this.cobrowseCanvas.getContext("2d");
|
|
557
|
-
if (!i || e.points.length < 2) return;
|
|
558
|
-
const s = this.cobrowseCanvas.width, a = this.cobrowseCanvas.height;
|
|
559
|
-
i.strokeStyle = e.color, i.lineWidth = Math.max(1, e.width * Math.min(s, a)), i.lineJoin = "round", i.lineCap = "round", i.beginPath(), i.moveTo(e.points[0].x * s, e.points[0].y * a);
|
|
560
|
-
for (const c of e.points.slice(1)) i.lineTo(c.x * s, c.y * a);
|
|
561
|
-
i.stroke();
|
|
562
|
-
}
|
|
563
|
-
redrawCobrowse() {
|
|
564
|
-
var i;
|
|
565
|
-
const e = this.cobrowseCanvas.getContext("2d");
|
|
566
|
-
if (e) {
|
|
567
|
-
e.clearRect(0, 0, this.cobrowseCanvas.width, this.cobrowseCanvas.height);
|
|
568
|
-
for (const s of ((i = this.storeRef) == null ? void 0 : i.annotations) ?? []) this.drawStroke(s);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
bindCobrowsePointerEvents() {
|
|
572
|
-
let e = !1, i = [];
|
|
573
|
-
const s = (w) => {
|
|
574
|
-
const b = this.cobrowseCanvas.getBoundingClientRect(), d = b.width > 0 ? (w.clientX - b.left) / b.width : 0, h = b.height > 0 ? (w.clientY - b.top) / b.height : 0;
|
|
575
|
-
return { x: Math.min(1, Math.max(0, d)), y: Math.min(1, Math.max(0, h)) };
|
|
576
|
-
}, a = 6e-3;
|
|
577
|
-
this.cobrowseCanvas.addEventListener("pointerdown", (w) => {
|
|
578
|
-
this.cobrowseActive && (e = !0, i = [s(w)], this.cobrowseCanvas.setPointerCapture(w.pointerId));
|
|
579
|
-
}), this.cobrowseCanvas.addEventListener("pointermove", (w) => {
|
|
580
|
-
e && (i.push(s(w)), this.redrawCobrowse(), this.drawStroke({ points: i, color: this.cobrowseColor, width: a }));
|
|
581
|
-
});
|
|
582
|
-
const c = (w) => {
|
|
583
|
-
var b, d;
|
|
584
|
-
if (e) {
|
|
585
|
-
e = !1, i.length > 1 && ((d = (b = this.h).onAnnotate) == null || d.call(b, { id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: i, color: this.cobrowseColor, width: a })), i = [];
|
|
586
|
-
try {
|
|
587
|
-
this.cobrowseCanvas.releasePointerCapture(w.pointerId);
|
|
588
|
-
} catch {
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
this.cobrowseCanvas.addEventListener("pointerup", c), this.cobrowseCanvas.addEventListener("pointercancel", c);
|
|
593
|
-
}
|
|
594
496
|
buildSubjectCard(e) {
|
|
595
497
|
if (this.subjectBuilt) return;
|
|
596
|
-
const
|
|
597
|
-
if (!
|
|
598
|
-
this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(
|
|
599
|
-
const
|
|
600
|
-
if (
|
|
601
|
-
else for (const
|
|
602
|
-
|
|
603
|
-
const w = (
|
|
498
|
+
const l = e.subject, c = this.cfg.subject, i = (l == null ? void 0 : l.title) ?? (c == null ? void 0 : c.title);
|
|
499
|
+
if (!i) return;
|
|
500
|
+
this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", i)), c != null && c.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", c.subtitle));
|
|
501
|
+
const x = n("div", "ocw-tags");
|
|
502
|
+
if (l) for (const [y, p] of Object.entries(l.fields)) x.append(n("span", "ocw-tag", `${y}: ${p}`));
|
|
503
|
+
else for (const y of (c == null ? void 0 : c.tags) ?? []) x.append(n("span", "ocw-tag", y));
|
|
504
|
+
x.childNodes.length && this.subjectCard.append(x);
|
|
505
|
+
const w = (l == null ? void 0 : l.state) ?? (c == null ? void 0 : c.status);
|
|
604
506
|
w && (this.statusBadge.textContent = w, this.statusBadge.style.display = "inline-flex");
|
|
605
507
|
}
|
|
606
508
|
chipEl(e) {
|
|
607
|
-
const
|
|
608
|
-
return
|
|
609
|
-
var
|
|
610
|
-
e.confirm && !await this.confirm(e.label) || ((
|
|
611
|
-
}),
|
|
509
|
+
const l = n("button", "ocw-chip", e.icon ? `${e.icon} ${e.label}` : e.label);
|
|
510
|
+
return l.dataset.actionId = e.id, l.addEventListener("click", async () => {
|
|
511
|
+
var c;
|
|
512
|
+
e.confirm && !await this.confirm(e.label) || ((c = e.input) != null && c.length ? this.openForm(e) : this.h.onInvoke(e.id));
|
|
513
|
+
}), l;
|
|
612
514
|
}
|
|
613
515
|
/** In-widget confirmation modal (replaces window.confirm). */
|
|
614
516
|
confirm(e) {
|
|
615
|
-
return new Promise((
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
const
|
|
619
|
-
|
|
517
|
+
return new Promise((l) => {
|
|
518
|
+
const c = n("div", "ocw-modal"), i = n("div", "ocw-modal-card");
|
|
519
|
+
i.append(n("div", "ocw-modal-title", e)), i.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
|
|
520
|
+
const x = n("div", "ocw-modal-actions"), w = n("button", "ocw-modal-cancel", "Cancel"), y = n("button", "ocw-modal-ok", "Confirm"), p = (h) => {
|
|
521
|
+
c.remove(), l(h);
|
|
620
522
|
};
|
|
621
|
-
w.addEventListener("click", () =>
|
|
622
|
-
h.target ===
|
|
623
|
-
}),
|
|
523
|
+
w.addEventListener("click", () => p(!1)), y.addEventListener("click", () => p(!0)), c.addEventListener("click", (h) => {
|
|
524
|
+
h.target === c && p(!1);
|
|
525
|
+
}), x.append(w, y), i.append(x), c.append(i), this.root.append(c), y.focus();
|
|
624
526
|
});
|
|
625
527
|
}
|
|
626
528
|
/** Inline form for a form-effect action: typed inputs (date picker, number,
|
|
627
529
|
* text) rendered above the composer — no browser prompts. */
|
|
628
530
|
openForm(e) {
|
|
629
|
-
var
|
|
531
|
+
var y, p;
|
|
630
532
|
this.formHost.replaceChildren();
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
const
|
|
533
|
+
const l = n("div", "ocw-form");
|
|
534
|
+
l.append(n("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
|
|
535
|
+
const c = /* @__PURE__ */ new Map();
|
|
634
536
|
for (const h of e.input ?? []) {
|
|
635
|
-
const
|
|
636
|
-
if (
|
|
637
|
-
const
|
|
638
|
-
h.required ||
|
|
639
|
-
for (const
|
|
640
|
-
const
|
|
641
|
-
|
|
537
|
+
const b = n("label", "ocw-form-row");
|
|
538
|
+
if (b.append(n("span", "ocw-form-lbl", h.label)), h.type === "select" && ((y = h.options) != null && y.length)) {
|
|
539
|
+
const a = n("select", "ocw-form-input");
|
|
540
|
+
h.required || a.append(n("option", void 0, "— select —"));
|
|
541
|
+
for (const P of h.options) {
|
|
542
|
+
const I = n("option");
|
|
543
|
+
I.value = P, I.textContent = P, a.append(I);
|
|
642
544
|
}
|
|
643
|
-
h.required && (
|
|
545
|
+
h.required && (a.required = !0), b.append(a), c.set(h.name, a);
|
|
644
546
|
} else {
|
|
645
|
-
const
|
|
646
|
-
|
|
547
|
+
const a = n("input", "ocw-form-input");
|
|
548
|
+
a.type = h.type === "number" ? "number" : h.type === "date" ? "datetime-local" : "text", h.required && (a.required = !0), b.append(a), c.set(h.name, a);
|
|
647
549
|
}
|
|
648
|
-
|
|
550
|
+
l.append(b);
|
|
649
551
|
}
|
|
650
|
-
const
|
|
651
|
-
|
|
552
|
+
const i = n("div", "ocw-form-actions"), x = n("button", "ocw-form-cancel", "Cancel"), w = n("button", "ocw-form-submit", "Send");
|
|
553
|
+
x.addEventListener("click", () => this.formHost.replaceChildren()), w.addEventListener("click", () => {
|
|
652
554
|
const h = {};
|
|
653
|
-
for (const [
|
|
654
|
-
if (
|
|
655
|
-
|
|
555
|
+
for (const [b, a] of c) {
|
|
556
|
+
if (a.required && !a.value) {
|
|
557
|
+
a.style.borderColor = "#e5484d";
|
|
656
558
|
return;
|
|
657
559
|
}
|
|
658
|
-
h[
|
|
560
|
+
h[b] = a.type === "number" ? Number(a.value) : a.value;
|
|
659
561
|
}
|
|
660
562
|
this.formHost.replaceChildren(), this.h.onInvoke(e.id, h);
|
|
661
|
-
}),
|
|
563
|
+
}), i.append(x, w), l.append(i), this.formHost.append(l), (p = c.values().next().value) == null || p.focus();
|
|
662
564
|
}
|
|
663
|
-
messageEl(e,
|
|
664
|
-
var
|
|
565
|
+
messageEl(e, l, c = !1) {
|
|
566
|
+
var P, I, M, j;
|
|
665
567
|
if (e.senderRole === "system") {
|
|
666
|
-
const
|
|
667
|
-
return
|
|
568
|
+
const d = n("div", "ocw-sys");
|
|
569
|
+
return d.textContent = e.deletedAt ? "message deleted" : ae(e.content), d;
|
|
570
|
+
}
|
|
571
|
+
const i = e.senderId === this.me, x = !!e.internal, w = n("div", `ocw-row ${x ? "ocw-note mine" : i ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
|
|
572
|
+
!i && !x && w.append(n("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
|
|
573
|
+
const y = n("div");
|
|
574
|
+
if (c) {
|
|
575
|
+
const d = e.senderRole === "bot" ? ((P = this.cfg.i18n) == null ? void 0 : P.aiAssistant) ?? "AI Assistant" : ((I = this.cfg.subject) == null ? void 0 : I.ownerLabel) ?? ((M = this.cfg.subject) == null ? void 0 : M.title) ?? "Support";
|
|
576
|
+
y.append(n("div", "ocw-msg-sender", d));
|
|
668
577
|
}
|
|
669
|
-
const
|
|
670
|
-
!s && !a && c.append(o("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
|
|
671
|
-
const w = o("div"), b = o("div", "ocw-bubble-wrap");
|
|
578
|
+
const p = n("div", "ocw-bubble-wrap");
|
|
672
579
|
if (e.replyToId) {
|
|
673
|
-
const
|
|
674
|
-
|
|
580
|
+
const d = n("div", "ocw-reply-to", "↩ replying to a message");
|
|
581
|
+
d.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", y.append(d);
|
|
675
582
|
}
|
|
676
|
-
const
|
|
677
|
-
let
|
|
678
|
-
if (e.deletedAt)
|
|
583
|
+
const h = n("div", "ocw-bubble");
|
|
584
|
+
let b = null;
|
|
585
|
+
if (e.deletedAt) h.append(n("span", "ocw-deleted", "message deleted"));
|
|
679
586
|
else if (e.content.kind === "attachment") {
|
|
680
|
-
const
|
|
681
|
-
if ((
|
|
682
|
-
const
|
|
683
|
-
|
|
587
|
+
const d = e.content;
|
|
588
|
+
if ((j = d.mime) != null && j.startsWith("image/")) {
|
|
589
|
+
const r = document.createElement("img");
|
|
590
|
+
r.src = d.url, r.alt = d.name ?? "image", r.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", r.addEventListener("click", () => window.open(d.url, "_blank")), h.append(r);
|
|
684
591
|
} else {
|
|
685
|
-
const
|
|
686
|
-
|
|
592
|
+
const r = document.createElement("a");
|
|
593
|
+
r.href = d.url, r.target = "_blank", r.rel = "noopener", r.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", r.append(n("span", void 0, "📄"), n("span", void 0, d.name ?? "file")), h.append(r);
|
|
687
594
|
}
|
|
688
595
|
} else if (e.content.kind === "appointment") {
|
|
689
|
-
const
|
|
690
|
-
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
const
|
|
694
|
-
|
|
596
|
+
const d = e.content, r = n("div", "ocw-appt");
|
|
597
|
+
r.append(n("div", "ocw-appt-title", `📅 ${d.title}`)), r.append(n("div", "ocw-appt-time", new Date(d.startIso).toLocaleString() + " – " + new Date(d.endIso).toLocaleTimeString())), d.location && r.append(n("div", "ocw-appt-loc", `📍 ${d.location}`)), d.description && r.append(n("div", "ocw-appt-desc", d.description));
|
|
598
|
+
const C = n("div", "ocw-appt-links"), v = document.createElement("a");
|
|
599
|
+
v.href = d.googleUrl, v.target = "_blank", v.rel = "noopener", v.className = "ocw-appt-btn", v.textContent = "📅 Add to Google Calendar";
|
|
600
|
+
const u = document.createElement("a");
|
|
601
|
+
u.href = d.icalUrl, u.download = `${d.title}.ics`, u.className = "ocw-appt-btn ocw-appt-btn-sec", u.textContent = "🍎 Apple / iCal", C.append(v, u), r.append(C), h.append(r);
|
|
695
602
|
} else
|
|
696
|
-
|
|
697
|
-
if (
|
|
698
|
-
const
|
|
699
|
-
if (
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
if (
|
|
703
|
-
this.showingTranslation.delete(e.id),
|
|
603
|
+
b = document.createTextNode(ae(e.content)), h.append(b), e.editedAt && h.append(n("span", "ocw-edited", "(edited)"));
|
|
604
|
+
if (p.append(h), !i && !x && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && b) {
|
|
605
|
+
const d = e.content.text;
|
|
606
|
+
if (d.trim()) {
|
|
607
|
+
const r = n("button", "ocw-translate-btn", "🌐");
|
|
608
|
+
r.type = "button", r.title = "Translate", r.addEventListener("click", (C) => {
|
|
609
|
+
if (C.stopPropagation(), this.showingTranslation.has(e.id)) {
|
|
610
|
+
this.showingTranslation.delete(e.id), b.textContent = d, r.textContent = "🌐", r.title = "Translate";
|
|
704
611
|
return;
|
|
705
612
|
}
|
|
706
|
-
const
|
|
707
|
-
if (
|
|
708
|
-
this.showingTranslation.add(e.id),
|
|
613
|
+
const v = this.translationCache.get(e.id);
|
|
614
|
+
if (v !== void 0) {
|
|
615
|
+
this.showingTranslation.add(e.id), b.textContent = v, r.textContent = "↩", r.title = "Show original";
|
|
709
616
|
return;
|
|
710
617
|
}
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
|
|
714
|
-
|
|
618
|
+
r.textContent = "⏳", this.h.onTranslate(d).then((u) => {
|
|
619
|
+
if (u === null) {
|
|
620
|
+
r.textContent = "⚠️", r.title = "Translation unavailable", setTimeout(() => {
|
|
621
|
+
r.textContent = "🌐", r.title = "Translate";
|
|
715
622
|
}, 1500);
|
|
716
623
|
return;
|
|
717
624
|
}
|
|
718
|
-
this.translationCache.set(e.id,
|
|
625
|
+
this.translationCache.set(e.id, u), this.showingTranslation.add(e.id), b.textContent = u, r.textContent = "↩", r.title = "Show original";
|
|
719
626
|
});
|
|
720
|
-
}),
|
|
627
|
+
}), p.append(r);
|
|
721
628
|
}
|
|
722
629
|
}
|
|
723
|
-
if (
|
|
724
|
-
const
|
|
630
|
+
if (i && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
|
|
631
|
+
const d = n("div", "ocw-msg-menu");
|
|
725
632
|
if (this.h.onEdit) {
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
const
|
|
738
|
-
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
}),
|
|
744
|
-
|
|
633
|
+
const r = n("button", void 0, "✏️");
|
|
634
|
+
r.title = "Edit", r.addEventListener("click", (C) => {
|
|
635
|
+
C.stopPropagation();
|
|
636
|
+
const v = ae(e.content), u = document.createElement("textarea");
|
|
637
|
+
u.value = v, u.rows = Math.min(4, Math.ceil(v.length / 40) + 1), u.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";
|
|
638
|
+
const f = n("button", "ocw-form-submit", "Save");
|
|
639
|
+
f.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
|
|
640
|
+
const R = n("button", "ocw-form-cancel", "Cancel");
|
|
641
|
+
R.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
|
|
642
|
+
const $ = n("div");
|
|
643
|
+
$.style.cssText = "display:flex;gap:6px;justify-content:flex-end", $.append(R, f);
|
|
644
|
+
const A = n("div");
|
|
645
|
+
A.append(u, $), h.replaceChildren(A), u.focus(), u.select();
|
|
646
|
+
const k = () => h.replaceChildren(b ?? document.createTextNode(v));
|
|
647
|
+
R.addEventListener("click", k), f.addEventListener("click", () => {
|
|
648
|
+
const S = u.value.trim();
|
|
649
|
+
S && S !== v && this.h.onEdit(e.id, S), k();
|
|
650
|
+
}), u.addEventListener("keydown", (S) => {
|
|
651
|
+
S.key === "Enter" && !S.shiftKey && (S.preventDefault(), f.click()), S.key === "Escape" && k();
|
|
745
652
|
});
|
|
746
|
-
}),
|
|
653
|
+
}), d.append(r);
|
|
747
654
|
}
|
|
748
655
|
if (this.h.onDelete) {
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
}),
|
|
656
|
+
const r = n("button", "del", "🗑");
|
|
657
|
+
r.title = "Delete", r.addEventListener("click", (C) => {
|
|
658
|
+
C.stopPropagation(), this.h.onDelete(e.id);
|
|
659
|
+
}), d.append(r);
|
|
753
660
|
}
|
|
754
|
-
|
|
661
|
+
p.append(d);
|
|
755
662
|
}
|
|
756
|
-
if (
|
|
757
|
-
const
|
|
663
|
+
if (y.append(p), this.h.onReact && !e.deletedAt && e.seq > 0) {
|
|
664
|
+
const d = n("div", "ocw-react-wrap"), r = n("div", "ocw-react");
|
|
758
665
|
if (e.reactions && Object.keys(e.reactions).length)
|
|
759
|
-
for (const [
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
var
|
|
763
|
-
return (
|
|
764
|
-
}),
|
|
666
|
+
for (const [u, f] of Object.entries(e.reactions)) {
|
|
667
|
+
const R = n("button", `ocw-react-pill${f.includes(this.me) ? " mine" : ""}`, `${u} ${f.length}`);
|
|
668
|
+
R.addEventListener("click", () => {
|
|
669
|
+
var $, A;
|
|
670
|
+
return (A = ($ = this.h).onReact) == null ? void 0 : A.call($, e.id, u, f.includes(this.me));
|
|
671
|
+
}), r.append(R);
|
|
765
672
|
}
|
|
766
|
-
const
|
|
767
|
-
for (const
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
var
|
|
771
|
-
|
|
772
|
-
const
|
|
773
|
-
(
|
|
774
|
-
}),
|
|
673
|
+
const C = n("button", "ocw-react-btn", "+"), v = n("div", "ocw-react-picker");
|
|
674
|
+
for (const u of Ue) {
|
|
675
|
+
const f = n("button", void 0, u);
|
|
676
|
+
f.addEventListener("click", (R) => {
|
|
677
|
+
var A, k, S, D;
|
|
678
|
+
R.stopPropagation();
|
|
679
|
+
const $ = (k = (A = e.reactions) == null ? void 0 : A[u]) == null ? void 0 : k.includes(this.me);
|
|
680
|
+
(D = (S = this.h).onReact) == null || D.call(S, e.id, u, !!$), v.style.display = "none";
|
|
681
|
+
}), v.append(f);
|
|
775
682
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
683
|
+
v.style.display = "none", C.addEventListener("click", (u) => {
|
|
684
|
+
u.stopPropagation();
|
|
685
|
+
const f = v.style.display === "none";
|
|
686
|
+
v.style.display = f ? "flex" : "none", f && document.addEventListener("click", () => {
|
|
687
|
+
v.style.display = "none";
|
|
781
688
|
}, { once: !0 });
|
|
782
|
-
}),
|
|
783
|
-
} else e.reactions && Object.keys(e.reactions).length &&
|
|
784
|
-
const
|
|
785
|
-
if (
|
|
786
|
-
const
|
|
787
|
-
|
|
689
|
+
}), r.append(C), d.append(r, v), y.append(d);
|
|
690
|
+
} else e.reactions && Object.keys(e.reactions).length && y.append(n("div", "ocw-react", Object.entries(e.reactions).map(([d, r]) => `${d}${r.length}`).join(" ")));
|
|
691
|
+
const a = n("div", "ocw-time ocw-meta", Ke(e.ts));
|
|
692
|
+
if (i && e.status) {
|
|
693
|
+
const d = n("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Ye(e.status));
|
|
694
|
+
a.append(d);
|
|
788
695
|
}
|
|
789
|
-
return
|
|
696
|
+
return i && e.seq > 0 && l.lastReadByOthers >= e.seq && a.append(n("span", "ocw-seen", " · Seen")), y.append(a), w.append(y), w;
|
|
790
697
|
}
|
|
791
698
|
}
|
|
792
|
-
function
|
|
699
|
+
function Ye(t) {
|
|
793
700
|
switch (t) {
|
|
794
701
|
case "read":
|
|
795
702
|
return "✓✓";
|
|
@@ -801,40 +708,40 @@ function Ge(t) {
|
|
|
801
708
|
return "🕓";
|
|
802
709
|
}
|
|
803
710
|
}
|
|
804
|
-
const
|
|
805
|
-
function
|
|
711
|
+
const _ = /* @__PURE__ */ new WeakMap(), Z = /* @__PURE__ */ new Map();
|
|
712
|
+
function ve(t) {
|
|
806
713
|
return `relay-launcher::${t.profileId}::${t.subjectId ?? ""}`;
|
|
807
714
|
}
|
|
808
|
-
let
|
|
809
|
-
function
|
|
810
|
-
if (
|
|
715
|
+
let K = null;
|
|
716
|
+
function Xe() {
|
|
717
|
+
if (K && K.state !== "closed") return K;
|
|
811
718
|
try {
|
|
812
|
-
return
|
|
719
|
+
return K = new AudioContext(), K;
|
|
813
720
|
} catch {
|
|
814
721
|
return null;
|
|
815
722
|
}
|
|
816
723
|
}
|
|
817
|
-
function
|
|
724
|
+
function nt(t) {
|
|
818
725
|
var e;
|
|
819
|
-
(e =
|
|
726
|
+
(e = _.get(t)) == null || e.close(), _.delete(t);
|
|
820
727
|
}
|
|
821
728
|
function ot(t) {
|
|
822
|
-
var le, de, pe, he, ue;
|
|
823
|
-
|
|
824
|
-
const e =
|
|
825
|
-
let
|
|
826
|
-
const
|
|
827
|
-
let
|
|
828
|
-
const h = t.subjectId ? `${
|
|
829
|
-
let
|
|
729
|
+
var se, le, de, pe, he, ue, fe, we;
|
|
730
|
+
_.has(t.el) && (_.get(t.el).close(), _.delete(t.el)), t.launcher && ((se = Z.get(ve(t))) == null || se.close());
|
|
731
|
+
const e = Me();
|
|
732
|
+
let l, c = !1;
|
|
733
|
+
const i = t.token ?? t.userId ?? e, x = i !== e ? e : void 0, { wsUrl: w, httpBase: y } = Re(t.url, t.apiUrl);
|
|
734
|
+
let p = new Ne(i);
|
|
735
|
+
const h = t.subjectId ? `${i}::${t.subjectId}` : i, b = new qe(h);
|
|
736
|
+
let a, P = !1, I = null, M = null, j = null, d = null;
|
|
830
737
|
!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
|
|
832
|
-
let
|
|
738
|
+
for (const o of b.load()) p.addOptimistic(o.clientMsgId, o.content);
|
|
739
|
+
let r = null, C = null, v = 0, u = !t.launcher;
|
|
833
740
|
if (t.launcher) {
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
-
const
|
|
837
|
-
t.el.classList.toggle("ocw-fs",
|
|
741
|
+
const s = (t.position ?? "bottom-right").includes("right");
|
|
742
|
+
r = document.createElement("div"), r.style.cssText = `position:fixed;${s ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${s ? "flex-end" : "flex-start"};gap:12px`;
|
|
743
|
+
const m = document.createElement("div"), L = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, W = (z) => {
|
|
744
|
+
t.el.classList.toggle("ocw-fs", z), m.style.cssText = z ? [
|
|
838
745
|
"position:fixed",
|
|
839
746
|
"inset:0",
|
|
840
747
|
"width:100%",
|
|
@@ -851,268 +758,268 @@ function ot(t) {
|
|
|
851
758
|
].join(";") : [
|
|
852
759
|
"width:min(380px, calc(100vw - 40px))",
|
|
853
760
|
"height:min(600px, calc(100dvh - 108px))",
|
|
854
|
-
"border-radius:
|
|
761
|
+
"border-radius:28px",
|
|
855
762
|
"overflow:hidden",
|
|
856
|
-
"box-shadow:0
|
|
763
|
+
"box-shadow:0 12px 32px rgba(108,92,231,.14)",
|
|
857
764
|
"display:none",
|
|
858
765
|
"flex-direction:column",
|
|
859
766
|
"background:#fff",
|
|
860
|
-
"transform-origin:bottom " + (
|
|
767
|
+
"transform-origin:bottom " + (s ? "right" : "left"),
|
|
861
768
|
"transition:opacity .18s,transform .18s",
|
|
862
769
|
"opacity:0",
|
|
863
770
|
"transform:scale(.95)"
|
|
864
771
|
].join(";");
|
|
865
772
|
};
|
|
866
|
-
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
const
|
|
870
|
-
|
|
773
|
+
W((L == null ? void 0 : L.matches) ?? !1);
|
|
774
|
+
const G = (z) => W(z.matches);
|
|
775
|
+
L == null || L.addEventListener("change", G), I = L, M = G, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", m.append(t.el);
|
|
776
|
+
const Y = '<svg viewBox="0 0 24 24" width="26" height="26" 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>', X = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', q = document.createElement("button");
|
|
777
|
+
q.type = "button", q.style.cssText = [
|
|
871
778
|
"width:56px;height:56px;border-radius:50%",
|
|
872
|
-
`background:${t.accent ?? "#
|
|
779
|
+
`background:${t.accent ?? "#6c5ce7"}`,
|
|
873
780
|
"color:#fff;border:none;cursor:pointer",
|
|
874
|
-
"box-shadow:0
|
|
781
|
+
"box-shadow:0 12px 32px rgba(108,92,231,.14)",
|
|
875
782
|
"position:relative;flex:none",
|
|
876
783
|
"display:flex;align-items:center;justify-content:center",
|
|
877
784
|
"transition:transform .15s"
|
|
878
|
-
].join(";"),
|
|
879
|
-
|
|
880
|
-
},
|
|
881
|
-
|
|
882
|
-
},
|
|
883
|
-
const
|
|
884
|
-
|
|
785
|
+
].join(";"), q.onmouseenter = () => {
|
|
786
|
+
q.style.transform = "scale(1.08)";
|
|
787
|
+
}, q.onmouseleave = () => {
|
|
788
|
+
q.style.transform = "scale(1)";
|
|
789
|
+
}, C = document.createElement("span"), C.style.cssText = "position:absolute;top:-4px;right:-4px;background:#4c6fff;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
|
|
790
|
+
const Q = () => {
|
|
791
|
+
q.innerHTML = u ? X : Y, q.setAttribute("aria-label", u ? "Close chat" : "Open chat"), q.setAttribute("aria-expanded", String(u)), q.append(C);
|
|
885
792
|
};
|
|
886
|
-
|
|
887
|
-
const
|
|
888
|
-
let
|
|
889
|
-
const
|
|
793
|
+
Q(), r.append(m, q), document.body.append(r);
|
|
794
|
+
const te = `ocw-teaser-dismissed::${t.profileId}`, J = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
|
|
795
|
+
let E = null;
|
|
796
|
+
const je = () => {
|
|
890
797
|
try {
|
|
891
|
-
return sessionStorage.getItem(
|
|
798
|
+
return sessionStorage.getItem(te) === "1";
|
|
892
799
|
} catch {
|
|
893
800
|
return !1;
|
|
894
801
|
}
|
|
895
|
-
},
|
|
896
|
-
const
|
|
897
|
-
if (!(!!(
|
|
898
|
-
|
|
802
|
+
}, Le = '<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>', be = () => {
|
|
803
|
+
const z = J != null && J.title ? J : p.launcherMessage ?? void 0;
|
|
804
|
+
if (!(!!(z != null && z.title) && !u && !je())) {
|
|
805
|
+
E && (E.remove(), E = null);
|
|
899
806
|
return;
|
|
900
807
|
}
|
|
901
|
-
if (
|
|
902
|
-
|
|
808
|
+
if (E) return;
|
|
809
|
+
E = document.createElement("div"), E.setAttribute("role", "button"), E.setAttribute("tabindex", "0"), E.setAttribute("aria-label", z.title), E.style.cssText = [
|
|
903
810
|
"max-width:280px",
|
|
904
811
|
"background:#fff",
|
|
905
|
-
"border-radius:
|
|
906
|
-
"box-shadow:0
|
|
812
|
+
"border-radius:16px",
|
|
813
|
+
"box-shadow:0 12px 32px rgba(108,92,231,.14)",
|
|
907
814
|
"padding:14px 40px 14px 16px",
|
|
908
815
|
"position:relative",
|
|
909
816
|
"cursor:pointer",
|
|
910
817
|
"font-family:inherit",
|
|
911
|
-
`align-self:${
|
|
818
|
+
`align-self:${s ? "flex-end" : "flex-start"}`,
|
|
912
819
|
"animation:ocw-teaser-in .22s ease-out"
|
|
913
820
|
].join(";");
|
|
914
821
|
const oe = document.createElement("div");
|
|
915
|
-
if (oe.textContent =
|
|
916
|
-
const
|
|
917
|
-
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
const
|
|
921
|
-
|
|
822
|
+
if (oe.textContent = z.title, oe.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", E.append(oe), z.subtitle) {
|
|
823
|
+
const O = document.createElement("div");
|
|
824
|
+
O.style.cssText = "display:flex;align-items:center;gap:6px;margin-top:6px;font-size:13px;color:#6b7280";
|
|
825
|
+
const ie = document.createElement("span");
|
|
826
|
+
ie.innerHTML = Le, ie.style.cssText = `color:${t.accent ?? "#6c5ce7"};display:inline-flex`;
|
|
827
|
+
const me = document.createElement("span");
|
|
828
|
+
me.textContent = z.subtitle, O.append(ie, me), E.append(O);
|
|
922
829
|
}
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
830
|
+
const U = document.createElement("button");
|
|
831
|
+
U.type = "button", U.setAttribute("aria-label", "Dismiss"), U.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', U.style.cssText = "position:absolute;top:8px;right:8px;width:24px;height:24px;border:none;border-radius:50%;background:#f3f4f6;color:#6b7280;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0", U.addEventListener("click", (O) => {
|
|
832
|
+
O.stopPropagation();
|
|
926
833
|
try {
|
|
927
|
-
sessionStorage.setItem(
|
|
834
|
+
sessionStorage.setItem(te, "1");
|
|
928
835
|
} catch {
|
|
929
836
|
}
|
|
930
|
-
|
|
931
|
-
}),
|
|
932
|
-
const
|
|
933
|
-
|
|
837
|
+
E && (E.remove(), E = null);
|
|
838
|
+
}), E.append(U);
|
|
839
|
+
const xe = () => {
|
|
840
|
+
u || (u = !0, ne(!0), Q(), v = 0, C && (C.style.display = "none"), E && (E.remove(), E = null));
|
|
934
841
|
};
|
|
935
|
-
|
|
936
|
-
(
|
|
937
|
-
}),
|
|
842
|
+
E.addEventListener("click", xe), E.addEventListener("keydown", (O) => {
|
|
843
|
+
(O.key === "Enter" || O.key === " ") && (O.preventDefault(), xe());
|
|
844
|
+
}), r.insertBefore(E, q);
|
|
938
845
|
};
|
|
939
846
|
if (!document.getElementById("ocw-teaser-style")) {
|
|
940
|
-
const
|
|
941
|
-
|
|
847
|
+
const z = document.createElement("style");
|
|
848
|
+
z.id = "ocw-teaser-style", z.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(z);
|
|
942
849
|
}
|
|
943
|
-
|
|
944
|
-
const
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
})) : (
|
|
948
|
-
|
|
850
|
+
d = be, be();
|
|
851
|
+
const ne = (z) => {
|
|
852
|
+
z ? (m.style.display = "flex", requestAnimationFrame(() => {
|
|
853
|
+
m.style.opacity = "1", m.style.transform = "scale(1)";
|
|
854
|
+
})) : (m.style.opacity = "0", m.style.transform = "scale(.95)", setTimeout(() => {
|
|
855
|
+
u || (m.style.display = "none");
|
|
949
856
|
}, 180));
|
|
950
857
|
};
|
|
951
|
-
|
|
952
|
-
if (
|
|
953
|
-
|
|
858
|
+
q.addEventListener("click", () => {
|
|
859
|
+
if (u = !u, ne(u), Q(), u) {
|
|
860
|
+
v = 0, C && (C.style.display = "none");
|
|
954
861
|
try {
|
|
955
|
-
sessionStorage.setItem(
|
|
862
|
+
sessionStorage.setItem(te, "1");
|
|
956
863
|
} catch {
|
|
957
864
|
}
|
|
958
865
|
}
|
|
959
|
-
|
|
960
|
-
}),
|
|
961
|
-
|
|
962
|
-
}, document.addEventListener("keydown",
|
|
866
|
+
d == null || d();
|
|
867
|
+
}), j = (z) => {
|
|
868
|
+
z.key === "Escape" && u && (u = !1, ne(!1), Q());
|
|
869
|
+
}, document.addEventListener("keydown", j);
|
|
963
870
|
}
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
},
|
|
871
|
+
const f = () => {
|
|
872
|
+
u || (v++, C && (C.textContent = String(v), C.style.display = "flex"));
|
|
873
|
+
}, R = () => {
|
|
967
874
|
try {
|
|
968
|
-
const
|
|
969
|
-
if (!
|
|
970
|
-
|
|
875
|
+
const o = Xe();
|
|
876
|
+
if (!o) return;
|
|
877
|
+
o.state === "suspended" && o.resume().catch(() => {
|
|
971
878
|
});
|
|
972
|
-
const
|
|
973
|
-
|
|
879
|
+
const s = o.createOscillator(), m = o.createGain();
|
|
880
|
+
s.connect(m), m.connect(o.destination), s.frequency.setValueAtTime(880, o.currentTime), s.frequency.exponentialRampToValueAtTime(440, o.currentTime + 0.15), m.gain.setValueAtTime(0.3, o.currentTime), m.gain.exponentialRampToValueAtTime(1e-3, o.currentTime + 0.3), s.start(), s.stop(o.currentTime + 0.3);
|
|
974
881
|
} catch {
|
|
975
882
|
}
|
|
976
|
-
},
|
|
977
|
-
for (;
|
|
978
|
-
const
|
|
979
|
-
|
|
883
|
+
}, $ = [], A = (o) => {
|
|
884
|
+
for (; $.length; ) {
|
|
885
|
+
const s = $.shift();
|
|
886
|
+
b.add({ clientMsgId: s.clientMsgId, content: s.content, ts: Date.now() }), k.send({ type: "send", conversationId: o, clientMsgId: s.clientMsgId, content: s.content });
|
|
980
887
|
}
|
|
981
888
|
};
|
|
982
|
-
let
|
|
983
|
-
const
|
|
984
|
-
let
|
|
985
|
-
const
|
|
986
|
-
let
|
|
987
|
-
const
|
|
988
|
-
|
|
989
|
-
|
|
889
|
+
let k;
|
|
890
|
+
const S = new De(`ocw-e2e-${t.profileId}`);
|
|
891
|
+
let D = !1;
|
|
892
|
+
const g = [], N = [];
|
|
893
|
+
let H = !1;
|
|
894
|
+
const ee = (o, s) => {
|
|
895
|
+
S.sealText(s).then((m) => {
|
|
896
|
+
a && k.send({ type: "send", conversationId: a, clientMsgId: o, content: m });
|
|
990
897
|
});
|
|
991
|
-
},
|
|
992
|
-
|
|
993
|
-
|
|
898
|
+
}, ke = (o, s, m) => {
|
|
899
|
+
S.sealText(s, m).then((L) => {
|
|
900
|
+
a && k.send({ type: "send", conversationId: a, clientMsgId: o, content: L });
|
|
994
901
|
});
|
|
995
|
-
},
|
|
996
|
-
for (;
|
|
997
|
-
const
|
|
998
|
-
|
|
902
|
+
}, Ce = () => {
|
|
903
|
+
for (; g.length; ) {
|
|
904
|
+
const o = g.shift();
|
|
905
|
+
ee(o.clientMsgId, o.text);
|
|
999
906
|
}
|
|
1000
|
-
for (;
|
|
1001
|
-
const
|
|
1002
|
-
|
|
907
|
+
for (; N.length; ) {
|
|
908
|
+
const o = N.shift();
|
|
909
|
+
ee(o.clientMsgId, o.text);
|
|
1003
910
|
}
|
|
1004
|
-
},
|
|
1005
|
-
|
|
1006
|
-
},
|
|
1007
|
-
|
|
1008
|
-
const
|
|
1009
|
-
onSend(
|
|
1010
|
-
const
|
|
1011
|
-
|
|
911
|
+
}, Te = (o) => {
|
|
912
|
+
k.send({ type: "fetchPrekey", targetUserId: o });
|
|
913
|
+
}, Ie = t.i18n ?? {}, Se = ["ar", "he", "fa", "ur"], Ee = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
|
|
914
|
+
Se.includes(Ee) && !t.el.dir && (t.el.dir = "rtl", t.el.style.fontFamily = t.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
|
|
915
|
+
const re = `oc_prechat_${t.profileId}_${i.slice(-8)}`, B = new Ve(t.el, i, {
|
|
916
|
+
onSend(o) {
|
|
917
|
+
const s = `cm_${Math.random().toString(36).slice(2)}`, m = { kind: "text", text: o };
|
|
918
|
+
p.addOptimistic(s, m), B.render(p), p.e2e ? S.ready ? ee(s, o) : H ? N.push({ clientMsgId: s, text: o }) : (g.push({ clientMsgId: s, text: o }), p.assignedAgentId && Te(p.assignedAgentId)) : a ? (b.add({ clientMsgId: s, content: m, ts: Date.now() }), k.send({ type: "send", conversationId: a, clientMsgId: s, content: m })) : $.push({ clientMsgId: s, content: m });
|
|
1012
919
|
},
|
|
1013
|
-
async onAttach(
|
|
1014
|
-
if (!
|
|
1015
|
-
const
|
|
1016
|
-
|
|
920
|
+
async onAttach(o) {
|
|
921
|
+
if (!a) return;
|
|
922
|
+
const s = `${y}/upload?name=${encodeURIComponent(o.name)}`, m = `cm_${Math.random().toString(36).slice(2)}`;
|
|
923
|
+
p.addOptimistic(m, { kind: "text", text: `📎 Uploading ${o.name}…` }), B.render(p);
|
|
1017
924
|
try {
|
|
1018
|
-
const
|
|
925
|
+
const L = await fetch(s, {
|
|
1019
926
|
method: "POST",
|
|
1020
927
|
// Use the resolved connection token (a signed JWT, an explicit userId,
|
|
1021
928
|
// or the anonymous persistent uid) — NOT just opts.token. The server
|
|
1022
929
|
// requires an Authorization header, and the verifier accepts an
|
|
1023
930
|
// anonymous id as a guest; keying off opts.token alone meant anonymous
|
|
1024
931
|
// visitors (the common case) sent no auth and every upload 401'd.
|
|
1025
|
-
headers: { "content-type":
|
|
1026
|
-
body:
|
|
932
|
+
headers: { "content-type": o.type, authorization: `Bearer ${i}` },
|
|
933
|
+
body: o
|
|
1027
934
|
});
|
|
1028
|
-
if (!
|
|
1029
|
-
const { url:
|
|
1030
|
-
|
|
1031
|
-
} catch (
|
|
1032
|
-
|
|
935
|
+
if (!L.ok) throw new Error(`Upload failed: ${L.status}`);
|
|
936
|
+
const { url: W, name: G, mime: Y, size: X } = await L.json();
|
|
937
|
+
p.addOptimistic(m, { kind: "attachment", url: W, name: G, mime: Y, size: X }), B.render(p), k.send({ type: "send", conversationId: a, clientMsgId: m, content: { kind: "attachment", url: W, name: G, mime: Y, size: X } });
|
|
938
|
+
} catch (L) {
|
|
939
|
+
p.addOptimistic(m, { kind: "text", text: `⚠️ Upload failed: ${L.message}` }), B.render(p);
|
|
1033
940
|
}
|
|
1034
941
|
},
|
|
1035
|
-
onInvoke(
|
|
1036
|
-
|
|
942
|
+
onInvoke(o, s) {
|
|
943
|
+
a && k.send({ type: "invoke", conversationId: a, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...s ? { inputs: s } : {} });
|
|
1037
944
|
},
|
|
1038
|
-
onTyping(
|
|
1039
|
-
|
|
945
|
+
onTyping(o, s) {
|
|
946
|
+
a && k.send({ type: "typing", conversationId: a, isTyping: o, ...s ? { preview: s } : {} });
|
|
1040
947
|
},
|
|
1041
|
-
onPreChat(
|
|
948
|
+
onPreChat(o) {
|
|
1042
949
|
try {
|
|
1043
950
|
localStorage.setItem(re, "1");
|
|
1044
951
|
} catch {
|
|
1045
952
|
}
|
|
1046
|
-
|
|
953
|
+
k.send({
|
|
1047
954
|
type: "open",
|
|
1048
955
|
profileId: t.profileId,
|
|
1049
956
|
...t.subjectId ? { subjectId: t.subjectId } : {},
|
|
1050
957
|
userInfo: {
|
|
1051
|
-
...
|
|
1052
|
-
...
|
|
1053
|
-
...
|
|
1054
|
-
...
|
|
1055
|
-
...
|
|
958
|
+
...o.name ? { name: o.name } : {},
|
|
959
|
+
...o.email ? { email: o.email } : {},
|
|
960
|
+
...o.phone || o.topic ? { meta: {
|
|
961
|
+
...o.phone ? { phone: o.phone } : {},
|
|
962
|
+
...o.topic ? { topic: o.topic } : {}
|
|
1056
963
|
} } : {}
|
|
1057
964
|
}
|
|
1058
965
|
});
|
|
1059
|
-
const
|
|
1060
|
-
|
|
966
|
+
const s = o.callback ? `📞 Call-back requested${o.phone ? `: ${o.phone}` : ""}${o.topic ? ` — ${o.topic}` : ""}` : o.topic ? `Topic: ${o.topic}` : "";
|
|
967
|
+
s && a && !p.e2e && k.send({ type: "send", conversationId: a, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: s } });
|
|
1061
968
|
},
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
969
|
+
...((le = t.features) == null ? void 0 : le.deflection) !== !1 ? {
|
|
970
|
+
onDeflectQuery(o) {
|
|
971
|
+
if (c) return;
|
|
972
|
+
clearTimeout(l);
|
|
973
|
+
const s = o.trim();
|
|
974
|
+
if (s.length < 3) {
|
|
975
|
+
B.hideDeflection();
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
l = setTimeout(() => {
|
|
979
|
+
fetch(`${y}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(s.slice(0, 200))}`).then((m) => m.ok ? m.json() : { articles: [] }).then((m) => B.showDeflection(m.articles ?? [])).catch(() => B.hideDeflection());
|
|
980
|
+
}, 350);
|
|
1069
981
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
},
|
|
1074
|
-
onReadUpTo(n) {
|
|
1075
|
-
r && T.send({ type: "read", conversationId: r, seq: n });
|
|
982
|
+
} : {},
|
|
983
|
+
onReadUpTo(o) {
|
|
984
|
+
a && k.send({ type: "read", conversationId: a, seq: o });
|
|
1076
985
|
},
|
|
1077
986
|
onLoadMore() {
|
|
1078
|
-
if (!
|
|
1079
|
-
const
|
|
1080
|
-
|
|
987
|
+
if (!a || !p.e2e) return;
|
|
988
|
+
const o = p.messages()[0];
|
|
989
|
+
o && k.send({ type: "history", conversationId: a, beforeSeq: o.seq, limit: 20 });
|
|
1081
990
|
},
|
|
1082
|
-
onEdit(
|
|
1083
|
-
|
|
991
|
+
onEdit(o, s) {
|
|
992
|
+
a && k.send({ type: "edit", conversationId: a, messageId: o, content: { kind: "text", text: s } });
|
|
1084
993
|
},
|
|
1085
|
-
onDelete(
|
|
1086
|
-
|
|
1087
|
-
},
|
|
1088
|
-
onReact(n, p, x) {
|
|
1089
|
-
r && T.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: x });
|
|
1090
|
-
},
|
|
1091
|
-
onCsat(n) {
|
|
1092
|
-
r && fetch(`${b}/conversations/${r}/csat`, {
|
|
1093
|
-
method: "POST",
|
|
1094
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${a}` },
|
|
1095
|
-
body: JSON.stringify({ score: n })
|
|
1096
|
-
}).catch(() => {
|
|
1097
|
-
});
|
|
1098
|
-
},
|
|
1099
|
-
onAnnotate(n) {
|
|
1100
|
-
r && T.send({ type: "annotate", conversationId: r, stroke: n });
|
|
1101
|
-
},
|
|
1102
|
-
onAnnotateClear() {
|
|
1103
|
-
r && T.send({ type: "annotate_clear", conversationId: r });
|
|
994
|
+
onDelete(o) {
|
|
995
|
+
a && k.send({ type: "delete", conversationId: a, messageId: o });
|
|
1104
996
|
},
|
|
997
|
+
...((de = t.features) == null ? void 0 : de.reactions) !== !1 ? {
|
|
998
|
+
onReact(o, s, m) {
|
|
999
|
+
a && k.send({ type: "react", conversationId: a, messageId: o, emoji: s, remove: m });
|
|
1000
|
+
}
|
|
1001
|
+
} : {},
|
|
1002
|
+
...((pe = t.features) == null ? void 0 : pe.csat) !== !1 ? {
|
|
1003
|
+
onCsat(o) {
|
|
1004
|
+
a && fetch(`${y}/conversations/${a}/csat`, {
|
|
1005
|
+
method: "POST",
|
|
1006
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${i}` },
|
|
1007
|
+
body: JSON.stringify({ score: o })
|
|
1008
|
+
}).catch(() => {
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
} : {},
|
|
1105
1012
|
...t.translateLang ? {
|
|
1106
|
-
async onTranslate(
|
|
1013
|
+
async onTranslate(o) {
|
|
1107
1014
|
try {
|
|
1108
|
-
const
|
|
1015
|
+
const s = await fetch(`${y}/translate`, {
|
|
1109
1016
|
method: "POST",
|
|
1110
|
-
headers: { "content-type": "application/json", authorization: `Bearer ${
|
|
1111
|
-
body: JSON.stringify({ text:
|
|
1017
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${i}` },
|
|
1018
|
+
body: JSON.stringify({ text: o, targetLang: t.translateLang })
|
|
1112
1019
|
});
|
|
1113
|
-
if (!
|
|
1114
|
-
const { translated:
|
|
1115
|
-
return
|
|
1020
|
+
if (!s.ok) return null;
|
|
1021
|
+
const { translated: m } = await s.json();
|
|
1022
|
+
return m;
|
|
1116
1023
|
} catch {
|
|
1117
1024
|
return null;
|
|
1118
1025
|
}
|
|
@@ -1123,8 +1030,10 @@ function ot(t) {
|
|
|
1123
1030
|
...t.subject ? { subject: t.subject } : {},
|
|
1124
1031
|
...t.quickReplies ? { quickReplies: t.quickReplies } : {},
|
|
1125
1032
|
...t.accent ? { accent: t.accent } : {},
|
|
1126
|
-
...
|
|
1127
|
-
|
|
1033
|
+
...t.accent2 ? { accent2: t.accent2 } : {},
|
|
1034
|
+
...t.theme ? { theme: t.theme } : {},
|
|
1035
|
+
...(he = t.user) != null && he.name || (ue = t.user) != null && ue.avatar ? { userInfo: { ...t.user.name ? { name: t.user.name } : {}, ...t.user.avatar ? { avatar: t.user.avatar } : {} } } : {},
|
|
1036
|
+
i18n: Ie
|
|
1128
1037
|
});
|
|
1129
1038
|
try {
|
|
1130
1039
|
localStorage.getItem(re) && B.completePreChat();
|
|
@@ -1135,90 +1044,90 @@ function ot(t) {
|
|
|
1135
1044
|
...t.user.email ? { email: t.user.email } : {},
|
|
1136
1045
|
...t.user.avatar ? { avatar: t.user.avatar } : {},
|
|
1137
1046
|
...t.user.meta ? { meta: t.user.meta } : {}
|
|
1138
|
-
} : void 0,
|
|
1047
|
+
} : void 0, ze = {
|
|
1139
1048
|
type: "open",
|
|
1140
1049
|
profileId: t.profileId,
|
|
1141
1050
|
// Direct conversations use the kind/peerId pair; the dm:… subject key is
|
|
1142
1051
|
// server-derived and owner-keyed, so passing it as subjectId from the
|
|
1143
1052
|
// NON-owner side would find-or-create a junk duplicate thread.
|
|
1144
1053
|
...t.kind === "direct" && t.peerId ? { kind: "direct", peerId: t.peerId } : t.subjectId ? { subjectId: t.subjectId } : {},
|
|
1145
|
-
...
|
|
1054
|
+
...x ? { linkFrom: x } : {},
|
|
1146
1055
|
...ce ? { userInfo: ce } : {},
|
|
1147
1056
|
...typeof location < "u" ? { pageUrl: location.href } : {},
|
|
1148
1057
|
...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
|
|
1149
1058
|
// Pass subject display info so the server can persist it to the Subject record.
|
|
1150
1059
|
// This is how listingTitle and listingMeta get saved without a separate API call.
|
|
1151
|
-
...(
|
|
1152
|
-
...(
|
|
1060
|
+
...(fe = t.subject) != null && fe.title ? { subjectTitle: t.subject.title } : {},
|
|
1061
|
+
...(we = t.subject) != null && we.subtitle ? { subjectMeta: t.subject.subtitle } : {}
|
|
1153
1062
|
};
|
|
1154
|
-
|
|
1063
|
+
k = new Oe({
|
|
1155
1064
|
...t.refreshToken ? { refreshToken: t.refreshToken } : {},
|
|
1156
1065
|
url: w,
|
|
1157
|
-
token:
|
|
1158
|
-
open:
|
|
1159
|
-
getCursor: () =>
|
|
1160
|
-
onStatusChange: (
|
|
1161
|
-
onFrame(
|
|
1162
|
-
if (
|
|
1163
|
-
if (
|
|
1164
|
-
|
|
1165
|
-
for (const
|
|
1166
|
-
|
|
1066
|
+
token: i,
|
|
1067
|
+
open: ze,
|
|
1068
|
+
getCursor: () => p.highestSeq(),
|
|
1069
|
+
onStatusChange: (o, s) => B.setConnStatus(o, s),
|
|
1070
|
+
onFrame(o) {
|
|
1071
|
+
if (o.type === "opened") {
|
|
1072
|
+
if (a = o.conversation.id, !P) {
|
|
1073
|
+
P = !0;
|
|
1074
|
+
for (const s of b.load())
|
|
1075
|
+
k.send({ type: "send", conversationId: a, clientMsgId: s.clientMsgId, content: s.content });
|
|
1167
1076
|
}
|
|
1168
|
-
|
|
1077
|
+
Ae(w, i, a, p, B, y), $.length && A(a);
|
|
1169
1078
|
}
|
|
1170
|
-
if (
|
|
1171
|
-
|
|
1172
|
-
const
|
|
1173
|
-
for (const
|
|
1174
|
-
B.render(
|
|
1079
|
+
if (o.type === "ack" && b.remove(o.clientMsgId), o.type === "prekeyBundle") {
|
|
1080
|
+
o.bundle && (H = !0, S.x3dhSendTo(o.bundle).then((s) => {
|
|
1081
|
+
const m = [...g.splice(0), ...N.splice(0)];
|
|
1082
|
+
for (const L of m) ke(L.clientMsgId, L.text, s);
|
|
1083
|
+
B.render(p);
|
|
1175
1084
|
}));
|
|
1176
1085
|
return;
|
|
1177
1086
|
}
|
|
1178
|
-
if (
|
|
1179
|
-
const
|
|
1180
|
-
if (
|
|
1181
|
-
|
|
1182
|
-
await
|
|
1087
|
+
if (o.type === "message" && p.e2e) {
|
|
1088
|
+
const s = He(o.message.content);
|
|
1089
|
+
if (s && !S.ready) {
|
|
1090
|
+
S.x3dhReceiveFrom(s.x3dhIK, s.x3dhEK, s.x3dhSPK, s.x3dhOTP).then(async () => {
|
|
1091
|
+
await S.openFrame(o), p.apply(o), B.render(p);
|
|
1183
1092
|
});
|
|
1184
1093
|
return;
|
|
1185
1094
|
}
|
|
1186
1095
|
}
|
|
1187
|
-
if (
|
|
1188
|
-
|
|
1189
|
-
|
|
1096
|
+
if (o.type === "peerkey") {
|
|
1097
|
+
S.onPeerKey(o.key).then(() => {
|
|
1098
|
+
Ce(), B.render(p);
|
|
1190
1099
|
});
|
|
1191
1100
|
return;
|
|
1192
1101
|
}
|
|
1193
1102
|
(async () => {
|
|
1194
|
-
if (
|
|
1195
|
-
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
const
|
|
1199
|
-
|
|
1103
|
+
if (p.e2e && await S.openFrame(o), p.apply(o), o.type === "manifest" && (d == null || d()), o.type === "message" && o.message.senderId !== i && !o.message.internal && (f(), R()), p.e2e && a && !D) {
|
|
1104
|
+
D = !0;
|
|
1105
|
+
const s = await S.initX3DH();
|
|
1106
|
+
k.send({ type: "uploadPrekeys", ...s });
|
|
1107
|
+
const m = await S.begin();
|
|
1108
|
+
k.send({ type: "pubkey", conversationId: a, key: m });
|
|
1200
1109
|
}
|
|
1201
|
-
B.render(
|
|
1110
|
+
B.render(p);
|
|
1202
1111
|
})();
|
|
1203
1112
|
}
|
|
1204
|
-
}),
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1113
|
+
}), k.connect(), B.render(p);
|
|
1114
|
+
const F = t.launcher ? ve(t) : null, V = { close: () => {
|
|
1115
|
+
c = !0, clearTimeout(l), k.close(), r == null || r.remove(), B.destroy(), I && M && I.removeEventListener("change", M), j && (document.removeEventListener("keydown", j), j = null), _.delete(t.el), F && Z.get(F) === V && Z.delete(F);
|
|
1207
1116
|
} };
|
|
1208
|
-
return
|
|
1117
|
+
return _.set(t.el, V), F && Z.set(F, V), V;
|
|
1209
1118
|
}
|
|
1210
1119
|
export {
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1120
|
+
Ne as ChatStore,
|
|
1121
|
+
Oe as ConnectionManager,
|
|
1122
|
+
De as E2ESession,
|
|
1123
|
+
qe as PersistentOutbox,
|
|
1124
|
+
Ve as Renderer,
|
|
1125
|
+
st as asConversationId,
|
|
1126
|
+
He as extractX3DHInit,
|
|
1127
|
+
rt as httpBaseFromWsUrl,
|
|
1219
1128
|
ot as mount,
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1129
|
+
Re as resolveRelayUrls,
|
|
1130
|
+
Ae as restoreHistory,
|
|
1131
|
+
nt as unmount
|
|
1223
1132
|
};
|
|
1224
1133
|
//# sourceMappingURL=index.js.map
|