Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forms support #531

Merged
merged 33 commits into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4016de0
Initial modals implementation
MrPowerGamerBR Feb 9, 2022
08a7cac
Change the "DiscordComponent" model to multiple classes due to button…
MrPowerGamerBR Feb 9, 2022
2b1f43a
Canonical order
MrPowerGamerBR Feb 9, 2022
89e1e30
Use two ***DiscordComponents classes for everything
MrPowerGamerBR Feb 9, 2022
7c39464
Rename the classes because it looks better this way
MrPowerGamerBR Feb 9, 2022
3856eee
Revert core changes
MrPowerGamerBR Feb 9, 2022
8d03e60
Implement text input component classes in the core module
MrPowerGamerBR Feb 9, 2022
8223e43
Fix TextInput component type deserialization
MrPowerGamerBR Feb 9, 2022
50a837e
improve the interaction tree
HopeBaron Feb 10, 2022
ec873d5
More changes to the tree
HopeBaron Feb 10, 2022
9eccb31
remove unresolved references
HopeBaron Feb 10, 2022
769c8d6
add core events
HopeBaron Feb 10, 2022
660f477
Apply suggestions from code review
HopeBaron Feb 11, 2022
eadce4d
change compontents top level to ActionRowBuilder
HopeBaron Feb 12, 2022
fa8a415
refactor files
HopeBaron Feb 12, 2022
a5a8272
refactor interaction files
HopeBaron Feb 12, 2022
f810972
refactor response files
HopeBaron Feb 12, 2022
992fac9
refactor followup messages
HopeBaron Feb 12, 2022
4b96ef5
add TextInputComponent list retrival property
HopeBaron Feb 12, 2022
edd6ff0
fix withStrategy return type
HopeBaron Feb 12, 2022
5e60f60
Apply suggestions from code review
HopeBaron Feb 12, 2022
81eab28
rename discord modal component to DiscordTextInputComponent
HopeBaron Feb 12, 2022
afab86b
fix interaction response type
HopeBaron Feb 12, 2022
8f705e7
Forms support adjustments (#534)
lukellmann Feb 12, 2022
8ae546f
GuildAutoCompleteInteraction is GuildInteraction (#535)
lukellmann Feb 12, 2022
5d9be2c
required is true by default for text inputs (#537)
lukellmann Feb 15, 2022
39d7608
Merge branch '0.8.x' into feature/forms
HopeBaron Feb 17, 2022
71159e9
rewrite a safer OptionValue implementation
HopeBaron Feb 17, 2022
a63e10f
Apply code review suggestions
HopeBaron Feb 18, 2022
0fb59bc
Yeet out IntOptionValue
HopeBaron Feb 18, 2022
9838aef
Fix interactions for forms feature (#538)
lukellmann Feb 19, 2022
a5bb146
cleanup and consider feedback in codereview
HopeBaron Feb 20, 2022
5f13f84
reintroduce CommandArgument convience methods
HopeBaron Feb 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 0 additions & 139 deletions core/src/main/kotlin/entity/interaction/ActionInteraction.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.kord.core.entity.interaction

import dev.kord.common.entity.ApplicationCommandType
import dev.kord.common.entity.CommandArgument
import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional
Expand All @@ -12,12 +11,9 @@ import dev.kord.core.KordObject
import dev.kord.core.behavior.interaction.GlobalInteractionBehavior
import dev.kord.core.behavior.interaction.ActionInteractionBehavior
import dev.kord.core.cache.data.ApplicationInteractionData
import dev.kord.core.cache.data.InteractionData
import dev.kord.core.cache.data.ResolvedObjectsData
import dev.kord.core.entity.*
import dev.kord.core.entity.application.GlobalApplicationCommand
import dev.kord.core.entity.channel.ResolvedChannel
import dev.kord.core.supplier.EntitySupplier
import dev.kord.core.supplier.EntitySupplyStrategy

/**
Expand Down Expand Up @@ -214,138 +210,3 @@ public class ResolvedObjects(
}


public sealed class OptionValue<out T>(public val value: T, public val focused: Boolean) {

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

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

public class MemberOptionValue(value: Member, focused: Boolean) : UserOptionValue(value, focused) {
override fun toString(): String = "MemberOptionValue(value=$value)"
}

public class ChannelOptionValue(value: ResolvedChannel, focused: Boolean) :
OptionValue<ResolvedChannel>(value, 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)"
}


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

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

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

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

}


public fun OptionValue(value: CommandArgument<*>, resolvedObjects: ResolvedObjects?): OptionValue<*> {
val focused = value.focused.orElse(false)
return when (value) {
is CommandArgument.NumberArgument -> OptionValue.NumberOptionValue(value.value, focused)
is CommandArgument.BooleanArgument -> OptionValue.BooleanOptionValue(value.value, focused)
is CommandArgument.IntegerArgument -> OptionValue.IntOptionValue(value.value, focused)
is CommandArgument.StringArgument, is CommandArgument.AutoCompleteArgument -> OptionValue.StringOptionValue(
value.value as String,
focused
)
is CommandArgument.ChannelArgument -> {
val channel = resolvedObjects?.channels.orEmpty()[value.value]
requireNotNull(channel) { "channel expected for $value but was missing" }

OptionValue.ChannelOptionValue(channel, focused)
}

is CommandArgument.MentionableArgument -> {
val channel = resolvedObjects?.channels.orEmpty()[value.value]
val user = resolvedObjects?.users.orEmpty()[value.value]
val member = resolvedObjects?.members.orEmpty()[value.value]
val role = resolvedObjects?.roles.orEmpty()[value.value]

val entity = channel ?: member ?: user ?: role
requireNotNull(entity) { "user, member, or channel expected for $value but was missing" }

OptionValue.MentionableOptionValue(entity, focused)
}

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

OptionValue.RoleOptionValue(role, focused)
}

is CommandArgument.UserArgument -> {
val member = resolvedObjects?.members.orEmpty()[value.value]

if (member != null) return OptionValue.MemberOptionValue(member, focused)

val user = resolvedObjects?.users.orEmpty()[value.value]
requireNotNull(user) { "user expected for $value but was missing" }

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)
}
}
}


public sealed interface GlobalInteraction : GlobalInteractionBehavior, Interaction {
public override val user: User get() = User(data.user.value!!, kord)
}

public fun OptionValue<*>.user(): User = value as User


public fun OptionValue<*>.channel(): ResolvedChannel = value as ResolvedChannel


public fun OptionValue<*>.role(): Role = value as Role


public fun OptionValue<*>.member(): Member = value as Member


public fun OptionValue<*>.string(): String = value.toString()


public fun OptionValue<*>.boolean(): Boolean = value as Boolean


public fun OptionValue<*>.int(): Long = value as Long


public fun OptionValue<*>.number(): Double = value as Double


public fun OptionValue<*>.mentionable(): Entity {
return value as Entity
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved
}
8 changes: 8 additions & 0 deletions core/src/main/kotlin/entity/interaction/GlobalInteraction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.kord.core.entity.interaction

import dev.kord.core.behavior.interaction.GlobalInteractionBehavior
import dev.kord.core.entity.User

public sealed interface GlobalInteraction : GlobalInteractionBehavior, Interaction {
public override val user: User get() = User(data.user.value!!, kord)
}
102 changes: 102 additions & 0 deletions core/src/main/kotlin/entity/interaction/OptionValue.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
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

public sealed interface OptionValue<out T> {
public val value: T
public val focused: Boolean
}

public sealed interface ResolvableOptionValue<out T> : OptionValue<Snowflake> {
public val resolvedObject: T?
}
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved

public class IntOptionValue(override val value: Long, override val focused: Boolean) : OptionValue<Long> {
override fun toString(): String = "IntOptionValue(value=$value)"
}
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved


public class NumberOptionValue(override val value: Double, override val focused: Boolean) : OptionValue<Double> {
override fun toString(): String = "DoubleOptionValue(value=$value)"
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved
}

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

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


public class RoleOptionValue(override val value: Snowflake, override val focused: Boolean, override val resolvedObject: Role?) : ResolvableOptionValue<Role> {
override fun toString(): String = "RoleOptionValue(value=$value)"
}

public open class UserOptionValue(override val value: Snowflake, override val focused: Boolean, override val resolvedObject: User?) : ResolvableOptionValue<User> {
override fun toString(): String = "UserOptionValue(value=$value)"
}

public class MemberOptionValue(value: Snowflake, focused: Boolean, override val resolvedObject: Member?) : UserOptionValue(value, focused, resolvedObject) {
override fun toString(): String = "MemberOptionValue(value=$value)"
}

public class ChannelOptionValue(override val value: Snowflake, override val focused: Boolean, override val resolvedObject: ResolvedChannel?) :
ResolvableOptionValue<ResolvedChannel> {
override fun toString(): String = "ChannelOptionValue(value=$value)"
}
public class MentionableOptionValue(override val value: Snowflake, override val focused: Boolean, override val resolvedObject: Entity?) : ResolvableOptionValue<Entity> {
override fun toString(): String = "MentionableOptionValue(value=$value)"
}
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved

public class AttachmentOptionValue(override val value: Snowflake, override val focused: Boolean, override val resolvedObject: Attachment?) : ResolvableOptionValue<Attachment> {
override fun toString(): String = "AttachmentOptionValue(value=$value)"
}

public fun OptionValue(value: CommandArgument<*>, resolvedObjects: ResolvedObjects?): OptionValue<*> {
val focused = value.focused.orElse(false)
return when (value) {
is CommandArgument.NumberArgument -> NumberOptionValue(value.value, focused)
is CommandArgument.BooleanArgument -> BooleanOptionValue(value.value, focused)
is CommandArgument.IntegerArgument -> IntOptionValue(value.value, focused)
HopeBaron marked this conversation as resolved.
Show resolved Hide resolved
is CommandArgument.StringArgument, is CommandArgument.AutoCompleteArgument ->
StringOptionValue(value.value as String, focused)
is CommandArgument.ChannelArgument -> {
val channel = resolvedObjects?.channels.orEmpty()[value.value]
ChannelOptionValue(value.value, focused, channel)
}

is CommandArgument.MentionableArgument -> {
val channel = resolvedObjects?.channels.orEmpty()[value.value]
val user = resolvedObjects?.users.orEmpty()[value.value]
val member = resolvedObjects?.members.orEmpty()[value.value]
val role = resolvedObjects?.roles.orEmpty()[value.value]

val entity = channel ?: member ?: user ?: role
MentionableOptionValue(value.value, focused, entity)
}

is CommandArgument.RoleArgument -> {
val role = resolvedObjects?.roles.orEmpty()[value.value]
RoleOptionValue(value.value, focused, role)
}

is CommandArgument.UserArgument -> {
val member = resolvedObjects?.members.orEmpty()[value.value]
if (member != null) return MemberOptionValue(value.value, focused, member)
val user = resolvedObjects?.users.orEmpty()[value.value]
UserOptionValue(value.value, focused, user)
}

is CommandArgument.AttachmentArgument -> {
val attachment = resolvedObjects?.attachments.orEmpty()[value.value]
AttachmentOptionValue(value.value, focused, attachment)

}
}
}