diff --git a/CHANGELOG.md b/CHANGELOG.md index 350c2f1f7e..f67426b952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # TelegramBotAPI changelog +## 0.21.0 TelegramBotAPI 4.5 + +* _**All `MessageEntity`'es now are replaced with `TextPart`**_ +* Added support of strikethrough and underline + * Added `UnderlineTextSource` + * Added `StrikethroughTextSource` + * Added support in `RawMessageEntity` +* Added support of `MarkdownV2` +* Now will not be thrown exception when there is income unknown type of `RawMessageEntity`. Instead of this will be +created `RegularTextSource` with the same text +* Fixed problem that usually string formatting did not trigger escaping of control characters +* Actualized work with `pre` type of text - now it is possible to use `language` for formatting of text +* Removed constructor of `TextMentionTextSource`, which was deprecated previously +* All `TelegramMediaFile` instances now have field `fileUniqueId`, which represents `file_unique_id` field from API +* Now `ChatPhoto` have two additional fields: `smallFileUniqueId` and `bigFileUniqueId` +* Now any administrator object instance have `customTitle` nullable field +* Added the new request `SetChatAdministratorCustomTitle` to manage the custom titles of administrators promoted by the +bot. +* Added the field `slowModeDelay` to the `ExtendedSupergroupChat` objects. + +* `CaptionedInput` now have extension `fullEntitiesList` which will return list of `TextPart` with `RegularSource`'s +* `TextPart` added - it will be used as part of some text and can be not related to telegram bot +* `MultilevelTextSource` was added - it is type of `TextSource`, which can have subsources as parts of this text +* In all `TextSource`s all fields now are lazy for avoiding of potential risk for performance issues + ## 0.20.0 MPP Migration * Time library change: `joda-time` -> `com.soywiz.korlibs.klock:klock` diff --git a/build.gradle b/build.gradle index d15f48af65..4a20b41134 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ plugins { id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" } -project.version = "0.20.4" +project.version = "0.21.0" project.group = "com.github.insanusmokrassar" apply from: "publish.gradle" diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt index 7a80c885a1..b7755a370f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt @@ -1,7 +1,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.ParseMode +import com.github.insanusmokrassar.TelegramBotAPI.utils.fullListOfSubSource interface Captioned { val caption: String? @@ -12,5 +12,7 @@ interface CaptionedOutput : Captioned { } interface CaptionedInput : Captioned { - val captionEntities: List + val captionEntities: List } + +fun CaptionedInput.fullEntitiesList() = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList() diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt index 6a40155809..be70f1032e 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt @@ -2,5 +2,16 @@ package com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts interface TextSource { val asMarkdownSource: String + val asMarkdownV2Source: String val asHtmlSource: String -} \ No newline at end of file +} + + +interface MultilevelTextSource : TextSource { + val textParts: List +} + +data class TextPart( + val range: IntRange, + val source: TextSource +) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt index 0658c692f3..4e8fb1f428 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/AbstractRequestCallFactory.kt @@ -9,8 +9,6 @@ import io.ktor.client.request.accept import io.ktor.client.request.url import io.ktor.http.ContentType import io.ktor.http.HttpMethod -import kotlin.collections.MutableMap -import kotlin.collections.mutableMapOf import kotlin.collections.set abstract class AbstractRequestCallFactory : KtorCallFactory { diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/chat/members/SetChatAdministratorCustomTitle.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/chat/members/SetChatAdministratorCustomTitle.kt new file mode 100644 index 0000000000..0595455bf2 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/chat/members/SetChatAdministratorCustomTitle.kt @@ -0,0 +1,33 @@ +package com.github.insanusmokrassar.TelegramBotAPI.requests.chat.members + +import com.github.insanusmokrassar.TelegramBotAPI.requests.chat.abstracts.ChatMemberRequest +import com.github.insanusmokrassar.TelegramBotAPI.types.* +import kotlinx.serialization.* +import kotlinx.serialization.internal.BooleanSerializer + +/** + * Representation of https://core.telegram.org/bots/api#setchatadministratorcustomtitle + * + * Please, remember about restrictions for characters in custom title + */ +@Serializable +data class SetChatAdministratorCustomTitle( + @SerialName(chatIdField) + override val chatId: ChatId, + @SerialName(userIdField) + override val userId: UserId, + @SerialName(customTitleField) + val customTitle: String +) : ChatMemberRequest { + override fun method(): String = "setChatAdministratorCustomTitle" + override val resultDeserializer: DeserializationStrategy + get() = BooleanSerializer + override val requestSerializer: SerializationStrategy<*> + get() = RestrictChatMember.serializer() + + init { + if (customTitle.length !in customTitleLength) { + throw IllegalArgumentException("Custom title length must be in range $customTitleLength, but was ${customTitle.length}") + } + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/AdministratorChatMemberImpl.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/AdministratorChatMemberImpl.kt index 168b61ff8f..23662f990e 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/AdministratorChatMemberImpl.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/AdministratorChatMemberImpl.kt @@ -13,5 +13,6 @@ data class AdministratorChatMemberImpl( override val canInviteUsers: Boolean, override val canRestrictMembers: Boolean, override val canPinMessages: Boolean, - override val canPromoteMembers: Boolean + override val canPromoteMembers: Boolean, + override val customTitle: String? ) : AdministratorChatMember diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/CreatorChatMember.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/CreatorChatMember.kt index b00de59489..d92d84b2d8 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/CreatorChatMember.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/CreatorChatMember.kt @@ -3,8 +3,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.ChatMember import com.github.insanusmokrassar.TelegramBotAPI.types.ChatMember.abstracts.AdministratorChatMember import com.github.insanusmokrassar.TelegramBotAPI.types.User -data class CreatorChatMember(override val user: User) : - AdministratorChatMember { +data class CreatorChatMember( + override val user: User, + override val customTitle: String? +) : AdministratorChatMember { override val canBeEdited: Boolean = true override val canChangeInfo: Boolean = true override val canPostMessages: Boolean = true diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/RawChatMember.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/RawChatMember.kt index 278f851e73..ac40748e8a 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/RawChatMember.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/RawChatMember.kt @@ -39,11 +39,13 @@ internal data class RawChatMember( @SerialName(canSendOtherMessagesField) private val canSendOtherMessages: Boolean = false, @SerialName(canAddWebPagePreviewsField) - private val canAddWebPagePreviews: Boolean = false + private val canAddWebPagePreviews: Boolean = false, + @SerialName(customTitleField) + private val customTitle: String? = null ) { val asChatMember: ChatMember by lazy { when (status) { - "creator" -> CreatorChatMember(user) + "creator" -> CreatorChatMember(user, customTitle) "administrator" -> AdministratorChatMemberImpl( user, canBeEdited, @@ -54,7 +56,8 @@ internal data class RawChatMember( canInviteUsers, canRestrictMembers, canPinMessages, - canPromoteMembers + canPromoteMembers, + customTitle ) "member" -> MemberChatMember(user) "restricted" -> RestrictedChatMember( diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/abstracts/AdministratorChatMember.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/abstracts/AdministratorChatMember.kt index 27bc3e5842..f99ce2ef25 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/abstracts/AdministratorChatMember.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatMember/abstracts/AdministratorChatMember.kt @@ -7,4 +7,5 @@ interface AdministratorChatMember : SpecialRightsChatMember { val canRemoveMessages: Boolean val canRestrictMembers: Boolean val canPromoteMembers: Boolean + val customTitle: String? } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatPhoto.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatPhoto.kt index ba6784430d..3e2e76811f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatPhoto.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ChatPhoto.kt @@ -5,8 +5,12 @@ import kotlinx.serialization.Serializable @Serializable data class ChatPhoto( - @SerialName("small_file_id") + @SerialName(smallFileIdField) val smallFileId: String, - @SerialName("big_file_id") - val bigFileId: String + @SerialName(bigFileIdField) + val bigFileId: String, + @SerialName(smallFileUniqueIdField) + val smallFileUniqueId: FileUniqueId, + @SerialName(bigFileUniqueIdField) + val bigFileUniqueId: FileUniqueId ) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt index dd07501d98..873e7c49de 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/Common.kt @@ -18,6 +18,7 @@ typealias StartParameter = String typealias InlineMessageIdentifier = String typealias PollIdentifier = String typealias StickerSetName = String +typealias FileUniqueId = String val callbackQueryAnswerLength = 0 until 200 val captionLength = 0 until 1024 @@ -40,6 +41,8 @@ val livePeriodLimit = 60 .. 86400 val inlineQueryAnswerResultsLimit = 0 .. 50 +val customTitleLength = 0 .. 16 + const val chatIdField = "chat_id" const val messageIdField = "message_id" const val updateIdField = "update_id" @@ -57,6 +60,7 @@ const val languageCodeField = "language_code" const val textEntitiesField = "text_entities" const val stickerSetNameField = "set_name" const val stickerSetNameFullField = "sticker_set_name" +const val slowModeDelayField = "slow_mode_delay" const val maskPositionField = "mask_position" const val phoneNumberField = "phone_number" const val userIdField = "user_id" @@ -94,6 +98,7 @@ const val switchInlineQueryField = "switch_inline_query" const val isAnimatedField = "is_animated" const val inviteLinkField = "invite_link" const val pinnedMessageField = "pinned_message" +const val customTitleField = "custom_title" const val requestWriteAccessField = "request_write_access" @@ -217,6 +222,14 @@ const val yShiftField = "y_shift" const val scaleField = "scale" +const val smallFileIdField = "small_file_id" +const val bigFileIdField = "big_file_id" +const val smallFileUniqueIdField = "small_file_unique_id" +const val bigFileUniqueIdField = "big_file_unique_id" + +const val fileUniqueIdField = "file_unique_id" + + const val currencyField = "currency" const val startParameterField = "start_parameter" const val totalAmountField = "total_amount" diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt deleted file mode 100644 index 2e02d6b935..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.BoldTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldMarkdown - -data class BoldTextMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by BoldTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt deleted file mode 100644 index 088956a44b..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.BotCommandTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandMarkdown - -data class BotCommandMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String, - private val botCommandTextSource: BotCommandTextSource = BotCommandTextSource(sourceString) -) : MessageEntity, TextSource by botCommandTextSource { - val command: String - get() = botCommandTextSource.command -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt deleted file mode 100644 index bb45546d75..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.CodeTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeMarkdown - -data class CodeTextMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by CodeTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt deleted file mode 100644 index f5456fbdea..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.EMailTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailMarkdown - -data class EMailMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by EMailTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt deleted file mode 100644 index 63733e5d8a..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.HashTagTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagMarkdown - -data class HashTagMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by HashTagTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt deleted file mode 100644 index db25785295..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.ItalicTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicMarkdown - -data class ItalicTextMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by ItalicTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt deleted file mode 100644 index 9886f4592e..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.MentionTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown - -class MentionMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by MentionTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt deleted file mode 100644 index 79a68f9997..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource - -interface MessageEntity : TextSource { - val offset: Int - val length: Int - val sourceString: String -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt deleted file mode 100644 index 79a5fb5357..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.PhoneNumberTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneMarkdown - -data class PhoneNumberMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by PhoneNumberTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt deleted file mode 100644 index 80943d942b..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.PreTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.preHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.preMarkdown - -data class PreTextMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by PreTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt index 489531935c..d33b743ab1 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt @@ -1,9 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.* import com.github.insanusmokrassar.TelegramBotAPI.types.User -import kotlinx.serialization.KSerializer +import com.github.insanusmokrassar.TelegramBotAPI.utils.shiftSourcesToTheLeft import kotlinx.serialization.Serializable -import kotlinx.serialization.internal.ArrayListSerializer @Serializable internal data class RawMessageEntity( @@ -12,30 +14,74 @@ internal data class RawMessageEntity( val length: Int, val url: String? = null, val user: User? = null -) { - fun asMessageEntity(source: String): MessageEntity { - val sourceSubstring = source.substring(offset, offset + length) - return when (type) { - "mention" -> MentionMessageEntity(offset, length, sourceSubstring) - "hashtag" -> HashTagMessageEntity(offset, length, sourceSubstring) - "cashtag" -> TODO() - "bot_command" -> BotCommandMessageEntity(offset, length, sourceSubstring) - "url" -> URLMessageEntity(offset, length, sourceSubstring) - "email" -> EMailMessageEntity(offset, length, sourceSubstring) - "phone_number" -> PhoneNumberMessageEntity(offset, length, sourceSubstring) - "bold" -> BoldTextMessageEntity(offset, length, sourceSubstring) - "italic" -> ItalicTextMessageEntity(offset, length, sourceSubstring) - "code" -> CodeTextMessageEntity(offset, length, sourceSubstring) - "pre" -> PreTextMessageEntity(offset, length, sourceSubstring) - "text_link" -> TextLinkMessageEntity(offset, length, sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link")) - "text_mention" -> TextMentionMessageEntity(offset, length, sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention")) - else -> throw IllegalArgumentException("Unknown type of message entity") +) + +internal fun RawMessageEntity.asTextParts(source: String, subParts: List): List { + val sourceSubstring = source.substring(offset, offset + length) + val range = offset until (offset + length) + val shiftedSubParts = subParts.shiftSourcesToTheLeft(offset) + return when (type) { + "mention" -> MentionTextSource(sourceSubstring, shiftedSubParts) + "hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubParts) + "cashtag" -> TODO() + "bot_command" -> BotCommandTextSource(sourceSubstring, shiftedSubParts) + "url" -> URLTextSource(sourceSubstring) + "email" -> EMailTextSource(sourceSubstring, shiftedSubParts) + "phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubParts) + "bold" -> BoldTextSource(sourceSubstring, shiftedSubParts) + "italic" -> ItalicTextSource(sourceSubstring, shiftedSubParts) + "code" -> CodeTextSource(sourceSubstring) + "pre" -> PreTextSource(sourceSubstring) + "text_link" -> TextLinkTextSource(sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link")) + "text_mention" -> TextMentionTextSource(sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention"), shiftedSubParts) + "underline" -> UnderlineTextSource(sourceSubstring, shiftedSubParts) + "strikethrough" -> StrikethroughTextSource(sourceSubstring, shiftedSubParts) + else -> RegularTextSource(sourceSubstring) + }.let { + val part = TextPart(range, it) + if (it !is MultilevelTextSource && subParts.isNotEmpty()) { + (subParts + part).sortedBy { currentPart -> currentPart.range.first } + } else { + listOf(part) } } } -internal typealias RawMessageEntities = List +internal fun createTextPart(from: String, entities: RawMessageEntities): List { + val mutableEntities = entities.toMutableList() + mutableEntities.sortBy { it.offset } + val resultList = mutableListOf() -internal object RawMessageEntitiesSerializer : KSerializer> by ArrayListSerializer( - RawMessageEntity.serializer() -) + while (mutableEntities.isNotEmpty()) { + val currentFirst = mutableEntities.removeAt(0) + val subEntities = if (mutableEntities.isNotEmpty()) { + val lastIndex = currentFirst.offset + currentFirst.length + val subEntities = mutableListOf() + while (mutableEntities.isNotEmpty()) { + val currentPossibleSubEntity = mutableEntities.first() + if (currentPossibleSubEntity.offset < lastIndex) { + subEntities.add(currentPossibleSubEntity) + mutableEntities.removeAt(0) + } else { + break + } + } + subEntities + } else { + emptyList() + } + + resultList.addAll( + currentFirst.asTextParts( + from, + createTextPart(from, subEntities) + ) + ) + } + + return resultList +} + +internal fun RawMessageEntities.asTextParts(sourceString: String): List = createTextPart(sourceString, this) + +internal typealias RawMessageEntities = List diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt deleted file mode 100644 index b7e683f80a..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.RegularTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toMarkdown - -data class RegularTextMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by RegularTextSource(sourceString) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt deleted file mode 100644 index 576f8043bc..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.TextLinkTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown - -data class TextLinkMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String, - val url: String -) : MessageEntity, TextSource by TextLinkTextSource(sourceString, url) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt deleted file mode 100644 index ad7334e9af..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.TextMentionTextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.User -import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown - -class TextMentionMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String, - val privateChat: PrivateChat -) : MessageEntity, TextSource by TextMentionTextSource(sourceString, privateChat) { - @Deprecated("Deprecated due to the fact that there is more common constructor") - constructor( - offset: Int, - length: Int, - sourceString: String, - user: User - ) : this(offset, length, sourceString, user as PrivateChat) -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt deleted file mode 100644 index 482ad28fe6..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.URLTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown - -data class URLMessageEntity( - override val offset: Int, - override val length: Int, - override val sourceString: String -) : MessageEntity, TextSource by URLTextSource(sourceString) { - val url: String = sourceString -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt index 9d1a1f7d7e..a491b5953f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt @@ -1,12 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class BoldTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.boldMarkdown() - override val asHtmlSource: String = sourceString.boldHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.boldMarkdown() } + override val asMarkdownV2Source: String by lazy { boldMarkdownV2() } + override val asHtmlSource: String by lazy { boldHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt index 2c6eb4e0a3..a8dfaa4c52 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt @@ -1,18 +1,25 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* private val commandRegex = Regex("[/!][^@\\s]*") class BotCommandTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.commandMarkdown() - override val asHtmlSource: String = sourceString.commandHTML() - + source: String, + textParts: List +) : MultilevelTextSource { val command: String by lazy { - commandRegex.find(sourceString) ?.value ?.substring(1) ?: sourceString.substring(1)// skip first symbol like "/" or "!" + commandRegex.find(source) ?.value ?.substring(1) ?: source.substring(1)// skip first symbol like "/" or "!" } + + override val textParts: List by lazy { + command.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + } + override val asMarkdownSource: String by lazy { source.commandMarkdown() } + override val asMarkdownV2Source: String by lazy { commandMarkdownV2() } + override val asHtmlSource: String by lazy { commandHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt index ab0066a60b..5b2359a458 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt @@ -1,12 +1,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class CodeTextSource( - sourceString: String + source: String ) : TextSource { - override val asMarkdownSource: String = sourceString.codeMarkdown() - override val asHtmlSource: String = sourceString.codeHTML() + override val asMarkdownSource: String by lazy { source.codeMarkdown() } + override val asMarkdownV2Source: String by lazy { source.codeMarkdownV2() } + override val asHtmlSource: String by lazy { source.codeHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt index 34b5ed34ce..f87d899953 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt @@ -1,12 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class EMailTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.emailMarkdown() - override val asHtmlSource: String = sourceString.emailHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.emailMarkdown() } + override val asMarkdownV2Source: String by lazy { emailMarkdownV2(source) } + override val asHtmlSource: String by lazy { emailHTML(source) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt index 4894fabecf..1daabab4d7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt @@ -1,12 +1,26 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +private val String.withoutSharp + get() = if (startsWith("#")){ + substring(1) + } else { + this + } class HashTagTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.hashTagMarkdown() - override val asHtmlSource: String = sourceString.hashTagHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { + source.withoutSharp.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + } + override val asMarkdownSource: String by lazy { source.hashTagMarkdown() } + override val asMarkdownV2Source: String by lazy { hashTagMarkdownV2() } + override val asHtmlSource: String by lazy { hashTagHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt index 2e1d1170e0..5043cd19d8 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt @@ -1,12 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class ItalicTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.italicMarkdown() - override val asHtmlSource: String = sourceString.italicHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.italicMarkdown() } + override val asMarkdownV2Source: String by lazy { italicMarkdownV2() } + override val asHtmlSource: String by lazy { italicHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt index 8d2b0cc71a..398ae8c388 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt @@ -1,12 +1,26 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +private val String.withoutCommercialAt + get() = if (startsWith("@")) { + substring(1) + } else { + this + } class MentionTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.mentionMarkdown() - override val asHtmlSource: String = sourceString.mentionHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { + source.withoutCommercialAt.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + } + override val asMarkdownSource: String by lazy { source.mentionMarkdown() } + override val asMarkdownV2Source: String by lazy { mentionMarkdownV2() } + override val asHtmlSource: String by lazy { mentionHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt index f5004fa7d5..f83e41be12 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt @@ -1,12 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class PhoneNumberTextSource( - sourceString: String -) : TextSource { - override val asMarkdownSource: String = sourceString.phoneMarkdown() - override val asHtmlSource: String = sourceString.phoneHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.phoneMarkdown() } + override val asMarkdownV2Source: String by lazy { phoneMarkdownV2() } + override val asHtmlSource: String by lazy { phoneHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt index 7a0fea96dc..d83896ba3f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt @@ -1,12 +1,13 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.preHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.preMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class PreTextSource( - sourceString: String + source: String, + val language: String? = null ) : TextSource { - override val asMarkdownSource: String = sourceString.preMarkdown() - override val asHtmlSource: String = sourceString.preHTML() + override val asMarkdownSource: String by lazy { source.preMarkdown(language) } + override val asMarkdownV2Source: String by lazy { source.preMarkdownV2(language) } + override val asHtmlSource: String by lazy { source.preHTML(language) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt index 0125346add..dca8f5aedc 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt @@ -1,12 +1,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class RegularTextSource( - sourceString: String + source: String ) : TextSource { - override val asMarkdownSource: String = sourceString.toMarkdown() - override val asHtmlSource: String = sourceString.toHtml() + override val asMarkdownSource: String by lazy { source.regularMarkdown() } + override val asMarkdownV2Source: String by lazy { source.regularMarkdownV2() } + override val asHtmlSource: String by lazy { source.regularHtml() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt new file mode 100644 index 0000000000..17c79618bf --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt @@ -0,0 +1,15 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +class StrikethroughTextSource( + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asHtmlSource: String by lazy { strikethroughHTML() } + override val asMarkdownV2Source: String by lazy { strikethroughMarkdownV2() } + override val asMarkdownSource: String by lazy { source.strikethroughMarkdown() } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt index a9e7ae225a..73d3ff8803 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt @@ -1,13 +1,13 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class TextLinkTextSource( - sourceString: String, + source: String, url: String ) : TextSource { - override val asMarkdownSource: String = sourceString.linkMarkdown(url) - override val asHtmlSource: String = sourceString.linkHTML(url) + override val asMarkdownSource: String by lazy { source.linkMarkdown(url) } + override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(url) } + override val asHtmlSource: String by lazy { source.linkHTML(url) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt index 720436e8d7..b335806c6f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt @@ -1,21 +1,17 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.User +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class TextMentionTextSource( - sourceString: String, - privateChat: PrivateChat -) : TextSource { - @Deprecated("Deprecated due to the fact that there is more common constructor") - constructor( - sourceString: String, - user: User - ) : this(sourceString, user as PrivateChat) - - override val asMarkdownSource: String = sourceString.mentionMarkdown(privateChat.id) - override val asHtmlSource: String = sourceString.mentionHTML(privateChat.id) + source: String, + privateChat: PrivateChat, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.textMentionMarkdown(privateChat.id) } + override val asMarkdownV2Source: String by lazy { textMentionMarkdownV2(privateChat.id) } + override val asHtmlSource: String by lazy { textMentionHTML(privateChat.id) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt index 581af0f015..bd572b097b 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt @@ -1,12 +1,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class URLTextSource( - sourceString: String -) : TextSource{ - override val asMarkdownSource: String = sourceString.linkMarkdown(sourceString) - override val asHtmlSource: String = sourceString.linkHTML(sourceString) + source: String +) : TextSource { + override val asMarkdownSource: String by lazy { source.linkMarkdown(source) } + override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(source) } + override val asHtmlSource: String by lazy { source.linkHTML(source) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt new file mode 100644 index 0000000000..6cc142ec25 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt @@ -0,0 +1,15 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +class UnderlineTextSource( + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.underlineMarkdown() } + override val asMarkdownV2Source: String by lazy { underlineMarkdownV2() } + override val asHtmlSource: String by lazy { underlineHTML() } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt index 7a94983458..e3558593d7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt @@ -16,6 +16,12 @@ object MarkdownParseMode : ParseMode() { override val parseModeName: String = "Markdown" } +@Serializable(ParseModeSerializerObject::class) +object MarkdownV2ParseMode : ParseMode() { + @Serializable + @SerialName(parseModeField) + override val parseModeName: String = "MarkdownV2" +} @Serializable(ParseModeSerializerObject::class) object HTMLParseMode : ParseMode() { @Serializable @@ -24,6 +30,7 @@ object HTMLParseMode : ParseMode() { } typealias Markdown = MarkdownParseMode +typealias MarkdownV2 = MarkdownV2ParseMode typealias HTML = HTMLParseMode @Serializer(ParseMode::class) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/abstracts/extended/ExtendedSupergroupChat.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/abstracts/extended/ExtendedSupergroupChat.kt index 5dd9f3d8ca..4979a0bd5c 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/abstracts/extended/ExtendedSupergroupChat.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/abstracts/extended/ExtendedSupergroupChat.kt @@ -4,6 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.StickerSetName import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.SupergroupChat interface ExtendedSupergroupChat : SupergroupChat, ExtendedGroupChat { + val slowModeDelay: Long? val stickerSetName: StickerSetName? val canSetStickerSet: Boolean } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/extended/ExtendedSupergroupChatImpl.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/extended/ExtendedSupergroupChatImpl.kt index 80a13e37f2..6f906ff566 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/extended/ExtendedSupergroupChatImpl.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/chat/extended/ExtendedSupergroupChatImpl.kt @@ -29,6 +29,8 @@ data class ExtendedSupergroupChatImpl( override val pinnedMessage: Message? = null, @SerialName(stickerSetNameFullField) override val stickerSetName: StickerSetName? = null, + @SerialName(slowModeDelayField) + override val slowModeDelay: Long? = null, @SerialName(canSetStickerSetField) override val canSetStickerSet: Boolean = false ) : ExtendedSupergroupChat diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AnimationFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AnimationFile.kt index 2894fb044e..ced764d938 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AnimationFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AnimationFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class AnimationFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, override val width: Int, override val height: Int, override val duration: Long? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AudioFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AudioFile.kt index eeff93e261..70681158ac 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AudioFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/AudioFile.kt @@ -2,6 +2,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.Performerable import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -10,6 +12,8 @@ import kotlinx.serialization.Serializable data class AudioFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, override val duration: Long? = null, override val performer: String? = null, override val title: String? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/DocumentFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/DocumentFile.kt index 4235c29696..80034393c5 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/DocumentFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/DocumentFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class DocumentFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName(fileSizeField) override val fileSize: Long? = null, override val thumb: PhotoSize? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/File.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/File.kt index 6badacd212..812daa78b7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/File.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/File.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class File( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName(fileSizeField) override val fileSize: Long? = null ): TelegramMediaFile diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PathedFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PathedFile.kt index 6b85ec49ed..c2a01cab85 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PathedFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PathedFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.utils.TelegramAPIUrlsKeeper import kotlinx.serialization.SerialName @@ -10,6 +12,8 @@ import kotlinx.serialization.Serializable data class PathedFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName(filePathField) val filePath: String, @SerialName(fileSizeField) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PhotoSize.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PhotoSize.kt index 6b977bf1c3..d42e3c4669 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PhotoSize.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/PhotoSize.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.* import kotlinx.serialization.internal.ArrayListSerializer @@ -19,6 +21,8 @@ object PhotoSerializer : KSerializer by ArrayListSerializer( data class PhotoSize( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName(fileSizeField) override val fileSize: Long? = null, override val width: Int, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/Sticker.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/Sticker.kt index fd779dad0e..21eeb15cce 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/Sticker.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/Sticker.kt @@ -11,6 +11,8 @@ import kotlinx.serialization.Serializable data class Sticker( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName(widthField) override val width: Int, @SerialName(heightField) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoFile.kt index f9e7d74e87..a232dafc7a 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class VideoFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, override val width: Int, override val height: Int, override val duration: Long? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoNoteFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoNoteFile.kt index 90bfb35239..98b058acfb 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoNoteFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VideoNoteFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class VideoNoteFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, @SerialName("length") override val width: Int, override val duration: Long? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VoiceFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VoiceFile.kt index b0ee5a26a7..6bcc6226f8 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VoiceFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/VoiceFile.kt @@ -1,6 +1,8 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId +import com.github.insanusmokrassar.TelegramBotAPI.types.fileUniqueIdField import com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -9,6 +11,8 @@ import kotlinx.serialization.Serializable data class VoiceFile( @SerialName(fileIdField) override val fileId: FileId, + @SerialName(fileUniqueIdField) + override val fileUniqueId: FileUniqueId, override val duration: Long? = null, @SerialName(mimeTypeField) override val mimeType: String? = null, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/abstracts/TelegramMediaFile.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/abstracts/TelegramMediaFile.kt index c4749caa59..67a34b9457 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/abstracts/TelegramMediaFile.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/files/abstracts/TelegramMediaFile.kt @@ -1,6 +1,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.files.abstracts import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.FileId +import com.github.insanusmokrassar.TelegramBotAPI.types.FileUniqueId internal const val fileIdField = "file_id" internal const val fileSizeField = "file_size" @@ -11,5 +12,6 @@ internal const val filePathField = "file_path" */ interface TelegramMediaFile { val fileId: FileId + val fileUniqueId: FileUniqueId val fileSize: Long? } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt index f35b549081..6fef99c5f6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt @@ -1,8 +1,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.games -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.Titled -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.files.AnimationFile import com.github.insanusmokrassar.TelegramBotAPI.types.files.Photo @@ -11,6 +9,6 @@ data class Game( val description: String, val photo: Photo, override val caption: String? = null, - override val captionEntities: List = emptyList(), + override val captionEntities: List = emptyList(), val animation: AnimationFile? = null ) : Titled, CaptionedInput diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt index 76054a81ea..5e740529d7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt @@ -2,6 +2,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.games import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RawMessageEntities +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.asTextParts import com.github.insanusmokrassar.TelegramBotAPI.types.files.* import kotlinx.serialization.* @@ -27,7 +28,7 @@ internal data class RawGame( description, photo, caption, - caption ?.let { _ -> captionEntities.map { it.asMessageEntity(caption) } } ?: emptyList(), + caption ?.let { _ -> captionEntities.asTextParts(caption) } ?: emptyList(), animation ) } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt index 14edb09d08..1a48869f16 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt @@ -2,6 +2,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RawMessageEntities +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.asTextParts import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.files.* @@ -85,13 +86,11 @@ internal data class RawMessage( ) { private val content: MessageContent? by lazy { val adaptedCaptionEntities = caption ?.let { - caption_entities ?.map { - it.asMessageEntity(caption) - } + caption_entities ?.asTextParts(caption) } ?: emptyList() when { - text != null -> TextContent(text, entities ?.map { it.asMessageEntity(text) } ?: emptyList()) + text != null -> TextContent(text, entities ?.asTextParts(text) ?: emptyList()) audio != null -> AudioContent( audio, caption, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt index 0dfa2f56f4..0fe6e3296c 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt @@ -1,20 +1,19 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.SendMessage import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent -import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlTexts -import com.github.insanusmokrassar.TelegramBotAPI.utils.toMarkdownTexts +import com.github.insanusmokrassar.TelegramBotAPI.utils.* data class TextContent( val text: String, - val entities: List = emptyList() + val entities: List = emptyList() ) : MessageContent { override fun createResend( chatId: ChatIdentifier, @@ -52,6 +51,7 @@ data class TextContent( parseMode: ParseMode = HTMLParseMode ): List> = when (parseMode) { is MarkdownParseMode -> toMarkdownTexts() + is MarkdownV2ParseMode -> toMarkdownV2Texts() is HTMLParseMode -> toHtmlTexts() }.map { SendMessage( @@ -65,3 +65,5 @@ data class TextContent( ) } } + +fun TextContent.fullEntitiesList() = text.fullListOfSubSource(entities).map { it.source } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt index a47d4d773e..04227b8c05 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendAnimation import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -18,7 +18,7 @@ data class AnimationContent( override val media: AnimationFile, val includedDocument: DocumentFile?, override val caption: String?, - override val captionEntities: List + override val captionEntities: List ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt index 346826b0b1..ff78e9c9a1 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendAudio import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class AudioContent( override val media: AudioFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt index 2b6b31cb8b..219859ce03 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendDocument import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class DocumentContent( override val media: DocumentFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt index d358b88ebe..8a03bd47c0 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt @@ -1,11 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendPhoto import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.InputMediaPhoto import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.MediaGroupMemberInputMedia -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -19,7 +19,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class PhotoContent( override val mediaCollection: List, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaCollectionContent, MediaGroupContent { override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content") diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt index 718845cafb..ff7210e201 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt @@ -1,11 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendVideo import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.InputMediaVideo import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.MediaGroupMemberInputMedia -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -17,7 +17,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class VideoContent( override val media: VideoFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaGroupContent { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt index 63c07dbb5c..61ab4290b6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendVoice import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class VoiceContent( override val media: VoiceFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt new file mode 100644 index 0000000000..7705a6c832 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt @@ -0,0 +1,98 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* +import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.fullEntitiesList +import com.github.insanusmokrassar.TelegramBotAPI.types.textLength + +fun createFormattedText( + entities: List, + partLength: Int = 4096, + mode: ParseMode = MarkdownParseMode +): List { + val texts = mutableListOf() + val textBuilder = StringBuilder(partLength) + for (entity in entities) { + val string = when (mode) { + is MarkdownParseMode -> entity.asMarkdownSource + is MarkdownV2ParseMode -> entity.asMarkdownV2Source + is HTMLParseMode -> entity.asHtmlSource + } + if (textBuilder.length + string.length > partLength) { + if (textBuilder.isNotEmpty()) { + texts.add(textBuilder.toString()) + textBuilder.clear() + } + val chunked = string.chunked(partLength) + val last = chunked.last() + textBuilder.append(last) + val listToAdd = if (chunked.size > 1) { + chunked.subList(0, chunked.size - 1) + } else { + emptyList() + } + listToAdd.forEach { + texts.add(it) + } + } else { + textBuilder.append(string) + } + } + if (textBuilder.isNotEmpty()) { + texts.add(textBuilder.toString()) + textBuilder.clear() + } + return texts +} + + +fun createMarkdownText( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, MarkdownParseMode) + +fun CaptionedInput.toMarkdownCaptions(): List = createMarkdownText( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toMarkdownTexts(): List = createMarkdownText( + fullEntitiesList(), + textLength.last + 1 +) + + +fun createMarkdownV2Text( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, MarkdownV2ParseMode) + +fun CaptionedInput.toMarkdownV2Captions(): List = createMarkdownV2Text( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toMarkdownV2Texts(): List = createMarkdownV2Text( + fullEntitiesList(), + textLength.last + 1 +) + + +fun createHtmlText( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, HTMLParseMode) + +fun CaptionedInput.toHtmlCaptions(): List = createHtmlText( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toHtmlTexts(): List = createHtmlText( + fullEntitiesList(), + textLength.last + 1 +) + + diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt deleted file mode 100644 index 5eca85548f..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RegularTextMessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent - -fun CaptionedInput.fullEntitiesList(): List = caption ?.let { - convertToFullMessageEntityList(it, captionEntities) -} ?: emptyList() - -fun TextContent.fullEntitiesList(): List = convertToFullMessageEntityList(text, entities) - -fun convertToFullMessageEntityList( - text: String, - messageEntities: List -): List { - val result = mutableListOf() - - var offset = 0 - for (entity in messageEntities) { - val newEntitySize = entity.offset - offset - if (newEntitySize > 0) { - val regularEntity = RegularTextMessageEntity(offset, newEntitySize, text.substring(offset, entity.offset)) - result.add(regularEntity) - offset += regularEntity.length - } - result.add(entity) - offset += entity.length - } - val newEntitySize = text.length - offset - if (newEntitySize > 0) { - result.add(RegularTextMessageEntity(offset, newEntitySize, text.substring(offset, text.length))) - } - return result -} - -fun createFormattedText( - entities: List, - partLength: Int = 4096, - mode: ParseMode = MarkdownParseMode -): List { - val texts = mutableListOf() - val textBuilder = StringBuilder(partLength) - for (entity in entities) { - val string = when (mode) { - is MarkdownParseMode -> entity.asMarkdownSource - is HTMLParseMode -> entity.asHtmlSource - } - if (textBuilder.length + string.length > partLength) { - if (textBuilder.isNotEmpty()) { - texts.add(textBuilder.toString()) - textBuilder.clear() - } - val chunked = string.chunked(partLength) - val last = chunked.last() - textBuilder.append(last) - val listToAdd = if (chunked.size > 1) { - chunked.subList(0, chunked.size - 1) - } else { - emptyList() - } - listToAdd.forEach { - texts.add(it) - } - } else { - textBuilder.append(string) - } - } - if (textBuilder.isNotEmpty()) { - texts.add(textBuilder.toString()) - textBuilder.clear() - } - return texts -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt deleted file mode 100644 index a36b52bee5..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode -import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent -import com.github.insanusmokrassar.TelegramBotAPI.types.textLength - -fun createHtmlText( - entities: List, - partLength: Int = 4096 -): List = createFormattedText(entities, partLength, HTMLParseMode) - -fun CaptionedInput.toHtmlCaptions(): List = createHtmlText( - fullEntitiesList(), - captionLength.endInclusive + 1 -) - -fun TextContent.toHtmlTexts(): List = createHtmlText( - fullEntitiesList(), - textLength.endInclusive + 1 -) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt deleted file mode 100644 index c506670702..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownParseMode -import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent -import com.github.insanusmokrassar.TelegramBotAPI.types.textLength - -fun createMarkdownText( - entities: List, - partLength: Int = 4096 -): List = createFormattedText(entities, partLength, MarkdownParseMode) - -fun CaptionedInput.toMarkdownCaptions(): List = createMarkdownText( - fullEntitiesList(), - captionLength.endInclusive + 1 -) - -fun TextContent.toMarkdownTexts(): List = createMarkdownText( - fullEntitiesList(), - textLength.endInclusive + 1 -) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt new file mode 100644 index 0000000000..f54265fc05 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt @@ -0,0 +1,139 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.RegularTextSource +import com.github.insanusmokrassar.TelegramBotAPI.types.UserId +import com.github.insanusmokrassar.TelegramBotAPI.types.link +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.escapeMarkdownV2Link +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml + +internal fun String.fullListOfSubSource(sourceList: List): List { + val sortedSourceList = sourceList.sortedBy { it.range.first }.toMutableList() + + var previousLastIndex = 0 + + val newSubSources = mutableListOf() + + while (sortedSourceList.isNotEmpty()) { + val topSource = sortedSourceList.removeAt(0) + if (topSource.range.first - previousLastIndex > 0) { + val range = previousLastIndex until topSource.range.first + newSubSources.add( + TextPart( + range, + RegularTextSource( + substring(range) + ) + ) + ) + } + newSubSources.add(topSource) + previousLastIndex = topSource.range.last + 1 + } + + if (length > previousLastIndex) { + val range = previousLastIndex until length + newSubSources.add( + TextPart( + range, + RegularTextSource( + substring(range) + ) + ) + ) + } + + return newSubSources +} + +internal fun List.shiftSourcesToTheLeft(shiftCount: Int = 1): List { + return mapNotNull { + val first = (it.range.first - shiftCount).let { firstCalculated -> + if (firstCalculated < 0) { + 0 + } else { + firstCalculated + } + } + val last = (it.range.last - shiftCount).let { lastCalculated -> + if (lastCalculated < 0) { + 0 + } else { + lastCalculated + } + } + it.copy(range = first .. last).let { newSubSource -> + if (newSubSource.range.isEmpty()) { + null + } else { + newSubSource + } + } + } +} + +private fun List.joinSubSourcesMarkdownV2() = joinToString("") { + it.source.asMarkdownV2Source +} + +private fun List.joinSubSourcesHtml() = joinToString("") { + it.source.asHtmlSource +} + +internal fun MultilevelTextSource.markdownV2Default( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "$openControlSymbol${textParts.joinSubSourcesMarkdownV2()}$closeControlSymbol" +internal fun MultilevelTextSource.htmlDefault( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "<$openControlSymbol>${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.linkMarkdownV2( + link: String +) = "[${textParts.joinSubSourcesMarkdownV2()}](${link.escapeMarkdownV2Link()})" +internal fun MultilevelTextSource.linkHTML( + link: String +) = "${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.emailMarkdownV2(address: String): String = linkMarkdownV2("mailto://$address") +internal fun MultilevelTextSource.emailHTML(address: String): String = linkHTML("mailto://$address}") + + +internal fun MultilevelTextSource.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl) +internal fun MultilevelTextSource.boldHTML(): String = htmlDefault(htmlBoldControl) + + +internal fun MultilevelTextSource.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl) +internal fun MultilevelTextSource.italicHTML(): String = htmlDefault(htmlItalicControl) + + +internal fun MultilevelTextSource.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl) +internal fun MultilevelTextSource.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl) + + +internal fun MultilevelTextSource.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl) +internal fun MultilevelTextSource.underlineHTML(): String = htmlDefault(htmlUnderlineControl) + + +internal fun MultilevelTextSource.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link) +internal fun MultilevelTextSource.textMentionHTML(userId: UserId): String = linkHTML(userId.link) + +internal fun MultilevelTextSource.mentionMarkdownV2(): String = "@${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.mentionHTML(): String = "@${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.hashTagMarkdownV2(): String = "\\#${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.hashTagHTML(): String = "#${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.phoneMarkdownV2(): String = textParts.joinSubSourcesMarkdownV2() +internal fun MultilevelTextSource.phoneHTML(): String = textParts.joinSubSourcesHtml() + + +internal fun MultilevelTextSource.commandMarkdownV2(): String = "/${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.commandHTML(): String = "/${textParts.joinSubSourcesHtml()}" + diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt index 1eb31850c4..bf500dabf1 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt @@ -2,138 +2,231 @@ package com.github.insanusmokrassar.TelegramBotAPI.utils import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.* const val markdownBoldControl = "*" const val markdownItalicControl = "_" const val markdownCodeControl = "`" const val markdownPreControl = "```" +const val markdownV2ItalicUnderlineDelimiter = "\u0013" +const val markdownV2StrikethroughControl = "~" +const val markdownV2UnderlineControl = "__" +const val markdownV2UnderlineEndControl = "$markdownV2UnderlineControl$markdownV2ItalicUnderlineDelimiter" +const val markdownV2ItalicEndControl = "$markdownItalicControl$markdownV2ItalicUnderlineDelimiter" + const val htmlBoldControl = "b" const val htmlItalicControl = "i" const val htmlCodeControl = "code" const val htmlPreControl = "pre" +const val htmlUnderlineControl = "u" +const val htmlStrikethroughControl = "s" -private infix fun String.markdownDefault(controlSymbol: String) = "$controlSymbol$this$controlSymbol" -private infix fun String.htmlDefault(controlSymbol: String) = "<$controlSymbol>$this" +private fun String.markdownDefault( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "$openControlSymbol${toMarkdown()}$closeControlSymbol" +private fun String.markdownV2Default( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol, + escapeFun: String.() -> String = String::escapeMarkdownV2Common +) = "$openControlSymbol${escapeFun()}$closeControlSymbol" +private fun String.htmlDefault( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "<$openControlSymbol>${toHtml()}" -infix fun String.linkMarkdown(link: String): String = "[$this]($link)" -infix fun String.linkHTML(link: String): String = "$this" +fun String.linkMarkdown(link: String): String = "[${toMarkdown()}](${link.toMarkdown()})" +fun String.linkMarkdownV2(link: String): String = "[${escapeMarkdownV2Common()}](${link.escapeMarkdownV2Link()})" +fun String.linkHTML(link: String): String = "${toHtml()}" fun String.boldMarkdown(): String = markdownDefault(markdownBoldControl) +fun String.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl) fun String.boldHTML(): String = htmlDefault(htmlBoldControl) fun String.italicMarkdown(): String = markdownDefault(markdownItalicControl) -fun String.italicHTML(): String =htmlDefault(htmlItalicControl) +fun String.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl, markdownV2ItalicEndControl) +fun String.italicHTML(): String = htmlDefault(htmlItalicControl) + +/** + * Crutch for support of strikethrough in default markdown. Simply add modifier, but it will not look like correct + */ +fun String.strikethroughMarkdown(): String = map { it + "\u0336" }.joinToString("") +fun String.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl) +fun String.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl) + + +/** + * Crutch for support of underline in default markdown. Simply add modifier, but it will not look like correct + */ +fun String.underlineMarkdown(): String = map { it + "\u0347" }.joinToString("") +fun String.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl, markdownV2UnderlineEndControl) +fun String.underlineHTML(): String = htmlDefault(htmlUnderlineControl) fun String.codeMarkdown(): String = markdownDefault(markdownCodeControl) +fun String.codeMarkdownV2(): String = markdownV2Default(markdownCodeControl, escapeFun = String::escapeMarkdownV2PreAndCode) fun String.codeHTML(): String = htmlDefault(htmlCodeControl) -fun String.preMarkdown(): String = markdownDefault(markdownPreControl) -fun String.preHTML(): String = htmlDefault(htmlPreControl) +fun String.preMarkdown(language: String? = null): String = markdownDefault( + "$markdownPreControl${language ?: ""}\n", + "\n$markdownPreControl" +) +fun String.preMarkdownV2(language: String? = null): String = markdownV2Default( + "$markdownPreControl${language ?: ""}\n", + "\n$markdownPreControl", + String::escapeMarkdownV2PreAndCode +) +fun String.preHTML(language: String? = null): String = htmlDefault( + language ?.let { + "$htmlPreControl><$htmlCodeControl class=\"language-$language\"" + } ?: htmlPreControl, + language ?.let { + "$htmlCodeControl> String): String = if (startsWith("@")) { - this +private inline fun String.mention(adapt: String.() -> String): String = if (startsWith("@")) { + adapt() } else { "@${adapt()}" } -private inline infix fun String.hashTag(adapt: String.() -> String): String = if (startsWith("#")) { - this +private inline fun String.hashTag(adapt: String.() -> String): String = if (startsWith("#")) { + adapt() } else { "#${adapt()}" } -infix fun String.mentionMarkdown(userId: UserId): String = linkMarkdown(userId.link) -infix fun String.mentionHTML(userId: UserId): String = linkHTML(userId.link) +fun String.textMentionMarkdown(userId: UserId): String = linkMarkdown(userId.link) +fun String.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link) +fun String.textMentionHTML(userId: UserId): String = linkHTML(userId.link) fun String.mentionMarkdown(): String = mention(String::toMarkdown) +fun String.mentionMarkdownV2(): String = mention(String::escapeMarkdownV2Common) fun String.mentionHTML(): String = mention(String::toHtml) fun String.hashTagMarkdown(): String = hashTag(String::toMarkdown) +fun String.hashTagMarkdownV2(): String = hashTag(String::escapeMarkdownV2Common) fun String.hashTagHTML(): String = hashTag(String::toHtml) fun String.phoneMarkdown(): String = toMarkdown() +fun String.phoneMarkdownV2(): String = escapeMarkdownV2Common() fun String.phoneHTML(): String = toHtml() -fun String.command(): String = if (startsWith("/")) { - this +fun String.command(adapt: String.() -> String): String = if (startsWith("/")) { + adapt() } else { - "/$this" + "/${adapt()}" } -fun String.commandMarkdown(): String = command() -fun String.commandHTML(): String = command() +fun String.commandMarkdown(): String = command(String::toMarkdown) +fun String.commandMarkdownV2(): String = command(String::escapeMarkdownV2Common) +fun String.commandHTML(): String = command(String::toHtml) + + +fun String.regularMarkdown(): String = toMarkdown() +fun String.regularMarkdownV2(): String = escapeMarkdownV2Common() +fun String.regularHtml(): String = toHtml() infix fun String.bold(parseMode: ParseMode): String = when (parseMode) { is HTML -> boldHTML() is Markdown -> boldMarkdown() + is MarkdownV2 -> boldMarkdownV2() } infix fun String.italic(parseMode: ParseMode): String = when (parseMode) { is HTML -> italicHTML() is Markdown -> italicMarkdown() + is MarkdownV2 -> italicMarkdownV2() } infix fun String.hashTag(parseMode: ParseMode): String = when (parseMode) { is HTML -> hashTagHTML() is Markdown -> hashTagMarkdown() + is MarkdownV2 -> hashTagMarkdownV2() } infix fun String.code(parseMode: ParseMode): String = when (parseMode) { is HTML -> codeHTML() is Markdown -> codeMarkdown() + is MarkdownV2 -> codeMarkdownV2() } -infix fun String.pre(parseMode: ParseMode): String = when (parseMode) { - is HTML -> preHTML() - is Markdown -> preMarkdown() +fun String.pre(parseMode: ParseMode, language: String? = null): String = when (parseMode) { + is HTML -> preHTML(language) + is Markdown -> preMarkdown(language) + is MarkdownV2 -> preMarkdownV2(language) } +infix fun String.pre(parseMode: ParseMode): String = pre(parseMode, null) infix fun String.email(parseMode: ParseMode): String = when (parseMode) { is HTML -> emailHTML() is Markdown -> emailMarkdown() + is MarkdownV2 -> emailMarkdownV2() } infix fun Pair.link(parseMode: ParseMode): String = when (parseMode) { is HTML -> first.linkHTML(second) is Markdown -> first.linkMarkdown(second) + is MarkdownV2 -> first.linkMarkdownV2(second) } infix fun String.mention(parseMode: ParseMode): String = when (parseMode) { is HTML -> mentionHTML() is Markdown -> mentionMarkdown() + is MarkdownV2 -> mentionMarkdownV2() } infix fun Pair.mention(parseMode: ParseMode): String = when (parseMode) { - is HTML -> first.mentionHTML(second) - is Markdown -> first.mentionMarkdown(second) + is HTML -> first.textMentionHTML(second) + is Markdown -> first.textMentionMarkdown(second) + is MarkdownV2 -> first.textMentionMarkdownV2(second) } infix fun String.phone(parseMode: ParseMode): String = when (parseMode) { is HTML -> phoneHTML() is Markdown -> phoneMarkdown() + is MarkdownV2 -> phoneMarkdownV2() } infix fun String.command(parseMode: ParseMode): String = when (parseMode) { is HTML -> commandHTML() is Markdown -> commandMarkdown() + is MarkdownV2 -> commandMarkdownV2() +} + +infix fun String.underline(parseMode: ParseMode): String = when (parseMode) { + is HTML -> underlineHTML() + is Markdown -> underlineMarkdown() + is MarkdownV2 -> underlineMarkdownV2() +} + +infix fun String.strikethrough(parseMode: ParseMode): String = when (parseMode) { + is HTML -> strikethroughHTML() + is Markdown -> strikethroughMarkdown() + is MarkdownV2 -> strikethroughMarkdownV2() +} + +infix fun String.regular(parseMode: ParseMode): String = when (parseMode) { + is HTML -> regularHtml() + is Markdown -> regularMarkdown() + is MarkdownV2 -> regularMarkdownV2() } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt index 9c2c4d9c33..349d644f83 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt @@ -7,9 +7,42 @@ fun String.toMarkdown(): String { ).replace( "_", "\\_" + ).replace( + "`", + "\\`" + ).replace( + "[", + "\\[" ) } +private val markdownV2LinkEscapes = mutableSetOf(')', '\\') +private val markdownV2PreAndCodeEscapes = mutableSetOf('`', '\\') +private val markdownV2CommonEscapes = mutableSetOf( + '_', + '*', + '[', ']', + '(', ')', + '~', + '`', + '>', + '#', + '+', '-', '=', + '|', + '{', '}', + '.', '!' +) +private fun String.escapeMarkdownV2(escapeCharacters: Iterable): String = map { + if (it in escapeCharacters) { + "\\$it" + } else { + "$it" + } +}.joinToString("") +fun String.escapeMarkdownV2Link() = escapeMarkdownV2(markdownV2LinkEscapes) +fun String.escapeMarkdownV2PreAndCode() = escapeMarkdownV2(markdownV2PreAndCodeEscapes) +fun String.escapeMarkdownV2Common() = escapeMarkdownV2(markdownV2CommonEscapes) + fun String.toHtml(): String = replace( "<", "<" @@ -19,7 +52,4 @@ fun String.toHtml(): String = replace( ).replace( "&", "&" -).replace( - "\"", - """ ) diff --git a/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt new file mode 100644 index 0000000000..7a2024523e --- /dev/null +++ b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt @@ -0,0 +1,142 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity + +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.* +import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2 +import com.github.insanusmokrassar.TelegramBotAPI.utils.* +import kotlin.test.* + +class TextPartsCreatingTests { + @Test + fun testThatTextWithMultilevelPartsCorrectlyCreating() { + val text = "It is simple hello world" + val formattedV2Text = "It *_is_ ~__simple__~* hello world" + val entities = listOf( + RawMessageEntity( + "bold", + 3, + 9 + ), + RawMessageEntity( + "italic", + 3, + 2 + ), + RawMessageEntity( + "strikethrough", + 6, + 6 + ), + RawMessageEntity( + "underline", + 6, + 6 + ) + ) + + val textParts = createTextPart(text, entities) + + + assertTrue ( + textParts.first().source is BoldTextSource + ) + + val boldSource = textParts.first().source as BoldTextSource + assertTrue ( + boldSource.textParts.first().source is ItalicTextSource + ) + assertTrue ( + boldSource.textParts[1].source is RegularTextSource + ) + assertTrue ( + boldSource.textParts[2].source is StrikethroughTextSource + ) + assertTrue ( + (boldSource.textParts[2].source as StrikethroughTextSource).textParts.first().source is UnderlineTextSource + ) + + + val fullTextParts = text.fullListOfSubSource(textParts) + + assertTrue( + fullTextParts.first().source is RegularTextSource + ) + assertTrue( + fullTextParts[1].source is BoldTextSource + ) + assertTrue( + fullTextParts[2].source is RegularTextSource + ) + + assertEquals( + formattedV2Text, + createMarkdownV2Text(fullTextParts.map { it.source }).first() + ) + } + + @Test + fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() { + val text = "It is simple hello world" + val formattedHtmlText = "It is simple hello world" + val entities = listOf( + RawMessageEntity( + "bold", + 3, + 9 + ), + RawMessageEntity( + "italic", + 3, + 2 + ), + RawMessageEntity( + "strikethrough", + 6, + 6 + ), + RawMessageEntity( + "underline", + 6, + 6 + ) + ) + + val textParts = createTextPart(text, entities) + + + assertTrue ( + textParts.first().source is BoldTextSource + ) + + val boldSource = textParts.first().source as BoldTextSource + assertTrue ( + boldSource.textParts.first().source is ItalicTextSource + ) + assertTrue ( + boldSource.textParts[1].source is RegularTextSource + ) + assertTrue ( + boldSource.textParts[2].source is StrikethroughTextSource + ) + assertTrue ( + (boldSource.textParts[2].source as StrikethroughTextSource).textParts.first().source is UnderlineTextSource + ) + + + val fullTextParts = text.fullListOfSubSource(textParts) + + assertTrue( + fullTextParts.first().source is RegularTextSource + ) + assertTrue( + fullTextParts[1].source is BoldTextSource + ) + assertTrue( + fullTextParts[2].source is RegularTextSource + ) + + assertEquals( + formattedHtmlText, + createHtmlText(fullTextParts.map { it.source }).first() + ) + } +} diff --git a/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormattingTests.kt b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormattingTests.kt new file mode 100644 index 0000000000..48a7db2ccf --- /dev/null +++ b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormattingTests.kt @@ -0,0 +1,36 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import kotlin.test.Test +import kotlin.test.assertEquals + +class StringFormattingTests { + @Test + fun testThatPreEscapingWorksCorrectly() { + val originalHelloWorld = """ + fun main() { + println("Hello world") + } + """.replace(" ", "") + val helloWorldLanguage = "kotlin" + assertEquals( + "
$originalHelloWorld
", + originalHelloWorld.preHTML( + helloWorldLanguage + ) + ) + assertEquals( + "
$originalHelloWorld
", + originalHelloWorld.preHTML() + ) + assertEquals( + "```$helloWorldLanguage\n$originalHelloWorld\n```", + originalHelloWorld.preMarkdown( + helloWorldLanguage + ) + ) + assertEquals( + "```\n$originalHelloWorld\n```", + originalHelloWorld.preMarkdown() + ) + } +}