From 8c77dd961d8cd9b3070562a9f5db63f5b4a2ea45 Mon Sep 17 00:00:00 2001 From: Luis Date: Tue, 11 Apr 2023 21:49:32 -0300 Subject: [PATCH 01/33] Replace Icon with Asset (#703) This introduces the new dev.kord.core.entity.Asset class that is a replacement for dev.kord.core.entity.Icon with coverage of more CDN endpoints and fewer inconsistencies (e.g. format was not considered when calling Icon.getImage() with no parameters). Properties with type Icon are now also deprecated and are replaced with similar properties with type Asset. This means there are a few source- (but not binary-) incompatible changes: * The types of dev.kord.core.entity.GuildEmoji.image, dev.kord.core.entity.Member.memberAvatar, dev.kord.core.entity.Role.icon, dev.kord.core.entity.User.avatar and dev.kord.core.entity.User.defaultAvatar were changed from Icon to Asset. * The type of dev.kord.core.entity.Team.icon was changed from String to Asset. Team.iconHash provides the previous functionality. --------- Co-authored-by: Lukellmann --- core/api/core.api | 69 ++++++++++-- .../commonMain/kotlin/entity/Application.kt | 4 + core/src/commonMain/kotlin/entity/Asset.kt | 100 ++++++++++++++++++ core/src/commonMain/kotlin/entity/Emoji.kt | 7 +- core/src/commonMain/kotlin/entity/Guild.kt | 25 +++++ .../kotlin/entity/GuildScheduledEvent.kt | 2 + core/src/commonMain/kotlin/entity/Icon.kt | 6 ++ core/src/commonMain/kotlin/entity/Member.kt | 11 +- .../commonMain/kotlin/entity/PartialGuild.kt | 25 +++++ core/src/commonMain/kotlin/entity/Role.kt | 8 +- core/src/commonMain/kotlin/entity/Sticker.kt | 8 +- core/src/commonMain/kotlin/entity/Team.kt | 8 +- core/src/commonMain/kotlin/entity/User.kt | 22 +++- rest/api/rest.api | 18 ++++ rest/src/commonMain/kotlin/Image.kt | 3 + rest/src/commonMain/kotlin/route/CdnUrl.kt | 6 +- .../src/commonMain/kotlin/route/DiscordCdn.kt | 31 ++++++ 17 files changed, 335 insertions(+), 18 deletions(-) create mode 100644 core/src/commonMain/kotlin/entity/Asset.kt diff --git a/core/api/core.api b/core/api/core.api index 3c38ed0f8ef4..c8c9c6ec08ed 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -5771,6 +5771,36 @@ public final class dev/kord/core/entity/Application : dev/kord/core/entity/BaseA public synthetic fun withStrategy (Ldev/kord/core/supplier/EntitySupplyStrategy;)Ldev/kord/core/entity/Strategizable; } +public final class dev/kord/core/entity/Asset : dev/kord/core/KordObject { + public static final field Companion Ldev/kord/core/entity/Asset$Companion; + public synthetic fun (ZLdev/kord/rest/route/CdnUrl;Ldev/kord/core/Kord;Ldev/kord/rest/Image$Format;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getCdnUrl ()Ldev/kord/rest/route/CdnUrl; + public final fun getImage (Ldev/kord/rest/Image$Format;Ldev/kord/rest/Image$Size;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun getImage$default (Ldev/kord/core/entity/Asset;Ldev/kord/rest/Image$Format;Ldev/kord/rest/Image$Size;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public fun getKord ()Ldev/kord/core/Kord; + public final fun isAnimated ()Z +} + +public final class dev/kord/core/entity/Asset$Companion { + public final fun applicationCover (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun applicationIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun defaultUserAvatar (ILdev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun emoji (Ldev/kord/common/entity/Snowflake;ZLdev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun guildBanner (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun guildDiscoverySplash (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun guildIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun guildScheduledEventCover (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun guildSplash (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun memberAvatar (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun memberBanner (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun roleIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun sticker (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/MessageStickerType;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun stickerPackBanner (Ldev/kord/common/entity/Snowflake;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun teamIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun userAvatar (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; + public final fun userBanner (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/Kord;)Ldev/kord/core/entity/Asset; +} + public final class dev/kord/core/entity/Attachment : dev/kord/core/entity/KordEntity { public fun (Ldev/kord/core/cache/data/AttachmentData;Ldev/kord/core/Kord;)V public fun compareTo (Ldev/kord/core/entity/Entity;)I @@ -5852,6 +5882,7 @@ public abstract class dev/kord/core/entity/BaseApplication : dev/kord/core/entit public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I public final fun equals (Ljava/lang/Object;)Z + public final fun getCoverImage ()Ldev/kord/core/entity/Asset; public final fun getCoverImageHash ()Ljava/lang/String; public final fun getCustomInstallUrl ()Ljava/lang/String; public abstract fun getData ()Ldev/kord/core/cache/data/BaseApplicationData; @@ -5860,6 +5891,7 @@ public abstract class dev/kord/core/entity/BaseApplication : dev/kord/core/entit public final fun getGuild ()Ldev/kord/core/behavior/GuildBehavior; public final fun getGuildId ()Ldev/kord/common/entity/Snowflake; public final fun getGuildOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getIcon ()Ldev/kord/core/entity/Asset; public final fun getIconHash ()Ljava/lang/String; public final fun getId ()Ldev/kord/common/entity/Snowflake; public final fun getInstallParams ()Ldev/kord/common/entity/InstallParams; @@ -6097,6 +6129,7 @@ public final class dev/kord/core/entity/Guild : dev/kord/core/behavior/GuildBeha public fun getAutoModerationRules ()Lkotlinx/coroutines/flow/Flow; public fun getBan (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getBanOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getBanner ()Ldev/kord/core/entity/Asset; public final fun getBanner (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getBannerHash ()Ljava/lang/String; public final fun getBannerUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; @@ -6111,6 +6144,7 @@ public final class dev/kord/core/entity/Guild : dev/kord/core/behavior/GuildBeha public final fun getData ()Ldev/kord/core/cache/data/GuildData; public final fun getDefaultMessageNotificationLevel ()Ldev/kord/common/entity/DefaultMessageNotificationLevel; public final fun getDescription ()Ljava/lang/String; + public final fun getDiscoverySplash ()Ldev/kord/core/entity/Asset; public final fun getDiscoverySplash (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getDiscoverySplashHash ()Ljava/lang/String; public final fun getDiscoverySplashUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; @@ -6126,6 +6160,7 @@ public final class dev/kord/core/entity/Guild : dev/kord/core/behavior/GuildBeha public fun getGateway ()Ldev/kord/gateway/Gateway; public fun getGuildScheduledEvent (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getGuildScheduledEventOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getIcon ()Ldev/kord/core/entity/Asset; public final fun getIcon (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getIconHash ()Ljava/lang/String; public final fun getIconUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; @@ -6177,6 +6212,7 @@ public final class dev/kord/core/entity/Guild : dev/kord/core/behavior/GuildBeha public final fun getRulesChannel (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getRulesChannelId ()Ldev/kord/common/entity/Snowflake; public fun getScheduledEvents ()Lkotlinx/coroutines/flow/Flow; + public final fun getSplash ()Ldev/kord/core/entity/Asset; public final fun getSplash (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getSplashHash ()Ljava/lang/String; public final fun getSplashUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; @@ -6233,7 +6269,8 @@ public final class dev/kord/core/entity/GuildEmoji : dev/kord/core/entity/Emoji, public final fun getData ()Ldev/kord/core/cache/data/EmojiData; public final fun getGuildId ()Ldev/kord/common/entity/Snowflake; public fun getId ()Ldev/kord/common/entity/Snowflake; - public final fun getImage ()Ldev/kord/core/entity/Icon; + public final fun getImage ()Ldev/kord/core/entity/Asset; + public final synthetic fun getImage ()Ldev/kord/core/entity/Icon; public fun getKord ()Ldev/kord/core/Kord; public final fun getMember ()Ldev/kord/core/behavior/MemberBehavior; public final fun getMember (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -6364,6 +6401,7 @@ public final class dev/kord/core/entity/GuildScheduledEvent : dev/kord/core/beha public fun getGuildId ()Ldev/kord/common/entity/Snowflake; public final fun getGuildOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getId ()Ldev/kord/common/entity/Snowflake; + public final fun getImage ()Ldev/kord/core/entity/Asset; public final fun getImageHash ()Ljava/lang/String; public fun getKord ()Ldev/kord/core/Kord; public fun getMembers ()Lkotlinx/coroutines/flow/Flow; @@ -6564,7 +6602,9 @@ public final class dev/kord/core/entity/Member : dev/kord/core/entity/User, dev/ public fun getGuildId ()Ldev/kord/common/entity/Snowflake; public fun getGuildOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getJoinedAt ()Lkotlinx/datetime/Instant; - public final fun getMemberAvatar ()Ldev/kord/core/entity/Icon; + public final fun getMemberAvatar ()Ldev/kord/core/entity/Asset; + public final synthetic fun getMemberAvatar ()Ldev/kord/core/entity/Icon; + public final fun getMemberAvatarHash ()Ljava/lang/String; public final fun getMemberData ()Ldev/kord/core/cache/data/MemberData; public final fun getNickname ()Ljava/lang/String; public final fun getPermissions (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -6722,7 +6762,9 @@ public final class dev/kord/core/entity/PartialGuild : dev/kord/core/behavior/Gu public fun getAutoModerationRules ()Lkotlinx/coroutines/flow/Flow; public fun getBan (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getBanOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getBanner ()Ldev/kord/core/entity/Asset; public final fun getBanner (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getBannerHash ()Ljava/lang/String; public final fun getBannerUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; public fun getBans ()Lkotlinx/coroutines/flow/Flow; public fun getCachedThreads ()Lkotlinx/coroutines/flow/Flow; @@ -6739,6 +6781,7 @@ public final class dev/kord/core/entity/PartialGuild : dev/kord/core/behavior/Gu public final fun getGuildOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getGuildScheduledEvent (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getGuildScheduledEventOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getIcon ()Ldev/kord/core/entity/Asset; public final fun getIcon (Ldev/kord/rest/Image$Format;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getIconHash ()Ljava/lang/String; public final fun getIconUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; @@ -6767,6 +6810,7 @@ public final class dev/kord/core/entity/PartialGuild : dev/kord/core/behavior/Gu public fun getRoleOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getRoles ()Lkotlinx/coroutines/flow/Flow; public fun getScheduledEvents ()Lkotlinx/coroutines/flow/Flow; + public final fun getSplash ()Ldev/kord/core/entity/Asset; public final fun getSplashHash ()Ljava/lang/String; public fun getSticker (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getStickerOrNull (Ldev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -6948,7 +6992,9 @@ public final class dev/kord/core/entity/Role : dev/kord/core/behavior/RoleBehavi public fun getGuild ()Ldev/kord/core/behavior/GuildBehavior; public fun getGuildId ()Ldev/kord/common/entity/Snowflake; public final fun getHoisted ()Z - public final fun getIcon ()Ldev/kord/core/entity/Icon; + public final fun getIcon ()Ldev/kord/core/entity/Asset; + public final synthetic fun getIcon ()Ldev/kord/core/entity/Icon; + public final fun getIconHash ()Ljava/lang/String; public fun getId ()Ldev/kord/common/entity/Snowflake; public fun getKord ()Ldev/kord/core/Kord; public final fun getManaged ()Z @@ -7026,6 +7072,7 @@ public class dev/kord/core/entity/Sticker : dev/kord/core/entity/KordEntity { public fun (Ldev/kord/core/cache/data/StickerData;Ldev/kord/core/Kord;)V public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I + public final fun getAsset ()Ldev/kord/core/entity/Asset; public final fun getAvailable ()Z public final fun getData ()Ldev/kord/core/cache/data/StickerData; public final fun getDescription ()Ljava/lang/String; @@ -7044,6 +7091,7 @@ public final class dev/kord/core/entity/StickerItem : dev/kord/core/entity/KordE public synthetic fun (Ldev/kord/core/cache/data/StickerItemData;Ldev/kord/core/Kord;Ldev/kord/core/supplier/EntitySupplier;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I + public final fun getAsset ()Ldev/kord/core/entity/Asset; public final fun getData ()Ldev/kord/core/cache/data/StickerItemData; public final fun getFormatType ()Ldev/kord/common/entity/MessageStickerType; public fun getId ()Ldev/kord/common/entity/Snowflake; @@ -7059,6 +7107,8 @@ public final class dev/kord/core/entity/StickerPack : dev/kord/core/entity/KordE public fun (Ldev/kord/core/cache/data/StickerPackData;Ldev/kord/core/Kord;)V public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I + public final fun getBanner ()Ldev/kord/core/entity/Asset; + public final fun getBannerId ()Ldev/kord/common/entity/Snowflake; public final fun getCoverStickerId ()Ldev/kord/common/entity/Snowflake; public final fun getData ()Ldev/kord/core/cache/data/StickerPackData; public final fun getDescription ()Ljava/lang/String; @@ -7080,7 +7130,9 @@ public final class dev/kord/core/entity/Team : dev/kord/core/entity/KordEntity, public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I public final fun getData ()Ldev/kord/core/cache/data/TeamData; - public final fun getIcon ()Ljava/lang/String; + public final fun getIcon ()Ldev/kord/core/entity/Asset; + public final synthetic fun getIcon ()Ljava/lang/String; + public final fun getIconHash ()Ljava/lang/String; public fun getId ()Ldev/kord/common/entity/Snowflake; public fun getKord ()Ldev/kord/core/Kord; public final fun getMembers ()Ljava/util/List; @@ -7139,10 +7191,15 @@ public class dev/kord/core/entity/User : dev/kord/core/behavior/UserBehavior { public fun fetchUser (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun fetchUserOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getAccentColor ()Ldev/kord/common/Color; - public final fun getAvatar ()Ldev/kord/core/entity/Icon; + public final fun getAvatar ()Ldev/kord/core/entity/Asset; + public final synthetic fun getAvatar ()Ldev/kord/core/entity/Icon; + public final fun getAvatarHash ()Ljava/lang/String; + public final fun getBanner ()Ldev/kord/core/entity/Asset; + public final fun getBannerHash ()Ljava/lang/String; public final fun getBannerUrl (Ldev/kord/rest/Image$Format;)Ljava/lang/String; public final fun getData ()Ldev/kord/core/cache/data/UserData; - public final fun getDefaultAvatar ()Ldev/kord/core/entity/Icon; + public final fun getDefaultAvatar ()Ldev/kord/core/entity/Asset; + public final synthetic fun getDefaultAvatar ()Ldev/kord/core/entity/Icon; public final fun getDiscriminator ()Ljava/lang/String; public fun getDmChannel (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getDmChannelOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/core/src/commonMain/kotlin/entity/Application.kt b/core/src/commonMain/kotlin/entity/Application.kt index f00c41bd06e4..bd7adb7f06a1 100644 --- a/core/src/commonMain/kotlin/entity/Application.kt +++ b/core/src/commonMain/kotlin/entity/Application.kt @@ -25,6 +25,8 @@ public sealed class BaseApplication( public val name: String get() = data.name + public val icon: Asset? get() = iconHash?.let { Asset.applicationIcon(id, it, kord) } + public val iconHash: String? get() = data.icon public val description: String get() = data.description @@ -52,6 +54,8 @@ public sealed class BaseApplication( public val slug: String? get() = data.slug.value + public val coverImage: Asset? get() = coverImageHash?.let { Asset.applicationCover(id, it, kord) } + public val coverImageHash: String? get() = data.coverImage.value public val flags: ApplicationFlags? get() = data.flags.value diff --git a/core/src/commonMain/kotlin/entity/Asset.kt b/core/src/commonMain/kotlin/entity/Asset.kt new file mode 100644 index 000000000000..bd6b57ef237d --- /dev/null +++ b/core/src/commonMain/kotlin/entity/Asset.kt @@ -0,0 +1,100 @@ +package dev.kord.core.entity + +import dev.kord.common.entity.MessageStickerType +import dev.kord.common.entity.Snowflake +import dev.kord.core.Kord +import dev.kord.core.KordObject +import dev.kord.rest.Image +import dev.kord.rest.Image.Format.* +import dev.kord.rest.route.CdnUrl +import dev.kord.rest.route.DiscordCdn + +public class Asset private constructor( + public val isAnimated: Boolean, + public val cdnUrl: CdnUrl, + override val kord: Kord, + private val recommendedFormat: Image.Format? = null, +) : KordObject { + + public suspend fun getImage(format: Image.Format? = null, size: Image.Size? = null): Image = Image.fromUrl( + client = kord.resources.httpClient, + url = cdnUrl.toUrl { + this.format = format ?: recommendedFormat ?: if (isAnimated) GIF else PNG + if (size != null) this.size = size + }, + ) + + public companion object { + // see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints + + private val String.isAnimated get() = startsWith("a_") + + private fun unknownFormatType(formatType: MessageStickerType): Nothing = + throw IllegalArgumentException("Unknown formatType: $formatType") + + + public fun emoji(emojiId: Snowflake, isAnimated: Boolean, kord: Kord): Asset = + Asset(isAnimated, DiscordCdn.emoji(emojiId), kord) + + public fun guildIcon(guildId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.guildIcon(guildId, hash), kord) + + public fun guildSplash(guildId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.guildSplash(guildId, hash), kord) + + public fun guildDiscoverySplash(guildId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.guildDiscoverySplash(guildId, hash), kord) + + public fun guildBanner(guildId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.guildBanner(guildId, hash), kord) + + public fun userBanner(userId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.userBanner(userId, hash), kord) + + public fun defaultUserAvatar(discriminator: Int, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.defaultAvatar(discriminator), kord, recommendedFormat = PNG) + + public fun userAvatar(userId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.userAvatar(userId, hash), kord) + + public fun memberAvatar(guildId: Snowflake, userId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.memberAvatar(guildId, userId, hash), kord) + + public fun applicationIcon(applicationId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.applicationIcon(applicationId, hash), kord) + + public fun applicationCover(applicationId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.applicationCover(applicationId, hash), kord) + + public fun stickerPackBanner(bannerId: Snowflake, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.stickerPackBanner(bannerId), kord) + + public fun teamIcon(teamId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.teamIcon(teamId, hash), kord) + + public fun sticker(stickerId: Snowflake, formatType: MessageStickerType, kord: Kord): Asset = Asset( + isAnimated = when (formatType) { + MessageStickerType.PNG -> false + MessageStickerType.APNG, MessageStickerType.LOTTIE, MessageStickerType.GIF -> true + is MessageStickerType.Unknown -> unknownFormatType(formatType) + }, + DiscordCdn.sticker(stickerId), + kord, + recommendedFormat = when (formatType) { + MessageStickerType.PNG, MessageStickerType.APNG -> PNG + MessageStickerType.LOTTIE -> LOTTIE + MessageStickerType.GIF -> GIF + is MessageStickerType.Unknown -> unknownFormatType(formatType) + }, + ) + + public fun roleIcon(roleId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.roleIcon(roleId, hash), kord) + + public fun guildScheduledEventCover(eventId: Snowflake, hash: String, kord: Kord): Asset = + Asset(isAnimated = false, DiscordCdn.guildScheduledEventCover(eventId, hash), kord) + + public fun memberBanner(guildId: Snowflake, userId: Snowflake, hash: String, kord: Kord): Asset = + Asset(hash.isAnimated, DiscordCdn.memberBanner(guildId, userId, hash), kord) + } +} diff --git a/core/src/commonMain/kotlin/entity/Emoji.kt b/core/src/commonMain/kotlin/entity/Emoji.kt index c7f33ff8d815..d8bfc37f935f 100644 --- a/core/src/commonMain/kotlin/entity/Emoji.kt +++ b/core/src/commonMain/kotlin/entity/Emoji.kt @@ -135,7 +135,12 @@ public class GuildEmoji( /** * The image as [Icon] object for the emoji */ - public val image: Icon get() = Icon.EmojiIcon(data.animated.discordBoolean, data.id, kord) + @Suppress("DEPRECATION") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getImage(): Icon = Icon.EmojiIcon(data.animated.discordBoolean, data.id, kord) + + /** The image of this emoji as an [Asset]. */ + public val image: Asset get() = Asset.emoji(id, isAnimated, kord) /** * Requests to delete this emoji, with the given [reason]. diff --git a/core/src/commonMain/kotlin/entity/Guild.kt b/core/src/commonMain/kotlin/entity/Guild.kt index d5ff19fba80a..ff63153cb2ed 100644 --- a/core/src/commonMain/kotlin/entity/Guild.kt +++ b/core/src/commonMain/kotlin/entity/Guild.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.datetime.Instant import dev.kord.core.hash +import kotlin.DeprecationLevel.WARNING import kotlin.time.Duration /** @@ -105,6 +106,8 @@ public class Guild( */ public val bannerHash: String? get() = data.banner + public val banner: Asset? get() = bannerHash?.let { Asset.guildBanner(id, it, kord) } + /** * The ids of all [channels][TopGuildChannel]. */ @@ -156,6 +159,8 @@ public class Guild( */ public val iconHash: String? get() = data.icon + public val icon: Asset? get() = iconHash?.let { Asset.guildIcon(id, it, kord) } + /** * The time at which this guild was joined, if present. */ @@ -259,11 +264,15 @@ public class Guild( */ public val splashHash: String? get() = data.splash.value + public val splash: Asset? get() = splashHash?.let { Asset.guildSplash(id, it, kord) } + /** * The hash of the discovery splash, if present. */ public val discoverySplashHash: String? get() = data.discoverySplash.value + public val discoverySplash: Asset? get() = discoverySplashHash?.let { Asset.guildDiscoverySplash(id, it, kord) } + /** * The id of the channel to which system messages are sent. */ @@ -349,12 +358,15 @@ public class Guild( /** * Gets the banner url in the specified format. */ + @Deprecated("Old method", ReplaceWith("this.banner?.cdnUrl?.toUrl { this@toUrl.format = format }"), level = WARNING) public fun getBannerUrl(format: Image.Format): String? = data.banner?.let { "https://cdn.discordapp.com/banners/$id/$it.${format.extension}" } /** * Requests to get the banner image in the specified [format], if present. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.banner?.getImage(format)"), level = WARNING) public suspend fun getBanner(format: Image.Format): Image? { val url = getBannerUrl(format) ?: return null @@ -407,6 +419,11 @@ public class Guild( /** * Gets the discovery splash url in the specified [format], if present. */ + @Deprecated( + "Old method", + ReplaceWith("this.discoverySplash?.cdnUrl?.toUrl { this@toUrl.format = format }"), + level = WARNING, + ) public fun getDiscoverySplashUrl(format: Image.Format): String? = splashHash?.let { "discovery-splashes/$id/${it}.${format.extension}" } @@ -415,6 +432,8 @@ public class Guild( * * This property is not resolvable through cache and will always use the [RestClient] instead. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.discoverySplash?.getImage(format)"), level = WARNING) public suspend fun getDiscoverySplash(format: Image.Format): Image? { val url = getDiscoverySplashUrl(format) ?: return null @@ -424,12 +443,15 @@ public class Guild( /** * Gets the icon url, if present. */ + @Deprecated("Old method", ReplaceWith("this.icon?.cdnUrl?.toUrl { this@toUrl.format = format }"), level = WARNING) public fun getIconUrl(format: Image.Format): String? = data.icon?.let { "https://cdn.discordapp.com/icons/$id/$it.${format.extension}" } /** * Requests to get the icon image in the specified [format], if present. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.icon?.getImage(format)"), level = WARNING) public suspend fun getIcon(format: Image.Format): Image? { val url = getIconUrl(format) ?: return null @@ -468,12 +490,15 @@ public class Guild( /** * Gets the splash url in the specified [format], if present. */ + @Deprecated("Old method", ReplaceWith("this.splash?.cdnUrl?.toUrl { this@toUrl.format = format }"), WARNING) public fun getSplashUrl(format: Image.Format): String? = data.splash.value?.let { "https://cdn.discordapp.com/splashes/$id/$it.${format.extension}" } /** * Requests to get the splash image in the specified [format], if present. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.splash?.getImage(format)"), WARNING) public suspend fun getSplash(format: Image.Format): Image? { val url = getSplashUrl(format) ?: return null diff --git a/core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt b/core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt index 8189913fbcfe..d45080019273 100644 --- a/core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt +++ b/core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt @@ -117,6 +117,8 @@ public class GuildScheduledEvent( /** The cover image hash of this event. */ public val imageHash: String? get() = data.image.value + public val image: Asset? get() = imageHash?.let { Asset.guildScheduledEventCover(id, it, kord) } + /** * Requests the [Guild] this event belongs to. * diff --git a/core/src/commonMain/kotlin/entity/Icon.kt b/core/src/commonMain/kotlin/entity/Icon.kt index 77020b2f91e6..82951b6d5257 100644 --- a/core/src/commonMain/kotlin/entity/Icon.kt +++ b/core/src/commonMain/kotlin/entity/Icon.kt @@ -7,6 +7,12 @@ import dev.kord.rest.Image import dev.kord.rest.route.CdnUrl import dev.kord.rest.route.DiscordCdn +@Suppress("DEPRECATION") +@Deprecated( + "Icon class does not cover all cdn endpoints and has some inconsistencies.", + ReplaceWith("Asset", "dev.kord.core.entity.Asset"), + DeprecationLevel.WARNING +) public sealed class Icon( public val format: Image.Format, public val animated: Boolean, diff --git a/core/src/commonMain/kotlin/entity/Member.kt b/core/src/commonMain/kotlin/entity/Member.kt index ac86987ee908..bad52a245f96 100644 --- a/core/src/commonMain/kotlin/entity/Member.kt +++ b/core/src/commonMain/kotlin/entity/Member.kt @@ -37,8 +37,15 @@ public class Member( /** * The members guild avatar as [Icon] object */ - public val memberAvatar: Icon? - get() = memberData.avatar.value?.let { Icon.MemberAvatar(memberData.guildId, data.id, it, kord) } + @Suppress("DEPRECATION") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getMemberAvatar(): Icon? = + memberData.avatar.value?.let { Icon.MemberAvatar(memberData.guildId, id, it, kord) } + + public val memberAvatarHash: String? get() = memberData.avatar.value + + /** The guild avatar of this member as an [Asset]. */ + public val memberAvatar: Asset? get() = memberAvatarHash?.let { Asset.memberAvatar(guildId, id, it, kord) } /** * When the user joined this [guild]. diff --git a/core/src/commonMain/kotlin/entity/PartialGuild.kt b/core/src/commonMain/kotlin/entity/PartialGuild.kt index 9f7220cdac90..9374c0a60a4b 100644 --- a/core/src/commonMain/kotlin/entity/PartialGuild.kt +++ b/core/src/commonMain/kotlin/entity/PartialGuild.kt @@ -16,6 +16,7 @@ import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.Image import dev.kord.rest.service.RestClient import dev.kord.core.hash +import kotlin.DeprecationLevel.WARNING public class PartialGuild( public val data: PartialGuildData, @@ -36,6 +37,8 @@ public class PartialGuild( */ public val iconHash: String? get() = data.icon + public val icon: Asset? get() = iconHash?.let { Asset.guildIcon(id, it, kord) } + /** * wither who created the invite is the owner or not. */ @@ -85,10 +88,20 @@ public class PartialGuild( public val splashHash: String? get() = data.splash.value + public val splash: Asset? get() = splashHash?.let { Asset.guildSplash(id, it, kord) } + + public val bannerHash: String? get() = data.banner.value + + public val banner: Asset? get() = bannerHash?.let { Asset.guildBanner(id, it, kord) } /** * Gets the discovery splash url in the specified [format], if present. */ + @Deprecated( + "This method uses the wrong hash.", + ReplaceWith("this.splash?.cdnUrl?.toUrl { this@toUrl.format = format }"), + level = WARNING, + ) public fun getDiscoverySplashUrl(format: Image.Format): String? = splashHash?.let { "discovery-splashes/$id/${it}.${format.extension}" } @@ -97,6 +110,12 @@ public class PartialGuild( * * This property is not resolvable through cache and will always use the [RestClient] instead. */ + @Suppress("DEPRECATION") + @Deprecated( + "This method uses the wrong hash.", + ReplaceWith("this.splash?.getImage(format)"), + level = WARNING, + ) public suspend fun getDiscoverySplash(format: Image.Format): Image? { val url = getDiscoverySplashUrl(format) ?: return null @@ -107,6 +126,7 @@ public class PartialGuild( /** * Gets the icon url, if present. */ + @Deprecated("Old method", ReplaceWith("this.icon?.cdnUrl?.toUrl { this@toUrl.format = format }"), level = WARNING) public fun getIconUrl(format: Image.Format): String? = iconHash?.let { "https://cdn.discordapp.com/icons/$id/$it.${format.extension}" } @@ -114,6 +134,8 @@ public class PartialGuild( /** * Requests to get the icon image in the specified [format], if present. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.icon?.getImage(format)"), level = WARNING) public suspend fun getIcon(format: Image.Format): Image? { val url = getIconUrl(format) ?: return null @@ -124,12 +146,15 @@ public class PartialGuild( /** * Gets the banner url in the specified format. */ + @Deprecated("Old method", ReplaceWith("this.banner?.cdnUrl?.toUrl { this@toUrl.format = format }"), level = WARNING) public fun getBannerUrl(format: Image.Format): String? = data.banner.value?.let { "https://cdn.discordapp.com/banners/$id/$it.${format.extension}" } /** * Requests to get the banner image in the specified [format], if present. */ + @Suppress("DEPRECATION") + @Deprecated("Old method", ReplaceWith("this.banner?.getImage(format)"), level = WARNING) public suspend fun getBanner(format: Image.Format): Image? { val url = getBannerUrl(format) ?: return null diff --git a/core/src/commonMain/kotlin/entity/Role.kt b/core/src/commonMain/kotlin/entity/Role.kt index 88408436f480..d533db821287 100644 --- a/core/src/commonMain/kotlin/entity/Role.kt +++ b/core/src/commonMain/kotlin/entity/Role.kt @@ -27,7 +27,13 @@ public data class Role( public val hoisted: Boolean get() = data.hoisted - val icon: Icon? get() = data.icon.value?.let { Icon.RoleIcon(data.id, it, kord) } + @Suppress("DEPRECATION") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getIcon(): Icon? = data.icon.value?.let { Icon.RoleIcon(data.id, it, kord) } + + val iconHash: String? get() = data.icon.value + + val icon: Asset? get() = iconHash?.let { Asset.roleIcon(id, it, kord) } val unicodeEmoji: String? = data.unicodeEmoji.value diff --git a/core/src/commonMain/kotlin/entity/Sticker.kt b/core/src/commonMain/kotlin/entity/Sticker.kt index 48419d56a3d9..8333346a3d98 100644 --- a/core/src/commonMain/kotlin/entity/Sticker.kt +++ b/core/src/commonMain/kotlin/entity/Sticker.kt @@ -53,6 +53,8 @@ public open class Sticker(public val data: StickerData, override val kord: Kord) public val formatType: MessageStickerType get() = data.formatType + public val asset: Asset get() = Asset.sticker(id, formatType, kord) + public val available: Boolean get() = data.available.discordBoolean @@ -96,6 +98,8 @@ public class StickerItem( public val formatType: MessageStickerType get() = data.formatType + public val asset: Asset get() = Asset.sticker(id, formatType, kord) + public suspend fun getStickerOrNull(): Sticker? = supplier.getStickerOrNull(id) @@ -123,5 +127,7 @@ public class StickerPack(public val data: StickerPackData, override val kord: Ko public val stickers: List get() = data.stickers.map { Sticker(it, kord) } + public val bannerId: Snowflake get() = data.bannerAssetId -} \ No newline at end of file + public val banner: Asset get() = Asset.stickerPackBanner(bannerId, kord) +} diff --git a/core/src/commonMain/kotlin/entity/Team.kt b/core/src/commonMain/kotlin/entity/Team.kt index 7d0eb6b3fdc3..d13fe2f14cd3 100644 --- a/core/src/commonMain/kotlin/entity/Team.kt +++ b/core/src/commonMain/kotlin/entity/Team.kt @@ -27,7 +27,13 @@ public class Team( /** * The hash of this team's icon. */ - public val icon: String? get() = data.icon + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getIcon(): String? = data.icon + + /** The hash of this team's icon. */ + public val iconHash: String? get() = data.icon + + public val icon: Asset? get() = iconHash?.let { Asset.teamIcon(id, it, kord) } /** * A collection of all members of this team. diff --git a/core/src/commonMain/kotlin/entity/User.kt b/core/src/commonMain/kotlin/entity/User.kt index 37e5b67c5bc7..ae80a16c044d 100644 --- a/core/src/commonMain/kotlin/entity/User.kt +++ b/core/src/commonMain/kotlin/entity/User.kt @@ -10,6 +10,7 @@ import dev.kord.core.cache.data.UserData import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.Image +import kotlin.DeprecationLevel.WARNING /** * An instance of a [Discord User](https://discord.com/developers/docs/resources/user#user-object). @@ -25,10 +26,20 @@ public open class User( /** * The users avatar as [Icon] object */ - public val avatar: Icon? - get() = data.avatar?.let { Icon.UserAvatar(data.id, it, kord) } + @Suppress("DEPRECATION") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getAvatar(): Icon? = data.avatar?.let { Icon.UserAvatar(data.id, it, kord) } - public val defaultAvatar: Icon get() = Icon.DefaultUserAvatar(data.discriminator.toInt(), kord) + public val avatarHash: String? get() = data.avatar + + /** The avatar of this user as an [Asset]. */ + public val avatar: Asset? get() = avatarHash?.let { Asset.userAvatar(data.id, it, kord) } + + @Suppress("DEPRECATION") + @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) + public fun getDefaultAvatar(): Icon = Icon.DefaultUserAvatar(data.discriminator.toInt(), kord) + + public val defaultAvatar: Asset get() = Asset.defaultUserAvatar(discriminator.toInt(), kord) /** * The username of this user. @@ -65,9 +76,13 @@ public open class User( public val accentColor: Color? get() = data.accentColor?.let { Color(it) } + @Deprecated("Old method", ReplaceWith("this.banner?.cdnUrl?.toUrl { this@toUrl.format = format }"), level = WARNING) public fun getBannerUrl(format: Image.Format): String? = data.banner?.let { "https://cdn.discordapp.com/banners/$id/$it.${format.extension}" } + public val bannerHash: String? get() = data.banner + + public val banner: Asset? get() = bannerHash?.let { Asset.userBanner(id, it, kord) } override fun hashCode(): Int = id.hashCode() @@ -85,6 +100,7 @@ public open class User( return "User(data=$data, kord=$kord, supplier=$supplier)" } + @Deprecated("Old class", ReplaceWith("Asset", "dev.kord.core.entity.Asset"), level = WARNING) public data class Avatar(val data: UserData, override val kord: Kord) : KordObject { /** diff --git a/rest/api/rest.api b/rest/api/rest.api index 299538983ef8..ce4b4c244b8c 100644 --- a/rest/api/rest.api +++ b/rest/api/rest.api @@ -33,6 +33,10 @@ public final class dev/kord/rest/Image$Format$JPEG : dev/kord/rest/Image$Format public static final field INSTANCE Ldev/kord/rest/Image$Format$JPEG; } +public final class dev/kord/rest/Image$Format$LOTTIE : dev/kord/rest/Image$Format { + public static final field INSTANCE Ldev/kord/rest/Image$Format$LOTTIE; +} + public final class dev/kord/rest/Image$Format$PNG : dev/kord/rest/Image$Format { public static final field INSTANCE Ldev/kord/rest/Image$Format$PNG; } @@ -6113,6 +6117,8 @@ public final class dev/kord/rest/request/StackTraceRecoveringKtorRequestHandlerK public final class dev/kord/rest/route/CdnUrl { public fun (Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I public fun toString ()Ljava/lang/String; public final fun toUrl ()Ljava/lang/String; public final fun toUrl (Ldev/kord/rest/route/CdnUrl$UrlFormatBuilder;)Ljava/lang/String; @@ -6129,11 +6135,23 @@ public final class dev/kord/rest/route/CdnUrl$UrlFormatBuilder { public final class dev/kord/rest/route/DiscordCdn { public static final field INSTANCE Ldev/kord/rest/route/DiscordCdn; + public final fun applicationCover (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun applicationIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; public final fun defaultAvatar (I)Ldev/kord/rest/route/CdnUrl; public final fun emoji (Ldev/kord/common/entity/Snowflake;)Ldev/kord/rest/route/CdnUrl; + public final fun guildBanner (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun guildDiscoverySplash (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun guildIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun guildScheduledEventCover (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun guildSplash (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; public final fun memberAvatar (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun memberBanner (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; public final fun roleIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun sticker (Ldev/kord/common/entity/Snowflake;)Ldev/kord/rest/route/CdnUrl; + public final fun stickerPackBanner (Ldev/kord/common/entity/Snowflake;)Ldev/kord/rest/route/CdnUrl; + public final fun teamIcon (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; public final fun userAvatar (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; + public final fun userBanner (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;)Ldev/kord/rest/route/CdnUrl; } public abstract interface class dev/kord/rest/route/Position { diff --git a/rest/src/commonMain/kotlin/Image.kt b/rest/src/commonMain/kotlin/Image.kt index 1ec1ee4a6f73..d95b25554791 100644 --- a/rest/src/commonMain/kotlin/Image.kt +++ b/rest/src/commonMain/kotlin/Image.kt @@ -34,6 +34,7 @@ public class Image private constructor(public val data: ByteArray, public val fo public object PNG : Format("png") public object WEBP : Format("webp") public object GIF : Format("gif") + public object LOTTIE : Format("json") public companion object { public val values: Set @@ -42,6 +43,7 @@ public class Image private constructor(public val data: ByteArray, public val fo PNG, WEBP, GIF, + LOTTIE, ) public fun isSupported(fileName: String): Boolean { @@ -55,6 +57,7 @@ public class Image private constructor(public val data: ByteArray, public val fo "image/png" -> PNG "image/webp" -> WEBP "image/gif" -> GIF + "application/json" -> LOTTIE else -> error(type) } } diff --git a/rest/src/commonMain/kotlin/route/CdnUrl.kt b/rest/src/commonMain/kotlin/route/CdnUrl.kt index 66b214af6e06..75d990c54b5b 100644 --- a/rest/src/commonMain/kotlin/route/CdnUrl.kt +++ b/rest/src/commonMain/kotlin/route/CdnUrl.kt @@ -19,9 +19,9 @@ public class CdnUrl(private val rawAssetUri: String) { return urlBuilder.toString() } - override fun toString(): String { - return "CdnUrl(rawAssetUri=$rawAssetUri)" - } + override fun equals(other: Any?): Boolean = other is CdnUrl && this.rawAssetUri == other.rawAssetUri + override fun hashCode(): Int = rawAssetUri.hashCode() + override fun toString(): String = "CdnUrl(rawAssetUri=$rawAssetUri)" public class UrlFormatBuilder { public var format: Image.Format = Image.Format.WEBP diff --git a/rest/src/commonMain/kotlin/route/DiscordCdn.kt b/rest/src/commonMain/kotlin/route/DiscordCdn.kt index 56028b2800cd..3964d11addee 100644 --- a/rest/src/commonMain/kotlin/route/DiscordCdn.kt +++ b/rest/src/commonMain/kotlin/route/DiscordCdn.kt @@ -3,11 +3,23 @@ package dev.kord.rest.route import dev.kord.common.entity.Snowflake public object DiscordCdn { + // see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints private const val BASE_URL = "https://cdn.discordapp.com" public fun emoji(emojiId: Snowflake): CdnUrl = CdnUrl("$BASE_URL/emojis/$emojiId") + public fun guildIcon(guildId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/icons/$guildId/$hash") + + public fun guildSplash(guildId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/splashes/$guildId/$hash") + + public fun guildDiscoverySplash(guildId: Snowflake, hash: String): CdnUrl = + CdnUrl("$BASE_URL/discovery-splashes/$guildId/$hash") + + public fun guildBanner(guildId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/banners/$guildId/$hash") + + public fun userBanner(userId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/banners/$userId/$hash") + public fun defaultAvatar(discriminator: Int): CdnUrl = CdnUrl("$BASE_URL/embed/avatars/${discriminator % 5}") public fun userAvatar(userId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/avatars/$userId/$hash") @@ -15,5 +27,24 @@ public object DiscordCdn { public fun memberAvatar(guildId: Snowflake, userId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/guilds/$guildId/users/$userId/avatars/$hash") + public fun applicationIcon(applicationId: Snowflake, hash: String): CdnUrl = + CdnUrl("$BASE_URL/app-icons/$applicationId/$hash") + + public fun applicationCover(applicationId: Snowflake, hash: String): CdnUrl = + CdnUrl("$BASE_URL/app-icons/$applicationId/$hash") + + public fun stickerPackBanner(bannerId: Snowflake): CdnUrl = + CdnUrl("$BASE_URL/app-assets/710982414301790216/store/$bannerId") + + public fun teamIcon(teamId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/team-icons/$teamId/$hash") + + public fun sticker(stickerId: Snowflake): CdnUrl = CdnUrl("$BASE_URL/stickers/$stickerId") + public fun roleIcon(roleId: Snowflake, hash: String): CdnUrl = CdnUrl("$BASE_URL/role-icons/$roleId/$hash") + + public fun guildScheduledEventCover(eventId: Snowflake, hash: String): CdnUrl = + CdnUrl("$BASE_URL/guild-events/$eventId/$hash") + + public fun memberBanner(guildId: Snowflake, userId: Snowflake, hash: String): CdnUrl = + CdnUrl("$BASE_URL/guilds/$guildId/users/$userId/banners/$hash") } From c466993d33b09847e4003710ea14ec760b867e12 Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Wed, 12 Apr 2023 19:50:38 +0200 Subject: [PATCH 02/33] Upgrade to Gradle 8.1 (#783) The changes in gradle-wrapper.jar, gradle-wrapper.properties and gradlew are the result of running this command twice: ./gradlew wrapper --gradle-version 8.1 --gradle-distribution-sha256-sum a62c5f99585dd9e1f95dab7b9415a0e698fa9dd1e6c38537faa81ac078f4d23e This commit also includes: * making use of simple property assignment in Kotlin DSL scripts, see https://docs.gradle.org/8.1/release-notes.html#kotlin-assign * removing no longer needed @Suppress("DSL_SCOPE_VIOLATION") for using version catalog in the plugins {} block, see https://docs.gradle.org/8.1/userguide/upgrading_version_8.html#kotlin_dsl_plugins_catalogs_workaround --------- Co-authored-by: Lukellmann --- buildSrc/src/main/kotlin/Compiler.kt | 3 +- buildSrc/src/main/kotlin/Documentation.kt | 17 ++++++----- .../main/kotlin/kord-publishing.gradle.kts | 28 +++++++++--------- common/build.gradle.kts | 1 - gradle.properties | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 61608 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 4 +-- gradlew | 7 +++-- 8 files changed, 32 insertions(+), 29 deletions(-) diff --git a/buildSrc/src/main/kotlin/Compiler.kt b/buildSrc/src/main/kotlin/Compiler.kt index 3d4cc2614d16..48a5f1d5bb96 100644 --- a/buildSrc/src/main/kotlin/Compiler.kt +++ b/buildSrc/src/main/kotlin/Compiler.kt @@ -1,6 +1,7 @@ import kotlinx.atomicfu.plugin.gradle.AtomicFUPluginExtension import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.getByType import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions @@ -26,7 +27,7 @@ object Jvm { fun KotlinCommonCompilerOptions.applyKordCompilerOptions() { // TODO: set to true again once https://github.com/Kotlin/kotlinx-atomicfu/issues/289 is fixed - allWarningsAsErrors.set(false) + allWarningsAsErrors = false freeCompilerArgs.add("-progressive") } diff --git a/buildSrc/src/main/kotlin/Documentation.kt b/buildSrc/src/main/kotlin/Documentation.kt index db5da77659e5..bd70ae5ca72b 100644 --- a/buildSrc/src/main/kotlin/Documentation.kt +++ b/buildSrc/src/main/kotlin/Documentation.kt @@ -1,19 +1,20 @@ +import org.gradle.kotlin.dsl.assign import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask import java.net.URL fun AbstractDokkaLeafTask.applyKordDokkaOptions() { - failOnWarning.set(true) + failOnWarning = true dokkaSourceSets.configureEach { - jdkVersion.set(Jvm.target) + jdkVersion = Jvm.target - suppressGeneratedFiles.set(false) + suppressGeneratedFiles = false sourceLink { - localDirectory.set(project.projectDir) - remoteUrl.set(URL("https://github.com/kordlib/kord/blob/${Library.commitHashOrDefault("0.9.x")}/${project.name}")) - remoteLineSuffix.set("#L") + localDirectory = project.projectDir + remoteUrl = URL("https://github.com/kordlib/kord/blob/${Library.commitHashOrDefault("0.9.x")}/${project.name}") + remoteLineSuffix = "#L" } externalDocumentationLink("https://kotlinlang.org/api/kotlinx.coroutines/") @@ -26,8 +27,8 @@ fun AbstractDokkaLeafTask.applyKordDokkaOptions() { // don't list `TweetNaclFast` in docs perPackageOption { - matchingRegex.set("""com\.iwebpp\.crypto""") - suppress.set(true) + matchingRegex = """com\.iwebpp\.crypto""" + suppress = true } } } diff --git a/buildSrc/src/main/kotlin/kord-publishing.gradle.kts b/buildSrc/src/main/kotlin/kord-publishing.gradle.kts index 593dd1348b86..0cfe3d9a3702 100644 --- a/buildSrc/src/main/kotlin/kord-publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/kord-publishing.gradle.kts @@ -6,7 +6,7 @@ plugins { } val dokkaJar by tasks.registering(Jar::class) { - archiveClassifier.set("javadoc") + archiveClassifier = "javadoc" from(tasks.named("dokkaHtml")) } @@ -19,37 +19,37 @@ publishing { version = Library.version pom { - name.set(Library.name) - description.set(Library.description) - url.set(Library.projectUrl) + name = Library.name + description = Library.description + url = Library.projectUrl organization { - name.set("Kord") - url.set("https://github.com/kordlib") + name = "Kord" + url = "https://github.com/kordlib" } developers { developer { - name.set("The Kord Team") + name = "The Kord Team" } } issueManagement { - system.set("GitHub") - url.set("https://github.com/kordlib/kord/issues") + system = "GitHub" + url = "https://github.com/kordlib/kord/issues" } licenses { license { - name.set("MIT") - url.set("http://opensource.org/licenses/MIT") + name = "MIT" + url = "http://opensource.org/licenses/MIT" } } scm { - connection.set("scm:git:ssh://github.com/kordlib/kord.git") - developerConnection.set("scm:git:ssh://git@github.com:kordlib/kord.git") - url.set(Library.projectUrl) + connection = "scm:git:ssh://github.com/kordlib/kord.git" + developerConnection = "scm:git:ssh://git@github.com:kordlib/kord.git" + url = Library.projectUrl } } } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 3975a46823f0..624f44ac9af9 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -1,4 +1,3 @@ -@Suppress("DSL_SCOPE_VIOLATION") // false positive for `libs` in IntelliJ plugins { `kord-multiplatform-module` `kord-publishing` diff --git a/gradle.properties b/gradle.properties index b28460e2ab10..ef230821e589 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,7 @@ #dokka will run out of memory with the default meta space org.gradle.jvmargs=-XX:MaxMetaspaceSize=1024m org.gradle.parallel=true +systemProp.org.gradle.unsafe.kotlin.assignment=true kotlin.code.style=official # https://github.com/Kotlin/kotlinx-atomicfu#atomicfu-compiler-plugin diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index ccebba7710deaf9f98673a68957ea02138b60d0a..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 8979 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 F{TFmrHLU;u delta 8469 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 Date: Thu, 13 Apr 2023 01:19:31 -0500 Subject: [PATCH 03/33] Gix some EntitySupplyStrategy toStrings being incorrect (#811) --- core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt b/core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt index 64c0c9e92838..f7f6b6313db8 100644 --- a/core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt +++ b/core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt @@ -49,7 +49,7 @@ public interface EntitySupplyStrategy { return StoreEntitySupplier(rest.supply(kord), kord.cache) } - override fun toString(): String = "EntitySupplyStrategy.cacheAwareRest" + override fun toString(): String = "EntitySupplyStrategy.cachingRest" } @@ -78,7 +78,7 @@ public interface EntitySupplyStrategy { override fun supply(kord: Kord): EntitySupplier = cache.supply(kord).withFallback(cachingRest.supply(kord)) - override fun toString(): String = "EntitySupplyStrategy.cacheWithCacheAwareRestFallback" + override fun toString(): String = "EntitySupplyStrategy.cacheWithCachingRestFallback" } /** From 57b186c0ee11d696a8ffa2c4301e55856e7468e4 Mon Sep 17 00:00:00 2001 From: Lukellmann <47486203+Lukellmann@users.noreply.github.com> Date: Fri, 14 Apr 2023 01:11:10 +0200 Subject: [PATCH 04/33] Fix Qodana findings (#812) See individual commits of #812 for details. --------- Co-authored-by: Michael Rittmeister --- .../kotlin/entity/DiscordComponent.kt | 1 - .../commonMain/kotlin/entity/DiscordUser.kt | 12 +-- .../serialization/InstantSerializers.kt | 1 - .../jsMain/kotlin/{http => }/HttpEngine.kt | 0 core/api/core.api | 10 +- core/src/commonMain/kotlin/Kord.kt | 13 +-- core/src/commonMain/kotlin/Util.kt | 33 ------ .../kotlin/behavior/GuildBehavior.kt | 6 +- .../kotlin/behavior/MemberBehavior.kt | 4 +- .../kotlin/behavior/UserBehavior.kt | 5 - .../channel/BaseVoiceChannelBehavior.kt | 2 +- .../behavior/channel/ChannelBehavior.kt | 4 +- .../threads/ThreadParentChannelBehavior.kt | 5 +- .../ButtonBuilderExtensions.kt | 0 .../commonMain/kotlin/cache/CachingGateway.kt | 2 +- .../kotlin/cache/DataCacheExtensions.kt | 9 +- .../GuildApplicationCommandPermissionsData.kt | 1 - core/src/commonMain/kotlin/entity/Guild.kt | 6 +- core/src/commonMain/kotlin/entity/Member.kt | 2 +- .../kotlin/entity/PermissionOverwrite.kt | 3 - .../kotlin/entity/channel/GuildChannel.kt | 9 -- .../entity/channel/StageVoiceChannel.kt | 4 +- .../kotlin/entity/channel/VoiceChannel.kt | 4 +- .../channel/thread/DeletedThreadChannel.kt | 2 - .../channel/thread/NewsChannelThread.kt | 2 +- .../entity/component/ButtonComponent.kt | 2 + .../kotlin/entity/interaction/OptionValue.kt | 2 - .../interaction/SelectMenuInteraction.kt | 1 - .../channel/thread/ThreadListSyncEvent.kt | 6 +- .../commonMain/kotlin/event/gateway/Events.kt | 9 +- .../gateway/handler/ChannelEventHandler.kt | 6 +- .../gateway/handler/GuildEventHandler.kt | 26 ++--- .../handler/InteractionEventHandler.kt | 2 +- .../gateway/handler/MessageEventHandler.kt | 28 ++--- .../gateway/handler/ThreadEventHandler.kt | 10 +- .../gateway/handler/UserEventHandler.kt | 2 +- .../gateway/handler/VoiceEventHandler.kt | 2 +- .../commonMain/kotlin/live/LiveKordEntity.kt | 8 +- .../kotlin/supplier/CacheEntitySupplier.kt | 100 +++++++++--------- .../kord/core}/builder/kord/KordBuilder.kt | 0 .../kord/core}/cache/KordCacheBuilder.kt | 0 .../builder/interaction/ModalBuilder.kt | 1 - .../builder/interaction/OptionsBuilder.kt | 3 + .../kotlin/request/RestRequestException.kt | 2 +- rest/src/commonTest/kotlin/Utils.kt | 12 --- .../message/create/MessageCreateBuilderJvm.kt | 0 .../message/modify/MessageModifyBuilderJvm.kt | 0 .../kord/rest}/request/RecoveredStackTrace.kt | 0 .../kord/rest}/request/RequestBuilder.kt | 0 .../kotlin/{ => dev/kord}/core/PingBot.kt | 0 .../{ => dev/kord}/gateway/GatewayExample.kt | 4 - .../kotlin/{ => dev/kord}/rest/RestExample.kt | 0 test-kit/src/commonMain/kotlin/Platform.kt | 1 - test-kit/src/jsMain/kotlin/Platform.kt | 4 - test-kit/src/jvmMain/kotlin/IgnoreOnJvm.kt | 1 + test-kit/src/jvmMain/kotlin/Platform.kt | 1 - .../gateway/DefaultVoiceGatewayBuilder.kt | 1 - voice/src/main/kotlin/streams/Streams.kt | 3 +- voice/src/main/kotlin/udp/AudioFrameSender.kt | 2 +- .../main/kotlin/udp/AudioPacketProvider.kt | 4 +- 60 files changed, 160 insertions(+), 223 deletions(-) rename common/src/jsMain/kotlin/{http => }/HttpEngine.kt (100%) rename core/src/commonMain/kotlin/builder/{component => components}/ButtonBuilderExtensions.kt (100%) rename core/src/jvmMain/kotlin/{ => dev/kord/core}/builder/kord/KordBuilder.kt (100%) rename core/src/jvmMain/kotlin/{ => dev/kord/core}/cache/KordCacheBuilder.kt (100%) delete mode 100644 rest/src/commonTest/kotlin/Utils.kt rename rest/src/jvmMain/kotlin/{ => dev/kord/rest}/builder/message/create/MessageCreateBuilderJvm.kt (100%) rename rest/src/jvmMain/kotlin/{ => dev/kord/rest}/builder/message/modify/MessageModifyBuilderJvm.kt (100%) rename rest/src/jvmMain/kotlin/{ => dev/kord/rest}/request/RecoveredStackTrace.kt (100%) rename rest/src/jvmMain/kotlin/{ => dev/kord/rest}/request/RequestBuilder.kt (100%) rename samples/src/commonMain/kotlin/{ => dev/kord}/core/PingBot.kt (100%) rename samples/src/commonMain/kotlin/{ => dev/kord}/gateway/GatewayExample.kt (90%) rename samples/src/commonMain/kotlin/{ => dev/kord}/rest/RestExample.kt (100%) diff --git a/common/src/commonMain/kotlin/entity/DiscordComponent.kt b/common/src/commonMain/kotlin/entity/DiscordComponent.kt index 0c12f10a0097..a8d0dc0c625e 100644 --- a/common/src/commonMain/kotlin/entity/DiscordComponent.kt +++ b/common/src/commonMain/kotlin/entity/DiscordComponent.kt @@ -61,7 +61,6 @@ import kotlinx.serialization.json.* * Represent a [interactable component within a message sent in Discord](https://discord.com/developers/docs/interactions/message-components#what-are-components). * * @property type the [ComponentType] of the component - * @property style the [ButtonStyle] of the component (if it is a button) * @property emoji an [DiscordPartialEmoji] that appears on the button (if the component is a button) * @property customId a developer-defined identifier for the button, max 100 characters * @property url a url for link-style buttons diff --git a/common/src/commonMain/kotlin/entity/DiscordUser.kt b/common/src/commonMain/kotlin/entity/DiscordUser.kt index 94a05da66fb8..45c91ff61204 100644 --- a/common/src/commonMain/kotlin/entity/DiscordUser.kt +++ b/common/src/commonMain/kotlin/entity/DiscordUser.kt @@ -138,15 +138,11 @@ public data class UserFlags(val code: Int) { public operator fun contains(flag: UserFlag): Boolean = flag in flags - public operator fun plus(flags: UserFlags): UserFlags = when { - code and flags.code == flags.code -> this - else -> UserFlags(this.code or flags.code) - } + public operator fun plus(flags: UserFlags): UserFlags = + if (code and flags.code == flags.code) this else UserFlags(this.code or flags.code) - public operator fun minus(flag: UserFlag): UserFlags = when { - code and flag.code == flag.code -> UserFlags(code xor flag.code) - else -> this - } + public operator fun minus(flag: UserFlag): UserFlags = + if (code and flag.code == flag.code) UserFlags(code xor flag.code) else this public inline fun copy(block: UserFlagsBuilder.() -> Unit): UserFlags { contract { diff --git a/common/src/commonMain/kotlin/serialization/InstantSerializers.kt b/common/src/commonMain/kotlin/serialization/InstantSerializers.kt index 12fe03a99238..31b1213e8860 100644 --- a/common/src/commonMain/kotlin/serialization/InstantSerializers.kt +++ b/common/src/commonMain/kotlin/serialization/InstantSerializers.kt @@ -2,7 +2,6 @@ package dev.kord.common.serialization import kotlinx.datetime.Instant import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor diff --git a/common/src/jsMain/kotlin/http/HttpEngine.kt b/common/src/jsMain/kotlin/HttpEngine.kt similarity index 100% rename from common/src/jsMain/kotlin/http/HttpEngine.kt rename to common/src/jsMain/kotlin/HttpEngine.kt diff --git a/core/api/core.api b/core/api/core.api index c8c9c6ec08ed..ea4c2c2cd140 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -83,6 +83,7 @@ public final class dev/kord/core/Kord : kotlinx/coroutines/CoroutineScope { public static synthetic fun getWebhookWithToken$default (Ldev/kord/core/Kord;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/supplier/EntitySupplyStrategy;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getWebhookWithTokenOrNull (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/supplier/EntitySupplyStrategy;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun getWebhookWithTokenOrNull$default (Ldev/kord/core/Kord;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;Ldev/kord/core/supplier/EntitySupplyStrategy;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public fun hashCode ()I public final fun login (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun login$default (Ldev/kord/core/Kord;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun logout (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2171,7 +2172,8 @@ public final class dev/kord/core/cache/CachingGateway : dev/kord/cache/api/DataC } public final class dev/kord/core/cache/DataCacheExtensionsKt { - public static final fun createView (Ldev/kord/cache/api/DataCache;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun createView (Ldev/kord/cache/api/DataCache;)Ldev/kord/core/cache/DataCacheView; + public static final synthetic fun createView (Ldev/kord/cache/api/DataCache;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/kord/core/cache/DataCacheView : dev/kord/cache/api/DataCache { @@ -11430,6 +11432,7 @@ public final class dev/kord/core/event/channel/thread/ThreadListSyncEvent : dev/ public synthetic fun (Ldev/kord/core/cache/data/ThreadListSyncData;Ldev/kord/core/Kord;ILjava/lang/Object;Ldev/kord/core/supplier/EntitySupplier;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getChannelBehaviors ()Ljava/util/List; public final fun getChannelIds ()Ljava/util/List; + public final fun getChannels ()Lkotlinx/coroutines/flow/Flow; public final fun getChannels (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getCustomContext ()Ljava/lang/Object; public final fun getData ()Ldev/kord/core/cache/data/ThreadListSyncData; @@ -11602,7 +11605,8 @@ public final class dev/kord/core/event/gateway/ReadyEvent : dev/kord/core/event/ public final fun getGatewayVersion ()I public final fun getGuildIds ()Ljava/util/Set; public final fun getGuilds ()Ljava/util/Set; - public final fun getGuilds (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getGuilds ()Lkotlinx/coroutines/flow/Flow; + public final synthetic fun getGuilds (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getKord ()Ldev/kord/core/Kord; public final fun getResumeGatewayUrl ()Ljava/lang/String; public final fun getSelf ()Ldev/kord/core/entity/User; @@ -13081,7 +13085,7 @@ public abstract class dev/kord/core/live/AbstractLiveKordEntity : dev/kord/core/ public fun compareTo (Ldev/kord/core/entity/Entity;)I public synthetic fun compareTo (Ljava/lang/Object;)I protected abstract fun filter (Ldev/kord/core/event/Event;)Z - public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; + public final fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; public synthetic fun getEvents ()Lkotlinx/coroutines/flow/Flow; public final fun getEvents ()Lkotlinx/coroutines/flow/SharedFlow; public final fun getKord ()Ldev/kord/core/Kord; diff --git a/core/src/commonMain/kotlin/Kord.kt b/core/src/commonMain/kotlin/Kord.kt index 547ef3718d1f..86c6e21f91df 100644 --- a/core/src/commonMain/kotlin/Kord.kt +++ b/core/src/commonMain/kotlin/Kord.kt @@ -373,15 +373,10 @@ public class Kord( gateway.sendAll(status) } - override fun equals(other: Any?): Boolean { - val kord = other as? Kord ?: return false - - return resources.token == kord.resources.token - } - - override fun toString(): String { - return "Kord(resources=$resources, cache=$cache, gateway=$gateway, rest=$rest, selfId=$selfId)" - } + override fun equals(other: Any?): Boolean = other is Kord && this.resources.token == other.resources.token + override fun hashCode(): Int = resources.token.hashCode() + override fun toString(): String = + "Kord(resources=$resources, cache=$cache, gateway=$gateway, rest=$rest, selfId=$selfId)" public companion object { diff --git a/core/src/commonMain/kotlin/Util.kt b/core/src/commonMain/kotlin/Util.kt index 827510177165..ecb5688f0403 100644 --- a/core/src/commonMain/kotlin/Util.kt +++ b/core/src/commonMain/kotlin/Util.kt @@ -1,7 +1,6 @@ package dev.kord.core import dev.kord.common.entity.Snowflake -import dev.kord.core.entity.KordEntity import dev.kord.core.entity.Message import dev.kord.core.entity.channel.thread.ThreadChannel import dev.kord.core.event.Event @@ -173,22 +172,6 @@ internal fun paginateForwards( request, ) -/** - * Selects the [Position.After] the youngest item in the batch. - */ -internal fun paginateForwards( - batchSize: Int, - start: Snowflake = Snowflake.min, - request: suspend (after: Position.After) -> Collection, -): Flow = paginate( - start, - batchSize, - itemSelector = youngestItem { it.id }, - idSelector = { it.id }, - directionSelector = Position::After, - request, -) - /** * Selects the [Position.Before] the oldest item in the batch. */ @@ -206,22 +189,6 @@ internal fun paginateBackwards( request, ) -/** - * Selects the [Position.Before] the oldest item in the batch. - */ -internal fun paginateBackwards( - batchSize: Int, - start: Snowflake = Snowflake.max, - request: suspend (before: Position.Before) -> Collection, -): Flow = paginate( - start, - batchSize, - itemSelector = oldestItem { it.id }, - idSelector = { it.id }, - directionSelector = Position::Before, - request, -) - /** * Paginates the [Collection] returned by [request] with [start] as an initial reference in time. * [instantSelector] is used to select the new reference to fetch from. diff --git a/core/src/commonMain/kotlin/behavior/GuildBehavior.kt b/core/src/commonMain/kotlin/behavior/GuildBehavior.kt index e7899b7ac8c6..2d5c575b0875 100644 --- a/core/src/commonMain/kotlin/behavior/GuildBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/GuildBehavior.kt @@ -91,7 +91,7 @@ public interface GuildBehavior : KordEntity, Strategizable { */ public val cachedThreads: Flow get() = kord.cache - .query { idEq(ChannelData::guildId, this@GuildBehavior.id) } + .query { idEq(ChannelData::guildId, this@GuildBehavior.id) } .asFlow() .mapNotNull { Channel.from(it, kord) as? ThreadChannel } @@ -139,7 +139,7 @@ public interface GuildBehavior : KordEntity, Strategizable { * This property is not resolvable through REST and will always use [Kord.cache] instead. */ public val presences: Flow - get() = kord.cache.query { idEq(PresenceData::guildId, id) } + get() = kord.cache.query { idEq(PresenceData::guildId, id) } .asFlow() .map { Presence(it, kord) } @@ -191,7 +191,7 @@ public interface GuildBehavior : KordEntity, Strategizable { */ public val voiceStates: Flow get() = kord.cache - .query { idEq(VoiceStateData::guildId, id) } + .query { idEq(VoiceStateData::guildId, id) } .asFlow() .map { VoiceState(it, kord) } diff --git a/core/src/commonMain/kotlin/behavior/MemberBehavior.kt b/core/src/commonMain/kotlin/behavior/MemberBehavior.kt index 341825bf4fbe..16d9e5728249 100644 --- a/core/src/commonMain/kotlin/behavior/MemberBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/MemberBehavior.kt @@ -135,7 +135,7 @@ public interface MemberBehavior : KordEntity, UserBehavior { * @throws [RequestException] if anything went wrong during the request. */ public suspend fun getPresenceOrNull(): Presence? { - val data = kord.cache.query { + val data = kord.cache.query { idEq(PresenceData::userId, id) idEq(PresenceData::guildId, guildId) }.singleOrNull() ?: return null @@ -166,7 +166,7 @@ public interface MemberBehavior : KordEntity, UserBehavior { * @throws [RequestException] if anything went wrong during the request. */ public suspend fun getVoiceStateOrNull(): VoiceState? { - val data = kord.cache.query { + val data = kord.cache.query { idEq(VoiceStateData::userId, id) idEq(VoiceStateData::guildId, guildId) }.singleOrNull() ?: return null diff --git a/core/src/commonMain/kotlin/behavior/UserBehavior.kt b/core/src/commonMain/kotlin/behavior/UserBehavior.kt index bc4bfe226e60..2d4e406d8cc8 100644 --- a/core/src/commonMain/kotlin/behavior/UserBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/UserBehavior.kt @@ -128,11 +128,6 @@ public interface UserBehavior : KordEntity, Strategizable { } } - /** - * returns a new [UserBehavior] with the given [strategy]. - * - * @param strategy the strategy to use for the new instance. By default [EntitySupplyStrategy.CacheWithRestFallback]. - */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): UserBehavior = UserBehavior(id, kord, strategy) } diff --git a/core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt index 30c7cc017363..811d3efd2bff 100644 --- a/core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt @@ -20,7 +20,7 @@ public interface BaseVoiceChannelBehavior : CategorizableChannelBehavior { * [terminal operators](https://kotlinlang.org/docs/reference/coroutines/flow.html#terminal-flow-operators) instead. */ public val voiceStates: Flow - get() = kord.cache.query { idEq(VoiceStateData::channelId, id) } + get() = kord.cache.query { idEq(VoiceStateData::channelId, id) } .asFlow() .map { VoiceState(it, kord) } } diff --git a/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt index 42ffd8272b1c..5408d3bffc45 100644 --- a/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt @@ -76,7 +76,7 @@ public interface ChannelBehavior : KordEntity, Strategizable { } /** - * Requests to get the [Channel] represented by the [id], + * Requests to get the [Channel] represented by this [ChannelBehavior], * returns null if the [Channel] isn't present. * * @throws [RequestException] if anything went wrong during the request. @@ -86,7 +86,7 @@ public suspend inline fun ChannelBehavior.asChannelOfOrNull /** - * Requests to get the [Channel] represented by the [id]. + * Requests to get the [Channel] represented by this [ChannelBehavior]. * * @throws [RequestException] if anything went wrong during the request. * @throws [EntityNotFoundException] if the [Channel] wasn't present. diff --git a/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt index 32d1c4e4a693..dfe282de4f0c 100644 --- a/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt @@ -121,8 +121,9 @@ public interface PrivateThreadParentChannelBehavior : ThreadParentChannelBehavio } /** - * starts a thread in the current thread parent based on [type] using given [name] and archived after [archiveDuration]. - * [type] should match the parent types. + * Starts a thread in the current thread parent based on [type] using the given [name]. [type] should match the parent + * types. + * * @throws [RequestException] if something went wrong during the request. */ internal suspend fun ThreadParentChannelBehavior.unsafeStartThread( diff --git a/core/src/commonMain/kotlin/builder/component/ButtonBuilderExtensions.kt b/core/src/commonMain/kotlin/builder/components/ButtonBuilderExtensions.kt similarity index 100% rename from core/src/commonMain/kotlin/builder/component/ButtonBuilderExtensions.kt rename to core/src/commonMain/kotlin/builder/components/ButtonBuilderExtensions.kt diff --git a/core/src/commonMain/kotlin/cache/CachingGateway.kt b/core/src/commonMain/kotlin/cache/CachingGateway.kt index f197bcc575e8..9b7f01b1da66 100644 --- a/core/src/commonMain/kotlin/cache/CachingGateway.kt +++ b/core/src/commonMain/kotlin/cache/CachingGateway.kt @@ -15,7 +15,7 @@ import kotlin.coroutines.CoroutineContext public class CachingGateway( private val cache: DataCache, private val gateway: Gateway, - private val dispatcher: CoroutineDispatcher = Dispatchers.Default + dispatcher: CoroutineDispatcher = Dispatchers.Default ) : DataCache by cache, Gateway by gateway, CoroutineScope { override val coroutineContext: CoroutineContext = SupervisorJob() + dispatcher diff --git a/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt b/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt index ec322be7f50d..cfa661b3c879 100644 --- a/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt +++ b/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt @@ -4,6 +4,8 @@ import dev.kord.cache.api.DataCache import dev.kord.cache.api.query import dev.kord.common.annotation.KordInternal import dev.kord.core.cache.data.* +import kotlin.DeprecationLevel.HIDDEN +import kotlin.jvm.JvmName /** * Registers all Kord data classes for this cache @@ -56,4 +58,9 @@ internal suspend fun DataCache.removeKordData() { * Creates a [DataCacheView] for this view, only removing elements that were added * directly to this instance. */ -public suspend fun DataCache.createView(): DataCacheView = DataCacheView(this) +public fun DataCache.createView(): DataCacheView = DataCacheView(this) + +@Suppress("RedundantSuspendModifier") +@Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN) +@JvmName("createView") +public suspend fun DataCache.createView0(): DataCacheView = createView() diff --git a/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt b/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt index ce5496efb3cb..3a74d2835a86 100644 --- a/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt +++ b/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt @@ -2,7 +2,6 @@ package dev.kord.core.cache.data import dev.kord.cache.api.data.DataDescription import dev.kord.cache.api.data.description -import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.DiscordGuildApplicationCommandPermissions import dev.kord.common.entity.Snowflake diff --git a/core/src/commonMain/kotlin/entity/Guild.kt b/core/src/commonMain/kotlin/entity/Guild.kt index ff63153cb2ed..f939f6aea424 100644 --- a/core/src/commonMain/kotlin/entity/Guild.kt +++ b/core/src/commonMain/kotlin/entity/Guild.kt @@ -15,6 +15,7 @@ import dev.kord.core.behavior.channel.VoiceChannelBehavior import dev.kord.core.cache.data.GuildData import dev.kord.core.entity.channel.* import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.core.supplier.getChannelOfOrNull @@ -24,7 +25,6 @@ import dev.kord.rest.service.RestClient import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.datetime.Instant -import dev.kord.core.hash import kotlin.DeprecationLevel.WARNING import kotlin.time.Duration @@ -374,8 +374,8 @@ public class Guild( } /** - * Requests to get the [TopGuildChannel] represented by the [embedChannel], - * returns null if the [TopGuildChannel] isn't present or [embedChannel] is null. + * Requests to get the [TopGuildChannel] represented by the [widgetChannelId], + * returns null if the [TopGuildChannel] isn't present or [widgetChannelId] is null. * * @throws [RequestException] if anything went wrong during the request. */ diff --git a/core/src/commonMain/kotlin/entity/Member.kt b/core/src/commonMain/kotlin/entity/Member.kt index bad52a245f96..3fd9255a5ac9 100644 --- a/core/src/commonMain/kotlin/entity/Member.kt +++ b/core/src/commonMain/kotlin/entity/Member.kt @@ -30,7 +30,7 @@ public class Member( get() = memberData.guildId /** - * The name as shown in the discord client, prioritizing the [nickname] over the [use]. + * The name as shown in the discord client, prioritizing the [nickname] over the [username]. */ public val displayName: String get() = nickname ?: username diff --git a/core/src/commonMain/kotlin/entity/PermissionOverwrite.kt b/core/src/commonMain/kotlin/entity/PermissionOverwrite.kt index b1bf14057901..da222e8db186 100644 --- a/core/src/commonMain/kotlin/entity/PermissionOverwrite.kt +++ b/core/src/commonMain/kotlin/entity/PermissionOverwrite.kt @@ -1,6 +1,5 @@ package dev.kord.core.entity -import dev.kord.common.entity.Overwrite import dev.kord.common.entity.OverwriteType import dev.kord.common.entity.Permissions import dev.kord.common.entity.Snowflake @@ -17,8 +16,6 @@ public open class PermissionOverwrite( internal fun asRequest() = ChannelPermissionEditRequest(allowed, denied, type) - internal fun toOverwrite() = Overwrite(id = target, type = type, allow = allowed, deny = denied) - override fun hashCode(): Int = target.hashCode() override fun equals(other: Any?): Boolean { val otherOverwrite = other as? PermissionOverwrite ?: return false diff --git a/core/src/commonMain/kotlin/entity/channel/GuildChannel.kt b/core/src/commonMain/kotlin/entity/channel/GuildChannel.kt index 42ba57a7613d..a7c549f7626c 100644 --- a/core/src/commonMain/kotlin/entity/channel/GuildChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/GuildChannel.kt @@ -1,16 +1,7 @@ package dev.kord.core.entity.channel -import dev.kord.common.entity.OverwriteType -import dev.kord.common.entity.Permission -import dev.kord.common.entity.Permissions import dev.kord.common.entity.Snowflake -import dev.kord.common.entity.optional.orEmpty -import dev.kord.common.entity.optional.value -import dev.kord.common.exception.RequestException import dev.kord.core.behavior.channel.GuildChannelBehavior -import dev.kord.core.behavior.channel.TopGuildChannelBehavior -import dev.kord.core.cache.data.PermissionOverwriteData -import dev.kord.core.entity.PermissionOverwriteEntity import dev.kord.core.supplier.EntitySupplyStrategy /** diff --git a/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt b/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt index 31ce9c43de74..4ff86c95a68c 100644 --- a/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt @@ -31,9 +31,7 @@ public class StageChannel( public val userLimit: Int get() = data.userLimit.getOrThrow() /** - * returns a new [StageChannel] with the given [strategy]. - * - * @param strategy the strategy to use for the new instance. By default [EntitySupplyStrategy.CacheWithRestFallback]. + * Returns a new [StageChannel] with the given [strategy]. */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): StageChannel = StageChannel(data, kord, strategy.supply(kord)) diff --git a/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt b/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt index 46db97f0372d..2da87d5b0e44 100644 --- a/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt @@ -10,13 +10,11 @@ import dev.kord.core.behavior.channel.VoiceChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.Region import dev.kord.core.exception.EntityNotFoundException -import dev.kord.core.supplier.getChannelOf -import dev.kord.core.supplier.getChannelOfOrNull +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull -import dev.kord.core.hash /** * An instance of a Discord Voice Channel associated to a guild. diff --git a/core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt b/core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt index e7ab0b01470b..13e191521112 100644 --- a/core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt @@ -5,12 +5,10 @@ import dev.kord.common.entity.Snowflake import dev.kord.common.exception.RequestException import dev.kord.core.Kord import dev.kord.core.behavior.GuildBehavior -import dev.kord.core.behavior.channel.GuildChannelBehavior import dev.kord.core.behavior.channel.threads.ThreadParentChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.Guild import dev.kord.core.entity.Strategizable -import dev.kord.core.entity.channel.GuildChannel import dev.kord.core.entity.channel.ThreadParentChannel import dev.kord.core.exception.EntityNotFoundException import dev.kord.core.supplier.EntitySupplier diff --git a/core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt b/core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt index 999f2e3cda81..32530c79fdf4 100644 --- a/core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt +++ b/core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt @@ -21,7 +21,7 @@ public class NewsChannelThread( override suspend fun asChannel(): NewsChannelThread = this - override suspend fun asChannelOrNull(): NewsChannelThread? = this + override suspend fun asChannelOrNull(): NewsChannelThread = this override suspend fun getParent(): NewsChannel { diff --git a/core/src/commonMain/kotlin/entity/component/ButtonComponent.kt b/core/src/commonMain/kotlin/entity/component/ButtonComponent.kt index 1ea403809011..c19fffa3d5d6 100644 --- a/core/src/commonMain/kotlin/entity/component/ButtonComponent.kt +++ b/core/src/commonMain/kotlin/entity/component/ButtonComponent.kt @@ -5,7 +5,9 @@ import dev.kord.common.entity.ComponentType import dev.kord.common.entity.optional.value import dev.kord.core.cache.data.ChatComponentData import dev.kord.core.entity.ReactionEmoji +import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.core.entity.interaction.ComponentInteraction +import dev.kord.core.event.interaction.InteractionCreateEvent /** * An interactive component rendered on a Message. diff --git a/core/src/commonMain/kotlin/entity/interaction/OptionValue.kt b/core/src/commonMain/kotlin/entity/interaction/OptionValue.kt index 2262fd9f7033..ee6ad945ea2f 100644 --- a/core/src/commonMain/kotlin/entity/interaction/OptionValue.kt +++ b/core/src/commonMain/kotlin/entity/interaction/OptionValue.kt @@ -2,7 +2,6 @@ package dev.kord.core.entity.interaction import dev.kord.common.entity.CommandArgument import dev.kord.common.entity.Snowflake -import dev.kord.core.behavior.interaction.GlobalInteractionBehavior import dev.kord.core.entity.* import dev.kord.core.entity.channel.ResolvedChannel @@ -97,4 +96,3 @@ public fun OptionValue(value: CommandArgument<*>, resolvedObjects: ResolvedObjec } } } - diff --git a/core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt index f511a969439a..92a204fbf089 100644 --- a/core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt +++ b/core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt @@ -4,7 +4,6 @@ import dev.kord.common.entity.optional.orEmpty import dev.kord.common.entity.optional.unwrap import dev.kord.core.Kord import dev.kord.core.cache.data.InteractionData -import dev.kord.core.cache.data.ResolvedObjectsData import dev.kord.core.entity.Guild import dev.kord.core.entity.component.SelectMenuComponent import dev.kord.core.supplier.EntitySupplier diff --git a/core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt index 103e3beac159..cdbfb9eb1647 100644 --- a/core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt +++ b/core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt @@ -65,8 +65,12 @@ public class ThreadListSyncEvent( return supplier.getGuildOrNull(guildId) } + public val channels: Flow get() = supplier.getGuildChannels(guildId).filter { it.id in channelIds } + + @Suppress("RedundantSuspendModifier") + @Deprecated("Replaced by 'channels' property.", ReplaceWith("this.channels"), DeprecationLevel.WARNING) public suspend fun getChannels(): Flow { - return supplier.getGuildChannels(guildId).filter { it.id in channelIds } + return channels } override fun withStrategy(strategy: EntitySupplyStrategy<*>): ThreadListSyncEvent = diff --git a/core/src/commonMain/kotlin/event/gateway/Events.kt b/core/src/commonMain/kotlin/event/gateway/Events.kt index 90d30f156e17..ca51c3418158 100644 --- a/core/src/commonMain/kotlin/event/gateway/Events.kt +++ b/core/src/commonMain/kotlin/event/gateway/Events.kt @@ -14,6 +14,8 @@ import dev.kord.gateway.Gateway import dev.kord.gateway.GatewayCloseCode import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter +import kotlin.DeprecationLevel.HIDDEN +import kotlin.jvm.JvmName public sealed class GatewayEvent : Event @@ -151,7 +153,12 @@ public class ReadyEvent( public val guilds: Set get() = guildIds.map { GuildBehavior(it, kord) }.toSet() - public suspend fun getGuilds(): Flow = supplier.guilds.filter { it.id in guildIds } + public fun getGuilds(): Flow = supplier.guilds.filter { it.id in guildIds } + + @Suppress("RedundantSuspendModifier") + @Deprecated("Binary compatibility, keep for some releases.", level = HIDDEN) + @JvmName("getGuilds") + public suspend fun getGuilds0(): Flow = getGuilds() override fun withStrategy(strategy: EntitySupplyStrategy<*>): ReadyEvent = ReadyEvent(gatewayVersion, guildIds, self, sessionId, resumeGatewayUrl, kord, shard, customContext, strategy.supply(kord)) diff --git a/core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt index 1b742762f725..37d2b3f9c4a4 100644 --- a/core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt @@ -52,7 +52,7 @@ internal class ChannelEventHandler : BaseGatewayEventHandler() { private suspend fun handle(event: ChannelUpdate, shard: Int, kord: Kord, context: LazyContext?): ChannelUpdateEvent? { val data = ChannelData.from(event.channel) - val oldData = kord.cache.query { idEq(ChannelData::id, data.id) }.singleOrNull() + val oldData = kord.cache.query { idEq(ChannelData::id, data.id) }.singleOrNull() kord.cache.put(data) val old = oldData?.let { Channel.from(it, kord) } val coreEvent = when (val channel = Channel.from(data, kord)) { @@ -72,7 +72,7 @@ internal class ChannelEventHandler : BaseGatewayEventHandler() { } private suspend fun handle(event: ChannelDelete, shard: Int, kord: Kord, context: LazyContext?): ChannelDeleteEvent? { - kord.cache.remove { idEq(ChannelData::id, event.channel.id) } + kord.cache.remove { idEq(ChannelData::id, event.channel.id) } val data = ChannelData.from(event.channel) val coreEvent = when (val channel = Channel.from(data, kord)) { @@ -104,7 +104,7 @@ internal class ChannelEventHandler : BaseGatewayEventHandler() { context?.get(), ) - kord.cache.query { idEq(ChannelData::id, channelId) }.update { + kord.cache.query { idEq(ChannelData::id, channelId) }.update { it.copy(lastPinTimestamp = lastPinTimestamp) } diff --git a/core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt index 9da19e3ccd9e..9b405beedfb9 100644 --- a/core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt @@ -116,7 +116,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { context: LazyContext?, ): GuildUpdateEvent { val data = GuildData.from(event.guild) - val old = kord.cache.query { idEq(GuildData::id, event.guild.id) }.singleOrNull() + val old = kord.cache.query { idEq(GuildData::id, event.guild.id) }.singleOrNull() kord.cache.put(data) event.guild.cache(kord.cache) @@ -129,7 +129,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { kord: Kord, context: LazyContext?, ): GuildDeleteEvent = with(event.guild) { - val query = kord.cache.query { idEq(GuildData::id, id) } + val query = kord.cache.query { idEq(GuildData::id, id) } val old = query.asFlow().map { Guild(it, kord) }.singleOrNull() query.remove() @@ -173,14 +173,14 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { with(event.emoji) { val data = emojis.map { EmojiData.from(guildId, it.id!!, it) } - val old = kord.cache.query { idEq(EmojiData::guildId, guildId) }.asFlow().map { + val old = kord.cache.query { idEq(EmojiData::guildId, guildId) }.asFlow().map { GuildEmoji(it, kord) }.toSet() kord.cache.putAll(data) val emojis = data.map { GuildEmoji(it, kord) } - kord.cache.query { idEq(GuildData::id, guildId) }.update { + kord.cache.query { idEq(GuildData::id, guildId) }.update { it.copy(emojis = emojis.map { emoji -> emoji.id }) } @@ -254,12 +254,12 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { with(event.member) { val userData = UserData.from(user) - val oldData = kord.cache.query { + val oldData = kord.cache.query { idEq(MemberData::userId, userData.id) idEq(MemberData::guildId, guildId) }.singleOrNull() - kord.cache.query { idEq(UserData::id, userData.id) }.remove() + kord.cache.query { idEq(UserData::id, userData.id) }.remove() val user = User(userData, kord) val old = oldData?.let { Member(it, userData, kord) } @@ -277,7 +277,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { val userData = UserData.from(user) kord.cache.put(userData) - val query = kord.cache.query { + val query = kord.cache.query { idEq(MemberData::userId, userData.id) idEq(MemberData::guildId, guildId) } @@ -309,7 +309,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { ): RoleUpdateEvent { val data = RoleData.from(event.role) - val oldData = kord.cache.query { + val oldData = kord.cache.query { idEq(RoleData::id, data.id) idEq(RoleData::guildId, data.guildId) // TODO("Is this worth keeping?") }.singleOrNull() @@ -326,7 +326,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { kord: Kord, context: LazyContext?, ): RoleDeleteEvent = with(event.role) { - val query = kord.cache.query { idEq(RoleData::id, event.role.id) } + val query = kord.cache.query { idEq(RoleData::id, event.role.id) } val old = run { val data = query.singleOrNull() ?: return@run null @@ -377,7 +377,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { context: LazyContext?, ): GuildScheduledEventUpdateEvent { val eventData = GuildScheduledEventData.from(event.event) - val oldData = kord.cache.query { + val oldData = kord.cache.query { idEq(GuildScheduledEventData::id, event.event.id) }.singleOrNull() val old = oldData?.let { GuildScheduledEvent(it, kord) } @@ -393,7 +393,7 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { kord: Kord, context: LazyContext?, ): GuildScheduledEventDeleteEvent { - val query = kord.cache.query { + val query = kord.cache.query { idEq(GuildScheduledEvent::id, event.event.id) } query.remove() @@ -445,14 +445,14 @@ internal class GuildEventHandler : BaseGatewayEventHandler() { with(event.presence) { val data = PresenceData.from(this.guildId.value!!, this) - val old = kord.cache.query { idEq(PresenceData::id, data.id) } + val old = kord.cache.query { idEq(PresenceData::id, data.id) } .asFlow().map { Presence(it, kord) }.singleOrNull() kord.cache.put(data) val new = Presence(data, kord) val user = kord.cache - .query { idEq(UserData::id, event.presence.user.id) } + .query { idEq(UserData::id, event.presence.user.id) } .singleOrNull() ?.let { User(it, kord) } diff --git a/core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt index afc3184ca4d8..b7aa5650640b 100644 --- a/core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt @@ -96,7 +96,7 @@ internal class InteractionEventHandler : BaseGatewayEventHandler() { context: LazyContext?, ): ApplicationCommandDeleteEvent { val data = ApplicationCommandData.from(event.application) - kord.cache.remove { idEq(ApplicationCommandData::id, data.id) } + kord.cache.remove { idEq(ApplicationCommandData::id, data.id) } val coreEvent = when (val application = GuildApplicationCommand(data, kord.rest.interaction)) { is GuildChatInputCommand -> ChatInputCommandDeleteEvent(application, kord, shard, context?.get()) is GuildMessageCommand -> MessageCommandDeleteEvent(application, kord, shard, context?.get()) diff --git a/core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt index 372b99a5bc6f..c714a4f92553 100644 --- a/core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt @@ -43,7 +43,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { val data = MessageData.from(this) kord.cache.put(data) - kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> + kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> channel.copy( lastMessageId = data.id.optionalSnowflake(), messageCount = channel.messageCount.map { it + 1 }, @@ -72,8 +72,8 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { mentions.forEach { val user = UserData.from(it) kord.cache.put(user) - it.member.value?.let { - kord.cache.put(MemberData.from(userId = user.id, guildId = guildId.value!!, it)) + it.member.value?.let { member -> + kord.cache.put(MemberData.from(userId = user.id, guildId = guildId.value!!, member)) } } @@ -86,7 +86,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { kord: Kord, context: LazyContext?, ): MessageUpdateEvent = with(event.message) { - val query = kord.cache.query { idEq(MessageData::id, id) } + val query = kord.cache.query { idEq(MessageData::id, id) } val old = query.asFlow().map { Message(it, kord) }.singleOrNull() query.update { it + this } @@ -94,8 +94,8 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { mentions.orEmpty().forEach { val user = UserData.from(it) kord.cache.put(user) - it.member.value?.let { - kord.cache.put(MemberData.from(userId = user.id, guildId = guildId.value!!, it)) + it.member.value?.let { member -> + kord.cache.put(MemberData.from(userId = user.id, guildId = guildId.value!!, member)) } } @@ -108,12 +108,12 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { kord: Kord, context: LazyContext?, ): MessageDeleteEvent = with(event.message) { - val query = kord.cache.query { idEq(MessageData::id, id) } + val query = kord.cache.query { idEq(MessageData::id, id) } val removed = query.singleOrNull()?.let { Message(it, kord) } query.remove() - kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> + kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> channel.copy(messageCount = channel.messageCount.map { it - 1 }) } @@ -129,12 +129,12 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { with(event.messageBulk) { val ids = ids.toSet() - val query = kord.cache.query { MessageData::id `in` ids } + val query = kord.cache.query { MessageData::id `in` ids } val removed = query.asFlow().map { Message(it, kord) }.toSet() query.remove() - kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> + kord.cache.query { idEq(ChannelData::id, channelId) }.update { channel -> channel.copy(messageCount = channel.messageCount.map { it - ids.size }) } @@ -165,7 +165,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { else -> ReactionEmoji.Custom(id, emoji.name!!, emoji.animated.orElse(false)) } - kord.cache.query { idEq(MessageData::id, messageId) }.update { + kord.cache.query { idEq(MessageData::id, messageId) }.update { val isMe = kord.selfId == event.reaction.userId val reactions = if (it.reactions.value.isNullOrEmpty()) { @@ -217,7 +217,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { else -> ReactionEmoji.Custom(id, emoji.name ?: "", emoji.animated.orElse(false)) } - kord.cache.query { idEq(MessageData::id, messageId) }.update { + kord.cache.query { idEq(MessageData::id, messageId) }.update { val oldReactions = it.reactions.value ?: return@update it if (oldReactions.isEmpty()) return@update it @@ -258,7 +258,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { context: LazyContext?, ): ReactionRemoveAllEvent = with(event.reactions) { - kord.cache.query { idEq(MessageData::id, messageId) } + kord.cache.query { idEq(MessageData::id, messageId) } .update { it.copy(reactions = Optional.Missing()) } ReactionRemoveAllEvent( @@ -278,7 +278,7 @@ internal class MessageEventHandler : BaseGatewayEventHandler() { context: LazyContext?, ): ReactionRemoveEmojiEvent = with(event.reaction) { - kord.cache.query { idEq(MessageData::id, messageId) } + kord.cache.query { idEq(MessageData::id, messageId) } .update { it.copy(reactions = it.reactions.map { list -> list.filter { data -> data.emojiName != emoji.name } }) } val data = ReactionRemoveEmojiData.from(this) diff --git a/core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt index 38a257f66d16..08ffcb061ef1 100644 --- a/core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt @@ -38,7 +38,7 @@ internal class ThreadEventHandler : BaseGatewayEventHandler() { // update lastMessageId for forum channels when thread is created // (same for other channels when message is created) val parentId = channelData.parentId?.value!! - kord.cache.query { + kord.cache.query { ChannelData::type eq ChannelType.GuildForum idEq(ChannelData::id, parentId) }.update { @@ -56,7 +56,7 @@ internal class ThreadEventHandler : BaseGatewayEventHandler() { private suspend fun handle(event: ThreadUpdate, shard: Int, kord: Kord, context: LazyContext?): ThreadUpdateEvent? { val channelData = event.channel.toData() - val oldData = kord.cache.query { + val oldData = kord.cache.query { idEq(ChannelData::id, event.channel.id) idEq(ChannelData::guildId, event.channel.guildId.value) }.singleOrNull() @@ -78,7 +78,7 @@ internal class ThreadEventHandler : BaseGatewayEventHandler() { private suspend fun handle(event: ThreadDelete, shard: Int, kord: Kord, context: LazyContext?): ThreadChannelDeleteEvent { val channelData = event.channel.toData() - val cachedData = kord.cache.query { idEq(ChannelData::id, channelData.id) }.singleOrNull() + val cachedData = kord.cache.query { idEq(ChannelData::id, channelData.id) }.singleOrNull() val channel = DeletedThreadChannel(channelData, kord) val old = cachedData?.let { Channel.from(cachedData, kord) } @@ -94,7 +94,7 @@ internal class ThreadEventHandler : BaseGatewayEventHandler() { else -> UnknownChannelThreadDeleteEvent(channel, old as? ThreadChannel, shard, context?.get()) } - kord.cache.remove { idEq(ChannelData::id, channel.id) } + kord.cache.remove { idEq(ChannelData::id, channel.id) } return coreEvent } @@ -120,7 +120,7 @@ internal class ThreadEventHandler : BaseGatewayEventHandler() { private suspend fun handle(event: ThreadMembersUpdate, shard: Int, kord: Kord, context: LazyContext?): ThreadMembersUpdateEvent { val data = ThreadMembersUpdateEventData.from(event) for (removedMemberId in data.removedMemberIds.orEmpty()) { - kord.cache.remove { + kord.cache.remove { idEq(ThreadMemberData::userId, removedMemberId) idEq(ThreadMemberData::id, data.id) } diff --git a/core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt index a4b459d74053..fe9fb3997ff6 100644 --- a/core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt @@ -23,7 +23,7 @@ internal class UserEventHandler : BaseGatewayEventHandler() { private suspend fun handle(event: UserUpdate, shard: Int, kord: Kord, context: LazyContext?): UserUpdateEvent { val data = UserData.from(event.user) - val old = kord.cache.query { idEq(UserData::id, data.id) } + val old = kord.cache.query { idEq(UserData::id, data.id) } .asFlow().map { User(it, kord) }.singleOrNull() kord.cache.put(data) diff --git a/core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt index 3847a9a177ee..621fe0053861 100644 --- a/core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt +++ b/core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt @@ -33,7 +33,7 @@ internal class VoiceEventHandler : BaseGatewayEventHandler() { ): VoiceStateUpdateEvent { val data = VoiceStateData.from(event.voiceState.guildId.value!!, event.voiceState) - val old = kord.cache.query { idEq(VoiceStateData::id, data.id) } + val old = kord.cache.query { idEq(VoiceStateData::id, data.id) } .asFlow().map { VoiceState(it, kord) }.singleOrNull() kord.cache.put(data) diff --git a/core/src/commonMain/kotlin/live/LiveKordEntity.kt b/core/src/commonMain/kotlin/live/LiveKordEntity.kt index 26cf795595b9..93e99ef7dd5b 100644 --- a/core/src/commonMain/kotlin/live/LiveKordEntity.kt +++ b/core/src/commonMain/kotlin/live/LiveKordEntity.kt @@ -10,6 +10,7 @@ import dev.kord.core.kordLogger import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.* +import kotlin.coroutines.CoroutineContext /** * A Discord entity that only emits events *related* to this entity. @@ -27,9 +28,12 @@ public interface LiveKordEntity : KordEntity, CoroutineScope { @KordPreview public abstract class AbstractLiveKordEntity( final override val kord: Kord, - coroutineScope: CoroutineScope = kord + SupervisorJob(kord.coroutineContext.job) -) : LiveKordEntity, CoroutineScope by coroutineScope { + private val coroutineScope: CoroutineScope = kord + SupervisorJob(kord.coroutineContext.job) +) : LiveKordEntity, CoroutineScope { + final override val coroutineContext: CoroutineContext + get() = coroutineScope.coroutineContext + @Suppress("LeakingThis") // only used as CoroutineScope; coroutineContext can not be overridden in subclasses final override val events: SharedFlow = kord.events.filter { filter(it) }.onEach { update(it) }.shareIn(this, SharingStarted.Eagerly) diff --git a/core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt b/core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt index 1cb1c886cb21..6f782fd40cce 100644 --- a/core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt +++ b/core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt @@ -94,18 +94,18 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { public val members: Flow get() = cache.query().asFlow().mapNotNull { val userData = - cache.query { idEq(UserData::id, it.userId) }.singleOrNull() ?: return@mapNotNull null + cache.query { idEq(UserData::id, it.userId) }.singleOrNull() ?: return@mapNotNull null Member(it, userData, kord) } public suspend fun getRole(id: Snowflake): Role? { - val data = cache.query { idEq(RoleData::id, id) }.singleOrNull() ?: return null + val data = cache.query { idEq(RoleData::id, id) }.singleOrNull() ?: return null return Role(data, kord) } override suspend fun getGuildPreviewOrNull(guildId: Snowflake): GuildPreview? { - val data = cache.query { idEq(GuildPreviewData::id, guildId) }.singleOrNull() ?: return null + val data = cache.query { idEq(GuildPreviewData::id, guildId) }.singleOrNull() ?: return null return GuildPreview(data, kord) } @@ -113,28 +113,28 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override suspend fun getGuildWidgetOrNull(guildId: Snowflake): GuildWidget? = null override suspend fun getChannelOrNull(id: Snowflake): Channel? { - val data = cache.query { idEq(ChannelData::id, id) }.singleOrNull() ?: return null + val data = cache.query { idEq(ChannelData::id, id) }.singleOrNull() ?: return null return Channel.from(data, kord) } - override fun getGuildChannels(guildId: Snowflake): Flow = cache.query { + override fun getGuildChannels(guildId: Snowflake): Flow = cache.query { idEq(ChannelData::guildId, guildId) }.asFlow().map { Channel.from(it, kord) }.filterIsInstance() - override fun getChannelPins(channelId: Snowflake): Flow = cache.query { + override fun getChannelPins(channelId: Snowflake): Flow = cache.query { idEq(MessageData::channelId, channelId) idEq(MessageData::pinned, true) }.asFlow().map { Message(it, kord) } override suspend fun getGuildOrNull(id: Snowflake): Guild? { - val data = cache.query { idEq(GuildData::id, id) }.singleOrNull() ?: return null + val data = cache.query { idEq(GuildData::id, id) }.singleOrNull() ?: return null return Guild(data, kord) } override suspend fun getMemberOrNull(guildId: Snowflake, userId: Snowflake): Member? { - val userData = cache.query { idEq(UserData::id, userId) }.singleOrNull() ?: return null + val userData = cache.query { idEq(UserData::id, userId) }.singleOrNull() ?: return null - val memberData = cache.query { + val memberData = cache.query { idEq(MemberData::userId, userId) idEq(MemberData::guildId, guildId) }.singleOrNull() ?: return null @@ -143,7 +143,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { } override suspend fun getMessageOrNull(channelId: Snowflake, messageId: Snowflake): Message? { - val data = cache.query { idEq(MessageData::id, messageId) }.singleOrNull() + val data = cache.query { idEq(MessageData::id, messageId) }.singleOrNull() ?: return null return Message(data, kord) @@ -151,7 +151,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override fun getMessagesAfter(messageId: Snowflake, channelId: Snowflake, limit: Int?): Flow { checkLimit(limit) - return cache.query { + return cache.query { idEq(MessageData::channelId, channelId) idGt(MessageData::id, messageId) }.asFlow().map { Message(it, kord) }.limit(limit) @@ -159,7 +159,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override fun getMessagesBefore(messageId: Snowflake, channelId: Snowflake, limit: Int?): Flow { checkLimit(limit) - return cache.query { + return cache.query { idEq(MessageData::channelId, channelId) idLt(MessageData::id, messageId) }.asFlow().map { Message(it, kord) }.limit(limit) @@ -178,7 +178,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override suspend fun getSelfOrNull(): User? = getUserOrNull(kord.selfId) override suspend fun getRoleOrNull(guildId: Snowflake, roleId: Snowflake): Role? { - val data = cache.query { + val data = cache.query { idEq(RoleData::id, roleId) idEq(RoleData::guildId, guildId) }.singleOrNull() ?: return null @@ -186,12 +186,12 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { return Role(data, kord) } - override fun getGuildRoles(guildId: Snowflake): Flow = cache.query { + override fun getGuildRoles(guildId: Snowflake): Flow = cache.query { idEq(RoleData::guildId, guildId) }.asFlow().map { Role(it, kord) } override suspend fun getGuildBanOrNull(guildId: Snowflake, userId: Snowflake): Ban? { - val data = cache.query { + val data = cache.query { idEq(BanData::userId, userId) idEq(BanData::guildId, guildId) }.singleOrNull() ?: return null @@ -200,7 +200,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override fun getGuildBans(guildId: Snowflake, limit: Int?): Flow { checkLimit(limit) - return cache.query { idEq(BanData::guildId, guildId) } + return cache.query { idEq(BanData::guildId, guildId) } .asFlow() .map { Ban(it, kord) } .limit(limit) @@ -208,21 +208,21 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow { checkLimit(limit) - return cache.query { idEq(MemberData::guildId, guildId) } + return cache.query { idEq(MemberData::guildId, guildId) } .asFlow() .mapNotNull { memberData -> - val userData = cache.query { idEq(UserData::id, memberData.userId) }.singleOrNull() + val userData = cache.query { idEq(UserData::id, memberData.userId) }.singleOrNull() userData?.let { Member(memberData, userData = it, kord) } } .limit(limit) } - override fun getGuildVoiceRegions(guildId: Snowflake): Flow = cache.query { + override fun getGuildVoiceRegions(guildId: Snowflake): Flow = cache.query { idEq(RegionData::guildId, guildId) }.asFlow().map { Region(it, kord) } override suspend fun getEmojiOrNull(guildId: Snowflake, emojiId: Snowflake): GuildEmoji? { - val data = cache.query { + val data = cache.query { idEq(EmojiData::guildId, guildId) idEq(EmojiData::id, emojiId) }.singleOrNull() ?: return null @@ -230,7 +230,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { return GuildEmoji(data, kord) } - override fun getEmojis(guildId: Snowflake): Flow = cache.query { + override fun getEmojis(guildId: Snowflake): Flow = cache.query { idEq(EmojiData::guildId, guildId) }.asFlow().map { GuildEmoji(it, kord) } @@ -241,16 +241,16 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { }.limit(limit) } - override fun getChannelWebhooks(channelId: Snowflake): Flow = cache.query { + override fun getChannelWebhooks(channelId: Snowflake): Flow = cache.query { idEq(WebhookData::channelId, channelId) }.asFlow().map { Webhook(it, kord) } - override fun getGuildWebhooks(guildId: Snowflake): Flow = cache.query { + override fun getGuildWebhooks(guildId: Snowflake): Flow = cache.query { idEq(WebhookData::guildId, guildId) }.asFlow().map { Webhook(it, kord) } override suspend fun getWebhookOrNull(id: Snowflake): Webhook? { - val data = cache.query { + val data = cache.query { idEq(WebhookData::id, id) }.singleOrNull() ?: return null @@ -258,7 +258,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { } override suspend fun getWebhookWithTokenOrNull(id: Snowflake, token: String): Webhook? { - val data = cache.query { + val data = cache.query { idEq(WebhookData::id, id) idEq(WebhookData::token, token) }.singleOrNull() ?: return null @@ -272,7 +272,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { messageId: Snowflake, threadId: Snowflake?, ): Message? { - val data = cache.query { + val data = cache.query { idEq(MessageData::webhookId, webhookId) idEq(MessageData::id, messageId) if (threadId != null) idEq(MessageData::channelId, threadId) @@ -282,13 +282,13 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { } override suspend fun getUserOrNull(id: Snowflake): User? { - val data = cache.query { idEq(UserData::id, id) }.singleOrNull() ?: return null + val data = cache.query { idEq(UserData::id, id) }.singleOrNull() ?: return null return User(data, kord) } override suspend fun getTemplateOrNull(code: String): Template? { - val data = cache.query { + val data = cache.query { idEq(TemplateData::code, code) }.singleOrNull() ?: return null @@ -296,7 +296,7 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { } override fun getTemplates(guildId: Snowflake): Flow