diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt index b559d65f18..387872f07a 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt @@ -1,69 +1,57 @@ package dev.inmo.tgbotapi.extensions.api.InternalUtils import dev.inmo.tgbotapi.types.MediaGroupIdentifier -import dev.inmo.tgbotapi.types.UpdateIdentifier +import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage +import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent import dev.inmo.tgbotapi.types.update.* import dev.inmo.tgbotapi.types.update.abstracts.* -import dev.inmo.tgbotapi.types.update.media_group.* - -internal fun Update.lastUpdateIdentifier(): UpdateIdentifier { - return if (this is SentMediaGroupUpdate) { - origins.last().updateId - } else { - updateId - } -} - -internal fun List.lastUpdateIdentifier(): UpdateIdentifier? { - return maxByOrNull { it.updateId } ?.lastUpdateIdentifier() -} +import dev.inmo.tgbotapi.utils.extensions.asMediaGroupMessage +/** + * Will convert incoming list of updates to list with [MediaGroupUpdate]s + */ internal fun List.convertWithMediaGroupUpdates(): List { val resultUpdates = mutableListOf() - val mediaGroups = mutableMapOf>() + val mediaGroups = mutableMapOf>>>() + for (update in this) { - val data = (update.data as? MediaGroupMessage<*>) - if (data == null) { + val message = (update.data as? PossiblySentViaBotCommonMessage<*>) ?.let { + if (it.content is MediaGroupPartContent) { + it as PossiblySentViaBotCommonMessage + } else { + null + } + } + val mediaGroupId = message ?.mediaGroupId + if (message == null || mediaGroupId == null) { resultUpdates.add(update) continue } when (update) { - is BaseEditMessageUpdate -> resultUpdates.add( - update.toEditMediaGroupUpdate() - ) is BaseSentMessageUpdate -> { - mediaGroups.getOrPut(data.mediaGroupId) { + mediaGroups.getOrPut(mediaGroupId) { mutableListOf() - }.add(update) + }.add(update to message) } else -> resultUpdates.add(update) } } - mediaGroups.values.map { - it.toSentMediaGroupUpdate() ?.let { mediaGroupUpdate -> - resultUpdates.add(mediaGroupUpdate) - } + + mediaGroups.map { (_, updatesWithMessages) -> + val update = updatesWithMessages.maxBy { it.first.updateId }.first + resultUpdates.add( + update.copy(updatesWithMessages.map { it.second }.asMediaGroupMessage()) + ) } + resultUpdates.sortBy { it.updateId } return resultUpdates } -internal fun List.toSentMediaGroupUpdate(): SentMediaGroupUpdate? = (this as? SentMediaGroupUpdate) ?: let { - if (isEmpty()) { - return@let null - } - val resultList = sortedBy { it.updateId } - when (first()) { - is MessageUpdate -> MessageMediaGroupUpdate(resultList) - is ChannelPostUpdate -> ChannelPostMediaGroupUpdate(resultList) - else -> null - } -} - -internal fun BaseEditMessageUpdate.toEditMediaGroupUpdate(): EditMediaGroupUpdate = (this as? EditMediaGroupUpdate) ?: let { - when (this) { - is EditMessageUpdate -> EditMessageMediaGroupUpdate(this) - is EditChannelPostUpdate -> EditChannelPostMediaGroupUpdate(this) - else -> error("Unsupported type of ${BaseEditMessageUpdate::class.simpleName}") - } -} +/** + * @return [EditMessageMediaGroupUpdate] in case if [this] is [EditMessageUpdate]. When [this] object is + * [EditChannelPostUpdate] instance - will return [EditChannelPostMediaGroupUpdate] + * + * @throws IllegalStateException + */ +internal fun BaseEditMessageUpdate.toEditMediaGroupUpdate() = this diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/CopyMessages.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/CopyMessages.kt deleted file mode 100644 index 2ab20d94bc..0000000000 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/CopyMessages.kt +++ /dev/null @@ -1,183 +0,0 @@ -package dev.inmo.tgbotapi.extensions.api.send - -import dev.inmo.tgbotapi.bot.TelegramBot -import dev.inmo.tgbotapi.extensions.api.send.media.sendMediaGroup -import dev.inmo.tgbotapi.types.ChatIdentifier -import dev.inmo.tgbotapi.types.media.* -import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList -import dev.inmo.tgbotapi.types.MessageId -import dev.inmo.tgbotapi.types.MessageThreadId -import dev.inmo.tgbotapi.types.message.ParseMode -import dev.inmo.tgbotapi.types.chat.Chat -import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChatId: ChatIdentifier, - messages: List>, - text: String? = null, - parseMode: ParseMode? = null, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -): List> { - val first = messages.first().content.toMediaGroupMemberTelegramMedia().let { - if (text != null) { - when (it) { - is TelegramMediaAudio -> it.copy(text = text, parseMode = parseMode) - is TelegramMediaDocument -> it.copy(text = text, parseMode = parseMode) - is TelegramMediaPhoto -> it.copy(text = text, parseMode = parseMode) - is TelegramMediaVideo -> it.copy(text = text, parseMode = parseMode) - } - } else { - it - } - } - - return sendMediaGroup( - toChatId, - listOf(first) + messages.drop(1).map { - it.content.toMediaGroupMemberTelegramMedia() - }, - threadId, - disableNotification, - protectContent, - replyToMessageId, - allowSendingWithoutReply - ) -} - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: Chat, - messages: List>, - text: String? = null, - parseMode: ParseMode? = null, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat.id, messages, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: ChatIdentifier, - update: SentMediaGroupUpdate, - text: String? = null, - parseMode: ParseMode? = null, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat, update.data, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: Chat, - update: SentMediaGroupUpdate, - text: String? = null, - parseMode: ParseMode? = null, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat.id, update, text, parseMode, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChatId: ChatIdentifier, - messages: List>, - entities: TextSourcesList, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -): List> { - val first = messages.first().content.toMediaGroupMemberTelegramMedia().let { - when (it) { - is TelegramMediaAudio -> TelegramMediaAudio(it.file, entities, it.duration, it.performer, it.title, it.thumb) - is TelegramMediaDocument -> TelegramMediaDocument(it.file, entities, it.thumb, it.disableContentTypeDetection) - is TelegramMediaPhoto -> TelegramMediaPhoto(it.file, entities) - is TelegramMediaVideo -> TelegramMediaVideo(it.file, entities, it.width, it.height, it.duration, it.thumb) - } - } - - return sendMediaGroup( - toChatId, - listOf(first) + messages.drop(1).map { - it.content.toMediaGroupMemberTelegramMedia() - }, - threadId, - disableNotification, - protectContent, - replyToMessageId, - allowSendingWithoutReply - ) -} - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: Chat, - messages: List>, - entities: TextSourcesList, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat.id, messages, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: ChatIdentifier, - update: SentMediaGroupUpdate, - entities: TextSourcesList, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat, update.data, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) - -/** - * Send media group via [sendMediaGroup] extension with edited [entities] of first [messages] element. Other elements - * will be copied as they are - */ -suspend inline fun TelegramBot.copyMessages( - toChat: Chat, - update: SentMediaGroupUpdate, - entities: TextSourcesList, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyToMessageId: MessageId? = null, - allowSendingWithoutReply: Boolean? = null -) = copyMessages(toChat.id, update, entities, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply) diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt index 16e695fe1f..1c660b8ad2 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.extensions.api.utils import dev.inmo.tgbotapi.extensions.api.InternalUtils.convertWithMediaGroupUpdates +import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver @@ -29,10 +30,21 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation( launch { launch { for (update in updatesChannel) { - when (val data = update.data) { - is MediaGroupMessage<*> -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate) - else -> output(update) + val dataAsPossiblySentViaBotCommonMessage = update.data as? PossiblySentViaBotCommonMessage<*> + + if (dataAsPossiblySentViaBotCommonMessage == null) { + output(update) + continue } + + val mediaGroupId = dataAsPossiblySentViaBotCommonMessage.mediaGroupId + + if (mediaGroupId == null) { + output(update) + continue + } + + mediaGroupChannel.send("${mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate) } } launch { diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt index 818da8ce2b..d908e016dd 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt @@ -9,7 +9,6 @@ import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage import kotlinx.coroutines.flow.Flow @@ -25,20 +24,7 @@ suspend inline fun BehaviourContext.waitContentMess initRequest, errorFactory ) { - val messages = when (it) { - is SentMediaGroupUpdate -> { - if (includeMediaGroups) { - it.data - } else { - emptyList() - } - } - is BaseSentMessageUpdate -> listOf(it.data) - else -> return@expectFlow emptyList() - } - messages.mapNotNull { message -> - (message as? CommonMessage<*>) ?.withContent() - } + listOfNotNull((it.data as? CommonMessage<*>) ?.withContent()) } internal inline fun contentMessageConverter( diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt index 7bac69114d..c78ab0452a 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContent.kt @@ -15,7 +15,7 @@ suspend inline fun BehaviourContext.waitEditedConte initRequest: Request<*>? = null, includeMediaGroups: Boolean = true, noinline errorFactory: NullableRequestBuilder<*> = { null } -): Flow = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory).map { it.content } +): Flow = waitEditedContentMessage(initRequest, errorFactory).map { it.content } suspend fun BehaviourContext.waitEditedMessageContent( initRequest: Request<*>? = null, diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContentMessage.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContentMessage.kt index 9b39b1f911..99d14d8d0b 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContentMessage.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEditedContentMessage.kt @@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.utils.baseEditMessageUpdateOrNull import dev.inmo.tgbotapi.extensions.utils.commonMessageOrNull import dev.inmo.tgbotapi.extensions.utils.withContent import dev.inmo.tgbotapi.requests.abstracts.Request @@ -16,7 +17,6 @@ import kotlinx.coroutines.flow.Flow @RiskFeature(lowLevelRiskFeatureMessage) suspend inline fun BehaviourContext.waitEditedContentMessage( initRequest: Request<*>? = null, - includeMediaGroups: Boolean = true, noinline errorFactory: NullableRequestBuilder<*> = { null } ): Flow> = expectFlow( initRequest, @@ -25,11 +25,7 @@ suspend inline fun BehaviourContext.waitEditedConte val messages = when (it) { is BaseEditMessageUpdate -> { val commonMessage = it.data.commonMessageOrNull() ?: return@expectFlow emptyList() - if (commonMessage !is MediaGroupMessage<*> || includeMediaGroups) { - listOf(commonMessage) - } else { - emptyList() - } + listOf(commonMessage) } else -> return@expectFlow emptyList() } @@ -40,109 +36,103 @@ suspend inline fun BehaviourContext.waitEditedConte suspend fun BehaviourContext.waitEditedMessageContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedContactMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedDiceMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedGameMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedLocationMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedLiveLocationMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedStaticLocationMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedTextMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedVenueMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedAudioMediaGroupContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedDocumentMediaGroupContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedMediaMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, includeMediaGroups: Boolean = false -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedAnyMediaGroupContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedVisualMediaGroupContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedTextedMediaContentMessage( initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null }, - includeMediaGroups: Boolean = true -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedAnimationMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedAudioMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, includeMediaGroups: Boolean = false -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedDocumentMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, includeMediaGroups: Boolean = false -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedPhotoMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, includeMediaGroups: Boolean = false -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedStickerMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedVideoMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, includeMediaGroups: Boolean = false -) = waitEditedContentMessage(initRequest, includeMediaGroups, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedVideoNoteMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedVoiceMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) suspend fun BehaviourContext.waitEditedInvoiceMessage( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } -) = waitEditedContentMessage(initRequest, false, errorFactory) +) = waitEditedContentMessage(initRequest, errorFactory) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt deleted file mode 100644 index 5e38f5555e..0000000000 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt +++ /dev/null @@ -1,44 +0,0 @@ -package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations - -import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext -import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter -import dev.inmo.tgbotapi.requests.abstracts.Request -import dev.inmo.tgbotapi.types.message.content.* -import dev.inmo.tgbotapi.utils.RiskFeature -import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map - -typealias MediaGroupFilter = SimpleFilter>> - - -@RiskFeature(lowLevelRiskFeatureMessage) -suspend inline fun BehaviourContext.buildMediaGroupWaiter( - initRequest: Request<*>? = null, - noinline errorFactory: NullableRequestBuilder<*> = { null } -): Flow> = buildMediaGroupMessagesWaiter(initRequest, errorFactory).map { it.map { it.content } } - -suspend fun BehaviourContext.waitMediaGroup( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitPlaylist( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitDocumentsGroup( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitVisualGallery( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitPhotoGallery( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitVideoGallery( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupWaiter(initRequest, errorFactory) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroupMessages.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroupMessages.kt deleted file mode 100644 index 828a582942..0000000000 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroupMessages.kt +++ /dev/null @@ -1,48 +0,0 @@ -package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations - -import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext -import dev.inmo.tgbotapi.extensions.utils.sentMediaGroupUpdateOrNull -import dev.inmo.tgbotapi.extensions.utils.withContent -import dev.inmo.tgbotapi.requests.abstracts.Request -import dev.inmo.tgbotapi.types.message.content.* -import dev.inmo.tgbotapi.utils.RiskFeature -import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage -import kotlinx.coroutines.flow.Flow - -@RiskFeature(lowLevelRiskFeatureMessage) -suspend inline fun BehaviourContext.buildMediaGroupMessagesWaiter( - initRequest: Request<*>? = null, - noinline errorFactory: NullableRequestBuilder<*> = { null } -): Flow>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update -> - update.sentMediaGroupUpdateOrNull() ?.data ?.let { mediaGroup -> - val mapped = mediaGroup.mapNotNull { it.withContent() } - listOf( - mapped - ) - } ?: emptyList() -} - -suspend fun BehaviourContext.waitMediaGroupMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitPlaylistMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitDocumentsGroupMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitVisualGalleryMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitPhotoGalleryMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) -suspend fun BehaviourContext.waitVideoGalleryMessages( - initRequest: Request<*>? = null, - errorFactory: NullableRequestBuilder<*> = { null } -) = buildMediaGroupMessagesWaiter(initRequest, errorFactory) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterExcludingMediaGroups.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterExcludingMediaGroups.kt index 60389a5ecf..aa22050056 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterExcludingMediaGroups.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/filters/MessageFilterExcludingMediaGroups.kt @@ -3,18 +3,13 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.filters import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.types.message.abstracts.* +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.MediaGroupMessage import dev.inmo.tgbotapi.types.update.abstracts.Update -/** - * Allow only messages which are not [MediaGroupMessage] - */ -val MessageFilterExcludingMediaGroups: BehaviourContextAndTwoTypesReceiver, Update> = { _, update -> - update !is MediaGroupMessage<*> -} - /** * Allow only messages which are not [MediaGroupMessage] */ val CommonMessageFilterExcludeMediaGroups = SimpleFilter { - it !is MediaGroupMessage<*> + it !is CommonMessage<*> || it.content !is MediaGroupContent } diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt index 4971de586e..d83be5e0f5 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt @@ -14,7 +14,6 @@ import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate typealias CommonMessageFilter = SimpleFilter> @@ -26,7 +25,6 @@ internal suspend inline fun ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { when (it) { is BaseSentMessageUpdate -> it.data.whenCommonMessage(::listOfNotNull) - is SentMediaGroupUpdate -> it.data else -> null } ?.mapNotNull { message -> if (message.content is T) message as CommonMessage else null diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt deleted file mode 100644 index 5394ec31b4..0000000000 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt +++ /dev/null @@ -1,160 +0,0 @@ -@file:Suppress("unused") - -package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling - -import dev.inmo.tgbotapi.extensions.behaviour_builder.* -import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessagesFilterByChat -import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter -import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMediaGroupMarkerFactory -import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory -import dev.inmo.tgbotapi.extensions.utils.sentMediaGroupUpdateOrNull -import dev.inmo.tgbotapi.types.message.content.* -import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.utils.PreviewFeature - -@PreviewFeature -internal suspend inline fun BC.buildMediaGroupTrigger( - initialFilter: SimpleFilter>>? = null, - noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { - (it.sentMediaGroupUpdateOrNull() ?.data ?.takeIf { messages -> - messages.all { message -> - message.content is T - } - } as? List>) ?.let(::listOfNotNull) -} - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onMediaGroup( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onPlaylist( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onDocumentsGroup( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onVisualGallery( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onVisualMediaGroup( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = onVisualGallery(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onPhotoGallery( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) - -/** - * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call - * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, - * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. - * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] - * to combinate several filters - * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously - * in one "stream". Output of [markerFactory] will be used as a key for "stream" - * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that - * data - */ -suspend fun BC.onVideoGallery( - initialFilter: SimpleFilter>>? = null, - subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update>? = MessagesFilterByChat, - markerFactory: MarkerFactory>, Any> = ByChatMediaGroupMarkerFactory, - scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = buildMediaGroupTrigger(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MediaGroupMarkerFactories.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MediaGroupMarkerFactories.kt deleted file mode 100644 index e4e0a5838b..0000000000 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/marker_factories/MediaGroupMarkerFactories.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories - -import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat - -object ByChatMediaGroupMarkerFactory : MarkerFactory>, Any> { - override suspend fun invoke(data: List>) = data.chat ?: error("Data must not be empty") -} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt index 6f2f59fbc1..2af4378fae 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt @@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.MediaGroupIdentifier import dev.inmo.tgbotapi.types.MessageId +import dev.inmo.tgbotapi.types.MessageThreadId import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.TelegramMediaFile import dev.inmo.tgbotapi.types.media.TelegramMedia @@ -31,6 +32,7 @@ data class MediaGroupContent( override fun createResend( chatId: ChatIdentifier, + threadId: MessageThreadId?, disableNotification: Boolean, protectContent: Boolean, replyToMessageId: MessageId?, @@ -39,10 +41,10 @@ data class MediaGroupContent( ): Request = SendMediaGroup( chatId, group.map { it.content.toMediaGroupMemberTelegramMedia() }, + threadId, disableNotification, protectContent, replyToMessageId, - allowSendingWithoutReply, - replyMarkup + allowSendingWithoutReply ) } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Typealiases.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Typealiases.kt index f14628d24e..03ca71bfeb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Typealiases.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Typealiases.kt @@ -20,7 +20,7 @@ typealias VideoNoteMessage = CommonMessage typealias StickerMessage = CommonMessage typealias TextedMediaMessage = CommonMessage typealias VoiceMessage = CommonMessage -typealias MediaGroupMessage = CommonMessage +typealias MediaGroupMessage = CommonMessage typealias AudioMediaGroupMessage = CommonMessage typealias AudioMessage = CommonMessage typealias DocumentMediaGroupMessage = CommonMessage diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt index c3265bc419..2e9c700266 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter.kt @@ -2,10 +2,11 @@ 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.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.flow.* @@ -13,16 +14,22 @@ interface FlowsUpdatesFilter : UpdatesFilter { override val allowedUpdates: List get() = ALL_UPDATES_LIST val allUpdatesFlow: Flow + @Deprecated("Since 4.0.0 is not actual", ReplaceWith("allUpdatesFlow")) val allUpdatesWithoutMediaGroupsGroupingFlow: Flow + get() = allUpdatesFlow val messagesFlow: Flow - val messageMediaGroupsFlow: Flow + val messageMediaGroupsFlow: Flow + get() = messagesFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val editedMessagesFlow: Flow - val editedMessageMediaGroupsFlow: Flow + val editedMessageMediaGroupsFlow: Flow + get() = editedMessagesFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val channelPostsFlow: Flow - val channelPostMediaGroupsFlow: Flow + val channelPostMediaGroupsFlow: Flow + get() = channelPostsFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val editedChannelPostsFlow: Flow - val editedChannelPostMediaGroupsFlow: Flow + val editedChannelPostMediaGroupsFlow: Flow + get() = editedChannelPostsFlow.filter { (it.data as? PossiblySentViaBotCommonMessage<*>) ?.mediaGroupId != null } val chosenInlineResultsFlow: Flow val inlineQueriesFlow: Flow val callbackQueriesFlow: Flow @@ -37,23 +44,10 @@ interface FlowsUpdatesFilter : UpdatesFilter { } 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() } @@ -92,14 +86,6 @@ class DefaultFlowsUpdatesFilter( 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 } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/UpdatesFilter.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/UpdatesFilter.kt index 4704a4c9d5..cfb0dc2a26 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/UpdatesFilter.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/updateshandlers/UpdatesFilter.kt @@ -1,10 +1,6 @@ package dev.inmo.tgbotapi.updateshandlers -import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.update.* -import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.* typealias UpdateReceiver = suspend (T) -> Unit @@ -12,111 +8,3 @@ interface UpdatesFilter { val asUpdateReceiver: UpdateReceiver val allowedUpdates: List } - -data class SimpleUpdatesFilter( - private val messageCallback: UpdateReceiver? = null, - private val messageMediaGroupCallback: UpdateReceiver? = null, - private val editedMessageCallback: UpdateReceiver? = null, - private val editedMessageMediaGroupCallback: UpdateReceiver? = null, - private val channelPostCallback: UpdateReceiver? = null, - private val channelPostMediaGroupCallback: UpdateReceiver? = null, - private val editedChannelPostCallback: UpdateReceiver? = null, - private val editedChannelPostMediaGroupCallback: UpdateReceiver? = null, - private val chosenInlineResultCallback: UpdateReceiver? = null, - private val inlineQueryCallback: UpdateReceiver? = null, - private val callbackQueryCallback: UpdateReceiver? = null, - private val shippingQueryCallback: UpdateReceiver? = null, - private val preCheckoutQueryCallback: UpdateReceiver? = null, - private val pollUpdateCallback: UpdateReceiver? = null, - private val pollAnswerUpdateCallback: UpdateReceiver? = null, - private val unknownUpdateTypeCallback: UpdateReceiver? = null -) : UpdatesFilter { - override val asUpdateReceiver: UpdateReceiver = this::invoke - override val allowedUpdates = listOfNotNull( - (messageCallback ?: messageMediaGroupCallback) ?.let { UPDATE_MESSAGE }, - (editedMessageCallback ?: editedMessageMediaGroupCallback) ?.let { UPDATE_EDITED_MESSAGE }, - (channelPostCallback ?: channelPostMediaGroupCallback) ?.let { UPDATE_CHANNEL_POST }, - (editedChannelPostCallback ?: editedChannelPostMediaGroupCallback) ?.let { UPDATE_EDITED_CHANNEL_POST }, - chosenInlineResultCallback ?.let { UPDATE_CHOSEN_INLINE_RESULT }, - inlineQueryCallback ?.let { UPDATE_INLINE_QUERY }, - callbackQueryCallback ?.let { UPDATE_CALLBACK_QUERY }, - shippingQueryCallback ?.let { UPDATE_SHIPPING_QUERY }, - preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY }, - pollUpdateCallback ?.let { UPDATE_POLL }, - pollAnswerUpdateCallback ?.let { UPDATE_POLL_ANSWER } - ) - - suspend fun invoke(update: Update) { - when (update) { - is MessageUpdate -> messageCallback ?.invoke(update) - is MessageMediaGroupUpdate -> messageMediaGroupCallback ?.also { receiver -> - receiver(update) - } ?: messageCallback ?.also { receiver -> - update.origins.mapNotNull { it as? MessageUpdate }.forEach { - receiver(it) - } - } - is EditMessageUpdate -> editedMessageCallback ?.invoke(update) - is EditMessageMediaGroupUpdate -> editedMessageMediaGroupCallback ?.also { receiver -> - receiver(update) - } ?: editedMessageCallback ?.also { receiver -> - receiver(update.origin) - } - is ChannelPostUpdate -> channelPostCallback ?.invoke(update) - is ChannelPostMediaGroupUpdate -> channelPostMediaGroupCallback ?.also { receiver -> - receiver(update) - } ?: channelPostCallback ?.also { receiver -> - update.origins.mapNotNull { it as? ChannelPostUpdate }.forEach { - receiver(it) - } - } - is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(update) - is EditChannelPostMediaGroupUpdate -> editedChannelPostMediaGroupCallback ?.also { receiver -> - receiver(update) - } ?: editedChannelPostCallback ?.also { receiver -> - receiver(update.origin) - } - is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(update) - is InlineQueryUpdate -> inlineQueryCallback ?.invoke(update) - is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(update) - is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update) - is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update) - is PollUpdate -> pollUpdateCallback ?.invoke(update) - is PollAnswerUpdate -> pollAnswerUpdateCallback ?.invoke(update) - is UnknownUpdate -> unknownUpdateTypeCallback ?.invoke(update) - } - } -} - -fun createSimpleUpdateFilter( - messageCallback: UpdateReceiver? = null, - mediaGroupCallback: UpdateReceiver? = null, - editedMessageCallback: UpdateReceiver? = null, - channelPostCallback: UpdateReceiver? = null, - editedChannelPostCallback: UpdateReceiver? = null, - chosenInlineResultCallback: UpdateReceiver? = null, - inlineQueryCallback: UpdateReceiver? = null, - callbackQueryCallback: UpdateReceiver? = null, - shippingQueryCallback: UpdateReceiver? = null, - preCheckoutQueryCallback: UpdateReceiver? = null, - pollCallback: UpdateReceiver? = null, - pollAnswerCallback: UpdateReceiver? = null, - unknownCallback: UpdateReceiver? = null -): UpdatesFilter = SimpleUpdatesFilter( - messageCallback = messageCallback, - messageMediaGroupCallback = mediaGroupCallback, - editedMessageCallback = editedMessageCallback, - editedMessageMediaGroupCallback = mediaGroupCallback, - channelPostCallback = channelPostCallback, - channelPostMediaGroupCallback = mediaGroupCallback, - editedChannelPostCallback = editedChannelPostCallback, - editedChannelPostMediaGroupCallback = mediaGroupCallback, - chosenInlineResultCallback = chosenInlineResultCallback, - inlineQueryCallback = inlineQueryCallback, - callbackQueryCallback = callbackQueryCallback, - shippingQueryCallback = shippingQueryCallback, - preCheckoutQueryCallback = preCheckoutQueryCallback, - pollUpdateCallback = pollCallback, - pollAnswerUpdateCallback = pollAnswerCallback, - unknownUpdateTypeCallback = unknownCallback -) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index a2e1c1dfba..0bf559a79a 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -46,7 +46,6 @@ import dev.inmo.tgbotapi.types.polls.* import dev.inmo.tgbotapi.types.queries.callback.* import dev.inmo.tgbotapi.types.update.* import dev.inmo.tgbotapi.types.update.abstracts.* -import dev.inmo.tgbotapi.types.update.media_group.* import dev.inmo.tgbotapi.utils.PreviewFeature @PreviewFeature @@ -1036,18 +1035,6 @@ inline fun Message.asChannelEventMessage(): ChannelEventMessage? = inline fun Message.requireChannelEventMessage(): ChannelEventMessage = this as ChannelEventMessage -@PreviewFeature -inline fun Message.whenChannelMediaGroupMessage(block: (ChannelMediaGroupMessage) -> T) = - asChannelMediaGroupMessage()?.let(block) - -@PreviewFeature -inline fun Message.asChannelMediaGroupMessage(): ChannelMediaGroupMessage? = - this as? ChannelMediaGroupMessage - -@PreviewFeature -inline fun Message.requireChannelMediaGroupMessage(): ChannelMediaGroupMessage = - this as ChannelMediaGroupMessage - @PreviewFeature inline fun Message.whenCommonGroupEventMessage(block: (CommonGroupEventMessage) -> T) = asCommonGroupEventMessage()?.let(block) @@ -1060,18 +1047,6 @@ inline fun Message.asCommonGroupEventMessage(): CommonGroupEventMessage = this as CommonGroupEventMessage -@PreviewFeature -inline fun Message.whenCommonMediaGroupMessage(block: (CommonMediaGroupMessage) -> T) = - asCommonMediaGroupMessage()?.let(block) - -@PreviewFeature -inline fun Message.asCommonMediaGroupMessage(): CommonMediaGroupMessage? = - this as? CommonMediaGroupMessage - -@PreviewFeature -inline fun Message.requireCommonMediaGroupMessage(): CommonMediaGroupMessage = - this as CommonMediaGroupMessage - @PreviewFeature inline fun Message.whenCommonSupergroupEventMessage(block: (CommonSupergroupEventMessage) -> T) = asCommonSupergroupEventMessage()?.let(block) @@ -1219,16 +1194,16 @@ inline fun Message.requireGroupContentMessage(): GroupContentMessage @PreviewFeature -inline fun Message.whenMediaGroupMessage(block: (MediaGroupMessage) -> T) = +inline fun Message.whenMediaGroupMessage(block: (MediaGroupMessage) -> T) = asMediaGroupMessage()?.let(block) @PreviewFeature -inline fun Message.asMediaGroupMessage(): MediaGroupMessage? = - this as? MediaGroupMessage +inline fun Message.asMediaGroupMessage(): MediaGroupMessage? = + this as? MediaGroupMessage @PreviewFeature -inline fun Message.requireMediaGroupMessage(): MediaGroupMessage = - this as MediaGroupMessage +inline fun Message.requireMediaGroupMessage(): MediaGroupMessage = + this as MediaGroupMessage @PreviewFeature inline fun Message.whenPossiblyEditedMessage(block: (PossiblyEditedMessage) -> T) = @@ -2218,79 +2193,6 @@ inline fun Update.asInlineQueryUpdate(): InlineQueryUpdate? = this as? InlineQue @PreviewFeature inline fun Update.requireInlineQueryUpdate(): InlineQueryUpdate = this as InlineQueryUpdate -@PreviewFeature -inline fun Update.whenChannelPostMediaGroupUpdate(block: (ChannelPostMediaGroupUpdate) -> T) = - asChannelPostMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asChannelPostMediaGroupUpdate(): ChannelPostMediaGroupUpdate? = this as? ChannelPostMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireChannelPostMediaGroupUpdate(): ChannelPostMediaGroupUpdate = - this as ChannelPostMediaGroupUpdate - -@PreviewFeature -inline fun Update.whenEditChannelPostMediaGroupUpdate(block: (EditChannelPostMediaGroupUpdate) -> T) = - asEditChannelPostMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asEditChannelPostMediaGroupUpdate(): EditChannelPostMediaGroupUpdate? = - this as? EditChannelPostMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireEditChannelPostMediaGroupUpdate(): EditChannelPostMediaGroupUpdate = - this as EditChannelPostMediaGroupUpdate - -@PreviewFeature -inline fun Update.whenEditMediaGroupUpdate(block: (EditMediaGroupUpdate) -> T) = - asEditMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asEditMediaGroupUpdate(): EditMediaGroupUpdate? = this as? EditMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireEditMediaGroupUpdate(): EditMediaGroupUpdate = this as EditMediaGroupUpdate - -@PreviewFeature -inline fun Update.whenEditMessageMediaGroupUpdate(block: (EditMessageMediaGroupUpdate) -> T) = - asEditMessageMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asEditMessageMediaGroupUpdate(): EditMessageMediaGroupUpdate? = this as? EditMessageMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireEditMessageMediaGroupUpdate(): EditMessageMediaGroupUpdate = - this as EditMessageMediaGroupUpdate - -@PreviewFeature -inline fun Update.whenMediaGroupUpdate(block: (MediaGroupUpdate) -> T) = asMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asMediaGroupUpdate(): MediaGroupUpdate? = this as? MediaGroupUpdate - -@PreviewFeature -inline fun Update.requireMediaGroupUpdate(): MediaGroupUpdate = this as MediaGroupUpdate - -@PreviewFeature -inline fun Update.whenMessageMediaGroupUpdate(block: (MessageMediaGroupUpdate) -> T) = - asMessageMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asMessageMediaGroupUpdate(): MessageMediaGroupUpdate? = this as? MessageMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireMessageMediaGroupUpdate(): MessageMediaGroupUpdate = this as MessageMediaGroupUpdate - -@PreviewFeature -inline fun Update.whenSentMediaGroupUpdate(block: (SentMediaGroupUpdate) -> T) = - asSentMediaGroupUpdate()?.let(block) - -@PreviewFeature -inline fun Update.asSentMediaGroupUpdate(): SentMediaGroupUpdate? = this as? SentMediaGroupUpdate - -@PreviewFeature -inline fun Update.requireSentMediaGroupUpdate(): SentMediaGroupUpdate = this as SentMediaGroupUpdate - @PreviewFeature inline fun Update.whenMessageUpdate(block: (MessageUpdate) -> T) = asMessageUpdate()?.let(block) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt index aa69edf531..123c9dfb6f 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt @@ -280,8 +280,10 @@ import dev.inmo.tgbotapi.types.message.abstracts.GroupEventMessage import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.PossiblyEditedMessage import dev.inmo.tgbotapi.types.message.abstracts.PossiblyForwardedMessage +import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.PossiblyPaymentMessage import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage +import dev.inmo.tgbotapi.types.message.abstracts.PossiblyTopicMessage import dev.inmo.tgbotapi.types.message.abstracts.PrivateContentMessage import dev.inmo.tgbotapi.types.message.abstracts.PublicContentMessage import dev.inmo.tgbotapi.types.message.abstracts.SignedMessage @@ -301,6 +303,8 @@ import dev.inmo.tgbotapi.types.message.content.LiveLocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.MediaCollectionContent import dev.inmo.tgbotapi.types.message.content.MediaContent +import dev.inmo.tgbotapi.types.message.content.MediaGroupCollectionContent +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.PhotoContent @@ -438,13 +442,6 @@ import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.ChatMemberUpdatedUpdate import dev.inmo.tgbotapi.types.update.abstracts.UnknownUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.ChannelPostMediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.EditChannelPostMediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.EditMediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.EditMessageMediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.MediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.MessageMediaGroupUpdate -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate import kotlin.Suppress public inline fun CommonSendInvoiceData.createInvoiceLinkOrNull(): CreateInvoiceLink? = this as? @@ -738,18 +735,6 @@ public inline fun WithUser.ifCommonGroupEventMessage(block: (CommonGroupEventMessage) -> T): T? = commonGroupEventMessageOrNull() ?.let(block) -public inline fun WithUser.commonMediaGroupMessageOrNull(): - CommonMediaGroupMessage? = this as? - dev.inmo.tgbotapi.types.message.CommonMediaGroupMessage - -public inline fun WithUser.commonMediaGroupMessageOrThrow(): - CommonMediaGroupMessage = this as - dev.inmo.tgbotapi.types.message.CommonMediaGroupMessage - -public inline fun - WithUser.ifCommonMediaGroupMessage(block: (CommonMediaGroupMessage) -> T): T? - = commonMediaGroupMessageOrNull() ?.let(block) - public inline fun WithUser.commonSupergroupEventMessageOrNull(): CommonSupergroupEventMessage? = this as? dev.inmo.tgbotapi.types.message.CommonSupergroupEventMessage @@ -3032,18 +3017,6 @@ public inline fun Message.ifChannelEventMessage(block: (ChannelEventMessage) -> T): T? = channelEventMessageOrNull() ?.let(block) -public inline fun Message.channelMediaGroupMessageOrNull(): - ChannelMediaGroupMessage? = this as? - dev.inmo.tgbotapi.types.message.ChannelMediaGroupMessage - -public inline fun Message.channelMediaGroupMessageOrThrow(): - ChannelMediaGroupMessage = this as - dev.inmo.tgbotapi.types.message.ChannelMediaGroupMessage - -public inline fun - Message.ifChannelMediaGroupMessage(block: (ChannelMediaGroupMessage) -> T): - T? = channelMediaGroupMessageOrNull() ?.let(block) - public inline fun Message.commonGroupEventMessageOrNull(): CommonGroupEventMessage? = this as? dev.inmo.tgbotapi.types.message.CommonGroupEventMessage @@ -3056,18 +3029,6 @@ public inline fun Message.ifCommonGroupEventMessage(block: (CommonGroupEventMessage) -> T): T? = commonGroupEventMessageOrNull() ?.let(block) -public inline fun Message.commonMediaGroupMessageOrNull(): - CommonMediaGroupMessage? = this as? - dev.inmo.tgbotapi.types.message.CommonMediaGroupMessage - -public inline fun Message.commonMediaGroupMessageOrThrow(): - CommonMediaGroupMessage = this as - dev.inmo.tgbotapi.types.message.CommonMediaGroupMessage - -public inline fun - Message.ifCommonMediaGroupMessage(block: (CommonMediaGroupMessage) -> T): T? - = commonMediaGroupMessageOrNull() ?.let(block) - public inline fun Message.commonSupergroupEventMessageOrNull(): CommonSupergroupEventMessage? = this as? dev.inmo.tgbotapi.types.message.CommonSupergroupEventMessage @@ -3372,17 +3333,6 @@ public inline fun Message.ifCommonForumContentMessage(block: (CommonForumContentMessage) -> T): T? = commonForumContentMessageOrNull() ?.let(block) -public inline fun Message.mediaGroupMessageOrNull(): MediaGroupMessage? = this - as? - dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage - -public inline fun Message.mediaGroupMessageOrThrow(): MediaGroupMessage = this as - dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage - -public inline fun - Message.ifMediaGroupMessage(block: (MediaGroupMessage) -> T): T? = - mediaGroupMessageOrNull() ?.let(block) - public inline fun Message.unknownMessageTypeOrNull(): UnknownMessageType? = this as? dev.inmo.tgbotapi.types.message.abstracts.UnknownMessageType @@ -3410,6 +3360,18 @@ public inline fun Message.possiblyForwardedMessageOrThrow(): PossiblyForwardedMe public inline fun Message.ifPossiblyForwardedMessage(block: (PossiblyForwardedMessage) -> T): T? = possiblyForwardedMessageOrNull() ?.let(block) +public inline fun Message.possiblyMediaGroupMessageOrNull(): + PossiblyMediaGroupMessage? = this as? + dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage + +public inline fun Message.possiblyMediaGroupMessageOrThrow(): + PossiblyMediaGroupMessage = this as + dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage + +public inline fun + Message.ifPossiblyMediaGroupMessage(block: (PossiblyMediaGroupMessage) -> T): T? + = possiblyMediaGroupMessageOrNull() ?.let(block) + public inline fun Message.possiblyPaymentMessageOrNull(): PossiblyPaymentMessage? = this as? dev.inmo.tgbotapi.types.message.abstracts.PossiblyPaymentMessage @@ -3431,6 +3393,15 @@ public inline fun Message.ifPossiblySentViaBotCommonMessage(block: (PossiblySentViaBotCommonMessage) -> T): T? = possiblySentViaBotCommonMessageOrNull() ?.let(block) +public inline fun Message.possiblyTopicMessageOrNull(): PossiblyTopicMessage? = this as? + dev.inmo.tgbotapi.types.message.abstracts.PossiblyTopicMessage + +public inline fun Message.possiblyTopicMessageOrThrow(): PossiblyTopicMessage = this as + dev.inmo.tgbotapi.types.message.abstracts.PossiblyTopicMessage + +public inline fun Message.ifPossiblyTopicMessage(block: (PossiblyTopicMessage) -> T): T? = + possiblyTopicMessageOrNull() ?.let(block) + public inline fun Message.privateContentMessageOrNull(): PrivateContentMessage? = this as? dev.inmo.tgbotapi.types.message.abstracts.PrivateContentMessage @@ -3506,34 +3477,27 @@ public inline fun ResendableContent.mediaContentOrThrow(): MediaContent = this a public inline fun ResendableContent.ifMediaContent(block: (MediaContent) -> T): T? = mediaContentOrNull() ?.let(block) -public inline fun ResendableContent.audioMediaGroupContentOrNull(): AudioMediaGroupPartContent? = this - as? dev.inmo.tgbotapi.types.message.content.AudioMediaGroupPartContent +public inline fun ResendableContent.audioMediaGroupPartContentOrNull(): AudioMediaGroupPartContent? + = this as? dev.inmo.tgbotapi.types.message.content.AudioMediaGroupPartContent -public inline fun ResendableContent.audioMediaGroupContentOrThrow(): AudioMediaGroupPartContent = this - as dev.inmo.tgbotapi.types.message.content.AudioMediaGroupPartContent +public inline fun ResendableContent.audioMediaGroupPartContentOrThrow(): AudioMediaGroupPartContent + = this as dev.inmo.tgbotapi.types.message.content.AudioMediaGroupPartContent public inline fun - ResendableContent.ifAudioMediaGroupContent(block: (AudioMediaGroupPartContent) -> T): T? = - audioMediaGroupContentOrNull() ?.let(block) + ResendableContent.ifAudioMediaGroupPartContent(block: (AudioMediaGroupPartContent) -> T): T? = + audioMediaGroupPartContentOrNull() ?.let(block) -public inline fun ResendableContent.documentMediaGroupContentOrNull(): DocumentMediaGroupPartContent? = - this as? dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupPartContent +public inline fun ResendableContent.documentMediaGroupPartContentOrNull(): + DocumentMediaGroupPartContent? = this as? + dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupPartContent -public inline fun ResendableContent.documentMediaGroupContentOrThrow(): DocumentMediaGroupPartContent = - this as dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupPartContent +public inline fun ResendableContent.documentMediaGroupPartContentOrThrow(): + DocumentMediaGroupPartContent = this as + dev.inmo.tgbotapi.types.message.content.DocumentMediaGroupPartContent public inline fun - ResendableContent.ifDocumentMediaGroupContent(block: (DocumentMediaGroupPartContent) -> T): T? = - documentMediaGroupContentOrNull() ?.let(block) - -public inline fun ResendableContent.mediaGroupContentOrNull(): MediaGroupPartContent? = this as? - dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent - -public inline fun ResendableContent.mediaGroupContentOrThrow(): MediaGroupPartContent = this as - dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent - -public inline fun ResendableContent.ifMediaGroupContent(block: (MediaGroupPartContent) -> T): T? = - mediaGroupContentOrNull() ?.let(block) + ResendableContent.ifDocumentMediaGroupPartContent(block: (DocumentMediaGroupPartContent) -> T): + T? = documentMediaGroupPartContentOrNull() ?.let(block) public inline fun ResendableContent.textedMediaContentOrNull(): TextedMediaContent? = this as? dev.inmo.tgbotapi.types.message.content.TextedMediaContent @@ -3544,15 +3508,39 @@ public inline fun ResendableContent.textedMediaContentOrThrow(): TextedMediaCont public inline fun ResendableContent.ifTextedMediaContent(block: (TextedMediaContent) -> T): T? = textedMediaContentOrNull() ?.let(block) -public inline fun ResendableContent.visualMediaGroupContentOrNull(): VisualMediaGroupPartContent? = this - as? dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent +public inline fun ResendableContent.mediaGroupCollectionContentOrNull(): + MediaGroupCollectionContent? = this as? + dev.inmo.tgbotapi.types.message.content.MediaGroupCollectionContent -public inline fun ResendableContent.visualMediaGroupContentOrThrow(): VisualMediaGroupPartContent = this - as dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent +public inline fun ResendableContent.mediaGroupCollectionContentOrThrow(): + MediaGroupCollectionContent = this as + dev.inmo.tgbotapi.types.message.content.MediaGroupCollectionContent public inline fun - ResendableContent.ifVisualMediaGroupContent(block: (VisualMediaGroupPartContent) -> T): T? = - visualMediaGroupContentOrNull() ?.let(block) + ResendableContent.ifMediaGroupCollectionContent(block: (MediaGroupCollectionContent) -> T): T? = + mediaGroupCollectionContentOrNull() ?.let(block) + +public inline fun ResendableContent.mediaGroupPartContentOrNull(): MediaGroupPartContent? = this as? + dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent + +public inline fun ResendableContent.mediaGroupPartContentOrThrow(): MediaGroupPartContent = this as + dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent + +public inline fun + ResendableContent.ifMediaGroupPartContent(block: (MediaGroupPartContent) -> T): T? = + mediaGroupPartContentOrNull() ?.let(block) + +public inline fun ResendableContent.visualMediaGroupPartContentOrNull(): + VisualMediaGroupPartContent? = this as? + dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent + +public inline fun ResendableContent.visualMediaGroupPartContentOrThrow(): + VisualMediaGroupPartContent = this as + dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent + +public inline fun + ResendableContent.ifVisualMediaGroupPartContent(block: (VisualMediaGroupPartContent) -> T): T? = + visualMediaGroupPartContentOrNull() ?.let(block) public inline fun ResendableContent.animationContentOrNull(): AnimationContent? = this as? dev.inmo.tgbotapi.types.message.content.AnimationContent @@ -3645,6 +3633,15 @@ public inline fun ResendableContent.ifStaticLocationContent(block: (StaticLocationContent) -> T): T? = staticLocationContentOrNull() ?.let(block) +public inline fun ResendableContent.mediaGroupContentOrNull(): MediaGroupContent? = this as? + dev.inmo.tgbotapi.types.message.content.MediaGroupContent + +public inline fun ResendableContent.mediaGroupContentOrThrow(): MediaGroupContent = this as + dev.inmo.tgbotapi.types.message.content.MediaGroupContent + +public inline fun ResendableContent.ifMediaGroupContent(block: (MediaGroupContent) -> T): T? = + mediaGroupContentOrNull() ?.let(block) + public inline fun ResendableContent.photoContentOrNull(): PhotoContent? = this as? dev.inmo.tgbotapi.types.message.content.PhotoContent @@ -4728,69 +4725,3 @@ public inline fun Update.unknownUpdateOrThrow(): UnknownUpdate = this as public inline fun Update.ifUnknownUpdate(block: (UnknownUpdate) -> T): T? = unknownUpdateOrNull() ?.let(block) - -public inline fun Update.channelPostMediaGroupUpdateOrNull(): ChannelPostMediaGroupUpdate? = this - as? dev.inmo.tgbotapi.types.update.media_group.ChannelPostMediaGroupUpdate - -public inline fun Update.channelPostMediaGroupUpdateOrThrow(): ChannelPostMediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.ChannelPostMediaGroupUpdate - -public inline fun - Update.ifChannelPostMediaGroupUpdate(block: (ChannelPostMediaGroupUpdate) -> T): T? = - channelPostMediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.editChannelPostMediaGroupUpdateOrNull(): EditChannelPostMediaGroupUpdate? = - this as? dev.inmo.tgbotapi.types.update.media_group.EditChannelPostMediaGroupUpdate - -public inline fun Update.editChannelPostMediaGroupUpdateOrThrow(): EditChannelPostMediaGroupUpdate = - this as dev.inmo.tgbotapi.types.update.media_group.EditChannelPostMediaGroupUpdate - -public inline fun - Update.ifEditChannelPostMediaGroupUpdate(block: (EditChannelPostMediaGroupUpdate) -> T): T? = - editChannelPostMediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.editMessageMediaGroupUpdateOrNull(): EditMessageMediaGroupUpdate? = this - as? dev.inmo.tgbotapi.types.update.media_group.EditMessageMediaGroupUpdate - -public inline fun Update.editMessageMediaGroupUpdateOrThrow(): EditMessageMediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.EditMessageMediaGroupUpdate - -public inline fun - Update.ifEditMessageMediaGroupUpdate(block: (EditMessageMediaGroupUpdate) -> T): T? = - editMessageMediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.mediaGroupUpdateOrNull(): MediaGroupUpdate? = this as? - dev.inmo.tgbotapi.types.update.media_group.MediaGroupUpdate - -public inline fun Update.mediaGroupUpdateOrThrow(): MediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.MediaGroupUpdate - -public inline fun Update.ifMediaGroupUpdate(block: (MediaGroupUpdate) -> T): T? = - mediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.sentMediaGroupUpdateOrNull(): SentMediaGroupUpdate? = this as? - dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate - -public inline fun Update.sentMediaGroupUpdateOrThrow(): SentMediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate - -public inline fun Update.ifSentMediaGroupUpdate(block: (SentMediaGroupUpdate) -> T): T? = - sentMediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.editMediaGroupUpdateOrNull(): EditMediaGroupUpdate? = this as? - dev.inmo.tgbotapi.types.update.media_group.EditMediaGroupUpdate - -public inline fun Update.editMediaGroupUpdateOrThrow(): EditMediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.EditMediaGroupUpdate - -public inline fun Update.ifEditMediaGroupUpdate(block: (EditMediaGroupUpdate) -> T): T? = - editMediaGroupUpdateOrNull() ?.let(block) - -public inline fun Update.messageMediaGroupUpdateOrNull(): MessageMediaGroupUpdate? = this as? - dev.inmo.tgbotapi.types.update.media_group.MessageMediaGroupUpdate - -public inline fun Update.messageMediaGroupUpdateOrThrow(): MessageMediaGroupUpdate = this as - dev.inmo.tgbotapi.types.update.media_group.MessageMediaGroupUpdate - -public inline fun Update.ifMessageMediaGroupUpdate(block: (MessageMediaGroupUpdate) -> T): T? = - messageMediaGroupUpdateOrNull() ?.let(block) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/WithContent.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/WithContent.kt index 9f632f078f..7fdcdf54fb 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/WithContent.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/WithContent.kt @@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.utils import dev.inmo.tgbotapi.types.message.abstracts.* +import dev.inmo.tgbotapi.types.message.content.MediaGroupMessage import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent import dev.inmo.tgbotapi.types.message.content.MessageContent @@ -36,6 +37,3 @@ inline fun AnonymousGroupContentMessage<*>.requireW inline fun CommonGroupContentMessage<*>.withContent() = if (content is T) { this as CommonGroupContentMessage } else { null } inline fun CommonGroupContentMessage<*>.requireWithContent() = withContent()!! - -inline fun MediaGroupMessage<*>.withContent() = if (content is T) { this as MediaGroupMessage } else { null } -inline fun MediaGroupMessage<*>.requireWithContent() = withContent()!! diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt index aaf91e4521..56ec9dc233 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/UpdateChatRetriever.kt @@ -3,21 +3,15 @@ package dev.inmo.tgbotapi.extensions.utils.extensions import dev.inmo.tgbotapi.abstracts.FromUser import dev.inmo.tgbotapi.abstracts.WithUser import dev.inmo.tgbotapi.extensions.utils.asUser -import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.User import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.* import dev.inmo.tgbotapi.utils.PreviewFeature @PreviewFeature fun Update.sourceChat(): Chat? = when (this) { - is MediaGroupUpdate -> when (this) { - is SentMediaGroupUpdate -> data.chat - is EditMediaGroupUpdate -> data.chat - } is BaseMessageUpdate -> data.chat is ChatJoinRequestUpdate -> data.chat else -> { diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/FlowsUpdatesFilter.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/FlowsUpdatesFilter.kt index 53d52cf338..91acd5419e 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/FlowsUpdatesFilter.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/FlowsUpdatesFilter.kt @@ -8,7 +8,6 @@ import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage @@ -30,19 +29,6 @@ inline fun filterForContentMessage(): suspend (Cont inline fun Flow.filterContentMessages( ): Flow> = asContentMessagesFlow().mapNotNull(filterForContentMessage()) -@RiskFeature("This method is low-level") -inline fun Flow.filterMediaGroupMessages( -): Flow>> = map { - it.data.mapNotNull { message -> - if (message.content is T) { - @Suppress("UNCHECKED_CAST") - message as CommonMessage - } else { - null - } - } -} - /** * @param scopeToIncludeChannels This parameter is required when you want to include [textMessages] for channels too. * In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messagesFlow] and @@ -62,39 +48,9 @@ inline fun FlowsUpdatesFilter.filterContentMessages( } ?: messagesFlow).filterContentMessages() } -/** - * @param scopeToIncludeChannels This parameter is required when you want to include [SentMediaGroupUpdate] for channels - * too. In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messagesFlow] and - * [FlowsUpdatesFilter.channelPostsFlow]. In case it is null will be used [Flow]s mapping - */ -@Suppress("UNCHECKED_CAST") -@RiskFeature(lowLevelRiskFeatureMessage) -inline fun FlowsUpdatesFilter.filterMediaGroupMessages( - scopeToIncludeChannels: CoroutineScope? = null -): Flow>> { - return (scopeToIncludeChannels ?.let { scope -> - aggregateFlows( - scope, - messageMediaGroupsFlow, - channelPostMediaGroupsFlow - ) - } ?: messageMediaGroupsFlow).filterMediaGroupMessages() -} - fun FlowsUpdatesFilter.sentMessages( scopeToIncludeChannels: CoroutineScope? = null ): Flow> = filterContentMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.sentMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -): Flow> = merge( - sentMessages(scopeToIncludeChannels), - mediaGroupMessages(scopeToIncludeChannels).flatMap { - it.mapNotNull { - @Suppress("UNCHECKED_CAST") - it as? ContentMessage - } - } -) fun Flow.animationMessages() = filterContentMessages() fun FlowsUpdatesFilter.animationMessages( @@ -105,12 +61,6 @@ fun Flow.audioMessages() = filterContentMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.audioMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -) = merge( - filterContentMessages(scopeToIncludeChannels), - mediaGroupAudioMessages(scopeToIncludeChannels).flatten() -) fun Flow.contactMessages() = filterContentMessages() fun FlowsUpdatesFilter.contactMessages( @@ -126,12 +76,6 @@ fun Flow.documentMessages() = filterContentMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.documentMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -) = merge( - filterContentMessages(scopeToIncludeChannels), - mediaGroupDocumentMessages(scopeToIncludeChannels).flatten() -) fun Flow.gameMessages() = filterContentMessages() fun FlowsUpdatesFilter.gameMessages( @@ -153,12 +97,6 @@ fun Flow.imageMessages() = photoMessages() fun FlowsUpdatesFilter.photoMessages( scopeToIncludeChannels: CoroutineScope? = null ) = filterContentMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.photoMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -) = merge( - filterContentMessages(scopeToIncludeChannels), - mediaGroupPhotosMessages(scopeToIncludeChannels).flatten() -) /** * Shortcut for [photoMessages] */ @@ -166,9 +104,6 @@ fun FlowsUpdatesFilter.photoMessagesWithMediaGroups( inline fun FlowsUpdatesFilter.imageMessages( scopeToIncludeChannels: CoroutineScope? = null ) = photoMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.imageMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -) = photoMessagesWithMediaGroups(scopeToIncludeChannels) fun Flow.pollMessages() = filterContentMessages() fun FlowsUpdatesFilter.pollMessages( @@ -194,12 +129,6 @@ fun Flow.videoMessages() = filterContentMessages(scopeToIncludeChannels) -fun FlowsUpdatesFilter.videoMessagesWithMediaGroups( - scopeToIncludeChannels: CoroutineScope? = null -) = merge( - filterContentMessages(scopeToIncludeChannels), - mediaGroupVideosMessages(scopeToIncludeChannels).flatten() -) fun Flow.videoNoteMessages() = filterContentMessages() fun FlowsUpdatesFilter.videoNoteMessages( @@ -210,34 +139,3 @@ fun Flow.voiceMessages() = filterContentMessages(scopeToIncludeChannels) - - -fun Flow.mediaGroupMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) - -fun Flow.mediaGroupPhotosMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupPhotosMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) - -fun Flow.mediaGroupVideosMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupVideosMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) - -fun Flow.mediaGroupVisualMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupVisualMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) - -fun Flow.mediaGroupAudioMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupAudioMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) - -fun Flow.mediaGroupDocumentMessages() = filterMediaGroupMessages() -fun FlowsUpdatesFilter.mediaGroupDocumentMessages( - scopeToIncludeChannels: CoroutineScope? = null -) = filterMediaGroupMessages(scopeToIncludeChannels) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt deleted file mode 100644 index 5b32fc4e99..0000000000 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt +++ /dev/null @@ -1,69 +0,0 @@ -package dev.inmo.tgbotapi.extensions.utils.shortcuts - -import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup -import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.chat.Chat -import dev.inmo.tgbotapi.types.message.ForwardInfo -import dev.inmo.tgbotapi.types.message.abstracts.* -import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate - -val List>.forwardInfo: ForwardInfo? - get() = firstOrNull() ?.forwardInfo -val List>.replyTo: Message? - get() = firstOrNull() ?.replyTo -val List>.chat: Chat? - get() = firstOrNull() ?.chat -val List>.mediaGroupId: MediaGroupIdentifier? - get() = firstOrNull() ?.mediaGroupId - -val SentMediaGroupUpdate.forwardInfo: ForwardInfo? - get() = data.first().forwardInfo -val SentMediaGroupUpdate.replyTo: Message? - get() = data.first().replyTo -val SentMediaGroupUpdate.chat: Chat - get() = data.chat!! -val SentMediaGroupUpdate.mediaGroupId: MediaGroupIdentifier - get() = data.mediaGroupId!! - -fun List>.createResend( - chatId: ChatId, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyTo: MessageId? = null -) = SendMediaGroup( - chatId, - map { it.content.toMediaGroupMemberTelegramMedia() }, - threadId, - disableNotification, - protectContent, - replyTo -) - -fun List>.createResend( - chat: Chat, - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyTo: MessageId? = null -) = createResend( - chat.id, - threadId, - disableNotification, - protectContent, - replyTo -) - -fun SentMediaGroupUpdate.createResend( - threadId: MessageThreadId? = null, - disableNotification: Boolean = false, - protectContent: Boolean = false, - replyTo: MessageId? = null -) = data.createResend( - chat, - threadId, - disableNotification, - protectContent, - replyTo -) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/BaseMessagesUpdatesConversations.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/BaseMessagesUpdatesConversations.kt index 0caa1805cc..2eae2350b0 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/BaseMessagesUpdatesConversations.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/BaseMessagesUpdatesConversations.kt @@ -1,7 +1,6 @@ package dev.inmo.tgbotapi.extensions.utils.updates import dev.inmo.tgbotapi.types.update.abstracts.* -import dev.inmo.tgbotapi.types.update.media_group.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterIsInstance @@ -16,22 +15,3 @@ fun Flow.onlySentMessageUpdates(): Flow.onlyEditMessageUpdates(): Flow = filterIsInstance() - -/** - * Converts flow to [Flow] of [MediaGroupUpdate]. Please, remember that it could be either [EditMediaGroupUpdate] - * or [SentMediaGroupUpdate] - * - * @see onlySentMediaGroupUpdates - * @see onlyEditMediaGroupUpdates - */ -fun Flow.onlyMediaGroupsUpdates(): Flow = filterIsInstance() - -/** - * Converts flow to [Flow] of [SentMediaGroupUpdate] - */ -fun Flow.onlySentMediaGroupUpdates(): Flow = filterIsInstance() - -/** - * Converts flow to [Flow] of [EditMediaGroupUpdate] - */ -fun Flow.onlyEditMediaGroupUpdates(): Flow = filterIsInstance() diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesChatFilters.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesChatFilters.kt index 70be37786a..bf415ce45e 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesChatFilters.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesChatFilters.kt @@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.extensions.utils.updates import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter @@ -15,13 +14,3 @@ fun Flow.filterBaseMessageUpdatesByChatId(chatId: Cha * [Flow.filter] incoming [BaseMessageUpdate]s by their [ChatId] using [Chat.id] of [chat] */ fun Flow.filterBaseMessageUpdatesByChat(chat: Chat): Flow = filterBaseMessageUpdatesByChatId(chat.id) - - -/** - * [Flow.filter] incoming [SentMediaGroupUpdate]s by their [ChatId] - */ -fun Flow.filterSentMediaGroupUpdatesByChatId(chatId: ChatId): Flow = filter { it.data.first().chat.id == chatId } -/** - * [Flow.filter] incoming [SentMediaGroupUpdate]s by their [ChatId] using [Chat.id] of [chat] - */ -fun Flow.filterSentMediaGroupUpdatesByChat(chat: Chat): Flow = filterSentMediaGroupUpdatesByChatId(chat.id) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPolling.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPolling.kt index 3e9f27dfaa..cb4f10b0db 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPolling.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPolling.kt @@ -8,9 +8,11 @@ import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates import dev.inmo.tgbotapi.extensions.utils.updates.lastUpdateIdentifier import dev.inmo.tgbotapi.requests.GetUpdates import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import dev.inmo.tgbotapi.types.update.* +import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.Update -import dev.inmo.tgbotapi.types.update.media_group.SentMediaGroupUpdate import dev.inmo.tgbotapi.updateshandlers.* import io.ktor.client.plugins.HttpRequestTimeoutException import io.ktor.utils.io.CancellationException @@ -56,7 +58,10 @@ fun TelegramBot.longPollingFlow( * We are throw out the last media group and will reretrieve it again in the next get updates * and it will guarantee that it is full */ - if (originalUpdates.size == getUpdatesLimit.last && converted.last() is SentMediaGroupUpdate) { + if ( + originalUpdates.size == getUpdatesLimit.last + && ((converted.last() as? BaseSentMessageUpdate) ?.data as? CommonMessage<*>) ?.content is MediaGroupContent + ) { converted - converted.last() } else { converted @@ -67,7 +72,7 @@ fun TelegramBot.longPollingFlow( for (update in updates) { send(update) - lastUpdateIdentifier = update.lastUpdateIdentifier() + lastUpdateIdentifier = update.updateId } }.onFailure { cancel(it as? CancellationException ?: return@onFailure)