@linktr.ee/messaging-react 1.36.0 → 1.38.0-rc-1777583423

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.
Files changed (30) hide show
  1. package/dist/Card-BlXnKGaR.js +127 -0
  2. package/dist/Card-BlXnKGaR.js.map +1 -0
  3. package/dist/Card-DoNJA-jg.js +138 -0
  4. package/dist/Card-DoNJA-jg.js.map +1 -0
  5. package/dist/{index-DOsC03ZN.js → index-jnKl3mQ0.js} +1404 -1352
  6. package/dist/index-jnKl3mQ0.js.map +1 -0
  7. package/dist/index.d.ts +21 -1
  8. package/dist/index.js +15 -13
  9. package/package.json +2 -2
  10. package/src/components/{LockedAttachment/components → AttachmentCard}/MediaPlayer.tsx +4 -3
  11. package/src/components/AttachmentCard/Thumbnail.tsx +150 -0
  12. package/src/components/AttachmentCard/index.tsx +112 -0
  13. package/src/components/LockedAttachment/components/Creator/Card.tsx +123 -113
  14. package/src/components/LockedAttachment/components/Visitor/Card.tsx +43 -42
  15. package/src/components/LockedAttachment/components/Visitor/LockBadge.tsx +12 -0
  16. package/src/components/MediaMessage/MediaMessage.stories.tsx +45 -4
  17. package/src/components/MediaMessage/MediaMessage.test.tsx +125 -160
  18. package/src/components/MediaMessage/index.tsx +226 -349
  19. package/src/index.ts +7 -3
  20. package/src/providers/MessagingProvider.test.tsx +126 -0
  21. package/dist/Card-BHrnmHeu.js +0 -167
  22. package/dist/Card-BHrnmHeu.js.map +0 -1
  23. package/dist/Card-D4vEgqWt.js +0 -195
  24. package/dist/Card-D4vEgqWt.js.map +0 -1
  25. package/dist/index-DOsC03ZN.js.map +0 -1
  26. package/src/components/LockedAttachment/components/Creator/CardThumbnail.tsx +0 -114
  27. package/src/components/LockedAttachment/components/Visitor/CardThumbnail.tsx +0 -81
  28. /package/src/components/{LockedAttachment → AttachmentCard}/utils/icons.ts +0 -0
  29. /package/src/components/{LockedAttachment → AttachmentCard}/utils/mimeType.test.ts +0 -0
  30. /package/src/components/{LockedAttachment → AttachmentCard}/utils/mimeType.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-jnKl3mQ0.js","sources":["../src/providers/MessagingProvider.tsx","../src/hooks/useMessaging.ts","../src/hooks/useRestorePendingMessages.ts","../src/components/ChannelList/ChannelListContext.tsx","../src/hooks/useChannelStar.ts","../src/utils/formatRelativeTime.ts","../src/components/Avatar/getAvatarEmoji.ts","../src/components/Avatar/index.tsx","../src/components/CustomMessage/MessageTag.tsx","../src/components/ChannelList/CustomChannelPreview.tsx","../src/components/ChannelList/index.tsx","../src/components/ActionButton/index.tsx","../src/components/IconButton/index.tsx","../src/components/CloseButton/index.tsx","../src/components/ChannelInfoDialog/index.tsx","../src/components/CustomDateSeparator/index.tsx","../src/hooks/useMessageVote.ts","../src/components/LockedAttachment/index.tsx","../src/components/LockedAttachment/types.ts","../src/components/CustomMessage/context.tsx","../src/components/CustomMessage/MessageVoteButtons.tsx","../src/components/CustomMessage/index.tsx","../src/components/CustomLinkPreviewList/index.tsx","../src/components/CustomMessageInput/index.tsx","../src/components/CustomSystemMessage/index.tsx","../src/components/CustomTypingIndicator/index.tsx","../src/components/MessagingShell/ChannelEmptyState.tsx","../src/components/Loading/index.tsx","../src/components/MessagingShell/LoadingState.tsx","../src/components/ChannelView.tsx","../src/components/SearchInput/index.tsx","../src/components/ParticipantPicker/index.tsx","../src/components/MessagingShell/EmptyState.tsx","../src/components/MessagingShell/ErrorState.tsx","../src/components/MessagingShell/index.tsx","../src/components/FaqList/FaqListItem.tsx","../src/components/FaqList/index.tsx","../src/components/AttachmentCard/utils/mimeType.ts","../src/components/AttachmentCard/utils/icons.ts","../src/components/AttachmentCard/MediaPlayer.tsx","../src/components/AttachmentCard/Thumbnail.tsx","../src/components/AttachmentCard/index.tsx","../src/components/MediaMessage/index.tsx","../src/hooks/useParticipants.ts"],"sourcesContent":["import { StreamChatService } from '@linktr.ee/messaging-core'\nimport React, {\n createContext,\n useContext,\n useEffect,\n useState,\n useRef,\n useCallback,\n} from 'react'\nimport type { StreamChat } from 'stream-chat'\nimport { Chat } from 'stream-chat-react'\n\nimport type { MessagingProviderProps, MessagingCapabilities } from '../types'\n\n/**\n * Context value for messaging state and service\n */\nexport interface MessagingContextValue {\n service: StreamChatService | null\n client: StreamChat | null // Stream Chat client\n isConnected: boolean\n isLoading: boolean\n error: string | null\n capabilities: MessagingCapabilities\n refreshConnection: () => Promise<void>\n debug: boolean\n}\n\nconst MessagingContext = createContext<MessagingContextValue>({\n service: null,\n client: null,\n isConnected: false,\n isLoading: false,\n error: null,\n capabilities: {},\n refreshConnection: async () => {},\n debug: false,\n})\n\n/**\n * Hook to access messaging context\n */\nexport const useMessagingContext = () => useContext(MessagingContext)\n\n/**\n * Provider component that wraps messaging-core with React state management\n */\nexport const MessagingProvider: React.FC<MessagingProviderProps> = ({\n children,\n user,\n serviceConfig,\n apiKey,\n capabilities = {},\n debug = false,\n}) => {\n // Create debug logger that respects the debug prop\n const debugLog = useCallback(\n (message: string, ...args: unknown[]) => {\n if (debug) {\n console.log(`🔥 [MessagingProvider] ${message}`, ...args)\n }\n },\n [debug]\n )\n\n debugLog('🔄 RENDER START', {\n userId: user?.id,\n apiKey: apiKey?.substring(0, 8) + '...',\n serviceConfig: !!serviceConfig,\n capabilities: Object.keys(capabilities),\n })\n\n const [service, setService] = useState<StreamChatService | null>(null)\n const [client, setClient] = useState<StreamChat | null>(null)\n const [isConnected, setIsConnected] = useState(false)\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n // Prevent multiple concurrent connection attempts\n const connectingRef = useRef(false)\n\n // Track renders and prop changes\n const prevPropsRef = useRef({\n userId: user?.id,\n apiKey,\n serviceConfig,\n capabilities,\n })\n const renderCountRef = useRef(0)\n renderCountRef.current++\n\n debugLog('📊 RENDER INFO', {\n renderCount: renderCountRef.current,\n currentProps: { userId: user?.id, apiKey: apiKey?.substring(0, 8) + '...' },\n propChanges: {\n userChanged: prevPropsRef.current.userId !== user?.id,\n apiKeyChanged: prevPropsRef.current.apiKey !== apiKey,\n serviceConfigChanged:\n prevPropsRef.current.serviceConfig !== serviceConfig,\n capabilitiesChanged: prevPropsRef.current.capabilities !== capabilities,\n },\n })\n\n prevPropsRef.current = {\n userId: user?.id,\n apiKey,\n serviceConfig,\n capabilities,\n }\n\n // Initialize service when config changes\n useEffect(() => {\n const currentRender = renderCountRef.current\n debugLog('🔧 SERVICE INIT EFFECT TRIGGERED', {\n renderCount: currentRender,\n apiKey: !!apiKey,\n serviceConfig: !!serviceConfig,\n dependencies: {\n apiKey: apiKey?.substring(0, 8) + '...',\n serviceConfigRef: serviceConfig,\n serviceConfigStable:\n prevPropsRef.current.serviceConfig === serviceConfig,\n apiKeyStable: prevPropsRef.current.apiKey === apiKey,\n },\n })\n\n if (!apiKey || !serviceConfig) {\n debugLog('⚠️ SERVICE INIT SKIPPED', {\n renderCount: currentRender,\n reason: 'Missing apiKey or serviceConfig',\n })\n return\n }\n\n debugLog('🚀 CREATING NEW SERVICE', {\n renderCount: currentRender,\n apiKey: apiKey?.substring(0, 8) + '...',\n serviceConfigChanged:\n prevPropsRef.current.serviceConfig !== serviceConfig,\n })\n\n const newService = new StreamChatService({\n ...serviceConfig,\n apiKey,\n debug,\n })\n\n setService(newService)\n debugLog('✅ SERVICE SET', {\n renderCount: currentRender,\n serviceInstance: !!newService,\n })\n\n return () => {\n debugLog('🧹 SERVICE CLEANUP', {\n renderCount: currentRender,\n reason: 'Effect cleanup',\n })\n newService.disconnectUser().catch(console.error)\n }\n }, [apiKey, serviceConfig, debug, debugLog]) // Use serviceConfig object directly, not individual properties\n\n // Track if we've already connected this user with this service to prevent duplicate connections\n const connectedUserRef = useRef<{\n serviceId: StreamChatService\n userId: string\n } | null>(null)\n\n // Connect user when service and user are available\n useEffect(() => {\n debugLog('🔗 USER CONNECTION EFFECT TRIGGERED', {\n hasService: !!service,\n hasUser: !!user,\n userId: user?.id,\n isConnecting: connectingRef.current,\n isConnected: isConnected,\n dependencies: { service: !!service, userId: user?.id },\n })\n\n if (!service || !user) {\n debugLog('⚠️ USER CONNECTION SKIPPED', 'Missing service or user')\n return\n }\n\n if (connectingRef.current) {\n debugLog('⚠️ USER CONNECTION SKIPPED', 'Already connecting')\n return\n }\n\n // Check if we've already connected this exact user with this exact service instance\n if (\n connectedUserRef.current?.serviceId === service &&\n connectedUserRef.current?.userId === user.id\n ) {\n debugLog(\n '⚠️ USER CONNECTION SKIPPED',\n 'Already connected this user with this service'\n )\n return\n }\n\n const connectUser = async () => {\n debugLog('🚀 STARTING USER CONNECTION', { userId: user.id })\n connectingRef.current = true\n setIsLoading(true)\n setError(null)\n\n try {\n debugLog('📞 CALLING SERVICE.CONNECTUSER', { userId: user.id })\n const streamClient = await service.connectUser(user)\n setClient(streamClient)\n setIsConnected(true)\n connectedUserRef.current = { serviceId: service, userId: user.id } // Mark as connected\n debugLog('✅ USER CONNECTION SUCCESS', {\n userId: user.id,\n clientId: streamClient.userID,\n })\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : 'Connection failed'\n setError(errorMessage)\n debugLog('❌ USER CONNECTION ERROR', {\n userId: user.id,\n error: errorMessage,\n })\n } finally {\n setIsLoading(false)\n connectingRef.current = false\n debugLog('🔄 USER CONNECTION FINISHED', {\n userId: user.id,\n isConnected,\n })\n }\n }\n\n connectUser()\n }, [service, user, debugLog, isConnected]) // Remove isConnected to prevent circular dependency\n\n // Disconnect when user is removed (cleanup effect)\n useEffect(() => {\n debugLog('🔌 CLEANUP EFFECT REGISTERED', {\n hasService: !!service,\n isConnected,\n })\n return () => {\n if (service && isConnected) {\n debugLog(\n '🧹 CLEANUP EFFECT TRIGGERED',\n 'Cleaning up connection on unmount'\n )\n connectedUserRef.current = null // Reset connection tracking\n service.disconnectUser().catch(console.error)\n } else {\n debugLog('🔇 CLEANUP EFFECT SKIPPED', {\n hasService: !!service,\n isConnected,\n })\n }\n }\n }, [service, isConnected, debugLog])\n\n const refreshConnection = useCallback(async () => {\n debugLog('🔄 REFRESH CONNECTION CALLED', {\n hasService: !!service,\n hasUser: !!user,\n })\n\n if (!service || !user) {\n debugLog('⚠️ REFRESH CONNECTION SKIPPED', 'Missing service or user')\n return\n }\n\n debugLog('🚀 STARTING CONNECTION REFRESH', { userId: user.id })\n setIsLoading(true)\n try {\n debugLog('🔌 DISCONNECTING FOR REFRESH')\n await service.disconnectUser()\n debugLog('📞 RECONNECTING FOR REFRESH')\n const streamClient = await service.connectUser(user)\n setClient(streamClient)\n setIsConnected(true)\n setError(null)\n debugLog('✅ CONNECTION REFRESH SUCCESS', { userId: user.id })\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Refresh failed'\n setError(errorMessage)\n debugLog('❌ CONNECTION REFRESH ERROR', {\n userId: user.id,\n error: errorMessage,\n })\n } finally {\n setIsLoading(false)\n debugLog('🔄 CONNECTION REFRESH FINISHED', { userId: user.id })\n }\n }, [service, user, debugLog])\n\n // Memoize context value to prevent unnecessary re-renders\n const contextValue: MessagingContextValue = React.useMemo(() => {\n debugLog('💫 CONTEXT VALUE MEMOIZATION', {\n hasService: !!service,\n hasClient: !!client,\n isConnected,\n isLoading,\n hasError: !!error,\n capabilitiesKeys: Object.keys(capabilities),\n })\n\n return {\n service,\n client,\n isConnected,\n isLoading,\n error,\n capabilities,\n refreshConnection,\n debug,\n }\n }, [\n service,\n client,\n isConnected,\n isLoading,\n error,\n capabilities,\n refreshConnection,\n debug,\n debugLog,\n ])\n\n debugLog('🔄 RENDER END', {\n renderCount: renderCountRef.current,\n willRenderChat: !!(client && isConnected),\n contextValueReady: !!contextValue,\n })\n\n return (\n <MessagingContext.Provider value={contextValue}>\n {client && isConnected ? (\n <Chat\n client={client}\n customClasses={{\n channelList:\n 'str-chat__channel-list str-chat__channel-list-react bg-transparent lg:border-r-2 border-r-0 border-[#0000000A]',\n }}\n >\n {children}\n </Chat>\n ) : (\n children\n )}\n </MessagingContext.Provider>\n )\n}\n","import { useMessagingContext } from '../providers/MessagingProvider';\nimport type { MessagingContextValue } from '../providers/MessagingProvider';\n\n/**\n * Hook to access messaging service and state\n */\nexport const useMessaging = (): MessagingContextValue => {\n return useMessagingContext();\n};\n","import type { Channel } from 'stream-chat'\n\n/**\n * Restores pending messages into the channel's visible message list so they\n * appear as if they were already sent.\n *\n * Stream's pending-messages feature removes messages from the channel view\n * once client state is lost (e.g. page refresh). This function works around\n * that limitation by reading `channel.state.pending_messages` and\n * re-inserting them via `channel.state.addMessageSorted`.\n */\nexport function restorePendingMessages(channel: Channel) {\n const pendingMessages = channel.state.pending_messages\n if (!pendingMessages?.length) return\n\n for (const pending of pendingMessages) {\n channel.state.addMessageSorted(pending.message)\n }\n}\n","import React from 'react'\nimport type { Channel, LocalMessage } from 'stream-chat'\n\ntype ChannelListContextValue = {\n selectedChannel?: Channel | null\n onChannelSelect: (channel: Channel) => void\n debug: boolean\n renderMessagePreview?: (\n message: LocalMessage | undefined,\n defaultPreview?: string\n ) => React.ReactNode\n}\n\nconst ChannelListContext = React.createContext<ChannelListContextValue>({\n selectedChannel: undefined,\n onChannelSelect: () => {},\n debug: false,\n renderMessagePreview: undefined,\n})\n\nexport const ChannelListProvider = ChannelListContext.Provider\n\nexport const useChannelListContext = () => React.useContext(ChannelListContext)\n","import { useEffect, useState } from 'react'\nimport { Channel, Event } from 'stream-chat'\n\nexport const useChannelStar = (channel?: Channel) => {\n const [isChannelStarred, setIsChannelStarred] = useState(\n !!channel?.state?.membership?.pinned_at\n )\n\n useEffect(() => {\n if (!channel) {\n setIsChannelStarred(false)\n return\n }\n\n setIsChannelStarred(!!channel.state.membership?.pinned_at)\n\n const handleMemberUpdate = (event: Event) => {\n setIsChannelStarred(\n event?.member ? !!event.member.pinned_at : !!channel.state.membership?.pinned_at\n )\n }\n\n channel.on('member.updated', handleMemberUpdate)\n\n return () => {\n channel.off('member.updated', handleMemberUpdate)\n }\n }, [channel])\n\n return isChannelStarred\n}\n","/**\n * Get the number of days between two dates (calendar days in UTC, not 24-hour periods)\n * Uses UTC to ensure consistent day calculations globally since messages are stored in UTC\n */\nconst getDaysDifference = (date1: Date, date2: Date): number => {\n const d1 = new Date(\n Date.UTC(date1.getUTCFullYear(), date1.getUTCMonth(), date1.getUTCDate())\n )\n const d2 = new Date(\n Date.UTC(date2.getUTCFullYear(), date2.getUTCMonth(), date2.getUTCDate())\n )\n const diffTime = d2.getTime() - d1.getTime()\n return Math.floor(diffTime / (1000 * 60 * 60 * 24))\n}\n\n/**\n * Format a date - shows time for today, relative time for older messages\n * (e.g., \"Just now\", \"2:08 PM\" for today, \"Yesterday\" for yesterday, \"2d\" for 2 days ago)\n */\nexport const formatRelativeTime = (date: Date): string => {\n const now = new Date()\n const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)\n\n // Less than 1 minute\n if (diffInSeconds < 60) {\n return 'Just now'\n }\n\n // Check if it's today (same calendar day)\n const daysDiff = getDaysDifference(date, now)\n\n // If today, show time in 12-hour format (e.g., \"8:40 PM\")\n if (daysDiff === 0) {\n return date.toLocaleTimeString([], {\n hour: 'numeric',\n minute: '2-digit',\n hour12: true,\n })\n }\n\n // Yesterday\n if (daysDiff === 1) {\n return 'Yesterday'\n }\n\n // Less than 7 days - show days\n if (daysDiff < 7) {\n return `${daysDiff}d`\n }\n\n // Less than 4 weeks - show weeks\n if (daysDiff < 28) {\n const weeks = Math.floor(daysDiff / 7)\n return `${weeks}w`\n }\n\n // More than 4 weeks - show date as MM/DD/YY\n return date.toLocaleDateString('en-US', {\n month: 'numeric',\n day: 'numeric',\n year: '2-digit',\n })\n}\n","/**\n * Generate a fruit emoji based on a string id\n * Returns a consistent fruit emoji for the same id\n */\nconst EMOJIS = [\n '🍎', // Apple\n '🍌', // Banana\n '🍇', // Grape\n '🍊', // Orange\n '🍓', // Strawberry\n '🥥', // Coconut\n '🍒', // Cherry\n '🥭', // Mango\n '🍉', // Watermelon\n '🍋', // Lemon\n '🥝', // Kiwi\n '🫒', // Olive\n '🍈', // Melon\n]\n\n/**\n * Simple hash function to convert string to number\n */\nfunction hashString(str: string): number {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32-bit integer\n }\n return Math.abs(hash)\n}\n\n/**\n * Get a fruit emoji based on an id string\n * @param id - The string id to generate emoji from\n * @returns A fruit emoji string\n */\nexport function getAvatarEmoji(id: string): string {\n const hash = hashString(id)\n const index = hash % EMOJIS.length\n return EMOJIS[index]\n}\n\n","import { StarIcon } from '@phosphor-icons/react'\nimport classNames from 'classnames'\nimport React from 'react'\n\nimport { getAvatarEmoji } from './getAvatarEmoji'\n\nexport interface AvatarProps {\n id: string\n name: string\n image?: string\n size?: number\n className?: string\n starred?: boolean\n shape?: 'squircle' | 'circle'\n dmAgentEnabled?: boolean\n}\n\n/**\n * Avatar component that displays a user image or colored initial fallback\n */\nexport const Avatar = ({\n id,\n image,\n size = 40,\n className,\n starred = false,\n shape = 'squircle',\n dmAgentEnabled = false,\n}: AvatarProps) => {\n const emoji = getAvatarEmoji(id)\n\n const getFontSizeClass = () => {\n if (size < 32) return 'text-xs'\n if (size < 56) return 'text-sm'\n if (size < 120) return 'text-lg'\n return 'text-4xl'\n }\n\n const fontSizeClass = getFontSizeClass()\n // Match design treatment: 2px AI border at 40px avatar size.\n const aiBorderWidth = size >= 40 ? 2 : 1\n\n const borderStyle =\n shape === 'circle'\n ? { borderRadius: '50%' }\n : {\n borderRadius: '33%',\n cornerShape: 'superellipse(1.3)',\n }\n\n const avatarInner = (\n <div className=\"h-full w-full overflow-hidden\" style={borderStyle}>\n {image ? (\n <img\n src={image}\n alt=\"\"\n className=\"aspect-square h-full w-full object-cover\"\n />\n ) : (\n <div\n aria-hidden=\"true\"\n className={classNames(\n 'avatar-fallback flex h-full w-full items-center justify-center bg-[#E6E5E3] font-semibold select-none transition-colors',\n fontSizeClass\n )}\n >\n {emoji}\n </div>\n )}\n </div>\n )\n\n return (\n <div\n className={classNames(\n 'relative flex-shrink-0 !bg-transparent',\n className\n )}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n }}\n >\n {starred && (\n <div\n aria-hidden=\"true\"\n className=\"absolute -left-1.5 -top-1.5 z-10 flex size-5 items-center justify-center rounded-full bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]\"\n >\n <StarIcon className=\"size-3 text-yellow-600\" weight=\"duotone\" />\n </div>\n )}\n <div\n data-testid=\"avatar-ring\"\n className={classNames(\n 'h-full w-full',\n 'bg-transparent'\n )}\n style={{\n ...borderStyle,\n ...(dmAgentEnabled && {\n borderWidth: `${aiBorderWidth}px`,\n borderStyle: 'solid',\n borderColor: 'var(--AI-Gradient, #7F22FE)',\n boxShadow: 'inset 0 1px 2px 0 rgba(255, 255, 255, 0.5)',\n }),\n }}\n >\n {avatarInner}\n </div>\n </div>\n )\n}\n","import { GiftIcon } from '@phosphor-icons/react'\nimport { LocalMessage } from 'stream-chat'\n\ninterface MessageTagProps {\n message: LocalMessage\n /** When true, renders as a standalone bubble instead of a small tag */\n standalone?: boolean\n /** When true, renders sender-side chatbot variants */\n isMyMessage?: boolean\n /** Whether the message includes an attachment */\n hasAttachment?: boolean\n}\n\nconst SparkleIcon = ({ size = 15 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M12.003 9a.985.985 0 0 1-.652.934l-3.223 1.191-1.188 3.226a.995.995 0 0 1-1.867 0l-1.195-3.226L.65 9.937a.995.995 0 0 1 0-1.867l3.227-1.195 1.187-3.226a.995.995 0 0 1 1.868 0l1.195 3.226 3.226 1.187a.99.99 0 0 1 .649.938m3-5.83a.52.52 0 0 1-.344.492l-1.702.63-.627 1.703a.525.525 0 0 1-.986 0l-.63-1.704-1.704-.627a.525.525 0 0 1 0-.986l1.703-.63.627-1.704a.526.526 0 0 1 .986 0l.631 1.703 1.704.627a.52.52 0 0 1 .342.495\"\n fill=\"currentColor\"\n fillOpacity={0.55}\n />\n </svg>\n)\n\n/** Check if a message is a tip based on metadata */\nexport const isTipMessage = (message: LocalMessage): boolean => {\n return message.metadata?.custom_type === 'MESSAGE_TIP'\n}\n\n/** Check if a message is a paid message based on metadata */\nexport const isPaidMessage = (message: LocalMessage): boolean => {\n return message.metadata?.custom_type === 'MESSAGE_PAID'\n}\n\n/** Check if a message is a chatbot message based on metadata */\nexport const isChatbotMessage = (message: LocalMessage): boolean => {\n return message.metadata?.custom_type === 'MESSAGE_CHATBOT'\n}\n\n/** Check if a message is a locked attachment */\nexport const isAttachmentMessage = (message: LocalMessage): boolean => {\n return message.metadata?.custom_type === 'MESSAGE_ATTACHMENT'\n}\n\n/** Check if a message has a tip/paid tag (both render the same) */\nexport const isTipOrPaidMessage = (message: LocalMessage): boolean => {\n return isTipMessage(message) || isPaidMessage(message)\n}\n\n/** Check if a message is a tip/paid-only message (no text) */\nexport const isTipOnlyMessage = (message: LocalMessage): boolean => {\n return isTipOrPaidMessage(message) && !message.text?.trim()\n}\n\nexport const MessageTag = ({\n message,\n standalone = false,\n isMyMessage = false,\n hasAttachment = false,\n}: MessageTagProps) => {\n const isTipOrPaid = isTipOrPaidMessage(message)\n const isChatbot = isChatbotMessage(message)\n\n if (!isTipOrPaid && !isChatbot) {\n return null\n }\n\n if (isTipOrPaid) {\n const amountText = message.metadata?.amount_text\n if (!amountText) return null\n\n const className = standalone\n ? 'message-tip-standalone'\n : 'message-tag message-tag--tip'\n\n const label = standalone\n ? `${amountText} tip`\n : `Delivered with ${amountText} tip`\n\n return (\n <div className={className}>\n <GiftIcon size={standalone ? 14 : 12} />\n <span>{label}</span>\n </div>\n )\n }\n\n const isSenderAttachmentVariant = isMyMessage && hasAttachment\n const chatbotLabel = isSenderAttachmentVariant\n ? 'Sent with AI'\n : 'Sent with DM Agent'\n\n const chatbotClassName = [\n 'message-chatbot-indicator',\n isMyMessage\n ? 'message-chatbot-indicator--sender'\n : 'message-chatbot-indicator--receiver',\n isSenderAttachmentVariant\n ? 'message-chatbot-indicator--attachment'\n : 'message-chatbot-indicator--text',\n ].join(' ')\n\n const label = (\n <span className=\"message-chatbot-indicator__label\">{chatbotLabel}</span>\n )\n const icon = (\n <span className=\"message-chatbot-indicator__icon\">\n <SparkleIcon size={isSenderAttachmentVariant ? 12 : 15} />\n </span>\n )\n\n // Chatbot indicator variant\n return (\n <div className={chatbotClassName} data-testid=\"message-chatbot-indicator\">\n {isMyMessage && !isSenderAttachmentVariant ? (\n <>\n {label}\n {icon}\n </>\n ) : (\n <>\n {icon}\n {label}\n </>\n )}\n </div>\n )\n}\n","import classNames from 'classnames'\nimport React from 'react'\nimport { ChannelPreviewUIComponentProps } from 'stream-chat-react'\n\nimport { useChannelStar } from '../../hooks/useChannelStar'\nimport { formatRelativeTime } from '../../utils/formatRelativeTime'\nimport { Avatar } from '../Avatar'\nimport { isChatbotMessage } from '../CustomMessage/MessageTag'\n\nimport { useChannelListContext } from './ChannelListContext'\n\n/**\n * Custom channel preview that handles selection\n */\nconst CustomChannelPreview = React.memo<ChannelPreviewUIComponentProps>(\n ({ channel, unread }) => {\n const { selectedChannel, onChannelSelect, debug, renderMessagePreview } =\n useChannelListContext()\n\n const isSelected = selectedChannel?.id === channel?.id\n\n const handleClick = () => {\n if (channel) {\n onChannelSelect(channel)\n }\n }\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const isActivationKey = event.key === 'Enter' || event.key === ' '\n const isRepeatedKeydown = event.repeat\n\n if (!isActivationKey || isRepeatedKeydown) return\n\n event.preventDefault()\n handleClick()\n }\n\n // Get participant info\n const members = Object.values(channel?.state?.members || {})\n const participant = members.find(\n (member) => member.user?.id && member.user.id !== channel?._client?.userID\n )\n const participantName = participant?.user?.name || 'Conversation'\n const participantImage = participant?.user?.image\n\n // Get last non-system message for preview\n const lastMessage = (() => {\n const messages = channel?.state?.messages\n if (!messages?.length) return undefined\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].type !== 'system') return messages[i]\n }\n return undefined\n })()\n\n const getLastMessageText = () => {\n if (lastMessage?.text) return lastMessage.text\n const isTip = lastMessage?.metadata?.custom_type === 'MESSAGE_TIP'\n if (isTip) return '💵 Sent a tip'\n\n const attachment = lastMessage?.attachments?.[0]\n if (attachment) {\n // Link previews - show the actual URL\n if (attachment.og_scrape_url) return attachment.og_scrape_url\n\n // Type-based detection\n if (attachment.type === 'image') return '📷 Sent an image'\n if (attachment.type === 'video') return '🎥 Sent a video'\n if (attachment.type === 'audio') return '🎵 Sent audio'\n if (attachment.type === 'file') return '📎 Sent a file'\n\n // Fallback\n return '📎 Sent an attachment'\n }\n\n return 'No messages yet'\n }\n\n const lastMessageText = getLastMessageText()\n const lastMessageTime = lastMessage?.created_at\n ? formatRelativeTime(new Date(lastMessage.created_at))\n : ''\n const isLastMessageFromChatbot = lastMessage\n ? isChatbotMessage(lastMessage)\n : false\n\n const messagePreview = renderMessagePreview\n ? renderMessagePreview(lastMessage, lastMessageText)\n : `${isLastMessageFromChatbot ? '✨ ' : ''}${lastMessageText}`\n const isChannelStarred = useChannelStar(channel)\n\n // Use the unread prop passed by Stream Chat (reactive and updates automatically)\n const unreadCount = unread ?? 0\n\n if (debug) {\n console.log('📺 [ChannelList] 📋 CHANNEL PREVIEW RENDER', {\n channelId: channel?.id,\n isSelected,\n participantName,\n unreadCount,\n hasTimestamp: !!lastMessageTime,\n })\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n className={classNames(\n 'group w-full px-4 py-3 transition-colors text-left max-w-full overflow-hidden focus-ring',\n {\n 'bg-primary-alt/10 border-l-4 border-l-primary': isSelected,\n 'hover:bg-sand': !isSelected,\n }\n )}\n >\n <div className=\"flex items-start gap-3\">\n {/* Avatar */}\n <Avatar\n id={participant?.user?.id || channel.id || 'unknown'}\n name={participantName}\n image={participantImage}\n size={44}\n starred={isChannelStarred}\n className=\"[&_.avatar-fallback]:group-hover:bg-[#eeeeee]\"\n />\n\n {/* Content column */}\n <div className=\"flex-1 min-w-0 flex flex-col gap-1\">\n {/* Name and timestamp row */}\n <div className=\"flex items-center justify-between gap-2\">\n <h3\n className={classNames(\n 'text-sm font-medium truncate',\n isSelected ? 'text-primary' : 'text-charcoal'\n )}\n >\n {isChannelStarred && (\n <span className=\"sr-only\">Starred conversation. </span>\n )}\n {participantName}\n </h3>\n {lastMessageTime && (\n <span className=\"text-xs text-stone flex-shrink-0\">\n {lastMessageTime}\n </span>\n )}\n </div>\n\n {/* Message and unread badge row */}\n <div className=\"flex items-center justify-between gap-2 min-w-0\">\n <p className=\"text-xs text-stone flex-1 line-clamp-1\">\n {messagePreview}\n </p>\n {unreadCount > 0 && (\n <span className=\"bg-[#7f22fe] text-white text-xs px-2 py-0.5 rounded-full min-w-[20px] text-center flex-shrink-0\">\n {unreadCount > 99 ? '99+' : unreadCount}\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n }\n)\n\nexport default CustomChannelPreview\nCustomChannelPreview.displayName = 'CustomChannelPreview'\n","import classNames from 'classnames'\nimport React from 'react'\nimport type { Channel } from 'stream-chat'\nimport { ChannelList as StreamChannelList } from 'stream-chat-react'\n\nimport { restorePendingMessages } from '../../hooks/useRestorePendingMessages'\nimport { useMessagingContext } from '../../providers/MessagingProvider'\nimport type { ChannelListProps } from '../../types'\n\nimport { ChannelListProvider } from './ChannelListContext'\nimport CustomChannelPreview from './CustomChannelPreview'\n\nconst DEFAULT_SORT = { last_message_at: -1 } as const\n\n/**\n * Channel list component with customizable header and actions\n */\nexport const ChannelList = React.memo<ChannelListProps>(\n ({\n onChannelSelect,\n selectedChannel,\n filters,\n allowNewMessagesFromUnfilteredChannels = false,\n onMessageNew,\n onAddedToChannel,\n channelRenderFilterFn,\n sort = DEFAULT_SORT,\n className,\n customEmptyStateIndicator,\n renderMessagePreview,\n }) => {\n // Track renders\n const renderCountRef = React.useRef(0)\n renderCountRef.current++\n\n // Get debug flag from context\n const { debug = false } = useMessagingContext()\n\n // Wrap channelRenderFilterFn to restore pending messages for all channels\n // as soon as they are loaded, without waiting for the user to click into each one.\n const wrappedChannelRenderFilterFn = React.useCallback(\n (channels: Channel[]) => {\n for (const channel of channels) {\n restorePendingMessages(channel)\n }\n return channelRenderFilterFn\n ? channelRenderFilterFn(channels)\n : channels\n },\n [channelRenderFilterFn]\n )\n\n if (debug) {\n console.log('📺 [ChannelList] 🔄 RENDER START', {\n renderCount: renderCountRef.current,\n selectedChannelId: selectedChannel?.id,\n filters,\n })\n }\n\n const contextValue = React.useMemo(\n () => ({\n selectedChannel,\n onChannelSelect,\n debug,\n renderMessagePreview,\n }),\n [selectedChannel, onChannelSelect, debug, renderMessagePreview]\n )\n\n return (\n <div\n className={classNames(\n 'messaging-channel-list h-full flex flex-col min-w-0 overflow-hidden',\n className\n )}\n >\n {/* Channel List */}\n <div className=\"flex-1 overflow-hidden min-w-0\">\n <ChannelListProvider value={contextValue}>\n <StreamChannelList\n key={`${JSON.stringify(filters)}:${JSON.stringify(sort)}`}\n filters={filters}\n sort={sort}\n options={{ limit: 30 }}\n allowNewMessagesFromUnfilteredChannels={\n allowNewMessagesFromUnfilteredChannels\n }\n onMessageNew={onMessageNew}\n onAddedToChannel={onAddedToChannel}\n channelRenderFilterFn={wrappedChannelRenderFilterFn}\n Preview={CustomChannelPreview}\n EmptyStateIndicator={customEmptyStateIndicator}\n />\n </ChannelListProvider>\n </div>\n </div>\n )\n }\n)\nChannelList.displayName = 'ChannelList'\n","import classNames from \"classnames\";\nimport React from \"react\";\n\nexport interface ActionButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"default\" | \"danger\";\n}\n\nconst ActionButton = ({\n variant = \"default\",\n className,\n children,\n ...rest\n}: ActionButtonProps) => {\n const isDanger = variant === \"danger\";\n return (\n <button\n type=\"button\"\n className={classNames(\n \"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left text-sm transition-colors focus-ring disabled:cursor-not-allowed disabled:opacity-60\",\n isDanger\n ? \"text-danger hover:bg-danger/50\"\n : \"text-charcoal hover:bg-sand\",\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n );\n};\n\nexport default ActionButton;\n","import classNames from \"classnames\";\nimport React from \"react\";\n\ninterface IconButtonProps\n extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\" | \"children\"\n > {\n label: string;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function IconButton({ label, className, children, ...rest }: IconButtonProps) {\n return (\n <button\n type=\"button\"\n className={classNames(\n \"inline-flex items-center justify-center rounded-full transition-colors focus-ring p-2\",\n {\n \"cursor-not-allowed opacity-50\": rest.disabled,\n \"hover:bg-sand\": !rest.disabled,\n },\n className,\n )}\n {...rest}\n >\n <span className=\"sr-only\">{label}</span>\n {children}\n </button>\n );\n}","import { XIcon } from '@phosphor-icons/react'\n\nimport { IconButton } from '../IconButton'\n\ninterface CloseButtonProps {\n onClick: () => void\n}\n\nexport function CloseButton({ onClick }: CloseButtonProps) {\n return (\n <IconButton label=\"Close\" onClick={onClick} className=\"p-1\">\n <XIcon className=\"h-5 w-5 text-stone\" weight=\"bold\" />\n </IconButton>\n )\n}\n","import {\n FlagIcon,\n ProhibitInsetIcon,\n SignOutIcon,\n SpinnerGapIcon,\n} from '@phosphor-icons/react'\nimport React, { useState, useCallback, useEffect } from 'react'\nimport type { Channel as ChannelType, ChannelMemberResponse } from 'stream-chat'\n\nimport { useMessagingContext } from '../../providers/MessagingProvider'\nimport ActionButton from '../ActionButton'\nimport { Avatar } from '../Avatar'\nimport { CloseButton } from '../CloseButton'\n\n// Custom user type with email and username\ntype CustomUser = {\n email?: string\n username?: string\n}\n\n// Blocked user from Stream Chat API\ntype BlockedUser = {\n blocked_user_id: string\n}\n\nexport interface ChannelInfoDialogProps {\n dialogRef: React.RefObject<HTMLDialogElement>\n onClose: () => void\n participant: ChannelMemberResponse | undefined\n channel: ChannelType\n followerStatusLabel?: string\n onLeaveConversation?: (channel: ChannelType) => void\n onBlockParticipant?: (participantId?: string) => void\n showDeleteConversation?: boolean\n onDeleteConversationClick?: () => void\n onBlockParticipantClick?: () => void\n onReportParticipantClick?: () => void\n customProfileContent?: React.ReactNode\n customChannelActions?: React.ReactNode\n}\n\n/**\n * Channel info dialog (matching original implementation)\n */\nexport const ChannelInfoDialog: React.FC<ChannelInfoDialogProps> = ({\n dialogRef,\n onClose,\n participant,\n channel,\n followerStatusLabel,\n onLeaveConversation,\n onBlockParticipant,\n showDeleteConversation = true,\n onDeleteConversationClick,\n onBlockParticipantClick,\n onReportParticipantClick,\n customProfileContent,\n customChannelActions,\n}) => {\n const { service, debug } = useMessagingContext()\n const [isParticipantBlocked, setIsParticipantBlocked] = useState(false)\n const [isLeaving, setIsLeaving] = useState(false)\n const [isUpdatingBlockStatus, setIsUpdatingBlockStatus] = useState(false)\n\n // Check if participant is blocked when participant changes\n const checkIsParticipantBlocked = useCallback(async () => {\n if (!service || !participant?.user?.id) return\n\n try {\n const blockedUsers = await service.getBlockedUsers()\n const isBlocked = blockedUsers.some(\n (user: BlockedUser) => user.blocked_user_id === participant?.user?.id\n )\n setIsParticipantBlocked(isBlocked)\n } catch (error) {\n console.error(\n '[ChannelInfoDialog] Failed to check blocked status:',\n error\n )\n }\n }, [service, participant?.user?.id])\n\n useEffect(() => {\n checkIsParticipantBlocked()\n }, [checkIsParticipantBlocked])\n\n const handleLeaveConversation = async () => {\n if (isLeaving) return\n\n // Fire analytics callback before action\n onDeleteConversationClick?.()\n\n if (debug) {\n console.log('[ChannelInfoDialog] Leave conversation', channel.cid)\n }\n setIsLeaving(true)\n\n try {\n const actingUserId = channel._client?.userID ?? null\n await channel.hide(actingUserId, false)\n\n if (onLeaveConversation) {\n await onLeaveConversation(channel)\n }\n\n onClose()\n } catch (error) {\n console.error('[ChannelInfoDialog] Failed to leave conversation', error)\n } finally {\n setIsLeaving(false)\n }\n }\n\n const handleBlockUser = async () => {\n if (isUpdatingBlockStatus || !service) return\n\n // Fire analytics callback before action\n onBlockParticipantClick?.()\n\n if (debug) {\n console.log('[ChannelInfoDialog] Block member', participant?.user?.id)\n }\n setIsUpdatingBlockStatus(true)\n\n try {\n await service.blockUser(participant?.user?.id)\n\n if (onBlockParticipant) {\n await onBlockParticipant(participant?.user?.id)\n }\n\n onClose()\n } catch (error) {\n console.error('[ChannelInfoDialog] Failed to block member', error)\n } finally {\n setIsUpdatingBlockStatus(false)\n }\n }\n\n const handleUnblockUser = async () => {\n if (isUpdatingBlockStatus || !service) return\n\n // Fire analytics callback before action\n onBlockParticipantClick?.()\n\n if (debug) {\n console.log('[ChannelInfoDialog] Unblock member', participant?.user?.id)\n }\n setIsUpdatingBlockStatus(true)\n\n try {\n await service.unBlockUser(participant?.user?.id)\n\n if (onBlockParticipant) {\n await onBlockParticipant(participant?.user?.id)\n }\n\n onClose()\n } catch (error) {\n console.error('[ChannelInfoDialog] Failed to unblock member', error)\n } finally {\n setIsUpdatingBlockStatus(false)\n }\n }\n\n const handleReportUser = () => {\n // Fire analytics callback before action\n onReportParticipantClick?.()\n\n onClose()\n window.open(\n 'https://linktr.ee/s/about/trust-center/report',\n '_blank',\n 'noopener,noreferrer'\n )\n }\n\n if (!participant) return null\n\n const participantName =\n participant.user?.name || participant.user?.id || 'Unknown member'\n const participantImage = participant.user?.image\n const participantEmail = (participant.user as CustomUser)?.email\n const participantUsername = (participant.user as CustomUser)?.username\n const participantSecondary = participantEmail\n ? participantEmail\n : participantUsername\n ? `linktr.ee/${participantUsername}`\n : undefined\n const participantId = participant.user?.id || 'unknown'\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n <dialog\n ref={dialogRef}\n className=\"mes-dialog group\"\n onClose={onClose}\n onClick={(e) => {\n if (e.target === dialogRef.current) {\n onClose()\n }\n }}\n >\n <div className=\"ml-auto flex h-full w-full flex-col bg-white shadow-none transition-shadow duration-200 group-open:shadow-max-elevation-light\">\n <div className=\"flex items-center justify-between border-b border-sand px-4 py-3\">\n <h2 className=\"text-base font-semibold text-charcoal\">Chat info</h2>\n <CloseButton onClick={onClose} />\n </div>\n\n <div className=\"flex-1 px-2 overflow-y-auto w-full\">\n <div\n className=\"flex flex-col items-center gap-3 self-stretch px-4 py-2 mt-6 rounded-lg border border-black/[0.04]\"\n style={{ backgroundColor: '#FBFAF9' }}\n >\n <div className=\"flex items-center gap-3 w-full\">\n <Avatar\n id={participantId}\n name={participantName}\n image={participantImage}\n size={88}\n shape=\"circle\"\n />\n <div className=\"flex flex-col min-w-0 flex-1\">\n <p className=\"truncate text-base font-semibold text-charcoal\">\n {participantName}\n </p>\n {participantSecondary && (\n <p className=\"truncate text-sm text-[#00000055]\">\n {participantSecondary}\n </p>\n )}\n {/* Deprecated: use customProfileContent instead. followerStatusLabel will be removed in a future release. */}\n {followerStatusLabel && !customProfileContent && (\n <span\n className=\"mt-1 rounded-full text-xs font-normal w-fit\"\n style={{\n padding: '4px 8px',\n backgroundColor:\n followerStatusLabel === 'Subscribed to you'\n ? '#DCFCE7'\n : '#F5F5F4',\n color:\n followerStatusLabel === 'Subscribed to you'\n ? '#008236'\n : '#78716C',\n lineHeight: '133.333%',\n letterSpacing: '0.21px',\n }}\n >\n {followerStatusLabel}\n </span>\n )}\n </div>\n </div>\n {customProfileContent && (\n <div className=\"w-full\">{customProfileContent}</div>\n )}\n </div>\n\n <ul className=\"flex flex-col gap-2 mt-2\">\n {showDeleteConversation && (\n <li>\n <ActionButton\n onClick={handleLeaveConversation}\n disabled={isLeaving}\n aria-busy={isLeaving}\n >\n {isLeaving ? (\n <SpinnerGapIcon className=\"h-5 w-5 animate-spin\" />\n ) : (\n <SignOutIcon className=\"h-5 w-5\" />\n )}\n <span>Delete Conversation</span>\n </ActionButton>\n </li>\n )}\n <li>\n {isParticipantBlocked ? (\n <ActionButton\n onClick={handleUnblockUser}\n disabled={isUpdatingBlockStatus}\n aria-busy={isUpdatingBlockStatus}\n >\n {isUpdatingBlockStatus ? (\n <SpinnerGapIcon className=\"h-5 w-5 animate-spin\" />\n ) : (\n <ProhibitInsetIcon className=\"h-5 w-5\" />\n )}\n <span>Unblock</span>\n </ActionButton>\n ) : (\n <ActionButton\n onClick={handleBlockUser}\n disabled={isUpdatingBlockStatus}\n aria-busy={isUpdatingBlockStatus}\n >\n {isUpdatingBlockStatus ? (\n <SpinnerGapIcon className=\"h-5 w-5 animate-spin\" />\n ) : (\n <ProhibitInsetIcon className=\"h-5 w-5\" />\n )}\n <span>Block</span>\n </ActionButton>\n )}\n </li>\n <li>\n <ActionButton variant=\"danger\" onClick={handleReportUser}>\n <FlagIcon className=\"h-5 w-5\" />\n <span>Report</span>\n </ActionButton>\n </li>\n {customChannelActions}\n </ul>\n </div>\n </div>\n </dialog>\n )\n}\n","import { DateSeparator, type DateSeparatorProps } from 'stream-chat-react'\n\nexport const CustomDateSeparator = (props: DateSeparatorProps) => (\n <DateSeparator {...props} position=\"center\" />\n)\n","import { useCallback, useMemo } from 'react'\nimport type { LocalMessage } from 'stream-chat'\nimport { useChannelStateContext, useChatContext } from 'stream-chat-react'\n\nexport type VoteSelection = 'up' | 'down' | null\n\nconst VOTE_UP = 'vote_up'\nconst VOTE_DOWN = 'vote_down'\n\nfunction getVoteFromReactions(\n ownReactions: LocalMessage['own_reactions']\n): VoteSelection {\n if (!ownReactions?.length) return null\n if (ownReactions.some((r) => r.type === VOTE_DOWN)) return 'down'\n if (ownReactions.some((r) => r.type === VOTE_UP)) return 'up'\n return null\n}\n\ninterface UseMessageVoteResult {\n selected: VoteSelection\n voteUp: () => void\n voteDown: () => void\n}\n\n/**\n * Hook that wraps Stream Chat reactions to provide toggle-style\n * upvote/downvote behavior on a message.\n *\n * Uses enforce_unique so sending a new reaction type automatically\n * removes the previous one. Uses skip_push to avoid notifying the\n * Linker on every vote.\n */\nexport function useMessageVote(message: LocalMessage): UseMessageVoteResult {\n const { channel } = useChannelStateContext()\n const { client } = useChatContext('useMessageVote')\n\n const selected = useMemo(\n () => getVoteFromReactions(message.own_reactions),\n [message.own_reactions]\n )\n\n const voteUp = useCallback(async () => {\n if (!client?.userID) return\n try {\n if (selected === 'up') {\n await channel.deleteReaction(message.id, VOTE_UP)\n } else {\n await channel.sendReaction(\n message.id,\n { type: VOTE_UP },\n { enforce_unique: true, skip_push: true }\n )\n }\n } catch {\n // Silently fail — voting is non-critical\n }\n }, [channel, client?.userID, message.id, selected])\n\n const voteDown = useCallback(async () => {\n if (!client?.userID) return\n try {\n if (selected === 'down') {\n await channel.deleteReaction(message.id, VOTE_DOWN)\n } else {\n await channel.sendReaction(\n message.id,\n { type: VOTE_DOWN },\n { enforce_unique: true, skip_push: true }\n )\n }\n } catch {\n // Silently fail — voting is non-critical\n }\n }, [channel, client?.userID, message.id, selected])\n\n return { selected, voteUp, voteDown }\n}\n","import React, { Suspense } from 'react'\n\nimport type { CreatorCardProps } from './components/Creator/Card'\nimport type { VisitorCardProps } from './components/Visitor/Card'\n\nconst CreatorCardLazy = React.lazy(() => import('./components/Creator/Card'))\nconst VisitorCardLazy = React.lazy(() => import('./components/Visitor/Card'))\n\nconst LockedAttachmentFallback = () => (\n <div\n className=\"w-[280px] min-h-[200px] animate-pulse rounded-[24px] bg-black/[0.06] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]\"\n aria-hidden\n />\n)\n\nconst Creator = (props: CreatorCardProps) => (\n <Suspense fallback={<LockedAttachmentFallback />}>\n <CreatorCardLazy {...props} />\n </Suspense>\n)\n\nconst Visitor = (props: VisitorCardProps) => (\n <Suspense fallback={<LockedAttachmentFallback />}>\n <VisitorCardLazy {...props} />\n </Suspense>\n)\n\nconst LockedAttachment = { Creator, Visitor }\n\nexport default LockedAttachment\nexport type { CreatorCardProps, VisitorCardProps }\nexport type { PaymentStatus, LockedAttachmentSource, LockedAttachmentContextValue } from './types'\n","import type { Channel, LocalMessage } from 'stream-chat'\n\nimport type { PaymentStatus } from '../../stream-custom-data'\n\nexport interface LockedAttachmentBaseProps {\n title?: string\n mimeType?: string\n thumbnailUrl?: string\n detail?: string\n amountText?: string\n paymentStatus?: PaymentStatus\n}\n\nexport interface LockedAttachmentSource {\n /** Proxied URL used by the media player for in-app playback. */\n sourceUrl: string\n /** URL opened when the visitor clicks Download — may be a file or a web destination. */\n redeemUrl?: string\n /** Thumbnail URL from the fetched asset — overrides the metadata thumbnail when present. */\n thumbnailUrl?: string\n}\n\nexport type { PaymentStatus }\n\nexport interface LockedAttachmentContextValue {\n isUnlocking: (id: string) => boolean\n onUnlockClick?: (message: LocalMessage, channel: Channel) => void\n onDownloadClick?: (message: LocalMessage, channel: Channel) => void\n onFetchSource?: (message: LocalMessage, channel: Channel) => Promise<LockedAttachmentSource | void>\n}\n\nexport const defaultLockedAttachmentContextValue: LockedAttachmentContextValue = {\n isUnlocking: () => false,\n}\n","import { createContext, useContext } from 'react'\n\nimport { defaultLockedAttachmentContextValue, type LockedAttachmentContextValue } from '../LockedAttachment/types'\n\nexport interface CustomMessageRegistry {\n LockedAttachment: LockedAttachmentContextValue\n}\n\nconst customMessageDefaults: CustomMessageRegistry = {\n LockedAttachment: defaultLockedAttachmentContextValue,\n}\n\nconst CustomMessageContext = createContext<Partial<CustomMessageRegistry>>({})\n\nexport const CustomMessageProvider = CustomMessageContext.Provider\n\nexport function useCustomMessage<K extends keyof CustomMessageRegistry>(key: K): CustomMessageRegistry[K] {\n const ctx = useContext(CustomMessageContext)\n return (ctx[key] ?? customMessageDefaults[key]) as CustomMessageRegistry[K]\n}\n","import React from 'react'\n\nimport type { VoteSelection } from '../../hooks/useMessageVote'\n\ninterface MessageVoteButtonsProps {\n selected: VoteSelection\n onVoteUp: () => void\n onVoteDown: () => void\n}\n\nconst ThumbUpIcon: React.FC<{ filled: boolean }> = ({ filled }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M4.667 7.333l2.666-6A1.333 1.333 0 018.667 2v2.667a.667.667 0 00.666.666h3.764a1.334 1.334 0 011.192 1.93l-2.333 4.666a1.333 1.333 0 01-1.193.738H4.667m0-5.334v5.334m0-5.334H2.667a1.333 1.333 0 00-1.334 1.334v2.666a1.333 1.333 0 001.334 1.334h2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.33\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill={filled ? 'currentColor' : 'none'}\n />\n </svg>\n)\n\nconst ThumbDownIcon: React.FC<{ filled: boolean }> = ({ filled }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M11.333 8.667l-2.666 6A1.333 1.333 0 017.333 14v-2.667a.667.667 0 00-.666-.666H2.903a1.334 1.334 0 01-1.192-1.93l2.333-4.666a1.333 1.333 0 011.193-.738h6.096m0 5.334V3.333m0 5.334h2a1.333 1.333 0 001.334-1.334V4.667a1.333 1.333 0 00-1.334-1.334h-2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.33\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill={filled ? 'currentColor' : 'none'}\n />\n </svg>\n)\n\nexport const MessageVoteButtons: React.FC<MessageVoteButtonsProps> = ({\n selected,\n onVoteUp,\n onVoteDown,\n}) => (\n <div className=\"message-vote-buttons\">\n <button\n type=\"button\"\n className={`message-vote-button${selected === 'up' ? ' message-vote-button--selected' : ''} focus-ring`}\n onClick={onVoteUp}\n aria-label=\"Helpful\"\n aria-pressed={selected === 'up'}\n >\n <ThumbUpIcon filled={selected === 'up'} />\n </button>\n <button\n type=\"button\"\n className={`message-vote-button${selected === 'down' ? ' message-vote-button--selected' : ''} focus-ring`}\n onClick={onVoteDown}\n aria-label=\"Not helpful\"\n aria-pressed={selected === 'down'}\n >\n <ThumbDownIcon filled={selected === 'down'} />\n </button>\n </div>\n)\n","import classNames from 'classnames'\nimport React, { useMemo, useState } from 'react'\nimport {\n Attachment as DefaultAttachment,\n EditMessageModal as DefaultEditMessageModal,\n MessageBounceModal,\n MessageBouncePrompt as DefaultMessageBouncePrompt,\n MessageBlocked as DefaultMessageBlocked,\n MessageDeleted as DefaultMessageDeleted,\n MessageErrorIcon,\n MessageIsThreadReplyInChannelButtonIndicator as DefaultMessageIsThreadReplyInChannelButtonIndicator,\n MessageRepliesCountButton as DefaultMessageRepliesCountButton,\n MessageText,\n Poll,\n ReminderNotification as DefaultReminderNotification,\n StreamedMessageText as DefaultStreamedMessageText,\n areMessageUIPropsEqual,\n isDateSeparatorMessage,\n isMessageBlocked,\n isMessageBounced,\n messageHasAttachments,\n messageHasReactions,\n useChannelStateContext,\n useComponentContext,\n useChatContext,\n useMessageContext,\n useMessageReminder,\n type MessageContextValue,\n type MessageUIComponentProps,\n} from 'stream-chat-react'\n\nimport { useMessageVote } from '../../hooks/useMessageVote'\nimport { Avatar } from '../Avatar'\nimport LockedAttachment from '../LockedAttachment'\n\nimport { useCustomMessage } from './context'\nimport {\n MessageTag,\n isAttachmentMessage,\n isChatbotMessage,\n isTipOnlyMessage,\n} from './MessageTag'\nimport { MessageVoteButtons } from './MessageVoteButtons'\n\ntype CustomMessageUIComponentProps = MessageUIComponentProps & {\n chatbotVotingEnabled?: boolean\n}\n\ntype CustomMessageWithContextProps = MessageContextValue & {\n chatbotVotingEnabled?: boolean\n}\n\nconst CustomMessageWithContext = (props: CustomMessageWithContextProps) => {\n const {\n additionalMessageInputProps,\n chatbotVotingEnabled,\n editing,\n endOfGroup,\n firstOfGroup,\n groupedByUser,\n handleAction,\n handleOpenThread,\n handleRetry,\n highlighted,\n isMessageAIGenerated,\n isMyMessage,\n message,\n renderText,\n threadList,\n } = props\n\n const { client } = useChatContext('CustomMessage')\n const { channel } = useChannelStateContext('CustomMessage')\n const { isUnlocking, onUnlockClick, onFetchSource, onDownloadClick } = useCustomMessage('LockedAttachment')\n const [isBounceDialogOpen, setIsBounceDialogOpen] = useState(false)\n const reminder = useMessageReminder(message.id)\n const { selected: voteState, voteUp, voteDown } = useMessageVote(message)\n\n const {\n Attachment = DefaultAttachment,\n EditMessageModal = DefaultEditMessageModal,\n MessageBlocked = DefaultMessageBlocked,\n MessageBouncePrompt = DefaultMessageBouncePrompt,\n MessageDeleted = DefaultMessageDeleted,\n MessageIsThreadReplyInChannelButtonIndicator = DefaultMessageIsThreadReplyInChannelButtonIndicator,\n MessageRepliesCountButton = DefaultMessageRepliesCountButton,\n ReminderNotification = DefaultReminderNotification,\n StreamedMessageText = DefaultStreamedMessageText,\n PinIndicator,\n } = useComponentContext('CustomMessage')\n\n const hasAttachment = messageHasAttachments(message)\n const hasReactions = messageHasReactions(message)\n const isAIGenerated = useMemo(\n () => isMessageAIGenerated?.(message),\n [isMessageAIGenerated, message]\n )\n const finalAttachments = useMemo(\n () =>\n !message.shared_location && !message.attachments\n ? []\n : !message.shared_location\n ? message.attachments\n : [message.shared_location, ...(message.attachments ?? [])],\n [message]\n )\n\n if (isDateSeparatorMessage(message)) {\n return null\n }\n\n if (message.deleted_at || message.type === 'deleted') {\n return <MessageDeleted message={message} />\n }\n\n if (isMessageBlocked(message)) {\n return <MessageBlocked />\n }\n\n const showReplyCountButton = !threadList && !!message.reply_count\n const showIsReplyInChannel =\n !threadList && message.show_in_channel && message.parent_id\n const allowRetry =\n message.status === 'failed' && message.error?.status !== 403\n const isBounced = isMessageBounced(message)\n let handleClick: (() => void) | undefined = undefined\n\n if (allowRetry) {\n handleClick = () => handleRetry(message)\n } else if (isBounced) {\n handleClick = () => setIsBounceDialogOpen(true)\n }\n\n const isMine = isMyMessage()\n const rootClassName = classNames(\n 'str-chat__message str-chat__message-simple',\n `str-chat__message--${message.type}`,\n `str-chat__message--${message.status}`,\n isMine\n ? 'str-chat__message--me str-chat__message-simple--me'\n : 'str-chat__message--other',\n message.text ? 'str-chat__message--has-text' : 'has-no-text',\n {\n 'str-chat__message--has-attachment': hasAttachment,\n 'str-chat__message--highlighted': highlighted,\n 'str-chat__message--pinned pinned-message': message.pinned,\n 'str-chat__message--with-reactions': hasReactions,\n 'str-chat__message-send-can-be-retried':\n message?.status === 'failed' && message?.error?.status !== 403,\n 'str-chat__message-with-thread-link':\n showReplyCountButton || showIsReplyInChannel,\n 'str-chat__virtual-message__wrapper--end': endOfGroup,\n 'str-chat__virtual-message__wrapper--first': firstOfGroup,\n 'str-chat__virtual-message__wrapper--group': groupedByUser,\n }\n )\n\n const poll = message.poll_id && client.polls.fromState(message.poll_id)\n const isTipOnly = isTipOnlyMessage(message)\n const isChatbot = isChatbotMessage(message)\n const isAttachment = isAttachmentMessage(message)\n const hasRenderableAttachments = !!(\n finalAttachments?.length && !message.quoted_message\n )\n const useAttachmentFooterChatbotTag =\n isChatbot && isMine && hasRenderableAttachments\n\n return (\n <>\n {editing && (\n <EditMessageModal\n additionalMessageInputProps={additionalMessageInputProps}\n />\n )}\n {isBounceDialogOpen && (\n <MessageBounceModal\n MessageBouncePrompt={MessageBouncePrompt}\n onClose={() => setIsBounceDialogOpen(false)}\n open={isBounceDialogOpen}\n />\n )}\n <div className={rootClassName} key={message.id}>\n {PinIndicator && <PinIndicator />}\n {!!reminder && <ReminderNotification reminder={reminder} />}\n {message.user && (\n <Avatar\n className=\"str-chat__avatar str-chat__message-sender-avatar\"\n id={message.user.id}\n image={message.user.image}\n name={message.user.name || message.user.id}\n />\n )}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div\n className={classNames('str-chat__message-inner', {\n 'str-chat__simple-message--error-failed': allowRetry || isBounced,\n })}\n data-testid=\"message-inner\"\n onClick={handleClick}\n onKeyDown={handleClick}\n role={handleClick ? 'button' : undefined}\n tabIndex={handleClick ? 0 : undefined}\n style={{\n // Force margins to 0 to prevent hover layout shift\n // Stream Chat CSS sets margin-inline-end/start to 78px, then 0 on hover\n marginInlineEnd: 0,\n marginInlineStart: 0,\n }}\n >\n {isAttachment ? (\n <div className=\"str-chat__message-bubble-wrapper\">\n {isMine ? (\n <LockedAttachment.Creator\n title={message.metadata?.attachment_title}\n mimeType={message.metadata?.attachment_mime_type}\n thumbnailUrl={message.metadata?.attachment_thumbnail}\n amountText={message.metadata?.amount_text}\n detail={message.metadata?.attachment_detail}\n paymentStatus={message.metadata?.payment_status}\n isUnlocking={isUnlocking(message.id)}\n onPreviewClick={() => onUnlockClick?.(message, channel)}\n onFetchSource={async () =>\n await onFetchSource?.(message, channel)\n }\n />\n ) : (\n <LockedAttachment.Visitor\n title={message.metadata?.attachment_title}\n mimeType={message.metadata?.attachment_mime_type}\n thumbnailUrl={message.metadata?.attachment_thumbnail}\n amountText={message.metadata?.amount_text}\n detail={message.metadata?.attachment_detail}\n paymentStatus={message.metadata?.payment_status}\n isUnlocking={isUnlocking(message.id)}\n onUnlockClick={() => onUnlockClick?.(message, channel)}\n onFetchSource={async () =>\n await onFetchSource?.(message, channel)\n }\n onDownloadClick={() => onDownloadClick?.(message, channel)}\n />\n )}\n {message.text && (\n <div className=\"str-chat__message-bubble\">\n <MessageText message={message} renderText={renderText} />\n </div>\n )}\n </div>\n ) : isTipOnly ? (\n /* Tip-only messages render as a standalone bubble */\n <MessageTag message={message} standalone />\n ) : (\n <div className=\"str-chat__message-bubble-wrapper\">\n <div className=\"str-chat__message-bubble\">\n {isChatbot && !useAttachmentFooterChatbotTag && (\n <MessageTag\n message={message}\n hasAttachment={hasRenderableAttachments}\n isMyMessage={isMine}\n />\n )}\n {poll && <Poll poll={poll} />}\n {finalAttachments?.length && !message.quoted_message ? (\n <Attachment\n actionHandler={handleAction}\n attachments={finalAttachments}\n />\n ) : null}\n {isAIGenerated ? (\n <StreamedMessageText\n message={message}\n renderText={renderText}\n />\n ) : (\n <MessageText message={message} renderText={renderText} />\n )}\n <MessageErrorIcon />\n </div>\n {/* Tip/paid tags stay outside; chatbot attachment indicator stays outside too */}\n {(!isChatbot || useAttachmentFooterChatbotTag) && (\n <MessageTag\n message={message}\n hasAttachment={hasRenderableAttachments}\n isMyMessage={isMine}\n />\n )}\n {chatbotVotingEnabled && isChatbot && (\n <MessageVoteButtons\n selected={voteState}\n onVoteUp={voteUp}\n onVoteDown={voteDown}\n />\n )}\n </div>\n )}\n </div>\n {showReplyCountButton && (\n <MessageRepliesCountButton\n onClick={handleOpenThread}\n reply_count={message.reply_count}\n />\n )}\n {showIsReplyInChannel && (\n <MessageIsThreadReplyInChannelButtonIndicator />\n )}\n </div>\n </>\n )\n}\n\nconst MemoizedCustomMessage = React.memo(\n CustomMessageWithContext,\n (prev, next) => {\n if (prev.chatbotVotingEnabled !== next.chatbotVotingEnabled) return false\n return areMessageUIPropsEqual(prev, next)\n }\n) as typeof CustomMessageWithContext\n\nexport const CustomMessage = (props: CustomMessageUIComponentProps) => {\n const messageContext = useMessageContext('CustomMessage')\n return <MemoizedCustomMessage {...messageContext} {...props} />\n}\n","import { XIcon } from '@phosphor-icons/react'\nimport React from 'react'\nimport {\n LinkPreview,\n LinkPreviewsManager,\n LinkPreviewsManagerState,\n} from 'stream-chat'\nimport { useMessageComposer, useStateStore } from 'stream-chat-react'\n\nconst linkPreviewsManagerStateSelector = (state: LinkPreviewsManagerState) => ({\n linkPreviews: Array.from(state.previews.values()).filter(\n (preview) =>\n LinkPreviewsManager.previewIsLoaded(preview) ||\n LinkPreviewsManager.previewIsLoading(preview)\n ),\n})\n\ninterface CustomLinkPreviewCardProps {\n link: LinkPreview\n onDismiss: (url: string) => void\n}\n\nconst CustomLinkPreviewCard: React.FC<CustomLinkPreviewCardProps> = ({\n link,\n onDismiss,\n}) => {\n const { og_scrape_url, title, image_url } = link\n\n const handleDismissLink = (e: React.MouseEvent) => {\n e.preventDefault()\n onDismiss(og_scrape_url)\n }\n\n return (\n <a\n href={og_scrape_url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"relative w-full block rounded-[24px] bg-[#121110] p-2 no-underline transition-opacity hover:opacity-90\"\n >\n {image_url && (\n <img\n src={image_url}\n alt={title || ''}\n className=\"h-[148px] w-full rounded-[20px] object-cover\"\n />\n )}\n <button\n type=\"button\"\n onClick={handleDismissLink}\n className=\"absolute right-4 top-4 flex size-6 items-center justify-center rounded-full border border-white/40 bg-white/70 backdrop-blur-2xl focus-ring\"\n aria-label=\"Close link preview\"\n >\n <XIcon className=\"size-4 text-black/90\" />\n </button>\n <div className=\"p-2\">\n {title && (\n <div className=\"text-[14px] font-medium leading-5 text-white\">\n {title}\n </div>\n )}\n <div className=\"text-[12px] leading-4 text-white/55\">\n {og_scrape_url}\n </div>\n </div>\n </a>\n )\n}\n\nexport const CustomLinkPreviewList = () => {\n const { linkPreviewsManager } = useMessageComposer()\n\n const { linkPreviews: stateLinkPreviews } = useStateStore(\n linkPreviewsManager.state,\n linkPreviewsManagerStateSelector\n )\n\n const handleDismiss = (url: string) => {\n linkPreviewsManager.dismissPreview(url)\n }\n\n const showLinkPreviews = stateLinkPreviews.length > 0\n\n if (!showLinkPreviews) return null\n\n return (\n <div className=\"flex flex-col items-center w-full gap-2 mb-4\">\n {stateLinkPreviews.map((linkPreview) => (\n <CustomLinkPreviewCard\n key={linkPreview.og_scrape_url}\n link={linkPreview}\n onDismiss={handleDismiss}\n />\n ))}\n </div>\n )\n}\n","import { ArrowUpIcon } from '@phosphor-icons/react'\nimport React from 'react'\nimport {\n AttachmentPreviewList,\n MessageInput,\n QuotedMessagePreview,\n SimpleAttachmentSelector,\n TextareaComposer,\n useChannelStateContext,\n useComponentContext,\n useMessageComposerHasSendableData,\n useMessageInputContext,\n} from 'stream-chat-react'\n\nimport { CustomLinkPreviewList } from '../CustomLinkPreviewList'\n\nconst DefaultSendButton: React.FC<{\n sendMessage: () => void\n disabled?: boolean\n [key: string]: unknown\n}> = ({ sendMessage, disabled, ...rest }) => (\n <button\n {...rest}\n type=\"button\"\n aria-label=\"Send\"\n disabled={disabled}\n onClick={sendMessage}\n >\n <ArrowUpIcon weight=\"bold\" className=\"size-4\" />\n </button>\n)\n\nconst CustomMessageInputInner: React.FC = () => {\n const { channel } = useChannelStateContext()\n const isFrozen = channel?.data?.frozen === true\n const { handleSubmit } = useMessageInputContext()\n const { SendButton: SendButtonFromContext } = useComponentContext(\n 'CustomMessageInput',\n )\n const SendButton = SendButtonFromContext ?? DefaultSendButton\n const hasSendableData = useMessageComposerHasSendableData()\n const isSendDisabled = isFrozen || !hasSendableData\n\n return (\n <>\n <div className=\"left-container\">\n <SimpleAttachmentSelector />\n </div>\n <div className=\"central-container min-w-0 w-full p-2 bg-white rounded-[1.5rem] shadow-[0_4px_16px_0_rgba(0,0,0,0.08),0_1px_2px_0_rgba(0,0,0,0.04),0_0_0_1px_rgba(0,0,0,0.04)]\">\n <QuotedMessagePreview />\n <CustomLinkPreviewList />\n <AttachmentPreviewList />\n <div className=\"flex\">\n <div className=\"w-full ml-2 mr-4 self-center leading-[0]\">\n <TextareaComposer\n aria-disabled={isFrozen || undefined}\n className=\"w-full resize-none outline-none leading-6\"\n // While this might usually be considered an anti-pattern, in most\n // cases, when a message thread is rendered, we want the input to\n // gain focus automatically.\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus={!isFrozen}\n maxRows={4}\n readOnly={isFrozen}\n tabIndex={isFrozen ? -1 : undefined}\n />\n </div>\n <SendButton\n sendMessage={handleSubmit}\n aria-label=\"Send\"\n className=\"str-chat__send-button mt-auto flex justify-center items-center flex-shrink-0 rounded-full size-8 bg-[#121110] disabled:bg-[#F1F0EE] disabled:text-black/20 text-white focus-ring\"\n data-testid=\"send-button\"\n disabled={isSendDisabled}\n type=\"button\"\n />\n </div>\n </div>\n </>\n )\n}\n\nexport interface CustomMessageInputProps {\n renderActions?: () => React.ReactNode\n}\n\nexport const CustomMessageInput: React.FC<CustomMessageInputProps> = ({\n renderActions,\n}) => {\n const { channel } = useChannelStateContext()\n const isFrozen = channel?.data?.frozen === true\n\n return (\n <div\n // @ts-expect-error Only React 19 onwards has `inert` in its types.\n inert={isFrozen ? '' : undefined}\n aria-disabled={isFrozen || undefined}\n className=\"message-input flex items-center gap-2 p-4 aria-disabled:opacity-40\"\n >\n {renderActions?.()}\n <MessageInput Input={CustomMessageInputInner} />\n </div>\n )\n}\n","import { ProhibitIcon, SparkleIcon } from '@phosphor-icons/react'\nimport { MessageTimestamp, type EventComponentProps } from 'stream-chat-react'\n\nimport type {\n AgeSafetySystemType,\n DmAgentSystemType,\n} from '../../stream-custom-data'\n\nconst DM_AGENT_SYSTEM_TYPES: readonly DmAgentSystemType[] = [\n 'SYSTEM_DM_AGENT_PAUSED',\n 'SYSTEM_DM_AGENT_RESUMED',\n]\n\nconst DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT: Record<DmAgentSystemType, string> =\n {\n SYSTEM_DM_AGENT_PAUSED: 'DM Agent has left the conversation',\n SYSTEM_DM_AGENT_RESUMED: 'DM Agent has rejoined the conversation',\n }\n\nconst AGE_SAFETY_SYSTEM_TYPES: readonly AgeSafetySystemType[] = [\n 'SYSTEM_AGE_SAFETY_BLOCKED',\n]\n\nconst AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT: Record<\n AgeSafetySystemType,\n string\n> = {\n SYSTEM_AGE_SAFETY_BLOCKED:\n 'This user isn’t able to reply because they don’t meet our age safety guidelines.',\n}\n\nconst AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS = 'age safety guidelines.'\nconst AGE_SAFETY_SYSTEM_MESSAGE_URL = 'https://linktr.ee/s/about/contact'\n\nconst isDmAgentSystemType = (\n value: string | undefined\n): value is DmAgentSystemType => {\n return DM_AGENT_SYSTEM_TYPES.includes(value as DmAgentSystemType)\n}\n\nconst isAgeSafetySystemType = (\n value: string | undefined\n): value is AgeSafetySystemType => {\n return AGE_SAFETY_SYSTEM_TYPES.includes(value as AgeSafetySystemType)\n}\n\ntype CustomSystemMessageVariant =\n | {\n kind: 'dm-agent'\n type: DmAgentSystemType\n }\n | {\n kind: 'age-safety'\n type: AgeSafetySystemType\n }\n\nconst getCustomSystemMessageVariant = (\n message: EventComponentProps['message']\n): CustomSystemMessageVariant | undefined => {\n const metadataCustomType = message.metadata?.custom_type\n if (isDmAgentSystemType(metadataCustomType)) {\n return {\n kind: 'dm-agent',\n type: metadataCustomType,\n }\n }\n\n if (isAgeSafetySystemType(metadataCustomType)) {\n return {\n kind: 'age-safety',\n type: metadataCustomType,\n }\n }\n\n const fallbackType = message.dm_agent_system_type\n if (isDmAgentSystemType(fallbackType)) {\n return {\n kind: 'dm-agent',\n type: fallbackType,\n }\n }\n\n return undefined\n}\n\nconst renderAgeSafetyMessageText = (messageText: string): React.ReactNode => {\n const emphasisIndex = messageText.indexOf(AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS)\n if (emphasisIndex === -1) {\n return messageText\n }\n\n const emphasisEndIndex =\n emphasisIndex + AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS.length\n\n return (\n <>\n {messageText.slice(0, emphasisIndex)}\n <a\n href={AGE_SAFETY_SYSTEM_MESSAGE_URL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mes-age-safety-system-message__emphasis font-medium text-inherit underline\"\n >\n {AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS}\n </a>\n {messageText.slice(emphasisEndIndex)}\n </>\n )\n}\n\nexport const CustomSystemMessage: React.FC<EventComponentProps> = (props) => {\n const isDateHidden = props.message.hide_date === true\n const customSystemMessageVariant = getCustomSystemMessageVariant(\n props.message\n )\n\n if (customSystemMessageVariant?.kind === 'dm-agent') {\n const messageText =\n props.message.text?.trim() ||\n DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type]\n\n return (\n <div className=\"str-chat__message--system\" data-testid=\"message-system\">\n <div\n className=\"mes-dm-agent-system-message mx-auto mb-2 inline-flex w-fit max-w-[min(100%,480px)] items-center justify-center gap-[10px] rounded-[12px] border border-[rgba(0,0,0,0.08)] p-3 text-[rgba(0,0,0,0.55)]\"\n data-testid=\"dm-agent-system-message\"\n data-dm-agent-system-type={customSystemMessageVariant.type}\n >\n <SparkleIcon\n size={16}\n weight=\"regular\"\n aria-hidden\n className=\"mes-dm-agent-system-message__sparkle shrink-0\"\n />\n <p className=\"mes-dm-agent-system-message__text m-0 text-center text-[14px] font-normal leading-5 tracking-[0.21px]\">\n {messageText}\n </p>\n </div>\n {!isDateHidden && <MessageTimestamp message={props.message} />}\n </div>\n )\n }\n\n if (customSystemMessageVariant?.kind === 'age-safety') {\n const messageText =\n props.message.text?.trim() ||\n AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type]\n\n return (\n <div className=\"str-chat__message--system\" data-testid=\"message-system\">\n <div\n className=\"mes-age-safety-system-message box-border mx-auto mb-2 flex w-full max-w-[329px] items-start justify-center gap-3 rounded-[12px] border border-[var(--border-secondary,rgba(0,0,0,0.08))] bg-[var(--bg-warning-subtle,#fef3c6)] px-2 py-4 pl-5 text-[color:var(--text-warning-on-warning,#894b00)]\"\n data-testid=\"age-safety-system-message\"\n data-age-safety-system-type={customSystemMessageVariant.type}\n >\n <ProhibitIcon\n size={24}\n weight=\"duotone\"\n aria-hidden\n className=\"mes-age-safety-system-message__icon shrink-0 text-[color:var(--text-warning-on-warning,#894b00)]\"\n data-testid=\"age-safety-system-message-icon\"\n />\n <div className=\"mes-age-safety-system-message__content min-w-0 flex-[1_0_0]\">\n <p className=\"m-0 text-balance text-left text-[12px] font-normal leading-4 tracking-[0.21px] text-[color:var(--text-warning-on-warning,#894b00)]\">\n {renderAgeSafetyMessageText(messageText)}\n </p>\n </div>\n </div>\n {!isDateHidden && <MessageTimestamp message={props.message} />}\n </div>\n )\n }\n\n return (\n <div className=\"str-chat__message--system\" data-testid=\"message-system\">\n <div className=\"str-chat__message--system__text\">\n <div className=\"str-chat__message--system__line\"></div>\n <p>{props.message.text}</p>\n <div className=\"str-chat__message--system__line\"></div>\n </div>\n {!isDateHidden && <MessageTimestamp message={props.message} />}\n </div>\n )\n}\n","import React from 'react'\nimport type { Event } from 'stream-chat'\nimport {\n useChannelStateContext,\n useChatContext,\n useTypingContext,\n} from 'stream-chat-react'\n\nimport { Avatar } from '../Avatar'\n\ninterface CustomTypingIndicatorProps {\n threadList?: boolean\n}\n\nconst Circle = ({ cx, index }: { cx: string; index: number }) => (\n <circle cx={cx} cy=\"4\" r=\"3.9\" fill=\"#A0A0A0\">\n <animateTransform\n attributeName=\"transform\"\n type=\"translate\"\n values=\"0 0; 0 -2.25; 0 0;\"\n dur=\"900ms\"\n begin={`${120 * index}ms`} // 0ms, 120ms, 240ms\n repeatCount=\"indefinite\"\n />\n </circle>\n)\n\nconst CustomTypingIndicator = ({ threadList }: CustomTypingIndicatorProps) => {\n const { channel, channelConfig, thread } = useChannelStateContext()\n const { client } = useChatContext()\n const { typing = {} } = useTypingContext()\n\n if (channelConfig?.typing_events === false) {\n return null\n }\n\n const typingInChannel = !threadList\n ? Object.values(typing).filter(\n ({ parent_id, user }: Event) =>\n user?.id !== client.user?.id && !parent_id\n )\n : []\n\n const typingInThread = threadList\n ? Object.values(typing).filter(\n ({ parent_id, user }: Event) =>\n user?.id !== client.user?.id && parent_id === thread?.id\n )\n : []\n\n const typingUsers = threadList ? typingInThread : typingInChannel\n if (!typingUsers.length) {\n return null\n }\n\n const typingUser = typingUsers[0]?.user\n const memberUser =\n typingUser?.id && channel.state.members[typingUser.id]\n ? channel.state.members[typingUser.id].user\n : undefined\n\n const avatarId = typingUser?.id ?? memberUser?.id ?? 'typing-user'\n const avatarName =\n typingUser?.name ?? memberUser?.name ?? typingUser?.id ?? 'Typing user'\n const avatarImage = typingUser?.image ?? memberUser?.image\n\n return (\n <div\n className=\"str-chat__typing-indicator !items-end !bg-transparent\"\n data-testid=\"typing-indicator\"\n style={{ insetInlineStart: 0, insetInlineEnd: 'auto' }}\n >\n <div className=\"shrink-0\" aria-hidden=\"true\">\n <Avatar\n id={avatarId}\n name={avatarName}\n image={avatarImage}\n size={24}\n shape=\"circle\"\n />\n </div>\n\n <div className=\"px-4 py-3 rounded-lg bg-[#E9EAED] h-12 flex flex-col justify-end\">\n <svg\n aria-hidden=\"true\"\n className=\"block overflow-visible mb-[0.2rem]\"\n viewBox=\"0 0 32 8\"\n width=\"32\"\n height=\"8\"\n overflow=\"visible\"\n >\n <Circle cx=\"4\" index={0} />\n <Circle cx=\"16\" index={1} />\n <Circle cx=\"28\" index={2} />\n </svg>\n </div>\n </div>\n )\n}\n\nexport default CustomTypingIndicator\n","import React from 'react'\n\n/**\n * Empty state component shown when a channel has no messages\n * Returns null to show nothing - the LoadingIndicator handles the loading state\n */\nexport const ChannelEmptyState: React.FC = () => null\n","import classNames from 'classnames'\n\ntype LoadingProps = {\n className?: string\n message?: string\n}\n\nconst Loading = ({ className, message }: LoadingProps) => (\n <div\n className={classNames('flex items-center justify-center h-full', className)}\n >\n <svg viewBox=\"0 0 100 100\" className=\"size-8 fill-pebble\" stroke=\"none\">\n <circle cx=\"6\" cy=\"50\" r=\"6\">\n <animateTransform\n attributeName=\"transform\"\n dur=\"1s\"\n type=\"translate\"\n values=\"0 15 ; 0 -15; 0 15\"\n repeatCount=\"indefinite\"\n begin=\"0.1\"\n />\n </circle>\n <circle cx=\"30\" cy=\"50\" r=\"6\">\n <animateTransform\n attributeName=\"transform\"\n dur=\"1s\"\n type=\"translate\"\n values=\"0 10 ; 0 -10; 0 10\"\n repeatCount=\"indefinite\"\n begin=\"0.2\"\n />\n </circle>\n <circle cx=\"54\" cy=\"50\" r=\"6\">\n <animateTransform\n attributeName=\"transform\"\n dur=\"1s\"\n type=\"translate\"\n values=\"0 5 ; 0 -5; 0 5\"\n repeatCount=\"indefinite\"\n begin=\"0.3\"\n />\n </circle>\n </svg>\n {message && <span className=\"text-stone\">{message}</span>}\n </div>\n)\n\nexport default Loading\n","import React from 'react'\n\nimport Loading from '../Loading'\n\n/**\n * Loading state component\n */\nexport const LoadingState = React.memo(() => (\n <div className=\"messaging-loading-state flex items-center justify-center h-full\">\n <div className=\"flex items-center\">\n <Loading className=\"w-6 h-6\" />\n <span className=\"text-sm text-stone\">Loading messages</span>\n </div>\n </div>\n))\nLoadingState.displayName = 'LoadingState'\n","import {\n ArrowLeftIcon,\n CaretRightIcon,\n DotsThreeIcon,\n SparkleIcon,\n StarIcon,\n} from '@phosphor-icons/react'\nimport classNames from 'classnames'\nimport React, { useCallback, useRef } from 'react'\nimport { Channel as ChannelType } from 'stream-chat'\nimport {\n Channel,\n Window,\n MessageList,\n useMessageContext,\n useChannelStateContext,\n WithComponents,\n MessageUIComponentProps,\n} from 'stream-chat-react'\n\nimport { useChannelStar } from '../hooks/useChannelStar'\nimport type { ChannelViewProps } from '../types'\n\nimport { Avatar } from './Avatar'\nimport { ChannelInfoDialog } from './ChannelInfoDialog'\nimport { CustomDateSeparator } from './CustomDateSeparator'\nimport { CustomMessage } from './CustomMessage'\nimport { CustomMessageInput } from './CustomMessageInput'\nimport { CustomSystemMessage } from './CustomSystemMessage'\nimport CustomTypingIndicator from './CustomTypingIndicator'\nimport { ChannelEmptyState } from './MessagingShell/ChannelEmptyState'\nimport { LoadingState } from './MessagingShell/LoadingState'\n\nconst ICON_BTN_CLASS =\n 'size-10 rounded-full bg-[#F1F0EE] hover:bg-[#E5E4E1] flex items-center justify-center transition-colors duration-150 focus-ring'\nconst DM_AGENT_HEADER_HELPER_TEXT = 'Replies instantly with AI assistant'\n\n/**\n * Custom channel header component\n */\nconst CustomChannelHeader: React.FC<{\n onBack?: () => void\n showBackButton: boolean\n onShowInfo: () => void\n canShowInfo: boolean\n showStarButton?: boolean\n dmAgentEnabled?: boolean\n}> = ({\n onBack,\n showBackButton,\n onShowInfo,\n canShowInfo,\n showStarButton = false,\n dmAgentEnabled = false,\n}) => {\n const { channel } = useChannelStateContext()\n\n // Get participant info (excluding current user)\n const participant = React.useMemo(() => {\n const members = Object.values(channel.state.members || {})\n return members.find(\n (member) => member.user?.id && member.user.id !== channel._client.userID\n )\n }, [channel._client.userID, channel.state.members])\n\n const participantName =\n participant?.user?.name || participant?.user?.id || 'Unknown member'\n const participantImage = participant?.user?.image\n const isStarred = useChannelStar(channel)\n\n const handleStarClick = async () => {\n try {\n if (isStarred) {\n await channel.unpin()\n } else {\n await channel.pin()\n }\n } catch (error) {\n console.error(\n '[CustomChannelHeader] Failed to update pinned status:',\n error\n )\n }\n }\n\n return (\n <div className=\"@container\">\n <div className=\"grid grid-cols-[1fr_auto_1fr] w-full items-center @lg:hidden\">\n <div className=\"flex items-center gap-2\">\n {showBackButton && (\n <button\n className={ICON_BTN_CLASS}\n onClick={onBack || (() => {})}\n type=\"button\"\n aria-label=\"Back to conversations\"\n >\n <ArrowLeftIcon className=\"size-5 text-black/90\" />\n </button>\n )}\n </div>\n <div className=\"flex flex-col gap-1 items-center\">\n <Avatar\n id={participant?.user?.id || channel.id || 'unknown'}\n name={participantName}\n image={participantImage}\n starred={showStarButton && isStarred}\n dmAgentEnabled={dmAgentEnabled}\n size={40}\n />\n <button\n type=\"button\"\n onClick={onShowInfo}\n className=\"flex items-center gap-0.5 rounded-full bg-black/[0.05] px-3 py-1 text-xs font-medium text-black/90 hover:bg-black/[0.08] transition-colors\"\n aria-label={`View info for ${participantName}`}\n >\n {participantName}\n <CaretRightIcon className=\"size-3 shrink-0\" />\n </button>\n {dmAgentEnabled && (\n <div className=\"flex items-center gap-1 text-[10px] leading-3 text-black/55\">\n <SparkleIcon className=\"size-3 shrink-0 text-black/55\" />\n <span>{DM_AGENT_HEADER_HELPER_TEXT}</span>\n </div>\n )}\n </div>\n <div className=\"flex justify-end items-center gap-2\">\n {showStarButton && (\n <button\n className={ICON_BTN_CLASS}\n onClick={handleStarClick}\n type=\"button\"\n aria-label={\n isStarred ? 'Unstar conversation' : 'Star conversation'\n }\n >\n <StarIcon\n className={classNames('size-5', {\n 'text-yellow-600': isStarred,\n 'text-black/90': !isStarred,\n })}\n weight={isStarred ? 'duotone' : 'regular'}\n />\n </button>\n )}\n <button\n className={ICON_BTN_CLASS}\n onClick={onShowInfo}\n type=\"button\"\n aria-label=\"Show info\"\n >\n <DotsThreeIcon className=\"size-5 text-black/90\" />\n </button>\n </div>\n </div>\n <div className=\"hidden @lg:flex items-center justify-between gap-3 min-h-12\">\n <div className=\"flex items-center gap-4 min-w-0\">\n {showBackButton && onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n className={ICON_BTN_CLASS}\n aria-label=\"Back to conversations\"\n >\n <ArrowLeftIcon className=\"size-5 text-black/90\" />\n </button>\n )}\n {/* Avatar */}\n <Avatar\n id={participant?.user?.id || channel.id || 'unknown'}\n name={participantName}\n image={participantImage}\n starred={showStarButton && isStarred}\n dmAgentEnabled={dmAgentEnabled}\n size={40}\n />\n <div className=\"min-w-0\">\n {canShowInfo ? (\n <button\n type=\"button\"\n onClick={onShowInfo}\n className=\"flex items-center gap-1 font-medium text-black/90 truncate hover:text-black/70 transition-colors\"\n aria-label={`View info for ${participantName}`}\n >\n <span className=\"truncate\">{participantName}</span>\n <CaretRightIcon className=\"size-4 shrink-0\" />\n </button>\n ) : (\n <h1 className=\"font-medium text-black/90 truncate\">\n {participantName}\n </h1>\n )}\n {dmAgentEnabled && (\n <div className=\"mt-0.5 flex items-center gap-1 text-[10px] leading-3 text-black/55\">\n <SparkleIcon className=\"size-3 shrink-0 text-black/55\" />\n <span className=\"truncate\">{DM_AGENT_HEADER_HELPER_TEXT}</span>\n </div>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {showStarButton && (\n <button\n className={ICON_BTN_CLASS}\n onClick={handleStarClick}\n type=\"button\"\n aria-label={\n isStarred ? 'Unstar conversation' : 'Star conversation'\n }\n >\n <StarIcon\n className={classNames('size-5', {\n 'text-yellow-600': isStarred,\n 'text-black/90': !isStarred,\n })}\n weight={isStarred ? 'duotone' : 'regular'}\n />\n </button>\n )}\n {canShowInfo && onShowInfo && (\n <button\n className={ICON_BTN_CLASS}\n onClick={onShowInfo}\n type=\"button\"\n aria-label=\"Show info\"\n >\n <DotsThreeIcon className=\"size-5 text-black/90\" />\n </button>\n )}\n </div>\n </div>\n </div>\n )\n}\n\n/**\n * Inner component that has access to channel context\n */\nconst ChannelViewInner: React.FC<{\n onBack?: () => void\n showBackButton: boolean\n renderMessageInputActions?: (channel: ChannelType) => React.ReactNode\n renderConversationFooter?: (channel: ChannelType) => React.ReactNode\n onLeaveConversation?: (channel: ChannelType) => void\n onBlockParticipant?: (participantId?: string) => void\n CustomChannelEmptyState?: React.ComponentType\n showDeleteConversation?: boolean\n onDeleteConversationClick?: () => void\n onBlockParticipantClick?: () => void\n onReportParticipantClick?: () => void\n showStarButton?: boolean\n chatbotVotingEnabled?: boolean\n renderChannelBanner?: () => React.ReactNode\n customProfileContent?: React.ReactNode\n customChannelActions?: React.ReactNode\n renderMessage?: (\n messageNode: React.ReactElement,\n message: NonNullable<MessageUIComponentProps['message']>\n ) => React.ReactNode\n dmAgentEnabled?: boolean\n}> = ({\n onBack,\n showBackButton,\n renderMessageInputActions,\n renderConversationFooter,\n onLeaveConversation,\n onBlockParticipant,\n showDeleteConversation = true,\n onDeleteConversationClick,\n onBlockParticipantClick,\n onReportParticipantClick,\n showStarButton = false,\n chatbotVotingEnabled = false,\n renderChannelBanner,\n customProfileContent,\n customChannelActions,\n renderMessage,\n dmAgentEnabled = false,\n}) => {\n const { channel } = useChannelStateContext()\n const infoDialogRef = useRef<HTMLDialogElement>(null)\n\n // Get participant info for info dialog\n const participant = React.useMemo(() => {\n const members = Object.values(channel.state.members || {})\n return members.find(\n (member) => member.user?.id && member.user.id !== channel._client.userID\n )\n }, [channel._client.userID, channel.state.members])\n\n const currentMember = React.useMemo(() => {\n const members = Object.values(channel.state.members || {})\n return members.find((member) => member.user?.id === channel._client.userID)\n }, [channel._client.userID, channel.state.members])\n\n const currentUserIsAccount =\n (currentMember?.user as { is_account?: boolean } | undefined)?.is_account ??\n (currentMember as { is_account?: boolean } | undefined)?.is_account\n const participantIsAccount =\n (participant?.user as { is_account?: boolean } | undefined)?.is_account ??\n (participant as { is_account?: boolean } | undefined)?.is_account\n\n const showDmAgentHeader =\n dmAgentEnabled &&\n currentUserIsAccount === false &&\n participantIsAccount === true\n\n // Get follower status label from channel data\n const followerStatusLabel = React.useMemo(() => {\n const channelExtraData = (channel.data ?? {}) as {\n followerStatus?: string\n isFollower?: boolean\n }\n\n // If explicit followerStatus is provided, use it\n if (channelExtraData.followerStatus) {\n return String(channelExtraData.followerStatus)\n }\n // If isFollower is explicitly defined, use it to determine status\n if (channelExtraData.isFollower !== undefined) {\n return channelExtraData.isFollower\n ? 'Subscribed to you'\n : 'Not subscribed'\n }\n // Otherwise, don't show any status\n return undefined\n }, [channel.data])\n\n const handleShowInfo = useCallback(() => {\n infoDialogRef.current?.showModal()\n }, [])\n\n const handleCloseInfo = useCallback(() => {\n infoDialogRef.current?.close()\n }, [])\n\n // Prevents all message instances from unmounting when ChannelViewInner re-renders\n const MessageOverride = useCallback(\n (props: MessageUIComponentProps) => {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const { message } = useMessageContext('ChannelView')\n const messageNode = (\n <CustomMessage {...props} chatbotVotingEnabled={chatbotVotingEnabled} />\n )\n\n if (!renderMessage || !message) {\n return messageNode\n }\n\n return renderMessage(messageNode, message)\n },\n [chatbotVotingEnabled, renderMessage]\n )\n\n return (\n <>\n <WithComponents overrides={{ Message: MessageOverride }}>\n <Window>\n {/* Custom Channel Header */}\n <div className=\"p-4\">\n <CustomChannelHeader\n onBack={onBack}\n showBackButton={showBackButton}\n onShowInfo={handleShowInfo}\n canShowInfo={Boolean(participant)}\n showStarButton={showStarButton}\n dmAgentEnabled={showDmAgentHeader}\n />\n </div>\n\n {/* Custom Banner/Summary */}\n {renderChannelBanner?.()}\n\n {/* Message List */}\n <div className=\"flex-1 overflow-hidden relative\">\n <MessageList\n hideDeletedMessages\n hideNewMessageSeparator={false}\n messageActions={undefined}\n />\n </div>\n\n {renderConversationFooter?.(channel)}\n\n {/* Message Input */}\n <CustomMessageInput\n renderActions={() => renderMessageInputActions?.(channel)}\n />\n </Window>\n </WithComponents>\n\n {/* Channel Info Dialog */}\n <ChannelInfoDialog\n dialogRef={infoDialogRef}\n onClose={handleCloseInfo}\n participant={participant}\n channel={channel}\n followerStatusLabel={followerStatusLabel}\n onLeaveConversation={onLeaveConversation}\n onBlockParticipant={onBlockParticipant}\n showDeleteConversation={showDeleteConversation}\n onDeleteConversationClick={onDeleteConversationClick}\n onBlockParticipantClick={onBlockParticipantClick}\n onReportParticipantClick={onReportParticipantClick}\n customProfileContent={customProfileContent}\n customChannelActions={customChannelActions}\n />\n </>\n )\n}\n\n/**\n * Channel view component with message list and input\n */\nexport const ChannelView = React.memo<ChannelViewProps>(\n ({\n channel,\n onBack,\n showBackButton = false,\n renderMessageInputActions,\n renderConversationFooter,\n onLeaveConversation,\n onBlockParticipant,\n className,\n CustomChannelEmptyState = ChannelEmptyState,\n showDeleteConversation = true,\n onDeleteConversationClick,\n onBlockParticipantClick,\n onReportParticipantClick,\n dmAgentEnabled,\n messageMetadata,\n onMessageSent,\n showStarButton = false,\n chatbotVotingEnabled = false,\n renderChannelBanner,\n customProfileContent,\n customChannelActions,\n renderMessage,\n sendButton,\n }) => {\n // Custom send message handler that:\n // 1. Applies messageMetadata if provided\n // 2. Adds skip_push and silent when DM agent is active\n // 3. Calls onMessageSent callback with full response\n // Read chatbot_paused inside callback to get current value at send time (not stale closure)\n const doSendMessageRequest = useCallback(\n async (\n _channel: ChannelType,\n message: Parameters<ChannelType['sendMessage']>[0],\n options?: Parameters<ChannelType['sendMessage']>[1]\n ) => {\n const agentPaused =\n (channel.data as { chatbot_paused?: boolean })?.chatbot_paused ===\n true\n const shouldSuppressNotifications = dmAgentEnabled && !agentPaused\n\n // Build final message with nested metadata\n const finalMessage = {\n ...message,\n ...(shouldSuppressNotifications && { silent: true }),\n ...(messageMetadata && {\n metadata: {\n ...(message.metadata ?? {}),\n ...messageMetadata,\n },\n }),\n }\n\n // Build final options\n const finalOptions = {\n ...options,\n ...(shouldSuppressNotifications && { skip_push: true }),\n }\n\n const response = await channel.sendMessage(finalMessage, finalOptions)\n\n // Fire callback with full response (includes message.id)\n onMessageSent?.(response)\n\n return response\n },\n [channel, dmAgentEnabled, messageMetadata, onMessageSent]\n )\n\n return (\n <div\n className={classNames(\n 'messaging-channel-view h-full flex flex-col',\n className\n )}\n >\n <Channel\n channel={channel}\n MessageSystem={CustomSystemMessage}\n EmptyStateIndicator={CustomChannelEmptyState}\n LoadingIndicator={LoadingState}\n DateSeparator={CustomDateSeparator}\n TypingIndicator={CustomTypingIndicator}\n doSendMessageRequest={doSendMessageRequest}\n {...(sendButton ? { SendButton: sendButton } : {})}\n >\n <ChannelViewInner\n onBack={onBack}\n showBackButton={showBackButton}\n renderMessageInputActions={renderMessageInputActions}\n renderConversationFooter={renderConversationFooter}\n onLeaveConversation={onLeaveConversation}\n onBlockParticipant={onBlockParticipant}\n CustomChannelEmptyState={CustomChannelEmptyState}\n showDeleteConversation={showDeleteConversation}\n onDeleteConversationClick={onDeleteConversationClick}\n onBlockParticipantClick={onBlockParticipantClick}\n onReportParticipantClick={onReportParticipantClick}\n showStarButton={showStarButton}\n dmAgentEnabled={dmAgentEnabled}\n chatbotVotingEnabled={chatbotVotingEnabled}\n renderChannelBanner={renderChannelBanner}\n customProfileContent={customProfileContent}\n customChannelActions={customChannelActions}\n renderMessage={renderMessage}\n />\n </Channel>\n </div>\n )\n }\n)\nChannelView.displayName = 'ChannelView'\n","import { MagnifyingGlassIcon, XIcon } from '@phosphor-icons/react'\nimport { useRef } from 'react'\n\nimport { IconButton } from '../IconButton'\n\ninterface SearchInputProps {\n searchQuery: string\n setSearchQuery: (value: string) => void\n placeholder: string\n}\n\nexport function SearchInput({\n searchQuery,\n setSearchQuery,\n placeholder,\n}: SearchInputProps) {\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n return (\n <div className=\"relative\">\n <MagnifyingGlassIcon\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-stone\"\n weight=\"bold\"\n />\n\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder={placeholder}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-10 pr-10 py-3 text-sm border border-sand rounded-xl focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent\"\n />\n\n {searchQuery && (\n <IconButton\n label=\"Clear search\"\n onClick={() => {\n setSearchQuery('')\n searchInputRef.current?.focus()\n }}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 p-1 text-stone hover:text-charcoal\"\n >\n <XIcon className=\"h-4 w-4\" weight=\"bold\" />\n </IconButton>\n )}\n </div>\n )\n}\n","import { ChatCircleDotsIcon, SpinnerGapIcon } from '@phosphor-icons/react'\nimport classNames from 'classnames'\nimport React, { useCallback, useEffect, useState, useRef } from 'react'\n\nimport { useMessagingContext } from '../../providers/MessagingProvider'\nimport type { ParticipantPickerProps, Participant } from '../../types'\nimport { Avatar } from '../Avatar'\nimport { CloseButton } from '../CloseButton'\nimport { SearchInput } from '../SearchInput'\n\n/**\n * Generic participant picker component for starting conversations\n */\nexport const ParticipantPicker: React.FC<ParticipantPickerProps> = ({\n participantSource,\n onSelectParticipant,\n onClose,\n existingParticipantIds = new Set(),\n participantLabel = 'participants',\n searchPlaceholder = 'Search participants...',\n className,\n}) => {\n const { debug } = useMessagingContext()\n const [searchQuery, setSearchQuery] = useState('')\n const [participants, setParticipants] = useState<Participant[]>([])\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [startingChatWithId, setStartingChatWithId] = useState<string | null>(\n null\n )\n\n // Track if we've already loaded participants to prevent repeated loading\n const loadedRef = useRef(false)\n\n // New source instance should be allowed to load again\n useEffect(() => {\n loadedRef.current = false\n }, [participantSource])\n\n /* eslint-disable react-hooks/exhaustive-deps -- syncs with participantSource + debug; inner async uses participantSource.loadParticipants */\n // Load participants initially - wait for participantSource to finish loading first\n useEffect(() => {\n // Wait for the participantSource to finish loading before we try to load participants\n if (participantSource.loading) {\n if (debug) {\n console.log(\n '[ParticipantPicker] Waiting for participant source to finish loading...'\n )\n }\n return\n }\n\n if (loadedRef.current) return // Prevent multiple loads\n\n const loadInitialParticipants = async () => {\n if (debug) {\n console.log('[ParticipantPicker] Loading initial participants...')\n }\n setLoading(true)\n setError(null)\n\n try {\n const result = await participantSource.loadParticipants({\n search: '', // Load all participants initially\n limit: 100,\n })\n setParticipants(result.participants)\n loadedRef.current = true // Mark as loaded\n if (debug) {\n console.log(\n '[ParticipantPicker] Participants loaded successfully:',\n result.participants.length\n )\n }\n } catch (err) {\n const errorMessage =\n err instanceof Error ? err.message : 'Failed to load participants'\n setError(errorMessage)\n console.error('[ParticipantPicker] Failed to load participants:', err)\n // Don't mark as loaded on error, allow retry\n } finally {\n setLoading(false)\n }\n }\n\n loadInitialParticipants()\n }, [participantSource, debug])\n /* eslint-enable react-hooks/exhaustive-deps */\n\n // Filter participants by search query and existing participants\n const availableParticipants = participants\n .filter((participant) => !existingParticipantIds.has(participant.id))\n .filter((participant) => {\n if (!searchQuery) return true\n const searchLower = searchQuery.toLowerCase()\n return (\n participant.name.toLowerCase().includes(searchLower) ||\n participant.email?.toLowerCase().includes(searchLower) ||\n false\n )\n })\n\n const handleSelectParticipant = useCallback(\n async (participant: Participant) => {\n if (startingChatWithId) return // Prevent multiple clicks\n\n setStartingChatWithId(participant.id)\n try {\n await onSelectParticipant(participant)\n } catch (error) {\n console.error('[ParticipantPicker] Failed to start chat:', error)\n // Reset the loading state on error\n setStartingChatWithId(null)\n }\n // Note: Don't reset startingChatWithId on success because the dialog will close\n },\n [onSelectParticipant, startingChatWithId]\n )\n\n const handleKeyDown = (\n event: React.KeyboardEvent,\n participant: Participant\n ) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n handleSelectParticipant(participant)\n }\n }\n\n return (\n <div className={classNames('flex flex-col h-full', className)}>\n {/* Header */}\n <div className=\"px-4 py-4 border-b border-sand bg-chalk\">\n <div className=\"flex items-center justify-between mb-3\">\n <h2 className=\"text-lg font-semibold text-charcoal\">\n Start a new Conversation\n </h2>\n <CloseButton onClick={onClose} />\n </div>\n\n <p className=\"text-xs text-stone mb-3\">\n Select a {participantLabel.slice(0, -1)} to start messaging (\n {availableParticipants.length} available)\n {participantSource.totalCount !== undefined &&\n ` • ${participantSource.totalCount} ${participantLabel} total`}\n </p>\n\n <SearchInput\n searchQuery={searchQuery}\n setSearchQuery={setSearchQuery}\n placeholder={searchPlaceholder}\n />\n </div>\n\n {/* Error State */}\n {error && (\n <div className=\"p-4 text-sm text-danger bg-danger-alt\">\n Error loading {participantLabel}: {error}\n </div>\n )}\n\n {/* Participants List */}\n <div className=\"flex-1 overflow-auto\">\n {loading && availableParticipants.length === 0 ? (\n <div className=\"h-32 flex items-center justify-center\">\n <div className=\"flex items-center space-x-2\">\n <div className=\"w-4 h-4 animate-spin rounded-full border-2 border-primary border-t-transparent\"></div>\n <span className=\"text-sm text-stone\">\n Loading {participantLabel}...\n </span>\n </div>\n </div>\n ) : availableParticipants.length === 0 ? (\n <div className=\"p-6 text-center\">\n <div className=\"mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-sand\">\n <ChatCircleDotsIcon className=\"h-8 w-8 text-charcoal\" />\n </div>\n <h3 className=\"text-sm font-semibold text-charcoal mb-2\">\n {searchQuery\n ? `No ${participantLabel} found`\n : participants.length > 0\n ? `Already chatting with all ${participantLabel}`\n : `No ${participantLabel} yet`}\n </h3>\n <p className=\"text-xs text-stone\">\n {searchQuery\n ? 'Try a different search term'\n : participants.length > 0\n ? `You have existing conversations with all your ${participantLabel}`\n : `${participantLabel.charAt(0).toUpperCase() + participantLabel.slice(1)} will appear here`}\n </p>\n </div>\n ) : (\n <ul className=\"space-y-0\">\n {availableParticipants.map((participant) => {\n const displayName =\n participant.name || participant.email || participant.id\n const displaySecondary =\n participant.email && participant.name\n ? participant.email\n : participant.phone\n\n return (\n <li key={participant.id}>\n <button\n type=\"button\"\n onClick={() => handleSelectParticipant(participant)}\n onKeyDown={(e) => handleKeyDown(e, participant)}\n className=\"w-full px-4 py-3 hover:bg-sand transition-colors border-b border-sand text-left focus-ring\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-3 flex-1 min-w-0\">\n {/* Avatar */}\n <Avatar\n id={participant.id}\n name={displayName}\n image={participant.image}\n size={40}\n />\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"text-sm font-medium text-charcoal truncate\">\n {displayName}\n </h4>\n {displaySecondary && (\n <p className=\"text-xs text-stone truncate\">\n {displaySecondary}\n </p>\n )}\n </div>\n </div>\n\n {/* Icon */}\n <div className=\"flex-shrink-0\">\n {startingChatWithId === participant.id ? (\n <SpinnerGapIcon className=\"h-5 w-5 text-primary animate-spin\" />\n ) : (\n <ChatCircleDotsIcon className=\"h-5 w-5 text-stone\" />\n )}\n </div>\n </div>\n </button>\n </li>\n )\n })}\n\n {/* Loading indicator */}\n {loading && (\n <li className=\"p-4 flex justify-center\">\n <div className=\"flex items-center space-x-2\">\n <div className=\"w-4 h-4 animate-spin rounded-full border-2 border-primary border-t-transparent\"></div>\n <span className=\"text-sm text-stone\">Loading more...</span>\n </div>\n </li>\n )}\n </ul>\n )}\n </div>\n </div>\n )\n}\n","import React from 'react'\n\nconst ChatBubblesIllustration = ({ className }: { className?: string }) => (\n <svg\n width=\"140\"\n height=\"120\"\n viewBox=\"44 -2 144 126\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n >\n <g clipPath=\"url(#clip0_empty_state)\">\n <path\n d=\"M123.68 82.1932C123.383 103.675 105.839 121 84.2417 121C77.4724 121 71.0986 119.297 65.5327 116.299L52.5873 119.687L53.8036 106.673C48.1776 99.8701 44.7994 91.1453 44.7994 81.6356C44.7994 59.8965 62.4554 42.2754 84.2374 42.2754C89.1328 42.2754 93.8175 43.1633 98.1413 44.789\"\n fill=\"#D7D4CE\"\n />\n <path\n d=\"M84.2458 86.0364C82.2851 86.0364 80.6957 84.4501 80.6957 82.4933C80.6957 80.5365 82.2851 78.9502 84.2458 78.9502C86.2065 78.9502 87.7959 80.5365 87.7959 82.4933C87.7959 84.4501 86.2065 86.0364 84.2458 86.0364Z\"\n fill=\"white\"\n />\n <path\n d=\"M68.3044 86.0364C66.3437 86.0364 64.7543 84.4501 64.7543 82.4933C64.7543 80.5365 66.3437 78.9502 68.3044 78.9502C70.2651 78.9502 71.8545 80.5365 71.8545 82.4933C71.8545 84.4501 70.2651 86.0364 68.3044 86.0364Z\"\n fill=\"white\"\n />\n <path\n d=\"M100.183 86.0364C98.2226 86.0364 96.6332 84.4501 96.6332 82.4933C96.6332 80.5365 98.2226 78.9502 100.183 78.9502C102.144 78.9502 103.733 80.5365 103.733 82.4933C103.733 84.4501 102.144 86.0364 100.183 86.0364Z\"\n fill=\"white\"\n />\n <g filter=\"url(#filter0_empty_state)\">\n <path\n d=\"M171.522 68.7154C177.443 61.4539 181 52.1488 181 42C181 18.8027 162.421 0 139.5 0C116.579 0 98 18.8027 98 42C98 65.1973 116.579 84 139.5 84C146.622 84 153.328 82.1857 159.184 78.9829L172.801 82.5993L171.522 68.7154Z\"\n fill=\"white\"\n />\n <path\n d=\"M171.522 68.7154C177.443 61.4539 181 52.1488 181 42C181 18.8027 162.421 0 139.5 0C116.579 0 98 18.8027 98 42C98 65.1973 116.579 84 139.5 84C146.622 84 153.328 82.1857 159.184 78.9829L172.801 82.5993L171.522 68.7154Z\"\n stroke=\"#D7D4CE\"\n strokeWidth=\"2\"\n strokeMiterlimit=\"10\"\n />\n </g>\n <path\n d=\"M139.502 45.5431C137.541 45.5431 135.952 43.9568 135.952 42C135.952 40.0432 137.541 38.4569 139.502 38.4569C141.462 38.4569 143.052 40.0432 143.052 42C143.052 43.9568 141.462 45.5431 139.502 45.5431Z\"\n fill=\"#D7D4CE\"\n />\n <path\n d=\"M123.561 45.5431C121.601 45.5431 120.011 43.9568 120.011 42C120.011 40.0432 121.601 38.4569 123.561 38.4569C125.522 38.4569 127.111 40.0432 127.111 42C127.111 43.9568 125.522 45.5431 123.561 45.5431Z\"\n fill=\"#D7D4CE\"\n />\n <path\n d=\"M155.439 45.5431C153.478 45.5431 151.889 43.9568 151.889 42C151.889 40.0432 153.478 38.4569 155.439 38.4569C157.4 38.4569 158.989 40.0432 158.989 42C158.989 43.9568 157.4 45.5431 155.439 45.5431Z\"\n fill=\"#D7D4CE\"\n />\n </g>\n <defs>\n <filter\n id=\"filter0_empty_state\"\n x=\"97\"\n y=\"-1\"\n width=\"89\"\n height=\"90\"\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\n <feColorMatrix\n in=\"SourceAlpha\"\n type=\"matrix\"\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\n result=\"hardAlpha\"\n />\n <feOffset dx=\"4\" dy=\"4\" />\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\n <feColorMatrix\n type=\"matrix\"\n values=\"0 0 0 0 0.8428 0 0 0 0 0.830064 0 0 0 0 0.8095 0 0 0 1 0\"\n />\n <feBlend\n mode=\"normal\"\n in2=\"BackgroundImageFix\"\n result=\"effect1_dropShadow\"\n />\n <feBlend\n mode=\"normal\"\n in=\"SourceGraphic\"\n in2=\"effect1_dropShadow\"\n result=\"shape\"\n />\n </filter>\n <clipPath id=\"clip0_empty_state\">\n <rect width=\"233\" height=\"233\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n)\n\n/**\n * Empty state component shown when no channel is selected\n */\nexport const EmptyState = React.memo<{ hasChannels: boolean; channelsLoaded: boolean }>(\n ({ hasChannels, channelsLoaded }) => (\n <div className=\"messaging-empty-state flex items-center justify-center h-full p-8 text-balance\">\n <div className=\"flex flex-col items-center max-w-sm text-center\">\n <ChatBubblesIllustration />\n {channelsLoaded && !hasChannels && (\n <div className=\"mt-8\">\n <h2 className=\"font-medium text-black text-[18px] mb-2\">\n Your inbox is empty\n </h2>\n <p className=\"text-[#676B5F] text-sm mb-6\">\n Share with your followers to start receiving messages\n </p>\n </div>\n )}\n </div>\n </div>\n))\nEmptyState.displayName = 'EmptyState'\n","import React from 'react'\n\ntype ErrorStateProps = {\n message: string\n onBack?: () => void\n}\n\n/**\n * Error state component shown when something goes wrong\n */\nexport const ErrorState = React.memo<ErrorStateProps>(({ message, onBack }) => (\n <div className=\"messaging-error-state flex items-center justify-center h-full p-8\">\n <div className=\"text-center max-w-sm\">\n <div className=\"w-24 h-24 bg-danger-alt/20 rounded-full flex items-center justify-center mx-auto mb-6\">\n <span className=\"text-4xl\">⚠️</span>\n </div>\n\n <h2 className=\"font-semibold text-charcoal mb-2\">Oops!</h2>\n\n <p className=\"text-stone text-sm mb-6\">{message}</p>\n\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-[#7f22fe] hover:bg-primary-alt rounded-lg transition-colors focus-ring\"\n >\n Go Back\n </button>\n )}\n </div>\n </div>\n))\nErrorState.displayName = 'ErrorState'\n","import classNames from 'classnames'\nimport React, { useState, useCallback, useRef, useEffect } from 'react'\nimport type { Channel } from 'stream-chat'\n\nimport { useMessaging } from '../../hooks/useMessaging'\nimport type { MessagingShellProps, Participant } from '../../types'\nimport { ChannelList } from '../ChannelList'\nimport { ChannelView } from '../ChannelView'\nimport { ParticipantPicker } from '../ParticipantPicker'\n\nimport { EmptyState } from './EmptyState'\nimport { ErrorState } from './ErrorState'\nimport { LoadingState } from './LoadingState'\n\n/**\n * Main messaging interface component that combines channel list and channel view\n */\nexport const MessagingShell: React.FC<MessagingShellProps> = ({\n capabilities = {},\n className,\n renderMessageInputActions,\n renderConversationFooter,\n onChannelSelect,\n onParticipantSelect,\n initialParticipantFilter,\n initialParticipantData,\n CustomChannelEmptyState,\n showChannelList = true,\n filters,\n channelRenderFilterFn,\n channelListCustomEmptyStateIndicator,\n onDeleteConversationClick,\n onBlockParticipantClick,\n onReportParticipantClick,\n dmAgentEnabled,\n messageMetadata,\n onMessageSent,\n showStarButton = false,\n chatbotVotingEnabled = false,\n renderMessagePreview,\n renderChannelBanner,\n customProfileContent,\n customChannelActions,\n renderMessage,\n sendButton,\n}) => {\n const {\n service,\n client,\n isConnected,\n isLoading,\n error,\n refreshConnection,\n debug,\n } = useMessaging()\n\n const [selectedChannel, setSelectedChannel] = useState<Channel | null>(null)\n const [hasChannels, setHasChannels] = useState(false)\n const [channelsLoaded, setChannelsLoaded] = useState(false)\n const [_showParticipantPicker, setShowParticipantPicker] = useState(false)\n const [existingParticipantIds, setExistingParticipantIds] = useState<\n Set<string>\n >(new Set())\n const [pickerKey, _setPickerKey] = useState(0) // Key to force remount of ParticipantPicker\n const [directConversationMode, setDirectConversationMode] = useState(false)\n const [directConversationError, setDirectConversationError] = useState<\n string | null\n >(null)\n\n const participantPickerRef = useRef<HTMLDialogElement>(null)\n\n const {\n participantSource,\n participantLabel = 'participants',\n showDeleteConversation = true,\n } = capabilities\n\n // Create default filters and merge with provided filters\n const channelFilters = React.useMemo(() => {\n const userId = client?.userID\n\n // Base filters that should always be present\n const baseFilters = {\n type: 'messaging',\n last_message_at: { $exists: true },\n ...(userId && {\n members: { $in: [userId] },\n hidden: false,\n }),\n }\n\n // Merge provided filters with base filters\n // Provided filters can override base filters if needed\n return {\n ...baseFilters,\n ...filters,\n }\n }, [filters, client?.userID])\n\n // Track if we've already synced channels to prevent repeated API calls\n const syncedRef = useRef<string | null>(null)\n\n // Function to sync channels (extracted for reuse)\n const syncChannels = useCallback(async () => {\n if (!client || !isConnected) return\n\n const userId = client.userID\n if (!userId) return\n\n try {\n if (debug) {\n console.log('[MessagingShell] Syncing channels for user:', userId)\n }\n\n const channels = await client.queryChannels(\n {\n type: 'messaging',\n members: { $in: [userId] },\n },\n {},\n { limit: 100 }\n )\n\n const memberIds = new Set<string>()\n channels.forEach((channel: Channel) => {\n const members = channel.state.members\n Object.values(members).forEach((member) => {\n const memberId = member.user?.id\n if (memberId && memberId !== userId) {\n memberIds.add(memberId)\n }\n })\n })\n\n // Only update if the set contents have changed to prevent re-renders\n setExistingParticipantIds((prev) => {\n if (\n prev.size === memberIds.size &&\n [...prev].every((id) => memberIds.has(id))\n ) {\n return prev\n }\n return memberIds\n })\n setHasChannels(channels.length > 0)\n setChannelsLoaded(true)\n syncedRef.current = userId // Mark as synced for this user\n\n if (debug) {\n console.log('[MessagingShell] Channels synced successfully:', {\n channelCount: channels.length,\n memberCount: memberIds.size,\n })\n }\n } catch (error) {\n console.error('[MessagingShell] Failed to sync channels:', error)\n // Don't mark as synced on error, allow retry\n }\n }, [client, isConnected, debug])\n\n // Sync existing channels to track which participants we can already message\n useEffect(() => {\n if (!client || !isConnected) return\n\n const userId = client.userID\n if (!userId) return\n\n // Prevent repeated sync for the same user\n if (syncedRef.current === userId) return\n\n syncChannels()\n }, [client, isConnected, syncChannels])\n\n // Load initial channel for direct conversation mode\n useEffect(() => {\n if (!initialParticipantFilter || !client || !isConnected) return\n\n const loadInitialChannel = async () => {\n const userId = client.userID\n if (!userId) return\n\n try {\n if (debug) {\n console.log(\n '[MessagingShell] Loading initial conversation with:',\n initialParticipantFilter\n )\n }\n\n const channels = await client.queryChannels(\n {\n type: 'messaging',\n members: { $eq: [userId, initialParticipantFilter] },\n },\n {},\n { limit: 1 }\n )\n\n if (channels.length > 0) {\n setSelectedChannel(channels[0])\n setDirectConversationMode(true)\n setDirectConversationError(null)\n\n // Notify parent component of channel selection\n if (onChannelSelect) {\n onChannelSelect(channels[0])\n }\n\n if (debug) {\n console.log(\n '[MessagingShell] Initial conversation loaded:',\n channels[0].id\n )\n }\n } else {\n // No channel found - try to create one if participant data is provided\n if (initialParticipantData && service) {\n if (debug) {\n console.log(\n '[MessagingShell] No conversation found, creating one for:',\n initialParticipantData\n )\n }\n\n try {\n // Use the existing service method to create the channel\n const channel = await service.startChannelWithParticipant({\n id: initialParticipantData.id,\n name: initialParticipantData.name,\n email: initialParticipantData.email,\n phone: initialParticipantData.phone,\n })\n\n setSelectedChannel(channel)\n setDirectConversationMode(true)\n setDirectConversationError(null)\n\n // Notify parent component of channel selection\n if (onChannelSelect) {\n onChannelSelect(channel)\n }\n\n if (debug) {\n console.log(\n '[MessagingShell] Channel created and loaded:',\n channel.id\n )\n }\n } catch (createErr) {\n console.error(\n '[MessagingShell] Failed to create conversation:',\n createErr\n )\n setDirectConversationError('Failed to create conversation')\n }\n } else {\n // No participant data provided, show error\n setDirectConversationError(\n 'No conversation found with this account'\n )\n\n if (debug) {\n console.log(\n '[MessagingShell] No conversation found for:',\n initialParticipantFilter\n )\n }\n }\n }\n } catch (err) {\n console.error(\n '[MessagingShell] Failed to load initial conversation:',\n err\n )\n setDirectConversationError('Failed to load conversation')\n }\n }\n\n loadInitialChannel()\n }, [\n initialParticipantFilter,\n initialParticipantData,\n client,\n isConnected,\n service,\n debug,\n onChannelSelect,\n ])\n\n const handleChannelSelect = useCallback(\n (channel: Channel) => {\n setSelectedChannel(channel)\n onChannelSelect?.(channel)\n },\n [onChannelSelect]\n )\n\n const handleBackToChannelList = useCallback(() => {\n // In direct conversation mode, don't allow going back to channel list\n // The parent component should handle navigation\n if (directConversationMode) return\n\n setSelectedChannel(null)\n }, [directConversationMode])\n\n const handleSelectParticipant = useCallback(\n async (participant: Participant) => {\n if (!service) return\n\n try {\n if (debug) {\n console.log(\n '[MessagingShell] Starting conversation with:',\n participant.id\n )\n }\n\n const channel = await service.startChannelWithParticipant({\n id: participant.id,\n name: participant.name,\n email: participant.email,\n phone: participant.phone,\n })\n\n // Show the channel\n try {\n await channel.show()\n } catch (error) {\n console.warn('[MessagingShell] Failed to unhide channel:', error)\n }\n\n setSelectedChannel(channel)\n setShowParticipantPicker(false)\n participantPickerRef.current?.close()\n\n onParticipantSelect?.(participant)\n } catch (error) {\n console.error('[MessagingShell] Failed to start conversation:', error)\n }\n },\n [service, onParticipantSelect, debug]\n )\n\n const handleCloseParticipantPicker = useCallback(() => {\n setShowParticipantPicker(false)\n participantPickerRef.current?.close()\n }, [])\n\n const handleDialogBackdropClick = useCallback(\n (e: React.MouseEvent<HTMLDialogElement>) => {\n if (e.target === participantPickerRef.current) {\n handleCloseParticipantPicker()\n }\n },\n [handleCloseParticipantPicker]\n )\n\n const handleLeaveConversation = useCallback(\n async (channel: Channel) => {\n if (debug) {\n console.log('[MessagingShell] Leaving conversation:', channel.id)\n }\n setSelectedChannel(null)\n setDirectConversationMode(false) // Exit direct conversation mode\n\n // Force re-sync to update the existing participants list\n syncedRef.current = null\n await syncChannels()\n },\n [syncChannels, debug]\n )\n\n const handleBlockParticipant = useCallback(\n async (participantId?: string) => {\n if (debug) {\n console.log('[MessagingShell] Blocking participant:', participantId)\n }\n setSelectedChannel(null)\n setDirectConversationMode(false) // Exit direct conversation mode\n\n // Force re-sync to update the existing participants list\n syncedRef.current = null\n await syncChannels()\n },\n [syncChannels, debug]\n )\n\n const isChannelSelected = Boolean(selectedChannel)\n\n // Show loading state\n if (isLoading) {\n return (\n <div className={classNames('h-full', className)}>\n <LoadingState />\n </div>\n )\n }\n\n // Show error state\n if (error) {\n return (\n <div className={classNames('h-full', className)}>\n <ErrorState message={error} onBack={refreshConnection} />\n </div>\n )\n }\n\n // Show not connected state\n if (!isConnected || !client) {\n return (\n <div className={classNames('h-full', className)}>\n <ErrorState\n message=\"Not connected to messaging service\"\n onBack={refreshConnection}\n />\n </div>\n )\n }\n\n // Show direct conversation error state\n if (directConversationError) {\n return (\n <div className={classNames('h-full', className)}>\n <ErrorState message={directConversationError} />\n </div>\n )\n }\n\n return (\n <div\n className={classNames(\n 'messaging-shell h-full bg-background-primary overflow-hidden',\n className\n )}\n >\n <div className=\"flex h-full min-h-0\">\n {/* Channel List Sidebar */}\n <div\n className={classNames(\n 'messaging-channel-list-sidebar min-h-0 min-w-0 lg:flex lg:flex-col',\n {\n '!hidden': showChannelList === false || directConversationMode,\n // Hide on mobile when channel selected, show on desktop with consistent wide width\n 'hidden lg:flex lg:flex-1 lg:max-w-2xl':\n showChannelList !== false &&\n !directConversationMode &&\n isChannelSelected,\n // Show on mobile when no channel selected, use same wide width on desktop\n 'flex flex-col w-full lg:flex-1 lg:max-w-2xl':\n showChannelList !== false &&\n !directConversationMode &&\n !isChannelSelected,\n }\n )}\n >\n <ChannelList\n onChannelSelect={handleChannelSelect}\n selectedChannel={selectedChannel || undefined}\n filters={channelFilters}\n channelRenderFilterFn={channelRenderFilterFn}\n customEmptyStateIndicator={channelListCustomEmptyStateIndicator}\n renderMessagePreview={renderMessagePreview}\n />\n </div>\n\n {/* Channel View */}\n <div\n className={classNames(\n 'messaging-conversation-view flex-1 flex-col min-w-0 min-h-0',\n {\n // In direct conversation mode (or waiting for it), always show (full width)\n flex:\n directConversationMode ||\n isChannelSelected ||\n initialParticipantFilter,\n // Normal mode: hide on mobile when no channel selected\n 'hidden lg:flex':\n !directConversationMode &&\n !isChannelSelected &&\n !initialParticipantFilter,\n }\n )}\n >\n {selectedChannel ? (\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <ChannelView\n channel={selectedChannel}\n key={selectedChannel.id}\n onBack={handleBackToChannelList}\n showBackButton={!directConversationMode}\n renderMessageInputActions={renderMessageInputActions}\n renderConversationFooter={renderConversationFooter}\n renderChannelBanner={renderChannelBanner}\n onLeaveConversation={handleLeaveConversation}\n onBlockParticipant={handleBlockParticipant}\n CustomChannelEmptyState={CustomChannelEmptyState}\n showDeleteConversation={showDeleteConversation}\n onDeleteConversationClick={onDeleteConversationClick}\n onBlockParticipantClick={onBlockParticipantClick}\n onReportParticipantClick={onReportParticipantClick}\n dmAgentEnabled={dmAgentEnabled}\n messageMetadata={messageMetadata}\n onMessageSent={onMessageSent}\n showStarButton={showStarButton}\n chatbotVotingEnabled={chatbotVotingEnabled}\n customProfileContent={customProfileContent}\n customChannelActions={customChannelActions}\n renderMessage={renderMessage}\n sendButton={sendButton}\n />\n </div>\n ) : initialParticipantFilter ? (\n // Show loading while creating/loading direct conversation channel\n <LoadingState />\n ) : (\n <EmptyState\n hasChannels={hasChannels}\n channelsLoaded={channelsLoaded}\n />\n )}\n </div>\n </div>\n\n {/* Participant Picker Dialog */}\n {participantSource && (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n <dialog\n ref={participantPickerRef}\n className=\"mes-dialog\"\n onClick={handleDialogBackdropClick}\n onClose={handleCloseParticipantPicker}\n >\n <div className=\"h-full w-full bg-white shadow-max-elevation-light\">\n <ParticipantPicker\n key={pickerKey}\n participantSource={participantSource}\n onSelectParticipant={handleSelectParticipant}\n onClose={handleCloseParticipantPicker}\n existingParticipantIds={existingParticipantIds}\n participantLabel={participantLabel}\n searchPlaceholder={`Search ${participantLabel}...`}\n />\n </div>\n </dialog>\n )}\n </div>\n )\n}\n","import classNames from 'classnames'\nimport React from 'react'\nexport interface FaqListItemProps {\n question: string\n onClick: () => void\n loading?: boolean\n className?: string\n}\n\nexport const FaqListItem: React.FC<FaqListItemProps> = ({\n question,\n onClick,\n loading = false,\n className,\n}) => {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={loading}\n style={{ backgroundColor: '#E6E5E3' }}\n className={classNames(\n 'w-full text-center p-4 rounded-xl text-charcoal font-medium transition-colors focus-ring',\n {\n 'hover:brightness-95 active:brightness-90': !loading,\n 'opacity-50 cursor-not-allowed': loading,\n },\n className\n )}\n >\n {question}\n </button>\n )\n}\n","import React from 'react'\n\nimport { Avatar } from '../Avatar'\n\nimport { FaqListItem } from './FaqListItem'\n\nexport interface Faq {\n id: string\n question: string\n answer: string\n enabled: boolean\n order?: number | null\n}\n\nexport interface FaqListProps {\n faqs: Faq[]\n onFaqClick: (faqId: string) => void\n loadingFaqId?: string | null\n headerText?: string\n className?: string\n avatarImage?: string\n avatarName?: string\n}\n\nexport const FaqList: React.FC<FaqListProps> = ({\n faqs,\n onFaqClick,\n loadingFaqId,\n headerText,\n className,\n avatarImage,\n avatarName,\n}) => {\n const enabledFaqs = faqs\n .filter((faq) => faq.enabled)\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n\n if (enabledFaqs.length === 0) {\n return null\n }\n\n return (\n <div className={className}>\n <div className=\"flex gap-3 items-end\">\n {/* Avatar at bottom-left, outside grey background */}\n {(avatarImage || avatarName) && (\n <div className=\"flex-none\">\n <Avatar\n id={avatarName || 'account'}\n name={avatarName || 'Account'}\n image={avatarImage}\n size={24}\n shape=\"circle\"\n />\n </div>\n )}\n\n {/* FAQs with grey background */}\n <div\n className=\"flex-1 flex flex-col gap-3 rounded-lg p-4\"\n style={{ backgroundColor: '#F1F0EE' }}\n >\n {headerText && (\n <p className=\"text-md text-charcoal mb-4\">{headerText}</p>\n )}\n {enabledFaqs.map((faq) => (\n <FaqListItem\n key={faq.id}\n question={faq.question}\n onClick={() => onFaqClick(faq.id)}\n loading={loadingFaqId === faq.id}\n />\n ))}\n </div>\n </div>\n </div>\n )\n}\n","export type AttachmentSourceType = 'image' | 'audio' | 'video' | 'document'\n\nexport type DocumentIconType =\n | 'pdf'\n | 'doc'\n | 'xls'\n | 'csv'\n | 'ppt'\n | 'zip'\n | 'text'\n | 'markdown'\n | 'generic'\n\nconst DOCUMENT_ICON_PATTERNS: Array<[RegExp, DocumentIconType]> = [\n [/pdf/, 'pdf'],\n [/wordprocessingml|msword|\\.doc/, 'doc'],\n [/spreadsheetml|ms-excel|\\.xls/, 'xls'],\n [/csv/, 'csv'],\n [/presentationml|ms-powerpoint|\\.ppt/, 'ppt'],\n [/zip|x-rar|x-7z|x-tar|x-gzip/, 'zip'],\n [/plain|rtf/, 'text'],\n [/markdown/, 'markdown'],\n]\n\nexport function getSourceType(mimeType: string): AttachmentSourceType {\n if (mimeType.startsWith('video/')) return 'video'\n if (mimeType.startsWith('audio/')) return 'audio'\n if (mimeType.startsWith('image/')) return 'image'\n return 'document'\n}\n\nexport function getDocumentIconType(mimeType: string): DocumentIconType {\n const match = DOCUMENT_ICON_PATTERNS.find(([pattern]) =>\n pattern.test(mimeType)\n )\n return match ? match[1] : 'generic'\n}\n","import {\n FileIcon,\n FileCsvIcon,\n FileDocIcon,\n FileMdIcon,\n FilePdfIcon,\n FilePptIcon,\n FileTextIcon,\n FileXlsIcon,\n FileZipIcon,\n ImageIcon,\n SpeakerHighIcon,\n VideoCameraIcon,\n IconProps,\n} from '@phosphor-icons/react'\nimport React from 'react'\n\nimport { getDocumentIconType, getSourceType } from './mimeType'\nimport type { AttachmentSourceType } from './mimeType'\n\nexport const MEDIA_TYPE_ICON: Record<AttachmentSourceType, React.ElementType> =\n {\n video: VideoCameraIcon,\n audio: SpeakerHighIcon,\n image: ImageIcon,\n document: FileIcon,\n }\n\nconst DOCUMENT_ICON_COMPONENT = {\n pdf: FilePdfIcon,\n doc: FileDocIcon,\n xls: FileXlsIcon,\n csv: FileCsvIcon,\n ppt: FilePptIcon,\n zip: FileZipIcon,\n text: FileTextIcon,\n markdown: FileMdIcon,\n generic: FileIcon,\n} as const\n\nexport function getTypeIcon(mimeType: string): React.ElementType {\n const sourceType = getSourceType(mimeType)\n if (sourceType !== 'document') return MEDIA_TYPE_ICON[sourceType]\n return DOCUMENT_ICON_COMPONENT[getDocumentIconType(mimeType)]\n}\n\n/** Use instead of `<TypeIcon />` where TypeIcon = getTypeIcon(mime) to satisfy react-hooks/static-components. */\nexport function renderTypeIcon(\n mimeType: string,\n props: IconProps\n): React.ReactElement {\n return React.createElement(getTypeIcon(mimeType), props)\n}\n","import { CircleNotchIcon, PauseIcon, PlayIcon } from '@phosphor-icons/react'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { isDevBuild } from '../../utils/isDevBuild'\n\nimport { renderTypeIcon } from './utils/icons'\nimport { getSourceType } from './utils/mimeType'\n\ntype TouchEventUnion =\n | MouseEvent\n | TouchEvent\n | React.MouseEvent\n | React.TouchEvent\n\n\nconst getClientXFromEvent = (e: TouchEventUnion): number => {\n if ('touches' in e) {\n return e.touches[0]?.clientX ?? e.changedTouches[0]?.clientX ?? 0\n }\n return e.clientX\n}\n\nexport interface MediaPlayerProps {\n source: string\n mimeType: string\n poster?: string\n autoPlay?: boolean\n /** Controlled playing state. When provided, syncs to internal play/pause. */\n playing?: boolean\n loop?: boolean\n controls?: boolean\n showProgress?: boolean\n /** When true, requests muted playback (helps autoplay policies on video). */\n muted?: boolean\n /**\n * When provided, overrides the default click-to-play-toggle behaviour on the\n * player container. The play/pause button (which calls stopPropagation) is\n * unaffected, so inline playback still works.\n */\n onContainerClick?: (e: React.MouseEvent) => void\n}\n\nconst MediaPlayer: React.FC<MediaPlayerProps> = ({\n source,\n mimeType,\n poster,\n autoPlay = false,\n playing: playingProp,\n loop = false,\n controls = true,\n showProgress = false,\n muted = false,\n onContainerClick,\n}) => {\n // --- Derived ---\n const sourceType = getSourceType(mimeType)\n\n // --- Refs ---\n const playerRef = useRef<HTMLMediaElement>(null)\n const trackRef = useRef<HTMLDivElement>(null)\n const rafRef = useRef<number | null>(null)\n const prevPlayingPropRef = useRef(playingProp)\n\n // --- State: playback ---\n const [playing, setPlaying] = useState(autoPlay)\n const [played, setPlayed] = useState(0)\n const [seeking, setSeeking] = useState(false)\n\n // --- State: UI ---\n const [scrubberHovered, setScrubberHovered] = useState(false)\n /** Set when autoplay/play() was rejected so user can start via gesture (no controls UI). */\n const [manualPlayRequired, setManualPlayRequired] = useState(false)\n\n // --- State: loading ---\n const [buffering, setBuffering] = useState(false)\n /** True until the first canPlay fires for the current source — hides controls/spinner behind poster. */\n const [initialLoad, setInitialLoad] = useState(true)\n const [videoAspect, setVideoAspect] = useState<number | null>(null)\n\n // --- Callbacks ---\n const startPlaybackFromGesture = useCallback(() => {\n setManualPlayRequired(false)\n setPlaying(true)\n }, [])\n\n const getFraction = useCallback((e: TouchEventUnion) => {\n const track = trackRef.current\n if (!track) return 0\n const rect = track.getBoundingClientRect()\n return Math.max(\n 0,\n Math.min(1, (getClientXFromEvent(e) - rect.left) / rect.width)\n )\n }, [])\n\n const seekTo = useCallback((fraction: number) => {\n const el = playerRef.current\n if (el && el.duration) el.currentTime = fraction * el.duration\n }, [])\n\n const handleTrackPointerDown = (\n e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>\n ) => {\n e.stopPropagation()\n setSeeking(true)\n const fraction = getFraction(e)\n setPlayed(fraction)\n seekTo(fraction)\n }\n\n // --- Effects ---\n\n // Sync controlled playing prop to internal state\n useEffect(() => {\n if (\n playingProp !== undefined &&\n playingProp !== prevPlayingPropRef.current\n ) {\n prevPlayingPropRef.current = playingProp\n setPlaying(playingProp)\n }\n }, [playingProp])\n\n // RAF-driven progress updates\n useEffect(() => {\n if (!playing) {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n return\n }\n const tick = () => {\n const el = playerRef.current\n if (el && el.duration && !seeking) setPlayed(el.currentTime / el.duration)\n rafRef.current = requestAnimationFrame(tick)\n }\n rafRef.current = requestAnimationFrame(tick)\n return () => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)\n }\n }, [playing, seeking])\n\n // ReactPlayer v3 uses native HTML media elements and does not support a\n // declarative `playing` prop — playback must be driven imperatively.\n useEffect(() => {\n const el = playerRef.current\n if (!el) return\n if (playing) {\n void el.play().catch((err) => {\n setPlaying(false)\n setManualPlayRequired(true)\n if (isDevBuild()) {\n console.debug('[MediaPlayer] play() failed', err)\n }\n })\n } else {\n el.pause()\n }\n }, [playing])\n\n // Global seeking listeners\n useEffect(() => {\n if (!seeking) return\n const onMove = (e: MouseEvent | TouchEvent) => setPlayed(getFraction(e))\n const onUp = (e: MouseEvent | TouchEvent) => {\n setSeeking(false)\n seekTo(getFraction(e))\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n window.addEventListener('touchmove', onMove, { passive: true })\n window.addEventListener('touchend', onUp)\n return () => {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n window.removeEventListener('touchmove', onMove)\n window.removeEventListener('touchend', onUp)\n }\n }, [seeking, getFraction, seekTo])\n\n // --- Derived render values ---\n // Use natural aspect ratio once metadata loads, fall back to 16:9 before then.\n const aspectStyle = videoAspect\n ? { aspectRatio: String(videoAspect) }\n : undefined\n const aspectClass = !videoAspect ? ' aspect-video' : ''\n const scrubberPercent = Math.round(played * 100)\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={`relative cursor-pointer overflow-hidden bg-black ${aspectClass}`}\n style={aspectStyle}\n onClick={(e) => {\n if (onContainerClick) { onContainerClick(e); return }\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n if (onContainerClick) { onContainerClick(e as unknown as React.MouseEvent); return }\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n >\n {/* For audio, poster persists as a visual background. For video, hide once loaded. */}\n {poster && (sourceType === 'audio' || initialLoad) && (\n <img\n src={poster}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n )}\n {!poster && (sourceType === 'audio' || initialLoad) && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n <div className=\"absolute inset-0\">\n {sourceType === 'audio' ? (\n <audio\n ref={playerRef as React.RefObject<HTMLAudioElement>}\n src={source}\n loop={loop}\n muted={muted}\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </audio>\n ) : (\n <video\n ref={playerRef as React.RefObject<HTMLVideoElement>}\n src={source}\n loop={loop}\n muted={muted}\n playsInline\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onLoadedMetadata={() => {\n const el = playerRef.current\n if (\n el instanceof HTMLVideoElement &&\n el.videoWidth &&\n el.videoHeight\n ) {\n setVideoAspect(el.videoWidth / el.videoHeight)\n }\n }}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </video>\n )}\n </div>\n\n {buffering && !manualPlayRequired && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n <CircleNotchIcon\n className=\"size-8 animate-spin text-white/80\"\n weight=\"bold\"\n />\n </div>\n )}\n\n {manualPlayRequired && !controls && (\n <div\n className=\"absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Play preview\"\n onClick={(e) => {\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n >\n <span className=\"flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm\">\n <PlayIcon className=\"size-9 translate-x-0.5\" weight=\"fill\" />\n </span>\n </div>\n )}\n\n {showProgress && !controls && (\n <div className=\"absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent\">\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') seekTo(Math.min(1, played + 0.05))\n if (e.key === 'ArrowLeft') seekTo(Math.max(0, played - 0.05))\n }}\n >\n <div className=\"w-full overflow-hidden rounded-full bg-white/30 h-1\">\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n </div>\n )}\n\n {controls && (\n <div className=\"absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setPlaying((p) => !p)\n }}\n className=\"shrink-0 text-white\"\n aria-label={playing ? 'Pause' : 'Play'}\n >\n {playing ? (\n <PauseIcon className=\"size-5\" weight=\"fill\" />\n ) : (\n <PlayIcon className=\"size-5 translate-x-px\" weight=\"fill\" />\n )}\n </button>\n\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onMouseEnter={() => setScrubberHovered(true)}\n onMouseLeave={() => setScrubberHovered(false)}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') seekTo(Math.min(1, played + 0.05))\n if (e.key === 'ArrowLeft') seekTo(Math.max(0, played - 0.05))\n }}\n >\n <div\n className={`w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${scrubberHovered || seeking ? 'h-1.5' : 'h-1'}`}\n >\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n <div\n className={`absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${scrubberHovered || seeking ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}\n style={{ left: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default MediaPlayer\n","import React, { useState } from 'react'\n\nimport MediaPlayer, { type MediaPlayerProps } from './MediaPlayer'\nimport { renderTypeIcon } from './utils/icons'\nimport { getSourceType } from './utils/mimeType'\n\nexport type AttachmentThumbnailVariant = 'light' | 'dark'\n\nexport interface AttachmentThumbnailProps {\n mimeType: string\n sourceUrl?: string\n thumbnailUrl?: string\n title?: string\n variant: AttachmentThumbnailVariant\n /** Extra props passed to MediaPlayer when source is video or audio. */\n mediaPlayerProps?: Partial<\n Pick<\n MediaPlayerProps,\n 'autoPlay' | 'loop' | 'muted' | 'controls' | 'onContainerClick'\n >\n >\n /**\n * When true (Visitor unlocked image/document), use aspect-video + object-contain fade-in.\n */\n containedImage?: boolean\n}\n\nconst placeholderIconClass = (variant: AttachmentThumbnailVariant) =>\n variant === 'dark' ? 'size-12 text-white/20' : 'size-12 text-black/20'\n\nconst posterShellClass = (variant: AttachmentThumbnailVariant) =>\n variant === 'dark'\n ? 'aspect-video overflow-hidden bg-white/10'\n : 'aspect-video overflow-hidden bg-black/5'\n\n/**\n * Renders the media preview area for attachment cards (LockedAttachment, MediaMessage).\n * Overlays (dim, lock, eye toggle) are composed by the parent.\n */\nconst AttachmentThumbnail: React.FC<AttachmentThumbnailProps> = ({\n mimeType,\n sourceUrl,\n thumbnailUrl,\n title,\n variant,\n mediaPlayerProps,\n containedImage = false,\n}) => {\n const sourceType = getSourceType(mimeType)\n const [sourceReady, setSourceReady] = useState(false)\n\n if (sourceUrl && (sourceType === 'video' || sourceType === 'audio')) {\n return (\n <MediaPlayer\n source={sourceUrl}\n mimeType={mimeType}\n poster={thumbnailUrl}\n controls\n {...mediaPlayerProps}\n />\n )\n }\n\n if (sourceUrl && sourceType === 'image') {\n if (containedImage) {\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n <img\n src={sourceUrl}\n alt={title ?? ''}\n className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n draggable={false}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n }\n return (\n <img\n src={sourceUrl}\n alt={title ?? ''}\n className=\"block w-full\"\n draggable={false}\n />\n )\n }\n\n if (sourceUrl && sourceType === 'document') {\n if (thumbnailUrl) {\n if (containedImage) {\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n <img\n src={thumbnailUrl}\n alt={title ?? ''}\n className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n draggable={false}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n }\n return (\n <img\n src={thumbnailUrl}\n alt=\"\"\n className=\"block w-full\"\n draggable={false}\n />\n )\n }\n return (\n <div\n className={`flex aspect-video w-full items-center justify-center ${variant === 'dark' ? 'bg-white/10' : 'bg-black/5'}`}\n >\n {renderTypeIcon(mimeType, {\n className: placeholderIconClass(variant),\n weight: 'regular',\n })}\n </div>\n )\n }\n\n // Poster-only or empty (no sourceUrl)\n if (thumbnailUrl) {\n return (\n <div className={`relative ${posterShellClass(variant)}`}>\n <img\n src={thumbnailUrl}\n alt={title ?? ''}\n draggable={false}\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n </div>\n )\n }\n\n return (\n <div\n className={`flex aspect-video w-full items-center justify-center ${variant === 'dark' ? 'bg-white/10' : 'bg-black/5'}`}\n >\n {renderTypeIcon(mimeType, {\n className: placeholderIconClass(variant),\n weight: 'regular',\n })}\n </div>\n )\n}\n\nexport default AttachmentThumbnail\n","import classNames from 'classnames'\nimport React from 'react'\n\nimport { renderTypeIcon } from './utils/icons'\n\nexport { default as AttachmentThumbnail } from './Thumbnail'\nexport type {\n AttachmentThumbnailProps,\n AttachmentThumbnailVariant,\n} from './Thumbnail'\nexport { default as MediaPlayer } from './MediaPlayer'\nexport type { MediaPlayerProps } from './MediaPlayer'\nexport { renderTypeIcon, getTypeIcon, MEDIA_TYPE_ICON } from './utils/icons'\nexport {\n getSourceType,\n getDocumentIconType,\n type AttachmentSourceType,\n type DocumentIconType,\n} from './utils/mimeType'\n\nexport interface AttachmentCardProps {\n variant: 'light' | 'dark'\n thumbnail: React.ReactNode\n title?: string\n placeholderTitle?: string\n mimeType: string\n detail?: string\n statusBadge?: React.ReactNode\n action?: React.ReactNode\n topLeft?: React.ReactNode\n topRight?: React.ReactNode\n rootRef?: React.Ref<HTMLDivElement>\n 'data-testid'?: string\n}\n\nconst AttachmentCard: React.FC<AttachmentCardProps> = ({\n variant,\n thumbnail,\n title,\n placeholderTitle = 'Attachment title',\n mimeType,\n detail,\n statusBadge,\n action,\n topLeft,\n topRight,\n rootRef,\n 'data-testid': dataTestId,\n}) => {\n const isDark = variant === 'dark'\n const displayTitle = isDark ? (title ?? placeholderTitle) : (title ?? '')\n const titleDimmed = isDark && !title\n\n return (\n <div\n ref={rootRef}\n data-testid={dataTestId}\n className={classNames(\n 'relative w-[280px] select-none overflow-hidden rounded-[24px] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]',\n isDark ? 'bg-[#121110]' : 'bg-white'\n )}\n >\n {topLeft ? (\n <div className=\"pointer-events-auto absolute left-3 top-3 z-50\">{topLeft}</div>\n ) : null}\n {topRight ? (\n <div className=\"pointer-events-auto absolute right-3 top-3 z-50\">{topRight}</div>\n ) : null}\n\n {thumbnail}\n\n <div className=\"px-4 pb-3 pt-3\">\n <p\n className={classNames('mb-0.5 truncate text-base font-medium', {\n 'text-black': !isDark,\n 'text-white/30': isDark && titleDimmed,\n 'text-white': isDark && !titleDimmed,\n })}\n >\n {displayTitle}\n </p>\n\n <div className=\"flex flex-wrap items-center gap-1\">\n {renderTypeIcon(mimeType, {\n className: classNames(\n 'size-5 shrink-0',\n isDark ? 'text-white/55' : 'text-black/55'\n ),\n weight: 'regular',\n })}\n\n {detail != null && detail !== '' && (\n <span\n className={classNames(\n 'text-xs font-medium',\n isDark ? 'text-white/55' : 'text-black/55'\n )}\n >\n {detail}\n </span>\n )}\n\n {statusBadge}\n </div>\n\n {action}\n </div>\n </div>\n )\n}\n\nexport default AttachmentCard\n","import { CircleNotchIcon, DownloadSimpleIcon, LinkIcon } from '@phosphor-icons/react'\nimport React, { useState } from 'react'\nimport type { Attachment, LocalMessage } from 'stream-chat'\n\nimport AttachmentCard, {\n AttachmentThumbnail,\n getSourceType,\n} from '../AttachmentCard'\nimport { Avatar } from '../Avatar'\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction linkCardShellClass(isMyMessage: boolean) {\n const bg = isMyMessage ? 'bg-[#121110]' : 'bg-[#F3F3F1]'\n return `w-[280px] select-none overflow-hidden rounded-[24px] ${bg} shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]`\n}\n\nfunction linkThumbnailBg(isMyMessage: boolean) {\n return isMyMessage ? 'bg-white/10' : 'bg-black/5'\n}\n\nfunction linkPrimaryText(isMyMessage: boolean) {\n return isMyMessage ? 'text-white' : 'text-black'\n}\n\nfunction linkSecondaryText(isMyMessage: boolean) {\n return isMyMessage ? 'text-white/55' : 'text-black/55'\n}\n\nfunction linkTertiaryText(isMyMessage: boolean) {\n return isMyMessage ? 'text-white/40' : 'text-black/40'\n}\n\nfunction linkIconColor(isMyMessage: boolean) {\n return isMyMessage ? 'text-white/20' : 'text-black/20'\n}\n\n/** Link preview (OG) — no download; opens in a new tab. */\nconst LinkCard: React.FC<{\n attachment: Attachment\n isMyMessage: boolean\n}> = ({ attachment, isMyMessage }) => {\n const { title, text, image_url, og_scrape_url, title_link } = attachment\n const url = og_scrape_url ?? title_link\n\n return (\n <a href={url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"block no-underline\">\n <div className=\"p-2\">\n {image_url ? (\n <img\n src={image_url}\n alt={title ?? ''}\n className=\"aspect-video w-full rounded-[20px] object-cover\"\n />\n ) : (\n <div\n className={`aspect-video w-full rounded-[20px] ${linkThumbnailBg(isMyMessage)} flex items-center justify-center`}\n >\n <LinkIcon className={`size-12 ${linkIconColor(isMyMessage)}`} />\n </div>\n )}\n </div>\n <div className=\"px-3 pb-3\">\n {title && (\n <p className={`truncate text-[14px] font-medium leading-5 ${linkPrimaryText(isMyMessage)}`}>\n {title}\n </p>\n )}\n {text && (\n <p className={`truncate text-[12px] leading-4 ${linkSecondaryText(isMyMessage)}`}>{text}</p>\n )}\n {url && (\n <p className={`mt-1 truncate text-[12px] leading-4 ${linkTertiaryText(isMyMessage)}`}>\n {url}\n </p>\n )}\n </div>\n </a>\n )\n}\n\nexport function resolveLinkAttachment(\n message: LocalMessage\n): Attachment | undefined {\n return message.attachments?.find(\n (a) => a.type === 'link' || (a.og_scrape_url != null && !a.asset_url)\n )\n}\n\nasync function triggerDownload(url: string, filename?: string): Promise<void> {\n let name: string\n try { name = filename ?? new URL(url).pathname.split('/').pop() ?? 'download' }\n catch { name = filename ?? 'download' }\n const res = await fetch(url, { mode: 'cors' })\n if (!res.ok) throw new Error(`HTTP ${res.status}`)\n const blob = await res.blob()\n const objectUrl = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = objectUrl\n a.download = name\n a.style.display = 'none'\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(objectUrl)\n}\n\nconst DownloadAction: React.FC<{ url: string; filename?: string }> = ({\n url,\n filename,\n}) => {\n const [busy, setBusy] = useState(false)\n\n const handleClick = (e: React.MouseEvent) => {\n e.stopPropagation()\n const fallback = window.open('', '_blank', 'noopener,noreferrer')\n setBusy(true)\n triggerDownload(url, filename)\n .then(() => { fallback?.close() })\n .catch(() => { if (fallback) fallback.location.href = url })\n .finally(() => setBusy(false))\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={busy}\n className=\"mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928] disabled:opacity-70\"\n >\n {busy ? (\n <CircleNotchIcon className=\"size-4 animate-spin text-white\" weight=\"bold\" />\n ) : (\n <React.Fragment>\n <DownloadSimpleIcon className=\"size-4 text-white\" weight=\"bold\" />\n Download\n </React.Fragment>\n )}\n </button>\n )\n}\n\nexport interface MediaMessageResolved {\n resolvedUrl: string\n resolvedType: string\n title?: string\n fileSize?: number\n thumbnailUrl?: string\n}\n\nexport function resolveMediaFromMessage(\n message: LocalMessage\n): MediaMessageResolved | null {\n const videoAttachment = message.attachments?.find(\n (a) => a.type === 'video' && a.asset_url\n )\n const imageAttachment = message.attachments?.find(\n (a) => a.type === 'image' && (a as { image_url?: string }).image_url\n )\n const audioAttachment = message.attachments?.find(\n (a) => a.type === 'audio' && a.asset_url\n )\n const fileAttachment = message.attachments?.find(\n (a) => a.type === 'file' && a.asset_url\n )\n\n const activeAttachment =\n videoAttachment ?? imageAttachment ?? audioAttachment ?? fileAttachment\n\n const resolvedUrl =\n videoAttachment?.asset_url ??\n (imageAttachment as { image_url?: string } | undefined)?.image_url ??\n audioAttachment?.asset_url ??\n fileAttachment?.asset_url\n\n if (!resolvedUrl) return null\n\n const resolvedType =\n activeAttachment?.mime_type ??\n (activeAttachment?.type === 'image'\n ? 'image/jpeg'\n : activeAttachment?.type === 'video'\n ? 'video/mp4'\n : activeAttachment?.type === 'audio'\n ? 'audio/mpeg'\n : 'application/octet-stream')\n\n const title = (activeAttachment as { title?: string } | undefined)?.title\n const fileSize = (activeAttachment as { file_size?: number } | undefined)?.file_size\n const thumbnailUrl = (videoAttachment as { thumb_url?: string } | undefined)?.thumb_url\n\n return {\n resolvedUrl,\n resolvedType,\n title,\n fileSize,\n thumbnailUrl,\n }\n}\n\n/** Dark card (sent / own message) — matches LockedAttachment.Creator preview without toggle. */\nconst Creator: React.FC<MediaMessageResolved> = ({\n resolvedUrl,\n resolvedType,\n title,\n fileSize,\n thumbnailUrl,\n}) => {\n const detail = fileSize !== undefined ? formatBytes(fileSize) : undefined\n\n return (\n <AttachmentCard\n variant=\"dark\"\n title={title}\n mimeType={resolvedType}\n detail={detail}\n thumbnail={\n <AttachmentThumbnail\n mimeType={resolvedType}\n sourceUrl={resolvedUrl}\n thumbnailUrl={thumbnailUrl}\n title={title}\n variant=\"dark\"\n />\n }\n />\n )\n}\n\n/** Light card (received) — matches LockedAttachment.Visitor unlocked without Purchased copy. */\nconst Visitor: React.FC<MediaMessageResolved> = ({\n resolvedUrl,\n resolvedType,\n title,\n fileSize,\n thumbnailUrl,\n}) => {\n const sourceType = getSourceType(resolvedType)\n const detail = fileSize !== undefined ? formatBytes(fileSize) : undefined\n\n return (\n <AttachmentCard\n variant=\"light\"\n title={title}\n mimeType={resolvedType}\n detail={detail}\n thumbnail={\n <AttachmentThumbnail\n mimeType={resolvedType}\n sourceUrl={resolvedUrl}\n thumbnailUrl={thumbnailUrl}\n title={title}\n variant=\"light\"\n containedImage={sourceType === 'image' || sourceType === 'document'}\n />\n }\n action={<DownloadAction url={resolvedUrl} filename={title} />}\n />\n )\n}\n\nexport interface MediaMessageProps {\n message: LocalMessage\n isMyMessage?: boolean\n}\n\nconst MediaMessageRoot: React.FC<MediaMessageProps> = ({\n message,\n isMyMessage = false,\n}) => {\n const linkAttachment = resolveLinkAttachment(message)\n const resolved = resolveMediaFromMessage(message)\n if (!linkAttachment && !resolved) return null\n\n const messageClass = isMyMessage\n ? 'str-chat__message str-chat__message-simple str-chat__message--me str-chat__message-simple--me'\n : 'str-chat__message str-chat__message-simple str-chat__message--other'\n\n return (\n <div className={messageClass}>\n {!isMyMessage && message.user && (\n <Avatar\n className=\"str-chat__avatar str-chat__message-sender-avatar\"\n id={message.user.id}\n image={message.user.image}\n name={message.user.name ?? message.user.id}\n />\n )}\n <div\n className=\"str-chat__message-inner\"\n style={{ marginInlineEnd: 0, marginInlineStart: 0 }}\n >\n <div className=\"str-chat__message-bubble-wrapper\">\n <div\n className=\"str-chat__message-bubble\"\n style={{ padding: 0, borderRadius: 0, overflow: 'visible', background: 'transparent' }}\n >\n {linkAttachment ? (\n <div className={linkCardShellClass(isMyMessage)}>\n <LinkCard attachment={linkAttachment} isMyMessage={isMyMessage} />\n </div>\n ) : isMyMessage ? (\n <Creator {...resolved!} />\n ) : (\n <Visitor {...resolved!} />\n )}\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nconst MediaMessageCreatorEntry: React.FC<{ message: LocalMessage }> = ({\n message,\n}) => {\n const linkAttachment = resolveLinkAttachment(message)\n if (linkAttachment) {\n return (\n <div className={linkCardShellClass(true)}>\n <LinkCard attachment={linkAttachment} isMyMessage={true} />\n </div>\n )\n }\n const resolved = resolveMediaFromMessage(message)\n if (!resolved) return null\n return <Creator {...resolved} />\n}\n\nconst MediaMessageVisitorEntry: React.FC<{ message: LocalMessage }> = ({\n message,\n}) => {\n const linkAttachment = resolveLinkAttachment(message)\n if (linkAttachment) {\n return (\n <div className={linkCardShellClass(false)}>\n <LinkCard attachment={linkAttachment} isMyMessage={false} />\n </div>\n )\n }\n const resolved = resolveMediaFromMessage(message)\n if (!resolved) return null\n return <Visitor {...resolved} />\n}\n\nexport const MediaMessage = Object.assign(MediaMessageRoot, {\n Creator: MediaMessageCreatorEntry,\n Visitor: MediaMessageVisitorEntry,\n})\n","import { useState, useEffect, useCallback } from 'react';\n\nimport type { ParticipantSource, Participant } from '../types';\n\n/**\n * Hook for managing participant loading with search and pagination\n */\nexport const useParticipants = (\n participantSource: ParticipantSource,\n options: {\n initialSearch?: string;\n pageSize?: number;\n } = {}\n) => {\n const { initialSearch = '', pageSize = 20 } = options;\n \n const [participants, setParticipants] = useState<Participant[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [searchQuery, setSearchQuery] = useState(initialSearch);\n const [hasMore, setHasMore] = useState(true);\n const [cursor, setCursor] = useState<string | undefined>();\n\n // Load participants with current search query\n const loadParticipants = useCallback(async (\n reset = false,\n customSearch?: string\n ) => {\n if (loading) return;\n \n const search = customSearch !== undefined ? customSearch : searchQuery;\n \n setLoading(true);\n setError(null);\n\n try {\n const result = await participantSource.loadParticipants({\n search: search || undefined,\n limit: pageSize,\n cursor: reset ? undefined : cursor,\n });\n\n setParticipants(prev => \n reset ? result.participants : [...prev, ...result.participants]\n );\n setHasMore(result.hasMore);\n setCursor(result.nextCursor);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to load participants';\n setError(errorMessage);\n console.error('[useParticipants] Load error:', err);\n } finally {\n setLoading(false);\n }\n }, [participantSource, searchQuery, cursor, pageSize, loading]);\n\n // Load more participants (pagination)\n const loadMore = useCallback(() => {\n if (hasMore && !loading) {\n loadParticipants(false);\n }\n }, [hasMore, loading, loadParticipants]);\n\n // Search participants\n const search = useCallback((query: string) => {\n setSearchQuery(query);\n setCursor(undefined);\n loadParticipants(true, query);\n }, [loadParticipants]);\n\n // Refresh participants\n const refresh = useCallback(() => {\n setCursor(undefined);\n loadParticipants(true);\n }, [loadParticipants]);\n\n /* eslint-disable react-hooks/exhaustive-deps -- initial load only; `loadParticipants` changes whenever `loading` flips */\n useEffect(() => {\n loadParticipants(true);\n }, [participantSource.loadParticipants]);\n /* eslint-enable react-hooks/exhaustive-deps */\n\n return {\n participants,\n loading,\n error,\n searchQuery,\n hasMore,\n totalCount: participantSource.totalCount,\n loadMore,\n search,\n refresh,\n };\n};\n"],"names":["MessagingContext","createContext","useMessagingContext","useContext","MessagingProvider","children","user","serviceConfig","apiKey","capabilities","debug","debugLog","useCallback","message","args","service","setService","useState","client","setClient","isConnected","setIsConnected","isLoading","setIsLoading","error","setError","connectingRef","useRef","prevPropsRef","renderCountRef","useEffect","currentRender","newService","StreamChatService","connectedUserRef","_a","_b","streamClient","err","errorMessage","refreshConnection","contextValue","React","jsx","Chat","useMessaging","restorePendingMessages","channel","pendingMessages","pending","ChannelListContext","ChannelListProvider","useChannelListContext","useChannelStar","isChannelStarred","setIsChannelStarred","handleMemberUpdate","event","getDaysDifference","date1","date2","d1","diffTime","formatRelativeTime","date","now","daysDiff","EMOJIS","hashString","str","hash","i","char","getAvatarEmoji","id","index","Avatar","image","size","className","starred","shape","dmAgentEnabled","emoji","fontSizeClass","aiBorderWidth","borderStyle","avatarInner","classNames","jsxs","StarIcon","SparkleIcon","isTipMessage","isPaidMessage","isChatbotMessage","isAttachmentMessage","isTipOrPaidMessage","isTipOnlyMessage","MessageTag","standalone","isMyMessage","hasAttachment","isTipOrPaid","isChatbot","amountText","label","GiftIcon","isSenderAttachmentVariant","chatbotLabel","chatbotClassName","icon","Fragment","CustomChannelPreview","unread","selectedChannel","onChannelSelect","renderMessagePreview","isSelected","handleClick","handleKeyDown","isActivationKey","isRepeatedKeydown","participant","member","participantName","participantImage","_c","lastMessage","messages","lastMessageText","attachment","lastMessageTime","isLastMessageFromChatbot","messagePreview","unreadCount","_d","DEFAULT_SORT","ChannelList","filters","allowNewMessagesFromUnfilteredChannels","onMessageNew","onAddedToChannel","channelRenderFilterFn","sort","customEmptyStateIndicator","wrappedChannelRenderFilterFn","channels","StreamChannelList","ActionButton","variant","rest","IconButton","CloseButton","onClick","XIcon","ChannelInfoDialog","dialogRef","onClose","followerStatusLabel","onLeaveConversation","onBlockParticipant","showDeleteConversation","onDeleteConversationClick","onBlockParticipantClick","onReportParticipantClick","customProfileContent","customChannelActions","isParticipantBlocked","setIsParticipantBlocked","isLeaving","setIsLeaving","isUpdatingBlockStatus","setIsUpdatingBlockStatus","checkIsParticipantBlocked","isBlocked","handleLeaveConversation","actingUserId","handleBlockUser","handleUnblockUser","handleReportUser","participantEmail","_e","participantUsername","_f","participantSecondary","participantId","_g","e","SpinnerGapIcon","SignOutIcon","ProhibitInsetIcon","FlagIcon","CustomDateSeparator","props","DateSeparator","VOTE_UP","VOTE_DOWN","getVoteFromReactions","ownReactions","r","useMessageVote","useChannelStateContext","useChatContext","selected","useMemo","voteUp","voteDown","CreatorCardLazy","VisitorCardLazy","LockedAttachmentFallback","Creator","Suspense","Visitor","LockedAttachment","defaultLockedAttachmentContextValue","customMessageDefaults","CustomMessageContext","CustomMessageProvider","useCustomMessage","key","ThumbUpIcon","filled","ThumbDownIcon","MessageVoteButtons","onVoteUp","onVoteDown","CustomMessageWithContext","additionalMessageInputProps","chatbotVotingEnabled","editing","endOfGroup","firstOfGroup","groupedByUser","handleAction","handleOpenThread","handleRetry","highlighted","isMessageAIGenerated","renderText","threadList","isUnlocking","onUnlockClick","onFetchSource","onDownloadClick","isBounceDialogOpen","setIsBounceDialogOpen","reminder","useMessageReminder","voteState","Attachment","DefaultAttachment","EditMessageModal","DefaultEditMessageModal","MessageBlocked","DefaultMessageBlocked","MessageBouncePrompt","DefaultMessageBouncePrompt","MessageDeleted","DefaultMessageDeleted","MessageIsThreadReplyInChannelButtonIndicator","DefaultMessageIsThreadReplyInChannelButtonIndicator","MessageRepliesCountButton","DefaultMessageRepliesCountButton","ReminderNotification","DefaultReminderNotification","StreamedMessageText","DefaultStreamedMessageText","PinIndicator","useComponentContext","messageHasAttachments","hasReactions","messageHasReactions","isAIGenerated","finalAttachments","isDateSeparatorMessage","isMessageBlocked","showReplyCountButton","showIsReplyInChannel","allowRetry","isBounced","isMessageBounced","isMine","rootClassName","poll","isTipOnly","isAttachment","hasRenderableAttachments","useAttachmentFooterChatbotTag","MessageBounceModal","_h","_i","_j","_k","_l","_m","_n","MessageText","Poll","MessageErrorIcon","MemoizedCustomMessage","prev","next","areMessageUIPropsEqual","CustomMessage","messageContext","useMessageContext","linkPreviewsManagerStateSelector","state","preview","LinkPreviewsManager","CustomLinkPreviewCard","link","onDismiss","og_scrape_url","title","image_url","CustomLinkPreviewList","linkPreviewsManager","useMessageComposer","stateLinkPreviews","useStateStore","handleDismiss","url","linkPreview","DefaultSendButton","sendMessage","disabled","ArrowUpIcon","CustomMessageInputInner","isFrozen","handleSubmit","useMessageInputContext","SendButtonFromContext","SendButton","hasSendableData","useMessageComposerHasSendableData","SimpleAttachmentSelector","QuotedMessagePreview","AttachmentPreviewList","TextareaComposer","CustomMessageInput","renderActions","MessageInput","DM_AGENT_SYSTEM_TYPES","DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT","AGE_SAFETY_SYSTEM_TYPES","AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT","AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS","AGE_SAFETY_SYSTEM_MESSAGE_URL","isDmAgentSystemType","value","isAgeSafetySystemType","getCustomSystemMessageVariant","metadataCustomType","fallbackType","renderAgeSafetyMessageText","messageText","emphasisIndex","emphasisEndIndex","CustomSystemMessage","isDateHidden","customSystemMessageVariant","MessageTimestamp","ProhibitIcon","Circle","cx","CustomTypingIndicator","channelConfig","thread","typing","useTypingContext","typingInChannel","parent_id","typingInThread","typingUsers","typingUser","memberUser","avatarId","avatarName","avatarImage","ChannelEmptyState","Loading","LoadingState","ICON_BTN_CLASS","DM_AGENT_HEADER_HELPER_TEXT","CustomChannelHeader","onBack","showBackButton","onShowInfo","canShowInfo","showStarButton","isStarred","handleStarClick","ArrowLeftIcon","CaretRightIcon","DotsThreeIcon","ChannelViewInner","renderMessageInputActions","renderConversationFooter","renderChannelBanner","renderMessage","infoDialogRef","currentMember","currentUserIsAccount","participantIsAccount","showDmAgentHeader","channelExtraData","handleShowInfo","handleCloseInfo","MessageOverride","messageNode","WithComponents","Window","MessageList","ChannelView","CustomChannelEmptyState","messageMetadata","onMessageSent","sendButton","doSendMessageRequest","_channel","options","agentPaused","shouldSuppressNotifications","finalMessage","finalOptions","response","Channel","SearchInput","searchQuery","setSearchQuery","placeholder","searchInputRef","MagnifyingGlassIcon","ParticipantPicker","participantSource","onSelectParticipant","existingParticipantIds","participantLabel","searchPlaceholder","participants","setParticipants","loading","setLoading","startingChatWithId","setStartingChatWithId","loadedRef","result","availableParticipants","searchLower","handleSelectParticipant","ChatCircleDotsIcon","displayName","displaySecondary","ChatBubblesIllustration","EmptyState","hasChannels","channelsLoaded","ErrorState","MessagingShell","onParticipantSelect","initialParticipantFilter","initialParticipantData","showChannelList","channelListCustomEmptyStateIndicator","setSelectedChannel","setHasChannels","setChannelsLoaded","_showParticipantPicker","setShowParticipantPicker","setExistingParticipantIds","pickerKey","_setPickerKey","directConversationMode","setDirectConversationMode","directConversationError","setDirectConversationError","participantPickerRef","channelFilters","userId","syncedRef","syncChannels","memberIds","members","memberId","createErr","handleChannelSelect","handleBackToChannelList","handleCloseParticipantPicker","handleDialogBackdropClick","handleBlockParticipant","isChannelSelected","FaqListItem","question","FaqList","faqs","onFaqClick","loadingFaqId","headerText","enabledFaqs","faq","a","b","DOCUMENT_ICON_PATTERNS","getSourceType","mimeType","getDocumentIconType","match","pattern","MEDIA_TYPE_ICON","VideoCameraIcon","SpeakerHighIcon","ImageIcon","FileIcon","DOCUMENT_ICON_COMPONENT","FilePdfIcon","FileDocIcon","FileXlsIcon","FileCsvIcon","FilePptIcon","FileZipIcon","FileTextIcon","FileMdIcon","getTypeIcon","sourceType","renderTypeIcon","getClientXFromEvent","MediaPlayer","source","poster","autoPlay","playingProp","loop","controls","showProgress","muted","onContainerClick","playerRef","trackRef","rafRef","prevPlayingPropRef","playing","setPlaying","played","setPlayed","seeking","setSeeking","scrubberHovered","setScrubberHovered","manualPlayRequired","setManualPlayRequired","buffering","setBuffering","initialLoad","setInitialLoad","videoAspect","setVideoAspect","startPlaybackFromGesture","getFraction","track","rect","seekTo","fraction","el","handleTrackPointerDown","tick","onMove","onUp","aspectStyle","aspectClass","scrubberPercent","p","CircleNotchIcon","PlayIcon","PauseIcon","placeholderIconClass","posterShellClass","AttachmentThumbnail","sourceUrl","thumbnailUrl","mediaPlayerProps","containedImage","sourceReady","setSourceReady","AttachmentCard","thumbnail","placeholderTitle","detail","statusBadge","action","topLeft","topRight","rootRef","dataTestId","isDark","displayTitle","titleDimmed","formatBytes","bytes","linkCardShellClass","linkThumbnailBg","linkPrimaryText","linkSecondaryText","linkTertiaryText","linkIconColor","LinkCard","text","title_link","LinkIcon","resolveLinkAttachment","triggerDownload","filename","name","res","blob","objectUrl","DownloadAction","busy","setBusy","fallback","DownloadSimpleIcon","resolveMediaFromMessage","videoAttachment","imageAttachment","audioAttachment","fileAttachment","activeAttachment","resolvedUrl","resolvedType","fileSize","MediaMessageRoot","linkAttachment","resolved","MediaMessageCreatorEntry","MediaMessageVisitorEntry","MediaMessage","useParticipants","initialSearch","pageSize","hasMore","setHasMore","cursor","setCursor","loadParticipants","reset","customSearch","search","loadMore","query","refresh"],"mappings":"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"}