@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/components/ChatButton/ChatButton.d.ts +5 -0
- package/dist/components/ChatButton/ChatButton.stories.d.ts +1 -0
- package/dist/components/CtaBubble/CtaBubble.d.ts +5 -0
- package/dist/components/CtaBubble/CtaBubble.stories.d.ts +1 -0
- package/dist/components/Suggestions/Suggestions.d.ts +1 -0
- package/dist/index.css +2 -2
- package/dist/index.es.js +110 -18
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +110 -18
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
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,
|
|
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 () {
|
|
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
|
|
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
|
-
|
|
8892
|
-
React__default$1["default"].createElement(SuggestionsList_1, { suggestions:
|
|
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
|
|
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
|
|
8899
|
-
var
|
|
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
|
|
8934
|
+
var _f = React$1.useState({
|
|
8911
8935
|
text: "",
|
|
8912
8936
|
formats: []
|
|
8913
|
-
}), input =
|
|
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
|
-
|
|
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
|
|
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) {
|