All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.gateway.handler.ThreadEventHandler.kt Maven / Gradle / Ivy

There is a newer version: 0.15.0
Show newest version
package dev.kord.core.gateway.handler

import dev.kord.cache.api.put
import dev.kord.cache.api.query
import dev.kord.cache.api.remove
import dev.kord.common.entity.ChannelType
import dev.kord.common.entity.optional.optionalSnowflake
import dev.kord.common.entity.optional.orEmpty
import dev.kord.core.Kord
import dev.kord.core.cache.data.*
import dev.kord.core.cache.idEq
import dev.kord.core.entity.channel.Channel
import dev.kord.core.entity.channel.thread.*
import dev.kord.core.event.channel.thread.*
import dev.kord.gateway.*

internal class ThreadEventHandler : BaseGatewayEventHandler() {

    override suspend fun handle(
        event: Event,
        shard: Int,
        kord: Kord,
        context: LazyContext?,
    ): dev.kord.core.event.Event? = when (event) {
        is ThreadCreate -> handle(event, shard, kord, context)
        is ThreadUpdate -> handle(event, shard, kord, context)
        is ThreadDelete -> handle(event, shard, kord, context)
        is ThreadListSync -> handle(event, shard, kord, context)
        is ThreadMemberUpdate -> handle(event, shard, kord, context)
        is ThreadMembersUpdate -> handle(event, shard, kord, context)
        else -> null
    }

    private suspend fun handle(event: ThreadCreate, shard: Int, kord: Kord, context: LazyContext?): ThreadChannelCreateEvent? {
        val channelData = event.channel.toData()
        kord.cache.put(channelData)

        // update lastMessageId for forum and media channels when thread is created
        // (same for other channels when message is created)
        val parentId = channelData.parentId?.value!!
        kord.cache.query {
            ChannelData::type predicate { it == ChannelType.GuildForum || it == ChannelType.GuildMedia }
            idEq(ChannelData::id, parentId)
        }.update {
            it.copy(lastMessageId = channelData.id.optionalSnowflake())
        }

        val coreEvent = when (val channel = Channel.from(channelData, kord)) {
            is NewsChannelThread -> NewsChannelThreadCreateEvent(channel, shard, context?.get())
            is TextChannelThread -> TextChannelThreadCreateEvent(channel, shard, context?.get())
            is ThreadChannel -> UnknownChannelThreadCreateEvent(channel, shard, context?.get())
            else -> return null
        }
        return coreEvent
    }

    private suspend fun handle(event: ThreadUpdate, shard: Int, kord: Kord, context: LazyContext?): ThreadUpdateEvent? {
        val channelData = event.channel.toData()
        val oldData = kord.cache.query {
            idEq(ChannelData::id, event.channel.id)
            idEq(ChannelData::guildId, event.channel.guildId.value)
        }.singleOrNull()
        kord.cache.put(channelData)

        val old = oldData?.let { ThreadChannel(it, kord) }

        val coreEvent = when (val channel = Channel.from(channelData, kord)) {
            is NewsChannelThread -> NewsChannelThreadUpdateEvent(channel, old as? NewsChannelThread, shard, context?.get())
            is TextChannelThread -> TextChannelThreadUpdateEvent(channel, old as? TextChannelThread, shard, context?.get())
            is ThreadChannel -> UnknownChannelThreadUpdateEvent(channel, old, shard, context?.get())
            else -> return null
        }

        return coreEvent

    }

    private suspend fun handle(event: ThreadDelete, shard: Int, kord: Kord, context: LazyContext?): ThreadChannelDeleteEvent {

        val channelData = event.channel.toData()
        val cachedData = kord.cache.query { idEq(ChannelData::id, channelData.id) }.singleOrNull()

        val channel = DeletedThreadChannel(channelData, kord)
        val old = cachedData?.let { Channel.from(cachedData, kord) }
        val coreEvent = when (channel.type) {
            ChannelType.PublicNewsThread -> NewsChannelThreadDeleteEvent(
                channel,
                old as? NewsChannelThread,
                shard,
                context?.get(),
            )
            ChannelType.PrivateThread,
            ChannelType.PublicGuildThread -> TextChannelThreadDeleteEvent(channel, old as? TextChannelThread, shard, context?.get())
            else -> UnknownChannelThreadDeleteEvent(channel, old as? ThreadChannel, shard, context?.get())
        }

        kord.cache.remove { idEq(ChannelData::id, channel.id) }
        return coreEvent
    }

    private suspend fun handle(event: ThreadListSync, shard: Int, kord: Kord, context: LazyContext?): ThreadListSyncEvent {
        val data = ThreadListSyncData.from(event)

        data.threads.forEach { thread ->
            kord.cache.put(thread)
        }
        data.members.forEach { member ->
            kord.cache.put(member)
        }

        return ThreadListSyncEvent(data, kord, shard, context?.get())
    }

    private suspend fun handle(event: ThreadMemberUpdate, shard: Int, kord: Kord, context: LazyContext?): ThreadMemberUpdateEvent {
        val data = ThreadMemberData.from(event.member)
        val member = ThreadMember(data, kord)
        return ThreadMemberUpdateEvent(member, kord, shard, context?.get())
    }

    private suspend fun handle(event: ThreadMembersUpdate, shard: Int, kord: Kord, context: LazyContext?): ThreadMembersUpdateEvent {
        val data = ThreadMembersUpdateEventData.from(event)
        for (removedMemberId in data.removedMemberIds.orEmpty()) {
            kord.cache.remove {
                idEq(ThreadMemberData::userId, removedMemberId)
                idEq(ThreadMemberData::id, data.id)
            }
        }
        for (addedMember in data.addedMembers.orEmpty()) {
            kord.cache.put(addedMember)
        }
        return ThreadMembersUpdateEvent(data, kord, shard, context?.get())
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy