diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e3c688fcd..10033cfe9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # TelegramBotAPI changelog +## 7.0.1 + +* `Core`: + * New interface `WithChat` which contains `chat` field + * `Message` now inherits `WithChat` + * `ChatMemberUpdated` now inherits `WithChat` +* `Utils`: + * Improvements in `same`-notations + ## 7.0.0 This update contains support of [Telegram Bot API 6.6](https://core.telegram.org/bots/api-changelog#march-9-2023) diff --git a/gradle.properties b/gradle.properties index 6932fd1002..7397299ac5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.incremental=true kotlin.incremental.js=true library_group=dev.inmo -library_version=7.0.0 +library_version=7.0.1 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt new file mode 100644 index 0000000000..1cdba4b9f3 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/abstracts/WithChat.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.abstracts + +import dev.inmo.tgbotapi.types.chat.Chat + +/** + * All inheritors of this interface have [chat] field and related to this [chat] + */ +interface WithChat { + val chat: Chat +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/member/ChatMemberUpdated.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/member/ChatMemberUpdated.kt index 59646cc3df..81f4ac184b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/member/ChatMemberUpdated.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/member/ChatMemberUpdated.kt @@ -1,5 +1,7 @@ package dev.inmo.tgbotapi.types.chat.member +import dev.inmo.tgbotapi.abstracts.WithChat +import dev.inmo.tgbotapi.abstracts.WithUser import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.User @@ -9,9 +11,9 @@ import kotlinx.serialization.Serializable @Serializable data class ChatMemberUpdated( @SerialName(chatField) - val chat: Chat, + override val chat: Chat, @SerialName(fromField) - val user: User, + override val user: User, @SerialName(dateField) val date: TelegramDate, @SerialName(oldChatMemberField) @@ -20,4 +22,4 @@ data class ChatMemberUpdated( val newChatMemberState: ChatMember, @SerialName(inviteLinkField) val inviteLink: ChatInviteLink? = null -) +) : WithChat, WithUser diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt index e9593c2da4..49f9eda9b9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/Message.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.types.message.abstracts import com.soywiz.klock.DateTime +import dev.inmo.tgbotapi.abstracts.WithChat import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.chat.Chat @@ -11,9 +12,8 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder @ClassCastsIncluded -interface Message { +interface Message : WithChat { val messageId: MessageId - val chat: Chat val date: DateTime } diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt new file mode 100644 index 0000000000..a45ecd1cb5 --- /dev/null +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/FlowsSame.kt @@ -0,0 +1,37 @@ +package dev.inmo.tgbotapi.extensions.utils.extensions + +import dev.inmo.tgbotapi.abstracts.FromUser +import dev.inmo.tgbotapi.abstracts.WithChat +import dev.inmo.tgbotapi.types.ChatIdentifier +import dev.inmo.tgbotapi.types.UserId +import dev.inmo.tgbotapi.types.chat.Chat +import dev.inmo.tgbotapi.types.chat.User +import dev.inmo.tgbotapi.types.message.abstracts.Message +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.transform + +/** + * Will pass only those [T] which have [sameChat] as [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromChat(chatId: ChatIdentifier): Flow = filter { it.sameChat(chatId) } + +/** + * Will pass only those [T] which have [sameChat] as [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromChat(chat: Chat): Flow = fromChat(chat.id) + +/** + * @return [Flow] with the [FromUser.user] field [User.id] the same as [userId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromUser(userId: UserId): Flow = filter { it.user.id == userId } + +/** + * @return [Flow] with the [FromUser.user] field [User.id] the same as [user] [User.id] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Flow.fromUser(user: User): Flow = fromUser(user.id) + diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt index 20ede5d212..8ef2b69166 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/extensions/Same.kt @@ -1,20 +1,120 @@ package dev.inmo.tgbotapi.extensions.utils.extensions +import dev.inmo.tgbotapi.abstracts.WithChat +import dev.inmo.tgbotapi.extensions.utils.usernameChatOrNull +import dev.inmo.tgbotapi.extensions.utils.whenUsernameChat +import dev.inmo.tgbotapi.types.ChatIdentifier +import dev.inmo.tgbotapi.types.MessageId +import dev.inmo.tgbotapi.types.MessageThreadId +import dev.inmo.tgbotapi.types.Username +import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.message.abstracts.Message +import dev.inmo.tgbotapi.types.threadId import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull +/** + * @return true in case if [this] message is placed in the chat with id == [chatId] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun WithChat.sameChat(chatId: ChatIdentifier) = chat.id == chatId || (chatId is Username && chat.whenUsernameChat { + it.username == chatId +} ?: false) + +/** + * @return true in case if [this] message is placed in the [chat] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun WithChat.sameChat(chat: Chat) = sameChat(chat.id) || chat.usernameChatOrNull() ?.username ?.let { sameChat(it) } ?: false + /** * @return true in case if [this] message is placed in the same chat that [other] */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameChat(other: Message) = chat.id == other.chat.id +inline fun WithChat.sameChat(other: Message) = sameChat(other.chat) + +/** + * @return true in case if [this] message is from the same chat (with id == [chatId]) and [this] [Message.messageId] + * equal [messageId] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameMessage( + chatId: ChatIdentifier, + messageId: MessageId +) = sameChat(chatId) && this.messageId == messageId + +/** + * @return true in case if [this] message is from the same [chat] and [this] [Message.messageId] equal [messageId] + * identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameMessage( + chat: Chat, + messageId: MessageId +) = sameChat(chat) && this.messageId == messageId /** * @return true in case if [this] message is the same as [other]. The same here means that these messages from one chat * and have equal [Message.messageId] identifier */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameMessage(other: Message) = sameChat(other) && messageId == other.messageId +inline fun Message.sameMessage(other: Message) = sameMessage(other.chat, other.messageId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is in the chat [chatId] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic( + chatId: ChatIdentifier, + threadId: MessageThreadId? = chatId.threadId +) = sameChat(chatId) && threadIdOrNull == threadId + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is in the chat [chatId] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameThread( + chatId: ChatIdentifier, + threadId: MessageThreadId? = chatId.threadId +) = sameTopic(chatId, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the [chat] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic( + chat: Chat, + threadId: MessageThreadId? = chat.id.threadId +) = sameTopic(chat.id, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the [chat] and topic [threadId]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameThread( + chat: Chat, + threadId: MessageThreadId? = chat.id.threadId +) = sameThread(chat.id, threadId) + +/** + * Thread is the same thing that topic + * + * @return true in case if [this] message is from the same chat and topic as [other]. The same here means that these + * messages from one chat and have equal [Message.threadIdOrNull] identifier + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Message.sameTopic(other: Message) = sameTopic(other.chat, other.threadIdOrNull) /** * Thread is the same thing that topic @@ -23,13 +123,4 @@ inline fun Message.sameMessage(other: Message) = sameChat(other) && messageId == * from one chat and have equal [Message.threadIdOrNull] identifier */ @Suppress("NOTHING_TO_INLINE") -inline fun Message.sameTopic(other: Message) = sameChat(other) && threadIdOrNull == other.threadIdOrNull - -/** - * Thread is the same thing that topic - * - * @return true in case if [this] message is in the same topic as the [other]. The same here means that these messages - * from one chat and have equal [Message.threadIdOrNull] identifier - */ -@Suppress("NOTHING_TO_INLINE") -inline fun Message.sameThread(other: Message) = sameChat(other) && threadIdOrNull == other.threadIdOrNull +inline fun Message.sameThread(other: Message) = sameTopic(other)