Skip to content

Commit 16c47d5

Browse files
authored
Add entity selects and text displays in modals (#2913)
1 parent d547708 commit 16c47d5

File tree

16 files changed

+215
-79
lines changed

16 files changed

+215
-79
lines changed

src/main/java/net/dv8tion/jda/api/components/Component.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ enum Type
122122
/** A text input field */
123123
TEXT_INPUT(4, false, true),
124124
/** A select menu of users */
125-
USER_SELECT(5, true, false),
125+
USER_SELECT(5, true, true),
126126
/** A select menu of roles */
127-
ROLE_SELECT(6, true, false),
127+
ROLE_SELECT(6, true, true),
128128
/** A select menu of users and roles */
129-
MENTIONABLE_SELECT(7, true, false),
129+
MENTIONABLE_SELECT(7, true, true),
130130
/** A select menu of channels */
131-
CHANNEL_SELECT(8, true, false),
131+
CHANNEL_SELECT(8, true, true),
132132
SECTION(9, true, false),
133-
TEXT_DISPLAY(10, true, false),
133+
TEXT_DISPLAY(10, true, true),
134134
THUMBNAIL(11, true, false),
135135
MEDIA_GALLERY(12, true, false),
136136
FILE_DISPLAY(13, true, false),
@@ -197,6 +197,16 @@ public boolean isModalCompatible()
197197
return modalCompatible;
198198
}
199199

200+
/**
201+
* Whether this component is an {@link net.dv8tion.jda.api.components.selections.EntitySelectMenu EntitySelectMenu}
202+
*
203+
* @return {@code true} is this is a type of {@link net.dv8tion.jda.api.components.selections.EntitySelectMenu EntitySelectMenu}
204+
*/
205+
public boolean isEntitySelectMenu()
206+
{
207+
return this == MENTIONABLE_SELECT || this == CHANNEL_SELECT || this == USER_SELECT || this == ROLE_SELECT;
208+
}
209+
200210
/**
201211
* Maps the provided type id to the respective enum instance.
202212
*

src/main/java/net/dv8tion/jda/api/components/ModalTopLevelComponent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* Represents a component that can be added directly to a modal, this includes:
2323
* <ul>
2424
* <li>{@link net.dv8tion.jda.api.components.label.Label Label}</li>
25+
* <li>{@link net.dv8tion.jda.api.components.textdisplay.TextDisplay TextDisplay}</li>
2526
* </ul>
2627
*/
2728
public interface ModalTopLevelComponent extends Component

src/main/java/net/dv8tion/jda/api/components/ModalTopLevelComponentUnion.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
package net.dv8tion.jda.api.components;
1818

1919
import net.dv8tion.jda.api.components.label.Label;
20+
import net.dv8tion.jda.api.components.textdisplay.TextDisplay;
2021

2122
import javax.annotation.Nonnull;
2223

2324
/**
2425
* Represents a union of {@link ModalTopLevelComponent ModalTopLevelComponents} that can be one of:
2526
* <ul>
2627
* <li>{@link Label}</li>
28+
* <li>{@link TextDisplay}</li>
2729
* <li>{@link UnknownComponent}, detectable via {@link #isUnknownComponent()}</li>
2830
* </ul>
2931
*/
@@ -51,6 +53,28 @@ public interface ModalTopLevelComponentUnion extends ModalTopLevelComponent, ICo
5153
@Nonnull
5254
Label asLabel();
5355

56+
/**
57+
* Casts this union to a {@link TextDisplay}.
58+
* This method exists for developer discoverability.
59+
*
60+
* <p>Note: This is effectively equivalent to using the cast operator:
61+
* <pre><code>
62+
* //These are the same!
63+
* TextDisplay textDisplay = union.asTextDisplay();
64+
* TextDisplay textDisplay2 = (TextDisplay) union;
65+
* </code></pre>
66+
*
67+
* You can use {@link #getType()} to see if the component is of type {@link net.dv8tion.jda.api.components.Component.Type#TEXT_DISPLAY TEXT_DISPLAY} to validate
68+
* whether you can call this method in addition to normal instanceof checks: <code>component instanceof TextDisplay</code>
69+
*
70+
* @throws IllegalStateException
71+
* If the component represented by this union is not actually a {@link TextDisplay}.
72+
*
73+
* @return The component as a {@link TextDisplay}
74+
*/
75+
@Nonnull
76+
TextDisplay asTextDisplay();
77+
5478
@Nonnull
5579
@Override
5680
ModalTopLevelComponentUnion withUniqueId(int uniqueId);

src/main/java/net/dv8tion/jda/api/components/label/LabelChildComponent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* <ul>
2626
* <li>{@link net.dv8tion.jda.api.components.textinput.TextInput TextInput}</li>
2727
* <li>{@link net.dv8tion.jda.api.components.selections.StringSelectMenu StringSelectMenu}</li>
28+
* <li>{@link net.dv8tion.jda.api.components.selections.EntitySelectMenu EntitySelectMenu}</li>
2829
* </ul>
2930
*/
3031
public interface LabelChildComponent extends Component

src/main/java/net/dv8tion/jda/api/components/label/LabelChildComponentUnion.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import net.dv8tion.jda.api.components.Component;
2020
import net.dv8tion.jda.api.components.IComponentUnion;
21+
import net.dv8tion.jda.api.components.selections.EntitySelectMenu;
2122
import net.dv8tion.jda.api.components.selections.StringSelectMenu;
2223
import net.dv8tion.jda.api.components.textinput.TextInput;
2324

@@ -28,6 +29,7 @@
2829
* <ul>
2930
* <li>{@link TextInput}</li>
3031
* <li>{@link StringSelectMenu}</li>
32+
* <li>{@link EntitySelectMenu}</li>
3133
* </ul>
3234
*/
3335
public interface LabelChildComponentUnion extends LabelChildComponent, IComponentUnion
@@ -76,6 +78,34 @@ public interface LabelChildComponentUnion extends LabelChildComponent, IComponen
7678
@Nonnull
7779
StringSelectMenu asStringSelectMenu();
7880

81+
/**
82+
* Casts this union to a {@link EntitySelectMenu}.
83+
* This method exists for developer discoverability.
84+
*
85+
* <p>Note: This is effectively equivalent to using the cast operator:
86+
* <pre><code>
87+
* //These are the same!
88+
* EntitySelectMenu menu = union.asEntitySelectMenu();
89+
* EntitySelectMenu menu2 = (EntitySelectMenu) union;
90+
* </code></pre>
91+
*
92+
* You can use {@link #getType()} to see if the component is one of:
93+
* <ul>
94+
* <li>{@link Component.Type#USER_SELECT USER_SELECT}</li>
95+
* <li>{@link Component.Type#ROLE_SELECT ROLE_SELECT}</li>
96+
* <li>{@link Component.Type#MENTIONABLE_SELECT MENTIONABLE_SELECT}</li>
97+
* <li>{@link Component.Type#CHANNEL_SELECT CHANNEL_SELECT}</li>
98+
* </ul>
99+
* to validate whether you can call this method in addition to normal instanceof checks: <code>component instanceof EntitySelectMenu</code>
100+
*
101+
* @throws IllegalStateException
102+
* If the component represented by this union is not actually a {@link EntitySelectMenu}.
103+
*
104+
* @return The component as a {@link EntitySelectMenu}
105+
*/
106+
@Nonnull
107+
EntitySelectMenu asEntitySelectMenu();
108+
79109
@Nonnull
80110
@Override
81111
LabelChildComponentUnion withUniqueId(int uniqueId);

