@morgan-and-morgan/intake-agent 1.2.0 → 1.4.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/README.md +5 -1
- package/dist/button-text-us.png +0 -0
- package/dist/consultation-prompt.webp +0 -0
- package/dist/mm-intake-widget.js +159 -14
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -21,6 +21,10 @@ placeholder, don't bump it by hand.
|
|
|
21
21
|
| `release/**` | `x.y.z-beta.N` | `beta` |
|
|
22
22
|
| `main` | `x.y.z` | `latest` |
|
|
23
23
|
|
|
24
|
+
Each bundle also carries its matching chat environment: development for
|
|
25
|
+
`alpha`, UAT for `beta`, and production for `latest`. `data-chat-url` remains
|
|
26
|
+
an explicit override.
|
|
27
|
+
|
|
24
28
|
`fix:` bumps the patch, `feat:` the minor, a `BREAKING CHANGE:` footer the
|
|
25
29
|
major. Every release is tagged `intake-agent-vx.y.z`.
|
|
26
30
|
|
|
@@ -28,5 +32,5 @@ major. Every release is tagged `intake-agent-vx.y.z`.
|
|
|
28
32
|
|
|
29
33
|
| Attribute | Default | Purpose |
|
|
30
34
|
| --- | --- | --- |
|
|
31
|
-
| `data-chat-url` |
|
|
35
|
+
| `data-chat-url` | Release environment URL | Chat iframe target |
|
|
32
36
|
| `data-auto-open` | `false` | Open the chat immediately after mount |
|
|
Binary file
|
|
Binary file
|
package/dist/mm-intake-widget.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
"use strict";
|
|
3
|
-
const DEFAULT_CHAT_PATH = "/embed/intake";
|
|
4
3
|
const readLoaderConfig = (script, baseUri) => {
|
|
5
4
|
var _a;
|
|
6
5
|
const scriptUrl = new URL(script.src, baseUri);
|
|
7
|
-
const
|
|
6
|
+
const bundledChatUrl = "https://chat.mx2.law/embed/intake";
|
|
7
|
+
const chatUrl = new URL((_a = script.dataset.chatUrl) != null ? _a : bundledChatUrl, scriptUrl).href;
|
|
8
8
|
return {
|
|
9
|
+
assetBaseUrl: new URL(".", scriptUrl).href,
|
|
9
10
|
autoOpen: script.dataset.autoOpen === "true",
|
|
10
11
|
chatOrigin: new URL(chatUrl).origin,
|
|
11
12
|
chatUrl
|
|
@@ -36,10 +37,10 @@
|
|
|
36
37
|
}
|
|
37
38
|
return Object.keys(sanitized).length === 0 ? null : sanitized;
|
|
38
39
|
};
|
|
39
|
-
const
|
|
40
|
-
const
|
|
40
|
+
const LANDING_PAGE_COOKIES = ["trackedLandingPage", "tracked_landing_page"];
|
|
41
|
+
const LANDING_TIMESTAMP_COOKIES = ["trackedLandingPageTimestamp", "tracked_landing_timestamp"];
|
|
41
42
|
const readTimestampCookie = (cookie) => {
|
|
42
|
-
const raw =
|
|
43
|
+
const raw = readFirstCookie(cookie, LANDING_TIMESTAMP_COOKIES);
|
|
43
44
|
return raw === void 0 ? void 0 : decodeCookieValue(raw);
|
|
44
45
|
};
|
|
45
46
|
const readCookie = (cookie, name) => {
|
|
@@ -47,6 +48,15 @@
|
|
|
47
48
|
const raw = (_a = cookie.split(";").map((entry) => entry.trim()).find((entry) => entry.startsWith(`${name}=`))) == null ? void 0 : _a.slice(name.length + 1);
|
|
48
49
|
return raw === void 0 || raw === "" ? void 0 : raw;
|
|
49
50
|
};
|
|
51
|
+
const readFirstCookie = (cookie, names) => {
|
|
52
|
+
for (const name of names) {
|
|
53
|
+
const raw = readCookie(cookie, name);
|
|
54
|
+
if (raw !== void 0) {
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return void 0;
|
|
59
|
+
};
|
|
50
60
|
const decodeCookieValue = (raw) => {
|
|
51
61
|
try {
|
|
52
62
|
return decodeURIComponent(raw);
|
|
@@ -62,7 +72,7 @@
|
|
|
62
72
|
}
|
|
63
73
|
};
|
|
64
74
|
const readLandingPage = (cookie) => {
|
|
65
|
-
const raw =
|
|
75
|
+
const raw = readFirstCookie(cookie, LANDING_PAGE_COOKIES);
|
|
66
76
|
if (raw === void 0 || parseUrl(raw) !== null) {
|
|
67
77
|
return raw;
|
|
68
78
|
}
|
|
@@ -115,6 +125,9 @@
|
|
|
115
125
|
const EMBED_MESSAGE_TYPE = Object.freeze({
|
|
116
126
|
HOST_READY: "mm:intake:host-ready",
|
|
117
127
|
CHILD_READY: "mm:intake:child-ready",
|
|
128
|
+
// Host asks the embedded chat to put the caret in its composer. Kept
|
|
129
|
+
// separate from HOST_READY so signing-card handshakes never steal focus.
|
|
130
|
+
FOCUS_COMPOSER: "mm:intake:focus-composer",
|
|
118
131
|
SIGNING_REQUESTED: "mm:intake:signing-requested",
|
|
119
132
|
SIGNING_RECORDED: "mm:intake:signing-recorded",
|
|
120
133
|
// Chat asks the host page for a signed-in token; the host answers with
|
|
@@ -210,10 +223,10 @@
|
|
|
210
223
|
"circle-check": '<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',
|
|
211
224
|
"chevron-down": '<path d="m6 9 6 6 6-6"/>'
|
|
212
225
|
};
|
|
213
|
-
const BUTTON_TEXT_US = "data:image/png;base64,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";
|
|
214
226
|
const FULL_PAGE_PANEL_QUERY = "(max-width:600px),(max-height:500px)";
|
|
215
227
|
const lucideIcon = (name, className, strokeWidth = 2) => `<svg class="${className}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${String(strokeWidth)}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${LUCIDE_ICON_PATHS[name]}</svg>`;
|
|
216
228
|
const OPEN_CLOSE_ICON = lucideIcon("x", "mm-icon mm-icon-close");
|
|
229
|
+
const PROMPT_CLOSE_ICON = lucideIcon("x", "mm-prompt-close-icon", 2.5);
|
|
217
230
|
const WIDGET_STYLES = [
|
|
218
231
|
':host{all:initial;color-scheme:light;--mm-yellow:#fdeb01;--mm-yellow-hover:#f5de00;--mm-yellow-pressed:#e6cc00;--mm-blue:#115099;--mm-blue-hover:#0b3568;--mm-ink:#111;--mm-white:#fff;--mm-surface-blue:#f3f8ff;--mm-chrome:#e8eef2;--mm-line:#e2e8f0;--mm-muted:#545454;--mm-green:#0f9d58;--mm-font:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}',
|
|
219
232
|
"*,*::before,*::after{box-sizing:border-box}",
|
|
@@ -222,6 +235,8 @@
|
|
|
222
235
|
"@keyframes mm-close-in{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}",
|
|
223
236
|
"@keyframes mm-panel-in{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}",
|
|
224
237
|
"@keyframes mm-panel-out{from{opacity:1;transform:none}to{opacity:0;transform:translateY(10px) scale(.98)}}",
|
|
238
|
+
"@keyframes mm-prompt-backdrop-in{from{opacity:0}to{opacity:1}}",
|
|
239
|
+
"@keyframes mm-prompt-card-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}",
|
|
225
240
|
"@keyframes mm-dot{0%,100%{opacity:.4;transform:scale(1)}50%{opacity:1;transform:scale(1.2)}}",
|
|
226
241
|
// Closed: LivePerson TEXT US sticky under the chat layer. Open: swap for a
|
|
227
242
|
// blue X disc above the chat so there is always a clear close control.
|
|
@@ -254,15 +269,31 @@
|
|
|
254
269
|
".mm-dot{width:8px;height:8px;border-radius:999px;background:var(--mm-muted);animation:mm-dot 1.2s ease-in-out infinite}",
|
|
255
270
|
".mm-dot:nth-child(2){animation-delay:.15s}",
|
|
256
271
|
".mm-dot:nth-child(3){animation-delay:.3s}",
|
|
272
|
+
".mm-prompt-backdrop{position:fixed;inset:0;z-index:2147483002;display:grid;place-items:center;padding:16px;overscroll-behavior:contain;touch-action:none;background:rgba(0,0,0,.64);animation:mm-prompt-backdrop-in .25s cubic-bezier(.23,1,.32,1) both;font-family:var(--mm-font)}",
|
|
273
|
+
".mm-prompt-card{position:relative;width:min(632px,calc(100vw - 32px),calc((100vh - 32px)*1.26148));aspect-ratio:632/501;animation:mm-prompt-card-in .25s cubic-bezier(.23,1,.32,1) both}",
|
|
274
|
+
".mm-prompt-image{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none}",
|
|
275
|
+
".mm-prompt-open,.mm-prompt-close{position:absolute;border:0;outline:none;background:transparent;cursor:pointer}",
|
|
276
|
+
".mm-prompt-open{inset:0;border-radius:24px}",
|
|
277
|
+
".mm-prompt-close{top:4.5%;right:3.1%;z-index:1;display:grid;place-items:center;width:44px;height:44px;border-radius:999px;color:var(--mm-white)}",
|
|
278
|
+
'.mm-prompt-close::before{content:"";position:absolute;width:28px;height:28px;border-radius:999px;background:#050505;box-shadow:0 1px 4px rgba(0,0,0,.35);transition:background-color .12s ease}',
|
|
279
|
+
".mm-prompt-close-icon{position:relative;display:block;width:16px;height:16px;pointer-events:none}",
|
|
280
|
+
".mm-prompt-close:hover::before{background:#252525}",
|
|
281
|
+
".mm-prompt-open:focus-visible{outline:3px solid var(--mm-yellow);outline-offset:-8px}",
|
|
282
|
+
".mm-prompt-close:focus-visible{outline:none}",
|
|
283
|
+
".mm-prompt-close:focus-visible::before{background:#050505;box-shadow:inset 0 0 0 2px var(--mm-yellow),0 1px 4px rgba(0,0,0,.35)}",
|
|
257
284
|
"[hidden]{display:none!important}",
|
|
258
285
|
`@media ${FULL_PAGE_PANEL_QUERY}{.mm-launcher[aria-expanded="true"]{top:calc(var(--mm-viewport-top,0px) + 10px);right:10px;bottom:auto;width:44px;height:44px}.mm-chat{left:0;right:0;top:var(--mm-viewport-top,auto);bottom:0;width:auto;height:var(--mm-viewport-height,100dvh);min-height:0;border:0;border-radius:0;box-shadow:0 calc(100lvh - 100svh) 0 var(--mm-panel-bottom,var(--mm-chrome))}}`,
|
|
259
|
-
"@media(
|
|
286
|
+
"@media(forced-colors:active){.mm-prompt-close:focus-visible{outline:2px solid ButtonText;outline-offset:-9px}}",
|
|
287
|
+
"@media(prefers-reduced-motion:reduce){.mm-launcher,.mm-chat{animation:none;transition:none}.mm-prompt-card{animation-name:mm-prompt-backdrop-in}.mm-dot{animation:none}}"
|
|
260
288
|
].join("");
|
|
261
|
-
const
|
|
289
|
+
const widgetMarkup = (launcherImageUrl, promptImageUrl) => [
|
|
262
290
|
`<style>${WIDGET_STYLES}</style>`,
|
|
263
|
-
`<button class="mm-launcher" type="button" aria-label="Open intake chat" aria-expanded="false" draggable="false"><img class="mm-text-us" src="${
|
|
291
|
+
`<button class="mm-launcher" type="button" aria-label="Open intake chat" aria-expanded="false" draggable="false"><img class="mm-text-us" src="${launcherImageUrl}" alt="" width="38" height="147" decoding="async" />${OPEN_CLOSE_ICON}</button>`,
|
|
264
292
|
'<section class="mm-chat" role="dialog" aria-label="Morgan and Morgan intake chat" inert hidden>',
|
|
265
293
|
'<div class="mm-frame-wrap"><div class="mm-loading" role="status" aria-label="Loading secure chat"><span class="mm-dot"></span><span class="mm-dot"></span><span class="mm-dot"></span></div><iframe class="mm-frame mm-chat-frame" title="Morgan and Morgan intake chat" referrerpolicy="strict-origin-when-cross-origin"></iframe></div>',
|
|
294
|
+
"</section>",
|
|
295
|
+
'<section class="mm-prompt-backdrop" role="dialog" aria-modal="true" aria-label="Start your free consultation" inert hidden>',
|
|
296
|
+
`<div class="mm-prompt-card"><img class="mm-prompt-image" src="${promptImageUrl}" alt="Our team is available 24/7. Chat with a real person. Click to start your free consultation." width="632" height="501" decoding="async" /><button class="mm-prompt-open" type="button" aria-label="Message us about a free consultation"></button><button class="mm-prompt-close" type="button" aria-label="Dismiss consultation prompt">${PROMPT_CLOSE_ICON}</button></div>`,
|
|
266
297
|
"</section>"
|
|
267
298
|
].join("");
|
|
268
299
|
const requireElement = (shadow, selector) => {
|
|
@@ -272,16 +303,23 @@
|
|
|
272
303
|
}
|
|
273
304
|
return element;
|
|
274
305
|
};
|
|
275
|
-
const renderWidgetShell = (shadow) => {
|
|
276
|
-
shadow.innerHTML =
|
|
306
|
+
const renderWidgetShell = (shadow, launcherImageUrl, promptImageUrl) => {
|
|
307
|
+
shadow.innerHTML = widgetMarkup(launcherImageUrl, promptImageUrl);
|
|
277
308
|
return {
|
|
278
309
|
chatDialog: requireElement(shadow, ".mm-chat"),
|
|
279
310
|
chatFrame: requireElement(shadow, ".mm-chat-frame"),
|
|
280
311
|
chatLoading: requireElement(shadow, ".mm-loading"),
|
|
281
|
-
launcher: requireElement(shadow, ".mm-launcher")
|
|
312
|
+
launcher: requireElement(shadow, ".mm-launcher"),
|
|
313
|
+
promptBackdrop: requireElement(shadow, ".mm-prompt-backdrop"),
|
|
314
|
+
promptClose: requireElement(shadow, ".mm-prompt-close"),
|
|
315
|
+
promptOpen: requireElement(shadow, ".mm-prompt-open")
|
|
282
316
|
};
|
|
283
317
|
};
|
|
284
318
|
const PANEL_ANIMATION_MS = 180;
|
|
319
|
+
const PROMPT_DELAY_MS = 6e4;
|
|
320
|
+
const PROMPT_COOLDOWN_MS = 24 * 60 * 60 * 1e3;
|
|
321
|
+
const PROMPT_COOLDOWN_KEY = "mm-intake-widget-prompt-dismissed-at";
|
|
322
|
+
const PROMPT_SESSION_KEY = "mm-intake-widget-prompt-dismissed";
|
|
285
323
|
const CHAT_CHROME_COLOR = "#e8eef2";
|
|
286
324
|
const KEYBOARD_MIN_SHRINK_PX = 100;
|
|
287
325
|
const CHAT_READY_FALLBACK_MS = 4e3;
|
|
@@ -291,12 +329,58 @@
|
|
|
291
329
|
globalThis.history.replaceState(globalThis.history.state, "", cleanedReturnUrl);
|
|
292
330
|
}
|
|
293
331
|
};
|
|
332
|
+
const hasPromptCooldown = () => {
|
|
333
|
+
try {
|
|
334
|
+
if (globalThis.sessionStorage.getItem(PROMPT_SESSION_KEY) === "true") {
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
} catch {
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const dismissedAt = Number(globalThis.localStorage.getItem(PROMPT_COOLDOWN_KEY));
|
|
341
|
+
return Number.isFinite(dismissedAt) && dismissedAt > 0 && Date.now() - dismissedAt < PROMPT_COOLDOWN_MS;
|
|
342
|
+
} catch {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const rememberPromptDismissal = () => {
|
|
347
|
+
try {
|
|
348
|
+
globalThis.sessionStorage.setItem(PROMPT_SESSION_KEY, "true");
|
|
349
|
+
} catch {
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
globalThis.localStorage.setItem(PROMPT_COOLDOWN_KEY, String(Date.now()));
|
|
353
|
+
} catch {
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
const playPromptSound = async () => {
|
|
357
|
+
try {
|
|
358
|
+
const context = new AudioContext();
|
|
359
|
+
const oscillator = context.createOscillator();
|
|
360
|
+
const gain = context.createGain();
|
|
361
|
+
oscillator.frequency.setValueAtTime(660, context.currentTime);
|
|
362
|
+
oscillator.frequency.exponentialRampToValueAtTime(880, context.currentTime + 0.16);
|
|
363
|
+
gain.gain.setValueAtTime(0.08, context.currentTime);
|
|
364
|
+
gain.gain.exponentialRampToValueAtTime(1e-3, context.currentTime + 0.2);
|
|
365
|
+
oscillator.connect(gain);
|
|
366
|
+
gain.connect(context.destination);
|
|
367
|
+
oscillator.start();
|
|
368
|
+
oscillator.stop(context.currentTime + 0.2);
|
|
369
|
+
oscillator.addEventListener("ended", () => void context.close());
|
|
370
|
+
await context.resume();
|
|
371
|
+
} catch {
|
|
372
|
+
}
|
|
373
|
+
};
|
|
294
374
|
const mountIntakeWidget = (config, onDestroy) => {
|
|
295
375
|
var _a;
|
|
296
376
|
const mount = document.createElement("div");
|
|
297
377
|
mount.dataset.mmIntakeWidget = "";
|
|
298
378
|
const shadow = mount.attachShadow({ mode: "open" });
|
|
299
|
-
const
|
|
379
|
+
const assetUrl = (fileName) => {
|
|
380
|
+
var _a2;
|
|
381
|
+
return new URL(fileName, (_a2 = config.assetBaseUrl) != null ? _a2 : `${config.chatOrigin}/intake-widget/`).href;
|
|
382
|
+
};
|
|
383
|
+
const elements = renderWidgetShell(shadow, assetUrl("button-text-us.png"), assetUrl("consultation-prompt.webp"));
|
|
300
384
|
document.body.append(mount);
|
|
301
385
|
if (typeof mount.showPopover === "function") {
|
|
302
386
|
mount.setAttribute("popover", "manual");
|
|
@@ -310,6 +394,8 @@
|
|
|
310
394
|
let chatHasLoaded = false;
|
|
311
395
|
let chatCloseTimer;
|
|
312
396
|
let chatReadyTimer;
|
|
397
|
+
let promptTimer;
|
|
398
|
+
let promptReturnFocus = null;
|
|
313
399
|
let isKeyboardOpen = false;
|
|
314
400
|
let hasReleasedKeyboardEarly = false;
|
|
315
401
|
const syncLauncherLabel = () => {
|
|
@@ -343,6 +429,9 @@
|
|
|
343
429
|
})
|
|
344
430
|
);
|
|
345
431
|
};
|
|
432
|
+
const focusChatComposer = () => {
|
|
433
|
+
postToChat(createEmbedProtocolMessage(EMBED_MESSAGE_TYPE.FOCUS_COMPOSER));
|
|
434
|
+
};
|
|
346
435
|
const answerAuthTokenRequest = async () => {
|
|
347
436
|
var _a2;
|
|
348
437
|
let token;
|
|
@@ -365,6 +454,31 @@
|
|
|
365
454
|
chatReadyTimer = void 0;
|
|
366
455
|
elements.chatLoading.hidden = true;
|
|
367
456
|
};
|
|
457
|
+
const dismissPrompt = (returnFocus = false) => {
|
|
458
|
+
globalThis.clearTimeout(promptTimer);
|
|
459
|
+
promptTimer = void 0;
|
|
460
|
+
const wasVisible = !elements.promptBackdrop.hidden;
|
|
461
|
+
elements.promptBackdrop.hidden = true;
|
|
462
|
+
elements.promptBackdrop.setAttribute("inert", "");
|
|
463
|
+
rememberPromptDismissal();
|
|
464
|
+
if (returnFocus && wasVisible) {
|
|
465
|
+
const focusTarget = (promptReturnFocus == null ? void 0 : promptReturnFocus.isConnected) === true ? promptReturnFocus : elements.launcher;
|
|
466
|
+
promptReturnFocus = null;
|
|
467
|
+
focusTarget.focus();
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
const showPrompt = () => {
|
|
471
|
+
globalThis.clearTimeout(promptTimer);
|
|
472
|
+
promptTimer = void 0;
|
|
473
|
+
if (hasPromptCooldown() || elements.chatDialog.dataset.state === "open") {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
promptReturnFocus = document.activeElement instanceof HTMLElement && document.activeElement !== mount ? document.activeElement : null;
|
|
477
|
+
elements.promptBackdrop.hidden = false;
|
|
478
|
+
elements.promptBackdrop.removeAttribute("inert");
|
|
479
|
+
elements.promptClose.focus();
|
|
480
|
+
void playPromptSound();
|
|
481
|
+
};
|
|
368
482
|
const syncViewport = () => {
|
|
369
483
|
const viewport = globalThis.visualViewport;
|
|
370
484
|
if (!viewport || viewport.height === 0) {
|
|
@@ -483,6 +597,7 @@
|
|
|
483
597
|
stopViewportTracking();
|
|
484
598
|
};
|
|
485
599
|
const openChat = () => {
|
|
600
|
+
dismissPrompt();
|
|
486
601
|
globalThis.clearTimeout(chatCloseTimer);
|
|
487
602
|
chatCloseTimer = void 0;
|
|
488
603
|
elements.chatDialog.hidden = false;
|
|
@@ -496,6 +611,7 @@
|
|
|
496
611
|
writeOpenState(true);
|
|
497
612
|
if (chatHasLoaded) {
|
|
498
613
|
postHostReady();
|
|
614
|
+
focusChatComposer();
|
|
499
615
|
}
|
|
500
616
|
};
|
|
501
617
|
const closeChat = () => {
|
|
@@ -531,6 +647,9 @@
|
|
|
531
647
|
if (isEmbedProtocolMessage(message, EMBED_MESSAGE_TYPE.CHILD_READY)) {
|
|
532
648
|
revealChat();
|
|
533
649
|
postHostReady();
|
|
650
|
+
if (elements.chatDialog.dataset.state === "open") {
|
|
651
|
+
focusChatComposer();
|
|
652
|
+
}
|
|
534
653
|
return;
|
|
535
654
|
}
|
|
536
655
|
if (isEmbedProtocolMessage(message, EMBED_MESSAGE_TYPE.AUTH_TOKEN_REQUEST)) {
|
|
@@ -558,9 +677,24 @@
|
|
|
558
677
|
}
|
|
559
678
|
};
|
|
560
679
|
const handleKeydown = (event) => {
|
|
680
|
+
if (event.key === "Tab" && !elements.promptBackdrop.hidden) {
|
|
681
|
+
const { activeElement } = shadow;
|
|
682
|
+
if (!event.shiftKey && activeElement === elements.promptClose) {
|
|
683
|
+
event.preventDefault();
|
|
684
|
+
elements.promptOpen.focus();
|
|
685
|
+
} else if (event.shiftKey && activeElement === elements.promptOpen) {
|
|
686
|
+
event.preventDefault();
|
|
687
|
+
elements.promptClose.focus();
|
|
688
|
+
}
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
561
691
|
if (event.key !== "Escape") {
|
|
562
692
|
return;
|
|
563
693
|
}
|
|
694
|
+
if (!elements.promptBackdrop.hidden) {
|
|
695
|
+
dismissPrompt(true);
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
564
698
|
if (elements.chatDialog.dataset.state === "open") {
|
|
565
699
|
closeChat();
|
|
566
700
|
}
|
|
@@ -569,6 +703,7 @@
|
|
|
569
703
|
stopViewportTracking();
|
|
570
704
|
globalThis.clearTimeout(chatCloseTimer);
|
|
571
705
|
globalThis.clearTimeout(chatReadyTimer);
|
|
706
|
+
globalThis.clearTimeout(promptTimer);
|
|
572
707
|
globalThis.removeEventListener("message", handleMessage);
|
|
573
708
|
document.removeEventListener("keydown", handleKeydown);
|
|
574
709
|
mount.remove();
|
|
@@ -581,6 +716,13 @@
|
|
|
581
716
|
openChat();
|
|
582
717
|
}
|
|
583
718
|
});
|
|
719
|
+
elements.promptOpen.addEventListener("click", openChat);
|
|
720
|
+
elements.promptClose.addEventListener("click", () => dismissPrompt(true));
|
|
721
|
+
elements.promptBackdrop.addEventListener("click", (event) => {
|
|
722
|
+
if (event.target === elements.promptBackdrop) {
|
|
723
|
+
dismissPrompt(true);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
584
726
|
elements.chatDialog.addEventListener("animationend", (event) => {
|
|
585
727
|
if (event.target === elements.chatDialog) {
|
|
586
728
|
finishChatClose();
|
|
@@ -597,11 +739,14 @@
|
|
|
597
739
|
syncLauncherLabel();
|
|
598
740
|
if (returnedFromSigning || readOpenState()) {
|
|
599
741
|
openChat();
|
|
742
|
+
} else if (!hasPromptCooldown()) {
|
|
743
|
+
promptTimer = globalThis.setTimeout(showPrompt, PROMPT_DELAY_MS);
|
|
600
744
|
}
|
|
601
745
|
return Object.freeze({
|
|
602
746
|
close: closeChat,
|
|
603
747
|
destroy,
|
|
604
748
|
open: openChat,
|
|
749
|
+
showPrompt,
|
|
605
750
|
version: EMBED_PROTOCOL_VERSION
|
|
606
751
|
});
|
|
607
752
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morgan-and-morgan/intake-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Embeddable chat widget loader.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"files": [
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"build": "pnpm run build:bundle",
|
|
24
24
|
"build:bundle": "node scripts/generate-icons.mjs && vite build",
|
|
25
25
|
"generate:icons": "node scripts/generate-icons.mjs",
|
|
26
|
+
"test": "node --test src/release-config.test.mjs",
|
|
26
27
|
"typecheck": "tsc --noEmit",
|
|
27
28
|
"lint": "eslint \"src/**/*.ts\" --quiet",
|
|
28
29
|
"lint:fix": "eslint \"src/**/*.ts\" --quiet --fix",
|