From b9341f89ac6221576227193980080d6a81ef6e37 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 8 Jan 2021 11:02:18 +0600 Subject: [PATCH] add media groups triggers and waiters --- .../expectations/WaitMediaGroup.kt | 61 +++++++++++++++ .../triggers_handling/MediaGroupTriggers.kt | 75 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt new file mode 100644 index 0000000000..f3ac40ad09 --- /dev/null +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt @@ -0,0 +1,61 @@ +package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations + +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.utils.* +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage +import dev.inmo.tgbotapi.types.message.content.abstracts.* +import dev.inmo.tgbotapi.types.message.content.media.PhotoContent +import dev.inmo.tgbotapi.types.message.content.media.VideoContent +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList + +@PreviewFeature +internal suspend inline fun BehaviourContext.onMediaGroup( + count: Int = 1, + initRequest: Request<*>? = null, + noinline errorFactory: NullableRequestBuilder<*> = { null }, + noinline filter: (suspend (List) -> Boolean)? = null +) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory) { update -> + update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup -> + if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup))) { + listOf( + mediaGroup.map { it.content as T } + ) + } else { + null + } + } ?: emptyList() +}.take(count).toList() + +suspend fun BehaviourContext.waitPlaylist( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: (suspend (List) -> Boolean)? = null +) = onMediaGroup(count, initRequest, errorFactory, filter) +suspend fun BehaviourContext.waitDocumentsGroup( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: (suspend (List) -> Boolean)? = null +) = onMediaGroup(count, initRequest, errorFactory, filter) +suspend fun BehaviourContext.waitVisualGallery( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: (suspend (List) -> Boolean)? = null +) = onMediaGroup(count, initRequest, errorFactory, filter) +suspend fun BehaviourContext.waitPhotoGallery( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: (suspend (List) -> Boolean)? = null +) = onMediaGroup(count, initRequest, errorFactory, filter) +suspend fun BehaviourContext.waitVideoGallery( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: (suspend (List) -> Boolean)? = null +) = onMediaGroup(count, initRequest, errorFactory, filter) diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt index 4adff39c3f..c3120c1a3c 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt @@ -1,2 +1,77 @@ +@file:Suppress("unused") + package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling +import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver +import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow +import dev.inmo.tgbotapi.extensions.utils.* +import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat +import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat +import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage +import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage +import dev.inmo.tgbotapi.types.message.content.ContactContent +import dev.inmo.tgbotapi.types.message.content.abstracts.* +import dev.inmo.tgbotapi.types.message.content.media.PhotoContent +import dev.inmo.tgbotapi.types.message.content.media.VideoContent +import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter +import dev.inmo.tgbotapi.utils.PreviewFeature +import kotlinx.coroutines.flow.filter + +@PreviewFeature +internal suspend inline fun BehaviourContext.onMediaGroup( + includeFilterByChatInBehaviourSubContext: Boolean = true, + noinline additionalFilter: (suspend (List) -> Boolean)? = null, + noinline scenarioReceiver: BehaviourContextAndTypeReceiver> +) = flowsUpdatesFilter.expectFlow(bot) { update -> + update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup -> + if (mediaGroup.all { message -> message.content is T } && (additionalFilter == null || additionalFilter(mediaGroup))) { + listOf(mediaGroup) + } else { + null + } + } ?: emptyList() +}.subscribeSafelyWithoutExceptions(scope) { mediaGroup -> + val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) { + val subFilter = FlowsUpdatesFilter() + val subBehaviourContext = copy(flowsUpdatesFilter = subFilter) + + flowsUpdatesFilter.allUpdatesFlow.filter { + val chat = it.sourceChat() ?: return@filter false + chat.id.chatId == mediaGroup.chat!!.id.chatId + }.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext + } else { + null to this + } + safelyWithoutExceptions { scenario.scenarioReceiver(mediaGroup) } + jobToCancel ?.cancel() +} + +suspend fun BehaviourContext.onPlaylist( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (List) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) +suspend fun BehaviourContext.onDocumentsGroup( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (List) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) +suspend fun BehaviourContext.onVisualGallery( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (List) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) +suspend fun BehaviourContext.onPhotoGallery( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (List) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) +suspend fun BehaviourContext.onVideoGallery( + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: (suspend (List) -> Boolean)? = null, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) +