src/main/java/net/dv8tion/jda/api/components/selections/EntitySelectMenu.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ public EntitySelectMenu build()
655655
Checks.check(minValues <= maxValues, "Min values cannot be greater than max values!");
656656
EnumSet<ChannelType> channelTypes = componentType == Type.CHANNEL_SELECT ? this.channelTypes : EnumSet.noneOf(ChannelType.class);
657657
List<DefaultValue> defaultValues = new ArrayList<>(this.defaultValues);
658-
return new EntitySelectMenuImpl(customId, uniqueId, placeholder, minValues, maxValues, disabled, componentType, channelTypes, defaultValues);
658+
return new EntitySelectMenuImpl(customId, uniqueId, placeholder, minValues, maxValues, disabled, componentType, channelTypes, defaultValues, required);
659659
}
660660
}
661661
}

src/main/java/net/dv8tion/jda/api/components/selections/SelectMenu.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.dv8tion.jda.api.components.ActionComponent;
2222
import net.dv8tion.jda.api.components.actionrow.ActionRow;
2323
import net.dv8tion.jda.api.components.actionrow.ActionRowChildComponent;
24+
import net.dv8tion.jda.api.components.label.LabelChildComponent;
2425
import net.dv8tion.jda.api.interactions.components.selections.SelectMenuInteraction;
2526
import net.dv8tion.jda.internal.utils.Checks;
2627

