import { ErmisChat } from './belo_chat'; import { DefaultGenerics, ExtendableGenerics, MessageResponse, ThreadResponse, ChannelResponse, FormatMessageResponse, ReactionResponse, UserResponse, } from './types'; import { addToMessageList, formatMessage } from './utils'; type ThreadReadStatus = Record< string, { last_read: Date; last_read_message_id: string; unread_messages: number; user: UserResponse; } >; export class Thread { id: string; latestReplies: FormatMessageResponse[] = []; participants: ThreadResponse['thread_participants'] = []; message: FormatMessageResponse; channel: ChannelResponse; _channel: ReturnType['channel']>; replyCount = 0; _client: ErmisChat; read: ThreadReadStatus = {}; constructor(client: ErmisChat, t: ThreadResponse) { this.id = t.parent_message.id; this.message = formatMessage(t.parent_message); this.latestReplies = t.latest_replies.map(formatMessage); this.participants = t.thread_participants; this.replyCount = t.reply_count; this.channel = t.channel; this._channel = client.channel(t.channel.type, t.channel.id); this._client = client; if (t.read) { for (const r of t.read) { this.read[r.user.id] = { ...r, last_read: new Date(r.last_read), }; } } } getClient(): ErmisChat { return this._client; } /** * addReply - Adds or updates a latestReplies to the thread * * @param {MessageResponse} message reply message to be added. */ addReply(message: MessageResponse) { if (message.parent_id !== this.message.id) { throw new Error('Message does not belong to this thread'); } this.latestReplies = addToMessageList(this.latestReplies, formatMessage(message), true); } updateReply(message: MessageResponse) { this.latestReplies = this.latestReplies.map((m) => { if (m.id === message.id) { return formatMessage(message); } return m; }); } updateMessageOrReplyIfExists(message: MessageResponse) { if (!message.parent_id && message.id !== this.message.id) { return; } if (message.parent_id && message.parent_id !== this.message.id) { return; } if (message.parent_id && message.parent_id === this.message.id) { this.updateReply(message); return; } if (!message.parent_id && message.id === this.message.id) { this.message = formatMessage(message); } } addReaction( reaction: ReactionResponse, message?: MessageResponse, enforce_unique?: boolean, ) { if (!message) return; this.latestReplies = this.latestReplies.map((m) => { if (m.id === message.id) { return formatMessage( this._channel.state.addReaction(reaction, message, enforce_unique) as MessageResponse, ); } return m; }); } removeReaction(reaction: ReactionResponse, message?: MessageResponse) { if (!message) return; this.latestReplies = this.latestReplies.map((m) => { if (m.id === message.id) { return formatMessage( this._channel.state.removeReaction(reaction, message) as MessageResponse, ); } return m; }); } }