From 97621bca67539e57a7a2432e1713558b861e5b40 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 9 May 2024 21:54:24 +0600 Subject: [PATCH] add support of ChatBackground --- .../expectations/WaitEventAction.kt | 6 + .../expectations/WaitEventActionMessages.kt | 6 + .../triggers_handling/EventTriggers.kt | 21 ++ .../dev/inmo/tgbotapi/types/BackgroundFill.kt | 128 +++++++++++++ .../dev/inmo/tgbotapi/types/BackgroundType.kt | 180 ++++++++++++++++++ .../kotlin/dev/inmo/tgbotapi/types/Common.kt | 14 ++ .../tgbotapi/types/chat/ChatBackground.kt | 13 ++ .../inmo/tgbotapi/types/message/RawMessage.kt | 4 + .../utils/ExtractDataAndJsonFromDecoder.kt | 15 ++ .../utils/IntProgress100Serializer.kt | 27 +++ .../utils/IntRGB24HEXAColorSerializer.kt | 22 +++ .../extensions/utils/ClassCastsNew.kt | 130 +++++++++++++ 12 files changed, 566 insertions(+) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatBackground.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntProgress100Serializer.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntRGB24HEXAColorSerializer.kt diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt index 196dcbf149..8db0996f95 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt @@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.chat.ChatBackground import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed @@ -219,3 +220,8 @@ suspend fun BehaviourContext.waitChatBoostAdded( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } ) = waitEvents(initRequest, errorFactory) + +suspend fun BehaviourContext.waitChatBackgroundSet( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEvents(initRequest, errorFactory) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventActionMessages.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventActionMessages.kt index 61246132b7..9805e194bc 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventActionMessages.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventActionMessages.kt @@ -5,6 +5,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.chat.ChatBackground import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed @@ -213,3 +214,8 @@ suspend fun BehaviourContext.waitChatBoostAddedEventsMessages( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null } ) = waitEventsMessages(initRequest, errorFactory) + +suspend fun BehaviourContext.waitChatBackgroundSetEventsMessages( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null } +) = waitEventsMessages(initRequest, errorFactory) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt index 55ff317b64..eb60a8b17f 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt @@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.Mar import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times import dev.inmo.tgbotapi.extensions.utils.baseSentMessageUpdateOrNull import dev.inmo.tgbotapi.extensions.utils.chatEventMessageOrNull +import dev.inmo.tgbotapi.types.chat.ChatBackground import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed @@ -844,3 +845,23 @@ suspend fun BC.onChatBoostAdded( markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> ) = onEventWithCustomChatEventMessage(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.onChatBackgroundSet( + initialFilter: SimpleFilter>? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update>? = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver> +) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt new file mode 100644 index 0000000000..0b344ae946 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundFill.kt @@ -0,0 +1,128 @@ +package dev.inmo.tgbotapi.types + +import dev.inmo.micro_utils.colors.common.HEXAColor +import dev.inmo.tgbotapi.utils.IntRGB24HEXAColorSerializer +import dev.inmo.tgbotapi.utils.extractDataAndJson +import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded +import kotlinx.serialization.* +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.decodeFromJsonElement + +@ClassCastsIncluded +@Serializable(BackgroundFill.Companion::class) +sealed interface BackgroundFill { + val type: String + val colors: List + + @Serializable + data class Solid( + @SerialName(colorField) + @Serializable(IntRGB24HEXAColorSerializer::class) + val color: HEXAColor + ) : BackgroundFill { + @Transient + override val colors: List = listOf(color) + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + + companion object { + const val type = "solid" + } + } + @Serializable + data class Gradient( + @SerialName(topColorField) + @Serializable(IntRGB24HEXAColorSerializer::class) + val topColor: HEXAColor, + @SerialName(bottomColorField) + @Serializable(IntRGB24HEXAColorSerializer::class) + val bottomColor: HEXAColor, + @SerialName(rotationAngleField) + val rotationAngle: Short, + ) : BackgroundFill { + @Transient + override val colors: List = listOf(topColor, bottomColor) + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + companion object { + const val type = "gradient" + } + } + @Serializable + data class FreeformGradient( + @SerialName(colorsField) + override val colors: List<@Serializable(IntRGB24HEXAColorSerializer::class) HEXAColor> + ) : BackgroundFill { + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + + companion object { + const val type = "freeform_gradient" + } + } + @Serializable + data class Unknown( + override val type: String, + val raw: JsonElement? + ) : BackgroundFill { + @SerialName(colorsField) + override val colors: List = emptyList() + } + + companion object : KSerializer { + @Serializable + class RawBackgroundFill private constructor( + @SerialName(typeField) + val type: String, + @Serializable(IntRGB24HEXAColorSerializer::class) + val color: HEXAColor? = null, + @SerialName(topColorField) + @Serializable(IntRGB24HEXAColorSerializer::class) + val topColor: HEXAColor? = null, + @SerialName(bottomColorField) + @Serializable(IntRGB24HEXAColorSerializer::class) + val bottomColor: HEXAColor? = null, + @SerialName(rotationAngleField) + val rotationAngle: Short? = null, + @SerialName(colorsField) + val colors: List<@Serializable(IntRGB24HEXAColorSerializer::class) HEXAColor>? = null + ) + + private val serializer = RawBackgroundFill.serializer() + override val descriptor: SerialDescriptor + get() = serializer.descriptor + + override fun deserialize(decoder: Decoder): BackgroundFill { + val (raw, json) = decoder.extractDataAndJson(serializer) + return when (raw.type) { + Solid.type -> Solid(color = raw.color ?: return Unknown(raw.type, json)) + Gradient.type -> Gradient( + topColor = raw.topColor ?: return Unknown(raw.type, json), + bottomColor = raw.bottomColor ?: return Unknown(raw.type, json), + rotationAngle = raw.rotationAngle ?: return Unknown(raw.type, json) + ) + FreeformGradient.type -> FreeformGradient(raw.colors ?: return Unknown(raw.type, json)) + else -> Unknown(raw.type, json) + } + } + + override fun serialize(encoder: Encoder, value: BackgroundFill) { + when (value) { + is FreeformGradient -> FreeformGradient.serializer().serialize(encoder, value) + is Gradient -> Gradient.serializer().serialize(encoder, value) + is Solid -> Solid.serializer().serialize(encoder, value) + is Unknown -> value.raw ?.also { + JsonElement.serializer().serialize(encoder, it) + } ?: Unknown.serializer().serialize(encoder, value) + } + } + + } +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt new file mode 100644 index 0000000000..d72361439f --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/BackgroundType.kt @@ -0,0 +1,180 @@ +package dev.inmo.tgbotapi.types + +import dev.inmo.micro_utils.common.Progress +import dev.inmo.tgbotapi.types.files.DocumentFile +import dev.inmo.tgbotapi.utils.IntProgress100Serializer +import dev.inmo.tgbotapi.utils.extractDataAndJson +import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonElement + +@ClassCastsIncluded +@Serializable(BackgroundType.Companion::class) +sealed interface BackgroundType { + val type: String + + sealed interface Movable : BackgroundType { + val isMoving: Boolean + } + sealed interface Dimmable : BackgroundType { + val darkThemeDimming: Progress + } + sealed interface Fillable : BackgroundType { + val fill: BackgroundFill + } + sealed interface WithDocument : BackgroundType { + val document: DocumentFile + } + + @Serializable + data class Fill( + @SerialName(fillField) + override val fill: BackgroundFill, + @SerialName(darkThemeDimmingField) + @Serializable(IntProgress100Serializer::class) + override val darkThemeDimming: Progress + ) : Fillable, Dimmable { + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + companion object { + const val type: String = "fill" + } + } + + @Serializable + data class Wallpaper( + @SerialName(documentField) + override val document: DocumentFile, + @SerialName(darkThemeDimmingField) + @Serializable(IntProgress100Serializer::class) + override val darkThemeDimming: Progress, + @SerialName(isBlurredField) + val isBlurred: Boolean = false, + @SerialName(isMovingField) + override val isMoving: Boolean = false + ) : WithDocument, Dimmable, Movable { + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + companion object { + const val type: String = "wallpaper" + } + } + + @Serializable + data class Pattern( + @SerialName(documentField) + override val document: DocumentFile, + @SerialName(fillField) + override val fill: BackgroundFill, + @SerialName(intensityField) + @Serializable(IntProgress100Serializer::class) + val intensity: Progress, + @SerialName(isInvertedField) + val isInverted: Boolean = false, + @SerialName(isMovingField) + override val isMoving: Boolean = false + ) : WithDocument, Fillable, Movable { + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + companion object { + const val type: String = "pattern" + } + } + + @Serializable + data class ChatTheme( + @SerialName(themeNameField) + val themeName: String + ): BackgroundType { + @EncodeDefault + @SerialName(typeField) + override val type: String = Companion.type + companion object { + const val type: String = "chat_theme" + } + } + + @Serializable + data class Unknown( + @SerialName(typeField) + override val type: String, + val raw: JsonElement? + ): BackgroundType + + companion object : KSerializer { + @Serializable + data class RawBackgroundType( + val type: String, + @SerialName(fillField) + val fill: BackgroundFill? = null, + @SerialName(darkThemeDimmingField) + @Serializable(IntProgress100Serializer::class) + val darkThemeDimming: Progress? = null, + @SerialName(documentField) + val document: DocumentFile? = null, + @SerialName(isBlurredField) + val isBlurred: Boolean = false, + @SerialName(isMovingField) + val isMoving: Boolean = false, + @SerialName(intensityField) + @Serializable(IntProgress100Serializer::class) + val intensity: Progress? = null, + @SerialName(isInvertedField) + val isInverted: Boolean = false, + @SerialName(themeNameField) + val themeName: String? = null + ) + + override val descriptor: SerialDescriptor + get() = RawBackgroundType.serializer().descriptor + + override fun deserialize(decoder: Decoder): BackgroundType { + val (raw, json) = decoder.extractDataAndJson(RawBackgroundType.serializer()) + val unknown by lazy { Unknown(raw.type, json) } + return when (raw.type) { + Fill.type -> Fill( + raw.fill ?: return unknown, + raw.darkThemeDimming ?: return unknown + ) + Wallpaper.type -> Wallpaper( + document = raw.document ?: return unknown, + darkThemeDimming = raw.darkThemeDimming ?: return unknown, + isBlurred = raw.isBlurred, + isMoving = raw.isMoving + ) + Pattern.type -> Pattern( + document = raw.document ?: return unknown, + fill = raw.fill ?: return unknown, + intensity = raw.intensity ?: return unknown, + isInverted = raw.isInverted, + isMoving = raw.isMoving + ) + ChatTheme.type -> ChatTheme( + raw.themeName ?: return unknown + ) + else -> unknown + } + } + + override fun serialize(encoder: Encoder, value: BackgroundType) { + when (value) { + is ChatTheme -> ChatTheme.serializer().serialize(encoder, value) + is Fill -> Fill.serializer().serialize(encoder, value) + is Wallpaper -> Wallpaper.serializer().serialize(encoder, value) + is Pattern -> Pattern.serializer().serialize(encoder, value) + is Unknown -> value.raw ?.also { + JsonElement.serializer().serialize(encoder, it) + } ?: Unknown.serializer().serialize(encoder, value) + } + } + } +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index 0082b8d9c5..8f20fa5cd7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -604,6 +604,20 @@ const val businessIntroField = "business_intro" const val businessLocationField = "business_location" const val businessOpeningHoursField = "business_opening_hours" +const val colorField = "color" +const val colorsField = "colors" +const val topColorField = "top_color" +const val bottomColorField = "bottom_color" +const val rotationAngleField = "rotation_angle" + +const val fillField = "fill" +const val darkThemeDimmingField = "dark_theme_dimming" +const val isBlurredField = "is_blurred" +const val isInvertedField = "is_inverted" +const val isMovingField = "is_moving" +const val intensityField = "intensity" +const val themeNameField = "theme_name" + const val dayField = "day" const val monthField = "month" const val yearField = "year" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatBackground.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatBackground.kt new file mode 100644 index 0000000000..513cecbd52 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/ChatBackground.kt @@ -0,0 +1,13 @@ +package dev.inmo.tgbotapi.types.chat + +import dev.inmo.tgbotapi.types.BackgroundType +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.typeField +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ChatBackground( + @SerialName(typeField) + val type: BackgroundType +) : CommonEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt index 1138ea7f7a..a8361042b5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt @@ -125,6 +125,9 @@ internal data class RawMessage( // Boost added to groups private val boost_added: ChatBoostAdded? = null, + // Chat background has been changed + private val chat_background_set: ChatBackground? = null, + // AutoDelete Message time changed private val message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged? = null, @@ -260,6 +263,7 @@ internal data class RawMessage( giveaway_winners is GiveawayPrivateResults -> giveaway_winners giveaway_completed != null -> giveaway_completed boost_added != null -> boost_added + chat_background_set != null -> chat_background_set else -> null } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt new file mode 100644 index 0000000000..518c417810 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ExtractDataAndJsonFromDecoder.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.utils + +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement + +fun Decoder.extractDataAndJson(serializer: DeserializationStrategy): Pair { + return if (this is JsonDecoder) { + val raw = decodeJsonElement() + json.decodeFromJsonElement(serializer, raw) to raw + } else { + serializer.deserialize(this) to null + } +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntProgress100Serializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntProgress100Serializer.kt new file mode 100644 index 0000000000..be7d39564b --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntProgress100Serializer.kt @@ -0,0 +1,27 @@ +package dev.inmo.tgbotapi.utils + +import dev.inmo.micro_utils.common.Progress +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +object IntProgress100Serializer : KSerializer { + override val descriptor: SerialDescriptor + get() = Int.serializer().descriptor + + override fun deserialize(decoder: Decoder): Progress { + return Progress( + decoder.decodeInt(), + 100 + ) + } + + override fun serialize(encoder: Encoder, value: Progress) { + encoder.encodeInt( + value.of100Int + ) + } + +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntRGB24HEXAColorSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntRGB24HEXAColorSerializer.kt new file mode 100644 index 0000000000..113c5ea722 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/IntRGB24HEXAColorSerializer.kt @@ -0,0 +1,22 @@ +package dev.inmo.tgbotapi.utils + +import dev.inmo.micro_utils.colors.common.HEXAColor +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +object IntRGB24HEXAColorSerializer : KSerializer { + override val descriptor: SerialDescriptor + get() = Int.serializer().descriptor + + override fun deserialize(decoder: Decoder): HEXAColor { + val raw = decoder.decodeInt() + return HEXAColor(raw.shl(2).toUInt() + 0xffu) + } + + override fun serialize(encoder: Encoder, value: HEXAColor) { + encoder.encodeInt(value.rgbInt) + } +} \ No newline at end of file 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 672aef3024..2b68a60cfe 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 @@ -16,6 +16,8 @@ import dev.inmo.tgbotapi.requests.answers.InlineQueryResultsButton import dev.inmo.tgbotapi.requests.send.payments.CreateInvoiceLink import dev.inmo.tgbotapi.requests.send.payments.SendInvoice import dev.inmo.tgbotapi.requests.stickers.InputSticker +import dev.inmo.tgbotapi.types.BackgroundFill +import dev.inmo.tgbotapi.types.BackgroundType import dev.inmo.tgbotapi.types.BusinessChatId import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatIdWithThreadId @@ -116,6 +118,7 @@ import dev.inmo.tgbotapi.types.chat.Bot import dev.inmo.tgbotapi.types.chat.BusinessChat import dev.inmo.tgbotapi.types.chat.ChannelChat import dev.inmo.tgbotapi.types.chat.Chat +import dev.inmo.tgbotapi.types.chat.ChatBackground import dev.inmo.tgbotapi.types.chat.ChatJoinRequest import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated import dev.inmo.tgbotapi.types.chat.CommonBot @@ -1088,6 +1091,124 @@ public inline fun InputSticker.regularOrThrow(): InputSticker.WithKeywords.Regul public inline fun InputSticker.ifRegular(block: (InputSticker.WithKeywords.Regular) -> T): T? = regularOrNull() ?.let(block) +public inline fun BackgroundFill.freeformGradientOrNull(): BackgroundFill.FreeformGradient? = this + as? dev.inmo.tgbotapi.types.BackgroundFill.FreeformGradient + +public inline fun BackgroundFill.freeformGradientOrThrow(): BackgroundFill.FreeformGradient = this + as dev.inmo.tgbotapi.types.BackgroundFill.FreeformGradient + +public inline fun + BackgroundFill.ifFreeformGradient(block: (BackgroundFill.FreeformGradient) -> T): T? = + freeformGradientOrNull() ?.let(block) + +public inline fun BackgroundFill.gradientOrNull(): BackgroundFill.Gradient? = this as? + dev.inmo.tgbotapi.types.BackgroundFill.Gradient + +public inline fun BackgroundFill.gradientOrThrow(): BackgroundFill.Gradient = this as + dev.inmo.tgbotapi.types.BackgroundFill.Gradient + +public inline fun BackgroundFill.ifGradient(block: (BackgroundFill.Gradient) -> T): T? = + gradientOrNull() ?.let(block) + +public inline fun BackgroundFill.solidOrNull(): BackgroundFill.Solid? = this as? + dev.inmo.tgbotapi.types.BackgroundFill.Solid + +public inline fun BackgroundFill.solidOrThrow(): BackgroundFill.Solid = this as + dev.inmo.tgbotapi.types.BackgroundFill.Solid + +public inline fun BackgroundFill.ifSolid(block: (BackgroundFill.Solid) -> T): T? = solidOrNull() + ?.let(block) + +public inline fun BackgroundFill.unknownOrNull(): BackgroundFill.Unknown? = this as? + dev.inmo.tgbotapi.types.BackgroundFill.Unknown + +public inline fun BackgroundFill.unknownOrThrow(): BackgroundFill.Unknown = this as + dev.inmo.tgbotapi.types.BackgroundFill.Unknown + +public inline fun BackgroundFill.ifUnknown(block: (BackgroundFill.Unknown) -> T): T? = + unknownOrNull() ?.let(block) + +public inline fun BackgroundType.chatThemeOrNull(): BackgroundType.ChatTheme? = this as? + dev.inmo.tgbotapi.types.BackgroundType.ChatTheme + +public inline fun BackgroundType.chatThemeOrThrow(): BackgroundType.ChatTheme = this as + dev.inmo.tgbotapi.types.BackgroundType.ChatTheme + +public inline fun BackgroundType.ifChatTheme(block: (BackgroundType.ChatTheme) -> T): T? = + chatThemeOrNull() ?.let(block) + +public inline fun BackgroundType.dimmableOrNull(): BackgroundType.Dimmable? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Dimmable + +public inline fun BackgroundType.dimmableOrThrow(): BackgroundType.Dimmable = this as + dev.inmo.tgbotapi.types.BackgroundType.Dimmable + +public inline fun BackgroundType.ifDimmable(block: (BackgroundType.Dimmable) -> T): T? = + dimmableOrNull() ?.let(block) + +public inline fun BackgroundType.fillOrNull(): BackgroundType.Fill? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Fill + +public inline fun BackgroundType.fillOrThrow(): BackgroundType.Fill = this as + dev.inmo.tgbotapi.types.BackgroundType.Fill + +public inline fun BackgroundType.ifFill(block: (BackgroundType.Fill) -> T): T? = fillOrNull() + ?.let(block) + +public inline fun BackgroundType.wallpaperOrNull(): BackgroundType.Wallpaper? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Wallpaper + +public inline fun BackgroundType.wallpaperOrThrow(): BackgroundType.Wallpaper = this as + dev.inmo.tgbotapi.types.BackgroundType.Wallpaper + +public inline fun BackgroundType.ifWallpaper(block: (BackgroundType.Wallpaper) -> T): T? = + wallpaperOrNull() ?.let(block) + +public inline fun BackgroundType.fillableOrNull(): BackgroundType.Fillable? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Fillable + +public inline fun BackgroundType.fillableOrThrow(): BackgroundType.Fillable = this as + dev.inmo.tgbotapi.types.BackgroundType.Fillable + +public inline fun BackgroundType.ifFillable(block: (BackgroundType.Fillable) -> T): T? = + fillableOrNull() ?.let(block) + +public inline fun BackgroundType.patternOrNull(): BackgroundType.Pattern? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Pattern + +public inline fun BackgroundType.patternOrThrow(): BackgroundType.Pattern = this as + dev.inmo.tgbotapi.types.BackgroundType.Pattern + +public inline fun BackgroundType.ifPattern(block: (BackgroundType.Pattern) -> T): T? = + patternOrNull() ?.let(block) + +public inline fun BackgroundType.movableOrNull(): BackgroundType.Movable? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Movable + +public inline fun BackgroundType.movableOrThrow(): BackgroundType.Movable = this as + dev.inmo.tgbotapi.types.BackgroundType.Movable + +public inline fun BackgroundType.ifMovable(block: (BackgroundType.Movable) -> T): T? = + movableOrNull() ?.let(block) + +public inline fun BackgroundType.unknownOrNull(): BackgroundType.Unknown? = this as? + dev.inmo.tgbotapi.types.BackgroundType.Unknown + +public inline fun BackgroundType.unknownOrThrow(): BackgroundType.Unknown = this as + dev.inmo.tgbotapi.types.BackgroundType.Unknown + +public inline fun BackgroundType.ifUnknown(block: (BackgroundType.Unknown) -> T): T? = + unknownOrNull() ?.let(block) + +public inline fun BackgroundType.withDocumentOrNull(): BackgroundType.WithDocument? = this as? + dev.inmo.tgbotapi.types.BackgroundType.WithDocument + +public inline fun BackgroundType.withDocumentOrThrow(): BackgroundType.WithDocument = this as + dev.inmo.tgbotapi.types.BackgroundType.WithDocument + +public inline fun BackgroundType.ifWithDocument(block: (BackgroundType.WithDocument) -> T): T? = + withDocumentOrNull() ?.let(block) + public inline fun ChatIdentifier.idChatIdentifierOrNull(): IdChatIdentifier? = this as? dev.inmo.tgbotapi.types.IdChatIdentifier @@ -2943,6 +3064,15 @@ public inline fun TelegramMedia.titledTelegramMediaOrThrow(): TitledTelegramMedi public inline fun TelegramMedia.ifTitledTelegramMedia(block: (TitledTelegramMedia) -> T): T? = titledTelegramMediaOrNull() ?.let(block) +public inline fun ChatEvent.chatBackgroundOrNull(): ChatBackground? = this as? + dev.inmo.tgbotapi.types.chat.ChatBackground + +public inline fun ChatEvent.chatBackgroundOrThrow(): ChatBackground = this as + dev.inmo.tgbotapi.types.chat.ChatBackground + +public inline fun ChatEvent.ifChatBackground(block: (ChatBackground) -> T): T? = + chatBackgroundOrNull() ?.let(block) + public inline fun ChatEvent.giveawayCreatedOrNull(): GiveawayCreated? = this as? dev.inmo.tgbotapi.types.giveaway.GiveawayCreated