@@ -45,7 +46,7 @@
4546
* @see EntitySelectMenu
4647
* @see SelectMenuInteraction
4748
*/
48-
public interface SelectMenu extends ActionComponent, ActionRowChildComponent
49+
public interface SelectMenu extends ActionComponent, ActionRowChildComponent, LabelChildComponent
4950
{
5051
/**
5152
* The maximum length a select menu id can have
@@ -110,6 +111,14 @@ default SelectMenu asEnabled()
110111
*/
111112
int getMaxValues();
112113

114+
/**
115+
* Whether the user must populate this select menu in Modals, or {@code null} if not set.
116+
*
117+
* @return Whether this menu must be populated, or null
118+
*/
119+
@Nullable
120+
Boolean isRequired();
121+
113122
/**
114123
* Creates a new preconfigured {@link SelectMenu.Builder} with the same settings used for this select menu.
115124
* <br>This can be useful to create an updated version of this menu without needing to rebuild it from scratch.
@@ -136,6 +145,7 @@ abstract class Builder<T extends SelectMenu, B extends Builder<T, B>>
136145
protected String placeholder;
137146
protected int minValues = 1, maxValues = 1;
138147
protected boolean disabled = false;
148+
protected Boolean required = null;
139149

140150
protected Builder(@Nonnull String customId)
141151
{
@@ -311,6 +321,24 @@ public B setDisabled(boolean disabled)
311321
return (B) this;
312322
}
313323

324+
/**
325+
* Configure whether the user must populate this select menu if inside a Modal.
326+
* <br>This defaults to {@code true} in Modals when unset.
327+
*
328+
* <p>This only has an effect in Modals!
329+
*
330+
* @param required
331+
* Whether this menu is required
332+
*
333+
* @return The same builder instance for chaining
334+
*/
335+
@Nonnull
336+
public B setRequired(@Nullable Boolean required)
337+
{
338+
this.required = required;
339+
return (B) this;
340+
}
341+
314342
/**
315343
* The custom id used to identify the select menu.
316344
*
@@ -390,6 +418,17 @@ public boolean isDisabled()
390418
return disabled;
391419
}
392420

421+
/**
422+
* Whether the user must populate this select menu in Modals, or {@code null} if not set.
423+
*
424+
* @return Whether this menu must be populated, or null
425+
*/
426+
@Nullable
427+
public Boolean isRequired()
428+
{
429+
return required;
430+
}
431+
393432
/**
394433
* Creates a new {@link SelectMenu} instance if all requirements are satisfied.
395434
*

src/main/java/net/dv8tion/jda/api/components/selections/StringSelectMenu.java

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import net.dv8tion.jda.api.components.ActionComponent;
2020
import net.dv8tion.jda.api.components.actionrow.ActionRow;
21-
import net.dv8tion.jda.api.components.label.LabelChildComponent;
2221
import net.dv8tion.jda.api.entities.emoji.Emoji;
2322
import net.dv8tion.jda.api.interactions.components.selections.SelectMenuInteraction;
2423
import net.dv8tion.jda.api.interactions.components.selections.StringSelectInteraction;
@@ -63,7 +62,7 @@
6362
* @see StringSelectInteraction
6463
* @see EntitySelectMenu
6564
*/
66-
public interface StringSelectMenu extends SelectMenu, LabelChildComponent
65+
public interface StringSelectMenu extends SelectMenu
6766
{
6867
@Nonnull
6968
@Override
@@ -100,14 +99,6 @@ default StringSelectMenu withDisabled(boolean disabled)
10099
@Nonnull
101100
List<SelectOption> getOptions();
102101

103-
/**
104-
* Whether the user must populate this select menu in Modals, or {@code null} if not set.
105-
*
106-
* @return Whether this menu must be populated, or null
107-
*/
108-
@Nullable
109-
Boolean isRequired();
110-
111102
/**
112103
* Creates a new preconfigured {@link Builder} with the same settings used for this select menu.
113104
* <br>This can be useful to create an updated version of this menu without needing to rebuild it from scratch.
@@ -153,7 +144,6 @@ static Builder create(@Nonnull String customId)
153144
class Builder extends SelectMenu.Builder<StringSelectMenu, StringSelectMenu.Builder>
154145
{
155146
private final List<SelectOption> options = new ArrayList<>();
156-
private Boolean required = null;
157147

158148
protected Builder(@Nonnull String customId)
159149
{
@@ -306,17 +296,6 @@ public List<SelectOption> getOptions()
306296
return options;
307297
}
308298

309-
/**
310-
* Whether the user must populate this select menu in Modals, or {@code null} if not set.
311-
*
312-
* @return Whether this menu must be populated, or null
313-
*/
314-
@Nullable
315-
public Boolean isRequired()
316-
{
317-
return required;
318-
}
319-
320299
/**
321300
* Configures which of the currently applied {@link #getOptions() options} should be selected by default.
322301
*
@@ -395,24 +374,6 @@ public Builder setDefaultOptions(@Nonnull SelectOption... values)
395374
return setDefaultOptions(Arrays.asList(values));
396375
}
397376

398-
/**
399-
* Configure whether the user must populate this select menu if inside a Modal.
400-
* <br>This defaults to {@code true} in Modals when unset.
401-
*
402-
* <p>This only has an effect in Modals!
403-
*
404-
* @param required
405-
* Whether this menu is required
406-
*
407-
* @return The same builder instance for chaining
408-
*/
409-
@Nonnull
410-
public Builder setRequired(@Nullable Boolean required)
411-
{
412-
this.required = required;
413-
return this;
414-
}
415-
416377
/**
417378
* Creates a new {@link StringSelectMenu} instance if all requirements are satisfied.
418379
* <br>A select menu may not have more than {@value #OPTIONS_MAX_AMOUNT} options at once.

src/main/java/net/dv8tion/jda/api/components/textdisplay/TextDisplay.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import net.dv8tion.jda.api.components.Component;
2020
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
21+
import net.dv8tion.jda.api.components.ModalTopLevelComponent;
2122
import net.dv8tion.jda.api.components.container.ContainerChildComponent;
2223
import net.dv8tion.jda.api.components.section.SectionContentComponent;
2324
import net.dv8tion.jda.api.entities.Message;
@@ -37,7 +38,9 @@
3738
*
3839
* <p><b>Requirements:</b> {@linkplain MessageRequest#useComponentsV2() Components V2} needs to be enabled!
3940
*/
40-
public interface TextDisplay extends Component, MessageTopLevelComponent, ContainerChildComponent, SectionContentComponent
41+
public interface TextDisplay
42+
extends Component, MessageTopLevelComponent, ModalTopLevelComponent,
43+
ContainerChildComponent, SectionContentComponent
4144
{
4245
/**
4346
* Constructs a new {@link TextDisplay} from the given content.

0 commit comments

Comments
 (0)