From 46cc37be62a449d6c5c68f549f56bc46b681e41d Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 12 Sep 2021 17:15:58 +0600 Subject: [PATCH] LocationContent -> LiveLocationContent / StaticLocationContent --- CHANGELOG.md | 1 + .../tgbotapi/requests/send/SendLocation.kt | 2 +- .../types/message/content/LocationContent.kt | 116 +++++++++++++----- .../dev/inmo/tgbotapi/types/BotActionTests.kt | 1 + .../tgbotapi/extensions/utils/ClassCasts.kt | 18 +++ 5 files changed, 108 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af778772b3..bddeb85c80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * `MicroUtils`: `0.5.25` -> `0.5.26` * `Core`: * New `BotAction` implementation - `CustomBotAction` + * `LocationContent` has been divided to two different types: `LiveLocationContent` and `StaticLocationContent` ## 0.35.8 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendLocation.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendLocation.kt index 69da7631dc..9d564a92f9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendLocation.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendLocation.kt @@ -6,7 +6,7 @@ import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass -import dev.inmo.tgbotapi.types.message.content.LocationContent +import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.utils.throwRangeError import kotlinx.serialization.* diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/LocationContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/LocationContent.kt index 36c5d90f35..f00fd71c44 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/LocationContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/LocationContent.kt @@ -3,46 +3,104 @@ package dev.inmo.tgbotapi.types.message.content import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.send.SendLiveLocation import dev.inmo.tgbotapi.requests.send.SendStaticLocation +import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest import dev.inmo.tgbotapi.types.ChatIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.location.* import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent -import kotlinx.serialization.Serializable +import kotlinx.serialization.* +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.encoding.* -@Serializable -data class LocationContent( +@Serializable(LocationContentSerializer::class) +sealed interface LocationContent : MessageContent { val location: Location -) : MessageContent { + + companion object { + operator fun invoke(location: Location): LocationContent { + return when (location) { + is StaticLocation -> StaticLocationContent(location) + is LiveLocation -> LiveLocationContent(location) + } + } + } +} + +@Serializer(LocationContent::class) +object LocationContentSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("LocationContent") { + element(LocationContent::location.name, LocationSerializer.descriptor) + } + + override fun deserialize(decoder: Decoder): LocationContent { + lateinit var location: Location + + decoder.decodeStructure(descriptor) { + while (true) { + when (val index = decodeElementIndex(descriptor)) { + 0 -> location = decodeSerializableElement(descriptor, index, LocationSerializer) + CompositeDecoder.DECODE_DONE -> break + else -> error("Unexpected index: $index") + } + } + } + + return LocationContent(location) + } + + override fun serialize(encoder: Encoder, value: LocationContent) { + encoder.beginStructure(descriptor).apply { + encodeSerializableElement(descriptor, 0, LocationSerializer, value.location) + }.endStructure(descriptor) + } + +} + +@Serializable(LocationContentSerializer::class) +data class LiveLocationContent( + override val location: LiveLocation +) : LocationContent { override fun createResend( chatId: ChatIdentifier, disableNotification: Boolean, replyToMessageId: MessageIdentifier?, allowSendingWithoutReply: Boolean?, replyMarkup: KeyboardMarkup? - ): Request> = when (location) { - is StaticLocation -> SendStaticLocation( - chatId, - location.latitude, - location.longitude, - disableNotification, - replyToMessageId, - allowSendingWithoutReply, - replyMarkup - ) - is LiveLocation -> SendLiveLocation( - chatId, - location.latitude, - location.longitude, - location.livePeriod, - location.horizontalAccuracy, - location.heading, - location.proximityAlertRadius, - disableNotification, - replyToMessageId, - allowSendingWithoutReply, - replyMarkup - ) - } -} \ No newline at end of file + ): Request> = SendLiveLocation( + chatId, + location.latitude, + location.longitude, + location.livePeriod, + location.horizontalAccuracy, + location.heading, + location.proximityAlertRadius, + disableNotification, + replyToMessageId, + allowSendingWithoutReply, + replyMarkup + ) as SendMessageRequest> +} + +@Serializable(LocationContentSerializer::class) +data class StaticLocationContent( + override val location: StaticLocation +) : LocationContent { + override fun createResend( + chatId: ChatIdentifier, + disableNotification: Boolean, + replyToMessageId: MessageIdentifier?, + allowSendingWithoutReply: Boolean?, + replyMarkup: KeyboardMarkup? + ): Request> = SendStaticLocation( + chatId, + location.latitude, + location.longitude, + disableNotification, + replyToMessageId, + allowSendingWithoutReply, + replyMarkup + ) as SendMessageRequest> +} diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt index e10fef23e7..451b36d9a1 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/BotActionTests.kt @@ -27,6 +27,7 @@ class BotActionTests { FindLocationAction -> example.botAction.actionName RecordVideoNoteAction -> example.botAction.actionName UploadVideoNoteAction -> example.botAction.actionName + is CustomBotAction -> example.botAction.actionName } ) } diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index c0da943b17..081897006e 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -2506,6 +2506,24 @@ inline fun ResendableContent.asLocationContent(): LocationContent? = this as? Lo @PreviewFeature inline fun ResendableContent.requireLocationContent(): LocationContent = this as LocationContent +@PreviewFeature +inline fun ResendableContent.whenLiveLocationContent(block: (LiveLocationContent) -> T) = asLiveLocationContent() ?.let(block) + +@PreviewFeature +inline fun ResendableContent.asLiveLocationContent(): LiveLocationContent? = this as? LiveLocationContent + +@PreviewFeature +inline fun ResendableContent.requireLiveLocationContent(): LiveLocationContent = this as LiveLocationContent + +@PreviewFeature +inline fun ResendableContent.whenStaticLocationContent(block: (StaticLocationContent) -> T) = asStaticLocationContent() ?.let(block) + +@PreviewFeature +inline fun ResendableContent.asStaticLocationContent(): StaticLocationContent? = this as? StaticLocationContent + +@PreviewFeature +inline fun ResendableContent.requireStaticLocationContent(): StaticLocationContent = this as StaticLocationContent + @PreviewFeature inline fun ResendableContent.whenPollContent(block: (PollContent) -> T) = asPollContent() ?.let(block)