@xapp/chat-widget 1.63.1 → 1.65.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/dist/index.js CHANGED
@@ -12,14 +12,15 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
12
12
  var React__default$1 = /*#__PURE__*/_interopDefaultLegacy(React$1);
13
13
  var thunk__default = /*#__PURE__*/_interopDefaultLegacy(thunk);
14
14
 
15
- var ActionButton = function (props) {
15
+ var ActionButton = function (_a) {
16
+ var label = _a.label, disable = _a.disable, type = _a.type, addClass = _a.addClass, onClick = _a.onClick;
16
17
  function handleClick(ev) {
17
18
  ev.stopPropagation();
18
- if (props.onClick) {
19
- props.onClick(props.label);
19
+ if (onClick) {
20
+ onClick(label);
20
21
  }
21
22
  }
22
- return (React__default$1["default"].createElement("button", { type: props.type, className: "action-button ".concat(props.addClass), onClick: handleClick }, props.label));
23
+ return (React__default$1["default"].createElement("button", { disabled: disable, type: type, className: "action-button ".concat(addClass), onClick: handleClick }, label));
23
24
  };
24
25
 
25
26
  var defaultServerUrl = "";
@@ -678,40 +679,45 @@ var CtaBubble = function (props) {
678
679
  };
679
680
 
680
681
  var CtaBubbleContainer = function (props) {
681
- var visible = props.visible, timeout = props.timeout, delay = props.delay, animate = props.animate, buttonAnimation = props.buttonAnimation, onClick = props.onClick;
682
+ var visible = props.visible, timeout = props.timeout, delay = props.delay, animate = props.animate, buttonAnimation = props.buttonAnimation, onClick = props.onClick, children = props.children;
682
683
  var startTime = React$1.useMemo(function () {
683
- if (visible) {
684
- return new Date().valueOf();
685
- }
686
- return undefined;
684
+ return visible ? new Date().valueOf() : undefined;
687
685
  }, [visible]);
688
686
  var _a = React$1.useState(false), showBubble = _a[0], setShowBubble = _a[1];
687
+ var isMounted = React$1.useRef(true);
689
688
  React$1.useEffect(function () {
690
- var isMounted = true;
689
+ var hideTimer = null;
691
690
  if (startTime) {
692
691
  var delayTimer_1 = setTimeout(function () {
693
- if (isMounted) {
692
+ if (isMounted.current) {
694
693
  setShowBubble(true);
695
694
  }
696
- var hideTimer = setTimeout(function () {
697
- if (isMounted) {
698
- setShowBubble(false);
699
- }
700
- }, timeout);
701
- return function () {
702
- clearTimeout(hideTimer);
703
- };
695
+ if (typeof timeout === "number") {
696
+ hideTimer = setTimeout(function () {
697
+ if (isMounted.current) {
698
+ setShowBubble(false);
699
+ }
700
+ }, timeout);
701
+ }
704
702
  }, delay);
705
703
  return function () {
706
- isMounted = false;
704
+ if (hideTimer) {
705
+ clearTimeout(hideTimer);
706
+ }
707
707
  clearTimeout(delayTimer_1);
708
+ isMounted.current = false;
708
709
  };
709
710
  }
711
+ // Return a cleanup function for the case where startTime is undefined
710
712
  return function () {
711
- isMounted = false;
713
+ if (hideTimer) {
714
+ clearTimeout(hideTimer);
715
+ }
716
+ isMounted.current = false;
712
717
  };
713
718
  }, [startTime, timeout, delay]);
714
- return (React__default$1["default"].createElement(React__default$1["default"].Fragment, null, visible && showBubble && React__default$1["default"].createElement(CtaBubble, { onClick: onClick, animate: animate, buttonAnimation: buttonAnimation }, props.children)));
719
+ console.log("visible ".concat(visible, " showBubble ").concat(showBubble));
720
+ return (React__default$1["default"].createElement(React__default$1["default"].Fragment, null, visible && showBubble && React__default$1["default"].createElement(CtaBubble, { onClick: onClick, animate: animate, buttonAnimation: buttonAnimation }, children)));
715
721
  };
716
722
 
717
723
  var ChatButton = function (_a) {
@@ -719,10 +725,11 @@ var ChatButton = function (_a) {
719
725
  var onClick = _a.onClick, addClass = _a.addClass, config = _a.config, visible = _a.visible, borderStyle = _a.borderStyle, imageUrl = _a.imageUrl;
720
726
  var _c = React$1.useState(defaultWidgetButtonWidth), buttonWidth = _c[0], setButtonWidth = _c[1];
721
727
  var _d = React$1.useState(false), animate = _d[0], setAnimate = _d[1];
722
- var mobileWidht = ((_b = config === null || config === void 0 ? void 0 : config.mobile) === null || _b === void 0 ? void 0 : _b.applyAtLessThanWidth) || defaultNonMobileScreenWidth;
728
+ var mobileWidth = ((_b = config === null || config === void 0 ? void 0 : config.mobile) === null || _b === void 0 ? void 0 : _b.applyAtLessThanWidth) || defaultNonMobileScreenWidth;
729
+ // Determines mobile or normal
723
730
  var getConfigToApply = function () {
724
731
  var screenWidth = window.innerWidth;
725
- if (screenWidth <= parseInt(mobileWidht, 10) && (config === null || config === void 0 ? void 0 : config.mobile)) {
732
+ if (screenWidth <= parseInt(mobileWidth, 10) && (config === null || config === void 0 ? void 0 : config.mobile)) {
726
733
  return config.mobile;
727
734
  }
728
735
  else {
@@ -731,27 +738,44 @@ var ChatButton = function (_a) {
731
738
  };
732
739
  var configToApply = getConfigToApply();
733
740
  React$1.useEffect(function () {
734
- if ((configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay) && (configToApply === null || configToApply === void 0 ? void 0 : configToApply.timeout)) {
735
- var delayTimer_1 = setTimeout(function () {
741
+ var delayTimer;
742
+ var timeoutTimer;
743
+ if (configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay) {
744
+ // Set a delay for the animation to start
745
+ delayTimer = setTimeout(function () {
736
746
  setAnimate(true);
737
- var timeoutTimer = setTimeout(function () {
738
- setAnimate(false);
739
- }, configToApply.timeout);
740
- return function () {
741
- clearTimeout(timeoutTimer);
742
- };
747
+ if (configToApply.animationTimeout) {
748
+ // Stop the animation after the specified timeout
749
+ timeoutTimer = setTimeout(function () {
750
+ setAnimate(false);
751
+ }, configToApply.animationTimeout);
752
+ }
743
753
  }, configToApply.delay);
744
- return function () {
745
- clearTimeout(delayTimer_1);
746
- };
747
754
  }
748
- return function () { };
749
- }, [configToApply]);
755
+ else if (configToApply === null || configToApply === void 0 ? void 0 : configToApply.animationTimeout) {
756
+ // Start animation immediately and set a timeout to stop it
757
+ setAnimate(true);
758
+ timeoutTimer = setTimeout(function () {
759
+ setAnimate(false);
760
+ }, configToApply.animationTimeout);
761
+ }
762
+ else if (configToApply === null || configToApply === void 0 ? void 0 : configToApply.animation) {
763
+ // No delay or timeout, start animation immediately
764
+ setAnimate(true);
765
+ }
766
+ return function () {
767
+ // Clear timers on unmount or when dependencies change
768
+ if (delayTimer)
769
+ clearTimeout(delayTimer);
770
+ if (timeoutTimer)
771
+ clearTimeout(timeoutTimer);
772
+ };
773
+ }, [configToApply, setAnimate]);
750
774
  var animation = animate ? ((configToApply === null || configToApply === void 0 ? void 0 : configToApply.animation) || "wiggle") : "none";
751
775
  React$1.useEffect(function () {
752
776
  var handleResize = function () {
753
777
  var screenWidth = window.innerWidth;
754
- var newButtonWidth = screenWidth < (parseInt(mobileWidht, 10))
778
+ var newButtonWidth = screenWidth < (parseInt(mobileWidth, 10))
755
779
  ? defaultMobileWidgetButtonWidth : defaultWidgetButtonWidth;
756
780
  setButtonWidth(newButtonWidth);
757
781
  };
@@ -760,7 +784,7 @@ var ChatButton = function (_a) {
760
784
  return function () {
761
785
  window.removeEventListener('resize', handleResize);
762
786
  };
763
- }, [mobileWidht]);
787
+ }, [mobileWidth]);
764
788
  var maxSvgSize = 22;
765
789
  var svgSize = Math.min(maxSvgSize, (+buttonWidth / +defaultWidgetButtonWidth) * maxSvgSize);
766
790
  return (React__default$1["default"].createElement("button", { "aria-label": "open chat", className: "xapp-chat-button ".concat(addClass || "").trim(), onClick: onClick },
@@ -778,8 +802,8 @@ var ChatButton = function (_a) {
778
802
  // Fallback to default SVG
779
803
  React__default$1["default"].createElement("svg", { width: svgSize, height: svgSize, viewBox: "0 0 22 22" },
780
804
  React__default$1["default"].createElement("path", { d: "M13 22l-4-6H2c-1.11-.043-2-.935-2-2V2C0 .89.89 0 2 0h18c1.11 0 2 .892 2 2v12c0 1.067-.89 1.957-2 2h-3l-4 6zm3-8h4c-.005.3-.01-12 0-12-.01.004-18 .006-18 0 .005.006 0 12 0 12h8l3 5 3-5z", fill: "#FFF", fillRule: "evenodd" })))),
781
- config && config.message && (React__default$1["default"].createElement("div", { className: "xapp-chat-button__cta" },
782
- React__default$1["default"].createElement(CtaBubbleContainer, { timeout: configToApply === null || configToApply === void 0 ? void 0 : configToApply.timeout, delay: configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay, animate: animate, buttonAnimation: animation, visible: !visible }, config.message)))));
805
+ configToApply && configToApply.message && (React__default$1["default"].createElement("div", { className: "xapp-chat-button__cta" },
806
+ React__default$1["default"].createElement(CtaBubbleContainer, { timeout: configToApply === null || configToApply === void 0 ? void 0 : configToApply.timeout, delay: configToApply === null || configToApply === void 0 ? void 0 : configToApply.delay, animate: animate, buttonAnimation: animation, visible: !visible /** Why is this !visible */ }, configToApply === null || configToApply === void 0 ? void 0 : configToApply.message)))));
783
807
  };
784
808
 
785
809
  var ChatCard = function (props) {
@@ -7931,11 +7955,17 @@ function useSuggestions(search, context) {
7931
7955
  }); }, [suggestions, suggestionIndex, execute, suggestionItem]);
7932
7956
  }
7933
7957
 
7934
- var AdminBar = function (_props) {
7958
+ var AdminBar = function (_a) {
7959
+ var onAdminJoin = _a.onAdminJoin;
7935
7960
  var name = React$1.useRef(null);
7936
7961
  // We can manage this locally
7937
7962
  // const hasAdminJoined = useSelector<ChatState, boolean | undefined>(state => state.hasAdminJoined);
7938
- var _a = React$1.useState(false), joined = _a[0], setJoined = _a[1];
7963
+ var _b = React$1.useState(false), joined = _b[0], setJoined = _b[1];
7964
+ var _c = React$1.useState(""), inputName = _c[0], setInputName = _c[1];
7965
+ function handleInputChange(event) {
7966
+ setInputName(event.target.value);
7967
+ }
7968
+ var disable = inputName === "" || inputName === undefined;
7939
7969
  var dispatch = useChatServerDispatch();
7940
7970
  function onSubmit(event) {
7941
7971
  var _a;
@@ -7943,18 +7973,21 @@ var AdminBar = function (_props) {
7943
7973
  if (!joined) {
7944
7974
  dispatch(sendBargeIn((_a = name.current) === null || _a === void 0 ? void 0 : _a.value));
7945
7975
  setJoined(true);
7976
+ onAdminJoin(true);
7946
7977
  }
7947
7978
  else {
7948
7979
  dispatch(sendBargeOut());
7949
7980
  setJoined(false);
7981
+ onAdminJoin(false);
7982
+ setInputName("");
7950
7983
  }
7951
7984
  }
7952
7985
  function renderJoin() {
7953
7986
  return (React__default$1["default"].createElement("form", { className: "xappw-admin-input-form", onSubmit: onSubmit },
7954
7987
  React__default$1["default"].createElement("div", { className: "xappw-admin-input-form__buttons" },
7955
- React__default$1["default"].createElement(ActionButton, { addClass: "xappw-admin-input-form__btn", type: "submit", label: "Join" })),
7988
+ React__default$1["default"].createElement(ActionButton, { addClass: "xappw-admin-input-form__btn", type: "submit", label: "Join", disable: disable })),
7956
7989
  React__default$1["default"].createElement("div", { className: "xappw-admin-input" },
7957
- React__default$1["default"].createElement("input", { ref: name, id: "adminBarInput", placeholder: "Type your name here...", className: "xappw-admin-input__input" }))));
7990
+ React__default$1["default"].createElement("input", { ref: name, id: "adminBarInput", placeholder: "Type your name here...", className: "xappw-admin-input__input", onChange: handleInputChange }))));
7958
7991
  }
