@mrrocket/sdk 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/api-client.d.ts +8 -0
- package/dist/api-client.js +13 -1
- package/dist/api-client.js.map +1 -1
- package/dist/browser/mrrocket-messenger.js +85 -50
- package/dist/browser/mrrocket.js +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/feedback.js +127 -22
- package/dist/feedback.js.map +1 -1
- package/dist/messenger-ui.d.ts +2 -0
- package/dist/messenger-ui.js +54 -18
- package/dist/messenger-ui.js.map +1 -1
- package/dist/react-native/index.d.cts +12 -2
- package/dist/react-native/index.d.ts +12 -2
- package/dist/react-native/index.js +201 -47
- package/dist/react-native/index.js.map +1 -1
- package/dist/styles-css.d.ts +1 -1
- package/dist/styles-css.js +83 -48
- package/dist/styles-css.js.map +1 -1
- package/package.json +5 -1
package/dist/messenger-ui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/messenger-ui.ts
|
|
2
|
-
import { createApi } from "./api-client.js";
|
|
2
|
+
import { createApi, inkOn, replyLine } from "./api-client.js";
|
|
3
3
|
import { injectStyles } from "./styles-css.js";
|
|
4
4
|
var POLL_OPEN_MS = 4e3;
|
|
5
5
|
var POLL_WAITING_MS = 8e3;
|
|
@@ -51,6 +51,7 @@ var I = {
|
|
|
51
51
|
cross: "m4 4 8 8M12 4l-8 8",
|
|
52
52
|
chat: "M2.5 4.5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v4.5a2 2 0 0 1-2 2H7l-3 2.5V11a2 2 0 0 1-1.5-2z",
|
|
53
53
|
send: "M2.5 8h10M8.5 3.5 13 8l-4.5 4.5",
|
|
54
|
+
up: "M8 13V3M3.5 7.5 8 3l4.5 4.5",
|
|
54
55
|
home: "M2.5 7 8 2.5 13.5 7v6a1 1 0 0 1-1 1h-3v-4h-3v4h-3a1 1 0 0 1-1-1z",
|
|
55
56
|
help: "M8 14.5A6.5 6.5 0 1 0 8 1.5a6.5 6.5 0 0 0 0 13zM6.2 6.2a1.9 1.9 0 1 1 2.6 1.8c-.5.2-.8.6-.8 1.1v.4M8 11.6v.1",
|
|
56
57
|
back: "M10 3.5 5.5 8l4.5 4.5",
|
|
@@ -158,13 +159,18 @@ var build = (o) => {
|
|
|
158
159
|
const greeting = o.greeting || "Hi! How can we help?";
|
|
159
160
|
const askEmail = o.askEmail ?? true;
|
|
160
161
|
const label = o.label ?? "";
|
|
162
|
+
const reply = replyLine(o.replyTime);
|
|
163
|
+
const initial = (title.trim()[0] ?? "?").toUpperCase();
|
|
161
164
|
const launcherOn = o.launcher ?? true;
|
|
162
165
|
const helpOn = o.help ?? true;
|
|
163
166
|
const soundOn = o.sound ?? true;
|
|
164
167
|
const previewOn = o.preview ?? true;
|
|
165
168
|
const api = () => createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user() });
|
|
166
169
|
const root = el("div", { class: "ckw-root", "data-theme": o.theme ?? "auto" });
|
|
167
|
-
if (o.accent)
|
|
170
|
+
if (o.accent) {
|
|
171
|
+
root.style.setProperty("--ckw-accent", o.accent);
|
|
172
|
+
root.style.setProperty("--ckw-accent-ink", inkOn(o.accent));
|
|
173
|
+
}
|
|
168
174
|
document.body.appendChild(root);
|
|
169
175
|
let open = false;
|
|
170
176
|
let view = "home";
|
|
@@ -210,10 +216,15 @@ var build = (o) => {
|
|
|
210
216
|
const id = lastTeamId(thread);
|
|
211
217
|
if (id) writeSeen(id);
|
|
212
218
|
};
|
|
219
|
+
const avatar = (size) => el("span", { class: `ckw-msgr-av${size ? " ckw-msgr-av-sm" : ""}`, "aria-hidden": "true" }, initial);
|
|
213
220
|
const fab = el("button", { type: "button", class: `ckw-fab ckw-msgr-fab${label ? "" : " ckw-msgr-round"}`, "data-pos": position, "aria-haspopup": "dialog" });
|
|
214
221
|
const prev = el("div", { class: "ckw-msgr-preview", "data-pos": position, role: "status" });
|
|
222
|
+
let fabShows = null;
|
|
215
223
|
const drawFab = () => {
|
|
216
|
-
|
|
224
|
+
const glyph = icon(open ? I.cross : I.chat, label ? 18 : 24);
|
|
225
|
+
if (fabShows !== null && fabShows !== open) glyph.classList.add("ckw-turn");
|
|
226
|
+
fabShows = open;
|
|
227
|
+
fab.replaceChildren(glyph);
|
|
217
228
|
if (label) fab.append(el("span", {}, label));
|
|
218
229
|
if (unseen.length && !open) fab.append(el("span", { class: "ckw-msgr-count", "aria-hidden": "true" }, String(Math.min(unseen.length, 9))));
|
|
219
230
|
fab.setAttribute("aria-expanded", String(open));
|
|
@@ -232,8 +243,13 @@ var build = (o) => {
|
|
|
232
243
|
const card = el(
|
|
233
244
|
"button",
|
|
234
245
|
{ type: "button", class: "ckw-msgr-preview-card" },
|
|
235
|
-
|
|
236
|
-
el(
|
|
246
|
+
avatar(),
|
|
247
|
+
el(
|
|
248
|
+
"span",
|
|
249
|
+
{ class: "ckw-msgr-preview-main" },
|
|
250
|
+
el("span", { class: "ckw-msgr-preview-who" }, `${whoLabel[m.from]}${unseen.length > 1 ? ` \xB7 ${unseen.length} new` : ""}`),
|
|
251
|
+
el("span", { class: "ckw-msgr-preview-text" }, m.body)
|
|
252
|
+
)
|
|
237
253
|
);
|
|
238
254
|
card.addEventListener("click", () => show("messages"));
|
|
239
255
|
prev.replaceChildren(card, x);
|
|
@@ -255,7 +271,7 @@ var build = (o) => {
|
|
|
255
271
|
const email = el("input", { class: "ckw-input", type: "email", inputmode: "email", autocomplete: "email", placeholder: "Your email (optional), so we can follow up", "aria-label": "Your email (optional)", maxlength: "200" });
|
|
256
272
|
const row = el("div", { class: "ckw-msgr-row" });
|
|
257
273
|
const text = el("textarea", { class: "ckw-textarea ckw-msgr-input", rows: "1", placeholder: "Write a message\u2026", "aria-label": "Message", maxlength: "4000" });
|
|
258
|
-
const send = el("button", { type: "submit", class: "ckw-
|
|
274
|
+
const send = el("button", { type: "submit", class: "ckw-msgr-send", "aria-label": "Send" }, icon(I.up));
|
|
259
275
|
row.append(text, send);
|
|
260
276
|
form.append(row);
|
|
261
277
|
const list = el("ol", { class: "ckw-msgs", "aria-live": "polite", "aria-label": "Messages" });
|
|
@@ -295,7 +311,7 @@ var build = (o) => {
|
|
|
295
311
|
return b;
|
|
296
312
|
};
|
|
297
313
|
const searchBox = () => {
|
|
298
|
-
const wrap = el("label", { class: "ckw-msgr-search" }
|
|
314
|
+
const wrap = el("label", { class: "ckw-msgr-search" });
|
|
299
315
|
const input = el("input", { class: "ckw-msgr-search-in", type: "search", placeholder: "Search for help", "aria-label": "Search for help", maxlength: "200" });
|
|
300
316
|
input.value = query;
|
|
301
317
|
let t;
|
|
@@ -313,7 +329,7 @@ var build = (o) => {
|
|
|
313
329
|
if (view !== "help") go("help");
|
|
314
330
|
}
|
|
315
331
|
});
|
|
316
|
-
wrap.append(input);
|
|
332
|
+
wrap.append(input, icon(I.search, 16));
|
|
317
333
|
return wrap;
|
|
318
334
|
};
|
|
319
335
|
const helpSearch = searchBox();
|
|
@@ -336,22 +352,39 @@ var build = (o) => {
|
|
|
336
352
|
draw();
|
|
337
353
|
};
|
|
338
354
|
const drawHome = () => {
|
|
339
|
-
head.replaceChildren(el("span", { class: "ckw-msgr-brand" }, title), closeBtn());
|
|
355
|
+
head.replaceChildren(el("span", { class: "ckw-msgr-brand" }, avatar("sm"), el("span", {}, title)), closeBtn());
|
|
340
356
|
const hero = el("div", { class: "ckw-msgr-hero" }, el("p", { class: "ckw-msgr-hello" }, greeting));
|
|
341
357
|
const last = (thread?.messages ?? []).at(-1);
|
|
358
|
+
const parts = [hero];
|
|
359
|
+
if (last) {
|
|
360
|
+
const recent = el(
|
|
361
|
+
"button",
|
|
362
|
+
{ type: "button", class: "ckw-msgr-card ckw-msgr-recent" },
|
|
363
|
+
el("span", { class: "ckw-msgr-card-label" }, "Recent message"),
|
|
364
|
+
el(
|
|
365
|
+
"span",
|
|
366
|
+
{ class: "ckw-msgr-recent-row" },
|
|
367
|
+
avatar(),
|
|
368
|
+
el(
|
|
369
|
+
"span",
|
|
370
|
+
{ class: "ckw-msgr-card-main" },
|
|
371
|
+
el("span", { class: "ckw-msgr-card-sub ckw-msgr-recent-text" }, last.body),
|
|
372
|
+
el("span", { class: "ckw-msgr-card-meta" }, `${last.from === "visitor" ? "You" : whoLabel[last.from]} \xB7 ${timeAgo(last.at)}`)
|
|
373
|
+
),
|
|
374
|
+
unseen.length ? el("span", { class: "ckw-msgr-badge" }, String(unseen.length)) : icon(I.next, 14)
|
|
375
|
+
)
|
|
376
|
+
);
|
|
377
|
+
recent.addEventListener("click", () => go("messages"));
|
|
378
|
+
parts.push(recent);
|
|
379
|
+
}
|
|
342
380
|
const msgCard = el(
|
|
343
381
|
"button",
|
|
344
382
|
{ type: "button", class: "ckw-msgr-card" },
|
|
345
|
-
el(
|
|
346
|
-
|
|
347
|
-
{ class: "ckw-msgr-card-main" },
|
|
348
|
-
el("b", {}, last ? "Recent message" : "Send us a message"),
|
|
349
|
-
el("span", { class: "ckw-msgr-card-sub" }, last ? `${last.from === "visitor" ? "You" : whoLabel[last.from]}: ${last.body}` : "We usually answer within a few hours")
|
|
350
|
-
),
|
|
351
|
-
unseen.length ? el("span", { class: "ckw-msgr-badge" }, String(unseen.length)) : icon(I.send)
|
|
383
|
+
el("span", { class: "ckw-msgr-card-main" }, el("b", {}, "Send us a message"), el("span", { class: "ckw-msgr-card-sub" }, reply)),
|
|
384
|
+
el("span", { class: "ckw-msgr-go" }, icon(I.send))
|
|
352
385
|
);
|
|
353
386
|
msgCard.addEventListener("click", () => go("messages"));
|
|
354
|
-
|
|
387
|
+
parts.push(msgCard);
|
|
355
388
|
if (helpOn && hasArticles !== false) {
|
|
356
389
|
const helpCard = el("div", { class: "ckw-msgr-card ckw-msgr-card-col" }, searchBox());
|
|
357
390
|
const top = (articles ?? []).slice(0, 4);
|
|
@@ -425,7 +458,10 @@ var build = (o) => {
|
|
|
425
458
|
let drawn = -1;
|
|
426
459
|
let listSig = "";
|
|
427
460
|
const drawMessages = () => {
|
|
428
|
-
head.replaceChildren(
|
|
461
|
+
head.replaceChildren(
|
|
462
|
+
el("span", { class: "ckw-msgr-who" }, avatar(), el("span", { class: "ckw-msgr-who-t" }, el("b", {}, title), el("span", {}, reply))),
|
|
463
|
+
closeBtn()
|
|
464
|
+
);
|
|
429
465
|
const msgs = thread?.messages ?? [];
|
|
430
466
|
const parts = [];
|
|
431
467
|
if (!loaded) parts.push(el("div", { class: "ckw-skel" }));
|
package/dist/messenger-ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/messenger-ui.ts"],"sourcesContent":["/**\n * The web messenger, after Featurebase's: a round launcher and a panel with three tabs, Home (greeting, the latest\n * chat, help search, top articles), Messages (the chat with the team, answered in MRRocket › Support by the owner or\n * the Customer experience agent) and Help (the product's published help articles, searchable, read in the panel).\n * While the panel is closed it checks for answers now and then; a new answer plays a short sound, shows a count on\n * the launcher and a preview card above it.\n *\n * Plain DOM, no React, so `<Messenger />` (Next.js) and the script tag share it; both load it only when it is used (a\n * dynamic import, and `sdk-messenger.js` for the script tag). Every text is set with textContent; articles arrive as\n * blocks, never HTML.\n */\nimport { type ArticleBlock, type ArticleSpan, type ArticleSummary, type ChatMessage, type ChatThread, type MessengerLook, createApi } from \"./api-client\";\nimport { injectStyles } from \"./styles-css\";\n\nexport interface MessengerUiOptions {\n host: string;\n apiKey: string;\n /** The visitor id now (it changes on identify and reset). */\n distinctId: () => string;\n /** The signed-in person's id, name and email, when the site called identify. */\n user: () => { id?: string; name?: string; email?: string } | undefined;\n /** Show the round launcher (default true). Without it the panel opens only through `open()`. */\n launcher?: boolean;\n position?: \"bottom-right\" | \"bottom-left\";\n /** The panel's title. */\n title?: string;\n /** The big line on Home and the first line of an empty chat. */\n greeting?: string;\n /** Ask anonymous visitors for an email (optional for them). Default true. */\n askEmail?: boolean;\n /** Text on the launcher; empty shows the icon only. */\n label?: string;\n /** The Help tab with the product's published help articles (default true; hidden while there are none). */\n help?: boolean;\n /** A short sound when an answer arrives (default true). */\n sound?: boolean;\n /** A preview of a new answer above the closed launcher (default true). */\n preview?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n accent?: string;\n}\n\nexport type MessengerView = \"home\" | \"messages\" | \"help\";\n\nexport interface MessengerHandle {\n /** Opens the panel, on Home or the given tab; `{ article }` opens a help article. */\n open(view?: MessengerView | { article: string }): void;\n close(): void;\n toggle(): void;\n /** Removes the launcher and the panel from the page. */\n destroy(): void;\n}\n\nconst POLL_OPEN_MS = 4000;\n/** While the panel is closed: soon after the visitor wrote, answers are looked for often, later now and then. */\nconst POLL_WAITING_MS = 8000;\nconst POLL_IDLE_MS = 30000;\nconst WAITING_FOR_MS = 10 * 60_000;\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/;\nconst SEEN_KEY = \"ckw_msgr_seen\";\nconst whoLabel: Record<ChatMessage[\"from\"], string> = { visitor: \"You\", team: \"Team\", ai: \"AI agent\", auto: \"Team\" };\n\nconst readSeen = () => {\n try {\n return window.localStorage.getItem(SEEN_KEY) ?? \"\";\n } catch {\n return \"\";\n }\n};\nconst writeSeen = (id: string) => {\n try {\n window.localStorage.setItem(SEEN_KEY, id);\n } catch {\n // Private mode: the count just shows again next time.\n }\n};\n\nconst timeAgo = (iso: string) => {\n const t = new Date(iso).getTime();\n if (Number.isNaN(t)) return \"\";\n const d = Math.max(0, Date.now() - t) / 1000;\n if (d < 60) return \"just now\";\n if (d < 3600) return `${Math.floor(d / 60)}m ago`;\n if (d < 86400) return `${Math.floor(d / 3600)}h ago`;\n if (d < 86400 * 30) return `${Math.floor(d / 86400)}d ago`;\n return new Date(iso).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\nconst el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, ...kids: (Node | string | null | false | undefined)[]) => {\n const e = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);\n for (const k of kids) if (k !== null && k !== false && k !== undefined) e.append(k);\n return e;\n};\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst icon = (d: string, size = 16) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.7\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\nconst I = {\n cross: \"m4 4 8 8M12 4l-8 8\",\n chat: \"M2.5 4.5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v4.5a2 2 0 0 1-2 2H7l-3 2.5V11a2 2 0 0 1-1.5-2z\",\n send: \"M2.5 8h10M8.5 3.5 13 8l-4.5 4.5\",\n home: \"M2.5 7 8 2.5 13.5 7v6a1 1 0 0 1-1 1h-3v-4h-3v4h-3a1 1 0 0 1-1-1z\",\n help: \"M8 14.5A6.5 6.5 0 1 0 8 1.5a6.5 6.5 0 0 0 0 13zM6.2 6.2a1.9 1.9 0 1 1 2.6 1.8c-.5.2-.8.6-.8 1.1v.4M8 11.6v.1\",\n back: \"M10 3.5 5.5 8l4.5 4.5\",\n next: \"M6 3.5 10.5 8 6 12.5\",\n search: \"M7 11.5a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9zM10.5 10.5l3 3\",\n doc: \"M4 1.5h5.5l3 3V14a.5.5 0 0 1-.5.5H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5zM9.5 1.5v3h3M6 8.5h4M6 11h4\",\n};\n\n/** A soft two-note chime made with Web Audio (no file to load). Browsers allow it once the visitor has clicked. */\nconst chime = (() => {\n let ctx: AudioContext | null = null;\n const get = () => {\n const AC = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AC) return null;\n ctx ??= new AC();\n return ctx;\n };\n return {\n /** Call from a click so later sounds may play. */\n unlock: () => {\n try {\n const c = get();\n if (c?.state === \"suspended\") void c.resume();\n } catch {\n // No audio: no sound.\n }\n },\n play: () => {\n try {\n const c = get();\n if (!c || c.state !== \"running\") return;\n const t = c.currentTime;\n [880, 1318.5].forEach((f, i) => {\n const o = c.createOscillator();\n const g = c.createGain();\n const at = t + i * 0.11;\n o.type = \"sine\";\n o.frequency.value = f;\n g.gain.setValueAtTime(0.0001, at);\n g.gain.exponentialRampToValueAtTime(0.12, at + 0.012);\n g.gain.exponentialRampToValueAtTime(0.0001, at + 0.32);\n o.connect(g);\n g.connect(c.destination);\n o.start(at);\n o.stop(at + 0.34);\n });\n } catch {\n // No audio: no sound.\n }\n },\n };\n})();\n\nconst spansOf = (spans: ArticleSpan[]) =>\n spans.map((s) => {\n let node: HTMLElement = s.href ? el(\"a\", { href: s.href, target: \"_blank\", rel: \"noopener noreferrer\" }, s.text) : el(\"span\", {}, s.text);\n if (s.code) node = el(\"code\", {}, node);\n if (s.italic) node = el(\"em\", {}, node);\n if (s.bold) node = el(\"strong\", {}, node);\n return node;\n });\n\nconst blockOf = (b: ArticleBlock): HTMLElement => {\n switch (b.type) {\n case \"h2\":\n case \"h3\":\n return el(b.type, {}, ...spansOf(b.spans));\n case \"quote\":\n return el(\"blockquote\", {}, ...spansOf(b.spans));\n case \"ul\":\n case \"ol\":\n return el(b.type, {}, ...b.items.map((it) => el(\"li\", {}, ...spansOf(it))));\n case \"code\":\n return el(\"pre\", {}, el(\"code\", {}, b.text));\n case \"hr\":\n return el(\"hr\");\n default:\n return el(\"p\", {}, ...spansOf(b.spans));\n }\n};\n\n/** How long the launcher waits for the look from MRRocket before it shows with the code's options and the defaults. */\nconst LOOK_WAIT_MS = 2500;\n\n/**\n * Mounts the messenger with its look from MRRocket (Support › Messenger) underneath what the code passes: an option the\n * code sets wins, one it leaves out comes from MRRocket, then the default. Calls made before the look arrived wait.\n */\nexport const mountMessenger = (o: MessengerUiOptions): MessengerHandle => {\n let real: MessengerHandle | null = null;\n let gone = false;\n const queued: ((h: MessengerHandle) => void)[] = [];\n const later = (fn: (h: MessengerHandle) => void) => (real ? fn(real) : queued.push(fn));\n const ctrl = new AbortController();\n const start = (look: Partial<MessengerLook> | null) => {\n if (real || gone) return;\n const defined = Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as MessengerUiOptions;\n real = build({ ...(look ?? {}), ...defined, accent: o.accent ?? look?.accent, theme: o.theme ?? look?.theme });\n for (const fn of queued.splice(0)) fn(real);\n };\n const timer = setTimeout(() => start(null), LOOK_WAIT_MS);\n createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user() })\n .messengerLook(ctrl.signal)\n .then((look) => start(look))\n .catch(() => start(null))\n .finally(() => clearTimeout(timer));\n return {\n open: (v) => later((h) => h.open(v)),\n close: () => real?.close(),\n toggle: () => later((h) => h.toggle()),\n destroy: () => {\n gone = true;\n ctrl.abort();\n clearTimeout(timer);\n real?.destroy();\n },\n };\n};\n\nconst build = (o: MessengerUiOptions): MessengerHandle => {\n injectStyles();\n const position = o.position ?? \"bottom-right\";\n const title = o.title || \"Chat with us\";\n const greeting = o.greeting || \"Hi! How can we help?\";\n const askEmail = o.askEmail ?? true;\n const label = o.label ?? \"\";\n const launcherOn = o.launcher ?? true;\n const helpOn = o.help ?? true;\n const soundOn = o.sound ?? true;\n const previewOn = o.preview ?? true;\n const api = () => createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user() });\n\n const root = el(\"div\", { class: \"ckw-root\", \"data-theme\": o.theme ?? \"auto\" });\n if (o.accent) root.style.setProperty(\"--ckw-accent\", o.accent);\n document.body.appendChild(root);\n\n let open = false;\n let view: MessengerView | { article: string } = \"home\";\n let thread: ChatThread | null = null;\n let loaded = false;\n let error = \"\";\n let pending: ChatMessage | null = null;\n /** The newest team message seen in this page load: what counts as new after it. */\n let lastKnown: string | null = null;\n let unseen: ChatMessage[] = [];\n let previewGone = false;\n let poll: ReturnType<typeof setTimeout> | undefined;\n let ctrl: AbortController | null = null;\n let articles: ArticleSummary[] | null = null;\n let query = \"\";\n let rated = new Set<string>();\n /** Whether the product has any published article: the Help tab and Home's help card hide when it has none. */\n let hasArticles: boolean | null = null;\n\n const teamMsgs = (t: ChatThread | null) => (t?.messages ?? []).filter((m) => m.from !== \"visitor\");\n const lastTeamId = (t: ChatThread | null) => teamMsgs(t).at(-1)?.id ?? \"\";\n const watching = () => open && view === \"messages\" && document.visibilityState !== \"hidden\";\n\n /** Takes a thread from the server: new answers count, chime and show in the preview. */\n const take = (t: ChatThread) => {\n const team = teamMsgs(t);\n if (lastKnown === null) {\n // First read: answers the visitor never saw in an earlier visit count, without a sound.\n const seen = readSeen();\n const i = team.findIndex((m) => m.id === seen);\n unseen = t.messages.some((m) => m.from === \"visitor\") ? team.slice(i + 1).filter((m) => m.from !== \"auto\") : [];\n } else {\n const i = team.findIndex((m) => m.id === lastKnown);\n const fresh = team.slice(i + 1).filter((m) => m.from !== \"auto\");\n if (fresh.length) {\n if (soundOn) chime.play();\n if (!watching()) {\n unseen = [...unseen, ...fresh];\n previewGone = false;\n }\n }\n }\n lastKnown = lastTeamId(t);\n thread = t;\n if (watching()) markSeen();\n };\n const markSeen = () => {\n unseen = [];\n const id = lastTeamId(thread);\n if (id) writeSeen(id);\n };\n\n // ---------- Launcher and preview ----------\n const fab = el(\"button\", { type: \"button\", class: `ckw-fab ckw-msgr-fab${label ? \"\" : \" ckw-msgr-round\"}`, \"data-pos\": position, \"aria-haspopup\": \"dialog\" });\n const prev = el(\"div\", { class: \"ckw-msgr-preview\", \"data-pos\": position, role: \"status\" });\n const drawFab = () => {\n fab.replaceChildren(icon(open ? I.cross : I.chat, label ? 16 : 20));\n if (label) fab.append(el(\"span\", {}, label));\n if (unseen.length && !open) fab.append(el(\"span\", { class: \"ckw-msgr-count\", \"aria-hidden\": \"true\" }, String(Math.min(unseen.length, 9))));\n fab.setAttribute(\"aria-expanded\", String(open));\n fab.setAttribute(\"aria-label\", open ? \"Close chat\" : unseen.length ? `Open chat, ${unseen.length} new ${unseen.length === 1 ? \"reply\" : \"replies\"}` : \"Open chat\");\n drawPreview();\n };\n const drawPreview = () => {\n const m = unseen.at(-1);\n if (!previewOn || open || previewGone || !m || !launcherOn) return prev.remove();\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-preview-x\", \"aria-label\": \"Dismiss\" }, icon(I.cross, 12));\n x.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n previewGone = true;\n drawPreview();\n });\n const card = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-preview-card\" },\n el(\"span\", { class: \"ckw-msgr-preview-who\" }, `${whoLabel[m.from]}${unseen.length > 1 ? ` · ${unseen.length} new` : \"\"}`),\n el(\"span\", { class: \"ckw-msgr-preview-text\" }, m.body),\n );\n card.addEventListener(\"click\", () => show(\"messages\"));\n prev.replaceChildren(card, x);\n if (!prev.isConnected) root.appendChild(prev);\n };\n fab.addEventListener(\"click\", () => {\n chime.unlock();\n if (open) close();\n else show(unseen.length ? \"messages\" : \"home\");\n });\n if (launcherOn) root.appendChild(fab);\n\n // ---------- Panel ----------\n const pop = el(\"div\", { class: \"ckw-pop ckw-msgr\", \"data-pos\": position, role: \"dialog\", \"aria-label\": title });\n const head = el(\"div\", { class: \"ckw-pop-head ckw-msgr-head\" });\n const body = el(\"div\", { class: \"ckw-pop-body ckw-msgr-body\" });\n const tabs = el(\"nav\", { class: \"ckw-msgr-tabs\", \"aria-label\": \"Messenger\" });\n pop.addEventListener(\"click\", () => chime.unlock());\n\n // The chat's compose form keeps its elements between draws, so the field never loses the focus.\n const form = el(\"form\", { class: \"ckw-msgr-compose\" });\n const err = el(\"p\", { class: \"ckw-msgr-error\", role: \"alert\" });\n const email = el(\"input\", { class: \"ckw-input\", type: \"email\", inputmode: \"email\", autocomplete: \"email\", placeholder: \"Your email (optional), so we can follow up\", \"aria-label\": \"Your email (optional)\", maxlength: \"200\" });\n const row = el(\"div\", { class: \"ckw-msgr-row\" });\n const text = el(\"textarea\", { class: \"ckw-textarea ckw-msgr-input\", rows: \"1\", placeholder: \"Write a message…\", \"aria-label\": \"Message\", maxlength: \"4000\" });\n const send = el(\"button\", { type: \"submit\", class: \"ckw-btn ckw-btn-primary ckw-msgr-send\", \"aria-label\": \"Send\" }, icon(I.send));\n row.append(text, send);\n form.append(row);\n\n const list = el(\"ol\", { class: \"ckw-msgs\", \"aria-live\": \"polite\", \"aria-label\": \"Messages\" });\n const needEmail = () => askEmail && !o.user()?.email && !thread?.hasEmail;\n const emailOk = () => !email.value.trim() || EMAIL.test(email.value.trim());\n const canSend = () => !!text.value.trim() && !pending && emailOk();\n\n const closeBtn = () => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-ghost ckw-msgr-x\", \"aria-label\": \"Close messenger\" }, icon(I.cross));\n b.addEventListener(\"click\", () => close());\n return b;\n };\n const go = (v: MessengerView | { article: string }) => {\n view = v;\n drawn = -1;\n draw();\n if (v === \"messages\") {\n markSeen();\n drawFab();\n text.focus();\n } else if (v === \"help\") helpInput.focus();\n schedule(0);\n };\n\n const bubble = (m: ChatMessage, isPending = false) => {\n const li = el(\"li\", { class: \"ckw-msg\", \"data-from\": m.from === \"visitor\" ? \"me\" : \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, m.body));\n if (isPending) li.setAttribute(\"aria-busy\", \"true\");\n for (const a of m.articles ?? []) {\n const chip = el(\"button\", { type: \"button\", class: \"ckw-msgr-cite\" }, icon(I.doc, 14), el(\"span\", {}, a.title));\n chip.addEventListener(\"click\", () => go({ article: a.id }));\n li.append(chip);\n }\n li.append(el(\"span\", { class: \"ckw-msg-meta\" }, `${m.from !== \"visitor\" ? `${whoLabel[m.from]} · ` : \"\"}${isPending ? \"Sending…\" : timeAgo(m.at)}`));\n return li;\n };\n\n const articleRow = (a: ArticleSummary) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-art\" }, el(\"span\", { class: \"ckw-msgr-art-t\" }, a.title), icon(I.next, 14));\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n };\n\n const searchBox = () => {\n const wrap = el(\"label\", { class: \"ckw-msgr-search\" }, icon(I.search, 14));\n const input = el(\"input\", { class: \"ckw-msgr-search-in\", type: \"search\", placeholder: \"Search for help\", \"aria-label\": \"Search for help\", maxlength: \"200\" });\n input.value = query;\n let t: ReturnType<typeof setTimeout> | undefined;\n input.addEventListener(\"input\", () => {\n query = input.value;\n clearTimeout(t);\n t = setTimeout(() => {\n if (view !== \"help\") return go(\"help\");\n void loadArticles(true);\n }, 250);\n });\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (view !== \"help\") go(\"help\");\n }\n });\n wrap.append(input);\n return wrap;\n };\n // Help's own field stays the same element between draws, so typing never loses the cursor.\n const helpSearch = searchBox();\n const helpInput = helpSearch.querySelector(\"input\")!;\n\n let loadingArticles = false;\n const loadArticles = async (force = false) => {\n if (!helpOn || (loadingArticles && !force)) return;\n loadingArticles = true;\n const q = query.trim();\n try {\n const r = await api().articles(q || undefined);\n if (q !== query.trim()) return;\n articles = r.articles;\n if (!q) hasArticles = r.articles.length > 0;\n } catch {\n articles = articles ?? [];\n } finally {\n loadingArticles = false;\n }\n draw();\n };\n const drawHome = () => {\n head.replaceChildren(el(\"span\", { class: \"ckw-msgr-brand\" }, title), closeBtn());\n const hero = el(\"div\", { class: \"ckw-msgr-hero\" }, el(\"p\", { class: \"ckw-msgr-hello\" }, greeting));\n const last = (thread?.messages ?? []).at(-1);\n const msgCard = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-card\" },\n el(\n \"span\",\n { class: \"ckw-msgr-card-main\" },\n el(\"b\", {}, last ? \"Recent message\" : \"Send us a message\"),\n el(\"span\", { class: \"ckw-msgr-card-sub\" }, last ? `${last.from === \"visitor\" ? \"You\" : whoLabel[last.from]}: ${last.body}` : \"We usually answer within a few hours\"),\n ),\n unseen.length ? el(\"span\", { class: \"ckw-msgr-badge\" }, String(unseen.length)) : icon(I.send),\n );\n msgCard.addEventListener(\"click\", () => go(\"messages\"));\n const parts: HTMLElement[] = [hero, msgCard];\n if (helpOn && hasArticles !== false) {\n const helpCard = el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, searchBox());\n const top = (articles ?? []).slice(0, 4);\n if (top.length) helpCard.append(...top.map(articleRow));\n else if (articles === null) helpCard.append(el(\"div\", { class: \"ckw-skel ckw-msgr-skel\" }));\n parts.push(helpCard);\n }\n body.replaceChildren(...parts);\n };\n\n const drawHelp = () => {\n head.replaceChildren(el(\"span\", {}, \"Help\"), closeBtn());\n if (helpInput.value !== query) helpInput.value = query;\n const parts: HTMLElement[] = [helpSearch];\n if (articles === null) parts.push(el(\"div\", { class: \"ckw-skel\" }));\n else if (!articles.length) {\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary\" }, \"Send us a message\");\n ask.addEventListener(\"click\", () => go(\"messages\"));\n parts.push(el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, query.trim() ? `Nothing found for “${query.trim()}”.` : \"No help articles yet.\"), ask));\n } else if (query.trim()) parts.push(el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, ...articles.map(articleRow)));\n else {\n const groups = new Map<string, ArticleSummary[]>();\n for (const a of articles) groups.set(a.collection, [...(groups.get(a.collection) ?? []), a]);\n for (const [name, items] of groups)\n parts.push(el(\"section\", { class: \"ckw-msgr-group\" }, el(\"h3\", { class: \"ckw-msgr-group-h\" }, `${name} · ${items.length}`), el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, ...items.map(articleRow))));\n }\n // The field stays in place (moving it would take its focus); only what is under it changes.\n if (body.firstChild !== helpSearch) body.replaceChildren(helpSearch);\n while (body.childNodes.length > 1) body.lastChild!.remove();\n body.append(...parts.slice(1));\n };\n\n let articleShown: { id: string; node: HTMLElement } | null = null;\n const drawArticle = (id: string) => {\n const back = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-ghost ckw-msgr-x\", \"aria-label\": \"Back to help\" }, icon(I.back));\n back.addEventListener(\"click\", () => go(\"help\"));\n head.replaceChildren(back, el(\"span\", { class: \"ckw-msgr-head-t\" }, \"Help\"), closeBtn());\n if (articleShown?.id === id) return body.replaceChildren(articleShown.node);\n const node = el(\"article\", { class: \"ckw-msgr-doc\" }, el(\"div\", { class: \"ckw-skel\" }));\n articleShown = { id, node };\n body.replaceChildren(node);\n api()\n .article(id)\n .then((a) => {\n const foot = el(\"div\", { class: \"ckw-msgr-rate\" });\n const drawRate = () => {\n if (rated.has(id)) return foot.replaceChildren(el(\"span\", {}, \"Thanks for letting us know.\"));\n const yes = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, \"Yes\");\n const no = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, \"No\");\n const rate = (helpful: boolean) => {\n rated = new Set(rated).add(id);\n drawRate();\n api()\n .rateArticle(id, helpful)\n .catch(() => undefined);\n if (!helpful) go(\"messages\");\n };\n yes.addEventListener(\"click\", () => rate(true));\n no.addEventListener(\"click\", () => rate(false));\n foot.replaceChildren(el(\"span\", {}, \"Did this answer your question?\"), el(\"span\", { class: \"ckw-msgr-rate-b\" }, yes, no));\n };\n drawRate();\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-msgr-ask\" }, icon(I.chat), \"Still need help? Send us a message\");\n ask.addEventListener(\"click\", () => go(\"messages\"));\n node.replaceChildren(\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, a.collection),\n el(\"h2\", { class: \"ckw-msgr-doc-t\" }, a.title),\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, `Updated ${timeAgo(a.updatedAt)}`),\n el(\"div\", { class: \"ckw-msgr-doc-b\" }, ...a.blocks.map(blockOf)),\n foot,\n ask,\n );\n })\n .catch((e: Error) => {\n articleShown = null;\n node.replaceChildren(el(\"p\", { class: \"ckw-msgr-error\" }, e.message));\n });\n };\n\n let drawn = -1;\n /** What the list shows, so a read that brings nothing new leaves it alone (no flicker, links stay where they are). */\n let listSig = \"\";\n const drawMessages = () => {\n head.replaceChildren(el(\"span\", {}, title), closeBtn());\n const msgs = thread?.messages ?? [];\n const parts: HTMLElement[] = [];\n if (!loaded) parts.push(el(\"div\", { class: \"ckw-skel\" }));\n else {\n const sig = `${msgs.map((m) => m.id).join(\",\")}|${pending ? pending.body : \"\"}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== listSig) {\n listSig = sig;\n const greet = el(\"li\", { class: \"ckw-msg\", \"data-from\": \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, greeting));\n list.replaceChildren(greet, ...msgs.map((m) => bubble(m)), ...(pending ? [bubble(pending, true)] : []));\n }\n parts.push(list);\n }\n if (thread?.conversation?.status === \"solved\" && !pending) parts.push(el(\"p\", { class: \"ckw-fine ckw-msgr-note\" }, \"This conversation is closed. Write to start a new one.\"));\n if (body.childNodes.length !== parts.length || parts.some((x, i) => body.childNodes[i] !== x)) body.replaceChildren(...parts);\n const count = msgs.length + (pending ? 1 : 0);\n if (count !== drawn) {\n drawn = count;\n body.scrollTop = body.scrollHeight;\n }\n err.textContent = error;\n if (error && !err.isConnected) form.prepend(err);\n else if (!error) err.remove();\n if (needEmail()) {\n if (emailOk()) email.removeAttribute(\"aria-invalid\");\n else email.setAttribute(\"aria-invalid\", \"true\");\n if (!email.isConnected) form.insertBefore(email, row);\n } else email.remove();\n send.disabled = !canSend();\n };\n\n const drawTabs = () => {\n const current = typeof view === \"string\" ? view : \"help\";\n const tab = (v: MessengerView, name: string, d: string, badge = 0) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-tab\", \"aria-current\": current === v ? \"page\" : \"false\" }, icon(d, 18), el(\"span\", {}, name));\n if (badge) b.append(el(\"span\", { class: \"ckw-msgr-count ckw-msgr-count-tab\" }, String(Math.min(badge, 9))));\n b.addEventListener(\"click\", () => go(v));\n return b;\n };\n tabs.replaceChildren(tab(\"home\", \"Home\", I.home), tab(\"messages\", \"Messages\", I.chat, view === \"messages\" ? 0 : unseen.length), ...(helpOn && hasArticles !== false ? [tab(\"help\", \"Help\", I.help)] : []));\n };\n\n const draw = () => {\n if (!open) return;\n pop.dataset.view = typeof view === \"string\" ? view : \"article\";\n if (view === \"home\") drawHome();\n else if (view === \"messages\") drawMessages();\n else if (view === \"help\") drawHelp();\n else drawArticle(view.article);\n const kids: HTMLElement[] = [head, body];\n if (view === \"messages\") kids.push(form);\n kids.push(tabs);\n drawTabs();\n if (pop.childNodes.length !== kids.length || kids.some((k, i) => pop.childNodes[i] !== k)) pop.replaceChildren(...kids);\n };\n\n // ---------- Reading the chat ----------\n const tick = async () => {\n ctrl?.abort();\n ctrl = new AbortController();\n try {\n take(await api().chat(ctrl.signal));\n error = \"\";\n } catch (e) {\n if ((e as Error).name === \"AbortError\") return;\n if (open && view === \"messages\") error = (e as Error).message;\n }\n loaded = true;\n draw();\n drawFab();\n schedule();\n };\n /** The next read: often while the chat is on screen, now and then while the visitor waits for an answer. */\n function schedule(now?: number) {\n clearTimeout(poll);\n const waiting = !!thread?.messages.some((m) => m.from === \"visitor\") && thread?.conversation?.status !== \"solved\";\n const wrote = (thread?.messages ?? []).filter((m) => m.from === \"visitor\").at(-1)?.at;\n const recent = !!wrote && Date.now() - new Date(wrote).getTime() < WAITING_FOR_MS;\n const ms = now ?? (watching() ? POLL_OPEN_MS : waiting && recent ? POLL_WAITING_MS : open || waiting ? POLL_IDLE_MS : 0);\n if (ms || now === 0) poll = setTimeout(() => void tick(), ms);\n }\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") schedule(0);\n else clearTimeout(poll);\n });\n\n const submit = async () => {\n const msg = text.value.trim();\n if (!msg || pending || !emailOk()) return;\n chime.unlock();\n pending = { id: \"pending\", from: \"visitor\", body: msg, at: new Date().toISOString() };\n text.value = \"\";\n error = \"\";\n draw();\n try {\n take(await api().sendChat({ body: msg, email: needEmail() && email.value.trim() ? email.value.trim() : undefined, url: window.location.href.slice(0, 500) }));\n } catch (e) {\n text.value = msg;\n error = (e as Error).message;\n }\n pending = null;\n draw();\n schedule();\n };\n form.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n void submit();\n });\n text.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n void submit();\n }\n });\n text.addEventListener(\"input\", () => (send.disabled = !canSend()));\n email.addEventListener(\"input\", () => draw());\n\n function show(v: MessengerView | { article: string } = \"home\") {\n open = true;\n view = v === \"help\" && !helpOn ? \"home\" : v;\n drawn = -1;\n previewGone = true;\n if (!pop.isConnected) root.appendChild(pop);\n if (articles === null || (view === \"help\" && query)) void loadArticles();\n draw();\n drawFab();\n if (view === \"messages\") {\n markSeen();\n text.focus();\n }\n schedule(0);\n }\n function close() {\n if (!open) return;\n open = false;\n pop.remove();\n drawFab();\n schedule();\n if (launcherOn) fab.focus();\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && open) close();\n };\n document.addEventListener(\"keydown\", onKey);\n\n // One read on load (the count and preview of answers not seen yet), and the article count for the Help tab.\n void tick();\n if (helpOn) void loadArticles();\n drawFab();\n\n return {\n open: (v) => show(v ?? \"home\"),\n close,\n toggle: () => (open ? close() : show()),\n destroy: () => {\n clearTimeout(poll);\n ctrl?.abort();\n document.removeEventListener(\"keydown\", onKey);\n root.remove();\n },\n };\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/messenger-ui.ts"],"sourcesContent":["/**\n * The web messenger, after Featurebase's: a round launcher and a panel with three tabs, Home (greeting, the latest\n * chat, help search, top articles), Messages (the chat with the team, answered in MRRocket › Support by the owner or\n * the Customer experience agent) and Help (the product's published help articles, searchable, read in the panel).\n * While the panel is closed it checks for answers now and then; a new answer plays a short sound, shows a count on\n * the launcher and a preview card above it.\n *\n * Plain DOM, no React, so `<Messenger />` (Next.js) and the script tag share it; both load it only when it is used (a\n * dynamic import, and `sdk-messenger.js` for the script tag). Every text is set with textContent; articles arrive as\n * blocks, never HTML.\n */\nimport { type ArticleBlock, type ArticleSpan, type ArticleSummary, type ChatMessage, type ChatThread, type MessengerLook, createApi, inkOn, replyLine } from \"./api-client\";\nimport { injectStyles } from \"./styles-css\";\n\nexport interface MessengerUiOptions {\n host: string;\n apiKey: string;\n /** The visitor id now (it changes on identify and reset). */\n distinctId: () => string;\n /** The signed-in person's id, name and email, when the site called identify. */\n user: () => { id?: string; name?: string; email?: string } | undefined;\n /** Show the round launcher (default true). Without it the panel opens only through `open()`. */\n launcher?: boolean;\n position?: \"bottom-right\" | \"bottom-left\";\n /** The panel's title. */\n title?: string;\n /** The big line on Home and the first line of an empty chat. */\n greeting?: string;\n /** Ask anonymous visitors for an email (optional for them). Default true. */\n askEmail?: boolean;\n /** Text on the launcher; empty shows the icon only. */\n label?: string;\n /** How soon the team usually answers, said under \"Send us a message\" and in the chat's head. */\n replyTime?: \"minutes\" | \"hours\" | \"day\";\n /** The Help tab with the product's published help articles (default true; hidden while there are none). */\n help?: boolean;\n /** A short sound when an answer arrives (default true). */\n sound?: boolean;\n /** A preview of a new answer above the closed launcher (default true). */\n preview?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n accent?: string;\n}\n\nexport type MessengerView = \"home\" | \"messages\" | \"help\";\n\nexport interface MessengerHandle {\n /** Opens the panel, on Home or the given tab; `{ article }` opens a help article. */\n open(view?: MessengerView | { article: string }): void;\n close(): void;\n toggle(): void;\n /** Removes the launcher and the panel from the page. */\n destroy(): void;\n}\n\nconst POLL_OPEN_MS = 4000;\n/** While the panel is closed: soon after the visitor wrote, answers are looked for often, later now and then. */\nconst POLL_WAITING_MS = 8000;\nconst POLL_IDLE_MS = 30000;\nconst WAITING_FOR_MS = 10 * 60_000;\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/;\nconst SEEN_KEY = \"ckw_msgr_seen\";\nconst whoLabel: Record<ChatMessage[\"from\"], string> = { visitor: \"You\", team: \"Team\", ai: \"AI agent\", auto: \"Team\" };\n\nconst readSeen = () => {\n try {\n return window.localStorage.getItem(SEEN_KEY) ?? \"\";\n } catch {\n return \"\";\n }\n};\nconst writeSeen = (id: string) => {\n try {\n window.localStorage.setItem(SEEN_KEY, id);\n } catch {\n // Private mode: the count just shows again next time.\n }\n};\n\nconst timeAgo = (iso: string) => {\n const t = new Date(iso).getTime();\n if (Number.isNaN(t)) return \"\";\n const d = Math.max(0, Date.now() - t) / 1000;\n if (d < 60) return \"just now\";\n if (d < 3600) return `${Math.floor(d / 60)}m ago`;\n if (d < 86400) return `${Math.floor(d / 3600)}h ago`;\n if (d < 86400 * 30) return `${Math.floor(d / 86400)}d ago`;\n return new Date(iso).toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\nconst el = <K extends keyof HTMLElementTagNameMap>(tag: K, attrs: Record<string, string> = {}, ...kids: (Node | string | null | false | undefined)[]) => {\n const e = document.createElement(tag);\n for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);\n for (const k of kids) if (k !== null && k !== false && k !== undefined) e.append(k);\n return e;\n};\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\nconst icon = (d: string, size = 16) => {\n const svg = document.createElementNS(SVG_NS, \"svg\");\n for (const [k, v] of Object.entries({ class: \"ckw-icon\", width: String(size), height: String(size), viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", \"stroke-width\": \"1.7\", \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\", \"aria-hidden\": \"true\" }))\n svg.setAttribute(k, v);\n const path = document.createElementNS(SVG_NS, \"path\");\n path.setAttribute(\"d\", d);\n svg.appendChild(path);\n return svg;\n};\nconst I = {\n cross: \"m4 4 8 8M12 4l-8 8\",\n chat: \"M2.5 4.5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v4.5a2 2 0 0 1-2 2H7l-3 2.5V11a2 2 0 0 1-1.5-2z\",\n send: \"M2.5 8h10M8.5 3.5 13 8l-4.5 4.5\",\n up: \"M8 13V3M3.5 7.5 8 3l4.5 4.5\",\n home: \"M2.5 7 8 2.5 13.5 7v6a1 1 0 0 1-1 1h-3v-4h-3v4h-3a1 1 0 0 1-1-1z\",\n help: \"M8 14.5A6.5 6.5 0 1 0 8 1.5a6.5 6.5 0 0 0 0 13zM6.2 6.2a1.9 1.9 0 1 1 2.6 1.8c-.5.2-.8.6-.8 1.1v.4M8 11.6v.1\",\n back: \"M10 3.5 5.5 8l4.5 4.5\",\n next: \"M6 3.5 10.5 8 6 12.5\",\n search: \"M7 11.5a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9zM10.5 10.5l3 3\",\n doc: \"M4 1.5h5.5l3 3V14a.5.5 0 0 1-.5.5H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5zM9.5 1.5v3h3M6 8.5h4M6 11h4\",\n};\n\n/** A soft two-note chime made with Web Audio (no file to load). Browsers allow it once the visitor has clicked. */\nconst chime = (() => {\n let ctx: AudioContext | null = null;\n const get = () => {\n const AC = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AC) return null;\n ctx ??= new AC();\n return ctx;\n };\n return {\n /** Call from a click so later sounds may play. */\n unlock: () => {\n try {\n const c = get();\n if (c?.state === \"suspended\") void c.resume();\n } catch {\n // No audio: no sound.\n }\n },\n play: () => {\n try {\n const c = get();\n if (!c || c.state !== \"running\") return;\n const t = c.currentTime;\n [880, 1318.5].forEach((f, i) => {\n const o = c.createOscillator();\n const g = c.createGain();\n const at = t + i * 0.11;\n o.type = \"sine\";\n o.frequency.value = f;\n g.gain.setValueAtTime(0.0001, at);\n g.gain.exponentialRampToValueAtTime(0.12, at + 0.012);\n g.gain.exponentialRampToValueAtTime(0.0001, at + 0.32);\n o.connect(g);\n g.connect(c.destination);\n o.start(at);\n o.stop(at + 0.34);\n });\n } catch {\n // No audio: no sound.\n }\n },\n };\n})();\n\nconst spansOf = (spans: ArticleSpan[]) =>\n spans.map((s) => {\n let node: HTMLElement = s.href ? el(\"a\", { href: s.href, target: \"_blank\", rel: \"noopener noreferrer\" }, s.text) : el(\"span\", {}, s.text);\n if (s.code) node = el(\"code\", {}, node);\n if (s.italic) node = el(\"em\", {}, node);\n if (s.bold) node = el(\"strong\", {}, node);\n return node;\n });\n\nconst blockOf = (b: ArticleBlock): HTMLElement => {\n switch (b.type) {\n case \"h2\":\n case \"h3\":\n return el(b.type, {}, ...spansOf(b.spans));\n case \"quote\":\n return el(\"blockquote\", {}, ...spansOf(b.spans));\n case \"ul\":\n case \"ol\":\n return el(b.type, {}, ...b.items.map((it) => el(\"li\", {}, ...spansOf(it))));\n case \"code\":\n return el(\"pre\", {}, el(\"code\", {}, b.text));\n case \"hr\":\n return el(\"hr\");\n default:\n return el(\"p\", {}, ...spansOf(b.spans));\n }\n};\n\n/** How long the launcher waits for the look from MRRocket before it shows with the code's options and the defaults. */\nconst LOOK_WAIT_MS = 2500;\n\n/**\n * Mounts the messenger with its look from MRRocket (Support › Messenger) underneath what the code passes: an option the\n * code sets wins, one it leaves out comes from MRRocket, then the default. Calls made before the look arrived wait.\n */\nexport const mountMessenger = (o: MessengerUiOptions): MessengerHandle => {\n let real: MessengerHandle | null = null;\n let gone = false;\n const queued: ((h: MessengerHandle) => void)[] = [];\n const later = (fn: (h: MessengerHandle) => void) => (real ? fn(real) : queued.push(fn));\n const ctrl = new AbortController();\n const start = (look: Partial<MessengerLook> | null) => {\n if (real || gone) return;\n const defined = Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as MessengerUiOptions;\n real = build({ ...(look ?? {}), ...defined, accent: o.accent ?? look?.accent, theme: o.theme ?? look?.theme });\n for (const fn of queued.splice(0)) fn(real);\n };\n const timer = setTimeout(() => start(null), LOOK_WAIT_MS);\n createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user() })\n .messengerLook(ctrl.signal)\n .then((look) => start(look))\n .catch(() => start(null))\n .finally(() => clearTimeout(timer));\n return {\n open: (v) => later((h) => h.open(v)),\n close: () => real?.close(),\n toggle: () => later((h) => h.toggle()),\n destroy: () => {\n gone = true;\n ctrl.abort();\n clearTimeout(timer);\n real?.destroy();\n },\n };\n};\n\nconst build = (o: MessengerUiOptions): MessengerHandle => {\n injectStyles();\n const position = o.position ?? \"bottom-right\";\n const title = o.title || \"Chat with us\";\n const greeting = o.greeting || \"Hi! How can we help?\";\n const askEmail = o.askEmail ?? true;\n const label = o.label ?? \"\";\n const reply = replyLine(o.replyTime);\n /** The team's mark: the first letter of the title, on the accent. */\n const initial = (title.trim()[0] ?? \"?\").toUpperCase();\n const launcherOn = o.launcher ?? true;\n const helpOn = o.help ?? true;\n const soundOn = o.sound ?? true;\n const previewOn = o.preview ?? true;\n const api = () => createApi({ host: o.host, apiKey: o.apiKey, distinctId: o.distinctId(), user: o.user() });\n\n const root = el(\"div\", { class: \"ckw-root\", \"data-theme\": o.theme ?? \"auto\" });\n if (o.accent) {\n root.style.setProperty(\"--ckw-accent\", o.accent);\n root.style.setProperty(\"--ckw-accent-ink\", inkOn(o.accent));\n }\n document.body.appendChild(root);\n\n let open = false;\n let view: MessengerView | { article: string } = \"home\";\n let thread: ChatThread | null = null;\n let loaded = false;\n let error = \"\";\n let pending: ChatMessage | null = null;\n /** The newest team message seen in this page load: what counts as new after it. */\n let lastKnown: string | null = null;\n let unseen: ChatMessage[] = [];\n let previewGone = false;\n let poll: ReturnType<typeof setTimeout> | undefined;\n let ctrl: AbortController | null = null;\n let articles: ArticleSummary[] | null = null;\n let query = \"\";\n let rated = new Set<string>();\n /** Whether the product has any published article: the Help tab and Home's help card hide when it has none. */\n let hasArticles: boolean | null = null;\n\n const teamMsgs = (t: ChatThread | null) => (t?.messages ?? []).filter((m) => m.from !== \"visitor\");\n const lastTeamId = (t: ChatThread | null) => teamMsgs(t).at(-1)?.id ?? \"\";\n const watching = () => open && view === \"messages\" && document.visibilityState !== \"hidden\";\n\n /** Takes a thread from the server: new answers count, chime and show in the preview. */\n const take = (t: ChatThread) => {\n const team = teamMsgs(t);\n if (lastKnown === null) {\n // First read: answers the visitor never saw in an earlier visit count, without a sound.\n const seen = readSeen();\n const i = team.findIndex((m) => m.id === seen);\n unseen = t.messages.some((m) => m.from === \"visitor\") ? team.slice(i + 1).filter((m) => m.from !== \"auto\") : [];\n } else {\n const i = team.findIndex((m) => m.id === lastKnown);\n const fresh = team.slice(i + 1).filter((m) => m.from !== \"auto\");\n if (fresh.length) {\n if (soundOn) chime.play();\n if (!watching()) {\n unseen = [...unseen, ...fresh];\n previewGone = false;\n }\n }\n }\n lastKnown = lastTeamId(t);\n thread = t;\n if (watching()) markSeen();\n };\n const markSeen = () => {\n unseen = [];\n const id = lastTeamId(thread);\n if (id) writeSeen(id);\n };\n\n const avatar = (size?: \"sm\") => el(\"span\", { class: `ckw-msgr-av${size ? \" ckw-msgr-av-sm\" : \"\"}`, \"aria-hidden\": \"true\" }, initial);\n\n // ---------- Launcher and preview ----------\n const fab = el(\"button\", { type: \"button\", class: `ckw-fab ckw-msgr-fab${label ? \"\" : \" ckw-msgr-round\"}`, \"data-pos\": position, \"aria-haspopup\": \"dialog\" });\n const prev = el(\"div\", { class: \"ckw-msgr-preview\", \"data-pos\": position, role: \"status\" });\n /** The open state the launcher's icon last showed: the icon turns only when it changes, not on every read. */\n let fabShows: boolean | null = null;\n const drawFab = () => {\n const glyph = icon(open ? I.cross : I.chat, label ? 18 : 24);\n if (fabShows !== null && fabShows !== open) glyph.classList.add(\"ckw-turn\");\n fabShows = open;\n fab.replaceChildren(glyph);\n if (label) fab.append(el(\"span\", {}, label));\n if (unseen.length && !open) fab.append(el(\"span\", { class: \"ckw-msgr-count\", \"aria-hidden\": \"true\" }, String(Math.min(unseen.length, 9))));\n fab.setAttribute(\"aria-expanded\", String(open));\n fab.setAttribute(\"aria-label\", open ? \"Close chat\" : unseen.length ? `Open chat, ${unseen.length} new ${unseen.length === 1 ? \"reply\" : \"replies\"}` : \"Open chat\");\n drawPreview();\n };\n const drawPreview = () => {\n const m = unseen.at(-1);\n if (!previewOn || open || previewGone || !m || !launcherOn) return prev.remove();\n const x = el(\"button\", { type: \"button\", class: \"ckw-msgr-preview-x\", \"aria-label\": \"Dismiss\" }, icon(I.cross, 12));\n x.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n previewGone = true;\n drawPreview();\n });\n const card = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-preview-card\" },\n avatar(),\n el(\n \"span\",\n { class: \"ckw-msgr-preview-main\" },\n el(\"span\", { class: \"ckw-msgr-preview-who\" }, `${whoLabel[m.from]}${unseen.length > 1 ? ` · ${unseen.length} new` : \"\"}`),\n el(\"span\", { class: \"ckw-msgr-preview-text\" }, m.body),\n ),\n );\n card.addEventListener(\"click\", () => show(\"messages\"));\n prev.replaceChildren(card, x);\n if (!prev.isConnected) root.appendChild(prev);\n };\n fab.addEventListener(\"click\", () => {\n chime.unlock();\n if (open) close();\n else show(unseen.length ? \"messages\" : \"home\");\n });\n if (launcherOn) root.appendChild(fab);\n\n // ---------- Panel ----------\n const pop = el(\"div\", { class: \"ckw-pop ckw-msgr\", \"data-pos\": position, role: \"dialog\", \"aria-label\": title });\n const head = el(\"div\", { class: \"ckw-pop-head ckw-msgr-head\" });\n const body = el(\"div\", { class: \"ckw-pop-body ckw-msgr-body\" });\n const tabs = el(\"nav\", { class: \"ckw-msgr-tabs\", \"aria-label\": \"Messenger\" });\n pop.addEventListener(\"click\", () => chime.unlock());\n\n // The chat's compose form keeps its elements between draws, so the field never loses the focus.\n const form = el(\"form\", { class: \"ckw-msgr-compose\" });\n const err = el(\"p\", { class: \"ckw-msgr-error\", role: \"alert\" });\n const email = el(\"input\", { class: \"ckw-input\", type: \"email\", inputmode: \"email\", autocomplete: \"email\", placeholder: \"Your email (optional), so we can follow up\", \"aria-label\": \"Your email (optional)\", maxlength: \"200\" });\n const row = el(\"div\", { class: \"ckw-msgr-row\" });\n const text = el(\"textarea\", { class: \"ckw-textarea ckw-msgr-input\", rows: \"1\", placeholder: \"Write a message…\", \"aria-label\": \"Message\", maxlength: \"4000\" });\n const send = el(\"button\", { type: \"submit\", class: \"ckw-msgr-send\", \"aria-label\": \"Send\" }, icon(I.up));\n row.append(text, send);\n form.append(row);\n\n const list = el(\"ol\", { class: \"ckw-msgs\", \"aria-live\": \"polite\", \"aria-label\": \"Messages\" });\n const needEmail = () => askEmail && !o.user()?.email && !thread?.hasEmail;\n const emailOk = () => !email.value.trim() || EMAIL.test(email.value.trim());\n const canSend = () => !!text.value.trim() && !pending && emailOk();\n\n const closeBtn = () => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-ghost ckw-msgr-x\", \"aria-label\": \"Close messenger\" }, icon(I.cross));\n b.addEventListener(\"click\", () => close());\n return b;\n };\n const go = (v: MessengerView | { article: string }) => {\n view = v;\n drawn = -1;\n draw();\n if (v === \"messages\") {\n markSeen();\n drawFab();\n text.focus();\n } else if (v === \"help\") helpInput.focus();\n schedule(0);\n };\n\n const bubble = (m: ChatMessage, isPending = false) => {\n const li = el(\"li\", { class: \"ckw-msg\", \"data-from\": m.from === \"visitor\" ? \"me\" : \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, m.body));\n if (isPending) li.setAttribute(\"aria-busy\", \"true\");\n for (const a of m.articles ?? []) {\n const chip = el(\"button\", { type: \"button\", class: \"ckw-msgr-cite\" }, icon(I.doc, 14), el(\"span\", {}, a.title));\n chip.addEventListener(\"click\", () => go({ article: a.id }));\n li.append(chip);\n }\n li.append(el(\"span\", { class: \"ckw-msg-meta\" }, `${m.from !== \"visitor\" ? `${whoLabel[m.from]} · ` : \"\"}${isPending ? \"Sending…\" : timeAgo(m.at)}`));\n return li;\n };\n\n const articleRow = (a: ArticleSummary) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-art\" }, el(\"span\", { class: \"ckw-msgr-art-t\" }, a.title), icon(I.next, 14));\n b.addEventListener(\"click\", () => go({ article: a.id }));\n return b;\n };\n\n const searchBox = () => {\n const wrap = el(\"label\", { class: \"ckw-msgr-search\" });\n const input = el(\"input\", { class: \"ckw-msgr-search-in\", type: \"search\", placeholder: \"Search for help\", \"aria-label\": \"Search for help\", maxlength: \"200\" });\n input.value = query;\n let t: ReturnType<typeof setTimeout> | undefined;\n input.addEventListener(\"input\", () => {\n query = input.value;\n clearTimeout(t);\n t = setTimeout(() => {\n if (view !== \"help\") return go(\"help\");\n void loadArticles(true);\n }, 250);\n });\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (view !== \"help\") go(\"help\");\n }\n });\n wrap.append(input, icon(I.search, 16));\n return wrap;\n };\n // Help's own field stays the same element between draws, so typing never loses the cursor.\n const helpSearch = searchBox();\n const helpInput = helpSearch.querySelector(\"input\")!;\n\n let loadingArticles = false;\n const loadArticles = async (force = false) => {\n if (!helpOn || (loadingArticles && !force)) return;\n loadingArticles = true;\n const q = query.trim();\n try {\n const r = await api().articles(q || undefined);\n if (q !== query.trim()) return;\n articles = r.articles;\n if (!q) hasArticles = r.articles.length > 0;\n } catch {\n articles = articles ?? [];\n } finally {\n loadingArticles = false;\n }\n draw();\n };\n const drawHome = () => {\n head.replaceChildren(el(\"span\", { class: \"ckw-msgr-brand\" }, avatar(\"sm\"), el(\"span\", {}, title)), closeBtn());\n const hero = el(\"div\", { class: \"ckw-msgr-hero\" }, el(\"p\", { class: \"ckw-msgr-hello\" }, greeting));\n const last = (thread?.messages ?? []).at(-1);\n const parts: HTMLElement[] = [hero];\n if (last) {\n const recent = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-card ckw-msgr-recent\" },\n el(\"span\", { class: \"ckw-msgr-card-label\" }, \"Recent message\"),\n el(\n \"span\",\n { class: \"ckw-msgr-recent-row\" },\n avatar(),\n el(\n \"span\",\n { class: \"ckw-msgr-card-main\" },\n el(\"span\", { class: \"ckw-msgr-card-sub ckw-msgr-recent-text\" }, last.body),\n el(\"span\", { class: \"ckw-msgr-card-meta\" }, `${last.from === \"visitor\" ? \"You\" : whoLabel[last.from]} · ${timeAgo(last.at)}`),\n ),\n unseen.length ? el(\"span\", { class: \"ckw-msgr-badge\" }, String(unseen.length)) : icon(I.next, 14),\n ),\n );\n recent.addEventListener(\"click\", () => go(\"messages\"));\n parts.push(recent);\n }\n const msgCard = el(\n \"button\",\n { type: \"button\", class: \"ckw-msgr-card\" },\n el(\"span\", { class: \"ckw-msgr-card-main\" }, el(\"b\", {}, \"Send us a message\"), el(\"span\", { class: \"ckw-msgr-card-sub\" }, reply)),\n el(\"span\", { class: \"ckw-msgr-go\" }, icon(I.send)),\n );\n msgCard.addEventListener(\"click\", () => go(\"messages\"));\n parts.push(msgCard);\n if (helpOn && hasArticles !== false) {\n const helpCard = el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, searchBox());\n const top = (articles ?? []).slice(0, 4);\n if (top.length) helpCard.append(...top.map(articleRow));\n else if (articles === null) helpCard.append(el(\"div\", { class: \"ckw-skel ckw-msgr-skel\" }));\n parts.push(helpCard);\n }\n body.replaceChildren(...parts);\n };\n\n const drawHelp = () => {\n head.replaceChildren(el(\"span\", {}, \"Help\"), closeBtn());\n if (helpInput.value !== query) helpInput.value = query;\n const parts: HTMLElement[] = [helpSearch];\n if (articles === null) parts.push(el(\"div\", { class: \"ckw-skel\" }));\n else if (!articles.length) {\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-primary\" }, \"Send us a message\");\n ask.addEventListener(\"click\", () => go(\"messages\"));\n parts.push(el(\"div\", { class: \"ckw-msgr-empty\" }, el(\"p\", {}, query.trim() ? `Nothing found for “${query.trim()}”.` : \"No help articles yet.\"), ask));\n } else if (query.trim()) parts.push(el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, ...articles.map(articleRow)));\n else {\n const groups = new Map<string, ArticleSummary[]>();\n for (const a of articles) groups.set(a.collection, [...(groups.get(a.collection) ?? []), a]);\n for (const [name, items] of groups)\n parts.push(el(\"section\", { class: \"ckw-msgr-group\" }, el(\"h3\", { class: \"ckw-msgr-group-h\" }, `${name} · ${items.length}`), el(\"div\", { class: \"ckw-msgr-card ckw-msgr-card-col\" }, ...items.map(articleRow))));\n }\n // The field stays in place (moving it would take its focus); only what is under it changes.\n if (body.firstChild !== helpSearch) body.replaceChildren(helpSearch);\n while (body.childNodes.length > 1) body.lastChild!.remove();\n body.append(...parts.slice(1));\n };\n\n let articleShown: { id: string; node: HTMLElement } | null = null;\n const drawArticle = (id: string) => {\n const back = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-btn-ghost ckw-msgr-x\", \"aria-label\": \"Back to help\" }, icon(I.back));\n back.addEventListener(\"click\", () => go(\"help\"));\n head.replaceChildren(back, el(\"span\", { class: \"ckw-msgr-head-t\" }, \"Help\"), closeBtn());\n if (articleShown?.id === id) return body.replaceChildren(articleShown.node);\n const node = el(\"article\", { class: \"ckw-msgr-doc\" }, el(\"div\", { class: \"ckw-skel\" }));\n articleShown = { id, node };\n body.replaceChildren(node);\n api()\n .article(id)\n .then((a) => {\n const foot = el(\"div\", { class: \"ckw-msgr-rate\" });\n const drawRate = () => {\n if (rated.has(id)) return foot.replaceChildren(el(\"span\", {}, \"Thanks for letting us know.\"));\n const yes = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, \"Yes\");\n const no = el(\"button\", { type: \"button\", class: \"ckw-btn\" }, \"No\");\n const rate = (helpful: boolean) => {\n rated = new Set(rated).add(id);\n drawRate();\n api()\n .rateArticle(id, helpful)\n .catch(() => undefined);\n if (!helpful) go(\"messages\");\n };\n yes.addEventListener(\"click\", () => rate(true));\n no.addEventListener(\"click\", () => rate(false));\n foot.replaceChildren(el(\"span\", {}, \"Did this answer your question?\"), el(\"span\", { class: \"ckw-msgr-rate-b\" }, yes, no));\n };\n drawRate();\n const ask = el(\"button\", { type: \"button\", class: \"ckw-btn ckw-msgr-ask\" }, icon(I.chat), \"Still need help? Send us a message\");\n ask.addEventListener(\"click\", () => go(\"messages\"));\n node.replaceChildren(\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, a.collection),\n el(\"h2\", { class: \"ckw-msgr-doc-t\" }, a.title),\n el(\"p\", { class: \"ckw-msgr-doc-c\" }, `Updated ${timeAgo(a.updatedAt)}`),\n el(\"div\", { class: \"ckw-msgr-doc-b\" }, ...a.blocks.map(blockOf)),\n foot,\n ask,\n );\n })\n .catch((e: Error) => {\n articleShown = null;\n node.replaceChildren(el(\"p\", { class: \"ckw-msgr-error\" }, e.message));\n });\n };\n\n let drawn = -1;\n /** What the list shows, so a read that brings nothing new leaves it alone (no flicker, links stay where they are). */\n let listSig = \"\";\n const drawMessages = () => {\n head.replaceChildren(\n el(\"span\", { class: \"ckw-msgr-who\" }, avatar(), el(\"span\", { class: \"ckw-msgr-who-t\" }, el(\"b\", {}, title), el(\"span\", {}, reply))),\n closeBtn(),\n );\n const msgs = thread?.messages ?? [];\n const parts: HTMLElement[] = [];\n if (!loaded) parts.push(el(\"div\", { class: \"ckw-skel\" }));\n else {\n const sig = `${msgs.map((m) => m.id).join(\",\")}|${pending ? pending.body : \"\"}|${Math.floor(Date.now() / 60_000)}`;\n if (sig !== listSig) {\n listSig = sig;\n const greet = el(\"li\", { class: \"ckw-msg\", \"data-from\": \"them\" }, el(\"div\", { class: \"ckw-bubble\" }, greeting));\n list.replaceChildren(greet, ...msgs.map((m) => bubble(m)), ...(pending ? [bubble(pending, true)] : []));\n }\n parts.push(list);\n }\n if (thread?.conversation?.status === \"solved\" && !pending) parts.push(el(\"p\", { class: \"ckw-fine ckw-msgr-note\" }, \"This conversation is closed. Write to start a new one.\"));\n if (body.childNodes.length !== parts.length || parts.some((x, i) => body.childNodes[i] !== x)) body.replaceChildren(...parts);\n const count = msgs.length + (pending ? 1 : 0);\n if (count !== drawn) {\n drawn = count;\n body.scrollTop = body.scrollHeight;\n }\n err.textContent = error;\n if (error && !err.isConnected) form.prepend(err);\n else if (!error) err.remove();\n if (needEmail()) {\n if (emailOk()) email.removeAttribute(\"aria-invalid\");\n else email.setAttribute(\"aria-invalid\", \"true\");\n if (!email.isConnected) form.insertBefore(email, row);\n } else email.remove();\n send.disabled = !canSend();\n };\n\n const drawTabs = () => {\n const current = typeof view === \"string\" ? view : \"help\";\n const tab = (v: MessengerView, name: string, d: string, badge = 0) => {\n const b = el(\"button\", { type: \"button\", class: \"ckw-msgr-tab\", \"aria-current\": current === v ? \"page\" : \"false\" }, icon(d, 18), el(\"span\", {}, name));\n if (badge) b.append(el(\"span\", { class: \"ckw-msgr-count ckw-msgr-count-tab\" }, String(Math.min(badge, 9))));\n b.addEventListener(\"click\", () => go(v));\n return b;\n };\n tabs.replaceChildren(tab(\"home\", \"Home\", I.home), tab(\"messages\", \"Messages\", I.chat, view === \"messages\" ? 0 : unseen.length), ...(helpOn && hasArticles !== false ? [tab(\"help\", \"Help\", I.help)] : []));\n };\n\n const draw = () => {\n if (!open) return;\n pop.dataset.view = typeof view === \"string\" ? view : \"article\";\n if (view === \"home\") drawHome();\n else if (view === \"messages\") drawMessages();\n else if (view === \"help\") drawHelp();\n else drawArticle(view.article);\n const kids: HTMLElement[] = [head, body];\n if (view === \"messages\") kids.push(form);\n kids.push(tabs);\n drawTabs();\n if (pop.childNodes.length !== kids.length || kids.some((k, i) => pop.childNodes[i] !== k)) pop.replaceChildren(...kids);\n };\n\n // ---------- Reading the chat ----------\n const tick = async () => {\n ctrl?.abort();\n ctrl = new AbortController();\n try {\n take(await api().chat(ctrl.signal));\n error = \"\";\n } catch (e) {\n if ((e as Error).name === \"AbortError\") return;\n if (open && view === \"messages\") error = (e as Error).message;\n }\n loaded = true;\n draw();\n drawFab();\n schedule();\n };\n /** The next read: often while the chat is on screen, now and then while the visitor waits for an answer. */\n function schedule(now?: number) {\n clearTimeout(poll);\n const waiting = !!thread?.messages.some((m) => m.from === \"visitor\") && thread?.conversation?.status !== \"solved\";\n const wrote = (thread?.messages ?? []).filter((m) => m.from === \"visitor\").at(-1)?.at;\n const recent = !!wrote && Date.now() - new Date(wrote).getTime() < WAITING_FOR_MS;\n const ms = now ?? (watching() ? POLL_OPEN_MS : waiting && recent ? POLL_WAITING_MS : open || waiting ? POLL_IDLE_MS : 0);\n if (ms || now === 0) poll = setTimeout(() => void tick(), ms);\n }\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") schedule(0);\n else clearTimeout(poll);\n });\n\n const submit = async () => {\n const msg = text.value.trim();\n if (!msg || pending || !emailOk()) return;\n chime.unlock();\n pending = { id: \"pending\", from: \"visitor\", body: msg, at: new Date().toISOString() };\n text.value = \"\";\n error = \"\";\n draw();\n try {\n take(await api().sendChat({ body: msg, email: needEmail() && email.value.trim() ? email.value.trim() : undefined, url: window.location.href.slice(0, 500) }));\n } catch (e) {\n text.value = msg;\n error = (e as Error).message;\n }\n pending = null;\n draw();\n schedule();\n };\n form.addEventListener(\"submit\", (e) => {\n e.preventDefault();\n void submit();\n });\n text.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey && !e.isComposing) {\n e.preventDefault();\n void submit();\n }\n });\n text.addEventListener(\"input\", () => (send.disabled = !canSend()));\n email.addEventListener(\"input\", () => draw());\n\n function show(v: MessengerView | { article: string } = \"home\") {\n open = true;\n view = v === \"help\" && !helpOn ? \"home\" : v;\n drawn = -1;\n previewGone = true;\n if (!pop.isConnected) root.appendChild(pop);\n if (articles === null || (view === \"help\" && query)) void loadArticles();\n draw();\n drawFab();\n if (view === \"messages\") {\n markSeen();\n text.focus();\n }\n schedule(0);\n }\n function close() {\n if (!open) return;\n open = false;\n pop.remove();\n drawFab();\n schedule();\n if (launcherOn) fab.focus();\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && open) close();\n };\n document.addEventListener(\"keydown\", onKey);\n\n // One read on load (the count and preview of answers not seen yet), and the article count for the Help tab.\n void tick();\n if (helpOn) void loadArticles();\n drawFab();\n\n return {\n open: (v) => show(v ?? \"home\"),\n close,\n toggle: () => (open ? close() : show()),\n destroy: () => {\n clearTimeout(poll);\n ctrl?.abort();\n document.removeEventListener(\"keydown\", onKey);\n root.remove();\n },\n };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -134,6 +134,10 @@ interface MessengerLook {
|
|
|
134
134
|
title: string;
|
|
135
135
|
greeting: string;
|
|
136
136
|
label: string;
|
|
137
|
+
/** How soon the team usually answers (MRRocket from 0.10; older servers leave it out). */
|
|
138
|
+
replyTime?: "minutes" | "hours" | "day";
|
|
139
|
+
/** A round chat button in the app (React Native) too. */
|
|
140
|
+
appLauncher?: boolean;
|
|
137
141
|
help: boolean;
|
|
138
142
|
sound: boolean;
|
|
139
143
|
preview: boolean;
|
|
@@ -391,7 +395,7 @@ interface FlowsController {
|
|
|
391
395
|
|
|
392
396
|
type VariantId = string;
|
|
393
397
|
/** This build of the SDK. Sent with the config request so MRRocket knows what the site runs (error tracking, flags). */
|
|
394
|
-
declare const SDK_VERSION = "0.
|
|
398
|
+
declare const SDK_VERSION = "0.10.0";
|
|
395
399
|
/** One variant of an experiment. `changes` replaces texts that the page marks with `<Text id>`. */
|
|
396
400
|
interface VariantConfig {
|
|
397
401
|
id: VariantId;
|
|
@@ -742,11 +746,17 @@ declare const useMessenger: () => {
|
|
|
742
746
|
toggle: () => void;
|
|
743
747
|
};
|
|
744
748
|
interface NativeMessengerOptions {
|
|
745
|
-
/** A round chat button
|
|
749
|
+
/** A round chat button (default false: open it with `useMessenger().open()` from your own button). */
|
|
746
750
|
launcher?: boolean;
|
|
751
|
+
/** Where the chat button sits (default bottom right). */
|
|
752
|
+
position?: "bottom-right" | "bottom-left";
|
|
753
|
+
/** Text beside the chat button's icon; empty: the round button. */
|
|
754
|
+
label?: string;
|
|
747
755
|
title?: string;
|
|
748
756
|
/** The big line on Home and the first line of an empty chat. */
|
|
749
757
|
greeting?: string;
|
|
758
|
+
/** How soon the team usually answers, said under "Send us a message" and in the chat's head. */
|
|
759
|
+
replyTime?: "minutes" | "hours" | "day";
|
|
750
760
|
/** Ask people the app did not identify with an email for an email (optional for them). Default true. */
|
|
751
761
|
askEmail?: boolean;
|
|
752
762
|
/** The Help tab with your published help articles (default true; hidden while there are none). */
|
|
@@ -134,6 +134,10 @@ interface MessengerLook {
|
|
|
134
134
|
title: string;
|
|
135
135
|
greeting: string;
|
|
136
136
|
label: string;
|
|
137
|
+
/** How soon the team usually answers (MRRocket from 0.10; older servers leave it out). */
|
|
138
|
+
replyTime?: "minutes" | "hours" | "day";
|
|
139
|
+
/** A round chat button in the app (React Native) too. */
|
|
140
|
+
appLauncher?: boolean;
|
|
137
141
|
help: boolean;
|
|
138
142
|
sound: boolean;
|
|
139
143
|
preview: boolean;
|
|
@@ -391,7 +395,7 @@ interface FlowsController {
|
|
|
391
395
|
|
|
392
396
|
type VariantId = string;
|
|
393
397
|
/** This build of the SDK. Sent with the config request so MRRocket knows what the site runs (error tracking, flags). */
|
|
394
|
-
declare const SDK_VERSION = "0.
|
|
398
|
+
declare const SDK_VERSION = "0.10.0";
|
|
395
399
|
/** One variant of an experiment. `changes` replaces texts that the page marks with `<Text id>`. */
|
|
396
400
|
interface VariantConfig {
|
|
397
401
|
id: VariantId;
|
|
@@ -742,11 +746,17 @@ declare const useMessenger: () => {
|
|
|
742
746
|
toggle: () => void;
|
|
743
747
|
};
|
|
744
748
|
interface NativeMessengerOptions {
|
|
745
|
-
/** A round chat button
|
|
749
|
+
/** A round chat button (default false: open it with `useMessenger().open()` from your own button). */
|
|
746
750
|
launcher?: boolean;
|
|
751
|
+
/** Where the chat button sits (default bottom right). */
|
|
752
|
+
position?: "bottom-right" | "bottom-left";
|
|
753
|
+
/** Text beside the chat button's icon; empty: the round button. */
|
|
754
|
+
label?: string;
|
|
747
755
|
title?: string;
|
|
748
756
|
/** The big line on Home and the first line of an empty chat. */
|
|
749
757
|
greeting?: string;
|
|
758
|
+
/** How soon the team usually answers, said under "Send us a message" and in the chat's head. */
|
|
759
|
+
replyTime?: "minutes" | "hours" | "day";
|
|
750
760
|
/** Ask people the app did not identify with an email for an email (optional for them). Default true. */
|
|
751
761
|
askEmail?: boolean;
|
|
752
762
|
/** The Help tab with your published help articles (default true; hidden while there are none). */
|