diff --git a/CHANGELOG.md b/CHANGELOG.md index c4735d1aee..f418b93824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Interface `Captioned` and `CaptionedInput` now is deprecated * Most of captions usages were replaced with texts * `textSources` become main field in `TextedInput` + * **MIGRATION** Remove all `import dev.inmo.tgbotapi.CommonAbstracts.textSources` in your project * `textEntities` become are calculable property in `TextedInput` ## 0.33.4 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt index 05e7cd1c63..71c1fa2633 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt @@ -17,15 +17,10 @@ interface EntitiesExplainedOutput : Explained { interface ExplainedOutput : ParsableExplainedOutput, EntitiesExplainedOutput interface ExplainedInput : Explained { + val textSources: TextSourcesList /** * Full list of entities. This list WILL contain [TextPart]s with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] */ val explanationEntities: List + get() = textSources.toTextParts() } - -/** - * @see ExplainedInput.explanationEntities - * @see justTextSources - */ -val ExplainedInput.textSources - get() = explanationEntities.justTextSources() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt index 05590f49b4..6a51ef9cca 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt @@ -2,7 +2,6 @@ package dev.inmo.tgbotapi.CommonAbstracts import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourceSerializer import dev.inmo.tgbotapi.types.MessageEntity.textsources.regular -import dev.inmo.tgbotapi.types.MessageEntity.toTextParts import dev.inmo.tgbotapi.types.captionLength import dev.inmo.tgbotapi.types.textLength import kotlinx.serialization.Serializable @@ -44,14 +43,27 @@ interface MultilevelTextSource : TextSource { } } +@Deprecated("This class will be removed soon. Use TextSources instead") data class TextPart( val range: IntRange, val source: TextSource ) +@Deprecated("This method is no longer required to work with TextSources") fun List.justTextSources() = map { it.source } +internal fun List.toTextParts(preOffset: Int = 0): List { + var i = preOffset + return map { + TextPart( + i until (i + it.source.length), + it + ).also { + i = it.range.last + 1 + } + } +} + fun List.makeString() = joinToString("") { it.source } -internal fun MultilevelTextSource.textParts(offset: Int): List = subsources.toTextParts(offset) fun List.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List> { if (isEmpty()) { return emptyList() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt index 1518631721..b9fedb0403 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt @@ -1,6 +1,5 @@ package dev.inmo.tgbotapi.CommonAbstracts -import dev.inmo.tgbotapi.types.MessageEntity.toTextParts import dev.inmo.tgbotapi.types.ParseMode.ParseMode interface Texted { @@ -20,8 +19,6 @@ interface TextedOutput : ParsableOutput, EntitiesOutput interface TextedInput : Texted { /** * Full list of [TextSource] built from source[TextedInput.textEntities] - * - * @see justTextSources */ val textSources: List /** diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditChatMessageCaption.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditChatMessageCaption.kt index 617970f108..57cbaaa355 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditChatMessageCaption.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditChatMessageCaption.kt @@ -59,7 +59,7 @@ data class EditChatMessageCaption internal constructor( override val replyMarkup: InlineKeyboardMarkup? = null ) : EditChatMessage, EditTextChatMessage, EditReplyMessage { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } override fun method(): String = editMessageCaptionMethod diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditInlineMessageCaption.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditInlineMessageCaption.kt index 20145b3939..80e024b7ce 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditInlineMessageCaption.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/caption/EditInlineMessageCaption.kt @@ -48,7 +48,7 @@ data class EditInlineMessageCaption internal constructor( override val replyMarkup: InlineKeyboardMarkup? = null ) : EditInlineMessage, EditTextChatMessage, EditReplyMessage { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } override fun method(): String = editMessageCaptionMethod diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditChatMessageText.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditChatMessageText.kt index a0f37f90b3..af7e87a389 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditChatMessageText.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditChatMessageText.kt @@ -65,7 +65,7 @@ data class EditChatMessageText internal constructor( override val replyMarkup: InlineKeyboardMarkup? = null ) : EditChatMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } override fun method(): String = editMessageTextMethod diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditInlineMessageText.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditInlineMessageText.kt index 61c89f500d..c457f01e1e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditInlineMessageText.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/text/EditInlineMessageText.kt @@ -54,7 +54,7 @@ data class EditInlineMessageText internal constructor( override val replyMarkup: InlineKeyboardMarkup? = null ) : EditInlineMessage, EditTextChatMessage, EditReplyMessage, EditDisableWebPagePreviewMessage { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } override fun method(): String = editMessageTextMethod diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/CopyMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/CopyMessage.kt index 4ddbf8e68f..4f3c12297d 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/CopyMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/CopyMessage.kt @@ -63,7 +63,7 @@ data class CopyMessage internal constructor( override val chatId: ChatIdentifier get() = fromChatId override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } override fun method(): String = "copyMessage" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendMessage.kt index c36219778c..c36f862686 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/SendMessage.kt @@ -84,7 +84,7 @@ data class SendTextMessage internal constructor( DisableWebPagePreview { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAnimation.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAnimation.kt index 6a26483056..85a1dede9a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAnimation.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAnimation.kt @@ -145,7 +145,7 @@ data class SendAnimationData internal constructor( SizedSendMessageRequest> { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAudio.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAudio.kt index c95d7e7f7c..e5cc73ba5e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAudio.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendAudio.kt @@ -146,7 +146,7 @@ data class SendAudioData internal constructor( Performerable { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendDocument.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendDocument.kt index 8c7d0a9cc2..9e5c8e7add 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendDocument.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendDocument.kt @@ -158,7 +158,7 @@ data class SendDocumentData internal constructor( ThumbedSendMessageRequest> { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPhoto.kt index 66d388ee91..9b03689e8b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPhoto.kt @@ -101,7 +101,7 @@ data class SendPhotoData internal constructor( TextableSendMessageRequest> { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVideo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVideo.kt index e50686c5dc..cc850aecc3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVideo.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVideo.kt @@ -151,7 +151,7 @@ data class SendVideoData internal constructor( SizedSendMessageRequest> { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVoice.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVoice.kt index 79b17c98e4..b6a37c7428 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVoice.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendVoice.kt @@ -121,7 +121,7 @@ data class SendVoiceData internal constructor( DuratedSendMessageRequest> { override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/polls/SendPoll.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/polls/SendPoll.kt index 2af52017ef..ffe2a64c0c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/polls/SendPoll.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/polls/SendPoll.kt @@ -360,7 +360,7 @@ data class SendQuizPoll internal constructor( override val requestSerializer: SerializationStrategy<*> get() = serializer() override val entities: List? by lazy { - rawEntities ?.asTextParts(explanation ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(explanation ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioCachedImpl.kt index 30f23487c8..2f556ff5cb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioCachedImpl.kt @@ -49,6 +49,6 @@ data class InlineQueryResultAudioCachedImpl internal constructor( ) : InlineQueryResultAudioCached { override val type: String = inlineQueryResultAudioType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioImpl.kt index f4221fae20..6bc56236b1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultAudioImpl.kt @@ -60,6 +60,6 @@ data class InlineQueryResultAudioImpl internal constructor( ) : InlineQueryResultAudio { override val type: String = inlineQueryResultAudioType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentCachedImpl.kt index 2b7bd33291..a15c0fd0a1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentCachedImpl.kt @@ -57,6 +57,6 @@ data class InlineQueryResultDocumentCachedImpl internal constructor( ) : InlineQueryResultDocumentCached { override val type: String = inlineQueryResultDocumentType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentImpl.kt index bca7294ef3..b9e95a488a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultDocumentImpl.kt @@ -74,6 +74,6 @@ data class InlineQueryResultDocumentImpl internal constructor( ) : InlineQueryResultDocument { override val type: String = inlineQueryResultDocumentType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifCachedImpl.kt index a65dd530ac..d12fdb5324 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifCachedImpl.kt @@ -53,6 +53,6 @@ data class InlineQueryResultGifCachedImpl internal constructor( ) : InlineQueryResultGifCached { override val type: String = inlineQueryResultGifType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifImpl.kt index d282045d62..b5417b68d0 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultGifImpl.kt @@ -73,7 +73,7 @@ data class InlineQueryResultGifImpl internal constructor( ) : InlineQueryResultGif { override val type: String = inlineQueryResultGifType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifCachedImpl.kt index d7726fa700..b4aa1a0ce9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifCachedImpl.kt @@ -53,6 +53,6 @@ data class InlineQueryResultMpeg4GifCachedImpl internal constructor( ) : InlineQueryResultMpeg4GifCached { override val type: String = inlineQueryResultMpeg4GifType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifImpl.kt index 9b07306447..272457cfc3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultMpeg4GifImpl.kt @@ -73,7 +73,7 @@ data class InlineQueryResultMpeg4GifImpl internal constructor( ) : InlineQueryResultMpeg4Gif { override val type: String = inlineQueryResultMpeg4GifType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } init { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoCachedImpl.kt index 942fb9039a..3949c0930a 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoCachedImpl.kt @@ -57,6 +57,6 @@ data class InlineQueryResultPhotoCachedImpl internal constructor( ) : InlineQueryResultPhotoCached { override val type: String = inlineQueryResultPhotoType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoImpl.kt index 332a2ce09c..6162842ac7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultPhotoImpl.kt @@ -68,6 +68,6 @@ data class InlineQueryResultPhotoImpl internal constructor( ) : InlineQueryResultPhoto { override val type: String = inlineQueryResultPhotoType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoCachedImpl.kt index 8fe16705c5..410ecbe845 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoCachedImpl.kt @@ -57,6 +57,6 @@ data class InlineQueryResultVideoCachedImpl internal constructor( ) : InlineQueryResultVideoCached { override val type: String = inlineQueryResultVideoType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoImpl.kt index e055c7f468..3c46f5a1e4 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVideoImpl.kt @@ -78,6 +78,6 @@ data class InlineQueryResultVideoImpl internal constructor( ) : InlineQueryResultVideo { override val type: String = inlineQueryResultVideoType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceCachedImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceCachedImpl.kt index e5e236120d..af0738d385 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceCachedImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceCachedImpl.kt @@ -53,6 +53,6 @@ data class InlineQueryResultVoiceCachedImpl internal constructor( ) : InlineQueryResultVoiceCached { override val type: String = inlineQueryResultVoiceType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceImpl.kt index 02c4189ed8..f3a375978b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InlineQueryResult/InlineQueryResultVoiceImpl.kt @@ -66,6 +66,6 @@ data class InlineQueryResultVoiceImpl internal constructor( ) : InlineQueryResultVoice { override val type: String = inlineQueryResultVoiceType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt index 5871b5a144..898cb84c77 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt @@ -39,6 +39,6 @@ data class InputTextMessageContent internal constructor( override val disableWebPagePreview: Boolean? = null ) : TextedOutput, DisableWebPagePreview, InputMessageContent { override val entities: List? by lazy { - rawEntities ?.asTextParts(text) ?.justTextSources() + rawEntities ?.asTextSources(text) } } \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAnimation.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAnimation.kt index 77eaec8b68..ea11be80bf 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAnimation.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAnimation.kt @@ -45,7 +45,7 @@ data class InputMediaAnimation internal constructor( ) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, TextedOutput { override val type: String = "animation" override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } @SerialName(mediaField) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAudio.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAudio.kt index 598e0ddc4a..0e78d9d244 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAudio.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaAudio.kt @@ -51,7 +51,7 @@ data class InputMediaAudio internal constructor( ) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, Performerable { override val type: String = audioInputMediaType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaDocument.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaDocument.kt index 6772614459..51457d81ed 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaDocument.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaDocument.kt @@ -51,7 +51,7 @@ data class InputMediaDocument internal constructor( ) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia { override val type: String = documentInputMediaType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt index b3d56b4574..1f0d0ca6f2 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaPhoto.kt @@ -35,7 +35,7 @@ data class InputMediaPhoto internal constructor( ) : InputMedia, VisualMediaGroupMemberInputMedia { override val type: String = photoInputMediaType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt index f7907dd023..eece259c8f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/InputMedia/InputMediaVideo.kt @@ -46,7 +46,7 @@ data class InputMediaVideo internal constructor ( ) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia { override val type: String = videoInputMediaType override val entities: List? by lazy { - rawEntities ?.asTextParts(text ?: return@lazy null) ?.justTextSources() + rawEntities ?.asTextSources(text ?: return@lazy null) } override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt index d8bff5f11d..b0965a4543 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt @@ -3,8 +3,6 @@ package dev.inmo.tgbotapi.types.MessageEntity import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import dev.inmo.tgbotapi.types.User -import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource -import dev.inmo.tgbotapi.utils.internal.shiftSourcesToTheLeft import kotlinx.serialization.Serializable @Serializable @@ -15,70 +13,115 @@ internal data class RawMessageEntity( val url: String? = null, val user: User? = null, val language: String? = null -) - -internal fun RawMessageEntity.asTextParts( - source: String, - subParts: List -): List { - val sourceSubstring: String = source.substring(offset, offset + length) - val range = offset until (offset + length) - val shiftedSubSources = sourceSubstring.fullListOfSubSource(subParts.shiftSourcesToTheLeft(offset)).justTextSources() - return when (type) { - "mention" -> MentionTextSource(sourceSubstring, shiftedSubSources) - "hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubSources) - "cashtag" -> CashTagTextSource(sourceSubstring, shiftedSubSources) - "bot_command" -> BotCommandTextSource(sourceSubstring) - "url" -> URLTextSource(sourceSubstring) - "email" -> EMailTextSource(sourceSubstring, shiftedSubSources) - "phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubSources) - "bold" -> BoldTextSource(sourceSubstring, shiftedSubSources) - "italic" -> ItalicTextSource(sourceSubstring, shiftedSubSources) - "code" -> CodeTextSource(sourceSubstring) - "pre" -> PreTextSource(sourceSubstring, language) - "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"), shiftedSubSources) - "underline" -> UnderlineTextSource(sourceSubstring, shiftedSubSources) - "strikethrough" -> StrikethroughTextSource(sourceSubstring, shiftedSubSources) - 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 val range by lazy { + offset until (offset + length) } } -internal fun createTextPart(originalFullString: String, entities: RawMessageEntities): List { - val mutableEntities = entities.toMutableList() - mutableEntities.sortBy { it.offset } - val resultList = mutableListOf() +internal fun RawMessageEntity.asTextSource( + source: String, + subParts: List +): TextSource { + val sourceSubstring: String = source.substring(range) + val subPartsWithRegulars by lazy { + subParts.fillWithRegulars(sourceSubstring) + } + return when (type) { + "mention" -> MentionTextSource(sourceSubstring, subPartsWithRegulars) + "hashtag" -> HashTagTextSource(sourceSubstring, subPartsWithRegulars) + "cashtag" -> CashTagTextSource(sourceSubstring, subPartsWithRegulars) + "bot_command" -> BotCommandTextSource(sourceSubstring) + "url" -> URLTextSource(sourceSubstring) + "email" -> EMailTextSource(sourceSubstring, subPartsWithRegulars) + "phone_number" -> PhoneNumberTextSource(sourceSubstring, subPartsWithRegulars) + "bold" -> BoldTextSource(sourceSubstring, subPartsWithRegulars) + "italic" -> ItalicTextSource(sourceSubstring, subPartsWithRegulars) + "code" -> CodeTextSource(sourceSubstring) + "pre" -> PreTextSource(sourceSubstring, language) + "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"), subPartsWithRegulars) + "underline" -> UnderlineTextSource(sourceSubstring, subPartsWithRegulars) + "strikethrough" -> StrikethroughTextSource(sourceSubstring, subPartsWithRegulars) + else -> RegularTextSource(sourceSubstring) + } +} + +private inline operator fun > ClosedRange.contains(other: ClosedRange): Boolean { + return start <= other.start && endInclusive >= other.endInclusive +} + +internal fun List.fillWithRegulars(source: String): List { + var index = 0 + val result = mutableListOf() + for (i in 0 until size) { + val textSource = get(i) + val thisSourceInStart = source.startsWith(textSource.source, index) + if (!thisSourceInStart) { + val regularEndIndex = source.indexOf(textSource.source) + result.add(regular(source.substring(index, regularEndIndex))) + index = regularEndIndex + } + result.add(textSource) + index += textSource.source.length + } + + if (index != source.length) { + result.add(regular(source.substring(index, source.length))) + } + + return result +} + +private fun createTextSources(originalFullString: String, entities: RawMessageEntities): List { + val mutableEntities = entities.toMutableList().apply { sortBy { it.offset } } + val resultList = mutableListOf() 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 + var parent = mutableEntities.removeFirst() + val subentities = mutableListOf() + val toAddCutted = mutableListOf() + while (mutableEntities.isNotEmpty()) { + val potentialParent = mutableEntities.first() + when { + potentialParent.range.first > parent.range.last -> break + potentialParent.range in parent.range -> { + subentities.add(potentialParent) + } + potentialParent.offset == parent.offset && potentialParent.length > parent.length -> { + subentities.add(parent) + parent = potentialParent + } + else -> { // need to cut + toAddCutted.add(potentialParent) } } - subEntities - } else { - emptyList() + mutableEntities.remove(potentialParent) } - - resultList.addAll( - currentFirst.asTextParts( + val subtextSources = if (subentities.isNotEmpty()) { + mutableEntities.removeAll(subentities) + if (toAddCutted.isNotEmpty()) { + val borderIndex = parent.range.last + 1 + mutableEntities.addAll( + 0, + toAddCutted.map { + val firstLength = borderIndex - it.offset + subentities.add(it.copy(length = firstLength)) + it.copy( + offset = borderIndex, + length = it.length - firstLength + ) + } + ) + } + createTextSources(originalFullString, subentities) + } else { + emptyList() + } + resultList.add( + parent.asTextSource( originalFullString, - createTextPart(originalFullString, subEntities) + subtextSources ) ) } @@ -86,46 +129,41 @@ internal fun createTextPart(originalFullString: String, entities: RawMessageEnti return resultList } -internal fun TextPart.asRawMessageEntities(): List { +internal fun TextSource.toRawMessageEntities(offset: Int = 0): List { val source = source - val length = range.last - range.first + 1 - + val length = source.length return listOfNotNull( - when (source) { - is MentionTextSource -> RawMessageEntity("mention", range.first, length) - is HashTagTextSource -> RawMessageEntity("hashtag", range.first, length) - is CashTagTextSource -> RawMessageEntity("cashtag", range.first, length) - is BotCommandTextSource -> RawMessageEntity("bot_command", range.first, length) - is URLTextSource -> RawMessageEntity("url", range.first, length) - is EMailTextSource -> RawMessageEntity("email", range.first, length) - is PhoneNumberTextSource -> RawMessageEntity("phone_number", range.first, length) - is BoldTextSource -> RawMessageEntity("bold", range.first, length) - is ItalicTextSource -> RawMessageEntity("italic", range.first, length) - is CodeTextSource -> RawMessageEntity("code", range.first, length) - is PreTextSource -> RawMessageEntity("pre", range.first, length, language = source.language) - is TextLinkTextSource -> RawMessageEntity("text_link", range.first, length, source.url) - is TextMentionTextSource -> RawMessageEntity("text_mention", range.first, length, user = source.user) - is UnderlineTextSource -> RawMessageEntity("underline", range.first, length) - is StrikethroughTextSource -> RawMessageEntity("strikethrough", range.first, length) + when (this) { + is MentionTextSource -> RawMessageEntity("mention", offset, length) + is HashTagTextSource -> RawMessageEntity("hashtag", offset, length) + is CashTagTextSource -> RawMessageEntity("cashtag", offset, length) + is BotCommandTextSource -> RawMessageEntity("bot_command", offset, length) + is URLTextSource -> RawMessageEntity("url", offset, length) + is EMailTextSource -> RawMessageEntity("email", offset, length) + is PhoneNumberTextSource -> RawMessageEntity("phone_number", offset, length) + is BoldTextSource -> RawMessageEntity("bold", offset, length) + is ItalicTextSource -> RawMessageEntity("italic", offset, length) + is CodeTextSource -> RawMessageEntity("code", offset, length) + is PreTextSource -> RawMessageEntity("pre", offset, length, language = language) + is TextLinkTextSource -> RawMessageEntity("text_link", offset, length, url) + is TextMentionTextSource -> RawMessageEntity("text_mention", offset, length, user = user) + is UnderlineTextSource -> RawMessageEntity("underline", offset, length) + is StrikethroughTextSource -> RawMessageEntity("strikethrough", offset, length) else -> null } - ) + if (source is MultilevelTextSource) { - source.textParts(range.first).asRawMessageEntities() + ) + if (this is MultilevelTextSource) { + subsources.toRawMessageEntities(offset) } else { emptyList() } } -internal fun List.asRawMessageEntities(): List = flatMap { it.asRawMessageEntities() } -internal fun List.toTextParts(preOffset: Int = 0): List { +internal fun List.toRawMessageEntities(preOffset: Int = 0): List { var i = preOffset - return map { - TextPart( - i until (i + it.source.length), - it - ).also { - i = it.range.last + 1 + return flatMap { + it.toRawMessageEntities(i).also { + i += it.maxByOrNull { it.length }!!.length + 1 } } } @@ -136,10 +174,8 @@ fun String.removeLeading(word: String) = if (startsWith(word)){ this } -internal fun List.toRawMessageEntities(): List = toTextParts().asRawMessageEntities() +internal fun List.toRawMessageEntities(): List = toRawMessageEntities(0) -internal fun RawMessageEntities.asTextParts(sourceString: String): List = sourceString.fullListOfSubSource( - createTextPart(sourceString, this) -) +internal fun RawMessageEntities.asTextSources(sourceString: String): List = createTextSources(sourceString, this).fillWithRegulars(sourceString) internal typealias RawMessageEntities = List diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourceSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourceSerializer.kt index a9f76a93ad..8ca19d3419 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourceSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourceSerializer.kt @@ -2,14 +2,7 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.micro_utils.serialization.typed_serializer.TypedSerializer import dev.inmo.tgbotapi.CommonAbstracts.TextSource -import dev.inmo.tgbotapi.CommonAbstracts.justTextSources -import dev.inmo.tgbotapi.types.MessageEntity.* -import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities -import dev.inmo.tgbotapi.utils.RiskFeature import kotlinx.serialization.* -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.descriptors.* -import kotlinx.serialization.encoding.* private val baseSerializers: Map> = mapOf( "regular" to RegularTextSource.serializer(), diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/RawGame.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/RawGame.kt index cf2225cd3a..db398702e3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/RawGame.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/games/RawGame.kt @@ -1,9 +1,8 @@ package dev.inmo.tgbotapi.types.games -import dev.inmo.tgbotapi.CommonAbstracts.justTextSources import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities -import dev.inmo.tgbotapi.types.MessageEntity.asTextParts +import dev.inmo.tgbotapi.types.MessageEntity.asTextSources import dev.inmo.tgbotapi.types.files.* import kotlinx.serialization.* @@ -29,7 +28,7 @@ internal data class RawGame( description, photo, text, - text ?.let { _ -> textEntities.asTextParts(text).justTextSources() } ?: emptyList(), + text ?.let { _ -> textEntities.asTextSources(text) } ?: emptyList(), animation ) } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt index 4c93700cd7..086b33b792 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt @@ -1,9 +1,8 @@ package dev.inmo.tgbotapi.types.message -import dev.inmo.tgbotapi.CommonAbstracts.justTextSources import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.MessageEntity.RawMessageEntities -import dev.inmo.tgbotapi.types.MessageEntity.asTextParts +import dev.inmo.tgbotapi.types.MessageEntity.asTextSources import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.chat.abstracts.* import dev.inmo.tgbotapi.types.dice.Dice @@ -103,11 +102,11 @@ internal data class RawMessage( ) { private val content: MessageContent? by lazy { val adaptedCaptionEntities = caption ?.let { - (caption_entities ?: emptyList()).asTextParts(caption).justTextSources() + (caption_entities ?: emptyList()).asTextSources(caption) } ?: emptyList() when { - text != null -> TextContent(text, (entities ?: emptyList()).asTextParts(text).justTextSources()) + text != null -> TextContent(text, (entities ?: emptyList()).asTextSources(text)) audio != null -> AudioContent( audio, caption, diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt index 8ca845fcd0..a26300419f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/polls/Poll.kt @@ -2,8 +2,7 @@ package dev.inmo.tgbotapi.types.polls import com.soywiz.klock.DateTime import com.soywiz.klock.TimeSpan -import dev.inmo.tgbotapi.CommonAbstracts.ExplainedInput -import dev.inmo.tgbotapi.CommonAbstracts.TextPart +import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.MessageEntity.* import dev.inmo.tgbotapi.utils.nonstrictJsonFormat @@ -136,7 +135,7 @@ data class QuizPoll( */ val correctOptionId: Int? = null, override val explanation: String? = null, - override val explanationEntities: List = emptyList(), + override val textSources: List = emptyList(), override val isClosed: Boolean = false, override val isAnonymous: Boolean = false, override val scheduledCloseInfo: ScheduledCloseInfo? = null @@ -159,7 +158,7 @@ internal object PollSerializer : KSerializer { rawPoll.votesCount, rawPoll.correctOptionId, rawPoll.explanation, - rawPoll.explanation?.let { rawPoll.explanationEntities.asTextParts(it) } ?: emptyList(), + rawPoll.explanation?.let { rawPoll.explanationEntities.asTextSources(it) } ?: emptyList(), rawPoll.isClosed, rawPoll.isAnonymous, rawPoll.scheduledCloseInfo @@ -211,7 +210,7 @@ internal object PollSerializer : KSerializer { regularPollType, correctOptionId = value.correctOptionId, explanation = value.explanation, - explanationEntities = value.explanationEntities.asRawMessageEntities(), + explanationEntities = value.textSources.toRawMessageEntities(), openPeriod = (closeInfo as? ApproximateScheduledCloseInfo) ?.openDuration ?.seconds ?.toLong(), closeDate = (closeInfo as? ExactScheduledCloseInfo) ?.closeDateTime ?.unixMillisLong ?.div(1000L) ) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/internal/MultilevelTextSourceFormatting.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/internal/MultilevelTextSourceFormatting.kt index bac1e06c41..b36cc15ec2 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/internal/MultilevelTextSourceFormatting.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/internal/MultilevelTextSourceFormatting.kt @@ -1,77 +1,12 @@ package dev.inmo.tgbotapi.utils.internal import dev.inmo.tgbotapi.CommonAbstracts.* -import dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource +import dev.inmo.tgbotapi.types.MessageEntity.textsources.regular import dev.inmo.tgbotapi.types.UserId import dev.inmo.tgbotapi.types.link import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Link import dev.inmo.tgbotapi.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.markdownV2 } diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt index b75814dcf1..08092c0350 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt @@ -1,6 +1,6 @@ package dev.inmo.tgbotapi.types.MessageEntity -import dev.inmo.tgbotapi.CommonAbstracts.TextPart +import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import kotlin.test.assertTrue @@ -36,19 +36,19 @@ internal val testTextEntities = listOf( RawMessageEntity( "mention", 39, - 6 + 8 ) ) -fun List.testTextParts() { - assertTrue (first().source is RegularTextSource) - assertTrue (get(1).source is BoldTextSource) - assertTrue (get(2).source is RegularTextSource) - assertTrue (get(3).source is HashTagTextSource) - assertTrue (get(4).source is RegularTextSource) - assertTrue (get(5).source is MentionTextSource) +fun List.testTextSources() { + assertTrue (first() is RegularTextSource) + assertTrue (get(1) is BoldTextSource) + assertTrue (get(2) is RegularTextSource) + assertTrue (get(3) is HashTagTextSource) + assertTrue (get(4) is RegularTextSource) + assertTrue (get(5) is MentionTextSource) - val boldSource = get(1).source as BoldTextSource + val boldSource = get(1) as BoldTextSource assertTrue (boldSource.subsources.first() is ItalicTextSource) assertTrue (boldSource.subsources[1] is RegularTextSource) assertTrue (boldSource.subsources[2] is StrikethroughTextSource) diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt index 1ba73f4c7f..f7b15a854a 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt @@ -48,7 +48,7 @@ class StringFormattingTests { hashtag("tag") + " and " + mention("mention") - sources.toTextParts().testTextParts() + sources.testTextSources() assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first()) assertEquals(formattedHtmlText, sources.toHtmlTexts().first()) diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt index 14e0a82f2e..a4e3900028 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt @@ -1,6 +1,5 @@ package dev.inmo.tgbotapi.types.MessageEntity -import dev.inmo.tgbotapi.CommonAbstracts.justTextSources import dev.inmo.tgbotapi.extensions.utils.formatting.toHtmlTexts import dev.inmo.tgbotapi.extensions.utils.formatting.toMarkdownV2Texts import kotlin.test.Test @@ -9,23 +8,23 @@ import kotlin.test.assertEquals class TextPartsCreatingTests { @Test fun testThatTextWithMultilevelPartsCorrectlyCreating() { - val textParts = testTextEntities.asTextParts(testText) - textParts.testTextParts() + val textSources = testTextEntities.asTextSources(testText) + textSources.testTextSources() assertEquals( formattedV2Text, - textParts.justTextSources().toMarkdownV2Texts().first() + textSources.toMarkdownV2Texts().first() ) } @Test fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() { - val textParts = testTextEntities.asTextParts(testText) - textParts.testTextParts() + val textSources = testTextEntities.asTextSources(testText) + textSources.testTextSources() assertEquals( formattedHtmlText, - textParts.justTextSources().toHtmlTexts().first() + textSources.toHtmlTexts().first() ) } } diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt index 0946a99140..4b77abaf69 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt @@ -1,6 +1,5 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling -import dev.inmo.tgbotapi.CommonAbstracts.textSources import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/CommandsShortcuts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/CommandsShortcuts.kt index 6df7887dea..749ae68aef 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/CommandsShortcuts.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/CommandsShortcuts.kt @@ -1,7 +1,6 @@ package dev.inmo.tgbotapi.extensions.utils.shortcuts import dev.inmo.tgbotapi.CommonAbstracts.TextSource -import dev.inmo.tgbotapi.CommonAbstracts.textSources import dev.inmo.tgbotapi.extensions.utils.onlyTextContentMessages import dev.inmo.tgbotapi.extensions.utils.updates.asContentMessagesFlow import dev.inmo.tgbotapi.types.MessageEntity.textsources.BotCommandTextSource