{"version":3,"sources":["../src/components/chat/Chat.tsx","../src/components/inputs/chat-input.tsx","../src/components/edit-panel/index.tsx","../src/components/text/text.tsx","../src/providers/chatClientProvider.tsx","../src/providers/clientStateProvider.tsx","../src/theme/index.tsx","../src/components/menu/index.tsx","../src/components/emoji/index.tsx","../src/helpers/date.ts","../src/components/audio/audio-player.tsx","../src/components/assets/icons.tsx","../src/components/Loaders/index.tsx","../src/components/message-list/message-list.tsx","../src/components/avartar/avartar.tsx","../src/components/message-item/index.tsx","../src/components/options-panel/options-panel.tsx","../src/components/user-conversations/index.tsx","../src/components/user-conversations/ConversationHeader.tsx","../src/components/modals/index.tsx","../src/components/chat/ChatTopNav.tsx","../src/components/navigation/index.tsx","../src/components/broadcast-lists/index.tsx"],"sourcesContent":["import React, { useContext, useEffect, useRef, useState, useMemo } from \"react\";\r\nimport ChatClient, {\r\n  ChatEventGenerics,\r\n  Conversation,\r\n  Message,\r\n  UserMeta,\r\n  ConnectionEvent,\r\n  ConversationListMeta,\r\n} from \"softchatjs-core\";\r\nimport styles from \"./chat.module.css\";\r\nimport ChatInput from \"../inputs/chat-input\";\r\nimport MessageList from \"../message-list/message-list\";\r\nimport { ConversationList as MainList } from \"../user-conversations\";\r\nimport {\r\n  ConversationItem,\r\n  useChatState,\r\n} from \"../../providers/clientStateProvider\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { ImageViewer } from \"../modals\";\r\nimport { ChatTopNav } from \"./ChatTopNav\";\r\nimport { ChatIcon } from \"../assets/icons\";\r\nimport Navbar, { NavButton } from \"../navigation\";\r\nimport BroadcastLists from \"../broadcast-lists\";\r\n\r\ntype ChatProps = {\r\n  renderChatBubble?: (message: Message) => JSX.Element;\r\n  renderConversationList?: (props: {\r\n    conversations: ConversationItem[];\r\n    onCoversationItemClick: (conversationItem: ConversationItem) => void;\r\n  }) => JSX.Element;\r\n  renderChatHeader?: () => JSX.Element;\r\n  renderChatInput?: (props: { onChange: (e: string) => void }) => JSX.Element;\r\n  renderNavbar?: (props: NavButton[]) => JSX.Element;\r\n  onCreateBroadcastList?: () => void;\r\n  user: UserMeta;\r\n  userList?: UserMeta[];\r\n  /**\r\n   * use activeConversationId to preselect a conversation once the user enters the chat.\r\n   */\r\n  activeConversationId?: string;\r\n  /**@note\r\n   * This value calculates the the height off the container incase of an external header\r\n   * Value should be in px i.e 300\r\n   */\r\n  headerHeightOffset?: number;\r\n  /**\r\n   * FCM token used to send push notifications to web users\r\n   */\r\n  webToken?: string;\r\n  /**\r\n   * Hide the broadcast icon on the navigation bar\r\n   * NOTE: this doesn't disable the functionality itself\r\n   */\r\n  enableBroadcasts?: boolean;\r\n  /**\r\n   * Set a custom height for the chat container\r\n   */\r\n  height?: number;\r\n  /**\r\n   * Set a custom width for the chat container\r\n   */\r\n  width?: number;\r\n};\r\n\r\nconst Chat = (props: ChatProps) => {\r\n  const {\r\n    headerHeightOffset = 0,\r\n    user,\r\n    userList = [],\r\n    onCreateBroadcastList,\r\n    activeConversationId,\r\n    webToken,\r\n    enableBroadcasts = true,\r\n    height,\r\n    width,\r\n  } = props;\r\n  const chatUserId = user.uid;\r\n  const { client, config } = useChatClient();\r\n  const {\r\n    activeConversation,\r\n    showImageModal,\r\n    setActiveConversation,\r\n    setConversations,\r\n    conversations,\r\n    connectionStatus,\r\n    setConnectionStatus,\r\n  } = useChatState();\r\n  const [isConnected, setIsConnected] = useState(false);\r\n  const [loadingMessages, setLoadingMessages] = useState(false);\r\n  const [fecthingmore, setFetchingMore] = useState(false);\r\n  const [messages, setMessages] = useState<Message[]>([]);\r\n  const [editDetails, setEditDetails] = useState<{\r\n    message: Message;\r\n    isEditing?: boolean;\r\n    isReplying?: boolean;\r\n  }>();\r\n  // 47698942\r\n  const [recipientTyping, setRecipientTyping] = useState(false);\r\n  const [presentPage, setpresentPage] = useState(1);\r\n  const [mainListOpen, setMainListOpen] = useState(true);\r\n  const [showUserList, setShowUserList] = useState(false);\r\n  const [scrollToKey, setScrollToKey] = useState<string>(\"\");\r\n  const messagesEndRef = useRef<null | HTMLDivElement>(null);\r\n  const [forceScrollCount, setForceScrollCount] = useState(0);\r\n  const [recipientId, setRecipientId] = useState(\"\");\r\n\r\n  const [isSmallScreen, setIsSmallScreen] = useState(false);\r\n  const [inputContainerWidth, setInputContainerWidth] = useState(0);\r\n  const [view, setView] = useState<\"conversation-list\" | \"broadcast-lists\">(\r\n    \"conversation-list\"\r\n  );\r\n  const chatContainerRef = useRef<HTMLDivElement>(null);\r\n\r\n  const { theme } = config;\r\n\r\n  const [position, setPosition] = useState({ x: 0, y: 0 });\r\n  const [menuDetails, setMenuDetails] = useState<{\r\n    element: JSX.Element | null;\r\n  }>({\r\n    element: null,\r\n  });\r\n\r\n  const generalMenuRef: any = useRef(null);\r\n  const textInputRef: any = useRef(null);\r\n  const userListRef: any = useRef(null);\r\n\r\n  const resetState = () => {\r\n    setpresentPage(1);\r\n  };\r\n\r\n  const closeGeneralMenu = (e: any) => {\r\n    if (menuDetails.element && !generalMenuRef.current?.contains(e.target)) {\r\n      setMenuDetails({\r\n        element: null,\r\n      });\r\n    }\r\n    if (!userListRef.current?.contains(e.target)) {\r\n      setShowUserList(false);\r\n    }\r\n  };\r\n\r\n  const getPreSelectedConversation = () => {\r\n    try {\r\n      if (activeConversationId) {\r\n        const converationListMeta = client.getConversations();\r\n        const selectedConveration = converationListMeta[activeConversationId];\r\n        if (selectedConveration) {\r\n          setActiveConversation(selectedConveration);\r\n        }\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message);\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    getPreSelectedConversation();\r\n  }, [activeConversationId, client, connectionStatus]);\r\n\r\n  useEffect(() => {\r\n    if (props.user && webToken) {\r\n      client.initializeUser(props.user, {\r\n        notificationConfig: { type: \"fcm\", token: webToken },\r\n      });\r\n    } else {\r\n      client.initializeUser(props.user);\r\n    }\r\n  }, [props.user, webToken]);\r\n\r\n  useEffect(() => {\r\n    const checkScreenSize = () => {\r\n      const screenWidth = window.innerWidth;\r\n      const screenHeight = window.innerHeight;\r\n      setIsSmallScreen(screenWidth < 1024 || screenHeight < 768);\r\n    };\r\n  \r\n    if (!width || !height) {\r\n      checkScreenSize();\r\n      window.addEventListener(\"resize\", checkScreenSize);\r\n  \r\n      return () => window.removeEventListener(\"resize\", checkScreenSize);\r\n    }\r\n  \r\n    const checkSize = () => {\r\n      if (!chatContainerRef.current) return;\r\n  \r\n      const { offsetWidth, offsetHeight } = chatContainerRef.current;\r\n      setIsSmallScreen(offsetWidth < 1024 || offsetHeight < 768);\r\n    };\r\n  \r\n    const observer = new ResizeObserver(() => checkSize());\r\n  \r\n    if (chatContainerRef.current) {\r\n      observer.observe(chatContainerRef.current);\r\n      checkSize(); // Initial check\r\n    }\r\n  \r\n    return () => observer.disconnect();\r\n  }, [height, width]);\r\n  \r\n\r\n  useEffect(() => {\r\n    document.addEventListener(\"mousedown\", closeGeneralMenu);\r\n  }, [generalMenuRef, closeGeneralMenu]);\r\n\r\n  const handleMessage = (event?: any) => {\r\n    if (activeConversation) {\r\n      if (\r\n        event.message.conversationId ===\r\n        activeConversation.conversation.conversationId\r\n      ) {\r\n        setMessages((prev) => {\r\n          return [...prev, event.message];\r\n        });\r\n        setForceScrollCount(forceScrollCount + 1); //((:)\r\n        setTimeout(() => {\r\n          messagesEndRef?.current?.scrollIntoView({\r\n            block: \"end\",\r\n            behavior: \"smooth\",\r\n          });\r\n        }, 300);\r\n      }\r\n    }\r\n  };\r\n\r\n  const handleTypingStarted = (event: any) => {\r\n    if (activeConversation) {\r\n      if (\r\n        activeConversation.conversation.conversationId === event.conversationId\r\n      ) {\r\n        setRecipientTyping(true);\r\n      }\r\n    }\r\n  };\r\n\r\n  const handleTypingStopped = (event: any) => {\r\n    setRecipientTyping(false);\r\n  };\r\n\r\n  const handleDeletedMessage = (event: any) => {\r\n    setMessages((prev) => {\r\n      return prev.filter(\r\n        (m: Message) => m.messageId !== event.message.messageId\r\n      );\r\n    });\r\n  };\r\n\r\n  const handleEditedMessage = (event: any) => {\r\n    setMessages((prev: any) => {\r\n      const newMessages = prev.map((item: Message) => {\r\n        if (item?.messageId === event?.message?.messageId) {\r\n          return { ...item, ...event.message };\r\n        }\r\n        return item;\r\n      });\r\n      return [...newMessages];\r\n    });\r\n  };\r\n\r\n  const handleConnectionChanged = (\r\n    event: ChatEventGenerics<ConnectionEvent>\r\n  ) => {\r\n    setConnectionStatus(event);\r\n  };\r\n\r\n  const handleConversationsListChanged = (e: {\r\n    conversationListMeta: ConversationListMeta;\r\n  }) => {\r\n    const conversationList = Object.values(\r\n      e.conversationListMeta\r\n    ).flat() as ConversationItem[];\r\n    conversationList.sort(\r\n      (a, b) =>\r\n        new Date(b.lastMessage?.createdAt).getTime() -\r\n        new Date(a.lastMessage?.createdAt).getTime()\r\n    );\r\n    setConversations(conversationList);\r\n  };\r\n\r\n  const clearUnread = () => {\r\n    if (client && activeConversation) {\r\n      const messageIds = activeConversation.unread;\r\n      const msClient = client.messageClient(\r\n        activeConversation.conversation.conversationId\r\n      );\r\n      msClient.readMessages(activeConversation?.conversation.conversationId, {\r\n        uid: chatUserId,\r\n        messageIds,\r\n      });\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    if (client && activeConversation) {\r\n      const recipients = activeConversation.conversation.participants.filter(\r\n        (id) => id !== chatUserId\r\n      );\r\n      setRecipientId(recipients[0]);\r\n      client\r\n        .messageClient(activeConversation.conversation.conversationId)\r\n        .setActiveConversation();\r\n      clearUnread();\r\n    }\r\n  }, [activeConversation, client]);\r\n\r\n  useEffect(() => {\r\n    if (client) {\r\n      resetState();\r\n      return () => {\r\n        client.unsubscribe(\"new_message\" as any, handleMessage);\r\n      };\r\n    }\r\n  }, [client, activeConversation]);\r\n\r\n  useEffect(() => {\r\n    if (client) {\r\n      client.subscribe(\"connection_changed\" as any, handleConnectionChanged);\r\n\r\n      client.subscribe(\"new_message\" as any, handleMessage);\r\n\r\n      client.subscribe(\"edited_message\" as any, handleEditedMessage);\r\n\r\n      client.subscribe(\"started_typing\" as any, handleTypingStarted);\r\n\r\n      client.subscribe(\"stopped_typing\" as any, handleTypingStopped);\r\n\r\n      client.subscribe(\"deleted_message\" as any, handleDeletedMessage);\r\n\r\n      client.subscribe(\r\n        \"conversation_list_meta_changed\" as any,\r\n        handleConversationsListChanged\r\n      );\r\n    }\r\n\r\n    return () => {\r\n      if (client) {\r\n        client.unsubscribe(\"started_typing\" as any, handleTypingStarted);\r\n        client.unsubscribe(\"stopped_typing\" as any, handleTypingStopped);\r\n        client.unsubscribe(\"deleted_message\" as any, handleDeletedMessage);\r\n        client.unsubscribe(\"edited_message\" as any, handleEditedMessage);\r\n        client.unsubscribe(\"new_message\" as any, handleMessage);\r\n        client.unsubscribe(\r\n          \"connection_changed\" as any,\r\n          handleConnectionChanged\r\n        );\r\n        client.unsubscribe(\r\n          \"conversation_list_meta_changed\" as any,\r\n          handleConversationsListChanged\r\n        );\r\n      }\r\n    };\r\n  }, [client, activeConversation]);\r\n\r\n  useEffect(() => {\r\n    if (activeConversation) {\r\n      messagesEndRef.current.scrollIntoView({});\r\n      setMessages(activeConversation.conversation.messages);\r\n      setForceScrollCount(forceScrollCount + 1); //to trigger rerender\r\n    }\r\n  }, [isConnected, activeConversation]);\r\n\r\n  useEffect(() => {\r\n    if (messagesEndRef.current) {\r\n      messagesEndRef.current.scrollIntoView({});\r\n    }\r\n  }, [forceScrollCount]);\r\n\r\n  const getBroadcastMessages = async (conversationId: string) => {\r\n    try {\r\n      if (client) {\r\n        const messageList = (await client\r\n          .messageClient(conversationId)\r\n          .getBroadcastListMessages(1)) as Array<Message>;\r\n        setMessages(messageList);\r\n        setpresentPage(2);\r\n        if (messages[0]) {\r\n          setScrollToKey(messages[0].messageId);\r\n        }\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message);\r\n    }\r\n  };\r\n\r\n  const getMessages = async (conversationId: string) => {\r\n    try {\r\n      if (client) {\r\n        const messageList = (await client\r\n          .messageClient(conversationId)\r\n          .getMessages(1)) as Array<Message>;\r\n        setMessages(messageList);\r\n        setpresentPage(2);\r\n        if (messages[0]) {\r\n          setScrollToKey(messages[0].messageId);\r\n        }\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message);\r\n    }\r\n  };\r\n\r\n  const getOlderMessages = async (func: () => void) => {\r\n    try {\r\n      if (client && presentPage > 1) {\r\n        setFetchingMore(true);\r\n        const messageList = (await client\r\n          .messageClient(activeConversation?.conversation?.conversationId!)\r\n          .getMessages(presentPage)) as Array<Message>;\r\n        setMessages((prev) => {\r\n          return [...messageList, ...prev];\r\n        });\r\n        setpresentPage((p) => p + 1);\r\n        if (messages[0]) {\r\n          setScrollToKey(messages[0].messageId);\r\n        }\r\n        func();\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message);\r\n    } finally {\r\n      setFetchingMore(false);\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    try {\r\n      var conversationId = activeConversation?.conversation?.conversationId;\r\n      if (conversationId) {\r\n        if (\r\n          activeConversation.conversation.conversationType === \"broadcast-chat\"\r\n        ) {\r\n          getBroadcastMessages(conversationId);\r\n        } else {\r\n          getMessages(conversationId);\r\n        }\r\n      }\r\n    } catch (err) {\r\n      console.error(err);\r\n    } finally {\r\n      setFetchingMore(false);\r\n    }\r\n  }, [activeConversation?.conversation?.conversationId]);\r\n\r\n  const chatConverationStyles = useMemo(() => {\r\n    if (isSmallScreen) {\r\n      return {\r\n        display: \"flex\",\r\n        width: \"100%\",\r\n        height: height? `${height}px` : \"100%\",\r\n      };\r\n    }\r\n    return {\r\n      display: \"flex\",\r\n      width: \"30%\",\r\n      height: \"100%\",\r\n    };\r\n  }, [width, height, isSmallScreen]);\r\n\r\n  if (isSmallScreen && activeConversation) {\r\n    return (\r\n      <div\r\n        ref={chatContainerRef}\r\n        className={styles.chat__messages}\r\n        // style={{ width: \"100%\", backgroundColor: theme?.background?.primary }}\r\n        style={{\r\n          width: width ? `${width}px` : \"100%\",\r\n          height: height\r\n          ? `${height}px`\r\n          : `calc(100vh - ${headerHeightOffset}px)`,\r\n          backgroundColor: theme?.background?.primary,\r\n        }}\r\n      >\r\n        <ChatTopNav\r\n          setMainListOpen={setMainListOpen}\r\n          renderChatHeader={props.renderChatHeader}\r\n          onClose={resetState}\r\n          chatUserId={chatUserId}\r\n        />\r\n        <MessageList\r\n          customHeight={height}\r\n          headerHeightOffset={headerHeightOffset}\r\n          setEditDetails={setEditDetails}\r\n          messages={messages}\r\n          mousePosition={position}\r\n          conversationId={activeConversation?.conversation?.conversationId}\r\n          client={client}\r\n          textInputRef={textInputRef}\r\n          presentPage={presentPage}\r\n          setPresentPage={setpresentPage}\r\n          recipientTyping={recipientTyping}\r\n          setMainListOpen={setMainListOpen}\r\n          recipientId={recipientId}\r\n          scrollToKey={scrollToKey}\r\n          fetchingMore={fecthingmore}\r\n          messagesEndRef={messagesEndRef}\r\n          renderChatBubble={props.renderChatBubble}\r\n          renderChatHeader={props.renderChatHeader}\r\n          getOlderMessages={(func) =>\r\n            activeConversation?.conversation?.conversationType !==\r\n            \"broadcast-chat\"\r\n              ? getOlderMessages(func)\r\n              : null\r\n          }\r\n        />\r\n        <ChatInput\r\n          closeGeneralMenu={() => setMenuDetails({ element: null })}\r\n          generalMenuRef={generalMenuRef}\r\n          setMenuDetails={setMenuDetails}\r\n          menuDetails={menuDetails}\r\n          setEditDetails={setEditDetails}\r\n          editProps={editDetails as any}\r\n          recipientId={recipientId}\r\n          conversationId={activeConversation?.conversation?.conversationId}\r\n          client={client}\r\n          recipientTyping={recipientTyping}\r\n          textInputRef={textInputRef}\r\n          renderChatInput={props.renderChatInput}\r\n        />\r\n        {showImageModal.length > 0 && <ImageViewer />}\r\n      </div>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <div\r\n      ref={chatContainerRef}\r\n      style={{\r\n        background: theme?.background?.primary,\r\n        // height: `calc(100vh - ${headerHeightOffset}px)`,\r\n        height: height\r\n          ? `${height}px`\r\n          : `calc(100vh - ${headerHeightOffset}px)`,\r\n        width: width ? `${width}px` : \"100%\",\r\n      }}\r\n      className={styles.chat}\r\n    >\r\n      <div style={{ ...chatConverationStyles }}>\r\n        {/* <div className={`${styles.chat__conversations}`} style={{ ...chatConverationStyles }}> */}\r\n        <Navbar\r\n          chatUser={user}\r\n          userList={userList}\r\n          renderNavbar={props.renderNavbar}\r\n          activeView={view}\r\n          onViewChanged={(value) => setView(value)}\r\n          connectionStatus={connectionStatus}\r\n          enableBroadcasts={enableBroadcasts}\r\n        />\r\n        {view === \"conversation-list\" ? (\r\n          <MainList\r\n            resetState={resetState}\r\n            connectionStatus={connectionStatus}\r\n            setShowUserList={setShowUserList}\r\n            showUserList={showUserList}\r\n            setMainListOpen={setMainListOpen}\r\n            userListRef={userListRef}\r\n            renderConversationList={props.renderConversationList}\r\n          />\r\n        ) : (\r\n          <BroadcastLists onCreateBroadcastList={onCreateBroadcastList} />\r\n        )}\r\n      </div>\r\n      {activeConversation ? (\r\n        <div className={styles.chat__messages}>\r\n          <ChatTopNav\r\n            setMainListOpen={setMainListOpen}\r\n            renderChatHeader={props.renderChatHeader}\r\n            onClose={resetState}\r\n            chatUserId={chatUserId}\r\n          />\r\n          <MessageList\r\n            headerHeightOffset={headerHeightOffset}\r\n            setEditDetails={setEditDetails}\r\n            messages={messages}\r\n            mousePosition={position}\r\n            conversationId={activeConversation?.conversation?.conversationId}\r\n            client={client}\r\n            textInputRef={textInputRef}\r\n            presentPage={presentPage}\r\n            setPresentPage={setpresentPage}\r\n            recipientTyping={recipientTyping}\r\n            setMainListOpen={setMainListOpen}\r\n            recipientId={recipientId}\r\n            scrollToKey={scrollToKey}\r\n            fetchingMore={fecthingmore}\r\n            messagesEndRef={messagesEndRef}\r\n            renderChatBubble={props.renderChatBubble}\r\n            renderChatHeader={props.renderChatHeader}\r\n            getOlderMessages={(func) => getOlderMessages(func)}\r\n          />\r\n          <ChatInput\r\n            closeGeneralMenu={() => setMenuDetails({ element: null })}\r\n            generalMenuRef={generalMenuRef}\r\n            setMenuDetails={setMenuDetails}\r\n            menuDetails={menuDetails}\r\n            setEditDetails={setEditDetails}\r\n            editProps={editDetails as any}\r\n            recipientId={recipientId}\r\n            conversationId={activeConversation?.conversation?.conversationId}\r\n            client={client}\r\n            recipientTyping={recipientTyping}\r\n            textInputRef={textInputRef}\r\n            renderChatInput={props.renderChatInput}\r\n          />\r\n        </div>\r\n      ) : (\r\n        <div\r\n          style={{\r\n            flex: 1,\r\n            display: isSmallScreen ? \"none\" : \"flex\",\r\n            alignItems: \"center\",\r\n            flexDirection: \"column\",\r\n            justifyContent: \"center\",\r\n          }}\r\n        >\r\n          <ChatIcon color={theme.icon} size={100} />\r\n          <p style={{ marginTop: \"30px\", color: theme.text.secondary }}>\r\n            Select a conversation to get started\r\n          </p>\r\n        </div>\r\n      )}\r\n      {showImageModal.length > 0 && <ImageViewer />}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default Chat;\r\n","import React, {\r\n  Dispatch,\r\n  SetStateAction,\r\n  useEffect,\r\n  useState,\r\n  useRef,\r\n} from \"react\";\r\nimport styles from \"./chat-input.module.css\";\r\nimport \"./chat-input.module.css\";\r\nimport ChatClient, {\r\n  AttachmentTypes,\r\n  Media,\r\n  MediaType,\r\n  Message,\r\n  generateId,\r\n} from \"softchatjs-core\";\r\nimport {\r\n  AiOutlineAudio,\r\n  AiOutlineClose,\r\n  AiOutlineDelete,\r\n  AiOutlinePlus,\r\n} from \"react-icons/ai\";\r\nimport EditPanel from \"../edit-panel\";\r\nimport Text from \"../text/text\";\r\nimport { AttachmentMenu, Menu } from \"../menu\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport { MdCancel } from \"react-icons/md\";\r\nimport { IoMdSend } from \"react-icons/io\";\r\nimport { text } from \"stream/consumers\";\r\nimport { VscSend } from \"react-icons/vsc\";\r\n// import AudioRecorder from \"../audio\";\r\n// import AudioReactRecorder, { RecordState } from \"audio-react-recorder\";\r\nimport { CiFaceSmile } from \"react-icons/ci\";\r\nimport { InputEmojis } from \"../emoji\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { convertToMinutes } from \"../../helpers/date\";\r\nimport AudioPlayer from \"../audio/audio-player\";\r\nimport TrashIcon, { LockIcon } from \"../assets/icons\";\r\n// import { AudioRecorder } from \"react-audio-voice-recorder\";\r\nimport { IoStopCircleOutline } from \"react-icons/io5\";\r\nimport { useChatState } from \"../../providers/clientStateProvider\";\r\nimport { LinearLoader } from \"../Loaders/index\";\r\n// import { convertWebmToMp3 } from \"@/src/helpers/toMp3\";\r\n\r\nconst ChatInput = ({\r\n  client,\r\n  conversationId,\r\n  recipientId,\r\n  editProps,\r\n  setEditDetails,\r\n  recipientTyping,\r\n  setMenuDetails,\r\n  menuDetails,\r\n  generalMenuRef,\r\n  closeGeneralMenu,\r\n  textInputRef,\r\n  renderChatInput,\r\n}: {\r\n  client: ChatClient;\r\n  conversationId: string;\r\n  recipientId: string;\r\n  editProps: {\r\n    message: Message;\r\n    isEditing?: boolean;\r\n    isReplying?: boolean;\r\n  };\r\n  setEditDetails: Dispatch<\r\n    SetStateAction<\r\n      | { message: Message; isEditing?: boolean; isReplying?: boolean }\r\n      | undefined\r\n    >\r\n  >;\r\n  recipientTyping: boolean;\r\n  menuDetails: { element: JSX.Element | null };\r\n  setMenuDetails?: Dispatch<SetStateAction<{ element: JSX.Element | null }>>;\r\n  generalMenuRef: any;\r\n  closeGeneralMenu: () => void;\r\n  textInputRef: any;\r\n  renderChatInput?: (props: { onChange: (e: string) => void }) => JSX.Element;\r\n}) => {\r\n  const [message, setMessage] = useState<Partial<Message>>();\r\n  const [files, setFiles] = useState<File[]>([]);\r\n  const [showEmojiPicker, setShowEmojiPicker] = useState(false);\r\n  const [sending, setSending] = useState(false);\r\n  const [isRecording, setIsRecording] = useState(false);\r\n  const [audioChunks, setAudioChunks] = useState([]);\r\n  const [audioRecorder, setAudioRecorder] = useState<MediaRecorder | null>(\r\n    null\r\n  );\r\n  const inputContainerRef = useRef<HTMLDivElement>();\r\n  const [voiceMessageDuration, setVoiceMessageDuration] = useState(0);\r\n  const [audioBlob, setAudioBlob] = useState<Blob | null>(null);\r\n  const [audioBlobPLaceHolder, setAudioBlobPlaceHolder] = useState<Blob | null>(\r\n    null\r\n  );\r\n  const [inputContainerWidth, setInputContainerWidth] = useState(0);\r\n\r\n  const msClient = client.messageClient(conversationId);\r\n  const { config } = useChatClient();\r\n  const { theme } = config;\r\n  const { activeConversation } = useChatState();\r\n  const [uploading, showUploading] = useState(false);\r\n  const primaryActionColor = theme?.icon || \"white\";\r\n  const inputBg = config?.theme?.input.bgColor || \"#222529\";\r\n\r\n  const updateWidth = () => {\r\n    if (inputContainerRef.current) {\r\n      const { width } = inputContainerRef?.current?.getBoundingClientRect();\r\n      setInputContainerWidth(width);\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    updateWidth();\r\n  }, []);\r\n\r\n  useEffect(() => {\r\n    if (editProps?.isEditing) {\r\n      setMessage(editProps?.message);\r\n    } else {\r\n      setMessage({});\r\n    }\r\n  }, [editProps?.isEditing]);\r\n\r\n  const prepareAudio = () => {\r\n    if (navigator.mediaDevices) {\r\n      const constraints = { audio: true };\r\n      navigator.mediaDevices\r\n        .getUserMedia(constraints)\r\n        .then((stream) => {\r\n          const mediaRecorder = new MediaRecorder(stream);\r\n          mediaRecorder.start(1000);\r\n          setIsRecording(true);\r\n          setAudioRecorder(mediaRecorder);\r\n\r\n          var chunks = [];\r\n\r\n          mediaRecorder.onstop = (e) => {\r\n            const blob = new Blob(chunks, { type: 'audio/mp3' });\r\n            chunks = [];\r\n            setAudioBlob(blob);\r\n          };\r\n\r\n          mediaRecorder.onstart = () => {};\r\n\r\n          mediaRecorder.ondataavailable = (e) => {\r\n            chunks.push(e.data);\r\n            if (voiceMessageDuration >= 300) {\r\n              mediaRecorder.stop();\r\n            } else {\r\n              setVoiceMessageDuration((t) => t + 1);\r\n            }\r\n          };\r\n        })\r\n        .catch((err) => {\r\n          console.error(`The following error occurred: ${err}`);\r\n        });\r\n    } else {\r\n      console.log(\"not media devices found\");\r\n    }\r\n  }\r\n\r\n  // useEffect(() => {\r\n  //   if(audioRecorder) {\r\n\r\n  //   }\r\n  // },[audioRecorder]);\r\n\r\n  useEffect(() => {\r\n    let debounceTimer: NodeJS.Timeout | undefined;\r\n    let idleTimer: NodeJS.Timeout | undefined;\r\n    if (message?.message && message.message.length > 0) {\r\n      clearTimeout(debounceTimer);\r\n      // set a new debounce timer to send a typing notification after 350ms\r\n      debounceTimer = setTimeout(() => {\r\n        if (client) {\r\n          client\r\n            .messageClient(conversationId)\r\n            .sendTypingNotification(recipientId);\r\n          debounceTimer = undefined; // clear debounce timer reference after sending the typing notification\r\n        }\r\n      }, 300);\r\n      // clear the previous idle timer (stopped typing)\r\n      clearTimeout(idleTimer);\r\n      // set a new idle timer to send a stopped typing notification after 1300ms of inactivity\r\n      idleTimer = setTimeout(() => {\r\n        if (client) {\r\n          client\r\n            .messageClient(conversationId)\r\n            .sendStoppedTypingNotification(recipientId);\r\n        }\r\n      }, 1300);\r\n    }\r\n    return () => clearTimeout(debounceTimer);\r\n  }, [message?.message, conversationId]);\r\n\r\n  const uploadMessageAttachment = async () => {\r\n    try {\r\n      let mediaData: Media[] = []\r\n      if (files.length > 0) {\r\n        // Wait for all uploads to complete using Promise.all\r\n        const type = files[0].type.split(\"/\")[0];\r\n\r\n        showUploading(true);\r\n        const res = await msClient.uploadFile(files[0], {\r\n          filename: files[0].name,\r\n          mimeType: files[0].type,\r\n          ext: type === \"image\" ? \".png\" : \".mp4\",\r\n        });\r\n\r\n\r\n        mediaData.push({\r\n          type: type === \"image\" ? MediaType.IMAGE : MediaType.VIDEO,\r\n          ext: type === \"image\" ? \".png\" : \".mp4\",\r\n          mediaId: uuidv4(),\r\n          mediaUrl: res.link,\r\n          mimeType: files[0].type,\r\n        });\r\n      }\r\n\r\n      if (audioBlob) {\r\n        showUploading(true);\r\n        // const mp3Blob = await convertWebmToMp3(audioBlob);\r\n        // console.log(mp3Blob, \":::new blob\")\r\n        console.log(audioBlob)\r\n        const url = URL.createObjectURL(audioBlob);\r\n        const res = await msClient.uploadFile(url, {\r\n          filename: `${generateId()}.mp3`,\r\n          mimeType: 'audio/mp3',\r\n          ext: '.mp3'\r\n        });\r\n        mediaData.push({\r\n          type: MediaType.AUDIO,\r\n          ext: \".mp3\",\r\n          mediaId: uuidv4(),\r\n          mediaUrl: res.link as any,\r\n          mimeType: \"audio/mp3\",\r\n          meta: {\r\n            audioDurationSec: voiceMessageDuration,\r\n          },\r\n        });\r\n        setVoiceMessageDuration(0);\r\n      }\r\n      return mediaData;\r\n    } catch (error) {\r\n      console.error(error.message);\r\n      return [];\r\n    } finally {\r\n      showUploading(false);\r\n    }\r\n  };\r\n\r\n  const reset = () => {\r\n    setMessage({\r\n      message: \"\",\r\n    });\r\n    setEditDetails(undefined);\r\n  };\r\n\r\n  const sendMessage = async () => {\r\n    var mediaData = await uploadMessageAttachment();\r\n    msClient.sendMessage({\r\n      conversationId,\r\n      to: recipientId,\r\n      message: message?.message as any,\r\n      reactions: [],\r\n      attachedMedia: mediaData,\r\n      quotedMessage: editProps?.message,\r\n      attachmentType:\r\n        mediaData.length > 0 ? AttachmentTypes.MEDIA : AttachmentTypes.NONE,\r\n    });\r\n    reset();\r\n  };\r\n\r\n  const sendEditedMessage = async () => {\r\n    msClient.editMessage({\r\n      to: recipientId,\r\n      conversationId,\r\n      messageId: editProps?.message?.messageId as string,\r\n      textMessage: message?.message as string,\r\n      shouldEdit: true,\r\n    });\r\n    reset();\r\n  };\r\n\r\n  const broadcastMessage = async () => {\r\n    var mediaData = await uploadMessageAttachment();\r\n    client.messageClient(conversationId).broadcastMessage({\r\n      broadcastListId: conversationId,\r\n      participantsIds: activeConversation.conversation.participants,\r\n      newMessage: {\r\n        conversationId: conversationId,\r\n        to: recipientId,\r\n        message: message?.message,\r\n        reactions: [],\r\n        attachedMedia: mediaData,\r\n        attachmentType:\r\n          mediaData.length > 0 ? AttachmentTypes.MEDIA : AttachmentTypes.NONE,\r\n        quotedMessage: editProps?.message,\r\n      },\r\n    });\r\n    reset();\r\n  };\r\n\r\n  const sendHandler = async () => {\r\n    setSending(true);\r\n    try {\r\n      \r\n      if (!message?.message?.length && !files.length && !audioBlob) {\r\n        return;\r\n      }\r\n      if (\r\n        activeConversation?.conversation.conversationType === \"broadcast-chat\"\r\n      ) {\r\n        if(editProps?.isEditing){\r\n          return sendEditedMessage()\r\n        }\r\n        return broadcastMessage();\r\n      }\r\n      if (editProps?.isEditing) {\r\n        return sendEditedMessage();\r\n      }\r\n      sendMessage()\r\n     \r\n    } catch (err) {\r\n      console.log(err);\r\n    } finally {\r\n      setSending(false);\r\n      setFiles([]);\r\n      setAudioBlob(null);\r\n    }\r\n  };\r\n\r\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n    if (e.key === \"Enter\" && message?.message?.length) {\r\n      // Check if Enter is pressed and message is not empty\r\n      sendHandler();\r\n    }\r\n  };\r\n\r\n  const addAudioElement = (blob: any) => {\r\n    const url = URL.createObjectURL(blob);\r\n    const audio = document.createElement(\"audio\");\r\n    audio.src = url;\r\n    audio.controls = true;\r\n    document.body.appendChild(audio);\r\n  };\r\n\r\n  // if (1)\r\n  //   return (\r\n  //     <AudioRecorder\r\n  //       onRecordingComplete={addAudioElement}\r\n  //       audioTrackConstraints={{\r\n  //         noiseSuppression: true,\r\n  //         echoCancellation: true,\r\n  //       }}\r\n  //       downloadOnSavePress={true}\r\n  //       downloadFileExtension=\"webm\"\r\n  //     />\r\n  //   );\r\n\r\n  const recordVoiceMessage = () => {\r\n    prepareAudio();\r\n    \r\n  };\r\n\r\n  const stopRecording = () => {\r\n    audioRecorder.stop();\r\n    setIsRecording(false);\r\n  };\r\n\r\n  const cancelAudioAttachments = () => {\r\n    setAudioBlob(null);\r\n    setAudioBlobPlaceHolder(null);\r\n  };\r\n\r\n  if (\r\n    activeConversation?.conversation?.conversationType === \"admin-chat\"\r\n  ) {\r\n    return (\r\n      <div\r\n        style={{\r\n          padding: \"20px\",\r\n          flex: 1,\r\n          display: \"flex\",\r\n          flexDirection: \"row\",\r\n          justifyContent: \"center\",\r\n          alignItems: \"center\",\r\n        }}\r\n      >\r\n        <LockIcon color=\"white\" size={20} />\r\n        <Text\r\n          size=\"xs\"\r\n          styles={{ marginLeft: \"5px\" }}\r\n          text={\"Only the Admin can send messages.\"}\r\n        />\r\n      </div>\r\n    );\r\n  }\r\n\r\n  if (isRecording) {\r\n    return (\r\n      <div\r\n        style={{\r\n          backgroundColor: theme?.background?.secondary,\r\n          justifyContent: \"flex-end\",\r\n          width: \"100%\",\r\n          flex: 1,\r\n        }}\r\n        className={styles.input}\r\n      >\r\n        <div\r\n          className={styles.input__inner}\r\n          style={{\r\n            width: \"30%\",\r\n            fontStyle: \"italic\",\r\n            display: \"flex\",\r\n            alignItems: \"center\",\r\n            justifyContent: \"space-between\",\r\n            padding: \"10px\",\r\n            backgroundColor: theme?.background?.secondary,\r\n            boxShadow: \"rgba(0, 0, 0, 0.35) 0px 5px 15px\",\r\n          }}\r\n        >\r\n          <button\r\n            onClick={stopRecording}\r\n            style={{\r\n              backgroundColor: \"transparent\",\r\n              border: 0,\r\n              marginRight: \"12px\",\r\n            }}\r\n          >\r\n            <IoStopCircleOutline\r\n              style={{ marginTop: \"5px\" }}\r\n              color=\"red\"\r\n              size={23}\r\n            />\r\n          </button>\r\n          <div\r\n            style={{\r\n              flex: 1,\r\n              width: \"100%\",\r\n              height: \"2px\",\r\n              backgroundColor: \"grey\",\r\n            }}\r\n          >\r\n            <div\r\n              style={{\r\n                height: \"100%\",\r\n                backgroundColor: \"white\",\r\n                width: `${(voiceMessageDuration / 300) * 100}%`,\r\n              }}\r\n            />\r\n          </div>\r\n          <p\r\n            style={{\r\n              fontSize: \"11.5px\",\r\n              marginLeft: \"15px\",\r\n              color: theme?.text?.primary,\r\n            }}\r\n          >\r\n            {convertToMinutes(voiceMessageDuration)} : {convertToMinutes(300)}\r\n          </p>\r\n        </div>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  if (audioBlob && !audioBlobPLaceHolder) {\r\n    return (\r\n      <div\r\n        style={{\r\n          width: \"100%\",\r\n          backgroundColor: theme?.background?.secondary || \"#1b1d21\",\r\n          justifyContent: \"flex-start\",\r\n          display: \"flex\",\r\n          alignItems: \"center\",\r\n        }}\r\n        className={styles.input}\r\n      >\r\n        <div\r\n          className={styles.input__inner}\r\n          style={{\r\n            width: \"30%\",\r\n            fontStyle: \"italic\",\r\n            display: \"flex\",\r\n            alignItems: \"center\",\r\n            justifyContent: \"space-between\",\r\n            padding: \"10px\",\r\n            marginRight: \"10px\",\r\n            backgroundColor: theme?.background?.secondary || \"#1b1d21\",\r\n            boxShadow: \"rgba(0, 0, 0, 0.35) 0px 5px 15px\",\r\n          }}\r\n        >\r\n          <button\r\n            onClick={() => {\r\n              setAudioBlob(null);\r\n              setVoiceMessageDuration(0);\r\n            }}\r\n            style={{ backgroundColor: \"transparent\", border: 0 }}\r\n          >\r\n            <AiOutlineDelete size={22} color={\"red\"} />\r\n          </button>\r\n          <AudioPlayer blob={audioBlob} duration={voiceMessageDuration} />\r\n        </div>\r\n        <VscSend\r\n          onClick={() => {\r\n            setAudioBlobPlaceHolder(audioBlob);\r\n          }}\r\n          size={22}\r\n          color={primaryActionColor}\r\n        />\r\n      </div>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <div ref={inputContainerRef} style={{ height: \"auto\", width: \"100%\" }}>\r\n      {uploading && <LinearLoader />}\r\n      <EditPanel\r\n        width={inputContainerWidth}\r\n        message={editProps?.message}\r\n        isEditing={editProps?.isEditing}\r\n        isReplying={editProps?.isReplying}\r\n        closePanel={() => setEditDetails(undefined)}\r\n      />\r\n      {files.length || audioBlob ? (\r\n        <ChatAttachments\r\n          width={inputContainerWidth}\r\n          files={files}\r\n          setFiles={setFiles}\r\n          audioBlob={audioBlobPLaceHolder}\r\n          voiceMessageDuration={voiceMessageDuration}\r\n          cancelAudioAttachment={cancelAudioAttachments}\r\n        />\r\n      ) : null}\r\n      <div\r\n        style={{ backgroundColor: theme?.background?.secondary }}\r\n        className={styles.input}\r\n      >\r\n        <div className={styles.input__wrap}>\r\n          <div className={styles.input__icon}>\r\n            {!audioBlob && (\r\n              <div>\r\n                <AiOutlinePlus\r\n                  onClick={() =>\r\n                    setMenuDetails?.({\r\n                      element: (\r\n                        <AttachmentMenu\r\n                          closeGeneralMenu={closeGeneralMenu}\r\n                          setFiles={setFiles}\r\n                        />\r\n                      ),\r\n                    })\r\n                  }\r\n                  color={primaryActionColor}\r\n                  size={22}\r\n                />\r\n              </div>\r\n            )}\r\n          </div>\r\n          <div\r\n            className={styles.input__inner}\r\n            style={{ flex: 1, fontStyle: \"italic\", background: inputBg }}\r\n          >\r\n            {renderChatInput ? (\r\n              renderChatInput({\r\n                onChange: (e) => {\r\n                  setMessage({\r\n                    ...message,\r\n                    message: e,\r\n                  });\r\n                },\r\n              })\r\n            ) : (\r\n              <div style={{ display: \"flex\", alignItems: \"center\" }}>\r\n                <input\r\n                  style={{\r\n                    background: inputBg,\r\n                    color: theme?.input?.textColor || \"white\",\r\n                  }}\r\n                  onKeyDown={handleKeyDown}\r\n                  ref={textInputRef}\r\n                  value={message?.message}\r\n                  onChange={(e) =>\r\n                    setMessage({\r\n                      ...message,\r\n                      message: e.target.value,\r\n                    })\r\n                  }\r\n                  placeholder=\"Say something...\"\r\n                />\r\n\r\n                <CiFaceSmile\r\n                  onClick={() => setShowEmojiPicker(!showEmojiPicker)}\r\n                  className={styles.input__emoji}\r\n                  size={24}\r\n                  color={primaryActionColor}\r\n                />\r\n              </div>\r\n            )}\r\n          </div>\r\n          <div className={styles.input__button}>\r\n            {/* {audioBlob || message?.message || files.length > 0 ? (\r\n              <div>\r\n                {sending ? (\r\n                  \"...\"\r\n                ) : (\r\n                  <VscSend\r\n                    onClick={sendHandler}\r\n                    size={20}\r\n                    color={primaryActionColor}\r\n                  />\r\n                )}\r\n              </div>\r\n            ) : null} */}\r\n\r\n            {!message?.message ? (\r\n              <button\r\n                onClick={recordVoiceMessage}\r\n                style={{\r\n                  backgroundColor: \"transparent\",\r\n                  border: 0,\r\n                  cursor: \"pointer\",\r\n                }}\r\n              >\r\n                <AiOutlineAudio color={primaryActionColor} size={20} />\r\n              </button>\r\n            ) : (\r\n              <VscSend\r\n                onClick={sendHandler}\r\n                size={20}\r\n                color={primaryActionColor}\r\n              />\r\n            )}\r\n          </div>\r\n          {menuDetails.element ? (\r\n            <div className={styles.input__menu}>\r\n              <Menu\r\n                generalMenuRef={generalMenuRef}\r\n                element={menuDetails.element}\r\n              />\r\n            </div>\r\n          ) : null}\r\n          {showEmojiPicker ? (\r\n            <div className={styles.input__emoji__picker}>\r\n              <InputEmojis\r\n                onEmojiPick={(e) => {\r\n                  setMessage({\r\n                    ...message,\r\n                    message: e,\r\n                  });\r\n                  setShowEmojiPicker(false);\r\n                }}\r\n              />\r\n            </div>\r\n          ) : null}\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n\r\nconst ChatAttachments = ({\r\n  audioBlob,\r\n  voiceMessageDuration,\r\n  cancelAudioAttachment,\r\n  files,\r\n  setFiles,\r\n  width,\r\n}: {\r\n  audioBlob: Blob;\r\n  voiceMessageDuration: number;\r\n  files: any[];\r\n  setFiles: any;\r\n  cancelAudioAttachment: () => void;\r\n  width: number;\r\n}) => {\r\n  const deleteAttachment = (id: string) => {\r\n    const imgs = files.filter((i) => i.name !== id);\r\n    setFiles(imgs);\r\n  };\r\n\r\n  const { config } = useChatClient();\r\n\r\n  const { theme } = config;\r\n\r\n  return (\r\n    <div className={styles.chatPhotos} style={{ width, paddingBottom: \"10px\" }}>\r\n      {audioBlob ? (\r\n        <div\r\n          style={{\r\n            padding: \"10px\",\r\n            background: theme?.background?.primary || \"#1b1d21\",\r\n            borderRadius: \"30px\",\r\n            cursor: \"pointer\",\r\n            position: \"relative\",\r\n          }}\r\n        >\r\n          <div onClick={cancelAudioAttachment} className={styles.audioCancel}>\r\n            <MdCancel size={20} color=\"grey\" />\r\n          </div>\r\n          <div\r\n            style={{\r\n              border: `1px solid ${theme.divider}`,\r\n              borderRadius: \"5px\",\r\n            }}\r\n          >\r\n            <AudioPlayer\r\n              style={{ padding: \"15px\" }}\r\n              blob={audioBlob}\r\n              duration={voiceMessageDuration}\r\n            />\r\n          </div>\r\n        </div>\r\n      ) : null}\r\n      {files.length\r\n        ? files.map((item, i) => {\r\n            const url = URL.createObjectURL(item);\r\n            return (\r\n              <div key={i} className={styles.chatPhotos__item}>\r\n                {item.type === \"video/quicktime\" ? (\r\n                  <video style={{}} src={url} />\r\n                ) : (\r\n                  <img src={url as any} alt=\"\" />\r\n                )}\r\n\r\n                <div\r\n                  onClick={() => deleteAttachment(item.name)}\r\n                  className={styles.chatPhotos__cancel}\r\n                >\r\n                  <MdCancel size={20} color=\"grey\" />\r\n                </div>\r\n              </div>\r\n            );\r\n          })\r\n        : null}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default ChatInput;\r\n","import React, { useEffect, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./edit.module.css\";\r\nimport Text from \"../text/text\";\r\nimport { Message } from \"softchatjs-core\";\r\nimport { AiOutlineClose } from \"react-icons/ai\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\n\r\ntype EditPanelProps = {\r\n  message: Message;\r\n  isEditing?: boolean;\r\n  isReplying?: boolean;\r\n  closePanel: () => void;\r\n  width: number\r\n};\r\n\r\nconst EditPanel = (props: EditPanelProps) => {\r\n  const { isEditing, message, isReplying, closePanel, width } = props;\r\n  const { config } = useChatClient();\r\n  const { theme } = config;\r\n\r\n  const secondaryColor = theme?.background?.secondary;\r\n  const textColor = theme?.text?.primary;\r\n  const iconColor = theme?.icon;\r\n\r\n  return (\r\n    <div\r\n      className={\r\n        isEditing || isReplying\r\n          ? `${styles.edit} ${styles.editOpen}`\r\n          : `${styles.edit}`\r\n      }\r\n      style={{ background: secondaryColor || \"#1b1d21\", width: width }}\r\n    >\r\n      <div\r\n        style={{ background: secondaryColor || \"#222529\" }}\r\n        className={styles.edit__message}\r\n      >\r\n        <div style={{ width: \"90%\" }}>\r\n          <Text text=\"You\" styles={{ color: textColor }} weight=\"bold\" />\r\n          <Text\r\n            text={message?.message}\r\n            styles={{ color: textColor }}\r\n            weight=\"medium\"\r\n          />\r\n        </div>\r\n\r\n        <div style={{ width: \"10%\", marginRight: '15px' }}>\r\n          {message?.attachedMedia[0]?.mediaUrl && (\r\n            <img\r\n              style={{ height: \"100%\", width: \"100%\", borderRadius: \"5px\" }}\r\n              src={message?.attachedMedia[0]?.mediaUrl}\r\n              alt=\"\"\r\n            />\r\n          )}\r\n        </div>\r\n        <AiOutlineClose\r\n          onClick={closePanel}\r\n          color={iconColor}\r\n          size={20}\r\n          style={{ cursor: \"pointer\" }}\r\n        />\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default EditPanel;\r\n","import React from \"react\";\r\nimport styles from \"./text.module.css\";\r\n\r\ntype TextProps = {\r\n  text: string;\r\n  styles?: React.CSSProperties | undefined;\r\n  weight?: \"bold\" | \"medium\";\r\n  size?: \"sm\" | \"md\" | \"xs\";\r\n};\r\n\r\nconst Text = (props: TextProps) => {\r\n  const textWeight = {\r\n    bold: styles.textBold,\r\n    medium: `${styles.textMedium}`,\r\n  };\r\n\r\n  const textSize: any = {\r\n    sm: styles.textSmall,\r\n    md: styles.textSizeMd,\r\n    xs: styles.textExtraSmall,\r\n  };\r\n\r\n  return (\r\n    <p\r\n      style={props.styles}\r\n      className={`${styles.text} ${textWeight[props.weight || \"medium\"]} ${\r\n        textSize[props.size || \"md\"]\r\n      }`}\r\n    >\r\n      {props.text}\r\n    </p>\r\n  );\r\n};\r\n\r\nexport default Text;\r\n","import { createContext, useContext } from \"react\";\r\nimport ChatClient from \"softchatjs-core\";\r\nimport { ChatStateProvider } from \"./clientStateProvider\";\r\nimport { defaulTheme } from \"../theme\";\r\nimport { ReactTheme } from \"../theme/type\";\r\n\r\ntype ContextType = {\r\n  config: { theme: ReactTheme },\r\n  client: ChatClient | null;\r\n};\r\n\r\nexport const ChatClientContext = createContext<ContextType>({\r\n  config: { theme: defaulTheme },\r\n  client: null,\r\n});\r\n\r\nexport const useChatClient = () => useContext(ChatClientContext);\r\n\r\nexport const ChatClientProvider = ({\r\n  theme,\r\n  children,\r\n  client\r\n}: {\r\n  theme?: ReactTheme\r\n  children: JSX.Element;\r\n  client: ChatClient | null\r\n}) => {\r\n\r\n  return (\r\n    <ChatClientContext.Provider value={{ config: { theme: theme? theme : defaulTheme }, client }}>\r\n      <ChatStateProvider>\r\n        {children}\r\n      </ChatStateProvider>\r\n    </ChatClientContext.Provider>\r\n  );\r\n};\r\n","import React, { createContext, useContext, useState } from \"react\";\r\nimport { Conversation, Media, Message } from \"softchatjs-core\";\r\n\r\nexport type ConversationItem = {\r\n  conversation: Conversation;\r\n  lastMessage: Message;\r\n  unread: string[];\r\n};\r\n\r\nexport type ConnectionStatus = {\r\n  isConnected: boolean;\r\n  fetchingConversations: boolean;\r\n  connecting: boolean;\r\n};\r\n\r\ntype Context = {\r\n  activeConversation: ConversationItem | null;\r\n  setActiveConversation: React.Dispatch<\r\n    React.SetStateAction<ConversationItem | null>\r\n  >;\r\n  conversations: ConversationItem[];\r\n  setConversations: React.Dispatch<React.SetStateAction<ConversationItem[]>>;\r\n  showImageModal: Media[];\r\n  setShowImageModal: React.Dispatch<React.SetStateAction<Media[]>>;\r\n  connectionStatus: ConnectionStatus;\r\n  setConnectionStatus: React.Dispatch<React.SetStateAction<ConnectionStatus>>;\r\n};\r\n\r\nexport const ChatStateContext = createContext<Context>({\r\n  activeConversation: null,\r\n  setActiveConversation: () => {},\r\n  conversations: [],\r\n  setConversations: () => {},\r\n  showImageModal: [],\r\n  setShowImageModal: () => {},\r\n  connectionStatus: {\r\n    isConnected: false,\r\n    fetchingConversations: false,\r\n    connecting: false,\r\n  },\r\n  setConnectionStatus: () => {},\r\n});\r\n\r\nexport const useChatState = () => useContext(ChatStateContext);\r\n\r\nexport const ChatStateProvider = ({ children }: { children: JSX.Element }) => {\r\n  const [activeConversation, setActiveConversation] =\r\n    useState<ConversationItem | null>(null);\r\n  const [conversations, setConversations] = useState<ConversationItem[]>([]);\r\n  const [showImageModal, setShowImageModal] = useState<Media[]>([]);\r\n  const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>({\r\n    isConnected: false,\r\n    fetchingConversations: false,\r\n    connecting: false,\r\n  });\r\n\r\n  return (\r\n    <ChatStateContext.Provider\r\n      value={{\r\n        activeConversation,\r\n        setActiveConversation,\r\n        conversations,\r\n        setConversations,\r\n        showImageModal,\r\n        setShowImageModal,\r\n        connectionStatus,\r\n        setConnectionStatus,\r\n      }}\r\n    >\r\n      {children}\r\n    </ChatStateContext.Provider>\r\n  );\r\n};\r\n","import { ReactTheme } from \"./type\";\r\n\r\nexport const defaulTheme: ReactTheme = {\r\n  background: {\r\n    primary: \"#1b1d21\", // White for the primary background\r\n    secondary: \"#202326\", // Light grey for secondary background\r\n    disabled: \"#E0E0E0\", // Very light grey for disabled background\r\n  },\r\n  text: {\r\n    primary: \"white\", // Black text for high contrast\r\n    secondary: \"#4A4A4A\", // Dark grey for secondary text\r\n    disabled: \"#9E9E9E\", // Light grey for disabled text\r\n  },\r\n  action: {\r\n    primary: \"#007AFF\", // Bright blue for primary action buttons\r\n    secondary: \"#5AA3FF\", // Light blue for secondary action buttons\r\n  },\r\n  chatBubble: {\r\n    left: {\r\n      bgColor: \"#343434\", // Light grey for incoming message background\r\n      messageColor: \"white\", // Dark grey for incoming message text\r\n      messageTimeColor: \"#6D6D6D\", // Medium grey for message time\r\n      replyBorderColor: \"#D1D1D6\", // Slightly darker grey for reply border\r\n    },\r\n    right: {\r\n      bgColor: \"#343434\", // Light blue for outgoing message background\r\n      messageColor: \"white\", // Black for outgoing message text\r\n      messageTimeColor: \"#6D6D6D\", // Medium grey for message time\r\n      replyBorderColor: \"#A3D1FF\", // Medium blue for reply border\r\n    },\r\n  },\r\n  icon: \"white\", // Dark grey for icons\r\n  divider: \"rgba(128, 128, 128, 0.136)\", // Light grey for dividers\r\n  hideDivider: false,\r\n  input: {\r\n    bgColor: \"#1b1d21\", // Light grey for input background\r\n    textColor: \"white\", // Black for input text\r\n    emojiPickerTheme: \"dark\", // Light theme for emoji picker\r\n  },\r\n};\r\n","import { Dispatch, SetStateAction, useEffect, useRef, useState } from \"react\";\r\nimport styles from \"./menu.module.css\";\r\nimport { HiPhoto } from \"react-icons/hi2\";\r\nimport Text from \"../text/text\";\r\n\r\ntype MenuProps = {\r\n  element: JSX.Element;\r\n  generalMenuRef: any;\r\n};\r\n\r\nexport const Menu = (props: MenuProps) => {\r\n  return (\r\n    <div ref={props.generalMenuRef} className={styles.menu}>\r\n      {props.element}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const AttachmentMenu = ({\r\n  onChange,\r\n  setFiles,\r\n  closeGeneralMenu,\r\n}: {\r\n  onChange?: (event: any) => void;\r\n  closeGeneralMenu: () => void;\r\n  setFiles:Dispatch<SetStateAction<any[]>>\r\n}) => {\r\n  const fileInputRef: any = useRef();\r\n  const options = [\r\n    {\r\n      icon: <HiPhoto size={24} color=\"white\" />,\r\n      title: \"Photo\",\r\n    },\r\n  ];\r\n\r\n  const handleChange = (event: any) => {\r\n    closeGeneralMenu();\r\n    const files = event.target.files;\r\n    setFiles(Array.from(files))\r\n  };\r\n\r\n  return (\r\n    <div className={styles.attachment}>\r\n      {options.map((item, index) => (\r\n        <label htmlFor=\"upload\" key={index}>\r\n          <div className={styles.attachment__item}>\r\n            <div style={{ marginRight: \"10px\" }}> {item.icon}</div>\r\n            <input\r\n              onChange={handleChange}\r\n              \r\n              ref={fileInputRef}\r\n              type=\"file\"\r\n              hidden\r\n              id=\"upload\"\r\n            />\r\n            <Text\r\n              styles={{ marginBottom: \"3px\" }}\r\n              size=\"sm\"\r\n              text={item.title}\r\n            />\r\n          </div>\r\n        </label>\r\n      ))}\r\n    </div>\r\n  );\r\n};\r\n","import React, {\r\n  Dispatch,\r\n  SetStateAction,\r\n  useContext,\r\n  useEffect,\r\n  useState,\r\n} from \"react\";\r\nimport EmojiPicker from \"emoji-picker-react\";\r\nimport styles from \"./emoji.module.css\";\r\nimport ChatClient, { Message } from \"softchatjs-core\";\r\nimport { CiFaceSmile } from \"react-icons/ci\";\r\nimport { BsReply } from \"react-icons/bs\";\r\nimport { AiOutlineDelete } from \"react-icons/ai\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { FiEdit2 } from \"react-icons/fi\";\r\nimport { CiEdit } from \"react-icons/ci\";\r\n\r\nconst emojis = [\"👍\", \"😔\", \"🙂\", \"😮\", \"😃\"];\r\n\r\ntype EmojiPanelProps = {\r\n  emojiPickerRef: any;\r\n  conversationId: string;\r\n  client: ChatClient;\r\n  message: Message;\r\n  recipientId: string;\r\n  setShowEmojiPanel: Dispatch<SetStateAction<boolean>>;\r\n};\r\n\r\ntype ReactionPanelProps = {\r\n  message: Message;\r\n  setEditDetails: Dispatch<\r\n    SetStateAction<\r\n      | { message: Message; isEditing?: boolean; isReplying?: boolean }\r\n      | undefined\r\n    >\r\n  >;\r\n  canEdit?: boolean;\r\n  openEmojiPanel: () => void;\r\n  optionsMenuRef: any;\r\n  mousePosition: {\r\n    x: number;\r\n    y: number;\r\n  };\r\n  conversationId: string;\r\n\r\n  closeOptionsMenu: () => void;\r\n  textInputRef: any;\r\n  client: ChatClient;\r\n};\r\n\r\nexport const EmojiPanel = (props: EmojiPanelProps) => {\r\n  const { client, message, conversationId, recipientId, setShowEmojiPanel } =\r\n    props;\r\n  const { config } = useChatClient();\r\n  const bgColor = config?.theme?.background?.secondary || \"#222529\";\r\n\r\n  const reactToMessage = ({ emoji }: { emoji: string }) => {\r\n    const msClient = client.messageClient(conversationId);\r\n\r\n    msClient.reactToMessage({\r\n      conversationId,\r\n      messageId: message.messageId,\r\n      reactions: [\r\n        {\r\n          emoji,\r\n          uid: client.chatUserId\r\n        },\r\n      ],\r\n      to: recipientId,\r\n    });\r\n    setShowEmojiPanel(false);\r\n  };\r\n  return (\r\n    <div\r\n      ref={props.emojiPickerRef}\r\n      style={{ background: bgColor }}\r\n      className={styles.emoji}\r\n    >\r\n      {/* <EmojiPicker\r\n        onEmojiClick={(e) => {\r\n          reactToMessage({ emoji: e.emoji });\r\n        }}\r\n        theme={\"dark\" as any}\r\n      /> */}\r\n      {emojis.map((item, index) => (\r\n        <div\r\n          key={index}\r\n          onClick={() => reactToMessage({ emoji: item })}\r\n          className={styles.reaction__emoji}\r\n        >\r\n          {item}\r\n        </div>\r\n      ))}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const ReactionPanel = ({\r\n  setEditDetails,\r\n  message,\r\n  closeOptionsMenu,\r\n  textInputRef,\r\n  openEmojiPanel,\r\n  client,\r\n  canEdit,\r\n  conversationId,\r\n}: ReactionPanelProps) => {\r\n  const { config } = useChatClient();\r\n  const iconColor = config.theme?.icon || \"#72767D\";\r\n\r\n  const emojiList = [\r\n    {\r\n      emoji: <FiEdit2 size={16} color={iconColor} />,\r\n      onPress: () => {\r\n        setEditDetails({\r\n          message,\r\n          isEditing: true,\r\n        });\r\n        closeOptionsMenu();\r\n      },\r\n      enabled: canEdit,\r\n    },\r\n    {\r\n      emoji: <CiFaceSmile size={16} color={iconColor} />,\r\n      onPress: () => {\r\n        openEmojiPanel();\r\n      },\r\n      enabled: true,\r\n    },\r\n    {\r\n      emoji: <BsReply size={16} color={iconColor} />,\r\n      onPress: () => {\r\n        setEditDetails({\r\n          message,\r\n          isReplying: true,\r\n        });\r\n        closeOptionsMenu();\r\n        textInputRef.current?.focus();\r\n      },\r\n      enabled: true,\r\n    },\r\n    {\r\n      emoji: <AiOutlineDelete size={16} color={iconColor} />,\r\n      onPress: () => {\r\n        const msClient = client.messageClient(conversationId);\r\n        msClient.deleteMessage(message.messageId, message.to, conversationId);\r\n      },\r\n      enabled: canEdit,\r\n    },\r\n  ];\r\n  return (\r\n    <div className={styles.reactions}>\r\n      {emojiList.map((item, index) => {\r\n        if (item.enabled) {\r\n          return (\r\n            <div key={index} onClick={item.onPress} className={styles.reaction__emoji}>\r\n              {item.emoji}\r\n            </div>\r\n          );\r\n        }\r\n      })}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const InputEmojis = ({\r\n  onEmojiPick,\r\n}: {\r\n  onEmojiPick: (emoji: string) => void;\r\n}) => {\r\n  const { config } = useChatClient();\r\n  return (\r\n    <EmojiPicker\r\n      height={350}\r\n      width={300}\r\n      onEmojiClick={(e) => {\r\n        onEmojiPick(e.emoji);\r\n      }}\r\n      theme={config?.theme?.input?.emojiPickerTheme as any}\r\n    />\r\n  );\r\n};\r\n ","import dayjs from \"dayjs\";\r\nimport moment from 'moment';\r\n\r\n\r\nimport localizedFormat from \"dayjs/plugin/localizedFormat\";\r\nimport calendarFormat from \"dayjs/plugin/calendar\";\r\ndayjs.extend(localizedFormat);\r\ndayjs.extend(calendarFormat);\r\n\r\nexport const formatMessageTime = (date: string) => {\r\n  return dayjs(date).format(\"LT\");\r\n};\r\n\r\nexport const formatSectionTime = (date: string) => {\r\n  return dayjs(date).format(\"ll\");\r\n};\r\n\r\nexport function formatWhatsAppDate(dateInput: Date): string {\r\n  const now = new Date();\r\n  const messageDate = new Date(dateInput);\r\n\r\n  const isSameDay = now.toDateString() === messageDate.toDateString();\r\n  const isYesterday =\r\n    now.getDate() - messageDate.getDate() === 1 &&\r\n    now.getMonth() === messageDate.getMonth() &&\r\n    now.getFullYear() === messageDate.getFullYear();\r\n\r\n  const oneWeekAgo = new Date();\r\n  oneWeekAgo.setDate(now.getDate() - 7);\r\n\r\n  if (isSameDay) {\r\n    return \"Today\";\r\n  } else if (isYesterday) {\r\n    return \"Yesterday\";\r\n  } else if (messageDate > oneWeekAgo) {\r\n    // Return the day of the week (e.g., \"Monday\")\r\n    return messageDate.toLocaleDateString(\"en-US\", { weekday: \"long\" });\r\n  } else {\r\n    // Return the date in DD/MM/YYYY format\r\n    const day = String(messageDate.getDate()).padStart(2, \"0\");\r\n    const month = String(messageDate.getMonth() + 1).padStart(2, \"0\"); // Months are zero-indexed\r\n    const year = messageDate.getFullYear();\r\n\r\n    return `${day}/${month}/${year}`;\r\n  }\r\n}\r\n\r\nexport function formatConversationTime(time: Date | string) {\r\n  if(!time) return ''\r\n  const now = moment();\r\n  const then = moment(time);\r\n  const duration = moment.duration(now.diff(then));\r\n\r\n  // Get the largest unit\r\n  const years = Math.floor(duration.asYears());\r\n  if (years > 0) return years + 'yr';\r\n\r\n  const months = Math.floor(duration.asMonths());\r\n  if (months > 0) return months + 'mo';\r\n\r\n  const weeks = Math.floor(duration.asWeeks());\r\n  if (weeks > 0) return weeks + 'w';\r\n\r\n  const days = Math.floor(duration.asDays());\r\n  if (days > 0) return days + 'd';\r\n\r\n  const hours = Math.floor(duration.asHours());\r\n  if (hours > 0) return hours + 'h';\r\n\r\n  const minutes = Math.floor(duration.asMinutes());\r\n  if (minutes > 0) return minutes + 'm';\r\n\r\n  // If duration is less than 1 minute\r\n  return 'Just now';\r\n}\r\n\r\nexport function convertToMinutes(seconds: number) {\r\n  if(seconds === 0) {\r\n    return '00:00'\r\n  }\r\n  var _seconds = Number(seconds.toFixed(0))\r\n  const minutes = Math.floor(_seconds / 60);\r\n  const remainingSeconds = _seconds % 60;\r\n\r\n  // Pad the numbers to always have two digits\r\n  const paddedMinutes = String(minutes).padStart(2, '0');\r\n  const paddedSeconds = String(remainingSeconds).padStart(2, '0');\r\n\r\n  return `${paddedMinutes}:${paddedSeconds}`;\r\n}","import React, { useState, useEffect, useRef, useCallback, CSSProperties } from \"react\";\r\n// import \"./audio-recorder.css\";\r\nimport { PauseIcon, PlayIcon } from \"../assets/icons\";\r\nimport { convertToMinutes } from \"../../helpers/date\";\r\nimport { FaSpinner } from \"react-icons/fa6\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\n\r\ntype AudioPlayerProps = {\r\n  blob: Blob;\r\n  url?: string;\r\n  duration: number;\r\n  style?: CSSProperties\r\n};\r\nexport default function AudioPlayer(props: AudioPlayerProps) {\r\n  const { blob, duration, url, style } = props;\r\n\r\n  const [audioUrl, setAudioUrl] = useState(\"\");\r\n  const audioRef = useRef<HTMLAudioElement>(null);\r\n  const [isPlaying, setIsPlaying] = useState(false);\r\n  const [currentTime, setCurrentTime] = useState(0);\r\n  const [isLoading, setIsLoading] = useState(true); // Set default to true\r\n  const { config } = useChatClient();\r\n  const theme = config.theme;\r\n  const textColor = config?.theme?.text?.primary || \"white\";\r\n\r\n  const togglePlayPause = () => {\r\n    if (audioRef.current) {\r\n      if (isPlaying) {\r\n        audioRef.current.pause();\r\n      } else {\r\n        audioRef.current.play();\r\n      }\r\n      setIsPlaying(!isPlaying);\r\n    }\r\n  };\r\n\r\n  const handleLoadedMetadata = () => {\r\n    // if (audioRef.current) {\r\n    // setDuration(audioRef.current.duration?? 0);\r\n    // }\r\n  };\r\n\r\n  const handleTimeUpdate = () => {\r\n    // if (audioRef.current) {\r\n    setCurrentTime(audioRef.current.currentTime);\r\n    // }\r\n  };\r\n\r\n  const handleEnded = () => {\r\n    setIsPlaying(false);\r\n    setCurrentTime(0);\r\n  };\r\n\r\n  useEffect(() => {\r\n    if (url) {\r\n      return setAudioUrl(url);\r\n    }\r\n    if (blob) {\r\n      const url = URL.createObjectURL(blob);\r\n      setAudioUrl(url);\r\n      setIsLoading(true);\r\n    }\r\n  }, [blob, url]);\r\n\r\n  const renderAction = useCallback(() => {\r\n    if (isLoading) {\r\n      return <FaSpinner style={{ marginRight: \"3px\", color:textColor} } />;\r\n    }\r\n\r\n    return (\r\n      <button\r\n        onClick={togglePlayPause}\r\n        style={{\r\n          backgroundColor: \"transparent\",\r\n          border: 0,\r\n          padding: 0,\r\n          margin: '0px',\r\n          marginTop: '4px'\r\n        }}\r\n      >\r\n        {isPlaying ? (\r\n          <PauseIcon size={15} color={textColor} />\r\n        ) : (\r\n          <PlayIcon size={15} color={textColor} />\r\n        )}\r\n      </button>\r\n    );\r\n  }, [isLoading, isPlaying]);\r\n\r\n  return (\r\n    <div style={{ display: \"flex\", alignItems: \"center\", padding: \"5px\", ...style }}>\r\n      {renderAction()}\r\n      <audio\r\n        ref={audioRef}\r\n        onLoadedMetadata={handleLoadedMetadata}\r\n        onTimeUpdate={handleTimeUpdate}\r\n        onEnded={handleEnded}\r\n        onLoadStart={() => setIsLoading(true)}\r\n        onCanPlay={() => setIsLoading(false)}\r\n        src={audioUrl}\r\n      >\r\n      </audio>\r\n      <p style={{ padding: 0, marginLeft: \"10px\", marginTop: 0, fontSize: \"11.5px\", color: textColor }}>\r\n        {convertToMinutes(currentTime)} : {convertToMinutes(duration)}\r\n      </p>\r\n    </div>\r\n  );\r\n}\r\n","type Icon = {\r\n  size?: number;\r\n  color?: string;\r\n};\r\n\r\nexport default function TrashIcon(props: Icon) {\r\n  const { size = 25, color = \"red\" } = props;\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"none\">\r\n      <path\r\n        fillRule=\"evenodd\"\r\n        clipRule=\"evenodd\"\r\n        d=\"M8.75009 1C8.02075 1 7.32127 1.28973 6.80555 1.80546C6.28982 2.32118 6.00009 3.02065 6.00009 3.75V4.193C5.20476 4.26967 4.41643 4.369 3.63509 4.491C3.53634 4.50445 3.44126 4.53745 3.35541 4.58807C3.26956 4.63869 3.19465 4.70591 3.13508 4.78581C3.0755 4.86571 3.03245 4.95667 3.00843 5.0534C2.98441 5.15013 2.97992 5.25067 2.9952 5.34916C3.01048 5.44764 3.04524 5.54209 3.09745 5.62699C3.14965 5.71189 3.21825 5.78553 3.29924 5.84361C3.38023 5.90169 3.47199 5.94305 3.56914 5.96526C3.6663 5.98748 3.76691 5.99011 3.86509 5.973L4.01409 5.951L4.85509 16.469C4.91015 17.1582 5.22279 17.8014 5.73075 18.2704C6.23871 18.7394 6.9047 18.9999 7.59609 19H12.4031C13.0945 19.0002 13.7606 18.74 14.2687 18.2711C14.7769 17.8022 15.0898 17.1592 15.1451 16.47L15.9861 5.95L16.1351 5.973C16.3298 5.99952 16.5271 5.94858 16.6847 5.83111C16.8422 5.71365 16.9473 5.53906 16.9775 5.34488C17.0076 5.15071 16.9603 4.95246 16.8458 4.79278C16.7313 4.6331 16.5587 4.52474 16.3651 4.491C15.5798 4.36877 14.7911 4.26939 14.0001 4.193V3.75C14.0001 3.02065 13.7104 2.32118 13.1946 1.80546C12.6789 1.28973 11.9794 1 11.2501 1H8.75009ZM10.0001 4C10.8401 4 11.6734 4.025 12.5001 4.075V3.75C12.5001 3.06 11.9401 2.5 11.2501 2.5H8.75009C8.06009 2.5 7.50009 3.06 7.50009 3.75V4.075C8.32676 4.025 9.16009 4 10.0001 4ZM8.58009 7.72C8.57213 7.52109 8.48549 7.33348 8.33921 7.19846C8.19293 7.06343 7.999 6.99204 7.80009 7C7.60118 7.00796 7.41357 7.0946 7.27855 7.24088C7.14352 7.38716 7.07213 7.58109 7.08009 7.78L7.38009 15.28C7.38403 15.3785 7.40733 15.4752 7.44866 15.5647C7.48999 15.6542 7.54854 15.7347 7.62097 15.8015C7.6934 15.8684 7.77829 15.9203 7.8708 15.9544C7.9633 15.9884 8.0616 16.0039 8.16009 16C8.25858 15.9961 8.35533 15.9728 8.44482 15.9314C8.53431 15.8901 8.61478 15.8315 8.68163 15.7591C8.74849 15.6867 8.80043 15.6018 8.83448 15.5093C8.86853 15.4168 8.88403 15.3185 8.88009 15.22L8.58009 7.72ZM12.9201 7.78C12.924 7.68151 12.9085 7.58321 12.8745 7.4907C12.8404 7.3982 12.7885 7.31331 12.7216 7.24088C12.6548 7.16845 12.5743 7.1099 12.4848 7.06857C12.3953 7.02724 12.2986 7.00394 12.2001 7C12.0012 6.99204 11.8073 7.06343 11.661 7.19846C11.5147 7.33348 11.428 7.52109 11.4201 7.72L11.1201 15.22C11.1162 15.3185 11.1317 15.4168 11.1657 15.5093C11.1998 15.6018 11.2517 15.6867 11.3185 15.7591C11.3854 15.8315 11.4659 15.8901 11.5554 15.9314C11.6448 15.9728 11.7416 15.9961 11.8401 16C11.9386 16.0039 12.0369 15.9884 12.1294 15.9544C12.2219 15.9203 12.3068 15.8684 12.3792 15.8015C12.4516 15.7347 12.5102 15.6542 12.5515 15.5647C12.5929 15.4752 12.6162 15.3785 12.6201 15.28L12.9201 7.78Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n}\r\n\r\nexport const PlayIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 256 256\" fill=\"none\">\r\n      <path\r\n        d=\"M240 128C240.007 130.716 239.31 133.388 237.978 135.756C236.647 138.123 234.725 140.105 232.4 141.51L88.32 229.65C85.8909 231.138 83.1087 231.95 80.2608 232.002C77.4129 232.055 74.6025 231.347 72.12 229.95C69.6611 228.575 67.6128 226.57 66.1856 224.141C64.7585 221.712 64.0041 218.947 64 216.13V39.8701C64.0041 37.053 64.7585 34.2877 66.1856 31.8588C67.6128 29.4299 69.6611 27.4249 72.12 26.0501C74.6025 24.6536 77.4129 23.9451 80.2608 23.9979C83.1087 24.0506 85.8909 24.8626 88.32 26.3501L232.4 114.49C234.725 115.895 236.647 117.877 237.978 120.245C239.31 122.612 240.007 125.284 240 128Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const PauseIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n      <path\r\n        fill-rule=\"evenodd\"\r\n        clip-rule=\"evenodd\"\r\n        d=\"M8 5C7.46957 5 6.96086 5.21071 6.58579 5.58579C6.21071 5.96086 6 6.46957 6 7V17C6 17.5304 6.21071 18.0391 6.58579 18.4142C6.96086 18.7893 7.46957 19 8 19H9C9.53043 19 10.0391 18.7893 10.4142 18.4142C10.7893 18.0391 11 17.5304 11 17V7C11 6.46957 10.7893 5.96086 10.4142 5.58579C10.0391 5.21071 9.53043 5 9 5H8ZM15 5C14.4696 5 13.9609 5.21071 13.5858 5.58579C13.2107 5.96086 13 6.46957 13 7V17C13 17.5304 13.2107 18.0391 13.5858 18.4142C13.9609 18.7893 14.4696 19 15 19H16C16.5304 19 17.0391 18.7893 17.4142 18.4142C17.7893 18.0391 18 17.5304 18 17V7C18 6.46957 17.7893 5.96086 17.4142 5.58579C17.0391 5.21071 16.5304 5 16 5H15Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const LockIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n      <path\r\n        d=\"M18 8H17V6C17 3.24 14.76 1 12 1C9.24 1 7 3.24 7 6V8H6C4.9 8 4 8.9 4 10V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V10C20 8.9 19.1 8 18 8ZM9 6C9 4.34 10.34 3 12 3C13.66 3 15 4.34 15 6V8H9V6ZM18 20H6V10H18V20ZM12 17C13.1 17 14 16.1 14 15C14 13.9 13.1 13 12 13C10.9 13 10 13.9 10 15C10 16.1 10.9 17 12 17Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const ChatIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n      <path\r\n        d=\"M12 2C17.523 2 22 6.477 22 12C22 17.523 17.523 22 12 22H4C3.46957 22 2.96086 21.7893 2.58579 21.4142C2.21071 21.0391 2 20.5304 2 20V12C2 6.477 6.477 2 12 2ZM12 14H9C8.73478 14 8.48043 14.1054 8.29289 14.2929C8.10536 14.4804 8 14.7348 8 15C8 15.2652 8.10536 15.5196 8.29289 15.7071C8.48043 15.8946 8.73478 16 9 16H12C12.2652 16 12.5196 15.8946 12.7071 15.7071C12.8946 15.5196 13 15.2652 13 15C13 14.7348 12.8946 14.4804 12.7071 14.2929C12.5196 14.1054 12.2652 14 12 14ZM15 10H9C8.74512 10.0003 8.49997 10.0979 8.31463 10.2728C8.1293 10.4478 8.01776 10.687 8.00283 10.9414C7.98789 11.1958 8.07067 11.4464 8.23426 11.6418C8.39785 11.8373 8.6299 11.9629 8.883 11.993L9 12H15C15.2549 11.9997 15.5 11.9021 15.6854 11.7272C15.8707 11.5522 15.9822 11.313 15.9972 11.0586C16.0121 10.8042 15.9293 10.5536 15.7657 10.3582C15.6021 10.1627 15.3701 10.0371 15.117 10.007L15 10Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const VerifiedIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg\r\n      width={size}\r\n      height={size}\r\n      viewBox=\"0 0 24 24\"\r\n      fill=\"none\"\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n    >\r\n      <path\r\n        d=\"M8.6 22.5L6.7 19.3L3.1 18.5L3.45 14.8L1 12L3.45 9.2L3.1 5.5L6.7 4.7L8.6 1.5L12 2.95L15.4 1.5L17.3 4.7L20.9 5.5L20.55 9.2L23 12L20.55 14.8L20.9 18.5L17.3 19.3L15.4 22.5L12 21.05L8.6 22.5ZM9.45 19.95L12 18.85L14.6 19.95L16 17.55L18.75 16.9L18.5 14.1L20.35 12L18.5 9.85L18.75 7.05L16 6.45L14.55 4.05L12 5.15L9.4 4.05L8 6.45L5.25 7.05L5.5 9.85L3.65 12L5.5 14.1L5.25 16.95L8 17.55L9.45 19.95ZM10.95 15.55L16.6 9.9L15.2 8.45L10.95 12.7L8.8 10.6L7.4 12L10.95 15.55Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const ChatPlus = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n\r\n  return (\r\n    <svg\r\n      width={size}\r\n      height={size}\r\n      viewBox=\"0 0 16 16\"\r\n      fill=\"none\"\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n    >\r\n      <path\r\n        d=\"M8.50007 5.5C8.50007 5.36739 8.44739 5.24022 8.35362 5.14645C8.25985 5.05268 8.13268 5 8.00007 5C7.86746 5 7.74028 5.05268 7.64651 5.14645C7.55275 5.24022 7.50007 5.36739 7.50007 5.5V7.5H5.50007C5.36746 7.5 5.24028 7.55268 5.14651 7.64645C5.05275 7.74022 5.00007 7.86739 5.00007 8C5.00007 8.13261 5.05275 8.25979 5.14651 8.35355C5.24028 8.44732 5.36746 8.5 5.50007 8.5H7.50007V10.5C7.50007 10.6326 7.55275 10.7598 7.64651 10.8536C7.74028 10.9473 7.86746 11 8.00007 11C8.13268 11 8.25985 10.9473 8.35362 10.8536C8.44739 10.7598 8.50007 10.6326 8.50007 10.5V8.5H10.5001C10.6327 8.5 10.7599 8.44732 10.8536 8.35355C10.9474 8.25979 11.0001 8.13261 11.0001 8C11.0001 7.86739 10.9474 7.74022 10.8536 7.64645C10.7599 7.55268 10.6327 7.5 10.5001 7.5H8.50007V5.5ZM8.00007 2C6.95912 1.99965 5.93598 2.27012 5.0312 2.78485C4.12641 3.29957 3.37111 4.04083 2.83949 4.9358C2.30788 5.83077 2.01825 6.84864 1.99907 7.88942C1.97988 8.93019 2.2318 9.95805 2.73007 10.872L2.02007 13.362C1.99508 13.4494 1.99442 13.542 2.01814 13.6298C2.04187 13.7176 2.08908 13.7972 2.1547 13.8602C2.22033 13.9231 2.30187 13.967 2.39057 13.9871C2.47926 14.0071 2.57175 14.0026 2.65807 13.974L4.99607 13.195C5.79293 13.6555 6.68504 13.9265 7.60338 13.987C8.52173 14.0475 9.44169 13.896 10.2921 13.5441C11.1425 13.1922 11.9006 12.6494 12.5077 11.9577C13.1147 11.266 13.5545 10.4439 13.7931 9.555C14.0316 8.6661 14.0624 7.73425 13.8832 6.83153C13.704 5.92882 13.3195 5.07943 12.7594 4.34908C12.1994 3.61873 11.4789 3.027 10.6536 2.61967C9.82834 2.21233 8.92041 2.00031 8.00007 2ZM3.00007 8C3.00023 6.8906 3.36935 5.81277 4.04931 4.93618C4.72928 4.05959 5.68146 3.43403 6.75597 3.15799C7.83048 2.88195 8.96627 2.97111 9.98455 3.41142C11.0028 3.85174 11.8457 4.6182 12.3806 5.59015C12.9155 6.5621 13.1119 7.68433 12.9389 8.78017C12.766 9.876 12.2335 10.8832 11.4253 11.6432C10.6172 12.4032 9.57917 12.8728 8.47478 12.9782C7.3704 13.0835 6.26234 12.8185 5.32507 12.225C5.26237 12.1853 5.19161 12.16 5.11793 12.151C5.04424 12.142 4.96948 12.1495 4.89907 12.173L3.24107 12.726L3.75107 10.945C3.76965 10.8794 3.77462 10.8107 3.76568 10.7431C3.75674 10.6755 3.73407 10.6105 3.69907 10.552C3.24112 9.77954 2.99967 8.898 3.00007 8Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const BroadcastIcon = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg width={size} height={size} viewBox=\"0 0 20 20\" fill=\"none\">\r\n      <path\r\n        d=\"M14.158 1.02584C14.2838 1.06763 14.3879 1.15768 14.4474 1.2762C14.5068 1.39472 14.5167 1.532 14.475 1.65784L13.975 3.15784C13.9331 3.28382 13.8428 3.38799 13.7241 3.44744C13.6054 3.50689 13.468 3.51675 13.342 3.47484C13.216 3.43294 13.1118 3.34271 13.0524 3.224C12.9929 3.10529 12.9831 2.96782 13.025 2.84184L13.525 1.34184C13.5458 1.27951 13.5786 1.22189 13.6217 1.17226C13.6648 1.12264 13.7172 1.08199 13.776 1.05265C13.8348 1.0233 13.8988 1.00582 13.9643 1.00123C14.0299 0.996627 14.0957 1.00499 14.158 1.02584ZM17.855 2.85384C17.9014 2.80736 17.9382 2.75218 17.9633 2.69147C17.9884 2.63075 18.0013 2.56569 18.0013 2.49999C18.0012 2.43429 17.9882 2.36925 17.963 2.30857C17.9379 2.24789 17.901 2.19277 17.8545 2.14634C17.808 2.09992 17.7528 2.06311 17.6921 2.03801C17.6314 2.01291 17.5663 2.00002 17.5006 2.00007C17.4349 2.00011 17.3699 2.0131 17.3092 2.03828C17.2485 2.06347 17.1934 2.10036 17.147 2.14684L15.147 4.14684C15.0559 4.24115 15.0055 4.36745 15.0066 4.49855C15.0078 4.62964 15.0604 4.75505 15.1531 4.84775C15.2458 4.94046 15.3712 4.99304 15.5023 4.99418C15.6334 4.99532 15.7597 4.94492 15.854 4.85384L17.855 2.85384ZM7.60698 3.14584C7.74648 2.85208 7.95551 2.59676 8.21596 2.40201C8.47641 2.20726 8.78042 2.07897 9.10164 2.02824C9.42287 1.97751 9.75162 2.00587 10.0594 2.11088C10.3672 2.21589 10.6447 2.39436 10.868 2.63084L17.455 9.61084C17.6748 9.84373 17.8355 10.126 17.9235 10.4339C18.0115 10.7418 18.0243 11.0663 17.9608 11.3802C17.8973 11.6941 17.7594 11.9882 17.5586 12.2376C17.3578 12.4871 17.1 12.6847 16.807 12.8138L12.87 14.5498C13.0159 15.0703 13.0395 15.6175 12.9387 16.1486C12.838 16.6797 12.6158 17.1803 12.2895 17.6113C11.9631 18.0422 11.5415 18.3918 11.0576 18.6327C10.5736 18.8736 10.0405 18.9992 9.49998 18.9998C8.90423 19 8.31831 18.848 7.7977 18.5584C7.27709 18.2688 6.83902 17.8511 6.52498 17.3448L5.32498 17.8738C5.04921 17.9953 4.74326 18.0308 4.447 17.9759C4.15073 17.921 3.87787 17.7781 3.66398 17.5658L2.44198 16.3558C2.22101 16.137 2.07355 15.8549 2.01998 15.5485C1.96641 15.2421 2.00939 14.9267 2.14298 14.6458L7.60698 3.14584ZM7.45298 16.9348C7.78487 17.4086 8.27081 17.7527 8.82797 17.9083C9.38512 18.064 9.97901 18.0216 10.5084 17.7884C11.0378 17.5552 11.4699 17.1456 11.7312 16.6294C11.9924 16.1133 12.0665 15.5225 11.941 14.9578L7.45298 16.9348ZM10.141 3.31784C10.0294 3.19969 9.89068 3.11052 9.73687 3.05805C9.58305 3.00557 9.41877 2.99137 9.25823 3.01669C9.0977 3.042 8.94575 3.10605 8.81555 3.20331C8.68534 3.30057 8.5808 3.42809 8.51098 3.57484L3.04598 15.0748C3.00172 15.1684 2.98757 15.2733 3.00548 15.3752C3.02339 15.4772 3.07248 15.571 3.14598 15.6438L4.36798 16.8548C4.4393 16.9253 4.53016 16.9728 4.62878 16.991C4.7274 17.0091 4.8292 16.9973 4.92098 16.9568L16.403 11.8998C16.5495 11.8354 16.6784 11.7366 16.7788 11.612C16.8793 11.4873 16.9483 11.3404 16.9801 11.1835C17.012 11.0266 17.0057 10.8644 16.9618 10.7105C16.9179 10.5565 16.8377 10.4154 16.728 10.2988L10.141 3.31784ZM17 5.99985C16.8674 5.99985 16.7402 6.05252 16.6464 6.14629C16.5527 6.24006 16.5 6.36724 16.5 6.49985C16.5 6.63245 16.5527 6.75963 16.6464 6.8534C16.7402 6.94717 16.8674 6.99985 17 6.99985H18.5C18.6326 6.99985 18.7598 6.94717 18.8535 6.8534C18.9473 6.75963 19 6.63245 19 6.49985C19 6.36724 18.9473 6.24006 18.8535 6.14629C18.7598 6.05252 18.6326 5.99985 18.5 5.99985H17Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const ArrowRight = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg width={size} height={size * 2} viewBox=\"0 0 12 24\" fill=\"none\">\r\n      <path\r\n        fillRule=\"evenodd\"\r\n        clipRule=\"evenodd\"\r\n        d=\"M10.1569 12.7111L4.49994 18.3681L3.08594 16.9541L8.03594 12.0041L3.08594 7.05414L4.49994 5.64014L10.1569 11.2971C10.3444 11.4847 10.4497 11.739 10.4497 12.0041C10.4497 12.2693 10.3444 12.5236 10.1569 12.7111Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n\r\nexport const ChatIconOutlined = (props: Icon) => {\r\n  const { size = 25, color = \"black\" } = props;\r\n  return (\r\n    <svg\r\n      width={size}\r\n      height={size}\r\n      viewBox=\"0 0 16 16\"\r\n      fill=\"none\"\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n    >\r\n      <path\r\n        d=\"M10.75 7C10.75 7.13261 10.6973 7.25979 10.6036 7.35355C10.5098 7.44732 10.3826 7.5 10.25 7.5H6C5.86739 7.5 5.74021 7.44732 5.64645 7.35355C5.55268 7.25979 5.5 7.13261 5.5 7C5.5 6.86739 5.55268 6.74021 5.64645 6.64645C5.74021 6.55268 5.86739 6.5 6 6.5H10.25C10.3826 6.5 10.5098 6.55268 10.6036 6.64645C10.6973 6.74021 10.75 6.86739 10.75 7ZM10.25 8.5H6C5.86739 8.5 5.74021 8.55268 5.64645 8.64645C5.55268 8.74021 5.5 8.86739 5.5 9C5.5 9.13261 5.55268 9.25979 5.64645 9.35355C5.74021 9.44732 5.86739 9.5 6 9.5H10.25C10.3826 9.5 10.5098 9.44732 10.6036 9.35355C10.6973 9.25979 10.75 9.13261 10.75 9C10.75 8.86739 10.6973 8.74021 10.6036 8.64645C10.5098 8.55268 10.3826 8.5 10.25 8.5ZM14.5 7.75C14.4982 9.40704 13.8391 10.9957 12.6674 12.1674C11.4957 13.3391 9.90704 13.9982 8.25 14H3C2.73478 14 2.48043 13.8946 2.29289 13.7071C2.10536 13.5196 2 13.2652 2 13V7.75C2 6.0924 2.65848 4.50268 3.83058 3.33058C5.00268 2.15848 6.5924 1.5 8.25 1.5C9.9076 1.5 11.4973 2.15848 12.6694 3.33058C13.8415 4.50268 14.5 6.0924 14.5 7.75ZM13.5 7.75C13.5 6.35761 12.9469 5.02226 11.9623 4.03769C10.9777 3.05312 9.64239 2.5 8.25 2.5C6.85761 2.5 5.52226 3.05312 4.53769 4.03769C3.55312 5.02226 3 6.35761 3 7.75V13H8.25C9.64193 12.9985 10.9764 12.4449 11.9607 11.4607C12.9449 10.4764 13.4985 9.14193 13.5 7.75Z\"\r\n        fill={color}\r\n      />\r\n    </svg>\r\n  );\r\n};\r\n","import React from 'react'\r\nimport './loaders.css'\r\n\r\nexport function LinearLoader() {\r\n  return (\r\n    <div className=\"loader\" />\r\n  )\r\n}\r\n","import React, {\r\n  Dispatch,\r\n  Ref,\r\n  useMemo,\r\n  SetStateAction,\r\n  createRef,\r\n  useCallback,\r\n  useEffect,\r\n  useRef,\r\n  useState,\r\n  useLayoutEffect,\r\n  forwardRef,\r\n} from \"react\";\r\nimport styles from \"./message-list.module.css\";\r\nimport ChatClient, { Message } from \"softchatjs-core\";\r\nimport { MessageItem, TypingIndicator } from \"../message-item\";\r\nimport Text from \"../text/text\";\r\nimport { formatSectionTime } from \"../../helpers/date\";\r\nimport { useChatState } from \"../../providers/clientStateProvider\";\r\nimport Avartar from \"../avartar/avartar\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { MdOutlineMenu } from \"react-icons/md\";\r\nimport moment from \"moment\";\r\n\r\ntype MessageListProps = {\r\n  messages: Message[];\r\n  setEditDetails: Dispatch<\r\n    SetStateAction<\r\n      | { message: Message; isEditing?: boolean; isReplying?: boolean }\r\n      | undefined\r\n    >\r\n  >;\r\n  recipientTyping?: boolean;\r\n  mousePosition: {\r\n    x: number;\r\n    y: number;\r\n  };\r\n  customHeight?: number;\r\n  client: ChatClient | null;\r\n  conversationId: string;\r\n  textInputRef: any;\r\n  setPresentPage: Dispatch<SetStateAction<number>>;\r\n  presentPage: number;\r\n  setMainListOpen: any;\r\n  recipientId: string;\r\n  scrollToKey: string;\r\n  fetchingMore: boolean;\r\n  messagesEndRef: any;\r\n  renderChatBubble?: (message: Message) => JSX.Element;\r\n  renderChatHeader?: () => JSX.Element;\r\n  headerHeightOffset: number;\r\n  getOlderMessages: (func: () => void) => void;\r\n};\r\n\r\nconst MessageList = (props: MessageListProps) => {\r\n  const {\r\n    messages = [],\r\n    setEditDetails,\r\n    recipientTyping,\r\n    mousePosition,\r\n    conversationId,\r\n    client,\r\n    textInputRef,\r\n    setPresentPage,\r\n    presentPage,\r\n    recipientId,\r\n    scrollToKey,\r\n    fetchingMore,\r\n    messagesEndRef,\r\n    renderChatBubble,\r\n    renderChatHeader,\r\n    headerHeightOffset,\r\n    getOlderMessages,\r\n    customHeight\r\n  } = props;\r\n\r\n  const ref = useRef<HTMLDivElement>()\r\n  const [showOptions, setShowOPtions] = useState(false);\r\n  const [showEmojiPanel, setShowEmojiPanel] = useState(false);\r\n  const [activeIndex, setActiveIndex] = useState(\"\");\r\n  const [quoteId, setQuoteId] = useState(\"\");\r\n  const optionsMenuRef: any = useRef(null);\r\n  const emojiPickerRef: any = useRef(null);\r\n  // const ref: any = useRef<HTMLDivElement>(null);\r\n  const [refMap, setRefMap] = useState<{ [key: string]: any }>({});\r\n  const { activeConversation } = useChatState();\r\n  const { config } = useChatClient();\r\n  const [messagesPrepared, setMessagesPrepared] = useState(false);\r\n\r\n  const itemRefs = useRef<Record<string, HTMLDivElement>>({});\r\n  const theme = config.theme;\r\n  const textColor = config?.theme?.text?.primary || \"white\";\r\n  var scrollDebounce: NodeJS.Timeout | null = null\r\n\r\n  function calculateHeight() {\r\n    // Get the viewport height in pixels\r\n    const viewportHeight = window.innerHeight;\r\n  \r\n    // Fixed pixel values in the calculation\r\n    const fixedOffset1 = 80;\r\n    const fixedOffset2 = 60;\r\n  \r\n    // Perform the calculation: (100vh - 80px - 60px - headerHeightOffset)\r\n    const result = viewportHeight - fixedOffset1 - fixedOffset2 - headerHeightOffset;\r\n  \r\n    return result; // This gives you the pixel value of the calculation\r\n  }\r\n\r\n  const handlePress = (event: any, id: string) => {\r\n    event.preventDefault();\r\n    setShowEmojiPanel(false);\r\n    setShowOPtions(true);\r\n    setActiveIndex(id);\r\n  };\r\n\r\n  const closeOpenMenus = (e: any) => {\r\n    if (showOptions && !optionsMenuRef.current?.contains(e.target)) {\r\n      setShowOPtions(false);\r\n    }\r\n    if (showEmojiPanel && !emojiPickerRef.current?.contains(e.target)) {\r\n      setShowEmojiPanel(false);\r\n    }\r\n  };\r\n\r\n  const openEmojiPanel = (id: string) => {\r\n    setShowEmojiPanel(true);\r\n    setActiveIndex(id);\r\n  };\r\n\r\n  useEffect(() => {\r\n    document.addEventListener(\"mousedown\", closeOpenMenus);\r\n  }, [optionsMenuRef, emojiPickerRef, closeOpenMenus]);\r\n\r\n  const scrollToBottom = (isInitial?: boolean) => {\r\n    if (messagesEndRef.current) {\r\n      messagesEndRef.current.scrollIntoView({\r\n        behavior: isInitial === true ? \"instant\" : (\"smooth\" as any),\r\n      });\r\n    }\r\n  };\r\n\r\n  useEffect(() => {\r\n    if (messages.length > 0) {\r\n      messages.map((m) => {\r\n        setRefMap((prev) => {\r\n          const prevRefs = { ...prev };\r\n          prevRefs[m.messageId] = createRef();\r\n          return prevRefs;\r\n        });\r\n      });\r\n    }\r\n  }, [messages]);\r\n\r\n  useEffect(() => {\r\n    scrollToBottom();\r\n  }, [activeConversation]);\r\n\r\n  const scrollToQuote = (id: string) => {\r\n    try {\r\n      setQuoteId(id);\r\n      const selectedRef = refMap[id];\r\n      if (selectedRef.current) {\r\n        selectedRef.current.style.backgroundColor = \"#282c34\";\r\n        selectedRef.current.style.transition = \"0.5s\";\r\n        setTimeout(() => {\r\n          selectedRef.current.style.backgroundColor = \"transparent\";\r\n        }, 1500);\r\n        selectedRef?.current.scrollIntoView({\r\n          behavior: \"smooth\",\r\n          block: \"center\",\r\n        });\r\n      }\r\n    } catch (error) {\r\n      console.log(error);\r\n    }\r\n  };\r\n\r\n  const sectionedMessages = messages.reduce(\r\n    (list: { date: string; messages: Message[] }[], item) => {\r\n      const date = moment(item.createdAt).format(\"MMMM DD, YYYY\");\r\n\r\n      const dateExists = list.find((i) => i.date === date);\r\n\r\n      if (dateExists) {\r\n        dateExists.messages.push(item);\r\n      } else {\r\n        const newRec = {\r\n          date,\r\n          messages: [item],\r\n        };\r\n        list.push(newRec);\r\n      }\r\n\r\n      return list;\r\n    },\r\n    []\r\n  );\r\n\r\n  const handleScroll = () => {\r\n    if (ref.current.scrollTop === 0) {\r\n      const scrollHeightBeforeFetch = ref.current.scrollHeight;\r\n      setPresentPage((prevPage) => prevPage + 1); // Increment page number\r\n      const scrollHeightAfterFetch = ref.current.scrollHeight;\r\n      ref.current.scrollTop = scrollHeightAfterFetch - scrollHeightBeforeFetch;\r\n    }\r\n  };\r\n\r\n  const onScroll = (e: React.UIEvent<HTMLDivElement>) => {\r\n    try {\r\n      const scrollContainer = ref.current;\r\n      const previousScrollHeight = scrollContainer.scrollHeight;\r\n      const previousScrollTop = scrollContainer.scrollTop;\r\n      const { scrollTop } = e.target as HTMLDivElement;\r\n      const containerHeigh = calculateHeight();\r\n      if (scrollTop <= 0) {\r\n        getOlderMessages(() => {});\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message)\r\n    }\r\n  }\r\n  \r\n\r\n  // Get's position of last message before pagination\r\n  useLayoutEffect(() => {\r\n    try {\r\n      if (!scrollToKey || (ref.current as HTMLDivElement).scrollTop !== 0) return;\r\n      if (itemRefs.current[scrollToKey]) {\r\n        itemRefs.current[scrollToKey].scrollIntoView();\r\n      }\r\n    } catch (error) {\r\n      console.error(error.message)\r\n    }\r\n   \r\n  }, [scrollToKey]);\r\n\r\n  const getListHeight = useMemo(() => {\r\n    if(customHeight){\r\n      return `calc(${customHeight}px - 80px - 60px - ${headerHeightOffset}px)`\r\n    }\r\n    return `calc(100vh - 80px - 60px - ${headerHeightOffset}px)`\r\n  },[customHeight])\r\n\r\n  return (\r\n    <div\r\n      ref={ref}\r\n      onScroll={onScroll}\r\n      className={styles.wrapper}\r\n      style={{ height: getListHeight }}\r\n    >\r\n      {fetchingMore && (\r\n        <div className={styles.loading}>\r\n          <Text styles={{ color: \"white\" }} size=\"sm\" text=\"Loading more...\" />\r\n        </div>\r\n      )}\r\n      {sectionedMessages.map((_item, i) => {\r\n        return (\r\n          <div key={i} className={styles.wrapper__sec}>\r\n            <div\r\n              style={{\r\n                justifyContent: \"center\",\r\n                display: \"flex\",\r\n                width: \"100%\",\r\n                alignItems: \"center\",\r\n              }}\r\n              key={`${i}-sec`}\r\n            >\r\n              <div\r\n                style={{\r\n                  flex: 1,\r\n                  height: \".5px\",\r\n                  width: \"100%\",\r\n                  backgroundColor: theme?.divider,\r\n                }}\r\n              />\r\n              <div\r\n                style={{\r\n                  backgroundColor:\r\n                    config?.theme?.background?.secondary || \"#1b1d21\",\r\n                }}\r\n                className={styles.wrapper__date}\r\n              >\r\n                <Text\r\n                  styles={{ color: textColor }}\r\n                  size=\"xs\"\r\n                  text={formatSectionTime(_item.date)}\r\n                />\r\n              </div>\r\n              <div\r\n                style={{\r\n                  flex: 1,\r\n                  height: \".5px\",\r\n                  width: \"100%\",\r\n                  backgroundColor: theme?.divider,\r\n                }}\r\n              />\r\n            </div>\r\n\r\n            {_item.messages.map((item, index) => (\r\n              <div\r\n                ref={(el: HTMLDivElement) =>\r\n                  (itemRefs.current[item.messageId] = el)\r\n                }\r\n              >\r\n                <div ref={refMap[item?.messageId]}>\r\n                  {props.renderChatBubble ? (\r\n                    props.renderChatBubble(item)\r\n                  ) : (\r\n                    <MessageItem\r\n                      hideAvartar={\r\n                        item.messageOwner.uid ===\r\n                        _item.messages[index + 1]?.messageOwner.uid\r\n                      }\r\n                      textInputRef={textInputRef}\r\n                      show={showOptions && activeIndex == item.messageId}\r\n                      showEmojiPanel={\r\n                        showEmojiPanel && activeIndex == item.messageId\r\n                      }\r\n                      index={index}\r\n                      key={index}\r\n                      message={item}\r\n                      onPress={(e) => handlePress(e, item.messageId)}\r\n                      setEditDetails={setEditDetails}\r\n                      canEdit={item.from === client?.chatUserId}\r\n                      openEmojiPanel={() => openEmojiPanel(item.messageId)}\r\n                      optionsMenuRef={optionsMenuRef}\r\n                      emojiPickerRef={emojiPickerRef}\r\n                      mousePosition={mousePosition}\r\n                      client={client}\r\n                      conversationId={conversationId}\r\n                      closeOptionsMenu={() => setShowOPtions(false)}\r\n                      scrollToQuote={scrollToQuote}\r\n                      recipientId={recipientId}\r\n                      setShowEmojiPanel={setShowEmojiPanel}\r\n                    />\r\n                  )}\r\n                </div>\r\n              </div>\r\n            ))}\r\n          </div>\r\n        );\r\n      })}\r\n      {recipientTyping && (\r\n        <TypingIndicator message={sectionedMessages[0]?.messages[0]} />\r\n      )}\r\n      <div ref={messagesEndRef} style={{ height: \"1px\", width: \"100%\" }} />\r\n    </div>\r\n  );\r\n}\r\n\r\nexport default MessageList;\r\n","import React, { useEffect, useState } from \"react\";\r\n\r\nimport styles from \"./avartar.module.css\";\r\nimport { Message } from \"softchatjs-core\";\r\nimport Text from \"../text/text\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\n\r\nconst Avartar = ({\r\n  initials,\r\n  url,\r\n  size = 35,\r\n}: {\r\n  initials: string;\r\n  url?: string;\r\n  size?: number;\r\n}) => {\r\n  const { client, config } = useChatClient();\r\n\r\n  if (!url) {\r\n    return (\r\n      <div\r\n        className={styles.avatar}\r\n        style={{ height: size, width: size, borderRadius: size, backgroundColor: config.theme.background.disabled }}\r\n      >\r\n        <p\r\n          style={{\r\n            fontSize: 35 * 0.5,\r\n            fontWeight: \"bold\",\r\n            textTransform: \"capitalize\",\r\n            color: config.theme.text.secondary\r\n          }}\r\n        >\r\n          {initials}\r\n        </p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <div\r\n      className={styles.avatar}\r\n      style={{ height: size, width: size, borderRadius: size }}\r\n    >\r\n      <img\r\n        src={url}\r\n        alt=\"avatar\"\r\n        style={{ height: \"100%\", width: \"100%\", borderRadius: \"100%\" }}\r\n      />\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default Avartar;\r\n","import React, {\r\n  Dispatch,\r\n  SetStateAction,\r\n  useContext,\r\n  useEffect,\r\n  useState,\r\n} from \"react\";\r\nimport Avartar from \"../avartar/avartar\";\r\n\r\nimport styles from \"./message-item.module.css\";\r\nimport ChatClient, { Message } from \"softchatjs-core\";\r\nimport Text from \"../text/text\";\r\nimport dayjs from \"dayjs\";\r\nimport { formatMessageTime } from \"../../helpers/date\";\r\nimport OptionsPanel from \"../options-panel/options-panel\";\r\nimport { EmojiPanel, ReactionPanel } from \"../emoji\";\r\nimport { Media, Reaction } from \"softchatjs-core\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { ThreeDots } from \"react-loader-spinner\";\r\nimport { BsCheck, BsCheckAll, BsClock, BsX } from \"react-icons/bs\";\r\nimport { useChatState } from \"../../providers/clientStateProvider\";\r\nimport { MessageStates } from \"softchatjs-core\";\r\nimport AudioPlayer from \"../audio/audio-player\";\r\n\r\nexport const regex = {\r\n  URL_REGEX:\r\n    /^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,8}(:[0-9]{1,5})?(\\/.*)?$/gm,\r\n};\r\n\r\ntype ConversationProps = {\r\n  message: Message;\r\n  index: number;\r\n  onPress: (event: any, index: number, message: Message) => void;\r\n  show: boolean;\r\n  setEditDetails: Dispatch<\r\n    SetStateAction<\r\n      | { message: Message; isEditing?: boolean; isReplying?: boolean }\r\n      | undefined\r\n    >\r\n  >;\r\n  canEdit?: boolean;\r\n  recipientTyping?: boolean;\r\n  showEmojiPanel?: boolean;\r\n  openEmojiPanel: () => void;\r\n  optionsMenuRef: any;\r\n  emojiPickerRef: any;\r\n  mousePosition: {\r\n    x: number;\r\n    y: number;\r\n  };\r\n  client: ChatClient;\r\n  conversationId: string;\r\n  closeOptionsMenu: () => void;\r\n  scrollToQuote: (id: string) => void;\r\n  textInputRef: any;\r\n  recipientId: string;\r\n  hideAvartar: boolean;\r\n  setShowEmojiPanel: Dispatch<SetStateAction<boolean>>;\r\n};\r\n\r\nexport const MessageItem = (props: ConversationProps) => {\r\n  const {\r\n    message,\r\n    index,\r\n    onPress,\r\n    show,\r\n    setEditDetails,\r\n    canEdit,\r\n    showEmojiPanel,\r\n    openEmojiPanel,\r\n    optionsMenuRef,\r\n    emojiPickerRef,\r\n    mousePosition,\r\n    client,\r\n    conversationId,\r\n    closeOptionsMenu,\r\n    scrollToQuote,\r\n    textInputRef,\r\n    recipientId,\r\n    hideAvartar,\r\n  } = props;\r\n\r\n  const hasAttachments = message?.attachedMedia?.length;\r\n  const { config } = useChatClient();\r\n  const stacked = true;\r\n  var chatUserId = client.chatUserId\r\n\r\n  const oppositBubbleBoxes = message.messageOwner.uid === chatUserId && stacked;\r\n\r\n  const chatBoxColor =\r\n    message.messageOwner.uid === chatUserId\r\n      ? config.theme?.chatBubble?.right?.bgColor\r\n      : config.theme?.chatBubble?.left?.bgColor || \"#343434\";\r\n\r\n  const messageColor =\r\n    message.messageOwner.uid === chatUserId\r\n      ? config.theme?.chatBubble?.right?.messageColor\r\n      : config.theme?.chatBubble?.left?.messageColor || \"white\";\r\n\r\n  const messageDateColor =\r\n    message.messageOwner.uid === chatUserId\r\n      ? config.theme?.chatBubble?.right?.messageTimeColor\r\n      : config.theme?.chatBubble?.left?.messageTimeColor || \"grey\";\r\n\r\n  const messageState = () => {\r\n    if (message.messageState === MessageStates.SENT) {\r\n      return <BsCheck style={{ marginTop: \"8px\", color: \"grey\" }} />;\r\n    }\r\n    if (\r\n      message.messageState === MessageStates.DELIVERED ||\r\n      message.messageState === MessageStates.READ\r\n    ) {\r\n      return <BsCheckAll style={{ marginTop: \"8px\", color: \"grey\" }} />;\r\n    }\r\n    if (message.messageState === MessageStates.LOADING) {\r\n      return <BsClock style={{ marginTop: \"8px\", color: \"grey\" }} />;\r\n    }\r\n    if (message.messageState === MessageStates.FAILED) {\r\n      return <BsX style={{ marginTop: \"8px\", color: \"red\" }} />;\r\n    }\r\n    return <BsClock style={{ marginTop: \"8px\", color: \"grey\" }} />;\r\n  };\r\n\r\n  return (\r\n    <div\r\n      className={`${styles.conversation}`}\r\n      onContextMenu={(event) => {\r\n        onPress(event, index, message);\r\n      }}\r\n    >\r\n      <div\r\n        className={`${\r\n          oppositBubbleBoxes\r\n            ? styles.conversation__wrapper__alternate\r\n            : styles.conversation__wrapper\r\n        }`}\r\n      >\r\n        {!oppositBubbleBoxes && (\r\n          <div className={styles.conversation__image}>\r\n            {hideAvartar ? null : (\r\n              <Avartar\r\n                initials={message.messageOwner.username.substring(0, 1)}\r\n                url={message.messageOwner.profileUrl}\r\n              />\r\n            )}\r\n          </div>\r\n        )}\r\n\r\n        <div\r\n          style={{\r\n            display: \"flex\",\r\n            alignItems: \"flex-start\",\r\n            flexDirection: \"column\",\r\n            justifyContent: \"flex-start\",\r\n          }}\r\n        >\r\n          {showEmojiPanel ? (\r\n            <EmojiPanel\r\n              conversationId={conversationId}\r\n              client={client}\r\n              emojiPickerRef={emojiPickerRef}\r\n              message={message}\r\n              recipientId={recipientId}\r\n              setShowEmojiPanel={props.setShowEmojiPanel}\r\n            />\r\n          ) : null}\r\n          <div className={styles.conversation__text__container}>\r\n            {oppositBubbleBoxes && (\r\n              <div className={styles.conversation__text__container__reactions}>\r\n                <ReactionPanel\r\n                  textInputRef={textInputRef}\r\n                  optionsMenuRef={optionsMenuRef}\r\n                  canEdit={canEdit}\r\n                  message={message}\r\n                  setEditDetails={setEditDetails}\r\n                  openEmojiPanel={openEmojiPanel}\r\n                  mousePosition={mousePosition}\r\n                  client={client}\r\n                  conversationId={conversationId}\r\n                  closeOptionsMenu={closeOptionsMenu}\r\n                />\r\n              </div>\r\n            )}\r\n            <div style={{ display: 'flex', alignItems: 'flex-end' }}>\r\n            <div\r\n              style={{ backgroundColor: chatBoxColor }}\r\n              className={`${styles.conversation__text__wrap} ${\r\n                hasAttachments\r\n                  ? styles.conversation__text__wrap__attach\r\n                  : styles.conversation__text__wrap__no__attach\r\n              } ${\r\n                hideAvartar\r\n                  ? styles.conversation__text__wrap__half__border\r\n                  : `${\r\n                      oppositBubbleBoxes\r\n                        ? styles.conversation__text__wrap__border__alternate\r\n                        : styles.conversation__text__wrap__border\r\n                    }`\r\n              }`}\r\n            >\r\n              {message.quotedMessageId && (\r\n                <QuotedMessage\r\n                  scrollToQuote={scrollToQuote}\r\n                  message={message?.quotedMessage as any}\r\n                />\r\n              )}\r\n              {hasAttachments ? (\r\n                <AttachmentList attachments={message.attachedMedia} />\r\n              ) : null}\r\n              {message.message ? (\r\n                <div\r\n                  style={{\r\n                    alignItems: \"center\",\r\n                    paddingLeft: hasAttachments && \"10px\",\r\n                    paddingRight: hasAttachments && \"10px\",\r\n                    justifyContent: \"space-between\",\r\n                    wordWrap: 'break-word',\r\n                  }}\r\n                >\r\n                  <Text\r\n                    styles={{\r\n                      textAlign: \"left\",\r\n                      marginRight: \"15px\",\r\n                      color: messageColor,\r\n                    }}\r\n                    size=\"sm\"\r\n                    text={message?.message}\r\n                  />\r\n                  <div\r\n                    style={{\r\n                      display: \"flex\",\r\n                      justifyContent: \"flex-end\",\r\n                      alignItems: \"center\",\r\n                      marginTop:\r\n                        message?.message?.length > 10 ? \"0px\" : \"-25px\",\r\n                    }}\r\n                  >\r\n                    {message.lastEdited && (\r\n                      <Text\r\n                        styles={{\r\n                          textAlign: \"right\",\r\n                          marginRight: \"5px\",\r\n                          color: messageDateColor,\r\n                          fontSize: \"9px\",\r\n                        }}\r\n                        size=\"sm\"\r\n                        text={\"(Edited)\"}\r\n                      />\r\n                    )}\r\n                    <Text\r\n                      size=\"xs\"\r\n                      styles={{ color: messageDateColor }}\r\n                      text={formatMessageTime(message.createdAt as string)}\r\n                    />\r\n                    {oppositBubbleBoxes && <>{messageState()}</>}\r\n                  </div>\r\n                </div>\r\n              ) : null}\r\n            </div>\r\n            {/* {!hideAvartar && (\r\n              \r\n            )} */}\r\n            {/* <div style={{ height: '20px', width: '20px', backgroundColor: hideAvartar? 'transparent' : chatBoxColor }}>\r\n              <div style={{ backgroundColor: hideAvartar? 'transparent' : config.theme.background.primary, height: '100%', width: '100%', borderBottomLeftRadius: '15px' }} />\r\n            </div> */}\r\n\r\n            </div>\r\n            {!oppositBubbleBoxes && (\r\n              <div className={styles.conversation__text__container__reactions}>\r\n                <ReactionPanel\r\n                  textInputRef={textInputRef}\r\n                  optionsMenuRef={optionsMenuRef}\r\n                  canEdit={canEdit}\r\n                  message={message}\r\n                  setEditDetails={setEditDetails}\r\n                  openEmojiPanel={openEmojiPanel}\r\n                  mousePosition={mousePosition}\r\n                  client={client}\r\n                  conversationId={conversationId}\r\n                  closeOptionsMenu={closeOptionsMenu}\r\n                  // setEditDetails={setEditDetails}\r\n                />\r\n              </div>\r\n            )}\r\n          </div>\r\n\r\n          {/* <div className={styles.conversation__wrapper__emojis}></div> */}\r\n          <div\r\n            style={{\r\n              width: \"100%\",\r\n              display: \"flex\",\r\n              justifyContent: oppositBubbleBoxes ? \"flex-end\" : \"flex-start\",\r\n            }}\r\n          >\r\n            <EmojiList reactions={message.reactions} message={message} />\r\n          </div>\r\n        </div>\r\n      </div>\r\n      {show ? (\r\n        <OptionsPanel\r\n          textInputRef={textInputRef}\r\n          optionsMenuRef={optionsMenuRef}\r\n          canEdit={canEdit}\r\n          message={message}\r\n          setEditDetails={setEditDetails}\r\n          openEmojiPanel={openEmojiPanel}\r\n          mousePosition={mousePosition}\r\n          client={client}\r\n          conversationId={conversationId}\r\n          closeOptionsMenu={closeOptionsMenu}\r\n        />\r\n      ) : null}\r\n    </div>\r\n  );\r\n};\r\n\r\nconst EmojiList = ({\r\n  reactions,\r\n  message,\r\n}: {\r\n  reactions: Reaction[];\r\n  message: Message;\r\n}) => {\r\n  const { client } = useChatClient();\r\n  const { conversationId } = message;\r\n\r\n  const msClient = client.messageClient(conversationId);\r\n\r\n  const deleteReaction = ({ emojiId }: { emojiId: string }) => {\r\n    const filteredEmojis = reactions.filter((i) => i.uid !== emojiId);\r\n    msClient.reactToMessage({\r\n      conversationId,\r\n      messageId: message.messageId,\r\n      reactions: filteredEmojis,\r\n      to: \"30\", // Make this dynamic\r\n    });\r\n  };\r\n  return (\r\n    <div className={styles.emoji}>\r\n      {reactions.map((item, index) => (\r\n        <div\r\n          key={index}\r\n          onClick={() => deleteReaction({ emojiId: item.uid })}\r\n          className={styles.emoji__wrap}\r\n        >\r\n          <p>{item.emoji}</p>\r\n        </div>\r\n      ))}\r\n    </div>\r\n  );\r\n};\r\n\r\nconst AttachmentList = ({ attachments }: { attachments: Media[] }) => {\r\n  const { setShowImageModal } = useChatState();\r\n\r\n  return (\r\n    <div className={styles.attachments}>\r\n      {attachments.map((i, index) => {\r\n        if (i.type === \"image\") {\r\n          return (\r\n            <img\r\n              onClick={() => setShowImageModal(attachments)}\r\n              key={`${index}-attch`}\r\n              src={i.mediaUrl}\r\n              className={styles.image}\r\n              alt=\"attached-images\"\r\n            />\r\n          );\r\n        }\r\n        if (i.type === \"video\") {\r\n          return (\r\n            <video\r\n              onClick={() => setShowImageModal(attachments)}\r\n              key={`${index}-attch`}\r\n              src={i.mediaUrl}\r\n              className={styles.image}\r\n              controls\r\n            />\r\n          );\r\n        }\r\n        if (i.type === \"audio\") {\r\n          // return <audio src={i.mediaUrl} controls />;\r\n          return (\r\n            <AudioPlayer\r\n              url={i?.mediaUrl}\r\n              duration={i?.meta?.audioDurationSec || 0}\r\n              blob={null}\r\n            />\r\n          );\r\n        }\r\n      })}\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const QuotedMessage = ({\r\n  message,\r\n  scrollToQuote,\r\n}: {\r\n  message: Message;\r\n  scrollToQuote: (id: string) => void;\r\n}) => {\r\n  const msg = message?.messageOwner?.username;\r\n  return (\r\n    <div\r\n      className={styles.quote}\r\n      onClick={() => scrollToQuote(message.messageId)}\r\n    >\r\n      <div>\r\n        <Text\r\n          styles={{ color: \"greenyellow\", textAlign: \"left\" }}\r\n          size=\"sm\"\r\n          weight=\"bold\"\r\n          text={msg?.length > 30 ? `${msg?.slice(0, 5)}...` : msg}\r\n        />\r\n        <Text\r\n          size=\"xs\"\r\n          text={message?.message}\r\n          styles={{ textAlign: \"left\" }}\r\n        />\r\n      </div>\r\n      <img src={message?.attachedMedia[0]?.mediaUrl} alt=\"\" />\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const FormattedText = ({ content }: { content: string }) => {\r\n  const lines = content?.split(\"/\");\r\n\r\n  return (\r\n    <>\r\n      {lines?.map((line, lineIndex) => {\r\n        return (\r\n          <div style={{ display: \"flex\" }} key={lineIndex}>\r\n            {line.split(\" \")?.map((word, index) => {\r\n              if (word.match(regex.URL_REGEX)) {\r\n                return (\r\n                  <>\r\n                    <a style={{ textDecoration: \"none\" }} href={word}>\r\n                      <Text\r\n                        key={index}\r\n                        styles={{\r\n                          textAlign: \"left\",\r\n                          marginRight: \"4px\",\r\n                          color: \"#1C9BEF\",\r\n                        }}\r\n                        size=\"sm\"\r\n                        text={word}\r\n                      />\r\n                    </a>\r\n                  </>\r\n                );\r\n              }\r\n\r\n              return (\r\n                <Text\r\n                  styles={{ textAlign: \"left\", marginRight: \"4px\" }}\r\n                  key={index}\r\n                  text={word}\r\n                  size=\"sm\"\r\n                />\r\n              );\r\n            })}\r\n          </div>\r\n        );\r\n      })}\r\n    </>\r\n  );\r\n};\r\n\r\nexport const TypingIndicator = ({ message }: { message: Message }) => {\r\n  return (\r\n    <div className={styles.typing__wrap}>\r\n      <div style={{ marginRight: \"10px\" }}>\r\n        <Avartar\r\n          initials={message.messageOwner.username.substring(0, 1)}\r\n          url={message.messageOwner.profileUrl}\r\n        />\r\n      </div>\r\n\r\n      <ThreeDots\r\n        visible={true}\r\n        height=\"20\"\r\n        width=\"50\"\r\n        color=\"#343434\"\r\n        radius=\"9\"\r\n        ariaLabel=\"three-dots-loading\"\r\n        wrapperClass=\"\"\r\n      />\r\n    </div>\r\n  );\r\n};\r\n","import { Dispatch, SetStateAction, useEffect, useState } from \"react\";\r\nimport Avartar from \"../avartar/avartar\";\r\n\r\nimport styles from \"./options-panel.module.css\";\r\nimport Text from \"../text/text\";\r\nimport ChatClient, { Message } from \"softchatjs-core\";\r\n\r\ntype ConversationListProps = {\r\n  message: Message;\r\n  setEditDetails: Dispatch<\r\n    SetStateAction<\r\n      | { message: Message; isEditing?: boolean; isReplying?: boolean }\r\n      | undefined\r\n    >\r\n  >;\r\n  canEdit?: boolean;\r\n  openEmojiPanel: () => void;\r\n  optionsMenuRef: any;\r\n  mousePosition: {\r\n    x: number;\r\n    y: number;\r\n  };\r\n  conversationId: string;\r\n  client: ChatClient;\r\n  closeOptionsMenu: () => void;\r\n  textInputRef: any;\r\n};\r\n\r\nconst OptionsPanel = (props: ConversationListProps) => {\r\n  const {\r\n    setEditDetails,\r\n    message,\r\n    canEdit,\r\n    openEmojiPanel,\r\n    optionsMenuRef,\r\n    mousePosition: position,\r\n    client,\r\n    conversationId,\r\n    closeOptionsMenu,\r\n    textInputRef,\r\n  } = props;\r\n\r\n  const options = [\r\n    {\r\n      title: \"Edit message\",\r\n      onPress: () => {\r\n        setEditDetails({\r\n          message,\r\n          isEditing: true,\r\n        });\r\n        closeOptionsMenu();\r\n      },\r\n      enabled: canEdit,\r\n    },\r\n\r\n    {\r\n      title: \"Reply\",\r\n      onPress: () => {\r\n        setEditDetails({\r\n          message,\r\n          isReplying: true,\r\n        });\r\n        closeOptionsMenu();\r\n        textInputRef.current?.focus();\r\n      },\r\n      enabled: true,\r\n    },\r\n    {\r\n      title: \"Add reaction\",\r\n      onPress: () => {\r\n        openEmojiPanel();\r\n      },\r\n      enabled: true,\r\n    },\r\n    {\r\n      title: \"Delete\",\r\n      onPress: () => {\r\n        const msClient = client.messageClient(conversationId);\r\n        msClient.deleteMessage(message.messageId, message.to, conversationId);\r\n      },\r\n      enabled: canEdit,\r\n    },\r\n  ];\r\n\r\n  return (\r\n    <div ref={optionsMenuRef} className={`${styles.options}`}>\r\n      <ul>\r\n        {options.map((item, index) => {\r\n          if (item.enabled) {\r\n            return (\r\n              <li key={index} onClick={item.onPress}>\r\n                <Text size=\"sm\" text={item.title} />\r\n              </li>\r\n            );\r\n          }\r\n        })}\r\n      </ul>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport default OptionsPanel;\r\n","import React, {\r\n  Dispatch,\r\n  SetStateAction,\r\n  useContext,\r\n  useEffect,\r\n  useState,\r\n  useCallback,\r\n  useMemo,\r\n} from \"react\";\r\nimport styles from \"./index.module.css\";\r\nimport {\r\n  ChatEventGenerics,\r\n  Conversation,\r\n  MediaType,\r\n  Message,\r\n  UserMeta,\r\n} from \"softchatjs-core\";\r\nimport Text from \"../text/text\";\r\nimport { formatConversationTime, formatWhatsAppDate } from \"../../helpers/date\";\r\nimport {\r\n  ConnectionStatus,\r\n  useChatState,\r\n} from \"../../providers/clientStateProvider\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport Avartar from \"../avartar/avartar\";\r\nimport { MdMessage } from \"react-icons/md\";\r\nimport { FaCheck } from \"react-icons/fa6\";\r\nimport ConversationHeader from \"./ConversationHeader\";\r\nimport { VerifiedIcon } from \"../assets/icons\";\r\nimport { IoCloseCircle } from \"react-icons/io5\";\r\n\r\ntype ConversationItem = {\r\n  conversation: Conversation;\r\n  lastMessage: Message;\r\n  unread: string[];\r\n};\r\n\r\nexport const ConversationList = ({\r\n  setMainListOpen,\r\n  setShowUserList,\r\n  showUserList,\r\n  userListRef,\r\n  renderConversationList,\r\n  connectionStatus,\r\n  resetState,\r\n}: {\r\n  setMainListOpen: any;\r\n  setShowUserList: Dispatch<SetStateAction<boolean>>;\r\n  showUserList: boolean;\r\n  userListRef: any;\r\n  renderConversationList?: (props: {\r\n    conversations: ConversationItem[];\r\n    onCoversationItemClick: (conversationItem: ConversationItem) => void;\r\n  }) => JSX.Element;\r\n  connectionStatus: ConnectionStatus;\r\n  resetState: () => void;\r\n}) => {\r\n  const { client, config } = useChatClient();\r\n  const { setActiveConversation, conversations } = useChatState();\r\n  const [searchVal, setSearchVal] = useState(\"\");\r\n\r\n  if (renderConversationList) {\r\n    return (\r\n      <div\r\n        style={{\r\n          width: \"100%\",\r\n          height: \"100%\",\r\n          background: \"green\",\r\n          position: \"relative\",\r\n        }}\r\n      >\r\n        {renderConversationList({\r\n          conversations,\r\n          onCoversationItemClick: (item) => {\r\n            setActiveConversation(item);\r\n            setMainListOpen(false);\r\n          },\r\n        })}\r\n      </div>\r\n    );\r\n  }\r\n\r\n  const filteredConversations = useMemo(() => {\r\n    try {\r\n      const userId = client.chatUserId;\r\n      const data = conversations.filter((c) => {\r\n        const participantMatch = c.conversation.participantList.some(\r\n          (participant) => {\r\n            const username =\r\n              participant.participantDetails.username.toLowerCase();\r\n            const firstname =\r\n              participant.participantDetails?.firstname?.toLowerCase() || \"\";\r\n            const lastname =\r\n              participant.participantDetails?.lastname?.toLowerCase() || \"\";\r\n            const uid = participant.participantDetails?.uid;\r\n\r\n            return (\r\n              uid !== userId &&\r\n              (username.includes(searchVal.toLowerCase()) ||\r\n                firstname.includes(searchVal.toLowerCase()) ||\r\n                lastname.includes(searchVal.toLowerCase()))\r\n            );\r\n          }\r\n        );\r\n        return participantMatch;\r\n      });\r\n\r\n      return data;\r\n    } catch (error) {\r\n      return conversations;\r\n    }\r\n  }, [conversations, searchVal]);\r\n\r\n  return (\r\n    <div\r\n      style={{\r\n        background: config?.theme?.background?.secondary,\r\n        borderRight: `1px solid ${config.theme.divider}`,\r\n      }}\r\n      className={styles.list}\r\n    >\r\n      <ConversationHeader\r\n        connectionStatus={connectionStatus}\r\n        theme={config.theme}\r\n        onTextChange={(val) => setSearchVal(val)}\r\n      />\r\n      {filteredConversations.length === 0 && (\r\n        <div className={styles.list__empty}>\r\n          <Text\r\n            styles={{ textAlign: \"center\", color: config.theme.text.primary }}\r\n            text=\"Start a new conversation.\"\r\n          />\r\n        </div>\r\n      )}\r\n      {filteredConversations.map((item, index) => (\r\n        <ConversationItem\r\n          key={index}\r\n          item={item}\r\n          onClick={() => {\r\n            setActiveConversation(item);\r\n            setMainListOpen(false);\r\n            resetState();\r\n          }}\r\n          borderBottom={\"\"}\r\n        />\r\n      ))}\r\n    </div>\r\n  );\r\n};\r\n\r\nconst ConversationItem = ({\r\n  item,\r\n  onClick,\r\n  borderBottom,\r\n}: {\r\n  item: {\r\n    conversation: Conversation;\r\n    lastMessage: Message;\r\n    unread: string[];\r\n  };\r\n  onClick: () => void;\r\n  borderBottom: string;\r\n}) => {\r\n  const { client, config } = useChatClient();\r\n  const { activeConversation } = useChatState();\r\n\r\n  const user = item.conversation.participantList.filter(\r\n    (p) => p.participantId !== client.chatUserId\r\n  );\r\n\r\n  const textColor = config?.theme?.text?.primary || \"white\";\r\n\r\n  const renderLastMessage = () => {\r\n    if (item.lastMessage?.attachmentType === \"media\") {\r\n      return (\r\n        <div className={styles.media}>\r\n          <img\r\n            src={\r\n              item.lastMessage.attachedMedia.find((i) => i.type === \"image\")\r\n                ?.mediaUrl\r\n            }\r\n            alt=\"\"\r\n          />\r\n          <Text\r\n            styles={{\r\n              textAlign: \"left\",\r\n              color: textColor,\r\n            }}\r\n            size=\"sm\"\r\n            text={\"Media\"}\r\n          />\r\n        </div>\r\n      );\r\n    }\r\n    return (\r\n      <Text\r\n        styles={{ textAlign: \"left\", color: textColor }}\r\n        size=\"sm\"\r\n        text={\r\n          item.lastMessage?.message?.length > 75\r\n            ? item.lastMessage?.message?.substring(0, 75) + \"...\"\r\n            : item.lastMessage?.message\r\n        }\r\n      />\r\n    );\r\n  };\r\n  return (\r\n    <div className={styles.item} onClick={onClick}>\r\n      <div style={{ marginRight: \"10px\" }}>\r\n        {user[0] && (\r\n          <Avartar\r\n            initials={user[0]?.participantDetails?.username?.substring(0, 1)}\r\n            size={40}\r\n            url={user[0]?.participantDetails?.profileUrl}\r\n          />\r\n        )}\r\n      </div>\r\n      <div\r\n        style={{ width: \"100%\", padding: \"20px 0px 20px 0px\", borderBottom }}\r\n      >\r\n        <div\r\n          style={{\r\n            width: \"100%\",\r\n            display: \"flex\",\r\n            alignItems: \"center\",\r\n            justifyContent: \"space-between\",\r\n          }}\r\n        >\r\n          <div style={{ display: \"flex\", alignItems: \"center\" }}>\r\n            <Text\r\n              styles={{\r\n                textAlign: \"left\",\r\n                color: textColor,\r\n                textTransform: \"capitalize\",\r\n                marginRight: \"5px\",\r\n              }}\r\n              weight=\"bold\"\r\n              text={user[0]?.participantDetails?.username}\r\n            />\r\n            {item.conversation.conversationType === (\"admin-chat\" as any) && (\r\n              <VerifiedIcon size={15} color={config.theme.icon} />\r\n            )}\r\n          </div>\r\n\r\n          <Text\r\n            size=\"sm\"\r\n            styles={{ color: textColor }}\r\n            text={formatConversationTime(item.lastMessage?.createdAt as any)}\r\n          />\r\n        </div>\r\n        <div\r\n          style={{\r\n            width: \"100%\",\r\n            display: \"flex\",\r\n            alignItems: \"center\",\r\n            justifyContent: \"space-between\",\r\n          }}\r\n        >\r\n          {renderLastMessage()}\r\n          {item.unread.length > 0 && (\r\n            <div className={styles.unread}>\r\n              <Text\r\n                size=\"xs\"\r\n                text={String(item.unread.length)}\r\n                styles={{ color: \"black\" }}\r\n              />\r\n            </div>\r\n          )}\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n\r\nexport const UserList = ({\r\n  users = [],\r\n  userListRef,\r\n  close,\r\n}: {\r\n  users?: UserMeta[];\r\n  userListRef?: any;\r\n  close: () => void;\r\n}) => {\r\n  const { client, config } = useChatClient();\r\n\r\n  const startConversation = (item: UserMeta) => {\r\n    try {\r\n      const conn = client.newConversation(item, null);\r\n      conn.create(\"Hey there 👋\");\r\n      close();\r\n    } catch (error) {\r\n      console.error(error?.message);\r\n    }\r\n  };\r\n  return (\r\n    <div\r\n      ref={userListRef}\r\n      style={{ background: config?.theme?.background?.secondary || \"#202326\" }}\r\n      className={styles.userList}\r\n    >\r\n      <div\r\n        style={{\r\n          display: \"flex\",\r\n          alignItems: \"center\",\r\n          justifyContent: \"space-between\",\r\n          padding: 15,\r\n        }}\r\n      >\r\n        <Text\r\n          styles={{ color: config?.theme?.text?.primary || \"white\" }}\r\n          text=\"Users\"\r\n        />\r\n        <button\r\n          onClick={close}\r\n          style={{\r\n            backgroundColor: \"transparent\",\r\n            border: 0,\r\n            cursor: \"pointer\",\r\n          }}\r\n        >\r\n          <IoCloseCircle size={22} />\r\n        </button>\r\n      </div>\r\n      <div className={styles.scrollbar} style={{ overflowY: 'scroll', height: '300px' }}>\r\n      {users.map((item, index) => (\r\n        <div\r\n          key={index}\r\n          onClick={() => {\r\n            startConversation(item);\r\n          }}\r\n          className={styles.userList__wrap}\r\n        >\r\n          <Avartar initials={item.username.substring(0,1)} url={item.profileUrl} />\r\n          <div className={styles.userList__user} style={{ marginLeft: '6px' }}>\r\n            <Text\r\n              size=\"sm\"\r\n              text={item.username}\r\n              styles={{ color: config?.theme?.text?.primary || \"white\" }}\r\n            />\r\n          </div>\r\n        </div>\r\n      ))}\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import { ConnectionStatus } from \"@/src/providers/clientStateProvider\";\r\nimport { ReactTheme } from \"@/src/theme/type\";\r\nimport React, { useState } from \"react\";\r\n\r\nexport default function ConversationHeader({\r\n  connectionStatus,\r\n  theme,\r\n  onTextChange\r\n}: {\r\n  connectionStatus: ConnectionStatus;\r\n  theme: ReactTheme;\r\n  onTextChange: (value: string) => void;\r\n}) {\r\n\r\n  const [ value, setValue ] = useState('');\r\n\r\n  const handleTextChange = (value: string) => {\r\n    setValue(value); onTextChange(value)\r\n  }\r\n\r\n  return (\r\n    <div\r\n      style={{\r\n        width: \"100%\",\r\n        padding: \"20px\",\r\n      }}\r\n    >\r\n      <div>\r\n        {connectionStatus.isConnected ? (\r\n          <span\r\n            style={{\r\n              display: \"flex\",\r\n              alignItems: \"center\",\r\n              color: theme.text.primary,\r\n            }}\r\n          >\r\n            {/* Connected{\" \"}\r\n            <div\r\n              style={{\r\n                marginLeft: 10,\r\n                height: \"5px\",\r\n                width: \"5px\",\r\n                borderRadius: \"5px\",\r\n                backgroundColor: \"green\",\r\n              }}\r\n            /> */}\r\n            <p style={{ fontWeight: \"bold\", fontSize: \"26px\" }}>Chats</p>\r\n            <span\r\n              style={{\r\n                marginLeft: 10,\r\n                height: \"5px\",\r\n                width: \"5px\",\r\n                borderRadius: \"5px\",\r\n                backgroundColor: \"green\",\r\n              }}\r\n            /> \r\n          </span>\r\n        ) : (\r\n          <p style={{ color: theme.text.primary }}>Connecting...</p>\r\n        )}\r\n      </div>\r\n      <input \r\n        value={value}\r\n        onChange={e => handleTextChange(e.target.value)}\r\n        placeholder=\"Search chats\"\r\n        style={{ \r\n          height: '40px', \r\n          width: '100%', \r\n          marginTop: '15px', \r\n          textIndent: '15px', \r\n          backgroundColor: 'transparent', \r\n          // color: 'white', \r\n          border: `1px solid ${theme.divider}`, \r\n          borderRadius: '10px',\r\n          color: theme.text.primary\r\n        }}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n","import { useChatState } from \"../../providers/clientStateProvider\";\r\nimport styles from \"./image.module.css\";\r\nimport { GrNext, GrPrevious } from \"react-icons/gr\";\r\nimport { useState } from \"react\";\r\nimport { LiaTimesSolid } from \"react-icons/lia\";\r\n\r\nexport const ImageViewer = () => {\r\n  const { showImageModal, setShowImageModal } = useChatState();\r\n  const [activeIndex, setActiveIndex] = useState(0);\r\n  return (\r\n    <div className={styles.images}>\r\n      <LiaTimesSolid\r\n        color=\"white\"\r\n        size={35}\r\n        onClick={() => {\r\n          setShowImageModal([]);\r\n        }}\r\n        style={{ position: \"absolute\", top: \"20px\", right: \"20px\" }}\r\n      />\r\n      <div className={styles.images__prev}>\r\n        {activeIndex === 0 ? null : (\r\n          <div style={{ padding: \"10px\" }}>\r\n            <GrPrevious\r\n              onClick={() => {\r\n                return setActiveIndex(activeIndex - 1);\r\n              }}\r\n              color=\"white\"\r\n              size={35}\r\n              style={{ cursor: \"pointer\" }}\r\n            />\r\n          </div>\r\n        )}\r\n      </div>\r\n      <div className={styles.images__center}>\r\n        <div className={styles.images__center__items}>\r\n          {showImageModal[activeIndex].type === \"image\" && (\r\n            <img\r\n              onClick={(e) => {\r\n                e.stopPropagation();\r\n              }}\r\n              src={showImageModal[activeIndex].mediaUrl}\r\n              alt=\"\"\r\n            />\r\n          )}\r\n          {showImageModal[activeIndex].type === \"video\" && (\r\n            <video\r\n              onClick={(e) => {\r\n                e.stopPropagation();\r\n              }}\r\n              src={showImageModal[activeIndex].mediaUrl}\r\n             controls\r\n            />\r\n          )}\r\n        </div>\r\n      </div>\r\n      <div className={styles.images__next}>\r\n        {activeIndex === showImageModal.length - 1 ? null : (\r\n          <div style={{ padding: \"10px\" }}>\r\n            <GrNext\r\n              onClick={() => {\r\n                return setActiveIndex(activeIndex + 1);\r\n              }}\r\n              color=\"white\"\r\n              size={35}\r\n              style={{ cursor: \"pointer\" }}\r\n            />\r\n          </div>\r\n        )}\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n","import React from 'react'\r\nimport { ConversationListItem, Message } from 'softchatjs-core';\r\nimport { useChatClient } from '../../providers/chatClientProvider';\r\nimport styles from \"./chat.module.css\";\r\nimport { MdOutlineClose, MdOutlineMenu } from 'react-icons/md';\r\nimport Avartar from '../avartar/avartar';\r\nimport { useChatState } from '../../providers/clientStateProvider';\r\n\r\nexport const ChatTopNav = ({\r\n  setMainListOpen,\r\n  renderChatHeader,\r\n  onClose,\r\n  chatUserId\r\n}: {\r\n  setMainListOpen: any;\r\n  renderChatHeader?: () => JSX.Element;\r\n  onClose: () => void;\r\n  chatUserId: string\r\n}) => {\r\n  const { client, config } = useChatClient();\r\n  const { activeConversation, setActiveConversation } = useChatState();\r\n  const { theme } = config;\r\n\r\n  const conversationTitle = () => {\r\n    try {\r\n      const participantList = activeConversation.conversation.participantList;\r\n      const data = participantList.filter(p => p.participantDetails.uid !== chatUserId)\r\n      return {\r\n        profileUrl: data[0].participantDetails.profileUrl,\r\n        title: data[0].participantDetails.firstname || data[0].participantDetails.username,\r\n      }\r\n    } catch (error) {\r\n      return   {\r\n        profileUrl: \"https://avatar.iran.liara.run/public\",\r\n        title: 'No name'\r\n      }\r\n    }\r\n  }\r\n\r\n  return (\r\n    <div\r\n      style={{ backgroundColor: theme?.background?.secondary || \"#222529\" }}\r\n      className={styles.topnav}\r\n    >\r\n      {renderChatHeader ? (\r\n        renderChatHeader()\r\n      ) : (\r\n        <div\r\n          style={{ paddingLeft: \"10px\", display: \"flex\", justifyContent: 'space-between', width: \"100%\", padding: '15px', alignItems: \"center\" }}\r\n        >\r\n          <Avartar initials={conversationTitle().title.substring(0,1)} url={conversationTitle().profileUrl} />\r\n          <div className={styles.topnav__menu} style={{  }}>\r\n            <MdOutlineClose\r\n              color={theme?.icon}\r\n              onClick={() => {\r\n                setMainListOpen(true);\r\n                setActiveConversation(null);\r\n                onClose()\r\n              }}\r\n              size={22}\r\n            />\r\n          </div>\r\n        </div>\r\n      )}\r\n    </div>\r\n  );\r\n};\r\n","import { useChatClient } from \"@/src/providers/chatClientProvider\";\r\nimport React, { useState, useEffect, useCallback } from \"react\";\r\nimport Avartar from \"../avartar/avartar\";\r\nimport { UserMeta } from \"softchatjs-core\";\r\nimport { BroadcastIcon, ChatIcon, ChatIconOutlined, ChatPlus } from \"../assets/icons\";\r\nimport \"./navigation.css\";\r\nimport { UserList } from \"../user-conversations\";\r\nimport {\r\n  ConnectionStatus,\r\n  useChatState,\r\n} from \"../../providers/clientStateProvider\";\r\n\r\ntype View = \"broadcast-lists\" | \"conversation-list\";\r\n\r\nexport type NavButton = {\r\n  label: string;\r\n  icon: JSX.Element;\r\n  key: string;\r\n  visible: boolean;\r\n  onClick: () => void;\r\n}\r\n\r\nexport default function Navbar(props: {\r\n  chatUser: UserMeta;\r\n  activeView: View;\r\n  userList: UserMeta[];\r\n  onViewChanged: (view: View) => void;\r\n  renderNavbar: (props: NavButton[]) => JSX.Element;\r\n  connectionStatus: ConnectionStatus;\r\n  enableBroadcasts?: boolean\r\n}) {\r\n  const { client, config } = useChatClient();\r\n  const { setActiveConversation } = useChatState();\r\n\r\n  const [menu, showMenu] = useState(false);\r\n\r\n  const navButtons = [\r\n    {\r\n      label: \"Chats\",\r\n      icon: <ChatIconOutlined color={config.theme.icon} size={25} />,\r\n      key: \"conversation-list\",\r\n      onClick: () => {\r\n        props.onViewChanged(\"conversation-list\");\r\n        setActiveConversation(null);\r\n      },\r\n      visible: true\r\n    },\r\n    {\r\n      label: \"New chat\",\r\n      icon: <ChatPlus color={config.theme.icon} size={25} />,\r\n      key: \"new-chat\",\r\n      onClick: () => showMenu(true),\r\n      visible: props.userList.length > 0? true : false\r\n    },\r\n    {\r\n      label: \"Broadcast lists\",\r\n      icon: <BroadcastIcon color={config.theme.icon} size={25} />,\r\n      key: \"broadcast-lists\",\r\n      onClick: () => {\r\n        props.onViewChanged(\"broadcast-lists\");\r\n        setActiveConversation(null);\r\n      },\r\n      visible: props.enableBroadcasts\r\n    },\r\n  ];\r\n\r\n  // useEffect(() => {\r\n  //   document.addEventListener(\"mousedown\", () => showMenu(false));\r\n  // }, []);\r\n\r\n  if (props.renderNavbar) {\r\n    return (\r\n      <div\r\n        style={{\r\n          height: \"100%\",\r\n          maxWidth: \"50px\",\r\n          borderRight: `1px solid ${config.theme.divider}`,\r\n          display: \"flex\",\r\n          flexDirection: \"column\",\r\n          alignItems: \"center\",\r\n        }}\r\n      >\r\n        {props.renderNavbar(navButtons)}\r\n      </div>\r\n    );\r\n  }\r\n\r\n  const renderNavList = useCallback(() => {\r\n    return (\r\n      <>\r\n        {navButtons.filter(b => b.visible).map((nav, i) => (\r\n          <button\r\n            key={i}\r\n            className={`nav-btn`}\r\n            style={{\r\n              borderRight: 0,\r\n              borderTop: 0,\r\n              borderBottom: 0,\r\n              cursor: props.connectionStatus.isConnected? 'pointer' : 'progress',\r\n              borderLeft:\r\n                props.activeView === nav.key\r\n                  ? `2px solid ${config.theme.icon}`\r\n                  : `2px solid ${config.theme.background.secondary}`,\r\n            }}\r\n            title={nav.label}\r\n            onClick={() =>\r\n              props.connectionStatus.isConnected ? nav.onClick() : null\r\n            }\r\n          >\r\n            {nav.icon}\r\n          </button>\r\n        ))}\r\n      </>\r\n    );\r\n  }, [navButtons, config.theme, props.activeView, props.connectionStatus]);\r\n\r\n  return (\r\n    <>\r\n      <div\r\n        style={{\r\n          height: \"100%\",\r\n          width: \"50px\",\r\n          backgroundColor: config.theme.background.secondary,\r\n          borderRight: `1px solid ${config.theme.divider}`,\r\n          display: \"flex\",\r\n          flexDirection: \"column\",\r\n          alignItems: \"center\",\r\n          paddingTop: \"20px\",\r\n          justifyContent: \"space-between\",\r\n        }}\r\n      >\r\n        <label title=\"Me\">\r\n          <Avartar\r\n            url={props.chatUser.profileUrl}\r\n            size={30}\r\n            initials={props.chatUser.username.substring(0, 1)}\r\n          />\r\n        </label>\r\n        <div\r\n          style={{\r\n            display: \"flex\",\r\n            flexDirection: \"column\",\r\n            alignItems: \"center\",\r\n            width: \"100%\",\r\n          }}\r\n        >\r\n          {renderNavList()}\r\n        </div>\r\n      </div>\r\n      {menu && <UserList users={props.userList} userListRef={null} close={() => showMenu(false)} />}\r\n    </>\r\n  );\r\n}\r\n","import React, { useEffect, useState } from \"react\";\r\nimport styles from \"./broadcast-lists.module.css\";\r\nimport Avartar from \"../avartar/avartar\";\r\nimport { ArrowRight, BroadcastIcon } from \"../assets/icons\";\r\nimport { useChatClient } from \"../../providers/chatClientProvider\";\r\nimport { ConversationListItem, ConversationListMeta } from \"softchatjs-core\";\r\nimport Text from \"../text/text\";\r\nimport { useChatState } from \"../../providers/clientStateProvider\";\r\nimport { PiPlusCircle } from \"react-icons/pi\";\r\n\r\nexport default function BroadcastLists(props: { onCreateBroadcastList: () => void; }) {\r\n  const { onCreateBroadcastList } = props;\r\n  const { client, config } = useChatClient();\r\n  const { setActiveConversation } = useChatState();\r\n\r\n  const [broadcastLists, setBroadcastLists] = useState<\r\n    Array<ConversationListItem>\r\n  >([]);\r\n\r\n  const handleBroadcastListMetaChanged = (event: any) => {\r\n    const list = Object.values(event.broadcastListMeta).flat() as ConversationListItem[]\r\n    setBroadcastLists(list);\r\n  };\r\n\r\n  const getBroadcastLists = () => {\r\n    try {\r\n      const res = client.getBroadcastLists();\r\n      const list = Object.values(res).flat();\r\n      setBroadcastLists(list);\r\n    } catch (error) {\r\n      \r\n    }\r\n  }\r\n\r\n  useEffect(() => {\r\n    if (client) {\r\n      getBroadcastLists();\r\n      client.subscribe(\r\n        \"broadcast_list_meta_changed\",\r\n        handleBroadcastListMetaChanged\r\n      );\r\n    }\r\n\r\n    return () => {\r\n      client.unsubscribe(\r\n        \"broadcast_list_meta_changed\",\r\n        handleBroadcastListMetaChanged\r\n      );\r\n    };\r\n  }, [client]);\r\n\r\n  return (\r\n    <main\r\n      className={styles.broadcast_container}\r\n      style={{\r\n        borderRight: `1px solid ${config.theme.divider}`,\r\n        backgroundColor: config.theme.background.secondary,\r\n        padding: '20px'\r\n      }}\r\n    >\r\n      <div\r\n        style={{\r\n          display: \"flex\",\r\n          justifyContent: \"space-between\",\r\n          width: \"100%\",\r\n          alignItems: \"center\",\r\n        }}\r\n      >\r\n        <p style={{ fontWeight: \"bold\", fontSize: \"26px\" }}>Broadcast lists</p>\r\n        <button onClick={() => onCreateBroadcastList?.()} style={{ border: 0, backgroundColor: 'transparent' }}>\r\n          <PiPlusCircle size={22} color={config.theme.icon} />\r\n        </button>\r\n      </div>\r\n\r\n      <div style={{ }}>\r\n        {broadcastLists.length === 0 && (\r\n          <div style={{ flex: 1, height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\r\n            <Text\r\n                styles={{\r\n                  textAlign: \"left\",\r\n                  marginRight: \"15px\",\r\n                  color: config.theme.text.disabled,\r\n                }}\r\n                size=\"sm\"\r\n                text={`No broadcast lists available yet`}\r\n              />\r\n          </div>\r\n        )}\r\n        {broadcastLists.length > 0 &&\r\n          broadcastLists.map((conversation, i) => (\r\n            <div key={i} className={styles.broadcast_item}\r\n              onClick={() => setActiveConversation(conversation)}\r\n            >\r\n              <div>\r\n                <Text\r\n                  styles={{\r\n                    textAlign: \"left\",\r\n                    marginRight: \"15px\",\r\n                    color: config.theme.text.primary,\r\n                  }}\r\n                  size=\"md\"\r\n                  text={conversation.conversation.name}\r\n                />\r\n                <Text\r\n                  styles={{\r\n                    textAlign: \"left\",\r\n                    marginRight: \"15px\",\r\n                    color: config.theme.text.disabled,\r\n                  }}\r\n                  size=\"sm\"\r\n                  text={`${conversation.conversation.participants.length} recipients`}\r\n                />\r\n              </div>\r\n              <ArrowRight size={10} color={config.theme.icon} />\r\n            </div>\r\n          ))}\r\n      </div>\r\n    </main>\r\n  );\r\n}\r\n"],"mappings":"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","names":["useEffect","useRef","useState","useMemo","styles","useEffect","useState","useRef","styles","AttachmentTypes","MediaType","generateId","AiOutlineAudio","AiOutlineDelete","AiOutlinePlus","styles","styles","jsx","Text","props","textWeight","textSize","text_default","AiOutlineClose","createContext","useContext","createContext","useContext","useState","jsx","ChatStateContext","useChatState","ChatStateProvider","children","activeConversation","setActiveConversation","conversations","setConversations","showImageModal","setShowImageModal","connectionStatus","setConnectionStatus","defaulTheme","jsx","ChatClientContext","createContext","defaulTheme","useChatClient","useContext","ChatClientProvider","theme","children","client","ChatStateProvider","jsx","jsxs","EditPanel","props","isEditing","message","isReplying","closePanel","width","config","useChatClient","theme","secondaryColor","textColor","iconColor","styles","text_default","AiOutlineClose","edit_panel_default","useRef","styles","HiPhoto","jsx","jsxs","Menu","props","styles","AttachmentMenu","onChange","setFiles","closeGeneralMenu","fileInputRef","useRef","options","HiPhoto","handleChange","event","files","item","index","text_default","uuidv4","MdCancel","VscSend","CiFaceSmile","EmojiPicker","styles","CiFaceSmile","BsReply","AiOutlineDelete","FiEdit2","jsx","emojis","EmojiPanel","props","client","message","conversationId","recipientId","setShowEmojiPanel","config","useChatClient","bgColor","reactToMessage","emoji","styles","item","index","ReactionPanel","setEditDetails","closeOptionsMenu","textInputRef","openEmojiPanel","canEdit","iconColor","emojiList","CiFaceSmile","BsReply","AiOutlineDelete","InputEmojis","onEmojiPick","EmojiPicker","e","dayjs","moment","localizedFormat","calendarFormat","formatMessageTime","date","formatSectionTime","formatConversationTime","time","now","moment","then","duration","years","months","weeks","days","hours","minutes","convertToMinutes","seconds","_seconds","remainingSeconds","paddedMinutes","paddedSeconds","useState","useEffect","useRef","useCallback","jsx","PlayIcon","props","size","color","jsx","PauseIcon","LockIcon","ChatIcon","VerifiedIcon","ChatPlus","BroadcastIcon","ArrowRight","ChatIconOutlined","FaSpinner","jsx","jsxs","AudioPlayer","props","blob","duration","url","style","audioUrl","setAudioUrl","useState","audioRef","useRef","isPlaying","setIsPlaying","currentTime","setCurrentTime","isLoading","setIsLoading","config","useChatClient","theme","textColor","togglePlayPause","handleLoadedMetadata","handleTimeUpdate","handleEnded","useEffect","renderAction","useCallback","FaSpinner","PauseIcon","PlayIcon","convertToMinutes","IoStopCircleOutline","jsx","LinearLoader","jsx","jsxs","ChatInput","client","conversationId","recipientId","editProps","setEditDetails","recipientTyping","setMenuDetails","menuDetails","generalMenuRef","closeGeneralMenu","textInputRef","renderChatInput","message","setMessage","useState","files","setFiles","showEmojiPicker","setShowEmojiPicker","sending","setSending","isRecording","setIsRecording","audioChunks","setAudioChunks","audioRecorder","setAudioRecorder","inputContainerRef","useRef","voiceMessageDuration","setVoiceMessageDuration","audioBlob","setAudioBlob","audioBlobPLaceHolder","setAudioBlobPlaceHolder","inputContainerWidth","setInputContainerWidth","msClient","config","useChatClient","theme","activeConversation","useChatState","uploading","showUploading","primaryActionColor","inputBg","updateWidth","width","useEffect","prepareAudio","constraints","stream","mediaRecorder","chunks","e","blob","t","err","debounceTimer","idleTimer","uploadMessageAttachment","mediaData","type","res","MediaType","uuidv4","url","generateId","error","reset","sendMessage","AttachmentTypes","sendEditedMessage","broadcastMessage","sendHandler","handleKeyDown","addAudioElement","audio","recordVoiceMessage","stopRecording","cancelAudioAttachments","LockIcon","text_default","styles","IoStopCircleOutline","convertToMinutes","AiOutlineDelete","AudioPlayer","VscSend","LinearLoader","edit_panel_default","ChatAttachments","AiOutlinePlus","AttachmentMenu","CiFaceSmile","AiOutlineAudio","Menu","InputEmojis","cancelAudioAttachment","deleteAttachment","id","imgs","i","MdCancel","item","chat_input_default","useMemo","createRef","useEffect","useRef","useState","useLayoutEffect","styles","styles","jsx","Avartar","initials","url","size","client","config","useChatClient","styles","avartar_default","styles","styles","jsx","OptionsPanel","props","setEditDetails","message","canEdit","openEmojiPanel","optionsMenuRef","position","client","conversationId","closeOptionsMenu","textInputRef","options","styles","item","index","text_default","options_panel_default","ThreeDots","BsCheck","BsCheckAll","BsClock","BsX","MessageStates","Fragment","jsx","jsxs","MessageItem","props","message","index","onPress","show","setEditDetails","canEdit","showEmojiPanel","openEmojiPanel","optionsMenuRef","emojiPickerRef","mousePosition","client","conversationId","closeOptionsMenu","scrollToQuote","textInputRef","recipientId","hideAvartar","hasAttachments","config","useChatClient","stacked","chatUserId","oppositBubbleBoxes","chatBoxColor","messageColor","messageDateColor","messageState","MessageStates","jsx","BsCheck","BsCheckAll","BsClock","BsX","jsxs","styles","event","avartar_default","EmojiPanel","ReactionPanel","QuotedMessage","AttachmentList","text_default","formatMessageTime","Fragment","EmojiList","options_panel_default","reactions","msClient","deleteReaction","emojiId","filteredEmojis","i","item","attachments","setShowImageModal","useChatState","AudioPlayer","msg","TypingIndicator","message","jsxs","styles","jsx","avartar_default","ThreeDots","moment","jsx","jsxs","MessageList","props","messages","setEditDetails","recipientTyping","mousePosition","conversationId","client","textInputRef","setPresentPage","presentPage","recipientId","scrollToKey","fetchingMore","messagesEndRef","renderChatBubble","renderChatHeader","headerHeightOffset","getOlderMessages","customHeight","ref","useRef","showOptions","setShowOPtions","useState","showEmojiPanel","setShowEmojiPanel","activeIndex","setActiveIndex","quoteId","setQuoteId","optionsMenuRef","emojiPickerRef","refMap","setRefMap","activeConversation","useChatState","config","useChatClient","messagesPrepared","setMessagesPrepared","itemRefs","theme","textColor","scrollDebounce","calculateHeight","handlePress","event","id","closeOpenMenus","e","openEmojiPanel","useEffect","scrollToBottom","isInitial","m","prev","prevRefs","createRef","scrollToQuote","selectedRef","error","sectionedMessages","list","item","date","dateExists","i","newRec","handleScroll","scrollHeightBeforeFetch","prevPage","scrollHeightAfterFetch","onScroll","scrollContainer","previousScrollHeight","previousScrollTop","scrollTop","containerHeigh","useLayoutEffect","getListHeight","useMemo","styles","text_default","_item","formatSectionTime","index","el","MessageItem","TypingIndicator","message_list_default","useState","useMemo","styles","useState","jsx","jsxs","ConversationHeader","connectionStatus","theme","onTextChange","value","setValue","handleTextChange","e","IoCloseCircle","jsx","jsxs","ConversationList","setMainListOpen","setShowUserList","showUserList","userListRef","renderConversationList","connectionStatus","resetState","client","config","useChatClient","setActiveConversation","conversations","useChatState","searchVal","setSearchVal","useState","item","filteredConversations","useMemo","userId","c","participant","username","firstname","lastname","styles","ConversationHeader","val","text_default","index","ConversationItem","onClick","borderBottom","activeConversation","user","p","textColor","renderLastMessage","i","avartar_default","VerifiedIcon","formatConversationTime","UserList","users","close","startConversation","error","styles","GrNext","GrPrevious","useState","LiaTimesSolid","jsx","jsxs","ImageViewer","showImageModal","setShowImageModal","useChatState","activeIndex","setActiveIndex","e","styles","MdOutlineClose","jsx","jsxs","ChatTopNav","setMainListOpen","renderChatHeader","onClose","chatUserId","client","config","useChatClient","activeConversation","setActiveConversation","useChatState","theme","conversationTitle","data","p","styles","avartar_default","MdOutlineClose","useState","useCallback","Fragment","jsx","jsxs","Navbar","props","client","config","useChatClient","setActiveConversation","useChatState","menu","showMenu","useState","navButtons","ChatIconOutlined","ChatPlus","BroadcastIcon","renderNavList","useCallback","b","nav","i","avartar_default","UserList","useEffect","useState","styles","PiPlusCircle","jsx","jsxs","BroadcastLists","props","onCreateBroadcastList","client","config","useChatClient","setActiveConversation","useChatState","broadcastLists","setBroadcastLists","useState","handleBroadcastListMetaChanged","event","list","getBroadcastLists","res","useEffect","styles","text_default","conversation","i","ArrowRight","jsx","jsxs","Chat","props","headerHeightOffset","user","userList","onCreateBroadcastList","activeConversationId","webToken","enableBroadcasts","height","width","chatUserId","client","config","useChatClient","activeConversation","showImageModal","setActiveConversation","setConversations","conversations","connectionStatus","setConnectionStatus","useChatState","isConnected","setIsConnected","useState","loadingMessages","setLoadingMessages","fecthingmore","setFetchingMore","messages","setMessages","editDetails","setEditDetails","recipientTyping","setRecipientTyping","presentPage","setpresentPage","mainListOpen","setMainListOpen","showUserList","setShowUserList","scrollToKey","setScrollToKey","messagesEndRef","useRef","forceScrollCount","setForceScrollCount","recipientId","setRecipientId","isSmallScreen","setIsSmallScreen","inputContainerWidth","setInputContainerWidth","view","setView","chatContainerRef","theme","position","setPosition","menuDetails","setMenuDetails","generalMenuRef","textInputRef","userListRef","resetState","closeGeneralMenu","e","getPreSelectedConversation","selectedConveration","error","useEffect","checkScreenSize","screenWidth","screenHeight","checkSize","offsetWidth","offsetHeight","observer","handleMessage","event","prev","handleTypingStarted","handleTypingStopped","handleDeletedMessage","m","handleEditedMessage","item","handleConnectionChanged","handleConversationsListChanged","conversationList","a","b","clearUnread","messageIds","recipients","id","getBroadcastMessages","conversationId","messageList","getMessages","getOlderMessages","func","p","err","chatConverationStyles","useMemo","styles","ChatTopNav","message_list_default","chat_input_default","ImageViewer","Navbar","value","ConversationList","BroadcastLists","ChatIcon","Chat_default"]}