{"version":3,"sources":["../src/utils.ts","../src/fetch.ts","../src/MessageClient.ts"],"sourcesContent":["import moment from 'moment';\r\n\r\nimport { Conversation, StringOrNumber, Participant, ParticipantListInfo, Message, MessageStates, UserMeta } from \"./types\";\r\n\r\nfunction murmurHash3_x64_64(str: string, seed = 0) {\r\n  let h1 = BigInt(seed);\r\n  let h2 = BigInt(seed);\r\n  const c1 = BigInt(\"0x87c37b91114253d5\");\r\n  const c2 = BigInt(\"0x4cf5ad432745937f\");\r\n\r\n  let length = str.length;\r\n  const remainder = length & 15; // length % 16\r\n  const bytes = length - remainder;\r\n\r\n  for (let i = 0; i < bytes; i += 16) {\r\n    let k1 =\r\n      BigInt(str.charCodeAt(i)) |\r\n      (BigInt(str.charCodeAt(i + 1)) << BigInt(8)) |\r\n      (BigInt(str.charCodeAt(i + 2)) << BigInt(16)) |\r\n      (BigInt(str.charCodeAt(i + 3)) << BigInt(24)) |\r\n      (BigInt(str.charCodeAt(i + 4)) << BigInt(32)) |\r\n      (BigInt(str.charCodeAt(i + 5)) << BigInt(40)) |\r\n      (BigInt(str.charCodeAt(i + 6)) << BigInt(48)) |\r\n      (BigInt(str.charCodeAt(i + 7)) << BigInt(56));\r\n\r\n    let k2 =\r\n      BigInt(str.charCodeAt(i + 8)) |\r\n      (BigInt(str.charCodeAt(i + 9)) << BigInt(8)) |\r\n      (BigInt(str.charCodeAt(i + 10)) << BigInt(16)) |\r\n      (BigInt(str.charCodeAt(i + 11)) << BigInt(24)) |\r\n      (BigInt(str.charCodeAt(i + 12)) << BigInt(32)) |\r\n      (BigInt(str.charCodeAt(i + 13)) << BigInt(40)) |\r\n      (BigInt(str.charCodeAt(i + 14)) << BigInt(48)) |\r\n      (BigInt(str.charCodeAt(i + 15)) << BigInt(56));\r\n\r\n    k1 = k1 * c1;\r\n    k1 = (k1 << BigInt(31)) | (k1 >> BigInt(33));\r\n    k1 = k1 * c2;\r\n    h1 ^= k1;\r\n\r\n    h1 = (h1 << BigInt(27)) | (h1 >> BigInt(37));\r\n    h1 = h1 + h2;\r\n    h1 = h1 * BigInt(5) + BigInt(\"0x52dce729\");\r\n\r\n    k2 = k2 * c2;\r\n    k2 = (k2 << BigInt(33)) | (k2 >> BigInt(31));\r\n    k2 = k2 * c1;\r\n    h2 ^= k2;\r\n\r\n    h2 = (h2 << BigInt(31)) | (h2 >> BigInt(33));\r\n    h2 = h1 + h2;\r\n    h2 = h2 * BigInt(5) + BigInt(\"0x38495ab5\");\r\n  }\r\n\r\n  let k1 = BigInt(0);\r\n  let k2 = BigInt(0);\r\n\r\n  switch (remainder) {\r\n    case 15:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 14)) << BigInt(48);\r\n    case 14:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 13)) << BigInt(40);\r\n    case 13:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 12)) << BigInt(32);\r\n    case 12:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 11)) << BigInt(24);\r\n    case 11:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 10)) << BigInt(16);\r\n    case 10:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 9)) << BigInt(8);\r\n    case 9:\r\n      k2 ^= BigInt(str.charCodeAt(bytes + 8));\r\n      k2 = k2 * c2;\r\n      k2 = (k2 << BigInt(33)) | (k2 >> BigInt(31));\r\n      k2 = k2 * c1;\r\n      h2 ^= k2;\r\n    case 8:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 7)) << BigInt(56);\r\n    case 7:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 6)) << BigInt(48);\r\n    case 6:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 5)) << BigInt(40);\r\n    case 5:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 4)) << BigInt(32);\r\n    case 4:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 3)) << BigInt(24);\r\n    case 3:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 2)) << BigInt(16);\r\n    case 2:\r\n      k1 ^= BigInt(str.charCodeAt(bytes + 1)) << BigInt(8);\r\n    case 1:\r\n      k1 ^= BigInt(str.charCodeAt(bytes));\r\n      k1 = k1 * c1;\r\n      k1 = (k1 << BigInt(31)) | (k1 >> BigInt(33));\r\n      k1 = k1 * c2;\r\n      h1 ^= k1;\r\n  }\r\n\r\n  h1 ^= BigInt(length);\r\n  h2 ^= BigInt(length);\r\n\r\n  h1 += h2;\r\n  h2 += h1;\r\n\r\n  h1 ^= h1 >> BigInt(33);\r\n  h1 = h1 * BigInt(\"0xff51afd7ed558ccd\");\r\n  h1 ^= h1 >> BigInt(33);\r\n  h1 = h1 * BigInt(\"0xc4ceb9fe1a85ec53\");\r\n  h1 ^= h1 >> BigInt(33);\r\n\r\n  h2 ^= h2 >> BigInt(33);\r\n  h2 = h2 * BigInt(\"0xff51afd7ed558ccd\");\r\n  h2 ^= h2 >> BigInt(33);\r\n  h2 = h2 * BigInt(\"0xc4ceb9fe1a85ec53\");\r\n  h2 ^= h2 >> BigInt(33);\r\n\r\n  h1 += h2;\r\n  h2 += h1;\r\n\r\n  // Combine h1 and h2 to return a 64-bit hash\r\n  return (h1 & BigInt(\"0xFFFFFFFFFFFFFFFF\")).toString(16);\r\n}\r\n\r\n// Updated generateConversationId using MurmurHash3 x64 (64-bit)\r\nexport function generateConversationId(str1: string, str2: string, projectId: string) {\r\n  // Sort the strings alphabetically to ensure consistency\r\n  const sortedStrings = [str1, str2].sort();\r\n  // Concatenate the sorted strings with a delimiter\r\n  const combinedString = sortedStrings.join(\"_\");\r\n  // Generate a 64-bit hash of the combined string using MurmurHash3 x64\r\n  const hash = murmurHash3_x64_64(`${projectId}:${combinedString}`);\r\n  // Return the hash as the unique ID\r\n  return hash;\r\n}\r\n\r\nexport const generateId = () => {\r\n    let uuid = '';\r\n    const characters = 'abcdef0123456789';\r\n    for (let i = 0; i < 32; i++) {\r\n      const randomNumber = Math.floor(Math.random() * characters.length);\r\n      const character = characters.charAt(randomNumber);\r\n      if (i === 8 || i === 12 || i === 16 || i === 20) {\r\n        uuid += '-';\r\n      }\r\n      uuid += character;\r\n    }\r\n    return uuid;\r\n}\r\n\r\n\r\nexport const getUserInfoWithId = (userId: string, participantList: ParticipantListInfo[]): {\r\n  presentUser: UserMeta | undefined,\r\n  receivingUser: UserMeta | undefined,\r\n} => {\r\n  let presentUser = participantList.find(participant => participant.participantId === userId);\r\n  let otherParticipants = participantList.filter(participant => participant.participantId !== userId)\r\n  return { presentUser: presentUser?.participantDetails, receivingUser: otherParticipants[0]?.participantDetails };\r\n};\r\n\r\nexport const truncate = (str: string, len: number) => {\r\n  return str.length > len ? str.substring(0, len)+'...' : str;\r\n}\r\n\r\nexport const getConversationTitle = (userId: string, converstaion: Conversation) => {\r\n  if(converstaion.conversationType === 'private-chat'){\r\n    const userInfos = getUserInfoWithId(userId, converstaion.participantList);\r\n\r\n    const firstname = userInfos.receivingUser?.firstname\r\n    const username = userInfos.receivingUser?.username\r\n    return firstname? firstname : username\r\n  }\r\n  if(converstaion.conversationType === 'group-chat') {\r\n    return converstaion.groupMeta?.groupName || 'no-groupname'\r\n  }\r\n}\r\n\r\nexport const getUsernameInitials = (username: string) =>{\r\n  return username.substring(0, 1)\r\n}\r\n\r\nexport function formatMessageTime(time: Date | string) {\r\n  return moment(new Date(time)).format(\"hh:mm a\");\r\n}\r\n\r\nexport function formatConversationTime(time: Date | string) {\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 const generateFillerTimestamps = () => {\r\n  return {\r\n    createdAt: new Date(),\r\n    updatedAt: new Date(),\r\n  }\r\n}\r\n\r\nexport const getUnreadMessageIds = (conversation: Conversation, userId: string) => {\r\n  var ids: string[] = []\r\n  conversation.messages.map(m => {\r\n    if (m.messageState === MessageStates.SENT && m.from !== userId) {\r\n      ids.push(m.messageId)\r\n    }\r\n  })\r\n  return ids\r\n}\r\n\r\nexport const getQuotedMessage = (messageId: string, messages: Message[]) => {\r\n  const message = messages.find(msg => msg.messageId === messageId)\r\n  return message\r\n}\r\n","import axios, { AxiosResponse } from \"axios\";\r\nimport { MediaType, Prettify, UploadContent } from \"./types\";\r\n\r\nlet API = \"https://api.softchatjs.com\";\r\n\r\nenum ENDPOINTS {\r\n  CONVERSATIONS = \"/conversations\",\r\n  CONVERSATION = \"/conversation\",\r\n  MESSAGES = \"/messages\",\r\n  UPLOAD = \"/upload\",\r\n  UPLOAD_ATTACHMENT = \"/upload-attachment\",\r\n  CREATE_SESSION = \"/auth/session\",\r\n  EMOJIS = \"/gifs/trending\",\r\n  GET_PRESIGNED_URL = \"/presigned-url\",\r\n  BROADCAST_LIST = \"/broadcastlist\",\r\n  BROADCAST_LISTS = \"/broadcastlists\",\r\n}\r\n\r\ntype Payload = {\r\n  endpoint: string;\r\n  body: Object;\r\n  method: \"GET\" | \"POST\" | \"PUT\";\r\n  token?: string;\r\n  headers?: Record<string, string>;\r\n};\r\n\r\nconst chatApi = async <R>(payload: Payload): Promise<APIResponse<R>> => {\r\n  try {\r\n    const res: AxiosResponse<R> = await axios({\r\n      url: payload.endpoint,\r\n      method: payload.method,\r\n      headers: {\r\n        \"Cache-Control\": \"no-cache\",\r\n        accessToken: payload.token || \"\",\r\n        \"Content-Type\": \"application/json\",\r\n        ...payload.headers,\r\n      },\r\n      data: payload.method === \"POST\" ? payload.body : undefined,\r\n      responseType: \"json\",\r\n      timeout: 30000,\r\n    });\r\n    const response = res.data;\r\n    if (typeof response === \"object\" && response && \"success\" in response) {\r\n      return response as unknown as APIResponse<R>;\r\n    }\r\n    return { ...response, success: false } as unknown as APIResponse<R>;\r\n  } catch (error) {\r\n    console.log(error, \"fetch error\");\r\n    if (axios.isAxiosError(error) && error.response) {\r\n      throw new Error(`HTTP error! Status: ${error.response.status}`);\r\n    }\r\n    throw new Error(\"An unknown error occurred.\");\r\n  }\r\n};\r\n\r\ntype APIResponse<R> = {\r\n  success: boolean;\r\n  data: R;\r\n  message: string;\r\n};\r\n\r\nexport async function CREATE_SESSION<Response>({\r\n  userId,\r\n  subId,\r\n  projectId,\r\n}: {\r\n  userId: string;\r\n  subId: string;\r\n  projectId: string;\r\n}): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.CREATE_SESSION}`,\r\n    body: { userId, projectId, subId },\r\n    method: \"POST\",\r\n    // headers: { \"x-api-key\": apiKey },\r\n  });\r\n}\r\n\r\nexport async function GET_CONVERSATIONS<Response>(\r\n  token: string | undefined,\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.CONVERSATIONS}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_CONVERSATION<Response>(\r\n  token: string | undefined, conversationId: string\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.CONVERSATION}/${conversationId}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_BROADCASTLISTS<Response>(\r\n  token: string | undefined\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.BROADCAST_LISTS}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_MESSAGES<Response>(\r\n  token: string | undefined,\r\n  conversationId: string,\r\n  page?: number\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.MESSAGES}/${conversationId}${page ? \"?page=\" + page : \"\"}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_BROADCAST_LIST_MESSAGES<Response>(\r\n  token: string | undefined,\r\n  broadcastListId: string,\r\n  page?: number\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.BROADCAST_LIST}/messages/${broadcastListId}${page ? \"?page=\" + page : \"\"}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_EMOJIS<Response>(\r\n  token: string | undefined\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.EMOJIS}`,\r\n    body: {},\r\n    method: \"GET\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function UPLOAD_MEDIA<Response>(\r\n  token: string,\r\n  data: Prettify<UploadContent>\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.UPLOAD}`,\r\n    body: data,\r\n    method: \"POST\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function GET_PRESIGNED_URL<Response>(\r\n  token: string,\r\n  data: Prettify<UploadContent & { mediaType: string, uid: string, ext: string }>\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.GET_PRESIGNED_URL}`,\r\n    body: data,\r\n    method: \"POST\",\r\n    token,\r\n  });\r\n}\r\n\r\nexport async function UPLOAD_ATTACHMENT<Response>(\r\n  token: string,\r\n  data: any\r\n): Promise<APIResponse<Response>> {\r\n  return await chatApi<Response>({\r\n    endpoint: `${API}${ENDPOINTS.UPLOAD_ATTACHMENT}`,\r\n    body: data,\r\n    method: \"POST\",\r\n    token,\r\n    headers: { \"Content-Type\": \"multipart/form-data\" },\r\n  });\r\n}\r\n","import Connection from \"./Connection\";\r\nimport {\r\n  ClientActions,\r\n  Conversation,\r\n  ConversationListItem,\r\n  ConversationType,\r\n  ConversationWithTypingIndicator,\r\n  DeletedMessage,\r\n  EditedMessage,\r\n  MediaType,\r\n  Message,\r\n  MessageStates,\r\n  Prettify,\r\n  Reaction,\r\n  ReadMessages,\r\n  Screens,\r\n  SendMessageGenerics,\r\n  ServerActions,\r\n  UserMeta,\r\n  WsPayLoad,\r\n} from \"./types\";\r\nimport {\r\n  generateConversationId,\r\n  generateFillerTimestamps,\r\n  generateId,\r\n} from \"./utils\";\r\nimport { Events } from \"./events\";\r\nimport {\r\n  GET_BROADCAST_LIST_MESSAGES,\r\n  GET_CONVERSATION,\r\n  GET_EMOJIS,\r\n  GET_MESSAGES,\r\n  GET_PRESIGNED_URL,\r\n  UPLOAD_ATTACHMENT,\r\n  UPLOAD_MEDIA,\r\n} from \"./fetch\";\r\nimport { Emoticon } from \"./emoticon.type\";\r\nimport moment from \"moment\";\r\nimport { Readable } from \"stream\";\r\n\r\nlet CLEAR_UNREAD_TIMEOUT = 1000;\r\n\r\nexport default class MessageClient {\r\n  private static message_client: MessageClient;\r\n  private connection: Connection;\r\n  // private currentConversationId: string;\r\n  private screen: Screens;\r\n  private idleTimers: { [key: string]: NodeJS.Timeout | undefined };\r\n\r\n  constructor(connection: Connection, conversationId: string) {\r\n    this.connection = connection;\r\n    this.idleTimers = {};\r\n    // this.connection.activeConversationId = conversationId;\r\n    this.screen = Screens.CONVERSATIONS;\r\n  }\r\n\r\n  static getInstace(connection: Connection, conversationId: string) {\r\n    if (MessageClient.message_client) {\r\n      if (conversationId) {\r\n        MessageClient.message_client.connection.activeConversationId =\r\n          conversationId;\r\n      }\r\n      return MessageClient.message_client;\r\n    } else {\r\n      MessageClient.message_client = new MessageClient(\r\n        connection,\r\n        conversationId\r\n      );\r\n      return MessageClient.message_client;\r\n    }\r\n  }\r\n\r\n  private getPublicMethods() {\r\n    return {\r\n      getMessages: this.getMessages.bind(this),\r\n      sendMessage: this.sendMessage.bind(this),\r\n      editMessage: this.editMessage.bind(this),\r\n      sendTypingNotification: this.sendTypingNotification.bind(this),\r\n      reactToMessage: this.reactToMessage.bind(this),\r\n      uploadAttachment: this.uploadAttachment.bind(this),\r\n    };\r\n  }\r\n\r\n  private getConversationType(conversationId?: string) {\r\n    // const conversationMeta = this.connection.conversationListMeta[conversationId? conversationId : this.connection.activeConversationId];\r\n    try {\r\n      const conversationMeta =\r\n        this.connection.conversationListMeta[\r\n          conversationId ? conversationId : this.connection.activeConversationId\r\n        ];\r\n      return conversationMeta.conversation.conversationType;\r\n    } catch (error) {\r\n      return \"private-chat\";\r\n    }\r\n  }\r\n\r\n  // removes the last item in the list and adds a new one to the end keeping the original length\r\n  private rotateAndInsertMessageList = (\r\n    messageList: Array<Message>,\r\n    message: Message\r\n  ) => {\r\n    var list = [...messageList];\r\n    if (messageList.length >= 25) {\r\n      var list = [...messageList];\r\n      list.unshift();\r\n      list.push(message);\r\n      return list;\r\n    }\r\n    list.push(message);\r\n    return list;\r\n  };\r\n\r\n  private _createMessage(newMessage: Message) {\r\n    try {\r\n      if (newMessage) {\r\n        const socketMessage = {\r\n          action: ServerActions.SEND_MESSAGE,\r\n          message: {\r\n            messageId: newMessage.messageId,\r\n            from: this.connection.userMeta.uid,\r\n            to: newMessage.to,\r\n            conversationType: this.getConversationType(),\r\n            message: { ...newMessage, messageState: MessageStates.SENT },\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        };\r\n        this.connection.emit(Events.NEW_MESSAGE, {\r\n          message: {\r\n            ...newMessage,\r\n            reactions: [],\r\n            messageState: MessageStates.LOADING,\r\n          },\r\n        });\r\n        if (\r\n          this.connection.socket &&\r\n          this.connection.socket?.readyState === WebSocket.OPEN\r\n        ) {\r\n          this.connection.socket.send(JSON.stringify(socketMessage));\r\n          this.connection.emit(Events.EDITED_MESSAGE, {\r\n            message: {\r\n              ...newMessage,\r\n              reactions: [],\r\n              messageState: MessageStates.SENT,\r\n            },\r\n          });\r\n          var conversationMeta =\r\n            this.connection.conversationListMeta[newMessage.conversationId];\r\n\r\n          var updatedMessages = this.rotateAndInsertMessageList(\r\n            conversationMeta.conversation.messages,\r\n            {\r\n              ...newMessage,\r\n              reactions: [],\r\n              messageState: MessageStates.SENT,\r\n            }\r\n          );\r\n          const unread = conversationMeta.unread;\r\n          this.connection.conversationListMeta[newMessage.conversationId] = {\r\n            conversation: {\r\n              ...conversationMeta.conversation,\r\n              messages: updatedMessages,\r\n            },\r\n            lastMessage: {\r\n              ...newMessage,\r\n            },\r\n            unread: unread,\r\n          };\r\n          this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n            conversationListMeta: this.connection.conversationListMeta,\r\n          });\r\n        } else {\r\n          this.connection.emit(Events.EDITED_MESSAGE, {\r\n            message: {\r\n              ...newMessage,\r\n              reactions: [],\r\n              messageState: MessageStates.FAILED,\r\n            },\r\n          });\r\n          this.connection.conversationListMeta[newMessage.conversationId] = {\r\n            conversation:\r\n              this.connection.conversationListMeta[newMessage.conversationId]\r\n                .conversation,\r\n            lastMessage: {\r\n              ...newMessage,\r\n              messageState: MessageStates.FAILED,\r\n            },\r\n            unread: [],\r\n          };\r\n          this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n            conversationListMeta: this.connection.conversationListMeta,\r\n          });\r\n        }\r\n      }\r\n    } catch (error) {\r\n      if (error instanceof Error) {\r\n        console.error(error);\r\n        this.connection.emit(Events.DELETED_MESSAGE, {\r\n          message: {\r\n            ...newMessage,\r\n            reactions: [],\r\n            messageState: MessageStates.FAILED,\r\n          },\r\n        });\r\n      }\r\n    }\r\n  }\r\n\r\n  private editConversationListMetaMessage({ isBroadcast, updatedMessage } : { isBroadcast: boolean, updatedMessage: any }) {\r\n    var conversationMeta = isBroadcast? this.connection.broadcastListMeta[updatedMessage.conversationId] : this.connection.conversationListMeta[updatedMessage.conversationId];\r\n    var messageId = updatedMessage.messageId;\r\n    if (conversationMeta) {\r\n      // const socketMessage = {\r\n      //   action: ServerActions.EDIT_MESSAGE,\r\n      //   message: {\r\n      //     ...updatedMessage,\r\n      //     token: this.connection.wsAccessConfig.token,\r\n      //   },\r\n      // };\r\n      // this.connection.socket.send(JSON.stringify(socketMessage));\r\n      var prevMessage = conversationMeta.conversation.messages.find(\r\n        (m) => m.messageId === messageId\r\n      );\r\n      if (prevMessage) {\r\n        var editedMessage = {\r\n          ...prevMessage,\r\n          message: updatedMessage.textMessage,\r\n          lastEdited: new Date(),\r\n        };\r\n        var updatedMessageList = conversationMeta.conversation.messages.map(\r\n          (m) => {\r\n            if (m.messageId === messageId) {\r\n              return editedMessage;\r\n            }\r\n            return m;\r\n          }\r\n        );\r\n        \r\n        if(isBroadcast){\r\n          this.connection.broadcastListMeta[updatedMessage.conversationId] = {\r\n            conversation: {\r\n              ...conversationMeta.conversation,\r\n              messages: updatedMessageList,\r\n            },\r\n            lastMessage: null,\r\n            unread: [],\r\n          };\r\n          this.connection.emit(Events.BROADCAST_LIST_META_CHANGED, {\r\n            broadcastListMeta: this.connection.broadcastListMeta,\r\n          });\r\n        }else{\r\n          this.connection.conversationListMeta[updatedMessage.conversationId] = {\r\n            conversation: {\r\n              ...conversationMeta.conversation,\r\n              messages: updatedMessageList,\r\n            },\r\n            lastMessage: { ...editedMessage },\r\n            unread: conversationMeta.unread,\r\n          };\r\n          this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n            conversationListMeta: this.connection.conversationListMeta,\r\n          });\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  private _editMessage(message: EditedMessage) {\r\n    try {\r\n      if (message) {\r\n        let updatedMessage = {\r\n          ...message,\r\n          message: message.textMessage,\r\n          lastEdited: new Date(),\r\n        };\r\n        this.connection.emit(Events.EDITED_MESSAGE, {\r\n          message: updatedMessage,\r\n        });\r\n        this.editConversationListMetaMessage({\r\n          isBroadcast: false, \r\n          updatedMessage \r\n        });\r\n\r\n        // update both lists !!might need improvement, maybe go back to using a single list.\r\n        this.editConversationListMetaMessage({\r\n          isBroadcast: true, \r\n          updatedMessage \r\n        });\r\n       \r\n        if(this.connection.socket){\r\n          const socketMessage = {\r\n            action: ServerActions.EDIT_MESSAGE,\r\n            message: {\r\n              ...updatedMessage,\r\n              token: this.connection.wsAccessConfig.token,\r\n              isBroadcast: message.isBroadcast,\r\n              user: this.connection.userMeta\r\n            },\r\n          };\r\n          this.connection.socket.send(JSON.stringify(socketMessage));\r\n        }\r\n        // if(this.connection.socket){\r\n        //   const socketMessage = {\r\n        //     action: ServerActions.EDIT_MESSAGE,\r\n        //     message: {\r\n        //       ...updatedMessage,\r\n        //       token: this.connection.wsAccessConfig.token,\r\n        //     },\r\n        //   };\r\n        //   console.log(socketMessage)\r\n        //   this.connection.socket.send(JSON.stringify(socketMessage));\r\n        // }\r\n        // if (conversationMeta && this.connection.socket) {\r\n        //   const socketMessage = {\r\n        //     action: ServerActions.EDIT_MESSAGE,\r\n        //     message: {\r\n        //       ...updatedMessage,\r\n        //       token: this.connection.wsAccessConfig.token,\r\n        //     },\r\n        //   };\r\n        //   this.connection.socket.send(JSON.stringify(socketMessage));\r\n        //   var prevMessage = conversationMeta.conversation.messages.find(\r\n        //     (m) => m.messageId === message.messageId\r\n        //   );\r\n        //   if (prevMessage) {\r\n        //     var editedMessage = {\r\n        //       ...prevMessage,\r\n        //       message: message.textMessage,\r\n        //       lastEdited: new Date(),\r\n        //     };\r\n        //     var updatedMessageList = conversationMeta.conversation.messages.map(\r\n        //       (m) => {\r\n        //         if (m.messageId === message.messageId) {\r\n        //           return editedMessage;\r\n        //         }\r\n        //         return m;\r\n        //       }\r\n        //     );\r\n        //     this.connection.conversationListMeta[message.conversationId] = {\r\n        //       conversation: {\r\n        //         ...conversationMeta.conversation,\r\n        //         messages: updatedMessageList,\r\n        //       },\r\n        //       lastMessage: { ...editedMessage },\r\n        //       unread: conversationMeta.unread,\r\n        //     };\r\n        //     this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n        //       conversationListMeta: this.connection.conversationListMeta,\r\n        //     });\r\n        //     // update message copy on broadcast chat screen\r\n        //     this.connection.emit(Events.BROADCAST_LIST_META_CHANGED, {\r\n        //       broadcastListMeta: this.connection.broadcastListMeta,\r\n        //     });\r\n        //   }\r\n        // }\r\n      }\r\n    } catch (error) {\r\n      // maybe an error listener instead\r\n      console.error(error);\r\n    }\r\n  }\r\n\r\n  _updateMessageReactions(\r\n    conversationId: string,\r\n    messageId: string,\r\n    reactions: Reaction[],\r\n    config?: { ws: boolean; to: string }\r\n  ) {\r\n    try {\r\n      this.connection.emit(Events.EDITED_MESSAGE, {\r\n        message: { messageId, reactions },\r\n      });\r\n      // should also send to the lastMessage in conversations meta.\r\n      if (config?.ws) {\r\n        const reactionPayload = {\r\n          action: ServerActions.SEND_MESSAGE_REACTION,\r\n          message: {\r\n            conversationId,\r\n            messageId: messageId,\r\n            from: this.connection.userMeta.uid,\r\n            to: config.to,\r\n            reactions,\r\n            token: this.connection.wsAccessConfig.token,\r\n            user: this.connection.userMeta\r\n          },\r\n        };\r\n        this.connection.socket.send(JSON.stringify(reactionPayload));\r\n      }\r\n\r\n      var conversationMeta =\r\n        this.connection.conversationListMeta[conversationId];\r\n      var prevLastMessage = conversationMeta?.lastMessage;\r\n\r\n      if (prevLastMessage && prevLastMessage.messageId === messageId) {\r\n        var updatedMessage = {\r\n          ...prevLastMessage,\r\n          reactions,\r\n        };\r\n        var updatedMessages = this.rotateAndInsertMessageList(\r\n          conversationMeta.conversation.messages,\r\n          updatedMessage\r\n        );\r\n\r\n        var updatedConversationListMeta = {\r\n          conversation: {\r\n            ...conversationMeta.conversation,\r\n            messages: updatedMessages,\r\n          },\r\n          unread: conversationMeta.unread,\r\n          lastMessage: {\r\n            ...updatedMessage,\r\n          },\r\n        };\r\n        this.connection.conversationListMeta[conversationId] =\r\n          updatedConversationListMeta;\r\n        this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n          conversationListMeta: this.connection.conversationListMeta,\r\n        });\r\n      }\r\n    } catch (error) {\r\n      if (error instanceof Error) {\r\n      }\r\n    }\r\n  }\r\n\r\n  private storeEditedMessage(data: EditedMessage) {\r\n    const conversation = this.connection.conversationMap[data.conversationId];\r\n    // const conversation = this.connection.conversationMap[data.conversationId];\r\n    if (conversation) {\r\n      var message = conversation.messages.find(\r\n        (message) => message.messageId === data.messageId\r\n      );\r\n      if (message) {\r\n        const updatedMessage = {\r\n          ...message,\r\n          message: data.textMessage,\r\n          lastEdited: new Date(),\r\n        };\r\n        this.connection.emit(Events.EDITED_MESSAGE, {\r\n          message: updatedMessage,\r\n        });\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   *\r\n   * @param conversationId\r\n   * @summary Updates the list of conversations with typing indicator flags\r\n   */\r\n  private showTypingIndicator = (\r\n    conversationId: string,\r\n    action: \"START\" | \"STOP\"\r\n  ) => {\r\n    if (action === \"START\") {\r\n      this.connection.emit(Events.HAS_STARTED_TYPING, {\r\n        conversationId,\r\n      });\r\n    } else {\r\n      this._clearActiveTypingIndicator(conversationId);\r\n      this.idleTimers[conversationId] = setTimeout(() => {\r\n        this.connection.emit(Events.HAS_STOPPED_TYPING, {\r\n          conversationId,\r\n        });\r\n      }, 4000);\r\n    }\r\n  };\r\n  // sent to message recipient\r\n  private _sendTypingNotification(uid: string) {\r\n    if (this.connection.socket) {\r\n      this.connection.socket.send(\r\n        JSON.stringify({\r\n          action: ServerActions.USER_TYPING,\r\n          message: {\r\n            uid,\r\n            conversationId: this.connection.activeConversationId,\r\n            action: \"START\",\r\n            conversationType: this.getConversationType(\r\n              this.connection.activeConversationId\r\n            ),\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        })\r\n      );\r\n    }\r\n  }\r\n\r\n  private _sendStoppedTypingNotification(uid: string) {\r\n    if (this.connection.socket) {\r\n      this.connection.socket.send(\r\n        JSON.stringify({\r\n          action: ServerActions.USER_TYPING,\r\n          message: {\r\n            uid,\r\n            conversationId: this.connection.activeConversationId,\r\n            action: \"STOP\",\r\n            conversationType: this.getConversationType(\r\n              this.connection.activeConversationId\r\n            ),\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        })\r\n      );\r\n    }\r\n  }\r\n\r\n  private addMessageToConversation(newMessage: Message, screen: string) {\r\n    try {\r\n      const conversation =\r\n        this.connection.conversationMap[newMessage.conversationId];\r\n      if (conversation) {\r\n        const updatedMessages = [\r\n          ...conversation.messages,\r\n          {\r\n            ...newMessage,\r\n            messageState:\r\n              screen === Screens.CHAT ? MessageStates.READ : MessageStates.SENT,\r\n          },\r\n        ];\r\n\r\n        this.connection.conversationMap[newMessage.conversationId] = {\r\n          ...conversation,\r\n          messages: updatedMessages,\r\n        };\r\n        this.connection.emit(Events.NEW_MESSAGE, {\r\n          message: {\r\n            ...newMessage,\r\n            messageState:\r\n              screen === Screens.CHAT ? MessageStates.READ : MessageStates.SENT,\r\n          },\r\n        });\r\n\r\n        const unread = [\r\n          ...this.connection.conversationListMeta[newMessage.conversationId]\r\n            .unread,\r\n        ];\r\n\r\n        if (\r\n          newMessage.conversationId !== this.connection.activeConversationId\r\n        ) {\r\n          unread.push(newMessage.messageId);\r\n        }\r\n\r\n        const updatedConversationListMeta = {\r\n          conversation: {\r\n            ...this.connection.conversationListMeta[newMessage.conversationId]\r\n              .conversation,\r\n            messages: updatedMessages,\r\n          },\r\n          lastMessage: {\r\n            ...newMessage,\r\n          },\r\n          unread: unread,\r\n        };\r\n        this.connection.conversationListMeta[newMessage.conversationId] =\r\n          updatedConversationListMeta;\r\n        this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n          conversationListMeta: this.connection.conversationListMeta,\r\n        });\r\n      }\r\n    } catch (error) {\r\n      console.error(error);\r\n    }\r\n  }\r\n\r\n  private sendReadNotification(data: ReadMessages) {\r\n    if (this.connection.socket) {\r\n      this.connection.socket.send(\r\n        JSON.stringify({\r\n          action: ServerActions.READ_MESSAGES,\r\n          message: { \r\n            ...data,\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token },\r\n        })\r\n      );\r\n    }\r\n  }\r\n\r\n  private _clearActiveTypingIndicator(conversationId: string, emit?: boolean) {\r\n    clearTimeout(this.idleTimers[conversationId]);\r\n    delete this.idleTimers[conversationId];\r\n    if (emit === true) {\r\n      this.connection.emit(Events.HAS_STOPPED_TYPING, {\r\n        conversationId,\r\n      });\r\n    }\r\n  }\r\n\r\n  private _updateConversationListMetaMessages() {}\r\n\r\n  readMessages(conversationId: string, data: ReadMessages) {\r\n    if (this.connection.socket) {\r\n      const socketMessage = {\r\n        action: ServerActions.READ_MESSAGES,\r\n        message: {\r\n          ...data,\r\n          user: this.connection.userMeta,\r\n          token: this.connection.wsAccessConfig.token,\r\n        },\r\n      };\r\n  \r\n      this.connection.socket.send(JSON.stringify(socketMessage));\r\n  \r\n      // Create an updated conversation list meta immutably\r\n      const conversationMeta = this.connection.conversationListMeta[conversationId];\r\n      if (conversationMeta) {\r\n        const updatedConversationListMeta = {\r\n          ...this.connection.conversationListMeta,\r\n          [conversationId]: {\r\n            ...conversationMeta,\r\n            unread: [],  // Clears unread without direct mutation\r\n          },\r\n        };\r\n  \r\n        this.connection.conversationListMeta = updatedConversationListMeta;\r\n        \r\n        this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n          conversationListMeta: updatedConversationListMeta,\r\n        });\r\n      }\r\n    }\r\n  }\r\n  \r\n\r\n  //this is to clear notifications for user who hasn't opened chat\r\n  clearUserUnreadNotifications(conversationId: string, ids: string[]) {\r\n    var i = 0;\r\n    var len = ids.length;\r\n\r\n    while (i < len) {\r\n      this.connection.emit(Events.EDITED_MESSAGE, {\r\n        message: { messageId: ids[i], messageState: MessageStates.READ },\r\n      });\r\n      i++;\r\n    }\r\n  }\r\n\r\n  private wsOnError(error: CloseEvent) {\r\n    this.connection.emit(Events.CONNECTION_CHANGED, {\r\n      isConnected: false,\r\n      connecting: false,\r\n      fetchingConversations: false,\r\n    });\r\n  }\r\n\r\n  private deleteMessageFromConversationMeta(\r\n    conversationId: string,\r\n    messageId: string\r\n  ) {\r\n    try {\r\n      const conversationMeta =\r\n        this.connection.conversationListMeta[conversationId];\r\n\r\n      // check if the message being deleted is the last message\r\n      var isLastMessage = messageId === conversationMeta.lastMessage?.messageId;\r\n\r\n      if (conversationMeta) {\r\n        const filteredMessages = conversationMeta.conversation.messages.filter(\r\n          (m) => m.messageId !== messageId\r\n        );\r\n\r\n        var newLastMessage = filteredMessages[filteredMessages.length - 1];\r\n\r\n        var updatedConversationListMeta = {\r\n          ...conversationMeta,\r\n          conversation: {\r\n            ...conversationMeta.conversation,\r\n            messages: filteredMessages,\r\n          },\r\n        };\r\n\r\n        if (isLastMessage) {\r\n          updatedConversationListMeta.lastMessage = newLastMessage\r\n            ? newLastMessage\r\n            : null;\r\n        }\r\n\r\n        this.connection.conversationListMeta[conversationId] =\r\n          updatedConversationListMeta;\r\n\r\n        this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n          conversationListMeta: this.connection.conversationListMeta,\r\n        });\r\n      } else {\r\n        throw new Error(`Conversation with ID ${conversationId} not found.`);\r\n      }\r\n    } catch (error) {\r\n      if (error instanceof Error) {\r\n        console.error(error.message);\r\n      }\r\n    }\r\n  }\r\n\r\n  reactToMessage({\r\n    conversationId,\r\n    messageId,\r\n    reactions,\r\n    to,\r\n  }: {\r\n    conversationId: string;\r\n    messageId: string;\r\n    reactions: Reaction[];\r\n    to: string;\r\n  }) {\r\n    if (this.connection) {\r\n      this._updateMessageReactions(conversationId, messageId, reactions, {\r\n        ws: true,\r\n        to,\r\n      });\r\n    }\r\n  }\r\n\r\n  sendMessage(newMessage: Prettify<SendMessageGenerics<Message>>) {\r\n    if (this.connection) {\r\n      const messageId = generateId();\r\n      var timeStamps = generateFillerTimestamps();\r\n      var messageOwner = {\r\n        ...this.connection.userMeta,\r\n        ...timeStamps,\r\n      };\r\n      const messageStruct: Message = {\r\n        ...newMessage,\r\n        quotedMessageId: newMessage?.quotedMessage?.messageId,\r\n        from: messageOwner.uid,\r\n        lastEdited: null,\r\n        messageState: MessageStates.LOADING,\r\n        messageOwner,\r\n        messageId,\r\n        ...timeStamps,\r\n      };\r\n      this._createMessage(messageStruct);\r\n    }\r\n  }\r\n\r\n  updateBroadcastList(payload: { broadcastListId: string, participants: string[], name: string }) {\r\n    try {\r\n      if (\r\n        this.connection.socket &&\r\n        this.connection.socket?.readyState === WebSocket.OPEN\r\n      ) {\r\n        const socketMessage = {\r\n          action: ServerActions.DELETE_BROADCAST_LIST,\r\n          message: {\r\n            broadcastListId: payload.broadcastListId,\r\n            participants: payload.participants,\r\n            name: payload.name,\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        };\r\n        this.connection.socket.send(JSON.stringify(socketMessage));\r\n      }else{\r\n        console.error(\"Failed to send broadcast\");\r\n      }\r\n    } catch (error) {\r\n      if(error instanceof Error){\r\n        console.error(error.message)\r\n      }\r\n    }\r\n  }\r\n\r\n  deleteBroadcastList(payload: { broadcastListId: string, participants: string[], name: string }) {\r\n    try {\r\n      if (\r\n        this.connection.socket &&\r\n        this.connection.socket?.readyState === WebSocket.OPEN\r\n      ) {\r\n        const socketMessage = {\r\n          action: ServerActions.UPDATE_BROADCAST_LIST,\r\n          message: {\r\n            broadcastListId: payload.broadcastListId,\r\n            participants: payload.participants,\r\n            name: payload.name,\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        };\r\n        this.connection.socket.send(JSON.stringify(socketMessage));\r\n        if(this.connection.broadcastListMeta[payload.broadcastListId]){{\r\n          delete this.connection.broadcastListMeta[payload.broadcastListId]\r\n          this.connection.emit(Events.BROADCAST_LIST_META_CHANGED, {\r\n            broadcastListMeta: this.connection.broadcastListMeta,\r\n          });\r\n        }}\r\n      }else{\r\n        console.error(\"Failed to send broadcast\");\r\n      }\r\n    } catch (error) {\r\n      if(error instanceof Error){\r\n        console.error(error.message)\r\n      }\r\n    }\r\n  }\r\n\r\n  broadcastMessage(\r\n    { broadcastListId, participantsIds, newMessage }:  { broadcastListId: string, participantsIds: string[], newMessage: Prettify<SendMessageGenerics<Message>> }) {\r\n    try {\r\n      if (\r\n        this.connection.socket &&\r\n        this.connection.socket?.readyState === WebSocket.OPEN\r\n      ) {\r\n        const messageId = generateId();\r\n        var timeStamps = generateFillerTimestamps();\r\n        var messageOwner = {\r\n          ...this.connection.userMeta,\r\n          ...timeStamps,\r\n        };\r\n        const messageStruct: Message = {\r\n          ...newMessage,\r\n          quotedMessageId: newMessage?.quotedMessage?.messageId,\r\n          from: messageOwner.uid,\r\n          lastEdited: null,\r\n          messageState: MessageStates.SENT,\r\n          messageOwner,\r\n          messageId,\r\n          isBroadcast: true,\r\n          broadcastListId,\r\n          ...timeStamps,\r\n        };\r\n\r\n        const socketMessage = {\r\n          action: ServerActions.BROADCAST_MESSAGE,\r\n          message: {\r\n            broadcastListId,\r\n            messageId,\r\n            from: messageOwner.uid,\r\n            to: participantsIds,\r\n            shouldEdit: false,\r\n            conversationType: \"broadcast-chat\",\r\n            message: messageStruct,\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        };\r\n\r\n        var broadcastItem = this.connection.broadcastListMeta[broadcastListId];\r\n        var messages = [...broadcastItem.conversation.messages];\r\n\r\n        messages.push(messageStruct);\r\n\r\n        var updatedBroadCastItem = { \r\n          conversation: { ...broadcastItem.conversation, messages },\r\n          lastMessage: null,\r\n          unread: []\r\n         };\r\n        this.connection.broadcastListMeta[broadcastListId] = updatedBroadCastItem;\r\n\r\n        this.connection.socket.send(JSON.stringify(socketMessage));\r\n\r\n        participantsIds.map(p => {\r\n          // send out new message events for any active listeners\r\n          const conversationId = generateConversationId(p, messageOwner.uid, this.connection.projectConfig.projectId);\r\n          this.connection.emit(Events.NEW_MESSAGE, {\r\n            message: {\r\n              ...messageStruct,\r\n              conversationId,\r\n              reactions: [],\r\n            },\r\n          });\r\n          var prevConversation = this.connection.conversationListMeta[conversationId]\r\n          // if a conversation exists, update all user conversations in conversationListMeta\r\n          if(prevConversation){\r\n            this.connection.conversationListMeta[conversationId] = {\r\n              conversation: {\r\n                ...prevConversation.conversation,\r\n                messages: [ ...prevConversation.conversation.messages, {\r\n                  ...messageStruct,\r\n                  conversationId,\r\n                  reactions: [],\r\n                } ],\r\n              },\r\n              lastMessage: {\r\n                ...messageStruct,\r\n                conversationId,\r\n                reactions: [],\r\n              },\r\n              unread: prevConversation.unread,\r\n            };\r\n          }\r\n        });\r\n        // send the updated conversationListMeta to active listeners\r\n        this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n          conversationListMeta: this.connection.conversationListMeta,\r\n        });\r\n\r\n        // send a new message event for the current broadcast chat\r\n        this.connection.emit(Events.NEW_MESSAGE, {\r\n          message: {\r\n            ...messageStruct,\r\n            conversationId: broadcastListId,\r\n            reactions: [],\r\n          },\r\n        });\r\n\r\n        this.connection.emit(Events.BROADCAST_LIST_META_CHANGED, {\r\n          broadcastListMeta: this.connection.broadcastListMeta,\r\n        });\r\n      } else {\r\n        console.error(\"Failed to send broadcast\");\r\n      }\r\n    } catch (error) {\r\n      if (error instanceof Error) {\r\n        console.error(error.message);\r\n      }\r\n    }\r\n  }\r\n\r\n  editMessage(message: Omit<EditedMessage, \"from\">) {\r\n    if (this.connection) {\r\n      this._editMessage({\r\n        ...message,\r\n        from: this.connection.userMeta.uid,\r\n      });\r\n    }\r\n  }\r\n\r\n  sendTypingNotification(uid: string) {\r\n    if (this.connection) {\r\n      this._sendTypingNotification(uid);\r\n    }\r\n  }\r\n\r\n  sendStoppedTypingNotification(uid: string) {\r\n    if (this.connection) {\r\n      this._sendStoppedTypingNotification(uid);\r\n    }\r\n  }\r\n\r\n  deleteMessage(messageId: string, to: string, conversationId: string) {\r\n    if (this.connection) {\r\n      this.connection.socket.send(\r\n        JSON.stringify({\r\n          action: ServerActions.DELETE_MESSAGE,\r\n          message: {\r\n            messageId,\r\n            to,\r\n            conversationId,\r\n            conversationType: this.getConversationType(),\r\n            user: this.connection.userMeta,\r\n            token: this.connection.wsAccessConfig.token,\r\n          },\r\n        })\r\n      );\r\n      this.connection.emit(Events.DELETED_MESSAGE, {\r\n        message: {\r\n          conversationId,\r\n          messageId,\r\n        },\r\n      });\r\n      this.deleteMessageFromConversationMeta(conversationId, messageId);\r\n    }\r\n  }\r\n\r\n  async getMessages(page?: number) {\r\n    if (this.connection) {\r\n      try {\r\n        const response = await GET_MESSAGES<{ messages: Message[] }>(\r\n          this.connection.wsAccessConfig.token,\r\n          this.connection.activeConversationId,\r\n          page\r\n        );\r\n        if (response.success) {\r\n          const sortedMessages = [...response.data.messages].sort((a, b) => {\r\n            const dateA = moment(a.createdAt).valueOf();\r\n            const dateB = moment(b.createdAt).valueOf();\r\n            return dateA - dateB;\r\n          });\r\n          return sortedMessages;\r\n        } else {\r\n          return [];\r\n        }\r\n      } catch (err) {\r\n        console.error(err);\r\n        return [];\r\n      }\r\n    } else {\r\n      return [];\r\n    }\r\n  }\r\n\r\n  async getBroadcastListMessages(page?: number) {\r\n    if (this.connection) {\r\n      try {\r\n        const response = await GET_BROADCAST_LIST_MESSAGES<{\r\n          messages: Message[];\r\n        }>(\r\n          this.connection.wsAccessConfig.token,\r\n          this.connection.activeConversationId,\r\n          page\r\n        );\r\n        if (response.success) {\r\n          const sortedMessages = [...response.data.messages].sort((a, b) => {\r\n            const dateA = moment(a.createdAt).valueOf();\r\n            const dateB = moment(b.createdAt).valueOf();\r\n            return dateA - dateB;\r\n          });\r\n          return sortedMessages;\r\n        } else {\r\n          return [];\r\n        }\r\n      } catch (err) {\r\n        console.error(err);\r\n        return [];\r\n      }\r\n    } else {\r\n      return [];\r\n    }\r\n  }\r\n\r\n  async getConversation(conversationId: string) {\r\n    if (this.connection) {\r\n      try {\r\n        const response = await GET_CONVERSATION<{ conversation: Conversation }>(\r\n          this.connection.wsAccessConfig.token,\r\n          conversationId\r\n        );\r\n        if (response.success) {\r\n          return response.data.conversation;\r\n        } else {\r\n          return null;\r\n        }\r\n      } catch (err) {\r\n        return null;\r\n      }\r\n    } else {\r\n      return null;\r\n    }\r\n  }\r\n\r\n  async getEmojiList() {\r\n    if (this.connection) {\r\n      try {\r\n        const response = await GET_EMOJIS<{ gifs: Emoticon[] }>(\r\n          this.connection.wsAccessConfig.token\r\n        );\r\n        return response.data.gifs;\r\n      } catch (err) {\r\n        return [];\r\n      }\r\n    } else {\r\n      return [];\r\n    }\r\n  }\r\n\r\n  async uploadAttachment({\r\n    base64,\r\n    fileKey,\r\n  }: {\r\n    base64: string;\r\n    fileKey: string;\r\n  }) {\r\n    if (this.connection) {\r\n      try {\r\n        const res = await UPLOAD_MEDIA<{ url: string }>(\r\n          this.connection.wsAccessConfig?.token,\r\n          {\r\n            base64,\r\n            conversationId: this.connection.activeConversationId,\r\n            key: fileKey,\r\n          }\r\n        );\r\n        return res;\r\n      } catch (error) {\r\n        if (error instanceof Error) {\r\n          console.error(error.message);\r\n        }\r\n      }\r\n    } else {\r\n      throw new Error(\"No connection established\");\r\n    }\r\n  }\r\n\r\n  private isReadableStream(uri: any): uri is Readable {\r\n    return uri && typeof uri.pipe === \"function\";\r\n  }\r\n\r\n  async uploadFile(\r\n    uri: string | NodeJS.ReadableStream | Buffer | File,\r\n    meta: {\r\n      filename: string;\r\n      mimeType: string;\r\n      ext: string\r\n    }\r\n  ) {\r\n    try {\r\n      // Get the presigned URL for upload\r\n      const res = await GET_PRESIGNED_URL<{\r\n        uploadUrl: string;\r\n        s3Link: string;\r\n      }>(this.connection.wsAccessConfig?.token, {\r\n        base64: \"\",\r\n        conversationId: this.connection.activeConversationId,\r\n        key: generateId(),\r\n        mediaType: meta.mimeType,\r\n        uid: this.connection.userMeta.uid,\r\n        ext: meta.ext\r\n      });\r\n\r\n      let body;\r\n\r\n      let fileSize = 0; // Initialize file size\r\n\r\n      if (typeof uri === \"string\") {\r\n        const response = await fetch(uri); // Fetch the file data from URI\r\n        body = await response.blob(); // Convert it to a Blob\r\n        fileSize = body.size;\r\n      }\r\n      // Check if the input is a File object (e.g., browser)\r\n      else if (uri instanceof File) {\r\n        body = uri;\r\n        fileSize = uri.size;\r\n      }\r\n      // Check if the input is a Buffer (Node.js)\r\n      else if (Buffer.isBuffer(uri)) {\r\n        body = new Blob([uri], { type: meta.mimeType });\r\n        fileSize = uri.length;\r\n      }\r\n      // Check if the input is a Node.js Readable stream\r\n      else if (this.isReadableStream(uri)) {\r\n        const chunks: any[] = [];\r\n        let totalSize = 0;\r\n        for await (const chunk of uri) {\r\n          chunks.push(chunk);\r\n          totalSize += chunk.length; // Accumulate size\r\n        }\r\n        const buffer = Buffer.concat(chunks);\r\n        body = new Blob([buffer], { type: meta.mimeType });\r\n        fileSize = totalSize;\r\n      }\r\n\r\n      await fetch(res.data.uploadUrl, {\r\n        method: \"PUT\",\r\n        body: body,\r\n        headers: {\r\n          \"Content-Type\": meta.mimeType,\r\n        },\r\n      });\r\n\r\n      return {\r\n        link: res.data.s3Link,\r\n        success: res.success,\r\n        fileSize,\r\n      };\r\n    } catch (error) {\r\n      console.log(error);\r\n      console.error(\"Error uploading file: \", error);\r\n      return {\r\n        link: \"\",\r\n        success: false,\r\n        fileSize: \"\",\r\n      };\r\n    }\r\n  }\r\n\r\n  async uploadAttachmentV2({\r\n    base64,\r\n    fileKey,\r\n    mediaType,\r\n    mimeType,\r\n  }: {\r\n    base64: string;\r\n    fileKey: string;\r\n    mediaType: MediaType;\r\n    mimeType: string;\r\n  }) {\r\n    if (this.connection) {\r\n      try {\r\n        const res = await GET_PRESIGNED_URL<{\r\n          uploadUrl: string;\r\n          s3Link: string;\r\n        }>(this.connection.wsAccessConfig?.token, {\r\n          base64,\r\n          conversationId: this.connection.activeConversationId,\r\n          key: generateId(),\r\n          mediaType,\r\n          uid: this.connection.userMeta.uid,\r\n          ext: \"\"\r\n        });\r\n        const data = await fetch(res.data.uploadUrl, {\r\n          method: \"PUT\",\r\n          body: {\r\n            base64,\r\n            fileKey,\r\n            mediaType,\r\n          } as any,\r\n          headers: {\r\n            \"Content-Type\": mimeType,\r\n          },\r\n        });\r\n        return res;\r\n      } catch (error) {\r\n        if (error instanceof Error) {\r\n          console.error(error.message);\r\n        }\r\n      }\r\n    } else {\r\n      throw new Error(\"No connection established\");\r\n    }\r\n  }\r\n\r\n  async setActiveConversation() {\r\n    if (this.connection) {\r\n      this.connection.screen = Screens.CHAT;\r\n      this.screen = Screens.CHAT;\r\n    } else {\r\n      throw new Error(\"No connection established\");\r\n    }\r\n  }\r\n\r\n  async unSetActiveConversation() {\r\n    if (this.connection) {\r\n      this.connection.activeConversationId = \"\";\r\n      this.connection.screen = Screens.CONVERSATIONS;\r\n      this.screen = Screens.CONVERSATIONS;\r\n    } else {\r\n      throw new Error(\"No connection established\");\r\n    }\r\n  }\r\n\r\n  messageEventHandler(event: MessageEvent) {\r\n    try {\r\n      if (!event) return null;\r\n      var wsData = JSON.parse(event.data);\r\n      const action: ClientActions | ServerActions = wsData.action;\r\n      if (\r\n        this.screen === Screens.CHAT &&\r\n        this.connection.activeConversationId === wsData?.message?.conversationId\r\n        // this.connection.activeConversationId === wsData?.message?.conversationId\r\n      ) {\r\n        // read messages if user is still on the screen\r\n        if (action === ClientActions.INCOMING_MESSAGE) {\r\n          const {\r\n            message: incomingMessagePayload,\r\n          }: WsPayLoad<ServerActions, Message> = JSON.parse(event.data);\r\n\r\n          // clear typing indicator timeout\r\n          this._clearActiveTypingIndicator(\r\n            this.connection.activeConversationId,\r\n            true\r\n          );\r\n\r\n          this.sendReadNotification({\r\n            uid: incomingMessagePayload.from,\r\n            messageIds: [incomingMessagePayload.messageId],\r\n          });\r\n        }\r\n\r\n        // to read the message as they come in\r\n        if (action === ClientActions.MESSAGES_READ) {\r\n          const {\r\n            message: readMessagesPayload,\r\n          }: WsPayLoad<\r\n            ClientActions,\r\n            ReadMessages & { conversationId: string }\r\n          > = wsData;\r\n          // const existingConversationForRead = this.connection.conversationMap[readMessagesPayload.conversationId]\r\n          if (\r\n            // existingConversationForRead &&\r\n            this.screen === Screens.CHAT &&\r\n            this.connection.activeConversationId ===\r\n              readMessagesPayload.conversationId\r\n          ) {\r\n            setTimeout(() => {\r\n              this.clearUserUnreadNotifications(\r\n                readMessagesPayload.conversationId,\r\n                readMessagesPayload.messageIds\r\n              );\r\n            }, CLEAR_UNREAD_TIMEOUT);\r\n          }\r\n        }\r\n      }\r\n      switch (action) {\r\n        case ClientActions.MESSAGES_READ:\r\n          const {\r\n            message: readMessagesPayload,\r\n          }: WsPayLoad<\r\n            ClientActions,\r\n            ReadMessages & { conversationId: string }\r\n          > = wsData;\r\n          const existingConversationForRead =\r\n            this.connection.conversationMap[readMessagesPayload.conversationId];\r\n          if (existingConversationForRead && this.screen === Screens.CHAT) {\r\n            setTimeout(() => {\r\n              // if user reads message immediately, then they are online\r\n              // this.updateActiveConversations(readMessagesPayload.conversationId);\r\n              this.clearUserUnreadNotifications(\r\n                readMessagesPayload.conversationId,\r\n                readMessagesPayload.messageIds\r\n              );\r\n            }, CLEAR_UNREAD_TIMEOUT);\r\n          }\r\n          break;\r\n        case ClientActions.INCOMING_MESSAGE:\r\n          const {\r\n            message: incomingMessagePayload,\r\n          }: WsPayLoad<\r\n            ClientActions,\r\n            {\r\n              message: Message;\r\n              senderMeta: UserMeta;\r\n              conversationType: ConversationType;\r\n            }\r\n          > = wsData;\r\n          var incomingMessage = incomingMessagePayload.message;\r\n          const existingConversation =\r\n            this.connection.conversationMap[incomingMessage.conversationId];\r\n          this._clearActiveTypingIndicator(\r\n            incomingMessage.conversationId,\r\n            true\r\n          );\r\n\r\n          if (existingConversation) {\r\n            this.addMessageToConversation(incomingMessage, this.screen);\r\n          } else {\r\n            const newConversationId =\r\n              incomingMessagePayload.conversationType === \"private-chat\"\r\n                ? generateConversationId(\r\n                    incomingMessage.from,\r\n                    incomingMessage.to,\r\n                    this.connection.projectConfig.projectId\r\n                  )\r\n                : incomingMessagePayload.message.conversationId;\r\n            const newMessage = {\r\n              ...incomingMessage,\r\n              messageId: generateId(),\r\n              messageState: MessageStates.SENT,\r\n              createdAt: new Date(),\r\n            };\r\n            var newConversation = {\r\n              participants: [newMessage.from, newMessage.to],\r\n              conversationId: generateConversationId(\r\n                newMessage.from,\r\n                newMessage.to,\r\n                this.connection.projectConfig.projectId\r\n              ),\r\n              messages: [newMessage],\r\n              admins: [newMessage.from],\r\n              meta: null,\r\n              groupMeta: null,\r\n              conversationType: incomingMessagePayload.conversationType,\r\n              participantList: [\r\n                {\r\n                  id: generateId(),\r\n                  uid: newMessage.from,\r\n                  connectionId: \"--\",\r\n                  participantId: newMessage.from,\r\n                  projectId: \"--\",\r\n                  participantDetails: {\r\n                    // projectId: \"--\",\r\n                    // uid: this.connection.userMeta.uid,\r\n                    // connectionId: \"--\",\r\n                    // meta: incomingMessagePayload.senderMeta,\r\n                    ...incomingMessagePayload.senderMeta,\r\n                    ...generateFillerTimestamps(),\r\n                  },\r\n                  ...generateFillerTimestamps(),\r\n                },\r\n                {\r\n                  id: generateId(),\r\n                  uid: newMessage.to,\r\n                  connectionId: \"--\",\r\n                  participantId: newMessage.to,\r\n                  projectId: \"--\",\r\n                  participantDetails: {\r\n                    // projectId: \"--\",\r\n                    // uid: this.connection.userMeta.uid,\r\n                    // connectionId: \"--\",\r\n                    // meta: this.connection.userMeta,\r\n                    ...this.connection.userMeta,\r\n                    ...generateFillerTimestamps(),\r\n                  },\r\n                  ...generateFillerTimestamps(),\r\n                },\r\n              ],\r\n              ...generateFillerTimestamps(),\r\n            };\r\n\r\n            const newConversationMeta = {\r\n              conversation: newConversation,\r\n              lastMessage: newMessage,\r\n              unread: [],\r\n            };\r\n            this.connection.conversationListMeta[newConversationId] =\r\n              newConversationMeta;\r\n            this.connection.emit(Events.CONVERSATION_LIST_META_CHANGED, {\r\n              conversationListMeta: this.connection.conversationListMeta,\r\n            });\r\n          }\r\n          break;\r\n        case ClientActions.USER_IS_TYPING:\r\n          const {\r\n            message: userTypingPayload,\r\n          }: WsPayLoad<\r\n            ClientActions,\r\n            { conversationId: string; action: \"START\" | \"STOP\" }\r\n          > = wsData;\r\n\r\n          this.showTypingIndicator(\r\n            userTypingPayload.conversationId,\r\n            userTypingPayload.action\r\n          );\r\n          break;\r\n        case ClientActions.NEW_MESSAGE_REACTION:\r\n          const {\r\n            message: messageReactionPayload,\r\n          }: WsPayLoad<\r\n            ClientActions,\r\n            {\r\n              conversationId: string;\r\n              messageId: string;\r\n              from: string;\r\n              to: string;\r\n              reactions: Reaction[];\r\n            }\r\n          > = wsData;\r\n          this._updateMessageReactions(\r\n            messageReactionPayload.conversationId,\r\n            messageReactionPayload.messageId,\r\n            messageReactionPayload.reactions\r\n          );\r\n          break;\r\n        case ClientActions.MESSAGE_ERROR:\r\n          const {\r\n            message: errorPayload,\r\n          }: WsPayLoad<ClientActions, { error: string }> = wsData;\r\n          console.error(\r\n            \"Failed to send message, please try again\",\r\n            errorPayload\r\n          );\r\n          break;\r\n        case ClientActions.EDITED_MESSAGE:\r\n          const {\r\n            message: editedMessage,\r\n          }: WsPayLoad<ClientActions, EditedMessage> = wsData;\r\n          this._clearActiveTypingIndicator(editedMessage.conversationId, true);\r\n          this.storeEditedMessage(editedMessage);\r\n          break;\r\n        case ClientActions.MESSAGE_DELETED:\r\n          const {\r\n            message: deletedMessage,\r\n          }: WsPayLoad<ClientActions, DeletedMessage> = wsData;\r\n          this.connection.emit(Events.DELETED_MESSAGE, {\r\n            message: deletedMessage,\r\n          });\r\n          this.deleteMessageFromConversationMeta(\r\n            deletedMessage.conversationId,\r\n            deletedMessage.messageId\r\n          );\r\n          break;\r\n        case ClientActions.ACK_HEALTH_CHECK:\r\n          console.info(\"HEALTH_CHECK: ok!\");\r\n          break;\r\n        default:\r\n          console.log(\"Unknown action recieved\");\r\n      }\r\n\r\n      this.connection.socket.onerror = (error: CloseEvent) => {\r\n        this.wsOnError(error);\r\n      };\r\n      // }\r\n    } catch (error) {\r\n      console.error(error);\r\n    }\r\n  }\r\n}\r\n"],"mappings":"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","names":["moment","murmurHash3_x64_64","str","seed","h1","h2","c1","c2","length","remainder","bytes","i","k1","k2","generateConversationId","str1","str2","projectId","combinedString","generateId","uuid","characters","randomNumber","character","generateFillerTimestamps","axios","API","chatApi","payload","response","axios","error","GET_CONVERSATION","token","conversationId","chatApi","API","GET_MESSAGES","token","conversationId","page","chatApi","API","GET_BROADCAST_LIST_MESSAGES","broadcastListId","GET_EMOJIS","UPLOAD_MEDIA","data","GET_PRESIGNED_URL","moment","CLEAR_UNREAD_TIMEOUT","MessageClient","_MessageClient","connection","conversationId","messageList","message","list","action","newMessage","socketMessage","conversationMeta","updatedMessages","unread","error","isBroadcast","updatedMessage","messageId","prevMessage","m","editedMessage","updatedMessageList","reactions","config","reactionPayload","prevLastMessage","updatedConversationListMeta","data","conversation","uid","screen","emit","ids","i","len","isLastMessage","filteredMessages","newLastMessage","to","generateId","timeStamps","generateFillerTimestamps","messageOwner","messageStruct","payload","broadcastListId","participantsIds","broadcastItem","messages","updatedBroadCastItem","p","generateConversationId","prevConversation","page","response","GET_MESSAGES","a","b","dateA","dateB","err","GET_BROADCAST_LIST_MESSAGES","GET_CONVERSATION","GET_EMOJIS","base64","fileKey","UPLOAD_MEDIA","uri","meta","res","GET_PRESIGNED_URL","body","fileSize","chunks","totalSize","chunk","buffer","mediaType","mimeType","event","wsData","incomingMessagePayload","readMessagesPayload","incomingMessage","existingConversation","newConversationId","newConversation","newConversationMeta","userTypingPayload","messageReactionPayload","errorPayload","deletedMessage"]}