diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt index fb458dbd9a..a64820dcff 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt @@ -8,12 +8,14 @@ import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.InputMedia.* import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass +import dev.inmo.tgbotapi.utils.* import dev.inmo.tgbotapi.utils.throwRangeError -import dev.inmo.tgbotapi.utils.toJsonWithoutNulls import kotlinx.serialization.* import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.buildJsonArray +@RiskFeature("Media groups contains restrictions related to combinations of media types. Currently it is possible to" + + " combine photo + video OR audio OR documents") fun SendMediaGroup( chatId: ChatIdentifier, media: List, @@ -52,6 +54,39 @@ fun SendMediaGroup( } } +/** + * Use this method to be sure that you are correctly sending playlist with audios + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendPlaylist( + chatId: ChatIdentifier, + media: List, + disableNotification: Boolean = false, + replyToMessageId: MessageIdentifier? = null +) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId) + +/** + * Use this method to be sure that you are correctly sending documents media group + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendDocumentsGroup( + chatId: ChatIdentifier, + media: List, + disableNotification: Boolean = false, + replyToMessageId: MessageIdentifier? = null +) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId) + +/** + * Use this method to be sure that you are correctly sending visual media group + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendVisualMediaGroup( + chatId: ChatIdentifier, + media: List, + disableNotification: Boolean = false, + replyToMessageId: MessageIdentifier? = null +) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId) + private val messagesListSerializer: KSerializer> = ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass()) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt index 432fd8a578..55aa777d6b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt @@ -17,7 +17,7 @@ data class InputMediaPhoto( override val caption: String? = null, @SerialName(parseModeField) override val parseMode: ParseMode? = null -) : InputMedia, MediaGroupMemberInputMedia { +) : InputMedia, VisualMediaGroupMemberInputMedia { override val type: String = photoInputMediaType override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt index 8be815907a..81e78aaa8f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt @@ -19,7 +19,7 @@ data class InputMediaVideo( override val height: Int? = null, override val duration: Long? = null, override val thumb: InputFile? = null -) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, MediaGroupMemberInputMedia { +) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia { override val type: String = videoInputMediaType override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/MediaGroupMemberInputMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/MediaGroupMemberInputMedia.kt index a587f121d5..202f40c366 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/MediaGroupMemberInputMedia.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/MediaGroupMemberInputMedia.kt @@ -18,3 +18,6 @@ internal fun T.buildArguments(withSerializer: SerializationStrategy) = ar interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput { fun serialize(format: StringFormat): String } + +@Serializable(MediaGroupMemberInputMediaSerializer::class) +interface VisualMediaGroupMemberInputMedia : MediaGroupMemberInputMedia diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt index 41c0ac7854..fc592389ac 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/DocumentFile.kt @@ -22,3 +22,12 @@ data class DocumentFile( @SerialName(fileNameField) override val fileName: String? = null ) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile + +inline fun T.asDocumentFile() = DocumentFile( + fileId, + fileUniqueId, + fileSize, + (this as? ThumbedMediaFile) ?.thumb, + (this as? MimedMediaFile) ?.mimeType, + (this as? CustomNamedMediaFile) ?.fileName +) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt index 18cc8686cd..7e46867647 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt @@ -5,4 +5,6 @@ import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia interface MediaGroupContent : MediaContent, CaptionedInput { fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia -} \ No newline at end of file +} + +interface VisualMediaGroupContent : MediaGroupContent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/DocumentContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/DocumentContent.kt index 530482b6db..9163fafcb8 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/DocumentContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/DocumentContent.kt @@ -11,6 +11,7 @@ import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2 import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.DocumentFile +import dev.inmo.tgbotapi.types.files.asDocumentFile import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent @@ -50,3 +51,14 @@ data class DocumentContent( media.thumb ?.fileId ) } + +inline fun T.asDocumentContent() = when (this) { + is CaptionedInput -> DocumentContent( + media.asDocumentFile(), + caption, + captionEntities + ) + else -> DocumentContent( + media.asDocumentFile() + ) +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/PhotoContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/PhotoContent.kt index e691370ab3..0b37841c06 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/PhotoContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/PhotoContent.kt @@ -12,8 +12,7 @@ import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2 import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage -import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent -import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.utils.toHtmlCaptions import dev.inmo.tgbotapi.utils.toMarkdownV2Captions @@ -21,7 +20,7 @@ data class PhotoContent( override val mediaCollection: Photo, override val caption: String? = null, override val captionEntities: List = emptyList() -) : MediaCollectionContent, MediaGroupContent { +) : MediaCollectionContent, VisualMediaGroupContent { override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content") override fun createResend( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/VideoContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/VideoContent.kt index 0461d17a63..7d76c656da 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/VideoContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/media/VideoContent.kt @@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.VideoFile import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent import dev.inmo.tgbotapi.utils.toHtmlCaptions import dev.inmo.tgbotapi.utils.toMarkdownV2Captions @@ -20,7 +21,7 @@ data class VideoContent( override val media: VideoFile, override val caption: String? = null, override val captionEntities: List = emptyList() -) : MediaGroupContent { +) : VisualMediaGroupContent { override fun createResend( chatId: ChatIdentifier, disableNotification: Boolean, diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Annotations.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Annotations.kt index 9de1d0cd70..f89e623676 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Annotations.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Annotations.kt @@ -17,3 +17,21 @@ package dev.inmo.tgbotapi.utils AnnotationTarget.TYPE_PARAMETER ) annotation class PreviewFeature + +@RequiresOptIn( + "This feature can work unstable and may have some restrictions in Telegram System", + RequiresOptIn.Level.WARNING +) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPE, + AnnotationTarget.TYPEALIAS, + AnnotationTarget.TYPE_PARAMETER +) +annotation class RiskFeature(val message: String)