UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

1,519 lines (1,462 loc) 523 kB
"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