|
10 | 10 | import net.dv8tion.jda.api.components.selections.SelectOption; |
11 | 11 | import net.dv8tion.jda.api.components.selections.StringSelectMenu; |
12 | 12 | import net.dv8tion.jda.api.entities.Member; |
| 13 | +import net.dv8tion.jda.api.entities.Message; |
| 14 | +import java.util.stream.Stream; |
13 | 15 | import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; |
14 | 16 | import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; |
15 | 17 | import org.jspecify.annotations.NonNull; |
@@ -104,10 +106,41 @@ public void handleStringSelectMenu(@NonNull StringSelectInteractionEvent event, |
104 | 106 | Language language = Language.fromString(values.getFirst()); |
105 | 107 | event.deferEdit().queue(); |
106 | 108 |
|
| 109 | + Runnable onError = () -> Responses.error(event.getHook(), |
| 110 | + "Could not update the code block — it may have changed or no longer be yours.").queue(); |
107 | 111 | LinkedMessages.resolveAfter(event.getMessage(), Integer.parseInt(id[2]), |
108 | | - messages -> messages.forEach(message -> |
109 | | - message.editMessage(withLanguage(message.getContentRaw(), language)).queue()), |
110 | | - () -> Responses.error(event.getHook(),"Could not update the code block").queue()); |
| 112 | + messages -> { |
| 113 | + if (ownsBlock(messages, event.getUser().getIdLong())) { |
| 114 | + messages.forEach(message -> |
| 115 | + message.editMessage(withLanguage(message.getContentRaw(), language)).queue()); |
| 116 | + } else { |
| 117 | + onError.run(); |
| 118 | + } |
| 119 | + }, |
| 120 | + onError); |
| 121 | + } |
| 122 | + |
| 123 | + private static boolean ownsBlock(List<Message> messages, long userId) { |
| 124 | + Message last = messages.get(messages.size() - 1); |
| 125 | + boolean lastIsUsers = buttonsOf(last).anyMatch(button -> isDeleteButtonOf(button, userId)); |
| 126 | + boolean noOtherHasButton = messages.subList(0, messages.size() - 1).stream() |
| 127 | + .flatMap(FormatCodeInteractionHandler::buttonsOf) |
| 128 | + .noneMatch(FormatCodeInteractionHandler::isDeleteButton); |
| 129 | + return lastIsUsers && noOtherHasButton; |
| 130 | + } |
| 131 | + |
| 132 | + private static Stream<Button> buttonsOf(Message message) { |
| 133 | + return message.getComponents().stream() |
| 134 | + .flatMap(component -> component instanceof ActionRow row ? row.getButtons().stream() : Stream.of()); |
| 135 | + } |
| 136 | + |
| 137 | + private static boolean isDeleteButton(Button button) { |
| 138 | + return button.getCustomId() != null && button.getCustomId().startsWith(COMPONENT_ID + ":"); |
| 139 | + } |
| 140 | + |
| 141 | + private static boolean isDeleteButtonOf(Button button, long userId) { |
| 142 | + return isDeleteButton(button) |
| 143 | + && Long.parseLong(ComponentIdBuilder.split(button.getCustomId())[1]) == userId; |
111 | 144 | } |
112 | 145 |
|
113 | 146 | private boolean canManage(Member member, long requesterId) { |
|
0 commit comments