mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-09-14 21:00:15 +00:00
add support of ChatBackground
This commit is contained in:
@@ -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<HEXAColor>
|
||||
|
||||
@Serializable
|
||||
data class Solid(
|
||||
@SerialName(colorField)
|
||||
@Serializable(IntRGB24HEXAColorSerializer::class)
|
||||
val color: HEXAColor
|
||||
) : BackgroundFill {
|
||||
@Transient
|
||||
override val colors: List<HEXAColor> = 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<HEXAColor> = 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<HEXAColor> = emptyList()
|
||||
}
|
||||
|
||||
companion object : KSerializer<BackgroundFill> {
|
||||
@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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -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<BackgroundType> {
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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"
|
||||
|
@@ -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
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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 <T> Decoder.extractDataAndJson(serializer: DeserializationStrategy<T>): Pair<T, JsonElement?> {
|
||||
return if (this is JsonDecoder) {
|
||||
val raw = decodeJsonElement()
|
||||
json.decodeFromJsonElement(serializer, raw) to raw
|
||||
} else {
|
||||
serializer.deserialize(this) to null
|
||||
}
|
||||
}
|
@@ -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<Progress> {
|
||||
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
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@@ -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<HEXAColor> {
|
||||
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)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user