Skip to content

feat: delete-all button and language dropdown for multi-message code blocks#550

Open
Neil-Tomar wants to merge 1 commit into
Java-Discord:mainfrom
Neil-Tomar:feat/format-code-message-linking
Open

feat: delete-all button and language dropdown for multi-message code blocks#550
Neil-Tomar wants to merge 1 commit into
Java-Discord:mainfrom
Neil-Tomar:feat/format-code-message-linking

Conversation

@Neil-Tomar

Copy link
Copy Markdown
Contributor

What

Multi-message formatted code blocks now have two interactions, backed by a small message-linking helper:

  • Delete-all button — removes every message of the block in one click
  • Language dropdown (ephemeral) — re-colors every chunk to a chosen language

How

  • LinkedMessages resolves the block from the component's message (getHistoryBefore/After), touching only the bot's own messages.
  • FormatCodeInteractionHandler handles the delete button and the language dropdown.
  • Permission: requester / staff / owner (same rule as the existing delete button).

Open questions

  • The language dropdown is ephemeral per your suggestion, so it's a one-time picker that's gone on reload — happy to make it a permanent public control instead.
  • Rare edge case: two simultaneous formats could interleave bot messages; the resolver is best-effort there.

…ching

Delete-all button removes every message of a block; ephemeral language dropdown re-colors every chunk. Only the bot's own messages are touched.
@Neil-Tomar Neil-Tomar requested a review from a team as a code owner July 4, 2026 15:41
@AutoDetectableComponentHandler(FormatCodeInteractionHandler.COMPONENT_ID)
@RequiredArgsConstructor
public class FormatCodeInteractionHandler implements ButtonHandler, StringSelectMenuHandler {
static final String COMPONENT_ID = "format-code-delete";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The select menu isn't about deleting hence the id format-code-delete isn't appropriate.

* @return the delete-all button
*/
public static Button createDeleteAllButton(long requesterID, int total){
return Button.secondary(ComponentIdBuilder.build(COMPONENT_ID,requesterID,total),"\uD83D\uDDD1️");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why such a special 1 character is used by InteractionUtils but it would be good if you could change it to use a normal 1 instead of it.

}

@Override
public void handleStringSelectMenu(@NonNull StringSelectInteractionEvent event, @NonNull List<String> values) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation is messed up here.

}

event.deferEdit().queue();
var channel = event.getChannel();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please use the proper type here? I assume it's a MessageChannel?

Language language = Language.fromString(values.getFirst());
event.deferEdit().queue();

LinkedMessages.resolveForward(event.getChannel(), event.getMessage(), Integer.parseInt(id[2]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the channel argument really needed here? Can't you derive it from the message?

* @param total the number of messages in the block
* @param onResolved receives the bot's messages that make up the block
*/
static void resolve(MessageChannel channel, Message triggerMessage, int total, Consumer<List<Message>> onResolved) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need the channel argument as you can use triggerMessage.getChannel() instead?

* @param total the number of messages in the block
* @param onResolved receives the bot's messages that make up the block
*/
static void resolveForward(MessageChannel channel, Message anchorMessage, int total, Consumer<List<Message>> onResolved) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need the channel argument as you can use anchorMessage.getChannel() instead?

event.deferEdit().queue();
var channel = event.getChannel();
LinkedMessages.resolve(channel, event.getMessage(), Integer.parseInt(id[2]),
messages -> messages.forEach(message -> message.delete().queue()));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*/
static void resolveForward(MessageChannel channel, Message anchorMessage, int total, Consumer<List<Message>> onResolved) {
channel.getHistoryAfter(anchorMessage.getIdLong(), total).queue(history ->
onResolved.accept(onlyOwn(channel, history.getRetrievedHistory())));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also perform the same message check/error handling approach here as well.

onResolved.accept(onlyOwn(channel, history.getRetrievedHistory())));
}

private static List<Message> onlyOwn(MessageChannel channel, List<Message> messages) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the channel argument isn't used here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants