import { reaction } from "mobx"; import { Channel } from "revolt.js/dist/maps/Channels"; import { useLayoutEffect } from "preact/hooks"; import { dispatch } from "../../../redux"; import { Unreads } from "../../../redux/reducers/unreads"; type UnreadProps = { channel: Channel; unreads: Unreads; }; export function useUnreads({ channel, unreads }: UnreadProps) { useLayoutEffect(() => { function checkUnread(target: Channel) { if (!target) return; if (target._id !== channel._id) return; if ( target.channel_type === "SavedMessages" || target.channel_type === "VoiceChannel" ) return; const unread = unreads[channel._id]?.last_id; if (target.last_message) { const message = typeof target.last_message === "string" ? target.last_message : target.last_message._id; if (!unread || (unread && message.localeCompare(unread) > 0)) { dispatch({ type: "UNREADS_MARK_READ", channel: channel._id, message, }); channel.ack(message); } } } checkUnread(channel); return reaction( () => channel.last_message, () => checkUnread(channel), ); }, [channel, unreads]); } export function mapChannelWithUnread(channel: Channel, unreads: Unreads) { let last_message_id; if ( channel.channel_type === "DirectMessage" || channel.channel_type === "Group" ) { last_message_id = (channel.last_message as { _id: string })?._id; } else if (channel.channel_type === "TextChannel") { last_message_id = channel.last_message as string; } else { return { channel, unread: undefined, alertCount: undefined, timestamp: channel._id, }; } let unread: "mention" | "unread" | undefined; let alertCount: undefined | number; if (last_message_id && unreads) { const u = unreads[channel._id]; if (u) { if (u.mentions && u.mentions.length > 0) { alertCount = u.mentions.length; unread = "mention"; } else if ( u.last_id && (last_message_id as string).localeCompare(u.last_id) > 0 ) { unread = "unread"; } } else { unread = "unread"; } } return { channel, timestamp: last_message_id ?? channel._id, unread, alertCount, }; }