@spilki/widget 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap.es.js +368 -240
- package/dist/bootstrap.es.js.map +1 -1
- package/dist/bootstrap.umd.js +12 -9
- package/dist/bootstrap.umd.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/ui/bubble.d.ts +3 -0
- package/dist/ui/bubble.d.ts.map +1 -1
- package/dist/ui/overlap.d.ts +42 -0
- package/dist/ui/overlap.d.ts.map +1 -0
- package/dist/ui/panel.d.ts +1 -0
- package/dist/ui/panel.d.ts.map +1 -1
- package/dist/widget.es.js +369 -241
- package/dist/widget.es.js.map +1 -1
- package/dist/widget.umd.js +12 -9
- package/dist/widget.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/widget.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const Y = `
|
|
2
2
|
<style>
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
@@ -12,6 +12,9 @@ const F = `
|
|
|
12
12
|
:host([data-position="bottom-left"]) {
|
|
13
13
|
left: 24px;
|
|
14
14
|
}
|
|
15
|
+
:host([data-dimmed]) button {
|
|
16
|
+
opacity: 0.4;
|
|
17
|
+
}
|
|
15
18
|
button {
|
|
16
19
|
all: unset;
|
|
17
20
|
position: relative;
|
|
@@ -25,7 +28,7 @@ const F = `
|
|
|
25
28
|
background: var(--spilki-accent);
|
|
26
29
|
color: #fff;
|
|
27
30
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
28
|
-
transition: transform 0.18s ease, box-shadow 0.18s ease;
|
|
31
|
+
transition: transform 0.18s ease, box-shadow 0.18s ease, opacity 0.2s ease;
|
|
29
32
|
}
|
|
30
33
|
button:focus-visible {
|
|
31
34
|
outline: 2px solid #fff;
|
|
@@ -71,13 +74,13 @@ const F = `
|
|
|
71
74
|
<span class="badge" hidden aria-hidden="true">0</span>
|
|
72
75
|
</button>
|
|
73
76
|
`;
|
|
74
|
-
function
|
|
77
|
+
function G(o) {
|
|
75
78
|
const e = document.createElement("div");
|
|
76
|
-
e.setAttribute("part", "bubble-root"), e.setAttribute("data-position",
|
|
79
|
+
e.setAttribute("part", "bubble-root"), e.setAttribute("data-position", o.position), e.style.setProperty("--spilki-accent", o.color);
|
|
77
80
|
const t = e.attachShadow({ mode: "open" });
|
|
78
|
-
t.innerHTML =
|
|
81
|
+
t.innerHTML = Y;
|
|
79
82
|
const s = t.querySelector("button"), i = t.querySelector(".badge");
|
|
80
|
-
return s.addEventListener("click", () =>
|
|
83
|
+
return s.addEventListener("click", () => o.onClick()), {
|
|
81
84
|
element: e,
|
|
82
85
|
mount() {
|
|
83
86
|
document.body.appendChild(e);
|
|
@@ -85,20 +88,29 @@ function R(r) {
|
|
|
85
88
|
destroy() {
|
|
86
89
|
e.remove();
|
|
87
90
|
},
|
|
88
|
-
setOpen(
|
|
89
|
-
s.setAttribute("aria-expanded", String(
|
|
91
|
+
setOpen(a) {
|
|
92
|
+
s.setAttribute("aria-expanded", String(a)), s.setAttribute("aria-label", a ? "Close chat" : "Open chat");
|
|
90
93
|
},
|
|
91
|
-
setBadge(
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
i.toggleAttribute("hidden", !0), i.textContent = "0",
|
|
94
|
+
setBadge(a) {
|
|
95
|
+
const r = Math.max(0, a), l = s.getAttribute("aria-expanded") === "true";
|
|
96
|
+
if (r === 0) {
|
|
97
|
+
i.toggleAttribute("hidden", !0), i.textContent = "0", l || s.setAttribute("aria-label", "Open chat");
|
|
95
98
|
return;
|
|
96
99
|
}
|
|
97
|
-
i.toggleAttribute("hidden", !1), i.textContent =
|
|
100
|
+
i.toggleAttribute("hidden", !1), i.textContent = r > 99 ? "99+" : String(r), l || s.setAttribute("aria-label", `Open chat, ${r} unread`);
|
|
101
|
+
},
|
|
102
|
+
setDimmed(a) {
|
|
103
|
+
e.toggleAttribute("data-dimmed", a);
|
|
104
|
+
},
|
|
105
|
+
setPassthrough(a) {
|
|
106
|
+
e.style.pointerEvents = a ? "none" : "";
|
|
107
|
+
},
|
|
108
|
+
setPosition(a) {
|
|
109
|
+
e.setAttribute("data-position", a);
|
|
98
110
|
}
|
|
99
111
|
};
|
|
100
112
|
}
|
|
101
|
-
const
|
|
113
|
+
const V = "https://api.spilki.app", M = {
|
|
102
114
|
welcome: "Hi! I'm your assistant.",
|
|
103
115
|
placeholder: "Type a message…",
|
|
104
116
|
sendLabel: "Send",
|
|
@@ -109,57 +121,57 @@ const K = "https://api.spilki.app", I = {
|
|
|
109
121
|
offline: "Unable to connect. Please try again later.",
|
|
110
122
|
title: "Spilki Assistant"
|
|
111
123
|
}, w = {
|
|
112
|
-
apiBase:
|
|
124
|
+
apiBase: V,
|
|
113
125
|
position: "bottom-right",
|
|
114
126
|
theme: "auto",
|
|
115
127
|
color: "#6366f1",
|
|
116
|
-
welcome:
|
|
128
|
+
welcome: M.welcome,
|
|
117
129
|
persist: !0,
|
|
118
130
|
sound: !0,
|
|
119
|
-
i18n:
|
|
131
|
+
i18n: M
|
|
120
132
|
};
|
|
121
|
-
function
|
|
122
|
-
var t, s, i,
|
|
123
|
-
const e = { ...
|
|
133
|
+
function J(o) {
|
|
134
|
+
var t, s, i, n, a, r, l, p;
|
|
135
|
+
const e = { ...M, ...(t = o.i18n) != null ? t : {} };
|
|
124
136
|
return {
|
|
125
137
|
...w,
|
|
126
|
-
...
|
|
127
|
-
apiBase: (s =
|
|
138
|
+
...o,
|
|
139
|
+
apiBase: (s = o.apiBase) != null ? s : w.apiBase,
|
|
128
140
|
i18n: e,
|
|
129
|
-
welcome: (i =
|
|
130
|
-
position: (
|
|
131
|
-
theme: (
|
|
132
|
-
color: (
|
|
133
|
-
persist: (
|
|
134
|
-
sound: (
|
|
141
|
+
welcome: (i = o.welcome) != null ? i : e.welcome,
|
|
142
|
+
position: (n = o.position) != null ? n : w.position,
|
|
143
|
+
theme: (a = o.theme) != null ? a : w.theme,
|
|
144
|
+
color: (r = o.color) != null ? r : w.color,
|
|
145
|
+
persist: (l = o.persist) != null ? l : w.persist,
|
|
146
|
+
sound: (p = o.sound) != null ? p : w.sound
|
|
135
147
|
};
|
|
136
148
|
}
|
|
137
|
-
function
|
|
138
|
-
return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${
|
|
149
|
+
function X(o = "msg") {
|
|
150
|
+
return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${o}-${Math.random().toString(16).slice(2)}`;
|
|
139
151
|
}
|
|
140
|
-
function
|
|
141
|
-
var
|
|
142
|
-
return (e = (
|
|
152
|
+
function Z() {
|
|
153
|
+
var o, e;
|
|
154
|
+
return (e = (o = window.matchMedia) == null ? void 0 : o.call(window, "(prefers-color-scheme: dark)").matches) != null ? e : !1;
|
|
143
155
|
}
|
|
144
|
-
function
|
|
145
|
-
return
|
|
156
|
+
function R(o) {
|
|
157
|
+
return o === "light" || o === "dark" ? o : Z() ? "dark" : "light";
|
|
146
158
|
}
|
|
147
|
-
function
|
|
148
|
-
return
|
|
159
|
+
function A(o, e = 30) {
|
|
160
|
+
return o.slice(-e);
|
|
149
161
|
}
|
|
150
|
-
function
|
|
151
|
-
if (!
|
|
162
|
+
function Q(o) {
|
|
163
|
+
if (!o || o.length === 0) return;
|
|
152
164
|
const e = window.location.origin;
|
|
153
|
-
|
|
154
|
-
`SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${
|
|
165
|
+
o.includes(e) || console.warn(
|
|
166
|
+
`SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${o.join(", ")}`
|
|
155
167
|
);
|
|
156
168
|
}
|
|
157
|
-
const
|
|
158
|
-
function
|
|
159
|
-
const e = new Date(
|
|
160
|
-
return
|
|
169
|
+
const ee = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
170
|
+
function te(o) {
|
|
171
|
+
const e = new Date(o), t = /* @__PURE__ */ new Date(), s = (l) => String(l).padStart(2, "0"), i = `${s(e.getHours())}:${s(e.getMinutes())}`, n = new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime(), a = n - 864e5, r = new Date(e.getFullYear(), e.getMonth(), e.getDate()).getTime();
|
|
172
|
+
return r === n ? `Today at ${i}` : r === a ? `Yesterday at ${i}` : `${ee[e.getMonth()]} ${e.getDate()}, ${i}`;
|
|
161
173
|
}
|
|
162
|
-
const
|
|
174
|
+
const se = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-text-light: #0f172a;--spilki-text-dark: #f8fafc;--spilki-border-light: rgba(15, 23, 42, .1);--spilki-border-dark: rgba(148, 163, 184, .25);--spilki-muted-light: #64748b;--spilki-muted-dark: #94a3b8;--spilki-shadow: 0 10px 40px rgba(15, 23, 42, .2);--spilki-radius: 16px;--spilki-font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;color:inherit;font-family:var(--spilki-font)}.wrapper{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:var(--spilki-surface);color:var(--spilki-text);border-radius:var(--spilki-radius);box-shadow:var(--spilki-shadow);border:1px solid var(--spilki-border);overflow:hidden}header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--spilki-surface);border-bottom:1px solid var(--spilki-border)}header h1{font-size:1rem;margin:0;display:flex;align-items:center;gap:.5rem}header button.close{border:none;background:transparent;color:inherit;font-size:1.25rem;cursor:pointer}header button.close:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}header .status-dot{width:10px;height:10px;border-radius:999px;background:var(--spilki-accent)}.messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem;scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent;scroll-behavior:smooth}.message{display:flex;flex-direction:column;gap:.15rem;max-width:85%;width:fit-content;line-height:1.4;word-wrap:break-word;overflow-wrap:anywhere;white-space:pre-wrap}.message.user{align-self:flex-end;align-items:flex-end}.message .bubble{padding:.6rem .8rem;border-radius:1rem;background:#6366f126}.message.user .bubble{background:var(--spilki-accent);color:#fff}.message.bot .bubble{background:#94a3b826}.msg-time{font-size:.7rem;color:var(--spilki-muted);margin-top:2px}.date-separator{display:flex;align-items:center;gap:.5rem;padding:.4rem 0;font-size:.72rem;color:var(--spilki-muted);white-space:nowrap}.date-separator:before,.date-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.scroll-bottom{position:absolute;right:1rem;bottom:88px;width:38px;height:38px;border:none;border-radius:999px;background:var(--spilki-accent);color:#fff;box-shadow:0 8px 20px #0f172a40;cursor:pointer;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease;z-index:3}.scroll-bottom.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.scroll-arrow{font-size:.8rem;line-height:1}.scroll-count{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;border-radius:999px;background:#ef4444;color:#fff;font-size:10px;line-height:16px;text-align:center;padding:0 4px}.suggested-replies{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem 1rem;border-top:1px solid var(--spilki-border)}.suggested-chip{border:1px solid var(--spilki-accent);background:transparent;color:var(--spilki-accent);border-radius:999px;padding:.35rem .75rem;font-size:.8rem;font-family:inherit;cursor:pointer;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:background .15s,color .15s}.suggested-chip:hover{background:var(--spilki-accent);color:#fff}.suggested-chip:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.input-area{padding:.5rem .75rem}.input-wrap{display:flex;align-items:center;border:1px solid var(--spilki-border);border-radius:1.5rem;background:transparent;padding-left:0}.input-area textarea{flex:1;resize:none;min-height:2.4rem;max-height:6rem;border:0;border-radius:0;outline:0;background:transparent;box-shadow:none;-webkit-box-shadow:none;-webkit-appearance:none;appearance:none;padding:.55rem 0 .55rem 1rem;font-family:inherit;font-size:.95rem;color:var(--spilki-text);scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent}.input-actions{display:flex;align-items:center;gap:.25rem;padding:.25rem .35rem;flex-shrink:0}.input-actions button{width:32px;height:32px;display:grid;place-items:center;border:none;border-radius:50%;cursor:pointer;padding:0;transition:opacity .15s}.emoji-btn{background:#6366f126;color:var(--spilki-accent)}.emoji-btn:hover{background:#6366f140}.emoji-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:1px}.send-btn{background:var(--spilki-accent);color:#fff}.send-btn:hover{opacity:.85}.send-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.emoji-picker{position:absolute;right:1rem;bottom:80px;width:240px;max-height:180px;overflow-y:auto;display:none;grid-template-columns:repeat(10,minmax(0,1fr));gap:.25rem;padding:.5rem;background:var(--spilki-surface);border:1px solid var(--spilki-border);border-radius:12px;box-shadow:0 14px 30px #0f172a40;z-index:4}.emoji-option{width:100%;aspect-ratio:1;border:none;border-radius:8px;background:transparent;font-size:1rem;cursor:pointer}.emoji-option:hover,.emoji-option:focus-visible{background:#94a3b833}.typing{font-size:.75rem;color:var(--spilki-muted);padding:0 1rem .75rem}.typing:after{content:"";animation:dots 1.2s steps(4,end) infinite}@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}.offline{font-size:.8rem;padding:0 1rem;color:#f97316}:host([data-theme="dark"]){--spilki-surface: var(--spilki-bg-dark);--spilki-text: var(--spilki-text-dark);--spilki-border: var(--spilki-border-dark);--spilki-muted: var(--spilki-muted-dark)}:host([data-theme="dark"]) .messages,:host([data-theme="dark"]) .input-area textarea,:host([data-theme="dark"]) .emoji-picker{scrollbar-color:rgba(255,255,255,.2) transparent}:host([data-theme="light"]){--spilki-surface: var(--spilki-bg-light);--spilki-text: var(--spilki-text-light);--spilki-border: var(--spilki-border-light);--spilki-muted: var(--spilki-muted-light)}:host([data-theme="dark"]) .message .bubble{background:#94a3b81f}:host([data-theme="dark"]) .message.bot .bubble{background:#6366f126}:host([data-theme="dark"]) .input-area textarea{background:transparent}.messages::-webkit-scrollbar,.input-area textarea::-webkit-scrollbar,.emoji-picker::-webkit-scrollbar{width:6px}.messages::-webkit-scrollbar-track,.input-area textarea::-webkit-scrollbar-track,.emoji-picker::-webkit-scrollbar-track{background:transparent}.messages::-webkit-scrollbar-thumb,.input-area textarea::-webkit-scrollbar-thumb,.emoji-picker::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:999px}.messages::-webkit-scrollbar-thumb:hover,.input-area textarea::-webkit-scrollbar-thumb:hover,.emoji-picker::-webkit-scrollbar-thumb:hover{background:#94a3b880}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb{background:#fff3}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb:hover{background:#ffffff59}.conversation-separator{display:flex;align-items:center;gap:.5rem;padding:.5rem 0;cursor:pointer;user-select:none;font-size:.7rem;color:var(--spilki-muted);white-space:nowrap}.conversation-separator:before,.conversation-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.conversation-separator:hover{color:var(--spilki-text)}.conversation-separator:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}.conversation-history{display:none;flex-direction:column;gap:.5rem}.conversation-history.expanded{display:flex}', $ = 24 * 60 * 60 * 1e3, ie = 2 * 60 * 1e3, oe = 200, ne = [
|
|
163
175
|
"😀",
|
|
164
176
|
"😂",
|
|
165
177
|
"🤣",
|
|
@@ -211,10 +223,10 @@ const Y = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-t
|
|
|
211
223
|
"☕",
|
|
212
224
|
"🍕"
|
|
213
225
|
];
|
|
214
|
-
function
|
|
215
|
-
return
|
|
226
|
+
function S(o) {
|
|
227
|
+
return o.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
216
228
|
}
|
|
217
|
-
class
|
|
229
|
+
class re {
|
|
218
230
|
constructor(e) {
|
|
219
231
|
this.options = e, this.relativeTimeFormat = new Intl.RelativeTimeFormat(void 0, {
|
|
220
232
|
numeric: "auto"
|
|
@@ -229,9 +241,9 @@ class Q {
|
|
|
229
241
|
day: "numeric",
|
|
230
242
|
year: "numeric"
|
|
231
243
|
}), this.renderedMessages = [], this.focusable = [], this.seenIds = /* @__PURE__ */ new Set(), this.lastTimelineMessage = null, this.scrollUnreadCount = 0, this.emojiPickerOpen = !1, this.open = !1, this.host = document.createElement("div"), this.host.setAttribute("part", "panel-root"), this.host.style.position = "fixed", this.host.style.bottom = "96px", this.host.style[e.position === "bottom-right" ? "right" : "left"] = "24px", this.host.style.width = "360px", this.host.style.maxWidth = "calc(100vw - 32px)", this.host.style.height = "520px", this.host.style.display = "none", this.host.style.zIndex = "2147483001", this.shadow = this.host.attachShadow({ mode: "open" });
|
|
232
|
-
const t =
|
|
244
|
+
const t = S(e.i18n.title), s = S(e.i18n.typing), i = S(e.i18n.offline), n = S(e.i18n.placeholder), a = S(e.i18n.sendLabel);
|
|
233
245
|
this.shadow.innerHTML = `
|
|
234
|
-
<style>${
|
|
246
|
+
<style>${se}</style>
|
|
235
247
|
<div class="wrapper" role="dialog" aria-modal="true" aria-label="${t}">
|
|
236
248
|
<header>
|
|
237
249
|
<h1><span class="status-dot" aria-hidden="true"></span>${t}</h1>
|
|
@@ -248,7 +260,7 @@ class Q {
|
|
|
248
260
|
<div class="emoji-picker" aria-label="Emoji picker"></div>
|
|
249
261
|
<div class="input-area">
|
|
250
262
|
<div class="input-wrap">
|
|
251
|
-
<textarea rows="1" placeholder="${
|
|
263
|
+
<textarea rows="1" placeholder="${n}" aria-label="${n}"></textarea>
|
|
252
264
|
<div class="input-actions">
|
|
253
265
|
<button class="emoji-btn" type="button" aria-label="Insert emoji">
|
|
254
266
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
@@ -258,7 +270,7 @@ class Q {
|
|
|
258
270
|
<circle cx="15" cy="10" r="1" fill="currentColor"/>
|
|
259
271
|
</svg>
|
|
260
272
|
</button>
|
|
261
|
-
<button type="button" class="send-btn" aria-label="${
|
|
273
|
+
<button type="button" class="send-btn" aria-label="${a}">
|
|
262
274
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
263
275
|
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" fill="currentColor"/>
|
|
264
276
|
</svg>
|
|
@@ -267,36 +279,39 @@ class Q {
|
|
|
267
279
|
</div>
|
|
268
280
|
</div>
|
|
269
281
|
</div>
|
|
270
|
-
`, this.host.dataset.theme = e.theme, this.host.style.setProperty("--spilki-accent", e.color), this.messagesEl = this.shadow.querySelector(".messages"), this.typingEl = this.shadow.querySelector(".typing"), this.input = this.shadow.querySelector("textarea"), this.offlineEl = this.shadow.querySelector(".offline"), this.sendButton = this.shadow.querySelector(".send-btn"), this.emojiButton = this.shadow.querySelector(".emoji-btn"), this.emojiPickerEl = this.shadow.querySelector(".emoji-picker"), this.scrollBottomButton = this.shadow.querySelector(".scroll-bottom"), this.scrollBottomCountEl = this.shadow.querySelector(".scroll-count"), this.closeButton = this.shadow.querySelector("header .close"), this.suggestedRepliesEl = this.shadow.querySelector(".suggested-replies"), this.handleCloseClick = () => this.options.onClose(), this.handleSendClick = () => this.send(), this.handleInputKeydown = (
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
else if (
|
|
282
|
+
`, this.host.dataset.theme = e.theme, this.host.style.setProperty("--spilki-accent", e.color), this.messagesEl = this.shadow.querySelector(".messages"), this.typingEl = this.shadow.querySelector(".typing"), this.input = this.shadow.querySelector("textarea"), this.offlineEl = this.shadow.querySelector(".offline"), this.sendButton = this.shadow.querySelector(".send-btn"), this.emojiButton = this.shadow.querySelector(".emoji-btn"), this.emojiPickerEl = this.shadow.querySelector(".emoji-picker"), this.scrollBottomButton = this.shadow.querySelector(".scroll-bottom"), this.scrollBottomCountEl = this.shadow.querySelector(".scroll-count"), this.closeButton = this.shadow.querySelector("header .close"), this.suggestedRepliesEl = this.shadow.querySelector(".suggested-replies"), this.handleCloseClick = () => this.options.onClose(), this.handleSendClick = () => this.send(), this.handleInputKeydown = (r) => {
|
|
283
|
+
if (r.key === "Enter" && !r.shiftKey)
|
|
284
|
+
r.preventDefault(), this.send();
|
|
285
|
+
else if (r.key === "Escape") {
|
|
274
286
|
if (this.emojiPickerOpen) {
|
|
275
|
-
|
|
287
|
+
r.stopPropagation(), this.closeEmojiPicker();
|
|
276
288
|
return;
|
|
277
289
|
}
|
|
278
290
|
this.options.onClose();
|
|
279
291
|
}
|
|
280
|
-
}, this.handleShadowKeydown = (
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
292
|
+
}, this.handleShadowKeydown = (r) => {
|
|
293
|
+
const l = r;
|
|
294
|
+
if (l.key === "Escape") {
|
|
283
295
|
if (this.emojiPickerOpen) {
|
|
284
|
-
|
|
296
|
+
l.preventDefault(), this.closeEmojiPicker();
|
|
285
297
|
return;
|
|
286
298
|
}
|
|
287
299
|
this.options.onClose();
|
|
288
300
|
}
|
|
289
|
-
|
|
301
|
+
l.key === "Tab" && this.trapFocus(l);
|
|
290
302
|
}, this.handleFocusin = () => this.collectFocusable(), this.handleMessagesScroll = () => this.updateScrollBottomState(), this.handleScrollBottomClick = () => {
|
|
291
303
|
this.scrollToBottom(), this.resetScrollUnreadCount();
|
|
292
304
|
}, this.handleEmojiClick = () => {
|
|
293
305
|
this.toggleEmojiPicker();
|
|
294
|
-
}, this.handleDocumentPointerDown = (
|
|
306
|
+
}, this.handleDocumentPointerDown = (r) => {
|
|
295
307
|
if (!this.emojiPickerOpen) return;
|
|
296
|
-
const
|
|
297
|
-
|
|
308
|
+
const l = r.composedPath();
|
|
309
|
+
l.includes(this.emojiPickerEl) || l.includes(this.emojiButton) || this.closeEmojiPicker();
|
|
298
310
|
}, this.closeButton.addEventListener("click", this.handleCloseClick), this.sendButton.addEventListener("click", this.handleSendClick), this.emojiButton.addEventListener("click", this.handleEmojiClick), this.scrollBottomButton.addEventListener("click", this.handleScrollBottomClick), this.input.addEventListener("keydown", this.handleInputKeydown), this.messagesEl.addEventListener("scroll", this.handleMessagesScroll), this.shadow.addEventListener("keydown", this.handleShadowKeydown), this.shadow.addEventListener("focusin", this.handleFocusin), document.addEventListener("pointerdown", this.handleDocumentPointerDown, !0), this.renderEmojiPicker(), this.updateScrollBottomState(), this.collectFocusable();
|
|
299
311
|
}
|
|
312
|
+
get element() {
|
|
313
|
+
return this.host;
|
|
314
|
+
}
|
|
300
315
|
mount() {
|
|
301
316
|
document.body.appendChild(this.host);
|
|
302
317
|
}
|
|
@@ -328,9 +343,9 @@ class Q {
|
|
|
328
343
|
renderWithConversations(e, t) {
|
|
329
344
|
this.messagesEl.innerHTML = "", this.seenIds.clear(), this.renderedMessages.length = 0, this.lastTimelineMessage = null;
|
|
330
345
|
for (const s of e) {
|
|
331
|
-
s.messages.forEach((
|
|
332
|
-
const i = this.createHistoryContainer(s.messages),
|
|
333
|
-
this.messagesEl.appendChild(i), this.messagesEl.appendChild(
|
|
346
|
+
s.messages.forEach((r) => this.seenIds.add(r.id));
|
|
347
|
+
const i = this.createHistoryContainer(s.messages), n = s.messages[s.messages.length - 1].ts, a = this.createSeparatorElement(n, i);
|
|
348
|
+
this.messagesEl.appendChild(i), this.messagesEl.appendChild(a);
|
|
334
349
|
}
|
|
335
350
|
t.forEach((s) => {
|
|
336
351
|
this.seenIds.add(s.id), this.appendTimelineMessage(s);
|
|
@@ -395,17 +410,17 @@ class Q {
|
|
|
395
410
|
}
|
|
396
411
|
createSeparatorElement(e, t) {
|
|
397
412
|
const s = document.createElement("div");
|
|
398
|
-
s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent =
|
|
413
|
+
s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent = te(e);
|
|
399
414
|
const i = () => {
|
|
400
|
-
const
|
|
401
|
-
s.setAttribute("aria-expanded", String(
|
|
415
|
+
const n = t.classList.toggle("expanded");
|
|
416
|
+
s.setAttribute("aria-expanded", String(n)), s.setAttribute(
|
|
402
417
|
"aria-label",
|
|
403
|
-
|
|
418
|
+
n ? "Hide previous conversation" : "Show previous conversation"
|
|
404
419
|
);
|
|
405
420
|
};
|
|
406
|
-
return s.addEventListener("click", i), s.addEventListener("keydown", (
|
|
407
|
-
const
|
|
408
|
-
(
|
|
421
|
+
return s.addEventListener("click", i), s.addEventListener("keydown", (n) => {
|
|
422
|
+
const a = n;
|
|
423
|
+
(a.key === "Enter" || a.key === " ") && (a.preventDefault(), i());
|
|
409
424
|
}), s;
|
|
410
425
|
}
|
|
411
426
|
createHistoryContainer(e) {
|
|
@@ -414,8 +429,8 @@ class Q {
|
|
|
414
429
|
let s = null;
|
|
415
430
|
return e.forEach((i) => {
|
|
416
431
|
this.appendDateSeparatorIfNeeded(s, i, t);
|
|
417
|
-
const { item:
|
|
418
|
-
t.appendChild(
|
|
432
|
+
const { item: n } = this.createMessageElement(i);
|
|
433
|
+
t.appendChild(n), s = i;
|
|
419
434
|
}), t;
|
|
420
435
|
}
|
|
421
436
|
appendTimelineMessage(e) {
|
|
@@ -431,24 +446,24 @@ class Q {
|
|
|
431
446
|
}
|
|
432
447
|
updateTimestampVisibility() {
|
|
433
448
|
for (let e = 0; e < this.renderedMessages.length; e += 1) {
|
|
434
|
-
const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <=
|
|
449
|
+
const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <= ie && s.message.ts >= t.message.ts;
|
|
435
450
|
t.timeEl.toggleAttribute("hidden", i), t.timeEl.textContent = this.formatMessageTimestamp(t.message.ts);
|
|
436
451
|
}
|
|
437
452
|
}
|
|
438
453
|
formatMessageTimestamp(e) {
|
|
439
454
|
const s = Date.now() - e;
|
|
440
|
-
if (s <
|
|
455
|
+
if (s < $) {
|
|
441
456
|
const i = Math.max(1, Math.round(s / 6e4));
|
|
442
457
|
if (i < 60)
|
|
443
458
|
return this.relativeTimeFormat.format(-i, "minute");
|
|
444
|
-
const
|
|
445
|
-
return this.relativeTimeFormat.format(-
|
|
459
|
+
const n = Math.max(1, Math.round(i / 60));
|
|
460
|
+
return this.relativeTimeFormat.format(-n, "hour");
|
|
446
461
|
}
|
|
447
462
|
return this.absoluteTimeFormat.format(new Date(e));
|
|
448
463
|
}
|
|
449
464
|
formatDateSeparator(e) {
|
|
450
465
|
const t = new Date(e), s = this.startOfDay(Date.now()), i = this.startOfDay(e);
|
|
451
|
-
return i === s ? "Today" : i === s -
|
|
466
|
+
return i === s ? "Today" : i === s - $ ? "Yesterday" : this.dateSeparatorFormat.format(t);
|
|
452
467
|
}
|
|
453
468
|
isSameDay(e, t) {
|
|
454
469
|
return this.startOfDay(e) === this.startOfDay(t);
|
|
@@ -458,7 +473,7 @@ class Q {
|
|
|
458
473
|
return new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime();
|
|
459
474
|
}
|
|
460
475
|
isScrolledUp() {
|
|
461
|
-
return this.distanceFromBottom() >
|
|
476
|
+
return this.distanceFromBottom() > oe;
|
|
462
477
|
}
|
|
463
478
|
distanceFromBottom() {
|
|
464
479
|
return this.messagesEl.scrollHeight - this.messagesEl.scrollTop - this.messagesEl.clientHeight;
|
|
@@ -505,7 +520,7 @@ class Q {
|
|
|
505
520
|
this.emojiPickerOpen && (this.emojiPickerOpen = !1, this.emojiPickerEl.style.display = "none", this.emojiButton.setAttribute("aria-expanded", "false"), this.collectFocusable());
|
|
506
521
|
}
|
|
507
522
|
renderEmojiPicker() {
|
|
508
|
-
this.emojiPickerEl.replaceChildren(),
|
|
523
|
+
this.emojiPickerEl.replaceChildren(), ne.forEach((e) => {
|
|
509
524
|
const t = document.createElement("button");
|
|
510
525
|
t.type = "button", t.className = "emoji-option", t.textContent = e, t.setAttribute("aria-label", `Insert ${e}`), t.addEventListener("click", () => {
|
|
511
526
|
this.insertEmojiAtCursor(e), this.closeEmojiPicker();
|
|
@@ -513,11 +528,11 @@ class Q {
|
|
|
513
528
|
});
|
|
514
529
|
}
|
|
515
530
|
insertEmojiAtCursor(e) {
|
|
516
|
-
var
|
|
517
|
-
const t = this.input.value, s = (
|
|
531
|
+
var a, r;
|
|
532
|
+
const t = this.input.value, s = (a = this.input.selectionStart) != null ? a : t.length, i = (r = this.input.selectionEnd) != null ? r : t.length;
|
|
518
533
|
this.input.value = `${t.slice(0, s)}${e}${t.slice(i)}`;
|
|
519
|
-
const
|
|
520
|
-
this.input.setSelectionRange(
|
|
534
|
+
const n = s + e.length;
|
|
535
|
+
this.input.setSelectionRange(n, n), this.input.dispatchEvent(new Event("input", { bubbles: !0 })), this.input.focus();
|
|
521
536
|
}
|
|
522
537
|
collectFocusable() {
|
|
523
538
|
const e = this.shadow.querySelectorAll(
|
|
@@ -533,8 +548,117 @@ class Q {
|
|
|
533
548
|
e.shiftKey && i === t ? (e.preventDefault(), s.focus()) : !e.shiftKey && i === s && (e.preventDefault(), t.focus());
|
|
534
549
|
}
|
|
535
550
|
}
|
|
536
|
-
|
|
537
|
-
|
|
551
|
+
function ae(o) {
|
|
552
|
+
if (!(o instanceof HTMLElement) || o.hasAttribute("disabled") || o.getAttribute("aria-disabled") === "true" || o.hasAttribute("inert"))
|
|
553
|
+
return !1;
|
|
554
|
+
const e = getComputedStyle(o);
|
|
555
|
+
if (e.display === "none" || e.visibility === "hidden" || e.pointerEvents === "none")
|
|
556
|
+
return !1;
|
|
557
|
+
const t = o.tagName;
|
|
558
|
+
if (t === "BUTTON" || t === "SELECT" || t === "TEXTAREA" || t === "A" && o.hasAttribute("href") || t === "INPUT" && o.type !== "hidden" || t === "IFRAME") return !0;
|
|
559
|
+
const s = o.getAttribute("role");
|
|
560
|
+
if (s === "button" || s === "link" || o.getAttribute("contenteditable") === "true") return !0;
|
|
561
|
+
const i = o.getAttribute("tabindex");
|
|
562
|
+
return i !== null && i !== "-1";
|
|
563
|
+
}
|
|
564
|
+
function K(o, e, t) {
|
|
565
|
+
const s = document.elementsFromPoint(o, e);
|
|
566
|
+
for (const i of s) {
|
|
567
|
+
if (t.has(i)) continue;
|
|
568
|
+
let n = !1;
|
|
569
|
+
for (const a of t)
|
|
570
|
+
if (a.contains(i)) {
|
|
571
|
+
n = !0;
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
if (!n && ae(i))
|
|
575
|
+
return !0;
|
|
576
|
+
}
|
|
577
|
+
return !1;
|
|
578
|
+
}
|
|
579
|
+
function N(o, e) {
|
|
580
|
+
const t = [
|
|
581
|
+
[o.x + o.width / 2, o.y + o.height / 2],
|
|
582
|
+
[o.x + o.width / 2, o.y + 4],
|
|
583
|
+
[o.x + o.width / 2, o.y + o.height - 4],
|
|
584
|
+
[o.x + 4, o.y + o.height / 2],
|
|
585
|
+
[o.x + o.width - 4, o.y + o.height / 2]
|
|
586
|
+
];
|
|
587
|
+
for (const [s, i] of t)
|
|
588
|
+
if (K(s, i, e)) return !0;
|
|
589
|
+
return !1;
|
|
590
|
+
}
|
|
591
|
+
function F() {
|
|
592
|
+
var o, e;
|
|
593
|
+
return (e = (o = window.matchMedia) == null ? void 0 : o.call(window, "(pointer: coarse)").matches) != null ? e : !1;
|
|
594
|
+
}
|
|
595
|
+
function le(o) {
|
|
596
|
+
return o === "bottom-right" ? "bottom-left" : "bottom-right";
|
|
597
|
+
}
|
|
598
|
+
class ce {
|
|
599
|
+
constructor(e) {
|
|
600
|
+
this.rafId = 0, this.pendingX = 0, this.pendingY = 0, this.pendingUpdate = !1, this.passthrough = !1, this.cachedRect = null, this.bubble = e.bubble, this.widgetHosts = e.widgetHosts, this.currentPosition = e.position, this.handlePointerMove = (t) => this.onPointerMove(t), this.handlePointerUp = () => this.exitPassthrough(), this.handleScroll = () => this.onLayoutChange(), this.handleResize = () => this.onLayoutChange(), window.addEventListener("scroll", this.handleScroll, { passive: !0 }), window.addEventListener("resize", this.handleResize, { passive: !0 }), F() ? this.scheduleAutoDockCheck() : (document.addEventListener("pointermove", this.handlePointerMove, {
|
|
601
|
+
passive: !0
|
|
602
|
+
}), document.addEventListener("pointerup", this.handlePointerUp, {
|
|
603
|
+
passive: !0
|
|
604
|
+
})), requestAnimationFrame(() => this.onLayoutChange());
|
|
605
|
+
}
|
|
606
|
+
destroy() {
|
|
607
|
+
document.removeEventListener("pointermove", this.handlePointerMove), document.removeEventListener("pointerup", this.handlePointerUp), window.removeEventListener("scroll", this.handleScroll), window.removeEventListener("resize", this.handleResize), this.rafId && cancelAnimationFrame(this.rafId), this.exitPassthrough();
|
|
608
|
+
}
|
|
609
|
+
onPointerMove(e) {
|
|
610
|
+
this.pendingX = e.clientX, this.pendingY = e.clientY, this.pendingUpdate || (this.pendingUpdate = !0, this.rafId = requestAnimationFrame(() => this.tick()));
|
|
611
|
+
}
|
|
612
|
+
tick() {
|
|
613
|
+
this.pendingUpdate = !1;
|
|
614
|
+
const e = this.getBubbleRect(), t = this.pendingX, s = this.pendingY;
|
|
615
|
+
if (!(t >= e.left && t <= e.right && s >= e.top && s <= e.bottom)) {
|
|
616
|
+
this.passthrough && this.exitPassthrough();
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
const n = this.bubble.element, a = n.style.pointerEvents;
|
|
620
|
+
n.style.pointerEvents = "none";
|
|
621
|
+
const r = K(t, s, this.widgetHosts);
|
|
622
|
+
n.style.pointerEvents = a, r && !this.passthrough ? this.enterPassthrough() : !r && this.passthrough && this.exitPassthrough();
|
|
623
|
+
}
|
|
624
|
+
enterPassthrough() {
|
|
625
|
+
this.passthrough = !0, this.bubble.setDimmed(!0), this.bubble.setPassthrough(!0);
|
|
626
|
+
}
|
|
627
|
+
exitPassthrough() {
|
|
628
|
+
this.passthrough && (this.passthrough = !1, this.bubble.setDimmed(!1), this.bubble.setPassthrough(!1));
|
|
629
|
+
}
|
|
630
|
+
scheduleAutoDockCheck() {
|
|
631
|
+
requestAnimationFrame(() => this.autoDockIfNeeded());
|
|
632
|
+
}
|
|
633
|
+
autoDockIfNeeded() {
|
|
634
|
+
this.invalidateRect();
|
|
635
|
+
const e = this.getBubbleRect(), t = this.bubble.element, s = t.style.pointerEvents;
|
|
636
|
+
t.style.pointerEvents = "none";
|
|
637
|
+
const i = N(e, this.widgetHosts);
|
|
638
|
+
if (t.style.pointerEvents = s, !i) return;
|
|
639
|
+
const n = le(this.currentPosition);
|
|
640
|
+
this.currentPosition = n, this.bubble.setPosition(n), this.invalidateRect(), requestAnimationFrame(() => {
|
|
641
|
+
const a = this.getBubbleRect(), r = this.bubble.element, l = r.style.pointerEvents;
|
|
642
|
+
r.style.pointerEvents = "none";
|
|
643
|
+
const p = N(
|
|
644
|
+
a,
|
|
645
|
+
this.widgetHosts
|
|
646
|
+
);
|
|
647
|
+
r.style.pointerEvents = l, p && this.bubble.setDimmed(!0);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
onLayoutChange() {
|
|
651
|
+
this.invalidateRect(), F() && this.autoDockIfNeeded();
|
|
652
|
+
}
|
|
653
|
+
getBubbleRect() {
|
|
654
|
+
return this.cachedRect || (this.cachedRect = this.bubble.element.getBoundingClientRect()), this.cachedRect;
|
|
655
|
+
}
|
|
656
|
+
invalidateRect() {
|
|
657
|
+
this.cachedRect = null;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
const v = 1500, W = 8e3;
|
|
661
|
+
class he {
|
|
538
662
|
constructor(e, t) {
|
|
539
663
|
this.sessionId = null, this.currentKind = null, this.stopped = !1, this.backoff = v, this.connectPromise = null, this.options = e, this.handlers = t;
|
|
540
664
|
}
|
|
@@ -545,8 +669,8 @@ class ee {
|
|
|
545
669
|
const t = {};
|
|
546
670
|
for (const [s, i] of Object.entries(e))
|
|
547
671
|
if (typeof i == "string") {
|
|
548
|
-
const
|
|
549
|
-
|
|
672
|
+
const n = i.trim();
|
|
673
|
+
n && (t[s] = n);
|
|
550
674
|
}
|
|
551
675
|
this.user = t, this.sessionId && this.sendIdentify().catch(
|
|
552
676
|
(s) => this.handlers.onError(s)
|
|
@@ -585,9 +709,9 @@ class ee {
|
|
|
585
709
|
}
|
|
586
710
|
}
|
|
587
711
|
async doConnect() {
|
|
588
|
-
var
|
|
712
|
+
var a, r;
|
|
589
713
|
this.stopped = !1;
|
|
590
|
-
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (
|
|
714
|
+
const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (r = (a = this.sessionId) != null ? a : this.options.sessionId) != null ? r : void 0, s = {
|
|
591
715
|
organisationId: this.options.org,
|
|
592
716
|
sessionId: t,
|
|
593
717
|
userAgent: typeof navigator != "undefined" ? navigator.userAgent : "",
|
|
@@ -604,16 +728,16 @@ class ee {
|
|
|
604
728
|
});
|
|
605
729
|
if (!i.ok)
|
|
606
730
|
throw new Error(`SpilkiWidget: connect failed (${i.status})`);
|
|
607
|
-
const
|
|
608
|
-
return this.sessionId =
|
|
731
|
+
const n = await i.json();
|
|
732
|
+
return this.sessionId = n.sessionId, this.options.sessionId = n.sessionId, this.backoff = v, await this.startTransport(n), n;
|
|
609
733
|
}
|
|
610
734
|
async send(e, t) {
|
|
611
|
-
var
|
|
735
|
+
var a, r, l;
|
|
612
736
|
const s = {
|
|
613
|
-
sessionId: (
|
|
737
|
+
sessionId: (r = (a = this.sessionId) != null ? a : this.options.sessionId) != null ? r : "",
|
|
614
738
|
text: e,
|
|
615
739
|
...t ? { messageId: t } : {},
|
|
616
|
-
...(
|
|
740
|
+
...(l = this.user) != null && l.userId ? { userId: this.user.userId } : {}
|
|
617
741
|
};
|
|
618
742
|
if (!s.sessionId)
|
|
619
743
|
throw new Error("SpilkiWidget: missing session id");
|
|
@@ -621,7 +745,7 @@ class ee {
|
|
|
621
745
|
this.ws.send(JSON.stringify({ type: "message", payload: s }));
|
|
622
746
|
return;
|
|
623
747
|
}
|
|
624
|
-
const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`,
|
|
748
|
+
const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`, n = await fetch(i, {
|
|
625
749
|
method: "POST",
|
|
626
750
|
headers: {
|
|
627
751
|
"Content-Type": "application/json",
|
|
@@ -629,8 +753,8 @@ class ee {
|
|
|
629
753
|
},
|
|
630
754
|
body: JSON.stringify(s)
|
|
631
755
|
});
|
|
632
|
-
if (!
|
|
633
|
-
throw new Error(`SpilkiWidget: send failed (${
|
|
756
|
+
if (!n.ok)
|
|
757
|
+
throw new Error(`SpilkiWidget: send failed (${n.status})`);
|
|
634
758
|
}
|
|
635
759
|
// #1: accept resetBackoff param; #8 #9: clear retryTimer
|
|
636
760
|
stop(e = !0) {
|
|
@@ -660,7 +784,7 @@ class ee {
|
|
|
660
784
|
return;
|
|
661
785
|
}
|
|
662
786
|
this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = v, t();
|
|
663
|
-
}, this.wsOnMessage = (
|
|
787
|
+
}, this.wsOnMessage = (n) => this.handleIncoming(n.data), this.wsOnClose = () => {
|
|
664
788
|
this.stopped || this.retryFallback("ws");
|
|
665
789
|
}, this.wsOnError = () => {
|
|
666
790
|
this.handlers.onError(new Error("SpilkiWidget: websocket error")), i.readyState !== WebSocket.OPEN && s(new Error("WebSocket failed"));
|
|
@@ -680,8 +804,8 @@ class ee {
|
|
|
680
804
|
"X-Authorization": `Bearer ${this.options.accessToken}`
|
|
681
805
|
},
|
|
682
806
|
signal: i.signal
|
|
683
|
-
}).then((
|
|
684
|
-
if (!
|
|
807
|
+
}).then((n) => {
|
|
808
|
+
if (!n.ok || !n.body) {
|
|
685
809
|
s(new Error("SSE failed"));
|
|
686
810
|
return;
|
|
687
811
|
}
|
|
@@ -690,32 +814,32 @@ class ee {
|
|
|
690
814
|
return;
|
|
691
815
|
}
|
|
692
816
|
this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff = v, t();
|
|
693
|
-
const
|
|
694
|
-
let
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
var
|
|
817
|
+
const a = n.body.getReader(), r = new TextDecoder();
|
|
818
|
+
let l = "";
|
|
819
|
+
const p = () => {
|
|
820
|
+
a.read().then(({ done: u, value: h }) => {
|
|
821
|
+
var y;
|
|
698
822
|
if (u || this.stopped) {
|
|
699
823
|
this.stopped || (this.handlers.onError(new Error("SpilkiWidget: SSE stream ended")), this.retryFallback("sse"));
|
|
700
824
|
return;
|
|
701
825
|
}
|
|
702
|
-
|
|
703
|
-
const d =
|
|
826
|
+
l += r.decode(h, { stream: !0 });
|
|
827
|
+
const d = l.split(`
|
|
704
828
|
|
|
705
829
|
`);
|
|
706
|
-
|
|
830
|
+
l = (y = d.pop()) != null ? y : "";
|
|
707
831
|
for (const f of d)
|
|
708
|
-
for (const
|
|
832
|
+
for (const g of f.split(`
|
|
709
833
|
`))
|
|
710
|
-
|
|
711
|
-
|
|
834
|
+
g.startsWith("data:") && this.handleIncoming(g.slice(5).trim());
|
|
835
|
+
p();
|
|
712
836
|
}).catch((u) => {
|
|
713
837
|
i.signal.aborted || (this.handlers.onError(u), this.stopped || this.retryFallback("sse"));
|
|
714
838
|
});
|
|
715
839
|
};
|
|
716
|
-
|
|
717
|
-
}).catch((
|
|
718
|
-
i.signal.aborted || s(
|
|
840
|
+
p();
|
|
841
|
+
}).catch((n) => {
|
|
842
|
+
i.signal.aborted || s(n);
|
|
719
843
|
});
|
|
720
844
|
});
|
|
721
845
|
}
|
|
@@ -732,9 +856,9 @@ class ee {
|
|
|
732
856
|
});
|
|
733
857
|
if (!s.ok) throw new Error(`Poll failed ${s.status}`);
|
|
734
858
|
const i = await s.json();
|
|
735
|
-
|
|
859
|
+
A(i).forEach((n) => this.handlers.onMessage(n)), this.backoff = v;
|
|
736
860
|
} catch (s) {
|
|
737
|
-
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5,
|
|
861
|
+
this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, W);
|
|
738
862
|
} finally {
|
|
739
863
|
this.stopped || (this.pollTimer = window.setTimeout(t, this.backoff));
|
|
740
864
|
}
|
|
@@ -743,7 +867,7 @@ class ee {
|
|
|
743
867
|
}
|
|
744
868
|
// #1: preserve backoff by calling stop(false); #8: check stopped before reconnect
|
|
745
869
|
retryFallback(e) {
|
|
746
|
-
this.stopped || (this.stop(!1), this.backoff = Math.min(this.backoff * 1.5,
|
|
870
|
+
this.stopped || (this.stop(!1), this.backoff = Math.min(this.backoff * 1.5, W), this.retryTimer = window.setTimeout(() => {
|
|
747
871
|
this.stopped || (this.handlers.onError(new Error(`SpilkiWidget: retrying after ${e}`)), this.connect().catch((t) => this.handlers.onError(t)));
|
|
748
872
|
}, this.backoff));
|
|
749
873
|
}
|
|
@@ -763,20 +887,20 @@ class ee {
|
|
|
763
887
|
dispatchIncoming(e) {
|
|
764
888
|
var t;
|
|
765
889
|
if ("type" in e) {
|
|
766
|
-
e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing" ? this.handlers.onTyping(!!((t = e.payload) != null && t.active)) : e.type === "AGENT_EVENT" &&
|
|
890
|
+
e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing" ? this.handlers.onTyping(!!((t = e.payload) != null && t.active)) : e.type === "AGENT_EVENT" && ue(e.payload) && this.handlers.onAgentEvent(e.payload);
|
|
767
891
|
return;
|
|
768
892
|
}
|
|
769
893
|
this.handlers.onMessage(e);
|
|
770
894
|
}
|
|
771
895
|
}
|
|
772
|
-
const
|
|
773
|
-
function
|
|
774
|
-
if (typeof
|
|
775
|
-
const e =
|
|
776
|
-
return
|
|
896
|
+
const de = /* @__PURE__ */ new Set(["TYPING", "THINKING", "SEARCHING", "EXECUTING_TOOL"]);
|
|
897
|
+
function ue(o) {
|
|
898
|
+
if (typeof o != "object" || o === null) return !1;
|
|
899
|
+
const e = o;
|
|
900
|
+
return de.has(e.eventType);
|
|
777
901
|
}
|
|
778
|
-
const
|
|
779
|
-
class
|
|
902
|
+
const H = 30 * 60 * 1e3, pe = 3e4, O = 30;
|
|
903
|
+
class ge {
|
|
780
904
|
constructor(e, t) {
|
|
781
905
|
this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.activityTimer = null, this.state = {
|
|
782
906
|
isOpen: !1,
|
|
@@ -805,7 +929,7 @@ class re {
|
|
|
805
929
|
handleAgentEvent(e) {
|
|
806
930
|
this.activityTimer && (clearTimeout(this.activityTimer), this.activityTimer = null), this.activityTimer = setTimeout(() => {
|
|
807
931
|
this.state.agentActivity = null, this.activityTimer = null, this.emit();
|
|
808
|
-
},
|
|
932
|
+
}, pe), this.state.agentActivity !== e && (this.state.agentActivity = e, this.emit());
|
|
809
933
|
}
|
|
810
934
|
clearAgentActivity() {
|
|
811
935
|
this.resetAgentActivity() && this.emit();
|
|
@@ -819,15 +943,15 @@ class re {
|
|
|
819
943
|
addMessage(e) {
|
|
820
944
|
var s, i;
|
|
821
945
|
const t = {
|
|
822
|
-
id: (s = e.id) != null ? s :
|
|
946
|
+
id: (s = e.id) != null ? s : X("msg"),
|
|
823
947
|
ts: (i = e.ts) != null ? i : Date.now(),
|
|
824
948
|
author: e.author,
|
|
825
949
|
text: e.text
|
|
826
950
|
};
|
|
827
|
-
return this.state.messages.some((
|
|
951
|
+
return this.state.messages.some((n) => n.id === t.id) ? null : (this.state.messages = A([...this.state.messages, t], O), this.resetAgentActivity(), this.persistMessages(), this.touchActivity(), this.emit(), t);
|
|
828
952
|
}
|
|
829
953
|
setMessages(e) {
|
|
830
|
-
this.state.messages =
|
|
954
|
+
this.state.messages = A(e, O), this.persistMessages(), this.emit();
|
|
831
955
|
}
|
|
832
956
|
clearMessages() {
|
|
833
957
|
this.state.messages = [], this.persistMessages(), this.emit();
|
|
@@ -919,7 +1043,7 @@ class re {
|
|
|
919
1043
|
}
|
|
920
1044
|
isSessionExpired() {
|
|
921
1045
|
const e = this.lastActivityTs;
|
|
922
|
-
return e === 0 ? !1 : Date.now() - e >=
|
|
1046
|
+
return e === 0 ? !1 : Date.now() - e >= H;
|
|
923
1047
|
}
|
|
924
1048
|
getConversationGroups() {
|
|
925
1049
|
const e = this.state.messages;
|
|
@@ -927,7 +1051,7 @@ class re {
|
|
|
927
1051
|
const t = [];
|
|
928
1052
|
let s = { startTs: e[0].ts, messages: [e[0]] };
|
|
929
1053
|
for (let i = 1; i < e.length; i++)
|
|
930
|
-
e[i].ts - e[i - 1].ts >=
|
|
1054
|
+
e[i].ts - e[i - 1].ts >= H ? (t.push(s), s = { startTs: e[i].ts, messages: [e[i]] }) : s.messages.push(e[i]);
|
|
931
1055
|
return t.push(s), t;
|
|
932
1056
|
}
|
|
933
1057
|
emit() {
|
|
@@ -947,14 +1071,14 @@ class re {
|
|
|
947
1071
|
const e = localStorage.getItem(this.historyKey);
|
|
948
1072
|
if (!e) return [];
|
|
949
1073
|
const t = JSON.parse(e);
|
|
950
|
-
return Array.isArray(t) ?
|
|
1074
|
+
return Array.isArray(t) ? A(t, O) : [];
|
|
951
1075
|
} catch (e) {
|
|
952
1076
|
return console.error("SpilkiWidget: unable to load messages", e), [];
|
|
953
1077
|
}
|
|
954
1078
|
}
|
|
955
1079
|
}
|
|
956
|
-
function
|
|
957
|
-
const e =
|
|
1080
|
+
function me(o) {
|
|
1081
|
+
const e = o.replace(/-/g, "+").replace(/_/g, "/"), t = e.padEnd(e.length + (4 - e.length % 4) % 4, "=");
|
|
958
1082
|
if (typeof atob == "function")
|
|
959
1083
|
return decodeURIComponent(
|
|
960
1084
|
Array.prototype.map.call(atob(t), (i) => `%${`00${i.charCodeAt(0).toString(16)}`.slice(-2)}`).join("")
|
|
@@ -964,24 +1088,24 @@ function oe(r) {
|
|
|
964
1088
|
return s.from(t, "base64").toString("utf8");
|
|
965
1089
|
throw new Error("SpilkiWidget: no base64 decoder available");
|
|
966
1090
|
}
|
|
967
|
-
function
|
|
968
|
-
if (!
|
|
969
|
-
const e =
|
|
1091
|
+
function fe(o) {
|
|
1092
|
+
if (!o) return null;
|
|
1093
|
+
const e = o.split(".");
|
|
970
1094
|
if (e.length < 2) return null;
|
|
971
1095
|
try {
|
|
972
|
-
const t =
|
|
1096
|
+
const t = me(e[1]);
|
|
973
1097
|
return JSON.parse(t);
|
|
974
1098
|
} catch (t) {
|
|
975
1099
|
return console.error("SpilkiWidget: unable to parse JWT", t), null;
|
|
976
1100
|
}
|
|
977
1101
|
}
|
|
978
|
-
function
|
|
979
|
-
const e =
|
|
1102
|
+
function be(o) {
|
|
1103
|
+
const e = fe(o);
|
|
980
1104
|
if (!(e != null && e.exp) || typeof e.exp != "number") return !0;
|
|
981
1105
|
const t = Math.floor(Date.now() / 1e3);
|
|
982
1106
|
return e.exp < t + 60;
|
|
983
1107
|
}
|
|
984
|
-
const
|
|
1108
|
+
const ke = {
|
|
985
1109
|
onOpen() {
|
|
986
1110
|
},
|
|
987
1111
|
onClose() {
|
|
@@ -993,8 +1117,8 @@ const le = {
|
|
|
993
1117
|
onTransportChange() {
|
|
994
1118
|
}
|
|
995
1119
|
};
|
|
996
|
-
async function
|
|
997
|
-
const s = `${
|
|
1120
|
+
async function ye(o, e, t) {
|
|
1121
|
+
const s = `${o.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
|
|
998
1122
|
method: "POST",
|
|
999
1123
|
headers: { "Content-Type": "application/json", Origin: window.location.origin },
|
|
1000
1124
|
body: JSON.stringify({ token: e, organisationId: t })
|
|
@@ -1002,127 +1126,127 @@ async function ce(r, e, t) {
|
|
|
1002
1126
|
if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
|
|
1003
1127
|
return (await i.json()).accessToken;
|
|
1004
1128
|
}
|
|
1005
|
-
async function
|
|
1006
|
-
const t = `${
|
|
1129
|
+
async function we(o, e) {
|
|
1130
|
+
const t = `${o.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
|
|
1007
1131
|
method: "POST",
|
|
1008
1132
|
headers: { "X-Authorization": `Bearer ${e}`, Origin: window.location.origin }
|
|
1009
1133
|
});
|
|
1010
1134
|
if (!s.ok) throw new Error(`SpilkiWidget: refresh failed (${s.status})`);
|
|
1011
1135
|
return (await s.json()).accessToken;
|
|
1012
1136
|
}
|
|
1013
|
-
function
|
|
1137
|
+
function ve(o) {
|
|
1014
1138
|
let e = !1, t = null;
|
|
1015
1139
|
const s = [], i = () => {
|
|
1016
|
-
var
|
|
1017
|
-
if (!
|
|
1140
|
+
var r;
|
|
1141
|
+
if (!o) return null;
|
|
1018
1142
|
if (t) return t;
|
|
1019
1143
|
try {
|
|
1020
|
-
const
|
|
1021
|
-
if (!
|
|
1022
|
-
t = new
|
|
1144
|
+
const l = (r = window.AudioContext) != null ? r : window.webkitAudioContext;
|
|
1145
|
+
if (!l) return null;
|
|
1146
|
+
t = new l();
|
|
1023
1147
|
} catch {
|
|
1024
1148
|
return null;
|
|
1025
1149
|
}
|
|
1026
1150
|
return t;
|
|
1027
|
-
},
|
|
1151
|
+
}, n = () => {
|
|
1028
1152
|
e = !0;
|
|
1029
1153
|
try {
|
|
1030
|
-
const
|
|
1031
|
-
(
|
|
1154
|
+
const r = i();
|
|
1155
|
+
(r == null ? void 0 : r.state) === "suspended" && r.resume().catch(() => {
|
|
1032
1156
|
});
|
|
1033
1157
|
} catch {
|
|
1034
1158
|
}
|
|
1035
|
-
},
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1159
|
+
}, a = (r) => {
|
|
1160
|
+
const l = () => {
|
|
1161
|
+
n(), window.removeEventListener(r, l, !0);
|
|
1038
1162
|
};
|
|
1039
|
-
s.push({ type:
|
|
1163
|
+
s.push({ type: r, listener: l }), window.addEventListener(r, l, { capture: !0, passive: !0 });
|
|
1040
1164
|
};
|
|
1041
|
-
return
|
|
1042
|
-
markUserInteraction:
|
|
1165
|
+
return a("pointerdown"), a("keydown"), {
|
|
1166
|
+
markUserInteraction: n,
|
|
1043
1167
|
play() {
|
|
1044
|
-
if (!
|
|
1045
|
-
const
|
|
1046
|
-
if (!
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1049
|
-
const
|
|
1050
|
-
const f =
|
|
1051
|
-
f.type = "sine", f.frequency.setValueAtTime(h, d),
|
|
1052
|
-
}, u =
|
|
1053
|
-
|
|
1168
|
+
if (!o || !e) return;
|
|
1169
|
+
const r = i();
|
|
1170
|
+
if (!r || r.state !== "running") return;
|
|
1171
|
+
const l = r.createGain();
|
|
1172
|
+
l.gain.value = 0.15, l.connect(r.destination);
|
|
1173
|
+
const p = (h, d, y) => {
|
|
1174
|
+
const f = r.createOscillator(), g = r.createGain();
|
|
1175
|
+
f.type = "sine", f.frequency.setValueAtTime(h, d), g.gain.setValueAtTime(1e-4, d), g.gain.exponentialRampToValueAtTime(1, d + 0.012), g.gain.exponentialRampToValueAtTime(1e-4, d + y), f.connect(g), g.connect(l), f.start(d), f.stop(d + y + 0.02);
|
|
1176
|
+
}, u = r.currentTime;
|
|
1177
|
+
p(880, u, 0.08), p(1175, u + 0.09, 0.08);
|
|
1054
1178
|
},
|
|
1055
1179
|
destroy() {
|
|
1056
|
-
s.forEach(({ type:
|
|
1057
|
-
window.removeEventListener(
|
|
1180
|
+
s.forEach(({ type: r, listener: l }) => {
|
|
1181
|
+
window.removeEventListener(r, l, !0);
|
|
1058
1182
|
}), s.length = 0, t && t.close().catch(() => {
|
|
1059
1183
|
}), t = null;
|
|
1060
1184
|
}
|
|
1061
1185
|
};
|
|
1062
1186
|
}
|
|
1063
|
-
function
|
|
1064
|
-
var
|
|
1065
|
-
if (!
|
|
1187
|
+
function z(o) {
|
|
1188
|
+
var B, L, D, j, U;
|
|
1189
|
+
if (!o.org)
|
|
1066
1190
|
throw new Error("SpilkiWidget: org is required");
|
|
1067
|
-
const e =
|
|
1068
|
-
|
|
1069
|
-
const t = { ...
|
|
1070
|
-
let
|
|
1071
|
-
const
|
|
1191
|
+
const e = J(o);
|
|
1192
|
+
Q(e.allowedOriginsHint);
|
|
1193
|
+
const t = { ...ke, ...(B = e.hooks) != null ? B : {} }, s = new ge(e.org, { persist: e.persist }), i = ve(e.sound);
|
|
1194
|
+
let n = (L = s.accessToken) != null ? L : void 0, a = null;
|
|
1195
|
+
const r = () => {
|
|
1072
1196
|
u.setBadge(s.countUnread());
|
|
1073
|
-
},
|
|
1197
|
+
}, l = () => {
|
|
1074
1198
|
s.markRead(), u.setBadge(0);
|
|
1075
|
-
},
|
|
1199
|
+
}, p = async () => a || (a = (async () => {
|
|
1076
1200
|
try {
|
|
1077
|
-
if (
|
|
1201
|
+
if (n && be(n))
|
|
1078
1202
|
try {
|
|
1079
|
-
|
|
1203
|
+
n = await we(e.apiBase, n), s.persistAccessToken(n), d.setAccessToken(n);
|
|
1080
1204
|
return;
|
|
1081
1205
|
} catch {
|
|
1082
|
-
|
|
1206
|
+
n = void 0, s.clearAccessToken();
|
|
1083
1207
|
}
|
|
1084
|
-
if (!
|
|
1085
|
-
if (!
|
|
1086
|
-
if (!
|
|
1087
|
-
|
|
1208
|
+
if (!n) {
|
|
1209
|
+
if (!o.installationToken) throw new Error("SpilkiWidget: missing installationToken");
|
|
1210
|
+
if (!o.org) throw new Error("SpilkiWidget: missing org");
|
|
1211
|
+
n = await ye(e.apiBase, o.installationToken, o.org), s.persistAccessToken(n), d.setAccessToken(n);
|
|
1088
1212
|
}
|
|
1089
1213
|
} finally {
|
|
1090
|
-
|
|
1214
|
+
a = null;
|
|
1091
1215
|
}
|
|
1092
|
-
})(),
|
|
1216
|
+
})(), a), u = G({
|
|
1093
1217
|
color: e.color,
|
|
1094
|
-
position: (
|
|
1218
|
+
position: (D = e.position) != null ? D : "bottom-right",
|
|
1095
1219
|
onClick: () => {
|
|
1096
|
-
s.snapshot.isOpen ? (s.close(), t.onClose()) : (i.markUserInteraction(), s.open(),
|
|
1220
|
+
s.snapshot.isOpen ? (s.close(), t.onClose()) : (i.markUserInteraction(), s.open(), l(), t.onOpen());
|
|
1097
1221
|
}
|
|
1098
|
-
}), h = new
|
|
1222
|
+
}), h = new re({
|
|
1099
1223
|
color: e.color,
|
|
1100
|
-
theme:
|
|
1224
|
+
theme: R(e.theme),
|
|
1101
1225
|
position: (j = e.position) != null ? j : "bottom-right",
|
|
1102
1226
|
i18n: e.i18n,
|
|
1103
1227
|
onClose: () => {
|
|
1104
1228
|
s.close(), t.onClose();
|
|
1105
1229
|
},
|
|
1106
1230
|
onSend: (c) => {
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1109
|
-
t.onError(
|
|
1231
|
+
const b = s.addMessage({ author: "user", text: c });
|
|
1232
|
+
b && (h.appendMessage(b), p().then(() => d.send(c, b.id)).catch((m) => {
|
|
1233
|
+
t.onError(m), s.setConnected(!1), h.setOffline(!0);
|
|
1110
1234
|
}));
|
|
1111
1235
|
}
|
|
1112
|
-
}), d = new
|
|
1236
|
+
}), d = new he(
|
|
1113
1237
|
{
|
|
1114
1238
|
apiBase: e.apiBase,
|
|
1115
|
-
accessToken:
|
|
1239
|
+
accessToken: n,
|
|
1116
1240
|
org: e.org,
|
|
1117
1241
|
sessionId: s.sessionId
|
|
1118
1242
|
},
|
|
1119
1243
|
{
|
|
1120
1244
|
onOpen(c) {
|
|
1121
|
-
|
|
1245
|
+
I.transport = c, t.onTransportChange(c), s.setConnected(!0), h.setOffline(!1);
|
|
1122
1246
|
},
|
|
1123
1247
|
onMessage(c) {
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1248
|
+
const m = c.suggestedReplies, k = s.addMessage(c);
|
|
1249
|
+
k && (h.appendMessage(k), k.author === "bot" && m && m.length > 0 && h.setSuggestedReplies(m), !s.snapshot.isOpen && k.author === "bot" && (r(), i.play()), t.onMessage(k));
|
|
1126
1250
|
},
|
|
1127
1251
|
onTyping() {
|
|
1128
1252
|
s.handleAgentEvent("TYPING");
|
|
@@ -1136,8 +1260,12 @@ function $(r) {
|
|
|
1136
1260
|
}
|
|
1137
1261
|
);
|
|
1138
1262
|
u.mount(), h.mount();
|
|
1139
|
-
const
|
|
1140
|
-
|
|
1263
|
+
const y = (U = e.position) != null ? U : "bottom-right", f = /* @__PURE__ */ new Set([u.element, h.element]), g = new ce({
|
|
1264
|
+
bubble: u,
|
|
1265
|
+
widgetHosts: f,
|
|
1266
|
+
position: y
|
|
1267
|
+
}), T = s.snapshot.messages, P = s.isSessionExpired(), x = s.getConversationGroups();
|
|
1268
|
+
if (T.length === 0 && e.welcome) {
|
|
1141
1269
|
const c = {
|
|
1142
1270
|
id: "welcome",
|
|
1143
1271
|
author: "bot",
|
|
@@ -1145,33 +1273,33 @@ function $(r) {
|
|
|
1145
1273
|
ts: Date.now()
|
|
1146
1274
|
};
|
|
1147
1275
|
s.addMessage(c), h.appendMessage(c);
|
|
1148
|
-
} else
|
|
1149
|
-
let
|
|
1150
|
-
const
|
|
1276
|
+
} else P && T.length > 0 ? h.renderWithConversations(x, []) : x.length > 1 ? h.renderWithConversations(x.slice(0, -1), x[x.length - 1].messages) : h.updateMessages(T);
|
|
1277
|
+
let C = !1;
|
|
1278
|
+
const _ = s.subscribe(() => {
|
|
1151
1279
|
const c = s.snapshot;
|
|
1152
|
-
if (u.setOpen(c.isOpen), h.setAgentActivity(c.agentActivity, e.i18n), h.setOffline(!c.isConnected), h.updateTheme(
|
|
1153
|
-
if (!
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1280
|
+
if (u.setOpen(c.isOpen), h.setAgentActivity(c.agentActivity, e.i18n), h.setOffline(!c.isConnected), h.updateTheme(R(e.theme)), c.isOpen) {
|
|
1281
|
+
if (!C) {
|
|
1282
|
+
const b = s.countUnread() > 0, m = s.lastReadTs;
|
|
1283
|
+
l(), b && h.scrollToFirstUnread(m);
|
|
1156
1284
|
}
|
|
1157
|
-
|
|
1285
|
+
C = !0, h.show();
|
|
1158
1286
|
} else
|
|
1159
|
-
|
|
1160
|
-
}),
|
|
1161
|
-
|
|
1287
|
+
C = !1, h.hide();
|
|
1288
|
+
}), q = T.length === 0 || P;
|
|
1289
|
+
r(), p().then(
|
|
1162
1290
|
() => d.connect().then((c) => {
|
|
1163
|
-
var
|
|
1164
|
-
e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1291
|
+
var m, k;
|
|
1292
|
+
e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((m = d.kind) != null ? m : "ws");
|
|
1293
|
+
const b = (k = c.suggestedReplies) != null ? k : [];
|
|
1294
|
+
b.length > 0 && q && h.setSuggestedReplies(b);
|
|
1167
1295
|
})
|
|
1168
1296
|
).catch((c) => {
|
|
1169
1297
|
t.onError(c), s.setConnected(!1), h.setOffline(!0);
|
|
1170
1298
|
});
|
|
1171
|
-
const
|
|
1299
|
+
const I = {
|
|
1172
1300
|
transport: null,
|
|
1173
1301
|
open() {
|
|
1174
|
-
i.markUserInteraction(), s.open(),
|
|
1302
|
+
i.markUserInteraction(), s.open(), l(), t.onOpen();
|
|
1175
1303
|
},
|
|
1176
1304
|
close() {
|
|
1177
1305
|
s.close(), t.onClose();
|
|
@@ -1180,24 +1308,24 @@ function $(r) {
|
|
|
1180
1308
|
d.setUser(c);
|
|
1181
1309
|
},
|
|
1182
1310
|
destroy() {
|
|
1183
|
-
|
|
1311
|
+
_(), g.destroy(), d.stop(), i.destroy(), u.destroy(), h.destroy(), E === I && (E = null);
|
|
1184
1312
|
}
|
|
1185
1313
|
};
|
|
1186
|
-
return
|
|
1314
|
+
return I;
|
|
1187
1315
|
}
|
|
1188
|
-
function
|
|
1316
|
+
function Ee() {
|
|
1189
1317
|
var s, i;
|
|
1190
1318
|
if (typeof document == "undefined") return;
|
|
1191
|
-
const
|
|
1192
|
-
if (!
|
|
1193
|
-
const e =
|
|
1319
|
+
const o = document.currentScript;
|
|
1320
|
+
if (!o) return;
|
|
1321
|
+
const e = o.dataset;
|
|
1194
1322
|
if (e.autoinit === "false") return;
|
|
1195
1323
|
const t = e.org;
|
|
1196
1324
|
if (!t) {
|
|
1197
1325
|
console.error("SpilkiWidget: data-org and is required for auto init");
|
|
1198
1326
|
return;
|
|
1199
1327
|
}
|
|
1200
|
-
|
|
1328
|
+
E = z({
|
|
1201
1329
|
org: t,
|
|
1202
1330
|
installationToken: e.installationToken,
|
|
1203
1331
|
apiBase: e.apiBase,
|
|
@@ -1205,13 +1333,13 @@ function pe() {
|
|
|
1205
1333
|
theme: (i = e.theme) != null ? i : void 0
|
|
1206
1334
|
});
|
|
1207
1335
|
}
|
|
1208
|
-
let
|
|
1209
|
-
typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (
|
|
1210
|
-
|
|
1336
|
+
let E = null;
|
|
1337
|
+
typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (o) => (E = z(o), E), window.SpilkiWidget.identify = (o) => {
|
|
1338
|
+
E ? E.identify(o) : console.warn("SpilkiWidget: call init() before identify()");
|
|
1211
1339
|
});
|
|
1212
|
-
|
|
1340
|
+
Ee();
|
|
1213
1341
|
export {
|
|
1214
|
-
|
|
1215
|
-
|
|
1342
|
+
Ee as autoInit,
|
|
1343
|
+
z as initSpilkiWidget
|
|
1216
1344
|
};
|
|
1217
1345
|
//# sourceMappingURL=widget.es.js.map
|