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.update.* import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.* 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 allUpdatesWithoutMediaGroupsGroupingFlow: Flow val messagesFlow: Flow val messageMediaGroupsFlow: Flow val editedMessagesFlow: Flow val editedMessageMediaGroupsFlow: Flow val channelPostsFlow: Flow val channelPostMediaGroupsFlow: Flow val editedChannelPostsFlow: Flow val editedChannelPostMediaGroupsFlow: Flow 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 unknownUpdatesFlow: Flow } abstract class AbstractFlowsUpdatesFilter : FlowsUpdatesFilter { override val allUpdatesWithoutMediaGroupsGroupingFlow: Flow get() = allUpdatesFlow.flatMapConcat { when (it) { is SentMediaGroupUpdate -> it.origins.asFlow() is EditMediaGroupUpdate -> flowOf(it.origin) else -> flowOf(it) } } override val messagesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val messageMediaGroupsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedMessagesFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedMessageMediaGroupsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val channelPostsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val channelPostMediaGroupsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedChannelPostsFlow: Flow by lazy { allUpdatesFlow.filterIsInstance() } override val editedChannelPostMediaGroupsFlow: 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 unknownUpdatesFlow: 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 } } @Suppress("MemberVisibilityCanBePrivate") override val allUpdatesWithoutMediaGroupsGroupingFlow: Flow = allUpdatesFlow.flatMapConcat { when (it) { is SentMediaGroupUpdate -> it.origins.asFlow() is EditMediaGroupUpdate -> flowOf(it.origin) else -> flowOf(it) } } override val asUpdateReceiver: UpdateReceiver = additionalUpdatesSharedFlow::emit }