stream-chat-react
Version:
React components to create chat conversations or livestream style chat
1,519 lines (1,462 loc) • 523 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all2) => {
for (var name2 in all2)
__defProp(target, name2, { get: all2[name2], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/inline-style-parser/index.js
var require_inline_style_parser = __commonJS({
"node_modules/inline-style-parser/index.js"(exports2, module2) {
var COMMENT_REGEX = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
var NEWLINE_REGEX = /\n/g;
var WHITESPACE_REGEX = /^\s*/;
var PROPERTY_REGEX = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/;
var COLON_REGEX = /^:\s*/;
var VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/;
var SEMICOLON_REGEX = /^[;\s]*/;
var TRIM_REGEX = /^\s+|\s+$/g;
var NEWLINE = "\n";
var FORWARD_SLASH = "/";
var ASTERISK = "*";
var EMPTY_STRING = "";
var TYPE_COMMENT = "comment";
var TYPE_DECLARATION = "declaration";
module2.exports = function(style, options) {
if (typeof style !== "string") {
throw new TypeError("First argument must be a string");
}
if (!style) return [];
options = options || {};
var lineno = 1;
var column = 1;
function updatePosition(str) {
var lines = str.match(NEWLINE_REGEX);
if (lines) lineno += lines.length;
var i = str.lastIndexOf(NEWLINE);
column = ~i ? str.length - i : column + str.length;
}
function position3() {
var start2 = { line: lineno, column };
return function(node2) {
node2.position = new Position(start2);
whitespace2();
return node2;
};
}
function Position(start2) {
this.start = start2;
this.end = { line: lineno, column };
this.source = options.source;
}
Position.prototype.content = style;
var errorsList = [];
function error(msg) {
var err = new Error(
options.source + ":" + lineno + ":" + column + ": " + msg
);
err.reason = msg;
err.filename = options.source;
err.line = lineno;
err.column = column;
err.source = style;
if (options.silent) {
errorsList.push(err);
} else {
throw err;
}
}
function match(re2) {
var m = re2.exec(style);
if (!m) return;
var str = m[0];
updatePosition(str);
style = style.slice(str.length);
return m;
}
function whitespace2() {
match(WHITESPACE_REGEX);
}
function comments(rules) {
var c;
rules = rules || [];
while (c = comment()) {
if (c !== false) {
rules.push(c);
}
}
return rules;
}
function comment() {
var pos = position3();
if (FORWARD_SLASH != style.charAt(0) || ASTERISK != style.charAt(1)) return;
var i = 2;
while (EMPTY_STRING != style.charAt(i) && (ASTERISK != style.charAt(i) || FORWARD_SLASH != style.charAt(i + 1))) {
++i;
}
i += 2;
if (EMPTY_STRING === style.charAt(i - 1)) {
return error("End of comment missing");
}
var str = style.slice(2, i - 2);
column += 2;
updatePosition(str);
style = style.slice(i);
column += 2;
return pos({
type: TYPE_COMMENT,
comment: str
});
}
function declaration() {
var pos = position3();
var prop = match(PROPERTY_REGEX);
if (!prop) return;
comment();
if (!match(COLON_REGEX)) return error("property missing ':'");
var val = match(VALUE_REGEX);
var ret = pos({
type: TYPE_DECLARATION,
property: trim(prop[0].replace(COMMENT_REGEX, EMPTY_STRING)),
value: val ? trim(val[0].replace(COMMENT_REGEX, EMPTY_STRING)) : EMPTY_STRING
});
match(SEMICOLON_REGEX);
return ret;
}
function declarations() {
var decls = [];
comments(decls);
var decl;
while (decl = declaration()) {
if (decl !== false) {
decls.push(decl);
comments(decls);
}
}
return decls;
}
whitespace2();
return declarations();
};
function trim(str) {
return str ? str.replace(TRIM_REGEX, EMPTY_STRING) : EMPTY_STRING;
}
}
});
// node_modules/style-to-object/cjs/index.js
var require_cjs = __commonJS({
"node_modules/style-to-object/cjs/index.js"(exports2) {
"use strict";
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { "default": mod };
};
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.default = StyleToObject2;
var inline_style_parser_1 = __importDefault(require_inline_style_parser());
function StyleToObject2(style, iterator) {
var styleObject = null;
if (!style || typeof style !== "string") {
return styleObject;
}
var declarations = (0, inline_style_parser_1.default)(style);
var hasIterator = typeof iterator === "function";
declarations.forEach(function(declaration) {
if (declaration.type !== "declaration") {
return;
}
var property = declaration.property, value = declaration.value;
if (hasIterator) {
iterator(property, value, declaration);
} else if (value) {
styleObject = styleObject || {};
styleObject[property] = value;
}
});
return styleObject;
}
}
});
// node_modules/extend/index.js
var require_extend = __commonJS({
"node_modules/extend/index.js"(exports2, module2) {
"use strict";
var hasOwn = Object.prototype.hasOwnProperty;
var toStr = Object.prototype.toString;
var defineProperty = Object.defineProperty;
var gOPD = Object.getOwnPropertyDescriptor;
var isArray = function isArray2(arr) {
if (typeof Array.isArray === "function") {
return Array.isArray(arr);
}
return toStr.call(arr) === "[object Array]";
};
var isPlainObject2 = function isPlainObject3(obj) {
if (!obj || toStr.call(obj) !== "[object Object]") {
return false;
}
var hasOwnConstructor = hasOwn.call(obj, "constructor");
var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, "isPrototypeOf");
if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
return false;
}
var key;
for (key in obj) {
}
return typeof key === "undefined" || hasOwn.call(obj, key);
};
var setProperty = function setProperty2(target, options) {
if (defineProperty && options.name === "__proto__") {
defineProperty(target, options.name, {
enumerable: true,
configurable: true,
value: options.newValue,
writable: true
});
} else {
target[options.name] = options.newValue;
}
};
var getProperty = function getProperty2(obj, name2) {
if (name2 === "__proto__") {
if (!hasOwn.call(obj, name2)) {
return void 0;
} else if (gOPD) {
return gOPD(obj, name2).value;
}
}
return obj[name2];
};
module2.exports = function extend2() {
var options, name2, src, copy, copyIsArray, clone;
var target = arguments[0];
var i = 1;
var length = arguments.length;
var deep = false;
if (typeof target === "boolean") {
deep = target;
target = arguments[1] || {};
i = 2;
}
if (target == null || typeof target !== "object" && typeof target !== "function") {
target = {};
}
for (; i < length; ++i) {
options = arguments[i];
if (options != null) {
for (name2 in options) {
src = getProperty(target, name2);
copy = getProperty(options, name2);
if (target !== copy) {
if (deep && copy && (isPlainObject2(copy) || (copyIsArray = isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false;
clone = src && isArray(src) ? src : [];
} else {
clone = src && isPlainObject2(src) ? src : {};
}
setProperty(target, { name: name2, newValue: extend2(deep, clone, copy) });
} else if (typeof copy !== "undefined") {
setProperty(target, { name: name2, newValue: copy });
}
}
}
}
}
return target;
};
}
});
// src/experimental/index.ts
var experimental_exports = {};
__export(experimental_exports, {
ChannelSearchResultItem: () => ChannelSearchResultItem,
DefaultDropdownActionButton: () => DefaultDropdownActionButton,
DefaultSearchResultItems: () => DefaultSearchResultItems,
MessageActions: () => MessageActions,
MessageSearchResultItem: () => MessageSearchResultItem,
Search: () => Search,
SearchBar: () => SearchBar,
SearchContext: () => SearchContext,
SearchContextProvider: () => SearchContextProvider,
SearchResults: () => SearchResults,
SearchResultsHeader: () => SearchResultsHeader,
SearchResultsPresearch: () => SearchResultsPresearch,
SearchSourceResultList: () => SearchSourceResultList,
SearchSourceResultListFooter: () => SearchSourceResultListFooter,
SearchSourceResults: () => SearchSourceResults,
SearchSourceResultsContext: () => SearchSourceResultsContext,
SearchSourceResultsContextProvider: () => SearchSourceResultsContextProvider,
SearchSourceResultsEmpty: () => SearchSourceResultsEmpty,
SearchSourceResultsLoadingIndicator: () => SearchSourceResultsLoadingIndicator,
UserSearchResultItem: () => UserSearchResultItem,
defaultMessageActionSet: () => defaultMessageActionSet,
useBaseMessageActionSetFilter: () => useBaseMessageActionSetFilter,
useSearchContext: () => useSearchContext,
useSearchSourceResultsContext: () => useSearchSourceResultsContext,
useSplitMessageActionSet: () => useSplitMessageActionSet
});
module.exports = __toCommonJS(experimental_exports);
// src/experimental/MessageActions/MessageActions.tsx
var import_clsx9 = __toESM(require("clsx"));
var import_react42 = __toESM(require("react"));
// src/context/ChannelListContext.tsx
var import_react = __toESM(require("react"));
var ChannelListContext = (0, import_react.createContext)(
void 0
);
var useChannelListContext = (componentName) => {
const contextValue = (0, import_react.useContext)(ChannelListContext);
if (!contextValue) {
console.warn(
`The useChannelListContext hook was called outside of the ChannelListContext provider. Make sure this hook is called within the ChannelList component. The errored call is located in the ${componentName} component.`
);
return {};
}
return contextValue;
};
// src/context/ChannelStateContext.tsx
var import_react2 = __toESM(require("react"));
var ChannelStateContext = import_react2.default.createContext(void 0);
var useChannelStateContext = (componentName) => {
const contextValue = (0, import_react2.useContext)(ChannelStateContext);
if (!contextValue) {
console.warn(
`The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`
);
return {};
}
return contextValue;
};
// src/context/ChatContext.tsx
var import_react3 = __toESM(require("react"));
var ChatContext = import_react3.default.createContext(void 0);
var useChatContext = (componentName) => {
const contextValue = (0, import_react3.useContext)(ChatContext);
if (!contextValue) {
console.warn(
`The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`
);
return {};
}
return contextValue;
};
// src/context/ComponentContext.tsx
var import_react4 = __toESM(require("react"));
var ComponentContext = import_react4.default.createContext({});
var useComponentContext = (_componentName) => (0, import_react4.useContext)(ComponentContext);
// src/context/DialogManagerContext.tsx
var import_react9 = __toESM(require("react"));
var import_stream_chat = require("stream-chat");
// src/components/Dialog/DialogPortal.tsx
var import_react8 = __toESM(require("react"));
// src/components/Dialog/hooks/useDialog.ts
var import_react6 = require("react");
// src/store/hooks/useStateStore.ts
var import_react5 = require("react");
var import_shim = require("use-sync-external-store/shim");
var noop = () => {
};
function useStateStore(store, selector2) {
const wrappedSubscription = (0, import_react5.useCallback)(
(onStoreChange) => {
const unsubscribe = store?.subscribeWithSelector(selector2, onStoreChange);
return unsubscribe ?? noop;
},
[store, selector2]
);
const wrappedSnapshot = (0, import_react5.useMemo)(() => {
let cachedTuple;
return () => {
const currentValue = store?.getLatestValue();
if (!currentValue) return void 0;
if (cachedTuple && cachedTuple[0] === currentValue) {
return cachedTuple[1];
}
const newlySelected = selector2(currentValue);
if (cachedTuple) {
let selectededAreEqualToCached = true;
for (const key in cachedTuple[1]) {
if (cachedTuple[1][key] === newlySelected[key]) continue;
selectededAreEqualToCached = false;
break;
}
if (selectededAreEqualToCached) return cachedTuple[1];
}
cachedTuple = [currentValue, newlySelected];
return cachedTuple[1];
};
}, [store, selector2]);
const state = (0, import_shim.useSyncExternalStore)(wrappedSubscription, wrappedSnapshot);
return state;
}
// src/components/Dialog/hooks/useDialog.ts
var useDialog = ({ dialogManagerId, id }) => {
const { dialogManager } = useDialogManager({ dialogManagerId });
(0, import_react6.useEffect)(
() => () => {
dialogManager.markForRemoval(id);
},
[dialogManager, id]
);
return dialogManager.getOrCreate({ id });
};
var useDialogIsOpen = (id, dialogManagerId) => {
const { dialogManager } = useDialogManager({ dialogManagerId });
const dialogIsOpenSelector = (0, import_react6.useCallback)(
({ dialogsById }) => ({ isOpen: !!dialogsById[id]?.isOpen }),
[id]
);
return useStateStore(dialogManager.state, dialogIsOpenSelector).isOpen;
};
// src/components/Portal/Portal.ts
var import_react7 = require("react");
var import_react_dom = require("react-dom");
var Portal = ({
children,
getPortalDestination,
isOpen
}) => {
const [portalDestination, setPortalDestination] = (0, import_react7.useState)(null);
(0, import_react7.useLayoutEffect)(() => {
const destination = getPortalDestination();
if (!destination || !isOpen) return;
setPortalDestination(destination);
}, [getPortalDestination, isOpen]);
if (!portalDestination) return null;
return (0, import_react_dom.createPortal)(children, portalDestination);
};
// src/components/Dialog/DialogPortal.tsx
var DialogPortalEntry = ({
children,
dialogId
}) => {
const { dialogManager } = useDialogManager({ dialogId });
const dialogIsOpen = useDialogIsOpen(dialogId, dialogManager.id);
const getPortalDestination = (0, import_react8.useCallback)(
() => document.querySelector(`div[data-str-chat__portal-id="${dialogManager.id}"]`),
[dialogManager.id]
);
return /* @__PURE__ */ import_react8.default.createElement(Portal, { getPortalDestination, isOpen: dialogIsOpen }, children);
};
// src/context/DialogManagerContext.tsx
var dialogManagersRegistry = new import_stream_chat.StateStore({});
var DialogManagerProviderContext = import_react9.default.createContext(void 0);
var getManagerFromStore = ({
dialogId,
dialogManagerId,
newState,
previousState
}) => {
let managerInNewState;
let managerInPrevState;
if (dialogManagerId) {
if (!dialogId) {
managerInNewState = newState[dialogManagerId];
managerInPrevState = previousState?.[dialogManagerId];
} else {
if (newState[dialogManagerId]?.get(dialogId)) {
managerInNewState = newState[dialogManagerId];
}
if (previousState?.[dialogManagerId]?.get(dialogId)) {
managerInPrevState = previousState[dialogManagerId];
}
}
} else if (dialogId) {
managerInNewState = Object.values(newState).find(
(dialogMng) => dialogId && dialogMng?.get(dialogId)
);
managerInPrevState = previousState && Object.values(previousState).find(
(dialogMng) => dialogId && dialogMng?.get(dialogId)
);
}
return { managerInNewState, managerInPrevState };
};
var useDialogManager = ({
dialogId,
dialogManagerId
} = {}) => {
const nearestDialogManagerContext = (0, import_react9.useContext)(DialogManagerProviderContext);
const [dialogManagerContext, setDialogManagerContext] = (0, import_react9.useState)(() => {
const { managerInNewState } = getManagerFromStore({
dialogId,
dialogManagerId,
newState: dialogManagersRegistry.getLatestValue(),
previousState: void 0
});
return managerInNewState ? { dialogManager: managerInNewState } : nearestDialogManagerContext;
});
(0, import_react9.useEffect)(() => {
if (!dialogId && !dialogManagerId) return;
const unsubscribe = dialogManagersRegistry.subscribeWithSelector(
(state) => state,
(newState, previousState) => {
const { managerInNewState, managerInPrevState } = getManagerFromStore({
dialogId,
dialogManagerId,
newState,
previousState
});
if (!managerInPrevState || managerInNewState?.id !== managerInPrevState.id) {
setDialogManagerContext((prevState) => {
if (prevState?.dialogManager.id === managerInNewState?.id) return prevState;
return {
dialogManager: managerInNewState || nearestDialogManagerContext?.dialogManager
};
});
}
}
);
return () => {
unsubscribe();
};
}, [dialogId, dialogManagerId, nearestDialogManagerContext?.dialogManager]);
if (!dialogManagerContext?.dialogManager) {
console.warn(
`Dialog manager (manager id: ${dialogManagerId}, dialog id: ${dialogId}) is not available`
);
}
return dialogManagerContext;
};
// src/context/MessageContext.tsx
var import_react10 = __toESM(require("react"));
var MessageContext = import_react10.default.createContext(
void 0
);
var useMessageContext = (_componentName) => {
const contextValue = (0, import_react10.useContext)(MessageContext);
if (!contextValue) {
return {};
}
return contextValue;
};
// src/context/TranslationContext.tsx
var import_react11 = __toESM(require("react"));
var import_dayjs2 = __toESM(require("dayjs"));
var import_calendar = __toESM(require("dayjs/plugin/calendar"));
var import_localizedFormat = __toESM(require("dayjs/plugin/localizedFormat"));
// src/i18n/utils.ts
var import_dayjs = __toESM(require("dayjs"));
var defaultTranslatorFunction = (key) => key;
var defaultDateTimeParser = (input) => (0, import_dayjs.default)(input);
// src/context/TranslationContext.tsx
import_dayjs2.default.extend(import_calendar.default);
import_dayjs2.default.extend(import_localizedFormat.default);
var TranslationContext = import_react11.default.createContext({
t: defaultTranslatorFunction,
tDateTimeParser: defaultDateTimeParser,
userLanguage: "en"
});
var useTranslationContext = (componentName) => {
const contextValue = (0, import_react11.useContext)(TranslationContext);
if (!contextValue) {
console.warn(
`The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`
);
return {};
}
return contextValue;
};
// src/components/MessageInput/hooks/useMessageComposer.ts
var import_react37 = require("react");
var import_stream_chat2 = require("stream-chat");
// src/components/Threads/ThreadContext.tsx
var import_react12 = __toESM(require("react"));
var ThreadContext = (0, import_react12.createContext)(void 0);
var useThreadContext = () => (0, import_react12.useContext)(ThreadContext);
// src/components/Avatar/Avatar.tsx
var import_clsx = __toESM(require("clsx"));
var import_react14 = __toESM(require("react"));
// src/components/Threads/icons.tsx
var import_react13 = __toESM(require("react"));
var Icon = {
MessageBubble: (props) => /* @__PURE__ */ import_react13.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--message-bubble",
fill: "none",
height: "14",
viewBox: "0 0 14 14",
width: "14",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react13.default.createElement(
"path",
{
d: "M1.66659 1.66665H12.3333V9.66665H2.44659L1.66659 10.4466V1.66665ZM1.66659 0.333313C0.933252 0.333313 0.339919 0.933313 0.339919 1.66665L0.333252 13.6666L2.99992 11H12.3333C13.0666 11 13.6666 10.4 13.6666 9.66665V1.66665C13.6666 0.933313 13.0666 0.333313 12.3333 0.333313H1.66659ZM2.99992 6.99998H10.9999V8.33331H2.99992V6.99998ZM2.99992 4.99998H10.9999V6.33331H2.99992V4.99998ZM2.99992 2.99998H10.9999V4.33331H2.99992V2.99998Z",
fill: "currentColor"
}
)
),
MessageBubbleEmpty: (props) => /* @__PURE__ */ import_react13.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--message-bubble-empty",
fill: "none",
height: "20",
viewBox: "0 0 20 20",
width: "20",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react13.default.createElement(
"path",
{
d: "M18 0H2C0.9 0 0 0.9 0 2V20L4 16H18C19.1 16 20 15.1 20 14V2C20 0.9 19.1 0 18 0ZM18 14H4L2 16V2H18V14Z",
fill: "currentColor"
}
)
),
Reload: (props) => /* @__PURE__ */ import_react13.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--reload",
fill: "none",
height: "22",
viewBox: "0 0 16 22",
width: "16",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react13.default.createElement(
"path",
{
d: "M8 3V0L4 4L8 8V5C11.31 5 14 7.69 14 11C14 12.01 13.75 12.97 13.3 13.8L14.76 15.26C15.54 14.03 16 12.57 16 11C16 6.58 12.42 3 8 3ZM8 17C4.69 17 2 14.31 2 11C2 9.99 2.25 9.03 2.7 8.2L1.24 6.74C0.46 7.97 0 9.43 0 11C0 15.42 3.58 19 8 19V22L12 18L8 14V17Z",
fill: "currentColor"
}
)
),
User: (props) => /* @__PURE__ */ import_react13.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--user",
fill: "none",
height: "16",
viewBox: "0 0 16 16",
width: "16",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react13.default.createElement(
"path",
{
d: "M8 2C9.1 2 10 2.9 10 4C10 5.1 9.1 6 8 6C6.9 6 6 5.1 6 4C6 2.9 6.9 2 8 2ZM8 12C10.7 12 13.8 13.29 14 14H2C2.23 13.28 5.31 12 8 12ZM8 0C5.79 0 4 1.79 4 4C4 6.21 5.79 8 8 8C10.21 8 12 6.21 12 4C12 1.79 10.21 0 8 0ZM8 10C5.33 10 0 11.34 0 14V16H16V14C16 11.34 10.67 10 8 10Z",
fill: "currentColor"
}
)
)
};
// src/utils/getWholeChar.ts
var getWholeChar = (str, i) => {
const code4 = str.charCodeAt(i);
if (Number.isNaN(code4)) return "";
if (code4 < 55296 || code4 > 57343) return str.charAt(i);
if (55296 <= code4 && code4 <= 56319) {
if (str.length <= i + 1) {
throw "High surrogate without following low surrogate";
}
const next = str.charCodeAt(i + 1);
if (56320 > next || next > 57343) {
throw "High surrogate without following low surrogate";
}
return str.charAt(i) + str.charAt(i + 1);
}
if (i === 0) {
throw "Low surrogate without preceding high surrogate";
}
const prev = str.charCodeAt(i - 1);
if (55296 > prev || prev > 56319) {
throw "Low surrogate without preceding high surrogate";
}
return "";
};
// src/components/Avatar/Avatar.tsx
var Avatar = (props) => {
const {
className,
image: image3,
name: name2,
onClick = () => void 0,
onMouseOver = () => void 0
} = props;
const [error, setError] = (0, import_react14.useState)(false);
(0, import_react14.useEffect)(() => {
setError(false);
}, [image3]);
const nameStr = name2?.toString() || "";
const initials = getWholeChar(nameStr, 0);
const showImage = image3 && !error;
return /* @__PURE__ */ import_react14.default.createElement(
"div",
{
className: (0, import_clsx.default)(`str-chat__avatar str-chat__message-sender-avatar`, className, {
["str-chat__avatar--multiple-letters"]: initials.length > 1,
["str-chat__avatar--no-letters"]: !initials.length,
["str-chat__avatar--one-letter"]: initials.length === 1
}),
"data-testid": "avatar",
onClick,
onMouseOver,
role: "button",
title: name2
},
showImage ? /* @__PURE__ */ import_react14.default.createElement(
"img",
{
alt: initials,
className: "str-chat__avatar-image",
"data-testid": "avatar-img",
onError: () => setError(true),
src: image3
}
) : /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, null, !!initials.length && /* @__PURE__ */ import_react14.default.createElement(
"div",
{
className: (0, import_clsx.default)("str-chat__avatar-fallback"),
"data-testid": "avatar-fallback"
},
initials
), !initials.length && /* @__PURE__ */ import_react14.default.createElement(Icon.User, null))
);
};
// src/components/ChannelPreview/ChannelPreview.tsx
var import_lodash2 = __toESM(require("lodash.throttle"));
var import_react35 = __toESM(require("react"));
// src/components/ChannelPreview/ChannelPreviewMessenger.tsx
var import_react18 = __toESM(require("react"));
var import_clsx3 = __toESM(require("clsx"));
// src/components/ChannelPreview/ChannelPreviewActionButtons.tsx
var import_react17 = __toESM(require("react"));
var import_clsx2 = __toESM(require("clsx"));
// src/constants/limits.ts
var DEFAULT_JUMP_TO_PAGE_SIZE = 100;
var DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD = 250;
var DEFAULT_UPLOAD_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
// src/components/ChannelList/hooks/useSelectedChannelState.ts
var import_react15 = require("react");
var import_shim2 = require("use-sync-external-store/shim");
var noop2 = () => {
};
function useSelectedChannelState({
channel,
selector: selector2,
stateChangeEventKeys = ["all"]
}) {
const subscribe = (0, import_react15.useCallback)(
(onStoreChange) => {
if (!channel) return noop2;
const subscriptions = stateChangeEventKeys.map(
(et) => channel.on(et, () => {
onStoreChange(selector2(channel));
})
);
return () => subscriptions.forEach((subscription) => subscription.unsubscribe());
},
[channel, selector2, stateChangeEventKeys]
);
const getSnapshot = (0, import_react15.useCallback)(() => {
if (!channel) return void 0;
return selector2(channel);
}, [channel, selector2]);
return (0, import_shim2.useSyncExternalStore)(subscribe, getSnapshot);
}
// src/components/ChannelList/hooks/useChannelMembershipState.ts
var selector = (c) => c.state.membership;
var keys = ["member.updated"];
function useChannelMembershipState(channel) {
return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys });
}
// src/components/ChannelPreview/icons.tsx
var import_react16 = __toESM(require("react"));
var Icon2 = {
ArchiveBox: (props) => /* @__PURE__ */ import_react16.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--archive-box",
fill: "currentColor",
viewBox: "0 0 512 512",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react16.default.createElement("path", { d: "M32 32l448 0c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96L0 64C0 46.3 14.3 32 32 32zm0 128l448 0 0 256c0 35.3-28.7 64-64 64L96 480c-35.3 0-64-28.7-64-64l0-256zm128 80c0 8.8 7.2 16 16 16l160 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-160 0c-8.8 0-16 7.2-16 16z" })
),
Pin: (props) => /* @__PURE__ */ import_react16.default.createElement(
"svg",
{
className: "str-chat__icon str-chat__icon--pin",
fill: "currentColor",
viewBox: "0 0 384 512",
xmlns: "http://www.w3.org/2000/svg",
...props
},
/* @__PURE__ */ import_react16.default.createElement("path", { d: "M32 32C32 14.3 46.3 0 64 0L320 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-29.5 0 11.4 148.2c36.7 19.9 65.7 53.2 79.5 94.7l1 3c3.3 9.8 1.6 20.5-4.4 28.8s-15.7 13.3-26 13.3L32 352c-10.3 0-19.9-4.9-26-13.3s-7.7-19.1-4.4-28.8l1-3c13.8-41.5 42.8-74.8 79.5-94.7L93.5 64 64 64C46.3 64 32 49.7 32 32zM160 384l64 0 0 96c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-96z" })
)
};
// src/components/ChannelPreview/ChannelPreviewActionButtons.tsx
function ChannelPreviewActionButtons({
channel
}) {
const membership = useChannelMembershipState(channel);
const { t } = useTranslationContext();
return /* @__PURE__ */ import_react17.default.createElement("div", { className: "str-chat__channel-preview__action-buttons" }, /* @__PURE__ */ import_react17.default.createElement(
"button",
{
"aria-label": membership.pinned_at ? t("Unpin") : t("Pin"),
className: (0, import_clsx2.default)(
"str-chat__channel-preview__action-button",
"str-chat__channel-preview__action-button--pin",
membership.pinned_at && "str-chat__channel-preview__action-button--active"
),
onClick: (e) => {
e.stopPropagation();
if (membership.pinned_at) {
channel.unpin();
} else {
channel.pin();
}
},
title: membership.pinned_at ? t("Unpin") : t("Pin")
},
/* @__PURE__ */ import_react17.default.createElement(Icon2.Pin, null)
), /* @__PURE__ */ import_react17.default.createElement(
"button",
{
"aria-label": membership.archived_at ? t("Unarchive") : t("Archive"),
className: (0, import_clsx2.default)(
"str-chat__channel-preview__action-button",
"str-chat__channel-preview__action-button--archive",
membership.archived_at && "str-chat__channel-preview__action-button--active"
),
onClick: (e) => {
e.stopPropagation();
if (membership.archived_at) {
channel.unarchive();
} else {
channel.archive();
}
},
title: membership.archived_at ? t("Unarchive") : t("Archive")
},
/* @__PURE__ */ import_react17.default.createElement(Icon2.ArchiveBox, null)
));
}
// src/components/ChannelPreview/ChannelPreviewMessenger.tsx
var UnMemoizedChannelPreviewMessenger = (props) => {
const {
active,
Avatar: Avatar2 = Avatar,
channel,
className: customClassName = "",
displayImage,
displayTitle,
groupChannelDisplayInfo,
latestMessagePreview,
onSelect: customOnSelectChannel,
setActiveChannel,
unread,
watchers
} = props;
const { ChannelPreviewActionButtons: ChannelPreviewActionButtons2 = ChannelPreviewActionButtons } = useComponentContext();
const channelPreviewButton = (0, import_react18.useRef)(null);
const avatarName = displayTitle || channel.state.messages[channel.state.messages.length - 1]?.user?.id;
const onSelectChannel = (e) => {
if (customOnSelectChannel) {
customOnSelectChannel(e);
} else if (setActiveChannel) {
setActiveChannel(channel, watchers);
}
if (channelPreviewButton?.current) {
channelPreviewButton.current.blur();
}
};
return /* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-container" }, /* @__PURE__ */ import_react18.default.createElement(ChannelPreviewActionButtons2, { channel }), /* @__PURE__ */ import_react18.default.createElement(
"button",
{
"aria-label": `Select Channel: ${displayTitle || ""}`,
"aria-selected": active,
className: (0, import_clsx3.default)(
`str-chat__channel-preview-messenger str-chat__channel-preview`,
active && "str-chat__channel-preview-messenger--active",
unread && unread >= 1 && "str-chat__channel-preview-messenger--unread",
customClassName
),
"data-testid": "channel-preview-button",
onClick: onSelectChannel,
ref: channelPreviewButton,
role: "option"
},
/* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-messenger--left" }, /* @__PURE__ */ import_react18.default.createElement(
Avatar2,
{
className: "str-chat__avatar--channel-preview",
groupChannelDisplayInfo,
image: displayImage,
name: avatarName
}
)),
/* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-end" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-end-first-row" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-messenger--name" }, /* @__PURE__ */ import_react18.default.createElement("span", null, displayTitle)), !!unread && /* @__PURE__ */ import_react18.default.createElement(
"div",
{
className: "str-chat__channel-preview-unread-badge",
"data-testid": "unread-badge"
},
unread
)), /* @__PURE__ */ import_react18.default.createElement("div", { className: "str-chat__channel-preview-messenger--last-message" }, latestMessagePreview))
));
};
var ChannelPreviewMessenger = import_react18.default.memo(
UnMemoizedChannelPreviewMessenger
);
// src/components/ChannelPreview/hooks/useIsChannelMuted.ts
var import_react19 = require("react");
var useIsChannelMuted = (channel) => {
const { client } = useChatContext("useIsChannelMuted");
const [muted, setMuted] = (0, import_react19.useState)(channel.muteStatus());
(0, import_react19.useEffect)(() => {
const handleEvent = () => setMuted(channel.muteStatus());
client.on("notification.channel_mutes_updated", handleEvent);
return () => client.off("notification.channel_mutes_updated", handleEvent);
}, [muted]);
return muted;
};
// src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts
var import_react33 = require("react");
// src/components/ChannelPreview/utils.tsx
var import_react32 = __toESM(require("react"));
// node_modules/devlop/lib/default.js
function ok() {
}
function unreachable() {
}
// node_modules/comma-separated-tokens/index.js
function stringify(values, options) {
const settings = options || {};
const input = values[values.length - 1] === "" ? [...values, ""] : values;
return input.join(
(settings.padRight ? " " : "") + "," + (settings.padLeft === false ? "" : " ")
).trim();
}
// node_modules/estree-util-is-identifier-name/lib/index.js
var nameRe = /^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
var nameReJsx = /^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u;
var emptyOptions = {};
function name(name2, options) {
const settings = options || emptyOptions;
const re2 = settings.jsx ? nameReJsx : nameRe;
return re2.test(name2);
}
// node_modules/hast-util-whitespace/lib/index.js
var re = /[ \t\n\f\r]/g;
function whitespace(thing) {
return typeof thing === "object" ? thing.type === "text" ? empty(thing.value) : false : empty(thing);
}
function empty(value) {
return value.replace(re, "") === "";
}
// node_modules/property-information/lib/util/schema.js
var Schema = class {
/**
* @constructor
* @param {Properties} property
* @param {Normal} normal
* @param {string} [space]
*/
constructor(property, normal, space2) {
this.property = property;
this.normal = normal;
if (space2) {
this.space = space2;
}
}
};
Schema.prototype.property = {};
Schema.prototype.normal = {};
Schema.prototype.space = null;
// node_modules/property-information/lib/util/merge.js
function merge(definitions, space2) {
const property = {};
const normal = {};
let index2 = -1;
while (++index2 < definitions.length) {
Object.assign(property, definitions[index2].property);
Object.assign(normal, definitions[index2].normal);
}
return new Schema(property, normal, space2);
}
// node_modules/property-information/lib/normalize.js
function normalize(value) {
return value.toLowerCase();
}
// node_modules/property-information/lib/util/info.js
var Info = class {
/**
* @constructor
* @param {string} property
* @param {string} attribute
*/
constructor(property, attribute) {
this.property = property;
this.attribute = attribute;
}
};
Info.prototype.space = null;
Info.prototype.boolean = false;
Info.prototype.booleanish = false;
Info.prototype.overloadedBoolean = false;
Info.prototype.number = false;
Info.prototype.commaSeparated = false;
Info.prototype.spaceSeparated = false;
Info.prototype.commaOrSpaceSeparated = false;
Info.prototype.mustUseProperty = false;
Info.prototype.defined = false;
// node_modules/property-information/lib/util/types.js
var types_exports = {};
__export(types_exports, {
boolean: () => boolean,
booleanish: () => booleanish,
commaOrSpaceSeparated: () => commaOrSpaceSeparated,
commaSeparated: () => commaSeparated,
number: () => number,
overloadedBoolean: () => overloadedBoolean,
spaceSeparated: () => spaceSeparated
});
var powers = 0;
var boolean = increment();
var booleanish = increment();
var overloadedBoolean = increment();
var number = increment();
var spaceSeparated = increment();
var commaSeparated = increment();
var commaOrSpaceSeparated = increment();
function increment() {
return 2 ** ++powers;
}
// node_modules/property-information/lib/util/defined-info.js
var checks = Object.keys(types_exports);
var DefinedInfo = class extends Info {
/**
* @constructor
* @param {string} property
* @param {string} attribute
* @param {number|null} [mask]
* @param {string} [space]
*/
constructor(property, attribute, mask, space2) {
let index2 = -1;
super(property, attribute);
mark(this, "space", space2);
if (typeof mask === "number") {
while (++index2 < checks.length) {
const check = checks[index2];
mark(this, checks[index2], (mask & types_exports[check]) === types_exports[check]);
}
}
}
};
DefinedInfo.prototype.defined = true;
function mark(values, key, value) {
if (value) {
values[key] = value;
}
}
// node_modules/property-information/lib/util/create.js
var own = {}.hasOwnProperty;
function create(definition3) {
const property = {};
const normal = {};
let prop;
for (prop in definition3.properties) {
if (own.call(definition3.properties, prop)) {
const value = definition3.properties[prop];
const info = new DefinedInfo(
prop,
definition3.transform(definition3.attributes || {}, prop),
value,
definition3.space
);
if (definition3.mustUseProperty && definition3.mustUseProperty.includes(prop)) {
info.mustUseProperty = true;
}
property[prop] = info;
normal[normalize(prop)] = prop;
normal[normalize(info.attribute)] = prop;
}
}
return new Schema(property, normal, definition3.space);
}
// node_modules/property-information/lib/xlink.js
var xlink = create({
space: "xlink",
transform(_, prop) {
return "xlink:" + prop.slice(5).toLowerCase();
},
properties: {
xLinkActuate: null,
xLinkArcRole: null,
xLinkHref: null,
xLinkRole: null,
xLinkShow: null,
xLinkTitle: null,
xLinkType: null
}
});
// node_modules/property-information/lib/xml.js
var xml = create({
space: "xml",
transform(_, prop) {
return "xml:" + prop.slice(3).toLowerCase();
},
properties: { xmlLang: null, xmlBase: null, xmlSpace: null }
});
// node_modules/property-information/lib/util/case-sensitive-transform.js
function caseSensitiveTransform(attributes, attribute) {
return attribute in attributes ? attributes[attribute] : attribute;
}
// node_modules/property-information/lib/util/case-insensitive-transform.js
function caseInsensitiveTransform(attributes, property) {
return caseSensitiveTransform(attributes, property.toLowerCase());
}
// node_modules/property-information/lib/xmlns.js
var xmlns = create({
space: "xmlns",
attributes: { xmlnsxlink: "xmlns:xlink" },
transform: caseInsensitiveTransform,
properties: { xmlns: null, xmlnsXLink: null }
});
// node_modules/property-information/lib/aria.js
var aria = create({
transform(_, prop) {
return prop === "role" ? prop : "aria-" + prop.slice(4).toLowerCase();
},
properties: {
ariaActiveDescendant: null,
ariaAtomic: booleanish,
ariaAutoComplete: null,
ariaBusy: booleanish,
ariaChecked: booleanish,
ariaColCount: number,
ariaColIndex: number,
ariaColSpan: number,
ariaControls: spaceSeparated,
ariaCurrent: null,
ariaDescribedBy: spaceSeparated,
ariaDetails: null,
ariaDisabled: booleanish,
ariaDropEffect: spaceSeparated,
ariaErrorMessage: null,
ariaExpanded: booleanish,
ariaFlowTo: spaceSeparated,
ariaGrabbed: booleanish,
ariaHasPopup: null,
ariaHidden: booleanish,
ariaInvalid: null,
ariaKeyShortcuts: null,
ariaLabel: null,
ariaLabelledBy: spaceSeparated,
ariaLevel: number,
ariaLive: null,
ariaModal: booleanish,
ariaMultiLine: booleanish,
ariaMultiSelectable: booleanish,
ariaOrientation: null,
ariaOwns: spaceSeparated,
ariaPlaceholder: null,
ariaPosInSet: number,
ariaPressed: booleanish,
ariaReadOnly: booleanish,
ariaRelevant: null,
ariaRequired: booleanish,
ariaRoleDescription: spaceSeparated,
ariaRowCount: number,
ariaRowIndex: number,
ariaRowSpan: number,
ariaSelected: booleanish,
ariaSetSize: number,
ariaSort: null,
ariaValueMax: number,
ariaValueMin: number,
ariaValueNow: number,
ariaValueText: null,
role: null
}
});
// node_modules/property-information/lib/html.js
var html = create({
space: "html",
attributes: {
acceptcharset: "accept-charset",
classname: "class",
htmlfor: "for",
httpequiv: "http-equiv"
},
transform: caseInsensitiveTransform,
mustUseProperty: ["checked", "multiple", "muted", "selected"],
properties: {
// Standard Properties.
abbr: null,
accept: commaSeparated,
acceptCharset: spaceSeparated,
accessKey: spaceSeparated,
action: null,
allow: null,
allowFullScreen: boolean,
allowPaymentRequest: boolean,
allowUserMedia: boolean,
alt: null,
as: null,
async: boolean,
autoCapitalize: null,
autoComplete: spaceSeparated,
autoFocus: boolean,
autoPlay: boolean,
blocking: spaceSeparated,
capture: boolean,
charSet: null,
checked: boolean,
cite: null,
className: spaceSeparated,
cols: number,
colSpan: null,
content: null,
contentEditable: booleanish,
controls: boolean,
controlsList: spaceSeparated,
coords: number | commaSeparated,
crossOrigin: null,
data: null,
dateTime: null,
decoding: null,
default: boolean,
defer: boolean,
dir: null,
dirName: null,
disabled: boolean,
download: overloadedBoolean,
draggable: booleanish,
encType: null,
enterKeyHint: null,
fetchPriority: null,
form: null,
formAction: null,
formEncType: null,
formMethod: null,
formNoValidate: boolean,
formTarget: null,
headers: spaceSeparated,
height: number,
hidden: boolean,
high: number,
href: null,
hrefLang: null,
htmlFor: spaceSeparated,
httpEquiv: spaceSeparated,
id: null,
imageSizes: null,
imageSrcSet: null,
inert: boolean,
inputMode: null,
integrity: null,
is: null,
isMap: boolean,
itemId: null,
itemProp: spaceSeparated,
itemRef: spaceSeparated,
itemScope: boolean,
itemType: spaceSeparated,
kind: null,
label: null,
lang: null,
language: null,
list: null,
loading: null,
loop: boolean,
low: number,
manifest: null,
max: null,
maxLength: number,
media: null,
method: null,
min: null,
minLength: number,
multiple: boolean,
muted: boolean,
name: null,
nonce: null,
noModule: boolean,
noValidate: boolean,
onAbort: null,
onAfterPrint: null,
onAuxClick: null,
onBeforeMatch: null,
onBeforePrint: null,
onBeforeToggle: null,
onBeforeUnload: null,
onBlur: null,
onCancel: null,
onCanPlay: null,
onCanPlayThrough: null,
onChange: null,
onClick: null,
onClose: null,
onContextLost: null,
onContextMenu: null,
onContextRestored: null,
onCopy: null,
onCueChange: null,
onCut: null,
onDblClick: null,
onDrag: null,
onDragEnd: null,
onDragEnter: null,
onDragExit: null,
onDragLeave: null,
onDragOver: null,
onDragStart: null,
onDrop: null,
onDurationChange: null,
onEmptied: null,
onEnded: null,
onError: null,
onFocus: null,
onFormData: null,
onHashChange: null,
onInput: null,
onInvalid: null,
onKeyDown: null,
onKeyPress: null,
onKeyUp: null,
onLanguageChange: null,
onLoad: null,
onLoadedData: null,
onLoadedMetadata: null,
onLoadEnd: null,
onLoadStart: null,
onMessage: null,
onMessageError: null,
onMouseDown: null,
onMouseEnter: null,
onMouseLeave: null,
onMouseMove: null,
onMouseOut: null,
onMouseOver: null,
onMouseUp: null,
onOffline: null,
onOnline: null,
onPageHide: null,
onPageShow: null,
onPaste: null,
onPause: null,
onPlay: null,
onPlaying: null,
onPopState: null,
onProgress: null,
onRateChange: null,
onRejectionHandled: null,
onReset: null,
onResize: null,
onScroll: null,
onScrollEnd: null,
onSecurityPolicyViolation: null,
onSeeked: null,
onSeeking: null,
onSelect: null,
onSlotChange: null,
onStalled: null,
onStorage: null,
onSubmit: null,
onSuspend: null,
onTimeUpdate: null,
onToggle: null,
onUnhandledRejection: null,
onUnload: null,
onVolumeChange: null,
onWaiting: null,
onWheel: null,
open: boolean,
optimum: number,
pattern: null,
ping: spaceSeparated,
placeholder: null,
playsInline: boolean,
popover: null,
popoverTarget: null,
popoverTargetAction: null,
poster: null,
preload: null,
readOnly: boolean,
referrerPolicy: null,
rel: spaceSeparated,
required: boolean,
reversed: boolean,
rows: number,
rowSpan: number,
sandbox: spaceSeparated,
scope: null,
scoped: boolean,
seamless: boolean,
selected: boolean,
shadowRootDelegatesFocus: boolean,
shadowRootMode: null,
shape: null,
size: number,
sizes: null,
slot: null,
span: number,
spellCheck: booleanish,
src: null,
srcDoc: null,
srcLang: null,
srcSet: null,
start: number,
step: null,
style: null,
tabIndex: number,
target: null,
title: null,
translate: null,
type: null,
typeMustMatch: boolean,
useMap: null,
value: booleanish,
width: number,
wrap: null,
// Legacy.
// See: https://html.spec.whatwg.org/#other-elements,-attributes-and-apis
align: null,
// Several. Use CSS `text-align` instead,
aLink: null,
// `<body>`. Use CSS `a:active {color}` instead
archive: spaceSeparated,
// `<object>`. List of URIs to archives
axis: null,
// `<td>` and `<th>`. Use `scope` on `<th>`
background: null,
// `<body>`. Use CSS `background-image` instead
bgColor: null,
// `<body>` and table elements. Use CSS `background-color` instead
border: number,
// `<t