package dev.inmo.tgbotapi.updateshandlers import dev.inmo.micro_utils.coroutines.plus import dev.inmo.tgbotapi.types.ALL_UPDATES_LIST import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage import dev.inmo.tgbotapi.types.update.* import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update import kotlinx.coroutines.channels.* import kotlinx.coroutines.flow.* interface FlowsUpdatesFilter : UpdatesFilter { override val allowedUpdates: List get() = ALL_UPDATES_LIST val allUpdatesFlow: Flow val messagesFlow: Flow val messageMediaGroupsFlow: Flow get() = messagesFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val editedMessagesFlow: Flow val editedMessageMediaGroupsFlow: Flow get() = editedMessagesFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val channelPostsFlow: Flow val channelPostMediaGroupsFlow: Flow get() = channelPostsFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val editedChannelPostsFlow: Flow val editedChannelPostMediaGroupsFlow: Flow get() = editedChannelPostsFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val chosenInlineResultsFlow: Flow val inlineQueriesFlow: Flow val callbackQueriesFlow: Flow val shippingQueriesFlow: Flow val preCheckoutQueriesFlow: Flow val pollsFlow: Flow val pollAnswersFlow: Flow val chatMemberUpdatesFlow: Flow val myChatMemberUpdatesFlow: Flow val chatJoinRequestUpdateFlow: Flow val chatMessageReactionUpdatedUpdateFlow: Flow val chatMessageReactionsCountUpdatedUpdateFlow: Flow val chatBoostUpdatedUpdateFlow: Flow val chatBoostRemovedUpdateFlow: Flow val businessConnectionUpdatesFlow: Flow val unknownUpdatesFlow: Flow } abstract class AbstractFlowsUpdatesFilter : FlowsUpdatesFilter { override val messagesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedMessagesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val channelPostsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedChannelPostsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chosenInlineResultsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val inlineQueriesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val callbackQueriesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val shippingQueriesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val preCheckoutQueriesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val pollsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val pollAnswersFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatMemberUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val myChatMemberUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatJoinRequestUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatMessageReactionUpdatedUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatMessageReactionsCountUpdatedUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val unknownUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatBoostUpdatedUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val chatBoostRemovedUpdateFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val businessConnectionUpdatesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } } /** * Creates [DefaultFlowsUpdatesFilter] */ @Suppress("FunctionName") fun FlowsUpdatesFilter( broadcastChannelsSize: Int = 100, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, upstreamUpdatesFlow: Flow? = null ) = DefaultFlowsUpdatesFilter(broadcastChannelsSize, onBufferOverflow, upstreamUpdatesFlow) @Suppress("unused") class DefaultFlowsUpdatesFilter( broadcastChannelsSize: Int = 100, onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND, upstreamUpdatesFlow: Flow? = null ): AbstractFlowsUpdatesFilter() { private val additionalUpdatesSharedFlow = MutableSharedFlow(0, broadcastChannelsSize, onBufferOverflow) @Suppress("MemberVisibilityCanBePrivate") override val allUpdatesFlow: Flow = (additionalUpdatesSharedFlow.asSharedFlow()).let { if (upstreamUpdatesFlow != null) { (it + upstreamUpdatesFlow).distinctUntilChanged { old, new -> old.updateId == new.updateId } } else { it } } override val asUpdateReceiver: UpdateReceiver = additionalUpdatesSharedFlow::emit }