Skip to content
Snippets Groups Projects
common.ts 2.71 KiB
Newer Older
insert's avatar
insert committed
import { Channel } from "revolt.js";
import { useLayoutEffect } from "preact/hooks";
import { WithDispatcher } from "../../../redux/reducers";
import { Unreads } from "../../../redux/reducers/unreads";
import { HookContext, useForceUpdate } from "../../../context/revoltjs/hooks";

type UnreadProps = WithDispatcher & {
    channel: Channel;
    unreads: Unreads;
}

export function useUnreads({ channel, unreads, dispatcher }: UnreadProps, context?: HookContext) {
    const ctx = useForceUpdate(context);

    useLayoutEffect(() => {
        function checkUnread(target?: Channel) {
            if (!target) return;
            if (target._id !== channel._id) return;
insert's avatar
insert committed
            if (target.channel_type === "SavedMessages" ||
                target.channel_type === "VoiceChannel") return;
insert's avatar
insert committed

            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)) {
                    dispatcher({
                        type: "UNREADS_MARK_READ",
                        channel: channel._id,
insert's avatar
insert committed
                        message
insert's avatar
insert committed
                    });
insert's avatar
insert committed
                    
                    ctx.client.req('PUT', `/channels/${channel._id}/ack/${message}` as '/channels/id/ack/id');
insert's avatar
insert committed
                }
            }
        }

        checkUnread(channel);

        ctx.client.channels.addListener("mutation", checkUnread);
        return () => ctx.client.channels.removeListener("mutation", checkUnread);
    }, [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?._id;
    } else if (channel.channel_type === 'TextChannel') {
        last_message_id = channel.last_message;
    } 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.localeCompare(u.last_id) > 0) {
                unread = 'unread';
            }
        } else {
            unread = 'unread';
        }
    }

    return {
        ...channel,
        timestamp: last_message_id ?? channel._id,
        unread,
        alertCount
    };
}