@xapp/chat-widget 1.54.0 → 1.54.2

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
@@ -1854,7 +1854,11 @@ var CtaBubbleTail = function (props) {
1854
1854
  var CtaBubble = function (props) {
1855
1855
  var _a, _b;
1856
1856
  var _c = useDimensions(), ref = _c[0], rect = _c[1];
1857
- return (React__default$1["default"].createElement("div", { ref: ref, className: "cta-bubble", onClick: props.onClick },
1857
+ return (React__default$1["default"].createElement("div", { ref: ref, style: props.borderStyle && {
1858
+ border: 'solid',
1859
+ borderWidth: props.borderStyle.width,
1860
+ borderColor: props.borderStyle.color
1861
+ }, className: "cta-bubble", onClick: props.onClick },
1858
1862
  React__default$1["default"].createElement(CtaBubbleTail, { width: (_a = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _a !== void 0 ? _a : 0, height: (_b = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _b !== void 0 ? _b : 0, direction: 60, angle: 45, length: 16 }),
1859
1863
  React__default$1["default"].createElement("div", { className: "cta-bubble__content" }, props.children)));
1860
1864
  };
@@ -1892,7 +1896,11 @@ var CtaBubbleContainer = function (props) {
1892
1896
 
1893
1897
  var ChatButton = function (props) {
1894
1898
  return (React__default$1["default"].createElement("button", { className: "xapp-chat-button ".concat(props.addClass), onClick: props.onClick },
1895
- React__default$1["default"].createElement("div", { id: "xapp-widget-button", className: "xapp-chat-button__btn" },
1899
+ React__default$1["default"].createElement("div", { id: "xapp-widget-button", className: "xapp-chat-button__btn", style: props.borderStyle && {
1900
+ border: 'solid',
1901
+ borderWidth: props.borderStyle.width,
1902
+ borderColor: props.borderStyle.color
1903
+ } },
1896
1904
  React__default$1["default"].createElement("svg", { width: "22", height: "22", viewBox: "0 0 22 22" },
1897
1905
  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" }))),
1898
1906
  props.config && props.config.message && (React__default$1["default"].createElement("div", { className: "xapp-chat-button__cta" },
@@ -2590,10 +2598,15 @@ function getItemsLength(result) {
2590
2598
 
2591
2599
  var SuggestionsList = function (props) {
2592
2600
  var suggestions = props.suggestions, itemActions = props.itemActions, className = props.className;
2593
- var length = React.useMemo(function () { return getItemsLength(suggestions); }, [suggestions]);
2601
+ var length = React.useMemo(function () {
2602
+ if (suggestions) {
2603
+ return getItemsLength(suggestions);
2604
+ }
2605
+ return 0;
2606
+ }, [suggestions]);
2594
2607
  var currentIndex = length >= 0 ? props.index : NaN;
2595
2608
  var indexWalker = 0;
2596
- return (React__default["default"].createElement("div", { className: "xappw-suggestions-list ".concat(className || "") }, suggestions.map(function (group, index) {
2609
+ return (React__default["default"].createElement("div", { className: "xappw-suggestions-list ".concat(className || "") }, suggestions === null || suggestions === void 0 ? void 0 : suggestions.map(function (group, index) {
2597
2610
  var res = (React__default["default"].createElement(SuggestionsGroup, { key: index, group: group, currentIndex: currentIndex - indexWalker, itemActions: itemActions, onItemClick: props.onItemClick, onItemHover: props.onItemHover, onSpanClick: props.onSpanClick }));
2598
2611
  indexWalker += group.items.length;
2599
2612
  return res;
@@ -8870,14 +8883,25 @@ function createActions(onItemUse) {
8870
8883
  };
8871
8884
  }
8872
8885
  var Suggestions = function (props) {
8873
- var data = props.data, onItemUse = props.onItemUse;
8874
- var len = data.length;
8886
+ var data = props.data, onItemUse = props.onItemUse, searchTerms = props.searchTerms;
8887
+ var _a = React$1.useState(), fixedSuggestions = _a[0], setFixedSuggestions = _a[1];
8888
+ var _b = React$1.useState(), activeItem = _b[0], setActiveItem = _b[1];
8889
+ React$1.useEffect(function () {
8890
+ if (data) {
8891
+ setFixedSuggestions(data);
8892
+ }
8893
+ if (!searchTerms) {
8894
+ setFixedSuggestions(undefined);
8895
+ setActiveItem(undefined);
8896
+ }
8897
+ }, [data, searchTerms]);
8898
+ var len = data === null || data === void 0 ? void 0 : data.length;
8875
8899
  var currentIndex = len > 0 ? props.index : NaN;
8876
- var _a = React$1.useState(), activeItem = _a[0], setActiveItem = _a[1];
8877
8900
  var item = React$1.useMemo(function () { return findItemByIndex_1(data, currentIndex); }, [data, currentIndex]);
8878
8901
  var handleSpanClick = React$1.useCallback(function (target, span) {
8879
8902
  if (span.type === "inputText") {
8880
8903
  onItemUse(target);
8904
+ setActiveItem(undefined);
8881
8905
  return false;
8882
8906
  }
8883
8907
  return undefined;
@@ -8888,15 +8912,15 @@ var Suggestions = function (props) {
8888
8912
  var actions = React$1.useMemo(function () { return createActions(onItemUse); }, [onItemUse]);
8889
8913
  return (React__default$1["default"].createElement("div", { className: "xappw-suggestions ".concat(props.className || "") },
8890
8914
  (activeItem === null || activeItem === void 0 ? void 0 : activeItem.content) && React__default$1["default"].createElement("div", { className: "xappw-suggestions__answer" }, activeItem.content),
8891
- !!data.length &&
8892
- React__default$1["default"].createElement(SuggestionsList_1, { suggestions: data, index: currentIndex, className: "xappw-suggestions__groups", itemActions: actions, onItemClick: props.onItemClick, onItemHover: setActiveItem, onSpanClick: handleSpanClick })));
8915
+ fixedSuggestions && fixedSuggestions.length > 0 &&
8916
+ React__default$1["default"].createElement(SuggestionsList_1, { suggestions: fixedSuggestions, index: currentIndex, className: "xappw-suggestions__groups", itemActions: actions, onItemClick: props.onItemClick, onItemHover: setActiveItem, onSpanClick: handleSpanClick })));
8893
8917
  };
8894
8918
 
8895
8919
  var ChatFooter = function (props) {
8896
- var _a, _b, _c, _d;
8920
+ var _a, _b, _c;
8897
8921
  var placeholder = props.placeholder, sendButtonIcon = props.sendButtonIcon, footerConfig = props.footerConfig, menuConfig = props.menuConfig, inputConfig = props.inputConfig, onSubmit = props.onSubmit;
8898
- var _e = React$1.useState(false), drawerOpen = _e[0], setDrawerState = _e[1]; // false initially
8899
- var _f = React$1.useState(), suggestionSearch = _f[0], setSuggestionSearch = _f[1];
8922
+ var _d = React$1.useState(false), drawerOpen = _d[0], setDrawerState = _d[1]; // false initially
8923
+ var _e = React$1.useState(), suggestionSearch = _e[0], setSuggestionSearch = _e[1];
8900
8924
  var contexts = reactRedux.useSelector(function (state) { return state.activeContexts; });
8901
8925
  var suggestions = useSuggestions(suggestionSearch, contexts);
8902
8926
  var menuPosition = (menuConfig === null || menuConfig === void 0 ? void 0 : menuConfig.menuButtonLocation) || "FOOTER";
@@ -8907,10 +8931,10 @@ var ChatFooter = function (props) {
8907
8931
  var menuItems = React$1.useMemo(function () { return menuItemsRaw ? menuItemsRaw : []; }, [menuItemsRaw]);
8908
8932
  var branding = (_b = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.branding) === null || _b === void 0 ? void 0 : _b.text; // useWidgetEnv()?.footer?.branding?.text;
8909
8933
  var brandingEnabled = (_c = footerConfig === null || footerConfig === void 0 ? void 0 : footerConfig.branding) === null || _c === void 0 ? void 0 : _c.enabled; // useWidgetEnv()?.footer?.branding?.enabled;
8910
- var _g = React$1.useState({
8934
+ var _f = React$1.useState({
8911
8935
  text: "",
8912
8936
  formats: []
8913
- }), input = _g[0], setInput = _g[1];
8937
+ }), input = _f[0], setInput = _f[1];
8914
8938
  function toggleDrawer() {
8915
8939
  var newDrawer = !drawerOpen;
8916
8940
  setDrawerState(newDrawer);
@@ -8927,7 +8951,9 @@ var ChatFooter = function (props) {
8927
8951
  }
8928
8952
  // Clears out suggestion and input text
8929
8953
  var handleSubmit = React$1.useCallback(function (message) {
8954
+ // Clears out the suggestions
8930
8955
  setSuggestionSearch("");
8956
+ // Clears out the input
8931
8957
  setInput({
8932
8958
  text: "",
8933
8959
  formats: []
@@ -8938,16 +8964,17 @@ var ChatFooter = function (props) {
8938
8964
  handleSubmit(data);
8939
8965
  }, [handleSubmit]);
8940
8966
  var handleItemUse = React$1.useCallback(function (data) {
8967
+ console.log(data);
8941
8968
  setInput(data);
8942
8969
  setSuggestionSearch(data.text);
8943
8970
  }, []);
8944
- return (React__default$1["default"].createElement("div", { className: "chat-footer", "aria-label": menuItems.length ? "to open menu click a button above the rounded rectangle at the bottom of widget" : "", "aria-hidden": true },
8971
+ 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": true },
8945
8972
  showMenu && menuItems.length ?
8946
8973
  React__default$1["default"].createElement(React__default$1["default"].Fragment, null,
8947
8974
  drawerOpen ? React__default$1["default"].createElement(ChatMenu, { opened: drawerOpen, tabIndex: menuItemsTabIndex, onItemClick: handleMenuItem, items: menuItems }) : React__default$1["default"].createElement(React__default$1["default"].Fragment, null),
8948
8975
  React__default$1["default"].createElement("div", { className: "chat-footer__menu-icon" },
8949
8976
  React__default$1["default"].createElement(DrawerBars, { tabIndex: menuButtonTabIndex, onToggle: toggleDrawer }))) : React__default$1["default"].createElement(React__default$1["default"].Fragment, null),
8950
- ((_d = suggestions.suggestions) === null || _d === void 0 ? void 0 : _d.length) > 0 && React__default$1["default"].createElement(Suggestions, { className: "xappw-chat-footer__suggestions", data: suggestions.suggestions, index: suggestions.index, onItemClick: handleItemClick, onItemUse: handleItemUse }),
8977
+ React__default$1["default"].createElement(Suggestions, { className: "xappw-chat-footer__suggestions", data: suggestions.suggestions, index: suggestions.index, searchTerms: suggestionSearch, onItemClick: handleItemClick, onItemUse: handleItemUse }),
8951
8978
  props.isAdmin && props.isChatting && props.visible && React__default$1["default"].createElement(AdminBar, null),
8952
8979
  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,
8953
8980
  // onFocus={this.inputOnFocus}
@@ -31538,7 +31565,7 @@ var ChatHeader = function (props) {
31538
31565
  onSubmit(label);
31539
31566
  }
31540
31567
  return (React__default$1["default"].createElement(React__default$1["default"].Fragment, null,
31541
- React__default$1["default"].createElement("div", { className: "status-container", "aria-label": props.canRefresh ? refreshButtonAriaLabel : "" + props.canMinimize ? minimizeButtonAriaLabel : "" + props.canCancel ? closeButtonAriaLabel : "", "aria-hidden": true },
31568
+ React__default$1["default"].createElement("div", { className: "status-container background-header", "aria-label": props.canRefresh ? refreshButtonAriaLabel : "" + props.canMinimize ? minimizeButtonAriaLabel : "" + props.canCancel ? closeButtonAriaLabel : "", "aria-hidden": true },
31542
31569
  showMenu && menuItems.length ? (React__default$1["default"].createElement(React__default$1["default"].Fragment, null,
31543
31570
  React__default$1["default"].createElement("div", { className: "chat-footer__menu-icon" },
31544
31571
  React__default$1["default"].createElement(DrawerBars, { bars: 3, tabIndex: menuButtonTabIndex, onToggle: toggleDrawer })))) : React__default$1["default"].createElement(React__default$1["default"].Fragment, null),
@@ -32348,7 +32375,10 @@ function storeHandler(state, action) {
32348
32375
  }
32349
32376
  }
32350
32377
 
32378
+ var ADMIN_STORE_KEY = "AdminAccessTimes";
32379
+ var ADMIN_STORE_MAX = 20;
32351
32380
  function createChatStore(config, dataStorage) {
32381
+ var _a;
32352
32382
  if (!dataStorage) {
32353
32383
  if (typeof window !== "undefined") {
32354
32384
  dataStorage = localStorage;
@@ -32358,7 +32388,39 @@ function createChatStore(config, dataStorage) {
32358
32388
  }
32359
32389
  }
32360
32390
  var connection = config.connection;
32361
- var storage = new BrowserStateStorage(dataStorage, "xappchat.".concat(connection.serverUrl, ".").concat(connection.accountKey));
32391
+ var joinSessionId = (_a = new URL(window.location.href).searchParams) === null || _a === void 0 ? void 0 : _a.get("sessionId");
32392
+ var dataStorageKey;
32393
+ var now = new Date().getTime();
32394
+ if (joinSessionId) {
32395
+ var adminTimesData = dataStorage.getItem(ADMIN_STORE_KEY);
32396
+ // Create
32397
+ var adminTimes = adminTimesData ? JSON.parse(adminTimesData) : {};
32398
+ // if exists, use it. If not, check if we are maxed out. evict one session if we are.
32399
+ if (adminTimes[joinSessionId]) {
32400
+ log("ChatStore: reusing session: ".concat(joinSessionId));
32401
+ adminTimes[joinSessionId].lastAccessMs = now;
32402
+ dataStorageKey = adminTimes[joinSessionId].dataStorageKey;
32403
+ }
32404
+ else {
32405
+ if (Object.keys(adminTimes).length >= ADMIN_STORE_MAX) {
32406
+ var evictedSessionId = evictAdminSession(adminTimes);
32407
+ log("ChatStore: evicting session: ".concat(evictedSessionId));
32408
+ dataStorage.removeItem(adminTimes[evictedSessionId].dataStorageKey);
32409
+ adminTimes[evictedSessionId] = undefined;
32410
+ }
32411
+ // We now have room
32412
+ dataStorageKey = generateKey(connection, joinSessionId);
32413
+ adminTimes[joinSessionId] = {
32414
+ lastAccessMs: now,
32415
+ dataStorageKey: dataStorageKey,
32416
+ };
32417
+ }
32418
+ dataStorage.setItem(ADMIN_STORE_KEY, JSON.stringify(adminTimes));
32419
+ }
32420
+ else {
32421
+ dataStorageKey = generateKey(connection);
32422
+ }
32423
+ var storage = new BrowserStateStorage(dataStorage, dataStorageKey);
32362
32424
  var defaultState = createDefaultState({
32363
32425
  accessToken: config.accessToken,
32364
32426
  userId: config.userId,
@@ -32372,6 +32434,36 @@ function createChatStore(config, dataStorage) {
32372
32434
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32373
32435
  var composeEnhancers = globalThis.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose;
32374
32436
  return redux.createStore(chatReducer, composeEnhancers(redux.applyMiddleware.apply(void 0, middlewares)));
32437
+ }
32438
+ /**
32439
+ * Pick one admin session for eviction
32440
+ *
32441
+ * @param adminTimes
32442
+ * @returns
32443
+ */
32444
+ function evictAdminSession(adminTimes) {
32445
+ // Find the oldest
32446
+ var minTimeTs = Number.MAX_VALUE;
32447
+ var minSessionId;
32448
+ for (var _i = 0, _a = Object.keys(adminTimes); _i < _a.length; _i++) {
32449
+ var sessionId = _a[_i];
32450
+ if (adminTimes[sessionId].lastAccessMs < minTimeTs) {
32451
+ minSessionId = sessionId;
32452
+ minTimeTs = adminTimes[sessionId].lastAccessMs;
32453
+ }
32454
+ }
32455
+ return minSessionId;
32456
+ }
32457
+ function generateKey(connection, sessionId) {
32458
+ var base = "xappchat.".concat(connection.serverUrl);
32459
+ if (sessionId) {
32460
+ return connection.accountKey
32461
+ ? "".concat(base, ".").concat(connection.accountKey, ".").concat(sessionId)
32462
+ : "".concat(base, ".").concat(sessionId);
32463
+ }
32464
+ else {
32465
+ return connection.accountKey ? "".concat(base, ".").concat(connection.accountKey) : base;
32466
+ }
32375
32467
  }
32376
32468
 
32377
32469
  var ChatWidgetContainer = function (props) {