Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
Interaction Framework#19
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
fdfe1e91ff18bb1aafd8ce6ba92ae5c09d370c1d51File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package net.javadiscord.javabot2.command.interaction; | ||
| import net.javadiscord.javabot2.command.interaction.button.ButtonAction; | ||
| import net.javadiscord.javabot2.command.interaction.selection_menu.SelectMenuAction; | ||
| import org.javacord.api.entity.message.component.ActionRow; | ||
| import org.javacord.api.entity.message.component.LowLevelComponent; | ||
| import org.javacord.api.interaction.callback.InteractionImmediateResponseBuilder; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| /** | ||
| * Class that is used to build message interactions. | ||
| */ | ||
| public class InteractionHandlerBuilder { | ||
| private final InteractionImmediateResponseBuilder responseBuilder; | ||
| private final List<LowLevelComponent> buttons = new ArrayList<>(); | ||
| private final List<LowLevelComponent> selectMenus = new ArrayList<>(); | ||
| public InteractionHandlerBuilder(InteractionImmediateResponseBuilder responseBuilder) { | ||
| this.responseBuilder = responseBuilder; | ||
| } | ||
| /** | ||
| * Adds one or multiple {@link ButtonAction}s. | ||
| * @param buttonActions an array of {@link ButtonAction}s. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public InteractionHandlerBuilder addButtons(ButtonAction... buttonActions) { | ||
| for (var action : buttonActions) buttons.add(action.getButton()); | ||
| return this; | ||
| } | ||
| /** | ||
| * Adds one or multiple {@link SelectMenuAction}s. | ||
| * @param selectMenuActions an array of {@link SelectMenuAction}s. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public InteractionHandlerBuilder addSelectionMenus(SelectMenuAction... selectMenuActions) { | ||
| for (var action : selectMenuActions) { | ||
| selectMenus.add(action.getSelectMenu()); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Returns the provided Response Builder. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public InteractionImmediateResponseBuilder getResponseBuilder() { | ||
| return responseBuilder.addComponents(ActionRow.of(buttons), ActionRow.of(selectMenus)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package net.javadiscord.javabot2.command.interaction; | ||
| import net.javadiscord.javabot2.command.ResponseException; | ||
| import net.javadiscord.javabot2.command.interaction.button.ButtonHandler; | ||
| import net.javadiscord.javabot2.command.interaction.selection_menu.SelectionMenuHandler; | ||
| import org.javacord.api.event.interaction.ButtonClickEvent; | ||
| import org.javacord.api.event.interaction.SelectMenuChooseEvent; | ||
| import org.javacord.api.listener.interaction.ButtonClickListener; | ||
| import org.javacord.api.listener.interaction.SelectMenuChooseListener; | ||
| import java.lang.reflect.InvocationTargetException; | ||
| /** | ||
| * Listener for all supported interactions. | ||
| */ | ||
| public class InteractionListener implements ButtonClickListener, SelectMenuChooseListener { | ||
| @Override | ||
| public void onButtonClick(ButtonClickEvent event) { | ||
| var id = event.getButtonInteraction().getCustomId().split(":"); | ||
| ButtonHandler handler = (ButtonHandler) getHandlerByName(id[0]); | ||
| try { | ||
| handler.handleButtonInteraction(event.getButtonInteraction()).respond(); | ||
| } catch (ResponseException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| } | ||
| @Override | ||
| public void onSelectMenuChoose(SelectMenuChooseEvent event) { | ||
| var id = event.getSelectMenuInteraction().getCustomId().split(":"); | ||
| SelectionMenuHandler handler = (SelectionMenuHandler) getHandlerByName(id[0]); | ||
| try { | ||
| handler.handleSelectMenuInteraction(event.getSelectMenuInteraction()).respond(); | ||
| } catch (ResponseException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| } | ||
| /** | ||
| * Tries to get a Class by the specified name | ||
| * (Class paths are baked into the button id) and returns it. | ||
| * @param name the class name | ||
| * @return The handler class | ||
| */ | ||
| private Object getHandlerByName(String name) { | ||
| try { | ||
| return Class.forName(name) | ||
| .getDeclaredConstructor() | ||
| .newInstance(); | ||
| } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | | ||
| IllegalAccessException | InvocationTargetException e) { | ||
| e.printStackTrace(); | ||
| return null; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| package net.javadiscord.javabot2.command.interaction.button; | ||
| import org.javacord.api.entity.emoji.Emoji; | ||
| import org.javacord.api.entity.message.component.Button; | ||
| import org.javacord.api.entity.message.component.ButtonBuilder; | ||
| import org.javacord.api.entity.message.component.ButtonStyle; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| /** | ||
| * Class that represents a single Button Interaction. | ||
| */ | ||
| public class ButtonAction { | ||
| private final String label; | ||
| private final ButtonStyle buttonStyle; | ||
| private Class<? extends ButtonHandler> handler; | ||
| private final List<String> params; | ||
| private boolean disabled = false; | ||
| private String url; | ||
| private Emoji emoji; | ||
| /** | ||
| * Constructor of the Button Action. | ||
| * @param label the button's label | ||
| * @param buttonStyle the button's {@link ButtonStyle} | ||
| */ | ||
| public ButtonAction(String label, ButtonStyle buttonStyle) { | ||
| this.params = new ArrayList<>(); | ||
| this.label = label; | ||
| this.buttonStyle = buttonStyle; | ||
| } | ||
| /** | ||
| * Sets a handler class for this button interaction. | ||
| * The class must extend {@link ButtonHandler}. | ||
| * @param handler a class that should handle the button interaction. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public ButtonAction handledBy(Class<? extends ButtonHandler> handler) { | ||
| this.handler = handler; | ||
| return this; | ||
| } | ||
| /** | ||
| * Adds a parameter, which is later baked into the button id. | ||
| * @param param an object that is later converted to a string to bake it into the button id as a parameter. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public ButtonAction addParam(Object param) { | ||
| params.add(String.valueOf(param)); | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, check that the param's string representation cannot contain the | ||
| return this; | ||
| } | ||
| /** | ||
| * Enables/Disables the button based on the provided boolean. | ||
| * @param disabled the boolean which enables/disables the button. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public ButtonAction setDisabled(boolean disabled) { | ||
| this.disabled = disabled; | ||
| return this; | ||
| } | ||
| /** | ||
| * Sets an Url for this button. | ||
| * This only works for buttons with the {@link ButtonStyle#LINK} button style. | ||
| * @param url the url as a string. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public ButtonAction setUrl(String url) { | ||
| this.url = url; | ||
| return this; | ||
| } | ||
| /** | ||
| * Sets an Emoji for this button. | ||
| * @param emoji the emoji which should be used. | ||
| * @return the current instance in order to allow chain call methods. | ||
| */ | ||
| public ButtonAction setEmoji(Emoji emoji) { | ||
| this.emoji = emoji; | ||
| return this; | ||
| } | ||
| /** | ||
| * Returns the compiled button id. Every parameter is seperated with a colon. | ||
| * The first argument is always the handler's class path. | ||
| * After that, all set params ({@link ButtonAction#addParam(Object)}) get appended to the id. | ||
| * @return the compiled button id. | ||
| */ | ||
| public String getCustomId() { | ||
| StringBuilder id = new StringBuilder(handler.getName()); | ||
| for (String param : params) { | ||
| id.append(":").append(param); | ||
| } | ||
| return id.toString(); | ||
| } | ||
| /** | ||
| * Returns the button's {@link ButtonStyle}. | ||
| * @return the button's {@link ButtonStyle}. | ||
| */ | ||
| public ButtonStyle getButtonStyle() { | ||
| return buttonStyle; | ||
| } | ||
| /** | ||
| * Returns the button's label. | ||
| * @return the button's label | ||
| */ | ||
| public String getLabel() { | ||
| return label; | ||
| } | ||
| /** | ||
| * Returns the button's handler class. | ||
| * @return The handler class | ||
| */ | ||
| public Class<? extends ButtonHandler> getHandler() { | ||
| return handler; | ||
| } | ||
| /** | ||
| * Returns a list with all parameters of the button. | ||
| * @return A List with all parameters. | ||
| */ | ||
| public List<String> getParams() { | ||
| return params; | ||
| } | ||
| /** | ||
| * Returns the complete button. | ||
| * @return the compiled button. | ||
| */ | ||
| public Button getButton() { | ||
| var builder = new ButtonBuilder() | ||
| .setLabel(label) | ||
| .setStyle(buttonStyle) | ||
| .setDisabled(disabled); | ||
| if (buttonStyle != ButtonStyle.LINK) builder.setCustomId(getCustomId()); | ||
| if (url != null && url.length() > 0 && buttonStyle == ButtonStyle.LINK) builder.setUrl(url); | ||
| if (emoji != null) builder.setEmoji(emoji); | ||
| return builder.build(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package net.javadiscord.javabot2.command.interaction.button; | ||
| import net.javadiscord.javabot2.command.ResponseException; | ||
| import org.javacord.api.interaction.ButtonInteraction; | ||
| import org.javacord.api.interaction.callback.InteractionImmediateResponseBuilder; | ||
| /** | ||
| * An interface that should be implemented by any class that is utilizing | ||
| * button interactions. | ||
| */ | ||
| public interface ButtonHandler { | ||
| InteractionImmediateResponseBuilder handleButtonInteraction(ButtonInteraction interaction) throws ResponseException; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a check to make sure that the label does not contain the
':'character. Throw an IllegalArgumentException if so, since this will mess up handling the interaction later on.