Skip to content

Commit

Permalink
Allow properties in message edits to be empty/null (#327)
Browse files Browse the repository at this point in the history
* Allow properties in message edits to be empty/null

This gives properties in message edit builders the ability to encode values as null or empty lists when applicable, allowing you to remove fields from a message.

This is how it should have been from the start, but was missed in code review.

* Update CHANGELOG.md
  • Loading branch information
BartArys authored and HopeBaron committed Jun 24, 2021
1 parent 9745fd3 commit 23fbc0a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 45 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
48 changes: 41 additions & 7 deletions rest/src/main/kotlin/builder/interaction/Base.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,38 @@ sealed interface BaseInteractionResponseBuilder<T> : RequestBuilder<T> {

var content: String?

val embeds: MutableList<EmbedBuilder>
val embeds: MutableList<EmbedBuilder>?

val components: MutableList<MessageComponentBuilder>
val components: MutableList<MessageComponentBuilder>?

var allowedMentions: AllowedMentionsBuilder?


}

@OptIn(ExperimentalContracts::class)
@KordPreview
@OptIn(ExperimentalContracts::class, KordPreview::class)
inline fun <T> BaseInteractionResponseBuilder<T>.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))
}
}
}
}

/**
* Configures the mentions that should trigger a mention (aka ping). Not calling this function will result in the default behavior
* (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 <T> BaseInteractionResponseBuilder<T>.allowedMentions(block: AllowedMentionsBuilder.() -> Unit = {}) {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
Expand All @@ -51,14 +63,36 @@ inline fun <T> BaseInteractionResponseBuilder<T>.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<MultipartInteractionResponseCreateRequest>
BaseInteractionResponseBuilder<MultipartInteractionResponseCreateRequest> {

override val components: MutableList<MessageComponentBuilder>

override val embeds: MutableList<EmbedBuilder>

}

@KordPreview
interface BaseInteractionResponseModifyBuilder :
BaseInteractionResponseBuilder<MultipartInteractionResponseModifyRequest>
BaseInteractionResponseBuilder<MultipartInteractionResponseModifyRequest> {

override var components: MutableList<MessageComponentBuilder>?

override var embeds: MutableList<EmbedBuilder>?

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = Optional.Missing()
private var _content: Optional<String?> = Optional.Missing()
override var content: String? by ::_content.delegate()

override val embeds: MutableList<EmbedBuilder> = mutableListOf()
private var _embeds: Optional<MutableList<EmbedBuilder>> = Optional.Missing()
override var embeds: MutableList<EmbedBuilder>? by ::_embeds.delegate()

private var _allowedMentions: Optional<AllowedMentionsBuilder> = Optional.Missing()
private var _allowedMentions: Optional<AllowedMentionsBuilder?> = Optional.Missing()
override var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate()

override val components: MutableList<MessageComponentBuilder> = mutableListOf()
private var _components: Optional<MutableList<MessageComponentBuilder>> = Optional.Missing()
override var components: MutableList<MessageComponentBuilder>? 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() },
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -73,17 +70,19 @@ class PublicInteractionResponseCreateBuilder :
@KordDsl
class PublicInteractionResponseModifyBuilder :
BaseInteractionResponseModifyBuilder {
private var _content: Optional<String> = Optional.Missing()
private var _content: Optional<String?> = Optional.Missing()
override var content: String? by ::_content.delegate()

override val embeds: MutableList<EmbedBuilder> = mutableListOf()
private var _embeds: Optional<MutableList<EmbedBuilder>> = Optional.Missing()
override var embeds: MutableList<EmbedBuilder>? by ::_embeds.delegate()

private var _allowedMentions: Optional<AllowedMentionsBuilder> = Optional.Missing()
private var _allowedMentions: Optional<AllowedMentionsBuilder?> = Optional.Missing()
override var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate()

val files: MutableList<Pair<String, InputStream>> = mutableListOf()

override val components: MutableList<MessageComponentBuilder> = mutableListOf()
private var _components: Optional<MutableList<MessageComponentBuilder>> = Optional.Missing()
override var components: MutableList<MessageComponentBuilder>? by ::_components.delegate()

fun addFile(name: String, content: InputStream) {
files += name to content
Expand All @@ -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
)
Expand Down
13 changes: 9 additions & 4 deletions rest/src/main/kotlin/builder/message/MessageModifyBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -29,8 +30,11 @@ class MessageModifyBuilder : RequestBuilder<MessageEditPatchRequest> {
private var _allowedMentions: Optional<AllowedMentionsBuilder?> = Optional.Missing()
var allowedMentions: AllowedMentionsBuilder? by ::_allowedMentions.delegate()

@OptIn(KordPreview::class)
private var _components: Optional<MutableList<MessageComponentBuilder>> = Optional.Missing()

@KordPreview
val components: MutableList<MessageComponentBuilder> = mutableListOf()
var components: MutableList<MessageComponentBuilder>? by ::_components.delegate()

@OptIn(ExperimentalContracts::class)
inline fun embed(block: EmbedBuilder.() -> Unit) {
Expand All @@ -57,8 +61,9 @@ class MessageModifyBuilder : RequestBuilder<MessageEditPatchRequest> {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}

components.add(ActionRowBuilder().apply(builder))
components = (components ?: mutableListOf()).also {
it.add(ActionRowBuilder().apply(builder))
}
}

@OptIn(KordPreview::class)
Expand All @@ -67,6 +72,6 @@ class MessageModifyBuilder : RequestBuilder<MessageEditPatchRequest> {
_embed.mapNullable { it?.toRequest() },
_flags,
_allowedMentions.mapNullable { it?.build() },
Optional.missingOnEmpty(components.map(MessageComponentBuilder::build))
_components.mapList { it.build() }
)
}
23 changes: 17 additions & 6 deletions rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,21 +25,29 @@ class EditWebhookMessageBuilder : RequestBuilder<MultipartWebhookEditMessageRequ
private var _content: Optional<String> = Optional.Missing()
var content: String? by ::_content.delegate()

var embeds: MutableList<EmbedBuilder> = mutableListOf()
private var _embeds: Optional<MutableList<EmbedBuilder>> = Optional.Missing()
var embeds: MutableList<EmbedBuilder>? by ::_embeds.delegate()

val files: MutableList<Pair<String, InputStream>> = mutableListOf()

private var _allowedMentions: Optional<AllowedMentions> = Optional.Missing()
var allowedMentions: AllowedMentions? by ::_allowedMentions.delegate()

val components: MutableList<MessageComponentBuilder> = mutableListOf()
@OptIn(KordPreview::class)
private var _components: Optional<MutableList<MessageComponentBuilder>> = Optional.Missing()

@KordPreview
var components: MutableList<MessageComponentBuilder>? 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) {
Expand All @@ -56,15 +65,17 @@ class EditWebhookMessageBuilder : RequestBuilder<MultipartWebhookEditMessageRequ
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}

components.add(ActionRowBuilder().apply(builder))
components = (components ?: mutableListOf()).also {
it.add(ActionRowBuilder().apply(builder))
}
}

override fun toRequest(): MultipartWebhookEditMessageRequest = MultipartWebhookEditMessageRequest(
WebhookEditMessageRequest(
_content,
Optional.missingOnEmpty(embeds.map(EmbedBuilder::toRequest)),
_embeds.mapList { it.toRequest() },
_allowedMentions,
Optional.missingOnEmpty(components.map { it.build() })
_components.mapList { it.build() }
),
files
)
Expand Down
10 changes: 5 additions & 5 deletions rest/src/main/kotlin/json/request/InteractionsRequests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ data class ApplicationCommandModifyRequest(
@Serializable
@KordPreview
data class InteractionResponseModifyRequest(
val content: Optional<String> = Optional.Missing(),
val embeds: List<EmbedRequest> = emptyList(),
val content: Optional<String?> = Optional.Missing(),
val embeds: Optional<List<EmbedRequest>?> = Optional.Missing(),
@SerialName("allowed_mentions")
val allowedMentions: Optional<AllowedMentions> = Optional.Missing(),
val flags: Optional<MessageFlags> = Optional.Missing(),
val components: Optional<List<DiscordComponent>> = Optional.Missing()
val allowedMentions: Optional<AllowedMentions?> = Optional.Missing(),
val flags: Optional<MessageFlags?> = Optional.Missing(),
val components: Optional<List<DiscordComponent>?> = Optional.Missing()
)

@KordPreview
Expand Down

0 comments on commit 23fbc0a

Please sign in to comment.