diff --git a/CHANGELOG.md b/CHANGELOG.md index bdd3b3afb30..ff1fbc69857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# 0.7.1 + +## Breaking + +* `BaseInteractionResponseBuilder` +* `BaseInteractionResponseBuilder` +* `BaseInteractionResponseModifyBuilder` +* `EphemeralInteractionResponseModifyBuilder` +* `PublicInteractionResponseModifyBuilder` +* `MessageModifyBuilder` +* `EditWebhookMessageBuilder` +* `InteractionResponseModifyRequest` + +## Changes + +* Message-related builders have been changed to accept `null` (for non-collections) and "empty list" (for collections) +when editing a message. This makes it possible to remove fields from a message without providing a substitution. + # 0.7.0 ## Additions diff --git a/rest/api/rest.api b/rest/api/rest.api index e3175214684..46f00d8e9ac 100644 --- a/rest/api/rest.api +++ b/rest/api/rest.api @@ -663,9 +663,15 @@ public abstract interface class dev/kord/rest/builder/interaction/BaseInteractio } public abstract interface class dev/kord/rest/builder/interaction/BaseInteractionResponseCreateBuilder : dev/kord/rest/builder/interaction/BaseInteractionResponseBuilder { + public abstract fun getComponents ()Ljava/util/List; + public abstract fun getEmbeds ()Ljava/util/List; } public abstract interface class dev/kord/rest/builder/interaction/BaseInteractionResponseModifyBuilder : dev/kord/rest/builder/interaction/BaseInteractionResponseBuilder { + public abstract fun getComponents ()Ljava/util/List; + public abstract fun getEmbeds ()Ljava/util/List; + public abstract fun setComponents (Ljava/util/List;)V + public abstract fun setEmbeds (Ljava/util/List;)V } public final class dev/kord/rest/builder/interaction/BaseKt { @@ -730,7 +736,9 @@ public final class dev/kord/rest/builder/interaction/EphemeralInteractionRespons public fun getContent ()Ljava/lang/String; public fun getEmbeds ()Ljava/util/List; public fun setAllowedMentions (Ldev/kord/rest/builder/message/AllowedMentionsBuilder;)V + public fun setComponents (Ljava/util/List;)V public fun setContent (Ljava/lang/String;)V + public fun setEmbeds (Ljava/util/List;)V public fun toRequest ()Ldev/kord/rest/json/request/MultipartInteractionResponseModifyRequest; public synthetic fun toRequest ()Ljava/lang/Object; } @@ -839,7 +847,9 @@ public final class dev/kord/rest/builder/interaction/PublicInteractionResponseMo public fun getEmbeds ()Ljava/util/List; public final fun getFiles ()Ljava/util/List; public fun setAllowedMentions (Ldev/kord/rest/builder/message/AllowedMentionsBuilder;)V + public fun setComponents (Ljava/util/List;)V public fun setContent (Ljava/lang/String;)V + public fun setEmbeds (Ljava/util/List;)V public fun toRequest ()Ldev/kord/rest/json/request/MultipartInteractionResponseModifyRequest; public synthetic fun toRequest ()Ljava/lang/Object; } @@ -1088,6 +1098,7 @@ public final class dev/kord/rest/builder/message/MessageModifyBuilder : dev/kord public final fun getEmbed ()Ldev/kord/rest/builder/message/EmbedBuilder; public final fun getFlags ()Ldev/kord/common/entity/MessageFlags; public final fun setAllowedMentions (Ldev/kord/rest/builder/message/AllowedMentionsBuilder;)V + public final fun setComponents (Ljava/util/List;)V public final fun setContent (Ljava/lang/String;)V public final fun setEmbed (Ldev/kord/rest/builder/message/EmbedBuilder;)V public final fun setFlags (Ldev/kord/common/entity/MessageFlags;)V @@ -1201,6 +1212,7 @@ public final class dev/kord/rest/builder/webhook/EditWebhookMessageBuilder : dev public final fun getEmbeds ()Ljava/util/List; public final fun getFiles ()Ljava/util/List; public final fun setAllowedMentions (Ldev/kord/common/entity/AllowedMentions;)V + public final fun setComponents (Ljava/util/List;)V public final fun setContent (Ljava/lang/String;)V public final fun setEmbeds (Ljava/util/List;)V public fun toRequest ()Ldev/kord/rest/json/request/MultipartWebhookEditMessageRequest; @@ -2892,21 +2904,21 @@ public final class dev/kord/rest/json/request/InteractionResponseCreateRequest$C public final class dev/kord/rest/json/request/InteractionResponseModifyRequest { public static final field Companion Ldev/kord/rest/json/request/InteractionResponseModifyRequest$Companion; public fun ()V - public synthetic fun (ILdev/kord/common/entity/optional/Optional;Ljava/util/List;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ldev/kord/common/entity/optional/Optional;Ljava/util/List;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;)V - public synthetic fun (Ldev/kord/common/entity/optional/Optional;Ljava/util/List;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (ILdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public fun (Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;)V + public synthetic fun (Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ldev/kord/common/entity/optional/Optional; - public final fun component2 ()Ljava/util/List; + public final fun component2 ()Ldev/kord/common/entity/optional/Optional; public final fun component3 ()Ldev/kord/common/entity/optional/Optional; public final fun component4 ()Ldev/kord/common/entity/optional/Optional; public final fun component5 ()Ldev/kord/common/entity/optional/Optional; - public final fun copy (Ldev/kord/common/entity/optional/Optional;Ljava/util/List;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;)Ldev/kord/rest/json/request/InteractionResponseModifyRequest; - public static synthetic fun copy$default (Ldev/kord/rest/json/request/InteractionResponseModifyRequest;Ldev/kord/common/entity/optional/Optional;Ljava/util/List;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILjava/lang/Object;)Ldev/kord/rest/json/request/InteractionResponseModifyRequest; + public final fun copy (Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;)Ldev/kord/rest/json/request/InteractionResponseModifyRequest; + public static synthetic fun copy$default (Ldev/kord/rest/json/request/InteractionResponseModifyRequest;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILjava/lang/Object;)Ldev/kord/rest/json/request/InteractionResponseModifyRequest; public fun equals (Ljava/lang/Object;)Z public final fun getAllowedMentions ()Ldev/kord/common/entity/optional/Optional; public final fun getComponents ()Ldev/kord/common/entity/optional/Optional; public final fun getContent ()Ldev/kord/common/entity/optional/Optional; - public final fun getEmbeds ()Ljava/util/List; + public final fun getEmbeds ()Ldev/kord/common/entity/optional/Optional; public final fun getFlags ()Ldev/kord/common/entity/optional/Optional; public fun hashCode ()I public fun toString ()Ljava/lang/String; diff --git a/rest/src/main/kotlin/builder/interaction/Base.kt b/rest/src/main/kotlin/builder/interaction/Base.kt index 803dc20a001..c55cf68c181 100644 --- a/rest/src/main/kotlin/builder/interaction/Base.kt +++ b/rest/src/main/kotlin/builder/interaction/Base.kt @@ -16,19 +16,30 @@ sealed interface BaseInteractionResponseBuilder : RequestBuilder { var content: String? - val embeds: MutableList + val embeds: MutableList? - val components: MutableList + val components: MutableList? var allowedMentions: AllowedMentionsBuilder? } -@OptIn(ExperimentalContracts::class) +@KordPreview +@OptIn(ExperimentalContracts::class, KordPreview::class) inline fun BaseInteractionResponseBuilder.embed(builder: EmbedBuilder.() -> Unit) { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - embeds += EmbedBuilder().apply(builder) + + when(this){ + is BaseInteractionResponseCreateBuilder -> { + embeds.add(EmbedBuilder().apply(builder)) + } + is BaseInteractionResponseModifyBuilder -> { + embeds = (embeds ?: mutableListOf()).also { + it.add(EmbedBuilder().apply(builder)) + } + } + } } /** @@ -36,6 +47,7 @@ inline fun BaseInteractionResponseBuilder.embed(builder: EmbedBuilder.() * (ping everything), calling this function but not configuring it before the request is build will result in all * pings being ignored. */ +@KordPreview @OptIn(ExperimentalContracts::class) inline fun BaseInteractionResponseBuilder.allowedMentions(block: AllowedMentionsBuilder.() -> Unit = {}) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } @@ -51,14 +63,36 @@ inline fun BaseInteractionResponseBuilder.actionRow(builder: ActionRowBui callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - components.add(ActionRowBuilder().apply(builder)) + when (this) { + is BaseInteractionResponseCreateBuilder -> { + components.add(ActionRowBuilder().apply(builder)) + } + is BaseInteractionResponseModifyBuilder -> { + components = (components ?: mutableListOf()).also { + it.add(ActionRowBuilder().apply(builder)) + } + } + } + } @KordPreview interface BaseInteractionResponseCreateBuilder : - BaseInteractionResponseBuilder + BaseInteractionResponseBuilder { + + override val components: MutableList + + override val embeds: MutableList + +} @KordPreview interface BaseInteractionResponseModifyBuilder : - BaseInteractionResponseBuilder + BaseInteractionResponseBuilder { + + override var components: MutableList? + + override var embeds: MutableList? + +} diff --git a/rest/src/main/kotlin/builder/interaction/EphemeralInteractionBuilders.kt b/rest/src/main/kotlin/builder/interaction/EphemeralInteractionBuilders.kt index d89704019ff..18dd346cd3b 100644 --- a/rest/src/main/kotlin/builder/interaction/EphemeralInteractionBuilders.kt +++ b/rest/src/main/kotlin/builder/interaction/EphemeralInteractionBuilders.kt @@ -5,40 +5,36 @@ import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.InteractionResponseType import dev.kord.common.entity.MessageFlag import dev.kord.common.entity.MessageFlags -import dev.kord.common.entity.optional.Optional +import dev.kord.common.entity.optional.* import dev.kord.common.entity.optional.delegate.delegate -import dev.kord.common.entity.optional.map -import dev.kord.common.entity.optional.optional -import dev.kord.rest.builder.component.ActionRowBuilder import dev.kord.rest.builder.component.ComponentBuilder import dev.kord.rest.builder.component.MessageComponentBuilder import dev.kord.rest.builder.message.AllowedMentionsBuilder import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.json.request.* -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract @KordDsl @KordPreview class EphemeralInteractionResponseModifyBuilder : BaseInteractionResponseModifyBuilder { - private var _content: Optional = Optional.Missing() + private var _content: Optional = Optional.Missing() override var content: String? by ::_content.delegate() - override val embeds: MutableList = mutableListOf() + private var _embeds: Optional> = Optional.Missing() + override var embeds: MutableList? by ::_embeds.delegate() - private var _allowedMentions: Optional = Optional.Missing() + private var _allowedMentions: Optional = Optional.Missing() override var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate() - override val components: MutableList = mutableListOf() + private var _components: Optional> = Optional.Missing() + override var components: MutableList? by ::_components.delegate() override fun toRequest(): MultipartInteractionResponseModifyRequest { return MultipartInteractionResponseModifyRequest( InteractionResponseModifyRequest( content = _content, allowedMentions = _allowedMentions.map { it.build() }, - components = Optional.missingOnEmpty(components.map { it.build() }), - embeds = embeds.map { it.toRequest() } + components = _components.mapList { it.build() }, + embeds = _embeds.mapList { it.toRequest() }, ) ) } diff --git a/rest/src/main/kotlin/builder/interaction/PublicInteractionBuilder.kt b/rest/src/main/kotlin/builder/interaction/PublicInteractionBuilder.kt index 9d9e1d9ca6c..8a817c7f8dd 100644 --- a/rest/src/main/kotlin/builder/interaction/PublicInteractionBuilder.kt +++ b/rest/src/main/kotlin/builder/interaction/PublicInteractionBuilder.kt @@ -3,11 +3,8 @@ package dev.kord.rest.builder.interaction import dev.kord.common.annotation.KordDsl import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.InteractionResponseType -import dev.kord.common.entity.optional.Optional -import dev.kord.common.entity.optional.OptionalBoolean +import dev.kord.common.entity.optional.* import dev.kord.common.entity.optional.delegate.delegate -import dev.kord.common.entity.optional.map -import dev.kord.common.entity.optional.optional import dev.kord.rest.builder.component.MessageComponentBuilder import dev.kord.rest.builder.message.AllowedMentionsBuilder import dev.kord.rest.builder.message.EmbedBuilder @@ -73,17 +70,19 @@ class PublicInteractionResponseCreateBuilder : @KordDsl class PublicInteractionResponseModifyBuilder : BaseInteractionResponseModifyBuilder { - private var _content: Optional = Optional.Missing() + private var _content: Optional = Optional.Missing() override var content: String? by ::_content.delegate() - override val embeds: MutableList = mutableListOf() + private var _embeds: Optional> = Optional.Missing() + override var embeds: MutableList? by ::_embeds.delegate() - private var _allowedMentions: Optional = Optional.Missing() + private var _allowedMentions: Optional = Optional.Missing() override var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate() val files: MutableList> = mutableListOf() - override val components: MutableList = mutableListOf() + private var _components: Optional> = Optional.Missing() + override var components: MutableList? by ::_components.delegate() fun addFile(name: String, content: InputStream) { files += name to content @@ -97,9 +96,9 @@ class PublicInteractionResponseModifyBuilder : return MultipartInteractionResponseModifyRequest( InteractionResponseModifyRequest( content = _content, - embeds = embeds.map { it.toRequest() }, + embeds = Optional(embeds).coerceToMissing().mapList { it.toRequest() }, allowedMentions = _allowedMentions.map { it.build() }, - components = Optional.missingOnEmpty(components.map(MessageComponentBuilder::build)) + components = Optional(components).coerceToMissing().mapList { it.build() }, ), files ) diff --git a/rest/src/main/kotlin/builder/message/MessageModifyBuilder.kt b/rest/src/main/kotlin/builder/message/MessageModifyBuilder.kt index b75b7721655..b9ee418fd2d 100644 --- a/rest/src/main/kotlin/builder/message/MessageModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/message/MessageModifyBuilder.kt @@ -5,6 +5,7 @@ import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.MessageFlags import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.delegate.delegate +import dev.kord.common.entity.optional.mapList import dev.kord.common.entity.optional.mapNullable import dev.kord.rest.builder.RequestBuilder import dev.kord.rest.builder.component.ActionRowBuilder @@ -29,8 +30,11 @@ class MessageModifyBuilder : RequestBuilder { private var _allowedMentions: Optional = Optional.Missing() var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate() + @OptIn(KordPreview::class) + private var _components: Optional> = Optional.Missing() + @KordPreview - val components: MutableList = mutableListOf() + var components: MutableList? by ::_components.delegate() @OptIn(ExperimentalContracts::class) inline fun embed(block: EmbedBuilder.() -> Unit) { @@ -57,8 +61,9 @@ class MessageModifyBuilder : RequestBuilder { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - - components.add(ActionRowBuilder().apply(builder)) + components = (components ?: mutableListOf()).also { + it.add(ActionRowBuilder().apply(builder)) + } } @OptIn(KordPreview::class) @@ -67,6 +72,6 @@ class MessageModifyBuilder : RequestBuilder { _embed.mapNullable { it?.toRequest() }, _flags, _allowedMentions.mapNullable { it?.build() }, - Optional.missingOnEmpty(components.map(MessageComponentBuilder::build)) + _components.mapList { it.build() } ) } diff --git a/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt b/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt index 523d7bc2096..4ca20fa34e5 100644 --- a/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt +++ b/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt @@ -4,6 +4,7 @@ import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.AllowedMentions import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.delegate.delegate +import dev.kord.common.entity.optional.mapList import dev.kord.rest.builder.RequestBuilder import dev.kord.rest.builder.component.ActionRowBuilder import dev.kord.rest.builder.component.MessageComponentBuilder @@ -24,21 +25,29 @@ class EditWebhookMessageBuilder : RequestBuilder = Optional.Missing() var content: String? by ::_content.delegate() - var embeds: MutableList = mutableListOf() + private var _embeds: Optional> = Optional.Missing() + var embeds: MutableList? by ::_embeds.delegate() val files: MutableList> = mutableListOf() private var _allowedMentions: Optional = Optional.Missing() var allowedMentions: AllowedMentions? by ::_allowedMentions.delegate() - val components: MutableList = mutableListOf() + @OptIn(KordPreview::class) + private var _components: Optional> = Optional.Missing() + + @KordPreview + var components: MutableList? by ::_components.delegate() @OptIn(ExperimentalContracts::class) inline fun embed(builder: EmbedBuilder.() -> Unit) { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - embeds.add(EmbedBuilder().apply(builder)) + + embeds = (embeds ?: mutableListOf()).also { + it.add(EmbedBuilder().apply(builder)) + } } fun addFile(name: String, content: InputStream) { @@ -56,15 +65,17 @@ class EditWebhookMessageBuilder : RequestBuilder = Optional.Missing(), - val embeds: List = emptyList(), + val content: Optional = Optional.Missing(), + val embeds: Optional?> = Optional.Missing(), @SerialName("allowed_mentions") - val allowedMentions: Optional = Optional.Missing(), - val flags: Optional = Optional.Missing(), - val components: Optional> = Optional.Missing() + val allowedMentions: Optional = Optional.Missing(), + val flags: Optional = Optional.Missing(), + val components: Optional?> = Optional.Missing() ) @KordPreview