Skip to content

Commit

Permalink
Add support for attachment options in chat input interactions (#524)
Browse files Browse the repository at this point in the history
* Add support for attachment options in chat input interactions

* Fix attachment option deserialization

* Update common/src/main/kotlin/entity/Interactions.kt

Co-authored-by: Lukellmann <[email protected]>

Co-authored-by: Lukellmann <[email protected]>
  • Loading branch information
MrPowerGamerBR and lukellmann authored Feb 11, 2022
1 parent 5da4971 commit cc0f1df
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 3 deletions.
24 changes: 23 additions & 1 deletion common/src/main/kotlin/entity/Interactions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public sealed class ApplicationCommandOptionType(public val type: Int) {
public object Role : ApplicationCommandOptionType(8)
public object Mentionable : ApplicationCommandOptionType(9)
public object Number : ApplicationCommandOptionType(10)
public object Attachment : ApplicationCommandOptionType(11)
public class Unknown(type: Int) : ApplicationCommandOptionType(type)

internal object Serializer : KSerializer<ApplicationCommandOptionType> {
Expand All @@ -118,6 +119,7 @@ public sealed class ApplicationCommandOptionType(public val type: Int) {
8 -> Role
9 -> Mentionable
10 -> Number
11 -> Attachment
else -> Unknown(type)
}
}
Expand Down Expand Up @@ -186,7 +188,8 @@ public data class ResolvedObjects(
val users: Optional<Map<Snowflake, DiscordUser>> = Optional.Missing(),
val roles: Optional<Map<Snowflake, DiscordRole>> = Optional.Missing(),
val channels: Optional<Map<Snowflake, DiscordChannel>> = Optional.Missing(),
val messages: Optional<Map<Snowflake, DiscordMessage>> = Optional.Missing()
val messages: Optional<Map<Snowflake, DiscordMessage>> = Optional.Missing(),
val attachments: Optional<Map<Snowflake, DiscordAttachment>> = Optional.Missing()
)

@Serializable
Expand Down Expand Up @@ -369,6 +372,7 @@ public sealed class Option {
ApplicationCommandOptionType.Mentionable,
ApplicationCommandOptionType.Role,
ApplicationCommandOptionType.String,
ApplicationCommandOptionType.Attachment,
ApplicationCommandOptionType.User -> CommandArgument.Serializer.deserialize(
json, jsonValue!!, name, type!!, focused
)
Expand Down Expand Up @@ -496,6 +500,15 @@ public sealed class CommandArgument<out T> : Option() {
get() = ApplicationCommandOptionType.Mentionable
}

public data class AttachmentArgument(
override val name: String,
override val value: Snowflake,
override val focused: OptionalBoolean = OptionalBoolean.Missing
) : CommandArgument<Snowflake>() {
override val type: ApplicationCommandOptionType
get() = ApplicationCommandOptionType.Attachment
}

/**
* Representation of a partial user input of an auto completed argument.
*
Expand Down Expand Up @@ -551,6 +564,12 @@ public sealed class CommandArgument<out T> : Option() {
)
is IntegerArgument -> encodeLongElement(descriptor, 1, value.value)
is NumberArgument -> encodeDoubleElement(descriptor, 1, value.value)
is AttachmentArgument -> encodeSerializableElement(
descriptor,
1,
Snowflake.serializer(),
value.value
)
is AutoCompleteArgument, is StringArgument -> encodeStringElement(
descriptor,
1,
Expand Down Expand Up @@ -600,6 +619,9 @@ public sealed class CommandArgument<out T> : Option() {
ApplicationCommandOptionType.User -> UserArgument(
name, json.decodeFromJsonElement(Snowflake.serializer(), element), focused
)
ApplicationCommandOptionType.Attachment -> AttachmentArgument(
name, json.decodeFromJsonElement(Snowflake.serializer(), element), focused
)
ApplicationCommandOptionType.SubCommand,
ApplicationCommandOptionType.SubCommandGroup,
is ApplicationCommandOptionType.Unknown -> error("unknown CommandArgument type ${type.type}")
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/kotlin/cache/data/InteractionData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public data class ResolvedObjectsData(
val users: Optional<Map<Snowflake, UserData>> = Optional.Missing(),
val roles: Optional<Map<Snowflake, RoleData>> = Optional.Missing(),
val channels: Optional<Map<Snowflake, ChannelData>> = Optional.Missing(),
val messages: Optional<Map<Snowflake, MessageData>> = Optional.Missing()
val messages: Optional<Map<Snowflake, MessageData>> = Optional.Missing(),
val attachments: Optional<Map<Snowflake, AttachmentData>> = Optional.Missing()
) {
public companion object {
public fun from(data: ResolvedObjects, guildId: Snowflake?): ResolvedObjectsData {
Expand All @@ -70,7 +71,8 @@ public data class ResolvedObjectsData(
channels = data.channels.mapValues { ChannelData.from(it.value) },
roles = data.roles.mapValues { RoleData.from(guildId!!, it.value) },
users = data.users.mapValues { it.value.toData() },
messages = data.messages.mapValues { it.value.toData() }
messages = data.messages.mapValues { it.value.toData() },
attachments = data.attachments.mapValues { AttachmentData.from(it.value) }
)
}
}
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/kotlin/entity/interaction/ActionInteraction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ public class ResolvedObjects(
public val messages: Map<Snowflake, Message>?
get() = data.messages.mapValues { Message(it.value, kord) }.value

public val attachments: Map<Snowflake, Attachment>?
get() = data.attachments.mapValues { Attachment(it.value, kord) }.value
}


Expand All @@ -245,6 +247,10 @@ public sealed class OptionValue<out T>(public val value: T, public val focused:
override fun toString(): String = "ChannelOptionValue(value=$value)"
}

public class AttachmentOptionValue(value: Attachment, focused: Boolean) : OptionValue<Attachment>(value, focused) {
override fun toString(): String = "AttachmentOptionValue(value=$value)"
}

public class IntOptionValue(value: Long, focused: Boolean) : OptionValue<Long>(value, focused) {
override fun toString(): String = "IntOptionValue(value=$value)"
}
Expand Down Expand Up @@ -315,6 +321,13 @@ public fun OptionValue(value: CommandArgument<*>, resolvedObjects: ResolvedObjec

OptionValue.UserOptionValue(user, focused)
}

is CommandArgument.AttachmentArgument -> {
val attachment = resolvedObjects?.attachments.orEmpty()[value.value]
requireNotNull(attachment) { "attachment expected for $value but was missing" }

OptionValue.AttachmentOptionValue(attachment, focused)
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions rest/src/main/kotlin/builder/interaction/InputChatBuilders.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public inline fun BaseInputChatBuilder.role(name: String, description: String, b
options!!.add(RoleBuilder(name, description).apply(builder))
}

public inline fun BaseInputChatBuilder.attachment(name: String, description: String, builder: AttachmentBuilder.() -> Unit = {}) {
contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) }
if (options == null) options = mutableListOf()
options!!.add(AttachmentBuilder(name, description).apply(builder))
}

public inline fun BaseInputChatBuilder.number(name: String, description: String, builder: NumberChoiceBuilder.() -> Unit = {}) {
contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) }
if (options == null) options = mutableListOf()
Expand Down
4 changes: 4 additions & 0 deletions rest/src/main/kotlin/builder/interaction/OptionsBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ public class ChannelBuilder(name: String, description: String) :
public class MentionableBuilder(name: String, description: String) :
OptionsBuilder(name, description, ApplicationCommandOptionType.Mentionable)

@KordDsl
public class AttachmentBuilder(name: String, description: String) :
OptionsBuilder(name, description, ApplicationCommandOptionType.Attachment)

@KordDsl
public sealed class BaseCommandOptionBuilder(
name: String,
Expand Down

0 comments on commit cc0f1df

Please sign in to comment.