7959
7992
  function renderLeave() {
7960
7993
  return (React__default$1["default"].createElement("form", { className: "xappw-admin-input-form", onSubmit: onSubmit },
@@ -8226,10 +8259,11 @@ var ChatFooter = function (props) {
8226
8259
  var menuButtonTabIndex = (_a = menuConfig === null || menuConfig === void 0 ? void 0 : menuConfig.button) === null || _a === void 0 ? void 0 : _a.tabIndex;
8227
8260
  var menuItems = React$1.useMemo(function () { return menuItemsRaw ? menuItemsRaw : []; }, [menuItemsRaw]);
8228
8261
  var brandingEnabled = (_b = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.branding) === null || _b === void 0 ? void 0 : _b.enabled;
8229
- var _e = React$1.useState({
8262
+ var _e = React$1.useState(false), isAdminJoined = _e[0], setAdminJoined = _e[1];
8263
+ var _f = React$1.useState({
8230
8264
  text: "",
8231
8265
  formats: []
8232
- }), input = _e[0], setInput = _e[1];
8266
+ }), input = _f[0], setInput = _f[1];
8233
8267
  function toggleDrawer() {
8234
8268
  var newDrawer = !drawerOpen;
8235
8269
  setDrawerState(newDrawer);
@@ -8265,6 +8299,9 @@ var ChatFooter = function (props) {
8265
8299
  setInput(data);
8266
8300
  setSuggestionSearch(data.text);
8267
8301
  }, []);
8302
+ var handleAdminJoin = function (status) {
8303
+ setAdminJoined(status);
8304
+ };
8268
8305
  return (React__default$1["default"].createElement("div", { className: "chat-footer background-footer", "aria-label": menuItems.length ? "to open menu click a button above the rounded rectangle at the bottom of widget" : "", "aria-hidden": false },
8269
8306
  showMenu && menuItems.length ?
8270
8307
  React__default$1["default"].createElement(React__default$1["default"].Fragment, null,
@@ -8272,10 +8309,11 @@ var ChatFooter = function (props) {
8272
8309
  React__default$1["default"].createElement("div", { className: "chat-footer__menu-icon" },
8273
8310
  React__default$1["default"].createElement(DrawerBars, { tabIndex: menuButtonTabIndex, onToggle: toggleDrawer }))) : React__default$1["default"].createElement(React__default$1["default"].Fragment, null),
8274
8311
  React__default$1["default"].createElement(Suggestions, { className: "xappw-chat-footer__suggestions", data: suggestions.suggestions, index: suggestions.index, searchTerms: suggestionSearch, onItemClick: handleItemClick, onItemUse: handleItemUse }),
8275
- props.isAdmin && props.isChatting && props.visible && React__default$1["default"].createElement(AdminBar, null),
8276
- React__default$1["default"].createElement(Input, { addClass: "chat-footer__input " + (props.isChatting && props.visible ? "visible" : ""), suggestion: suggestions.item, value: input, placeholder: placeholder, sendButtonIcon: sendButtonIcon, footerConfig: footerConfig, inputConfig: inputConfig, onSubmit: handleSubmit, onChange: handleChange, onSuggestionCommand: suggestions.execute,
8277
- // onFocus={this.inputOnFocus}
8278
- onFileUpload: props.onFileUpload }),
8312
+ props.isAdmin && props.isChatting && props.visible && React__default$1["default"].createElement(AdminBar, { onAdminJoin: handleAdminJoin }),
8313
+ React__default$1["default"].createElement("div", { style: { pointerEvents: isAdminJoined ? "auto" : "none", opacity: isAdminJoined ? 1 : 0.5 } },
8314
+ React__default$1["default"].createElement(Input, { addClass: "chat-footer__input " + (props.isChatting && props.visible ? "visible" : ""), suggestion: suggestions.item, value: input, placeholder: placeholder, sendButtonIcon: sendButtonIcon, footerConfig: footerConfig, inputConfig: inputConfig, onSubmit: handleSubmit, onChange: handleChange, onSuggestionCommand: suggestions.execute,
8315
+ // onFocus={this.inputOnFocus}
8316
+ onFileUpload: props.onFileUpload })),
8279
8317
  brandingEnabled && React__default$1["default"].createElement(ChatBranding, { text: 'Powered by [XAPP AI](https://xapp.ai)' })));
8280
8318
  };
8281
8319
 
@@ -30766,16 +30804,16 @@ var MessageList = function (props) {
30766
30804
  switch (msg.type) {
30767
30805
  case "chat.file":
30768
30806
  case "chat.msg":
30769
- return (React__default$1["default"].createElement(ChatMessage, { key: msg.type + msg.timestamp, message: msg, sibling: sibling, agent: user, messageMiddleware: props.messageMiddleware, middlewareContext: ctxCache.resolve(user) }));
30807
+ return (React__default$1["default"].createElement(ChatMessage, { key: "cm-".concat(msg.type, "-").concat(msg.timestamp), message: msg, sibling: sibling, agent: user, messageMiddleware: props.messageMiddleware, middlewareContext: ctxCache.resolve(user) }));
30770
30808
  case "chat.failureMsg":
30771
- return (React__default$1["default"].createElement(FailureMessage, __assign({ key: msg.type + msg.timestamp, agents: props.agents, time: time }, msg.failureMsg)));
30809
+ return (React__default$1["default"].createElement(FailureMessage, __assign({ key: "fm-".concat(msg.type, "-").concat(msg.timestamp), agents: props.agents, time: time }, msg.failureMsg)));
30772
30810
  case "chat.memberjoin":
30773
30811
  case "chat.memberleave":
30774
30812
  case "chat.rating":
30775
30813
  case "chat.typing":
30776
- return (React__default$1["default"].createElement(SystemMessage, { key: msg.type + msg.timestamp, time: time, message: msg }));
30814
+ return (React__default$1["default"].createElement(SystemMessage, { key: "sm-".concat(msg.type, "-").concat(msg.timestamp), time: time, message: msg }));
30777
30815
  case "chat.request.rating":
30778
- return (React__default$1["default"].createElement(ChatRatingContainer, { key: msg.type + msg.timestamp, agent: user, hasRating: props.hasRating, time: time, shouldDisplay: msg.timestamp === props.lastRatingRequestTimestamp }));
30816
+ return (React__default$1["default"].createElement(ChatRatingContainer, { key: "cr-".concat(msg.type, "-").concat(msg.timestamp), agent: user, hasRating: props.hasRating, time: time, shouldDisplay: msg.timestamp === props.lastRatingRequestTimestamp }));
30779
30817
  case "chat.offline":
30780
30818
  return React__default$1["default"].createElement(OfflineFormContainer, { key: "offline-".concat(msg.timestamp), time: time });
30781
30819
  case "chat.prechat":
@@ -30783,7 +30821,7 @@ var MessageList = function (props) {
30783
30821
  default:
30784
30822
  return (React__default$1["default"].createElement(React__default$1["default"].Fragment, null,
30785
30823
  React__default$1["default"].createElement("span", { className: "message-sr-only" }, "at " + time + " system message"),
30786
- React__default$1["default"].createElement("div", { key: +new Date() },
30824
+ React__default$1["default"].createElement("div", { key: "uhm-".concat(+new Date()) },
30787
30825
  "Unhandled message: ",
30788
30826
  JSON.stringify(msg))));
30789
30827
  }