From a046a7239223c2169a9a62244ec641e37f4a2ed3 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 14 Sep 2021 16:04:58 +0600 Subject: [PATCH] waitEditedContent* extensions --- CHANGELOG.md | 3 +- .../expectations/WaitContent.kt | 47 +++- .../expectations/WaitEditedContent.kt | 252 ++++++++++++++++++ .../triggers_handling/ContentTriggers.kt | 22 ++ 4 files changed, 309 insertions(+), 15 deletions(-) create mode 100644 tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 533ac0bbd0..a43e25fe2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ * `API`: * Two new extensions: `TelegramBot#answer` with `CallbackQuery` and `InlineQuery` * `Behaviour Builder`: - * All triggers has been changed to use two filters: filter for in subcontext data and filter for incoming data + * All triggers have been changed to use two filters: filter for in subcontext data and filter for incoming data + * New waiters for edited content ## 0.35.8 diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt index 2e3063c057..d7abb32cee 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt @@ -51,6 +51,22 @@ private suspend fun BehaviourContext.waitCommonMessage( } }.toList().toList() +internal inline fun contentConverter( + noinline mapper: CommonMessageToContentMapper? = null +): suspend CommonMessage.() -> T? = { + if (content is T) { + @Suppress("UNCHECKED_CAST") + val message = (this as CommonMessage) + if (mapper == null) { + message.content + } else { + safelyWithoutExceptions { mapper(message) } + } + } else { + null + } +} + private suspend inline fun BehaviourContext.waitContent( count: Int = 1, initRequest: Request<*>? = null, @@ -67,20 +83,9 @@ private suspend inline fun BehaviourContext.waitCon { it.withContent() ?.let { filter(it) } == true } - } -) { - if (content is T) { - @Suppress("UNCHECKED_CAST") - val message = (this as CommonMessage) - if (mapper == null) { - message.content - } else { - safelyWithoutExceptions { mapper(message) } - } - } else { - null - } -} + }, + contentConverter(mapper) +) suspend fun BehaviourContext.waitContentMessage( initRequest: Request<*>? = null, @@ -118,6 +123,20 @@ suspend fun BehaviourContext.waitLocation( filter: SimpleFilter>? = null, mapper: CommonMessageToContentMapper? = null ) = waitContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitLiveLocation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitStaticLocation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitContent(count, initRequest, false, errorFactory, filter, mapper) suspend fun BehaviourContext.waitPoll( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt new file mode 100644 index 0000000000..1077d9aa02 --- /dev/null +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt @@ -0,0 +1,252 @@ +@file:Suppress("unused") + +package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations + +import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter +import dev.inmo.tgbotapi.extensions.utils.asCommonMessage +import dev.inmo.tgbotapi.extensions.utils.withContent +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage +import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage +import dev.inmo.tgbotapi.types.message.content.* +import dev.inmo.tgbotapi.types.message.content.abstracts.* +import dev.inmo.tgbotapi.types.message.content.media.* +import dev.inmo.tgbotapi.types.message.payments.InvoiceContent +import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate +import dev.inmo.tgbotapi.types.update.abstracts.BaseEditMessageUpdate +import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate +import kotlinx.coroutines.flow.toList + +private suspend fun BehaviourContext.waitEditedCommonMessage( + count: Int = 1, + initRequest: Request<*>? = null, + includeMediaGroups: Boolean = true, + errorFactory: NullableRequestBuilder<*> = { null }, + filter: SimpleFilter>? = null, + mapper: suspend CommonMessage.() -> O? +): List = expectFlow( + initRequest, + count, + errorFactory +) { + val messages = when (it) { + is BaseEditMessageUpdate -> { + val commonMessage = it.data.asCommonMessage() + if (commonMessage !is MediaGroupMessage<*> || includeMediaGroups) { + listOf(commonMessage) + } else { + emptyList() + } + } + else -> return@expectFlow emptyList() + } + messages.mapNotNull { message -> + val asCommonMessage = message as CommonMessage + if (filter == null || filter(asCommonMessage)) { + asCommonMessage.mapper() + } else { + null + } + } +}.toList().toList() + +private suspend inline fun BehaviourContext.waitEditedContent( + count: Int = 1, + initRequest: Request<*>? = null, + includeMediaGroups: Boolean = true, + noinline errorFactory: NullableRequestBuilder<*> = { null }, + noinline filter: SimpleFilter>? = null, + noinline mapper: CommonMessageToContentMapper? = null +) : List = waitEditedCommonMessage( + count, + initRequest, + includeMediaGroups, + errorFactory, + filter ?.let { + { + it.withContent() ?.let { filter(it) } == true + } + }, + contentConverter(mapper) +) + +suspend fun BehaviourContext.waitEditedContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedContact( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedDice( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedGame( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedLocation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedLiveLocation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedStaticLocation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedPoll( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedText( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedVenue( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedAudioMediaGroupContent( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedDocumentMediaGroupContent( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedMedia( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedAnyMediaGroupContent( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedVisualMediaGroupContent( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedAnimation( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedAudio( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedDocument( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedPhoto( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedSticker( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedVideo( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedVideoNote( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedVoice( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitEditedInvoice( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToContentMapper? = null +) = waitEditedContent(count, initRequest, false, errorFactory, filter, mapper) diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt index 098372705e..dfe6d3e3ba 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt @@ -333,6 +333,28 @@ suspend fun BehaviourContext.onLocation( markerFactory, scenarioReceiver ) +suspend fun BehaviourContext.onLiveLocation( + initialFilter: CommonMessageFilter? = CommonMessageFilterExcludeMediaGroups, + updatesFilter: BehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onContent( + initialFilter, + updatesFilter, + markerFactory, + scenarioReceiver +) +suspend fun BehaviourContext.onStaticLocation( + initialFilter: CommonMessageFilter? = CommonMessageFilterExcludeMediaGroups, + updatesFilter: BehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onContent( + initialFilter, + updatesFilter, + markerFactory, + scenarioReceiver +) suspend fun BehaviourContext.onPoll( initialFilter: CommonMessageFilter? = CommonMessageFilterExcludeMediaGroups, updatesFilter: BehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat,