@morgan-and-morgan/intake-agent 1.0.0-alpha.16 → 1.0.0-alpha.17

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 CHANGED
@@ -6,6 +6,7 @@ Load the widget with a script tag, pinning an exact version:
6
6
  <script
7
7
  src="https://cdn.jsdelivr.net/npm/@morgan-and-morgan/intake-agent@<version>/dist/mm-intake-widget.js"
8
8
  data-chat-url="https://example.com/chat"
9
+ data-prompt-delay-seconds="30"
9
10
  ></script>
10
11
  ```
11
12
 
@@ -34,12 +35,22 @@ major. Every release is tagged `intake-agent-vx.y.z`.
34
35
  | --- | --- | --- |
35
36
  | `data-chat-url` | Release environment URL | Chat iframe target |
36
37
  | `data-auto-open` | `false` | Open the chat immediately after mount |
38
+ | `data-prompt-delay-seconds` | `30` | Seconds after mount before showing the consultation modal |
39
+
40
+ Set the delay on the script tag before it loads. Non-negative numbers are
41
+ accepted, including fractions; `0` shows the modal immediately. Missing, empty,
42
+ invalid, negative, or overflowing values (above 2147483.647 seconds) use 30 seconds.
43
+ The value is read locally and adds no configuration request. Changing the
44
+ attribute after the script loads does not reschedule the modal. Existing popup
45
+ suppression and dismissal cooldowns still apply.
37
46
 
38
47
  The consultation modal reads `window.drupalSettings.mxPopup`, falling back to
39
48
  `window.mxChatbotSettings.mxPopup` when the Drupal field is absent. Only the
40
49
  boolean `false` suppresses the modal, including calls to `showPrompt()`.
41
50
  Missing settings preserve the usual display rules. Settings are read when the
42
- modal is about to appear; the launcher and chat remain available.
51
+ modal is about to appear; the launcher and chat remain available. Set suppression
52
+ before loading the embed when using a zero-second delay, so the first display
53
+ check sees the intended setting.
43
54
 
44
55
  ## Consultation prompt design
45
56
 
@@ -1,5 +1,17 @@
1
1
  (function() {
2
2
  "use strict";
3
+ const DEFAULT_PROMPT_DELAY_MS = 3e4;
4
+ const MAX_PROMPT_DELAY_MS = 2147483647;
5
+ const readPromptDelayMs = (seconds) => {
6
+ if (seconds === void 0 || seconds.trim() === "") {
7
+ return DEFAULT_PROMPT_DELAY_MS;
8
+ }
9
+ const delayMs = Number(seconds) * 1e3;
10
+ if (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > MAX_PROMPT_DELAY_MS) {
11
+ return DEFAULT_PROMPT_DELAY_MS;
12
+ }
13
+ return delayMs;
14
+ };
3
15
  const readLoaderConfig = (script, baseUri) => {
4
16
  var _a;
5
17
  const scriptUrl = new URL(script.src, baseUri);
@@ -9,7 +21,8 @@
9
21
  assetBaseUrl: new URL(".", scriptUrl).href,
10
22
  autoOpen: script.dataset.autoOpen === "true",
11
23
  chatOrigin: new URL(chatUrl).origin,
12
- chatUrl
24
+ chatUrl,
25
+ promptDelayMs: readPromptDelayMs(script.dataset.promptDelaySeconds)
13
26
  };
14
27
  };
15
28
  const ATTRIBUTION_FIELD_MAX_LENGTH = {
@@ -438,7 +451,6 @@
438
451
  };
439
452
  };
440
453
  const PANEL_ANIMATION_MS = 180;
441
- const PROMPT_DELAY_MS = 5e3;
442
454
  const PROMPT_COOLDOWN_MS = 24 * 60 * 60 * 1e3;
443
455
  const PROMPT_COOLDOWN_KEY = "mm-intake-widget-prompt-dismissed-at";
444
456
  const PROMPT_SESSION_KEY = "mm-intake-widget-prompt-dismissed";
@@ -480,12 +492,13 @@
480
492
  }
481
493
  };
482
494
  const mountIntakeWidget = (config, onDestroy) => {
495
+ var _a;
483
496
  const mount = document.createElement("div");
484
497
  mount.dataset.mmIntakeWidget = "";
485
498
  const shadow = mount.attachShadow({ mode: "open" });
486
499
  const assetUrl = (fileName) => {
487
- var _a;
488
- return new URL(fileName, (_a = config.assetBaseUrl) != null ? _a : `${config.chatOrigin}/intake-widget/`).href;
500
+ var _a2;
501
+ return new URL(fileName, (_a2 = config.assetBaseUrl) != null ? _a2 : `${config.chatOrigin}/intake-widget/`).href;
489
502
  };
490
503
  const elements = renderWidgetShell(shadow, assetUrl);
491
504
  document.body.append(mount);
@@ -511,8 +524,8 @@
511
524
  elements.launcher.setAttribute("aria-label", isOpen ? "Close intake chat" : "Open intake chat");
512
525
  };
513
526
  const postToChat = (message) => {
514
- var _a;
515
- (_a = elements.chatFrame.contentWindow) == null ? void 0 : _a.postMessage(message, config.chatOrigin);
527
+ var _a2;
528
+ (_a2 = elements.chatFrame.contentWindow) == null ? void 0 : _a2.postMessage(message, config.chatOrigin);
516
529
  };
517
530
  const postHostReady = () => {
518
531
  const currentUrl = globalThis.location.href;
@@ -540,10 +553,10 @@
540
553
  postToChat(createEmbedProtocolMessage(EMBED_MESSAGE_TYPE.FOCUS_COMPOSER));
541
554
  };
542
555
  const answerAuthTokenRequest = async () => {
543
- var _a;
556
+ var _a2;
544
557
  let token;
545
558
  try {
546
- token = await ((_a = config.getAuthToken) == null ? void 0 : _a.call(config));
559
+ token = await ((_a2 = config.getAuthToken) == null ? void 0 : _a2.call(config));
547
560
  } catch {
548
561
  token = void 0;
549
562
  }
@@ -575,11 +588,11 @@
575
588
  }
576
589
  };
577
590
  const showPrompt = () => {
578
- var _a, _b, _c;
591
+ var _a2, _b, _c;
579
592
  globalThis.clearTimeout(promptTimer);
580
593
  promptTimer = void 0;
581
594
  const host = globalThis;
582
- const mxPopup = (_c = (_a = host.drupalSettings) == null ? void 0 : _a.mxPopup) != null ? _c : (_b = host.mxChatbotSettings) == null ? void 0 : _b.mxPopup;
595
+ const mxPopup = (_c = (_a2 = host.drupalSettings) == null ? void 0 : _a2.mxPopup) != null ? _c : (_b = host.mxChatbotSettings) == null ? void 0 : _b.mxPopup;
583
596
  if (mxPopup === false || hasPromptCooldown() || elements.chatDialog.dataset.state === "open") {
584
597
  return;
585
598
  }
@@ -641,7 +654,7 @@
641
654
  }
642
655
  };
643
656
  const restoreHostChrome = () => {
644
- var _a, _b;
657
+ var _a2, _b;
645
658
  if (themeColorBackup === null) {
646
659
  return;
647
660
  }
@@ -652,7 +665,7 @@
652
665
  createdThemeColor = null;
653
666
  themeColorBackup = null;
654
667
  for (const [index, root] of hostRoots.entries()) {
655
- root.style.backgroundColor = (_a = hostBackgroundColorBackup == null ? void 0 : hostBackgroundColorBackup[index]) != null ? _a : "";
668
+ root.style.backgroundColor = (_a2 = hostBackgroundColorBackup == null ? void 0 : hostBackgroundColorBackup[index]) != null ? _a2 : "";
656
669
  root.style.overflow = (_b = hostOverflowBackup == null ? void 0 : hostOverflowBackup[index]) != null ? _b : "";
657
670
  }
658
671
  hostBackgroundColorBackup = null;
@@ -678,16 +691,16 @@
678
691
  syncHostChrome();
679
692
  }
680
693
  const startViewportTracking = () => {
681
- var _a, _b;
682
- (_a = globalThis.visualViewport) == null ? void 0 : _a.addEventListener("resize", syncViewport);
694
+ var _a2, _b;
695
+ (_a2 = globalThis.visualViewport) == null ? void 0 : _a2.addEventListener("resize", syncViewport);
683
696
  (_b = globalThis.visualViewport) == null ? void 0 : _b.addEventListener("scroll", syncViewport);
684
697
  fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.addEventListener("change", syncHostChrome);
685
698
  syncViewport();
686
699
  syncHostChrome();
687
700
  };
688
701
  const stopViewportTracking = () => {
689
- var _a, _b;
690
- (_a = globalThis.visualViewport) == null ? void 0 : _a.removeEventListener("resize", syncViewport);
702
+ var _a2, _b;
703
+ (_a2 = globalThis.visualViewport) == null ? void 0 : _a2.removeEventListener("resize", syncViewport);
691
704
  (_b = globalThis.visualViewport) == null ? void 0 : _b.removeEventListener("scroll", syncViewport);
692
705
  fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.removeEventListener("change", syncHostChrome);
693
706
  setKeyboardOpen(false);
@@ -724,7 +737,7 @@
724
737
  }
725
738
  };
726
739
  const closeChat = () => {
727
- var _a;
740
+ var _a2;
728
741
  elements.launcher.focus();
729
742
  writeOpenState(false);
730
743
  const wasOpen = elements.chatDialog.dataset.state === "open";
@@ -737,7 +750,7 @@
737
750
  if (!wasOpen) {
738
751
  return;
739
752
  }
740
- if (((_a = matchMediaQuery("(prefers-reduced-motion: reduce)")) == null ? void 0 : _a.matches) === true) {
753
+ if (((_a2 = matchMediaQuery("(prefers-reduced-motion: reduce)")) == null ? void 0 : _a2.matches) === true) {
741
754
  finishChatClose();
742
755
  return;
743
756
  }
@@ -854,7 +867,7 @@
854
867
  if (returnedFromSigning || readOpenState()) {
855
868
  openChat();
856
869
  } else if (!hasPromptCooldown()) {
857
- promptTimer = globalThis.setTimeout(showPrompt, PROMPT_DELAY_MS);
870
+ promptTimer = globalThis.setTimeout(showPrompt, (_a = config.promptDelayMs) != null ? _a : DEFAULT_PROMPT_DELAY_MS);
858
871
  }
859
872
  return Object.freeze({
860
873
  close: closeChat,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morgan-and-morgan/intake-agent",
3
- "version": "1.0.0-alpha.16",
3
+ "version": "1.0.0-alpha.17",
4
4
  "description": "Embeddable chat widget loader.",
5
5
  "license": "UNLICENSED",
6
6
  "files": [