diff --git a/.classpath b/.classpath index d91be04..2d9bac5 100644 --- a/.classpath +++ b/.classpath @@ -39,17 +39,11 @@ - - - - - - diff --git a/pom.xml b/pom.xml index ede01b5..5dd077b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,30 +1,31 @@ - 4.0.0 org.springframework.boot spring-boot-starter-parent 3.4.5 - + net.foxgenesis customjail 0.1.0 Custom Jail Demo project for Spring Boot - + - + - + - - - - + + + + 17 @@ -34,13 +35,13 @@ org.springframework.boot spring-boot-starter - + net.foxgenesis watame 0.1.0 - + net.foxgenesis role-storage @@ -58,5 +59,11 @@ spring-boot-configuration-processor true + + + org.projectlombok + lombok + true + diff --git a/src/main/java/net/foxgenesis/customjail/CommonMessages.java b/src/main/java/net/foxgenesis/customjail/CommonMessages.java new file mode 100644 index 0000000..6091e88 --- /dev/null +++ b/src/main/java/net/foxgenesis/customjail/CommonMessages.java @@ -0,0 +1,41 @@ +package net.foxgenesis.customjail; + +import java.util.Objects; + +import org.springframework.context.MessageSourceResolvable; + +public enum CommonMessages implements MessageSourceResolvable { + MEMBER("customjail.embed.member"), + MODERATOR("customjail.embed.moderator"), + ANONYMOUS("customjail.anonymous"), + ACCEPT("customjail.embed.accept"), + ACCEPTED("customjail.embed.accepted"), + YES("customjail.embed.yes"), + NO("customjail.embed.no"), + REASON("customjail.embed.reason"), + DEFAULT_REASON("customjail.embed.defaultReason"), + WARNING_LEVEL("customjail.embed.warning-level"), + TOTAL_WARNINGS("customjail.embed.total-warnings"), + WARNING_EXPIRES("customjail.embed.warning-expires"), + WITH_WARNING("customjail.embed.with-warning"), + NA("customjail.embed.na"), + CASE_ID("customjail.embed.caseid"), + DURATION("customjail.embed.duration"), + TIME_LEFT("customjail.embed.time-left"), + JAIL_DETAILS("customjail.container.jaildetails"), + UNJAIL("customjail.embed.unjail"), + FORCESTART("customjail.embed.forcestart"), + MEMBER_JAILED("customjail.embed.jailed"); + + private final String[] codes; + + CommonMessages(String code) { + this.codes = new String[] { Objects.requireNonNull(code) }; + } + + @Override + public String[] getCodes() { + return codes; + } + +} diff --git a/src/main/java/net/foxgenesis/customjail/CustomJailAutoConfiguration.java b/src/main/java/net/foxgenesis/customjail/CustomJailAutoConfiguration.java index 0b86e46..df53819 100644 --- a/src/main/java/net/foxgenesis/customjail/CustomJailAutoConfiguration.java +++ b/src/main/java/net/foxgenesis/customjail/CustomJailAutoConfiguration.java @@ -27,6 +27,7 @@ import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.InteractionContextType; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.Command.Choice; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; @@ -194,7 +195,7 @@ private static CommandData user(String id, DefaultMemberPermissions permissions, LocalizationFunction localization) { return Commands.user(id) // Set guild only - .setGuildOnly(true) + .setContexts(InteractionContextType.GUILD) // Set default permissions .setDefaultPermissions(permissions) // Set localization @@ -205,7 +206,7 @@ private static SlashCommandData slash(String id, String description, DefaultMemb LocalizationFunction localization) { return Commands.slash(id, description) // Set guild only - .setGuildOnly(true) + .setContexts(InteractionContextType.GUILD) // Set default permissions .setDefaultPermissions(permissions) // Set localization diff --git a/src/main/java/net/foxgenesis/customjail/JailFrontend.java b/src/main/java/net/foxgenesis/customjail/JailFrontend.java index c519570..65d30ce 100644 --- a/src/main/java/net/foxgenesis/customjail/JailFrontend.java +++ b/src/main/java/net/foxgenesis/customjail/JailFrontend.java @@ -4,51 +4,47 @@ import java.util.Locale; import java.util.NoSuchElementException; import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.function.Supplier; import org.springframework.beans.factory.annotation.Autowired; - +import org.springframework.context.MessageSourceResolvable; + +import net.dv8tion.jda.api.components.label.Label; +import net.dv8tion.jda.api.components.selections.SelectMenu; +import net.dv8tion.jda.api.components.selections.SelectOption; +import net.dv8tion.jda.api.components.selections.StringSelectMenu; +import net.dv8tion.jda.api.components.textdisplay.TextDisplay; +import net.dv8tion.jda.api.components.textinput.TextInput; +import net.dv8tion.jda.api.components.textinput.TextInputStyle; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent; -import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.components.ActionRow; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.selections.SelectMenu; -import net.dv8tion.jda.api.interactions.components.selections.SelectOption; -import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu; -import net.dv8tion.jda.api.interactions.components.text.TextInput; -import net.dv8tion.jda.api.interactions.components.text.TextInputStyle; -import net.dv8tion.jda.api.interactions.modals.Modal; +import net.dv8tion.jda.api.modals.Modal; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; +import net.dv8tion.jda.api.utils.MarkdownUtil; import net.foxgenesis.customjail.database.warning.Warning; import net.foxgenesis.customjail.jail.JailDetails; import net.foxgenesis.customjail.jail.JailSystem; import net.foxgenesis.customjail.jail.exception.LocalizedException; import net.foxgenesis.customjail.util.CustomTime; import net.foxgenesis.customjail.util.Utilities; -import net.foxgenesis.watame.util.discord.Colors; import net.foxgenesis.watame.util.discord.DiscordUtils; -import net.foxgenesis.watame.util.discord.InteractionListener; -import net.foxgenesis.watame.util.discord.Response; +import net.foxgenesis.watame.util.discord.components.Response; import net.foxgenesis.watame.util.lang.DiscordLocaleMessageSource; -import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.Localized; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; +import net.foxgenesis.watame.util.lang.LocalizedModalBuilder; public class JailFrontend extends ListenerAdapter { @@ -70,7 +66,8 @@ public void onUserContextInteraction(UserContextInteractionEvent event) { if (jail.isJailed(event.getTargetMember())) error(event, "customjail.alreadyJailed").queue(); else - new JailUserListener(event); +// new JailUserListener(event); + displayJailModal(event); } case "Jail Details" -> { @@ -81,33 +78,22 @@ public void onUserContextInteraction(UserContextInteractionEvent event) { if (!jail.isJailed(member)) error(event, "customjail.notJailed").queue(); else if (isNonBotUser(event, member)) { - Optional jailEndTimestamp = jail.getJailEndTimestamp(member); - boolean isTimerRunning = jailEndTimestamp.isPresent(); - // Create embed JailDetails details = jail.getJailDetails(member); - LocalizedEmbedBuilder builder = new LocalizedEmbedBuilder(messages, locale); - details.applyToEmbedBuilder(builder, messages, locale, member, - jail.getJailEndTimestamp(member)); - - MessageEmbed embed = builder.build(); - - // Create actions - ActionRow interactions = ActionRow.of( - Button.danger(Utilities.Interactions.wrapInteraction("forcestart", member), - messages.getMessage("customjail.embed.forcestart", locale)) - .withDisabled(isTimerRunning), - Button.danger(Utilities.Interactions.wrapInteraction("unjail", member), - messages.getMessage("customjail.embed.unjail", locale))); + LocalizedContainerBuilder cb = new LocalizedContainerBuilder(messages, locale); + details.applyToContainerBuilder(cb, member, jail.getJailEndTimestamp(member)); // Reply with embed and actions - event.replyEmbeds(embed).setComponents(interactions).setEphemeral(true).queue(); + event.replyComponents(cb.build()) + // This is required any time you are using Components V2 + .useComponentsV2().setEphemeral(true).queue(); } } case "View Warnings" -> { if (isValidUser(event, event.getTargetMember())) { - new WarningPage(event, jail, event.getTargetMember(), messages); + // new WarningPage(event, jail, event.getTargetMember(), messages); + new WarningPageContainer(event, jail, event.getTargetMember(), messages); } } } @@ -161,6 +147,28 @@ public void onModalInteraction(ModalInteractionEvent event) { if (Utilities.Interactions.unwrapInteraction(event, (id, unwrappedMember, variant) -> { unwrappedMember.ifPresentOrElse(member -> { switch (id) { + // Callback from jail user modal + case "jailuser" -> { + if (isValidUser(event, member)) + if (jail.isJailed(member)) { + error(event, "customjail.alreadyJailed").queue(); + return; + } + + CustomTime duration = event.getValue("time-selection").getAsStringList().stream() + .reduce((a, b) -> a + b).map(CustomTime::new).orElseThrow(); + boolean active = Boolean.valueOf(event.getValue("add-warning").getAsStringList().get(0)); + boolean anon = Boolean.valueOf(event.getValue("anon").getAsStringList().get(0)); + String reason = event.getValue("reason").getAsString(); + + attemptAction(event, (hook, locale) -> { + jail.jail(member, event.getMember(), duration, reason, active, anon); + + String response = messages.getMessage("customjail.embed.jailed-user", new Object[] { + member.getAsMention(), duration.getLocalizedDisplayString(messages, locale) }, locale); + return Response.success(response); + }).queue(); + } case "addreason" -> { // Ensure the callback is valid if (variant.isEmpty()) { @@ -275,7 +283,7 @@ private void handleWarningCommands(SlashCommandInteractionEvent event) { case "list" -> { Member member = event.getOption("user", OptionMapping::getAsMember); if (isNonBotUser(event, member)) - new WarningPage(event, jail, member, messages); + new WarningPageContainer(event, jail, member, messages); } // Add warning case "add" -> { @@ -422,187 +430,93 @@ private void displayReasonModal(GenericComponentInteractionCreateEvent event, Su wrappedMember != null ? wrappedMember.get() : event.getMember(), callback), messages.getMessage("customjail.modal.title", locale)); - TextInput body = TextInput - .create("reason", messages.getMessage("customjail.embed.reason", locale), TextInputStyle.PARAGRAPH) + TextInput body = TextInput.create("reason", TextInputStyle.PARAGRAPH) .setPlaceholder(messages.getMessage("customjail.modal.placeholder", locale)).setMinLength(3) .setMaxLength(500).setRequired(false).build(); - builder.addActionRow(body); + builder.addComponents(Label.of(messages.getMessage(CommonMessages.REASON, locale), body)); event.replyModal(builder.build()).queue(); } - private class JailUserListener extends InteractionListener { - private CompletableFuture expirationFuture; - - private final Member member; - private final int warningLevel; - private final int warnings; - private final String warningExpires; - - private CustomTime time; - - public JailUserListener(UserContextInteractionEvent event) { - super(event); - this.member = event.getTargetMember(); - this.warningLevel = jail.getWarningLevel(member); - this.warnings = jail.getTotalWarnings(member); - this.warningExpires = jail.getWarningEndTimestamp(member) - .orElseGet(() -> messages.getMessage("customjail.embed.na", locale)); - - ActionRow interactions = ActionRow.of(getAddWarningButton(true), addAnonButton(true), - Button.danger("jailuser", messages.getMessage("customjail.embed.jail-user", locale)).asDisabled()); - - InteractionHook hook = event.getHook(); - event.replyEmbeds(createJailEmbed()) - // Add time menu - .addActionRow(getTimeMenu()) - // Add buttons - .addComponents(interactions) - // Set user only - .setEphemeral(true) - // Send - .queue(v -> { - hook.getJDA().addEventListener(this); - expirationFuture = CompletableFuture.runAsync(() -> { - hook.getJDA().removeEventListener(this); - hook.editOriginalEmbeds( - Response.error(messages.getMessage("watame.interaction.expired", null, locale))) - .setReplace(true).queue(); - }, CompletableFuture.delayedExecutor(894, TimeUnit.SECONDS)); - }); - } + private void displayJailModal(UserContextInteractionEvent event) { + Locale locale = event.getUserLocale().toLocale(); + Member target = event.getTargetMember(); - @Override - public void onButtonInteraction(ButtonInteractionEvent event) { - if (!shouldRespond(event)) - return; - switch (event.getButton().getId()) { - case "with-warning" -> event.editButton(getAddWarningButton(false)).queue(); - case "without-warning" -> event.editButton(getAddWarningButton(true)).queue(); - case "anon" -> event.editButton(addAnonButton(false)).queue(); - case "non-anon" -> event.editButton(addAnonButton(true)).queue(); - case "jailuser" -> event.replyModal(createJailModal(member)).queue(); - } - } + LocalizedModalBuilder builder = new LocalizedModalBuilder(messages, locale, + Utilities.Interactions.wrapInteraction("jailuser", target, "jailuser"), "customjail.embed.jail-user"); - @Override - public void onStringSelectInteraction(StringSelectInteractionEvent event) { - if (!shouldRespond(event)) - return; - switch (event.getComponentId()) { - case "time-selection" -> { - time = event.getValues().stream().reduce((a, b) -> a + b).map(CustomTime::new).orElseThrow(); - - Message message = event.getMessage(); - Button withWarning = message.getButtonById("with-warning"), - withoutWarning = message.getButtonById("without-warning"), anon = message.getButtonById("anon"), - nonAnon = message.getButtonById("non-anon"), jailButton = message.getButtonById("jailuser"); - - event.editComponents( - ActionRow.of(event.getSelectMenu().createCopy().setDefaultValues(event.getValues()).build()), - ActionRow.of(withWarning != null ? withWarning : withoutWarning, anon != null ? anon : nonAnon, - jailButton.asEnabled())) - .queue(); - } - } - } + TextDisplay details = getJailModalDetails(target, locale); - @Override - public void onModalInteraction(ModalInteractionEvent event) { - Message.Interaction interactionContext = event.getMessage().getInteraction(); - if (interactionContext != null && interactionContext.getIdLong() == id) { - Message message = event.getMessage(); + TextInput body = TextInput.create("reason", TextInputStyle.PARAGRAPH) + .setPlaceholder(messages.getMessage("customjail.modal.placeholder", locale)).setMinLength(3) + .setMaxLength(500).setRequired(false).build(); - boolean withWarning = message.getButtonById("with-warning") != null; - boolean anon = message.getButtonById("anon") != null; - String reason = event.getValue("reason").getAsString(); + SelectOption[] yesNo = new SelectOption[] { + SelectOption.of(messages.getMessage(CommonMessages.YES, locale), Boolean.TRUE.toString()), + SelectOption.of(messages.getMessage(CommonMessages.NO, locale), Boolean.FALSE.toString()) }; + SelectMenu addWarning = StringSelectMenu.create("add-warning").addOptions(yesNo).setDefaultOptions(yesNo[0]) + .setRequired(true).build(); + SelectMenu anon = StringSelectMenu.create("anon").addOptions(yesNo).setDefaultOptions(yesNo[0]) + .setRequired(true).build(); - expirationFuture.cancel(true); - event.getJDA().removeEventListener(this); + SelectMenu timeMenu = getTimeMenu(locale); - event.deferEdit().flatMap(hook -> { - Locale locale = event.getUserLocale().toLocale(); + builder.addComponents(details); + builder.addLocalizedLabelWithDescription(CommonMessages.DURATION, + Localized.resolved("customjail.embed.duration-description"), timeMenu); + builder.addLocalizedLabelWithDescription(CommonMessages.WITH_WARNING, + Localized.resolved("customjail.embed.with-warning-description"), addWarning); + builder.addLocalizedLabelWithDescription(CommonMessages.ANONYMOUS, + Localized.resolved("customjail.embed.anonymous-description"), anon); - MessageEmbed embed = null; - try { - jail.jail(member, event.getMember(), time, reason, withWarning, anon); + builder.addLocalizedLabelWithDescription(CommonMessages.REASON, + Localized.resolved("customjail.embed.reason-description"), body); - embed = Response.success(messages.getMessage("customjail.embed.jailed-user", new Object[] { - member.getAsMention(), time.getLocalizedDisplayString(messages, locale) }, locale)); - } catch (LocalizedException e) { - embed = Response.error(messages.getMessage(e.getErrorMessage(), locale)); - } catch (Exception e) { - embed = Response.error(DiscordUtils.toString(e)); - } + event.replyModal(builder.build()).queue(); + } - return hook.editOriginalEmbeds(embed != null ? embed : Response.error("Uknown error while jailing")) - .setReplace(true); - }).queue(); - } - } + private TextDisplay getJailModalDetails(Member target, Locale locale) { + int warningLevel = jail.getWarningLevel(target); + int totalWarnings = jail.getTotalWarnings(target); + Object expires = jail.getWarningEndTimestamp(target).map(Object.class::cast).orElse(CommonMessages.NA); - private MessageEmbed createJailEmbed() { - LocalizedEmbedBuilder builder = new LocalizedEmbedBuilder(messages, locale); - builder.setColor(Colors.INFO); - builder.setLocalizedTitle("customjail.embed.jail-user"); - builder.setThumbnail(member.getEffectiveAvatarUrl()); - - builder.addLocalizedField("customjail.embed.member", member.getAsMention(), true); - builder.addLocalizedField("customjail.embed.warning-level", "" + warningLevel, true); - builder.addLocalizedField("customjail.embed.total-warnings", "" + warnings, true); - builder.addLocalizedField("customjail.embed.warning-expires", warningExpires, false); - return builder.build(); - } + StringBuilder builder = new StringBuilder(); - private Button addAnonButton(boolean anon) { - return anon - ? Button.primary("anon", messages.getMessage("customjail.embed.anon", locale)) - .withEmoji(Emoji.fromFormatted("U+1F92B")) - : Button.secondary("non-anon", messages.getMessage("customjail.embed.non-anon", locale)) - .withEmoji(Emoji.fromFormatted("U+1F4E3")); - } + appendBoldField(builder, locale, CommonMessages.MEMBER, target.getAsMention()); + appendBoldField(builder, locale, CommonMessages.WARNING_LEVEL, MarkdownUtil.monospace(warningLevel + "")); + appendBoldField(builder, locale, CommonMessages.TOTAL_WARNINGS, MarkdownUtil.monospace(totalWarnings + "")); + appendBoldField(builder, locale, CommonMessages.WARNING_EXPIRES, expires); - private Button getAddWarningButton(boolean addWarning) { - return addWarning - ? Button.primary("with-warning", messages.getMessage("customjail.embed.with-warning", locale)) - .withEmoji(Emoji.fromFormatted("U+2705")) - : Button.secondary("without-warning", - messages.getMessage("customjail.embed.without-warning", locale)) - .withEmoji(Emoji.fromFormatted("U+274C")); - } + return TextDisplay.of(builder.toString()); + } - private SelectMenu getTimeMenu() { - SelectOption[] options = Arrays - // Stream times - .stream(jail.getJailTimings()) - // Create select option - .map(time -> SelectOption.of(new CustomTime(time).getLocalizedDisplayString(messages, locale), - time)) - // To array - .toArray(SelectOption[]::new); - - return StringSelectMenu - // Set ID - .create("time-selection") - // Set placeholder - .setPlaceholder(messages.getMessage("customjail.embed.set-time", locale)) - // Add time options - .addOptions(options) - // Build - .build(); + private void appendBoldField(StringBuilder builder, Locale locale, Object... args) { + Object[] resolved = Arrays.copyOf(args, args.length); + for (int i = 0; i < resolved.length; i++) { + Object arg = resolved[i]; + if (arg instanceof MessageSourceResolvable resolvable) + resolved[i] = messages.getMessage(resolvable, locale); } + builder.append(String.format("**%s:** %s\n", resolved)); + } - private Modal createJailModal(Member member) { - Modal.Builder builder = Modal.create(Utilities.Interactions.wrapInteraction("jailuser", member), - messages.getMessage("customjail.modal.title", locale)); - - TextInput body = TextInput - .create("reason", messages.getMessage("customjail.embed.reason", locale), TextInputStyle.PARAGRAPH) - .setPlaceholder(messages.getMessage("customjail.modal.placeholder", locale)).setMinLength(3) - .setMaxLength(500).setRequired(false).build(); - - builder.addActionRow(body); - return builder.build(); - } + private SelectMenu getTimeMenu(Locale locale) { + SelectOption[] options = Arrays + // Stream times + .stream(jail.getJailTimings()) + // Create select option + .map(time -> SelectOption.of(new CustomTime(time).getLocalizedDisplayString(messages, locale), time)) + // To array + .toArray(SelectOption[]::new); + + return StringSelectMenu + // Set ID + .create("time-selection") + // Set placeholder + .setPlaceholder(messages.getMessage("customjail.embed.set-time", locale)) + // Add time options + .addOptions(options) + // Build + .build(); } } diff --git a/src/main/java/net/foxgenesis/customjail/WarningPage.java b/src/main/java/net/foxgenesis/customjail/WarningPage.java deleted file mode 100644 index 6b0700e..0000000 --- a/src/main/java/net/foxgenesis/customjail/WarningPage.java +++ /dev/null @@ -1,119 +0,0 @@ -package net.foxgenesis.customjail; - -import java.util.Iterator; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import org.springframework.context.MessageSource; -import org.springframework.context.MessageSourceResolvable; -import org.springframework.context.support.DefaultMessageSourceResolvable; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; -import net.dv8tion.jda.api.utils.MarkdownUtil; -import net.dv8tion.jda.api.utils.TimeFormat; -import net.foxgenesis.customjail.database.warning.Warning; -import net.foxgenesis.customjail.jail.WarningSystem; -import net.foxgenesis.customjail.util.CachedObject; -import net.foxgenesis.watame.util.discord.Colors; -import net.foxgenesis.watame.util.discord.DiscordUtils; -import net.foxgenesis.watame.util.discord.Response; -import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; -import net.foxgenesis.watame.util.lang.LocalizedPageMenu; - -public class WarningPage extends LocalizedPageMenu { - private static final MessageSourceResolvable NA = new DefaultMessageSourceResolvable("customjail.embed.na"); - - private final WarningSystem database; - private final Member target; - - private final CachedObject warningLevelCache; - private final CachedObject expiresCache; - - public WarningPage(GenericCommandInteractionEvent event, WarningSystem database, Member target, - MessageSource source) { - super(event, database.getWarningPage(target, PageRequest.of(0, 3, Sort.by("time").descending())), source); - this.database = Objects.requireNonNull(database); - this.target = Objects.requireNonNull(target); - - // Cache Database calls - this.warningLevelCache = new CachedObject<>(() -> database.getWarningLevel(target), 15, TimeUnit.SECONDS); - this.expiresCache = new CachedObject<>( - () -> database.getWarningEndTimestamp(target).orElseGet(() -> messages.getMessage(NA, locale)), 15, - TimeUnit.SECONDS); - - this.sendInitalMessage(event); - } - - @Override - protected MessageEmbed createEmbed(Page page, Locale locale) { - LocalizedEmbedBuilder builder = new LocalizedEmbedBuilder(messages, locale); - builder.setColor(Colors.INFO); - builder.setThumbnail(target.getEffectiveAvatarUrl()); - - builder.appendLocalizedDescription("customjail.embed.warning.title", target.getAsMention()); - builder.newLine(); - - builder.appendLocalizedDescription("customjail.embed.warning.level", warningLevelCache.get()); - builder.newLine(); - - builder.appendLocalizedDescription("customjail.embed.warning.expires", expiresCache.get()); - builder.newLine(); - builder.newLine(); - - // Write notes - writeNotes(builder, page, locale); - - Object[] args = { page.getTotalElements(), page.getNumber() + 1, page.getTotalPages() }; - builder.setLocalizedFooter("customjail.warnings.footer", args); - - return builder.build(); - } - - private void writeNotes(LocalizedEmbedBuilder builder, Page page, Locale locale) { - StringBuilder sb = builder.getDescriptionBuilder(); - sb.append(">>> "); - - Iterator iterator = page.iterator(); - while (iterator.hasNext()) { - Warning warning = iterator.next(); - // FIXME: clean up and make readable - // "%1$s#%caseid%:% messages.getMessage("customjail.embed.defaultReason", null, locale))); - - if (iterator.hasNext()) - sb.append("\n\n"); - } - } - - @Override - protected MessageEmbed createEmptyPageEmbed(Locale locale) { - return Response - .error(messages.getMessage("customjail.warnings.empty", null, "customjail.warnings.empty", locale)); - } - - @Override - protected Page getNewPage(Pageable pagable) { - return database.getWarningPage(target, pagable); - } - - @Override - protected MessageEmbed createExpiredEmbed(Locale locale) { - return Response.error(messages.getMessage(INTERACTION_EXPIRED, locale)); - } -} diff --git a/src/main/java/net/foxgenesis/customjail/WarningPageContainer.java b/src/main/java/net/foxgenesis/customjail/WarningPageContainer.java new file mode 100644 index 0000000..92d3fc4 --- /dev/null +++ b/src/main/java/net/foxgenesis/customjail/WarningPageContainer.java @@ -0,0 +1,132 @@ +package net.foxgenesis.customjail; + +import java.util.Iterator; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import net.dv8tion.jda.api.components.container.Container; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; +import net.dv8tion.jda.api.utils.TimeFormat; +import net.foxgenesis.customjail.database.warning.Warning; +import net.foxgenesis.customjail.jail.WarningSystem; +import net.foxgenesis.customjail.util.CachedObject; +import net.foxgenesis.watame.util.StringUtils; +import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.discord.DiscordUtils; +import net.foxgenesis.watame.util.discord.components.ComponentUtils; +import net.foxgenesis.watame.util.lang.Localized; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; +import net.foxgenesis.watame.util.lang.LocalizedContainerPageMenu; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; + +public class WarningPageContainer extends LocalizedContainerPageMenu { + private static final MessageSourceResolvable TITLE = Localized.resolved("customjail.embed.warnings"); + + private final WarningSystem database; + private final Member target; + + private final CachedObject warningLevelCache; + private final CachedObject totalWarningsCache; + private final CachedObject expiresCache; + + public WarningPageContainer(GenericCommandInteractionEvent event, WarningSystem database, Member target, + MessageSource source) { + super(event, database.getWarningPage(target, PageRequest.of(0, 3, Sort.by("time").descending())), source); + this.database = Objects.requireNonNull(database); + this.target = Objects.requireNonNull(target); + + warningLevelCache = new CachedObject<>(() -> database.getWarningLevel(target), 15, TimeUnit.SECONDS); + totalWarningsCache = new CachedObject<>(() -> database.getTotalWarnings(target), 15, TimeUnit.SECONDS); + expiresCache = new CachedObject<>( + () -> database.getWarningEndTimestamp(target).map(Object.class::cast).orElse(CommonMessages.NA), 15, + TimeUnit.SECONDS); + + this.sendInitalMessage(event); + } + + @Override + protected void populateContainer(LocalizedContainerBuilder builder, Page page) { + builder.setColor(Colors.INFO); + + LocalizedSectionBuilder sb = builder.getNewLocalizedSectionBuilder(); + + String headerFormat = """ + %s: `%s` + %s: `%s` + %s: %s + """; + sb.setThumbnailUrl(target.getEffectiveAvatarUrl()); + sb.addLocalizedFormattedTextDisplay("### %s - %s", TITLE, target.getAsMention()); + sb.addLocalizedFormattedTextDisplay(headerFormat, + // Warning Level + CommonMessages.WARNING_LEVEL, warningLevelCache.get(), + // Total Warnings + CommonMessages.TOTAL_WARNINGS, totalWarningsCache.get(), + // Warning Expires + CommonMessages.WARNING_EXPIRES, expiresCache.get()); + builder.addSectionAndClear(sb); + + builder.addDividingSeparator(Spacing.SMALL); + + Iterator iterator = page.iterator(); + while (iterator.hasNext()) { + Warning warning = iterator.next(); + buildWarningSection(builder, warning); + } + } + + private void buildWarningSection(LocalizedContainerBuilder builder, Warning warning) { + String format = """ + #%,d: %s - %s + >>> %s + """; + builder.addLocalizedFormattedTextDisplay(warning.isActive() ? "\u23F2 " + format : format, + // Case-ID + warning.getId(), + // Date + TimeFormat.RELATIVE.format(warning.getTime()), + // Moderator + Localized.resolved("customjail.embed.by", DiscordUtils.mentionUser(warning.getModerator())), + // Reason + StringUtils.nullIfBlank(warning.getReason()) == null ? CommonMessages.DEFAULT_REASON + : warning.getReason()); + } + +// private void buildWarningSection(LocalizedSectionBuilder builder, Warning warning) { +// builder.setButton(Button.of(ButtonStyle.DANGER, DELETE_PREFIX + warning.getId(), "\u2715")); +// String format = "%,d: %s - %s"; +// builder.addLocalizedFormattedTextDisplay(warning.isActive() ? "\u23F2 " + format : format, +// // Case-ID +// warning.getId(), +// // Date +// TimeFormat.RELATIVE.format(warning.getTime()), +// // Moderator +// Localized.resolved("customjail.embed.by", DiscordUtils.mentionUser(warning.getModerator()))); +// //builder.addLocalizedTextDisplay("customjail.embed.by", DiscordUtils.mentionUser(warning.getModerator())); +// +// if (StringUtils.nullIfBlank(warning.getReason()) == null) +// builder.addLocalizedFormattedTextDisplay(">>> %s", CommonMessages.DEFAULT_REASON); +// else +// builder.addTextDisplay(MarkdownUtil.quoteBlock(warning.getReason())); +// } + + @Override + protected Container createEmptyPage() { + return ComponentUtils.Response.error(messages.getMessage("customjail.warnings.empty", null, locale)); + } + + @Override + protected Page getNewPage(Pageable pagable) { + return database.getWarningPage(target, pagable); + } + +} diff --git a/src/main/java/net/foxgenesis/customjail/database/CustomJailConfiguration.java b/src/main/java/net/foxgenesis/customjail/database/CustomJailConfiguration.java index 5550158..5b14a5e 100644 --- a/src/main/java/net/foxgenesis/customjail/database/CustomJailConfiguration.java +++ b/src/main/java/net/foxgenesis/customjail/database/CustomJailConfiguration.java @@ -1,17 +1,19 @@ package net.foxgenesis.customjail.database; -import java.util.Objects; - +import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; - +import lombok.Data; +import lombok.EqualsAndHashCode; import net.foxgenesis.customjail.util.CustomTime; import net.foxgenesis.springJDA.annotation.Snowflake; import net.foxgenesis.watame.data.PluginConfiguration; +@Data +@EqualsAndHashCode(callSuper = true) @Entity public class CustomJailConfiguration extends PluginConfiguration { @@ -43,99 +45,7 @@ public class CustomJailConfiguration extends PluginConfiguration { @Column(nullable = false) private int maxWarnings = 3; - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Long getJailRole() { - return jailRole; - } - - public void setJailRole(Long jailRole) { - this.jailRole = jailRole; - } - - public Long getJailChannel() { - return jailChannel; - } - - public void setJailChannel(Long jailChannel) { - this.jailChannel = jailChannel; - } - - public Long getLogChannel() { - return logChannel; - } - - public void setLogChannel(Long logChannel) { - this.logChannel = logChannel; - } - - public CustomTime getWarningTime() { - return warningTime; - } - - public void setWarningTime(CustomTime warningTime) { - this.warningTime = warningTime; - } - - public String getWarningsPrefix() { - return warningsPrefix; - } - - public void setWarningsPrefix(String warningsPrefix) { - this.warningsPrefix = warningsPrefix; - } - - public boolean isNotifyMember() { - return notifyMember; - } - - public void setNotifyMember(boolean notifyMember) { - this.notifyMember = notifyMember; - } - - public int getMaxWarnings() { - return maxWarnings; - } - - public void setMaxWarnings(int maxWarnings) { - this.maxWarnings = maxWarnings; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + Objects.hash(enabled, jailChannel, jailRole, logChannel, maxWarnings, notifyMember, - warningTime, warningsPrefix); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - CustomJailConfiguration other = (CustomJailConfiguration) obj; - return enabled == other.enabled && Objects.equals(jailChannel, other.jailChannel) - && Objects.equals(jailRole, other.jailRole) && Objects.equals(logChannel, other.logChannel) - && maxWarnings == other.maxWarnings && notifyMember == other.notifyMember - && Objects.equals(warningTime, other.warningTime) - && Objects.equals(warningsPrefix, other.warningsPrefix); - } - - @Override - public String toString() { - return "CustomJailConfiguration [enabled=" + enabled + ", jailRole=" + jailRole + ", jailChannel=" + jailChannel - + ", logChannel=" + logChannel + ", warningTime=" + warningTime + ", warningsPrefix=" + warningsPrefix - + ", notifyMember=" + notifyMember + ", maxWarnings=" + maxWarnings + "]"; - } + @Length(max = 500) + @Column + private String jailEmbedDescription; } diff --git a/src/main/java/net/foxgenesis/customjail/database/CustomJailConfigurationService.java b/src/main/java/net/foxgenesis/customjail/database/CustomJailConfigurationService.java index 3a329d6..8a1178a 100644 --- a/src/main/java/net/foxgenesis/customjail/database/CustomJailConfigurationService.java +++ b/src/main/java/net/foxgenesis/customjail/database/CustomJailConfigurationService.java @@ -46,21 +46,6 @@ public Set getManagedRoles(Guild guild) { }).orElse(Set.of()); } -// private List getWarningRoles(Guild guild) { -// return get(guild) -// // Map -// .map(config -> guild.getRoles() -// // Stream -// .stream() -// // Filter roles that start with prefix -// .filter(r -> r.getName().startsWith(config.getWarningsPrefix())) -// // Reverse order -// .sorted(Comparator.reverseOrder()) -// // As set -// .toList()) -// .orElseThrow(); -// } - public boolean isEnabled(Guild guild) { return get(guild).map(CustomJailConfiguration::isEnabled).orElse(false); } diff --git a/src/main/java/net/foxgenesis/customjail/database/warning/Warning.java b/src/main/java/net/foxgenesis/customjail/database/warning/Warning.java index 556172b..1cd25e5 100644 --- a/src/main/java/net/foxgenesis/customjail/database/warning/Warning.java +++ b/src/main/java/net/foxgenesis/customjail/database/warning/Warning.java @@ -1,7 +1,6 @@ package net.foxgenesis.customjail.database.warning; import java.time.Instant; -import java.util.Objects; import org.hibernate.annotations.CreationTimestamp; @@ -12,11 +11,14 @@ import jakarta.persistence.Id; import jakarta.persistence.Index; import jakarta.persistence.Table; -import net.dv8tion.jda.api.entities.Guild; +import lombok.Data; +import lombok.NoArgsConstructor; import net.dv8tion.jda.api.entities.Member; -import net.foxgenesis.customjail.util.Utilities; import net.foxgenesis.springJDA.annotation.Snowflake; +@Data +@NoArgsConstructor + @Entity @Table(indexes = @Index(columnList = "guild, member")) public class Warning { @@ -26,30 +28,27 @@ public class Warning { private long id; @Snowflake - @Column(nullable = false) + @Column(updatable = false, nullable = false) private long guild; @Snowflake - @Column(nullable = false) + @Column(updatable = false, nullable = false) private long member; @Snowflake - @Column(nullable = false) + @Column(updatable = false, nullable = false) private long moderator; @Column(length = 500) private String reason; @CreationTimestamp - @Column(nullable = false) + @Column(updatable = false, nullable = false) private Instant time; @Column(nullable = false) private boolean active; - public Warning() { - } - public Warning(long guild, long member, long moderator, String reason, boolean active) { this(); setGuild(guild); @@ -63,104 +62,7 @@ public Warning(Member member, Member moderator, String reason, boolean active) { this(member.getGuild().getIdLong(), member.getIdLong(), moderator.getIdLong(), reason, active); } - public Warning(Warning other) { - this(other.guild, other.member ,other.moderator, other.reason, other.active); - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public long getGuild() { - return guild; - } - - public void setGuild(long guild) { - this.guild = guild; - } - - public void setGuild(Guild guild) { - setGuild(guild.getIdLong()); - } - - public long getMember() { - return member; - } - - public void setMember(long member) { - this.member = member; - } - - public void setMember(Member member) { - setMember(member.getIdLong()); - } - - public long getModerator() { - return moderator; - } - - public void setModerator(long moderator) { - this.moderator = moderator; - } - - public void setModerator(Member moderator) { - setModerator(moderator.getIdLong()); - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = Utilities.nullIfBlank(reason); - } - - public Instant getTime() { - return time; - } - - public void setTime(Instant time) { - this.time = time; - } - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - public Warning copy() { - return new Warning(this); - } - - @Override - public int hashCode() { - return Objects.hash(active, guild, id, member, moderator, reason, time); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Warning other = (Warning) obj; - return active == other.active && guild == other.guild && id == other.id && member == other.member - && moderator == other.moderator && Objects.equals(reason, other.reason) - && Objects.equals(time, other.time); - } - - @Override - public String toString() { - return "Warning [id=" + id + ", guild=" + guild + ", member=" + member + ", moderator=" + moderator - + ", reason=" + reason + ", time=" + time + ", active=" + active + "]"; + return new Warning(guild, member, moderator, reason, active); } } diff --git a/src/main/java/net/foxgenesis/customjail/event/CustomJailEvent.java b/src/main/java/net/foxgenesis/customjail/event/CustomJailEvent.java index 7d853b8..634b71e 100644 --- a/src/main/java/net/foxgenesis/customjail/event/CustomJailEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/CustomJailEvent.java @@ -5,7 +5,7 @@ import org.springframework.context.MessageSource; -import net.foxgenesis.watame.util.discord.LoggableEvent; +import net.foxgenesis.watame.util.discord.components.LoggableEvent; public abstract class CustomJailEvent extends LoggableEvent { diff --git a/src/main/java/net/foxgenesis/customjail/event/JailEvent.java b/src/main/java/net/foxgenesis/customjail/event/JailEvent.java index 3a9249a..1290a7e 100644 --- a/src/main/java/net/foxgenesis/customjail/event/JailEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/JailEvent.java @@ -1,7 +1,7 @@ package net.foxgenesis.customjail.event; import net.dv8tion.jda.api.entities.Member; -import net.foxgenesis.watame.util.discord.ModeratorActionEvent; +import net.foxgenesis.watame.util.discord.components.ModeratorActionEvent; public abstract class JailEvent extends ModeratorActionEvent { diff --git a/src/main/java/net/foxgenesis/customjail/event/JailTimerStartedEvent.java b/src/main/java/net/foxgenesis/customjail/event/JailTimerStartedEvent.java index b5c6daf..4677ea6 100644 --- a/src/main/java/net/foxgenesis/customjail/event/JailTimerStartedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/JailTimerStartedEvent.java @@ -5,10 +5,14 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.utils.TimeFormat; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class JailTimerStartedEvent extends JailEvent { @@ -31,13 +35,41 @@ public Date getEndDate() { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); builder.addLocalizedField("customjail.embed.moderator", getModerator(source, locale), true); builder.addLocalizedField("customjail.embed.time-left", TimeFormat.RELATIVE.format(date.toInstant()), true); - + // Row 2 builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), false); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale), + // Case-ID + CommonMessages.TIME_LEFT, TimeFormat.RELATIVE.format(date.toInstant())); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/JailedEvent.java b/src/main/java/net/foxgenesis/customjail/event/JailedEvent.java index 6929bd7..09d8cb7 100644 --- a/src/main/java/net/foxgenesis/customjail/event/JailedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/JailedEvent.java @@ -5,10 +5,14 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.util.CustomTime; import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class JailedEvent extends JailEvent { @@ -42,7 +46,7 @@ public String getCaseId(MessageSource source, Locale locale) { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); builder.addLocalizedField("customjail.embed.moderator", getModerator(source, locale), true); @@ -55,4 +59,35 @@ public void fillEmbed(LocalizedEmbedBuilder builder) { // Row 3 builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), false); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale), + // Case-ID + CommonMessages.CASE_ID, getCaseId(source, locale)); + + builder.addLocalizedFormattedTextDisplay("**%s:** %s", CommonMessages.DURATION, + getDuration().getLocalizedDisplayString(source, locale)); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/UnjailEvent.java b/src/main/java/net/foxgenesis/customjail/event/UnjailEvent.java index 0496c4e..fa28998 100644 --- a/src/main/java/net/foxgenesis/customjail/event/UnjailEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/UnjailEvent.java @@ -4,9 +4,13 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class UnjailEvent extends JailEvent { @@ -23,12 +27,39 @@ public UnjailEvent(Member member, Member moderator, String reason) { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); - getModerator().ifPresent(moderator -> builder.addLocalizedField("customjail.embed.moderator", moderator.getAsMention(), true)); - + getModerator().ifPresent( + moderator -> builder.addLocalizedField("customjail.embed.moderator", moderator.getAsMention(), true)); + // Row 2 builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), false); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + """; + + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale)); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningAddedEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningAddedEvent.java index 714fa0f..ef4b97a 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningAddedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningAddedEvent.java @@ -4,10 +4,14 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.database.warning.Warning; import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class WarningAddedEvent extends WarningEvent { @@ -24,7 +28,7 @@ public WarningAddedEvent(Member member, Member moderator, Warning warning) { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); builder.addLocalizedField("customjail.embed.moderator", getModerator(source, locale), true); @@ -33,4 +37,32 @@ public void fillEmbed(LocalizedEmbedBuilder builder) { // Row 2 builder.addLocalizedField("customjail.embed.reason", getWarningReason(source, locale), false); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getWarningReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale), + // Case-ID + CommonMessages.CASE_ID, getWarning().getId()); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningEvent.java index d6eb6d8..2ad2795 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningEvent.java @@ -8,7 +8,7 @@ import net.dv8tion.jda.api.entities.Member; import net.foxgenesis.customjail.database.warning.Warning; -import net.foxgenesis.watame.util.discord.ModeratorActionEvent; +import net.foxgenesis.watame.util.discord.components.ModeratorActionEvent; public abstract class WarningEvent extends ModeratorActionEvent { diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningLevelDecreasedEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningLevelDecreasedEvent.java index 2614ddb..7c9bb1f 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningLevelDecreasedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningLevelDecreasedEvent.java @@ -4,10 +4,14 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.watame.util.discord.Colors; -import net.foxgenesis.watame.util.discord.ModeratorActionEvent; +import net.foxgenesis.watame.util.discord.components.ModeratorActionEvent; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class WarningLevelDecreasedEvent extends ModeratorActionEvent { @@ -40,7 +44,7 @@ public int getNewLevel() { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); builder.addLocalizedField("customjail.embed.moderator", getModerator(source, locale), true); @@ -49,4 +53,32 @@ public void fillEmbed(LocalizedEmbedBuilder builder) { // Row 2 builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), false); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale), + // Case-ID + CommonMessages.WARNING_LEVEL, originalLevel + " \u2192 " + newLevel); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningRemovedEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningRemovedEvent.java index 5da70df..d26d757 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningRemovedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningRemovedEvent.java @@ -4,11 +4,16 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.database.warning.Warning; import net.foxgenesis.watame.util.discord.Colors; import net.foxgenesis.watame.util.discord.DiscordUtils; +import net.foxgenesis.watame.util.lang.Localized; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class WarningRemovedEvent extends WarningEvent { @@ -25,14 +30,13 @@ public WarningRemovedEvent(Member member, Member moderator, String reason, Warni public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 Warning warning = getWarning(); builder.addLocalizedField("customjail.embed.member", DiscordUtils.mentionUser(warning.getMember()), true); - builder.addLocalizedField("customjail.embed.moderator", DiscordUtils.mentionUser(warning.getModerator()), - true); + builder.addLocalizedField("customjail.embed.moderator", DiscordUtils.mentionUser(warning.getModerator()), true); builder.addLocalizedField("customjail.embed.caseid", getCaseId(source, locale), true); - + // Row 2 builder.addLocalizedField("customjail.embed.reason", getWarningReason(source, locale), true); @@ -40,4 +44,38 @@ public void fillEmbed(LocalizedEmbedBuilder builder) { builder.addLocalizedField("customjail.embed.changed-by", getModerator(source, locale), false); builder.addLocalizedField("customjail.embed.reasoning", getReason(source, locale), true); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getWarningReason(source, locale)); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("**%s:** %s\n### %s\n%s", + Localized.resolved("customjail.embed.changed-by"), getModerator(source, locale), + Localized.resolved("customjail.embed.reasoning"), getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + Warning warning = getWarning(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, DiscordUtils.mentionUser(warning.getMember()), + // Moderator + CommonMessages.MODERATOR, DiscordUtils.mentionUser(warning.getModerator()), + // Case-ID + CommonMessages.CASE_ID, getCaseId(source, locale)); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningUpdatedEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningUpdatedEvent.java index 4f499e7..e7d75f5 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningUpdatedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningUpdatedEvent.java @@ -6,11 +6,16 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.database.warning.Warning; import net.foxgenesis.watame.util.discord.Colors; import net.foxgenesis.watame.util.discord.DiscordUtils; +import net.foxgenesis.watame.util.lang.Localized; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class WarningUpdatedEvent extends WarningEvent { @@ -33,18 +38,63 @@ public Warning getOldWarning() { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", DiscordUtils.mentionUser(oldWarning.getMember()), true); - builder.addLocalizedField("customjail.embed.moderator", DiscordUtils.mentionUser(oldWarning.getModerator()), true); + builder.addLocalizedField("customjail.embed.moderator", DiscordUtils.mentionUser(oldWarning.getModerator()), + true); builder.addLocalizedField("customjail.embed.caseid", getCaseId(source, locale), true); // Row 2 - builder.addLocalizedField("customjail.embed.old-reason", Optional.ofNullable(oldWarning.getReason()).orElseGet(getDefaultReason(source, locale)), true); + builder.addLocalizedField("customjail.embed.old-reason", + Optional.ofNullable(oldWarning.getReason()).orElseGet(getDefaultReason(source, locale)), true); builder.addLocalizedField("customjail.embed.new-reason", getWarningReason(source, locale), true); - + // Row 3 builder.addLocalizedField("customjail.embed.changed-by", getModerator(source, locale), false); builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), true); } + + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + """; + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Old reason + Localized.resolved("customjail.embed.old-reason"), + Optional.ofNullable(oldWarning.getReason()).orElseGet(getDefaultReason(source, locale)), + // New reason + Localized.resolved("customjail.embed.new-reason"), getWarningReason(source, locale)); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("**%s:** %s\n### %s\n%s", + Localized.resolved("customjail.embed.changed-by"), getModerator(source, locale), + Localized.resolved("customjail.embed.reasoning"), getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale), + // Case-ID + CommonMessages.CASE_ID, getCaseId(source, locale)); + } } diff --git a/src/main/java/net/foxgenesis/customjail/event/warning/WarningsClearedEvent.java b/src/main/java/net/foxgenesis/customjail/event/warning/WarningsClearedEvent.java index a640c3d..ec036d0 100644 --- a/src/main/java/net/foxgenesis/customjail/event/warning/WarningsClearedEvent.java +++ b/src/main/java/net/foxgenesis/customjail/event/warning/WarningsClearedEvent.java @@ -4,10 +4,14 @@ import org.springframework.context.MessageSource; +import net.dv8tion.jda.api.components.separator.Separator.Spacing; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.watame.util.discord.Colors; -import net.foxgenesis.watame.util.discord.ModeratorActionEvent; +import net.foxgenesis.watame.util.discord.components.ModeratorActionEvent; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public class WarningsClearedEvent extends ModeratorActionEvent { @@ -24,13 +28,38 @@ public WarningsClearedEvent(Member member, Member moderator, String reason) { public void fillEmbed(LocalizedEmbedBuilder builder) { MessageSource source = builder.getMessageSource(); Locale locale = builder.getLocale(); - + // Row 1 builder.addLocalizedField("customjail.embed.member", getMember().getAsMention(), true); builder.addLocalizedField("customjail.embed.moderator", getModerator(source, locale), true); - + // Row 2 builder.addLocalizedField("customjail.embed.reason", getReason(source, locale), false); } + @Override + public void fillContainer(LocalizedContainerBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + builder.addDividingSeparator(Spacing.SMALL); + builder.addLocalizedFormattedTextDisplay("### %s\n%s", CommonMessages.REASON, getReason(source, locale)); + } + + @Override + protected void fillContainerDetails(LocalizedSectionBuilder builder) { + MessageSource source = builder.getMessageSource(); + Locale locale = builder.getLocale(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + """; + builder.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, getMember().getAsMention(), + // Moderator + CommonMessages.MODERATOR, getModerator(source, locale)); + } + } diff --git a/src/main/java/net/foxgenesis/customjail/jail/JailDetails.java b/src/main/java/net/foxgenesis/customjail/jail/JailDetails.java index 95ceb6e..bfa4c07 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/JailDetails.java +++ b/src/main/java/net/foxgenesis/customjail/jail/JailDetails.java @@ -1,22 +1,29 @@ package net.foxgenesis.customjail.jail; -import java.time.Instant; -import java.util.Locale; import java.util.Objects; import java.util.Optional; import org.quartz.JobDataMap; -import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import net.dv8tion.jda.api.components.buttons.Button; +import net.dv8tion.jda.api.components.buttons.ButtonStyle; import net.dv8tion.jda.api.entities.Member; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.util.CustomTime; +import net.foxgenesis.customjail.util.Utilities; +import net.foxgenesis.watame.util.StringUtils; import net.foxgenesis.watame.util.discord.Colors; import net.foxgenesis.watame.util.discord.DiscordUtils; -import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; public record JailDetails(long guild, long member, Long moderator, CustomTime duration, String reason, long caseid, long timestamp) { + private static final String BOLD_FIELD = "**%s:** %s"; + private static final String KEY_GUILD = "guild-id"; private static final String KEY_MEMBER = "member-id"; private static final String KEY_MODERATOR = "moderator-id"; @@ -76,34 +83,58 @@ public static JailDetails resolveFromDataMap(JobDataMap map) { return new JailDetails(guild, member, modId, duration, reason, caseid, timestamp); } - public void applyToEmbedBuilder(LocalizedEmbedBuilder builder, MessageSource source, Locale locale, Member member, + private static final MessageSourceResolvable JAILED_BY = new DefaultMessageSourceResolvable( + "customjail.container.jailed-by"); + private static final MessageSourceResolvable TIME_LEFT = new DefaultMessageSourceResolvable( + "customjail.embed.time-left"); + private static final MessageSourceResolvable NOT_ACCEPTED = new DefaultMessageSourceResolvable( + "customjail.embed.not-accepted"); + + public void applyToContainerBuilder(LocalizedContainerBuilder cb, Member member, Optional jailEndTimestamp) { + cb.setColor(Colors.INFO); + LocalizedSectionBuilder sb = cb.getNewLocalizedSectionBuilder(); boolean isTimerRunning = jailEndTimestamp.isPresent(); - builder.setColor(Colors.INFO); - builder.setThumbnail(member.getEffectiveAvatarUrl()); - builder.setLocalizedTitle("customjail.embed.jaildetails"); - builder.addLocalizedField("customjail.embed.member", DiscordUtils.mentionUser(this.member), true); - builder.addLocalizedField("customjail.embed.moderator", DiscordUtils.mentionUser(moderator), true); - - builder.addLocalizedField("customjail.embed.caseid", - caseid != -1 ? "" + caseid : source.getMessage("customjail.embed.na", null, locale), true); - - builder.addLocalizedFieldAndValue("customjail.embed.accepted", - isTimerRunning ? "customjail.embed.yes" : "customjail.embed.no", true, null); - - builder.addLocalizedField("customjail.embed.duration", duration.getLocalizedDisplayString(source, locale), - true); - - String endTime = isTimerRunning - ? jailEndTimestamp.orElseGet(() -> source.getMessage("customjail.embed.na", null, locale)) - : source.getMessage("customjail.embed.not-accepted", null, locale); - builder.addLocalizedField("customjail.embed.time-left", endTime, true); - - builder.addLocalizedField("customjail.embed.reason", Optional.ofNullable(reason) - .orElseGet(() -> source.getMessage("customjail.embed.defaultReason", null, locale)), false); - builder.setLocalizedFooter("customjail.footer"); - - builder.setTimestamp(Instant.ofEpochMilli(timestamp)); + Button unjail = sb.newLocalizedButton(ButtonStyle.DANGER, + Utilities.Interactions.wrapInteraction("unjail", member), CommonMessages.UNJAIL); + Button forcestart = sb.newLocalizedButton(ButtonStyle.DANGER, + Utilities.Interactions.wrapInteraction("forcestart", member), CommonMessages.FORCESTART) + .withDisabled(isTimerRunning); + + // Section 1 + sb.setThumbnailUrl(member.getEffectiveAvatarUrl()); + sb.addLocalizedTextDisplay(CommonMessages.JAIL_DETAILS); + sb.addLocalizedTextDisplay("customjail.container.jaildetails-for", DiscordUtils.mentionUser(this.member)); + cb.addSectionAndClear(sb); + + cb.addSmallDividingSeparator(); + + // Section 2 + sb.setButton(unjail); + sb.addLocalizedFormattedTextDisplay(BOLD_FIELD, JAILED_BY, DiscordUtils.mentionUser(moderator)); + sb.addLocalizedFormattedTextDisplay(BOLD_FIELD, CommonMessages.CASE_ID, + caseid != -1 ? caseid : CommonMessages.NA); + sb.addLocalizedFormattedTextDisplay(BOLD_FIELD, CommonMessages.DURATION, + duration.getLocalizedDisplayString(sb.getMessageSource(), sb.getLocale())); + cb.addSectionAndClear(sb); + + cb.addSmallDividingSeparator(); + + // Section 3 + sb.setButton(forcestart); + sb.addLocalizedFormattedTextDisplay(BOLD_FIELD, CommonMessages.ACCEPTED, + isTimerRunning ? CommonMessages.YES : CommonMessages.NO); + sb.addLocalizedFormattedTextDisplay(BOLD_FIELD, TIME_LEFT, + isTimerRunning ? jailEndTimestamp.get() : NOT_ACCEPTED); + cb.addSectionAndClear(sb); + + cb.addSmallDividingSeparator(); + + cb.addLocalizedFormattedTextDisplay("### %s", CommonMessages.REASON); + if (StringUtils.nullIfBlank(reason) == null) + cb.addLocalizedTextDisplay(CommonMessages.DEFAULT_REASON); + else + cb.addTextDisplay(reason); } } diff --git a/src/main/java/net/foxgenesis/customjail/jail/JailJob.java b/src/main/java/net/foxgenesis/customjail/jail/JailJob.java index edbc17c..7c8f5af 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/JailJob.java +++ b/src/main/java/net/foxgenesis/customjail/jail/JailJob.java @@ -14,15 +14,7 @@ public class JailJob implements Job { private static final Logger logger = LoggerFactory.getLogger(JailJob.class); @Autowired - private JailSystem system; - -// @Override -// protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { -// JailDetails details = JailDetails.resolveFromDataMap(ctx.getMergedJobDataMap()); -// -// logger.info("Jail job finished for member {} in {}: ", details.member(), details.guild(), details); -// system.unjail(details.guild(), details.member(), null, null); -// } + private transient JailSystem system; @Override public void execute(JobExecutionContext ctx) throws JobExecutionException { diff --git a/src/main/java/net/foxgenesis/customjail/jail/WarningJob.java b/src/main/java/net/foxgenesis/customjail/jail/WarningJob.java index f2b5719..ba40dca 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/WarningJob.java +++ b/src/main/java/net/foxgenesis/customjail/jail/WarningJob.java @@ -14,15 +14,7 @@ public class WarningJob implements Job { private static final Logger logger = LoggerFactory.getLogger(WarningJob.class); @Autowired - private JailSystem system; - -// @Override -// protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { -// WarningDetails details = WarningDetails.resolveFromDataMap(ctx.getMergedJobDataMap()); -// -// logger.info("Warning job finished for member {} in {}: ", details.member(), details.guild(), details); -// system.decreaseWarningLevel(details.guild(), details.member(), null, null); -// } + private transient JailSystem system; @Override public void execute(JobExecutionContext ctx) throws JobExecutionException { diff --git a/src/main/java/net/foxgenesis/customjail/jail/WarningSystem.java b/src/main/java/net/foxgenesis/customjail/jail/WarningSystem.java index 3e704b0..f82cd18 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/WarningSystem.java +++ b/src/main/java/net/foxgenesis/customjail/jail/WarningSystem.java @@ -2,6 +2,7 @@ import java.util.NoSuchElementException; import java.util.Optional; +import java.util.Set; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -17,6 +18,13 @@ * @author Ashley */ public interface WarningSystem { + + default Set getWarnings(Member member) { + return getWarnings(member.getGuild().getIdLong(), member.getIdLong()); + } + + Set getWarnings(long guild, long member); + /** * Get the total amount of warnings for the specified {@link Member}. * @@ -73,6 +81,6 @@ default Warning updateWarningReason(long id, Member moderator, String newReason, void clearWarnings(Member member, Member moderator, String reason); void clearWarnings(Guild guild); - + Optional getWarningEndTimestamp(Member member); } diff --git a/src/main/java/net/foxgenesis/customjail/jail/exception/LocalizedException.java b/src/main/java/net/foxgenesis/customjail/jail/exception/LocalizedException.java index d803535..4234679 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/exception/LocalizedException.java +++ b/src/main/java/net/foxgenesis/customjail/jail/exception/LocalizedException.java @@ -6,8 +6,11 @@ import org.springframework.context.MessageSourceResolvable; import org.springframework.context.support.DefaultMessageSourceResolvable; +import net.dv8tion.jda.api.components.container.Container; import net.dv8tion.jda.api.entities.MessageEmbed; -import net.foxgenesis.watame.util.discord.Response; +import net.foxgenesis.watame.util.discord.Colors; +import net.foxgenesis.watame.util.discord.components.Response; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; public class LocalizedException extends RuntimeException { @@ -32,4 +35,11 @@ public MessageSourceResolvable getErrorMessage() { public MessageEmbed getErrorEmbed(MessageSource source, Locale locale) { return Response.error(source.getMessage(getErrorMessage(), locale)); } + + public Container getErrorContainer(MessageSource source, Locale locale) { + LocalizedContainerBuilder builder = new LocalizedContainerBuilder(source, locale); + builder.setColor(Colors.ERROR); + builder.addLocalizedTextDisplay(resolvable); + return builder.build(); + } } diff --git a/src/main/java/net/foxgenesis/customjail/jail/impl/JailSystemImpl.java b/src/main/java/net/foxgenesis/customjail/jail/impl/JailSystemImpl.java index 4b77588..3826e24 100644 --- a/src/main/java/net/foxgenesis/customjail/jail/impl/JailSystemImpl.java +++ b/src/main/java/net/foxgenesis/customjail/jail/impl/JailSystemImpl.java @@ -12,7 +12,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.function.Function; @@ -24,15 +23,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.context.MessageSource; -import org.springframework.context.MessageSourceAware; import org.springframework.context.event.EventListener; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.lang.Nullable; +import lombok.Setter; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.components.actionrow.ActionRow; +import net.dv8tion.jda.api.components.buttons.Button; +import net.dv8tion.jda.api.components.buttons.ButtonStyle; +import net.dv8tion.jda.api.components.container.Container; +import net.dv8tion.jda.api.components.replacer.ComponentReplacer; +import net.dv8tion.jda.api.components.textdisplay.TextDisplay; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.GuildVoiceState; import net.dv8tion.jda.api.entities.Member; @@ -42,6 +45,7 @@ import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.events.guild.GuildBanEvent; import net.dv8tion.jda.api.events.guild.GuildLeaveEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; @@ -49,13 +53,13 @@ import net.dv8tion.jda.api.exceptions.ErrorHandler; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; -import net.dv8tion.jda.api.interactions.components.buttons.Button; -import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; import net.dv8tion.jda.api.requests.ErrorResponse; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import net.dv8tion.jda.api.utils.MarkdownUtil; import net.dv8tion.jda.api.utils.TimeFormat; +import net.dv8tion.jda.api.utils.Timestamp; +import net.foxgenesis.customjail.CommonMessages; import net.foxgenesis.customjail.database.CustomJailConfiguration; import net.foxgenesis.customjail.database.CustomJailConfigurationService; import net.foxgenesis.customjail.database.warning.Warning; @@ -79,30 +83,30 @@ import net.foxgenesis.customjail.jail.exception.NotSetupException; import net.foxgenesis.customjail.util.CustomTime; import net.foxgenesis.customjail.util.Utilities; -import net.foxgenesis.springJDA.SpringJDA; +import net.foxgenesis.watame.WatameUtils; +import net.foxgenesis.watame.util.StringUtils; import net.foxgenesis.watame.util.discord.Colors; -import net.foxgenesis.watame.util.discord.DiscordLogger; import net.foxgenesis.watame.util.discord.DiscordUtils; -import net.foxgenesis.watame.util.discord.ModeratorActionEvent; -import net.foxgenesis.watame.util.discord.Response; +import net.foxgenesis.watame.util.discord.components.ComponentUtils; +import net.foxgenesis.watame.util.discord.components.ModeratorActionEvent; +import net.foxgenesis.watame.util.discord.components.Response; +import net.foxgenesis.watame.util.lang.DiscordLocaleMessageSource; +import net.foxgenesis.watame.util.lang.Localized; +import net.foxgenesis.watame.util.lang.LocalizedContainerBuilder; import net.foxgenesis.watame.util.lang.LocalizedEmbedBuilder; +import net.foxgenesis.watame.util.lang.LocalizedSectionBuilder; /** * Standard implementation of a {@link JailSystem}. * * @author Ashley */ -public class JailSystemImpl extends ListenerAdapter - implements JailSystem, ApplicationEventPublisherAware, MessageSourceAware { +public class JailSystemImpl extends ListenerAdapter implements JailSystem { private final Logger logger = LoggerFactory.getLogger(JailSystem.class); private final String[] timings; - private ApplicationEventPublisher publisher; - - private MessageSource messages; - @Autowired private CustomJailConfigurationService service; @@ -110,13 +114,16 @@ public class JailSystemImpl extends ListenerAdapter private WarningDatabase warningDatabase; @Autowired - private DiscordLogger discordLogger; + private JailScheduler scheduler; @Autowired - private JailScheduler scheduler; + private WatameUtils watame; @Autowired - private SpringJDA jda; + private ApplicationEventPublisher publisher; + + @Setter + private boolean useComponentV2Logging = true; public JailSystemImpl(String[] timings) { this.timings = Objects.requireNonNull(timings); @@ -186,18 +193,14 @@ public void jail(Member member, Member moderator, CustomTime time, String reason } // Create the jail embed - Locale locale = discordLogger.getEffectiveLocale(guild); - MessageEmbed embed = createJailEmbed(member, moderator, warning.map(Warning::getId), time, + Locale locale = messages().getLocaleForGuild(guild); + Container container = createJailContainer(member, moderator, warning.map(Warning::getId), time, reason, anon, locale); - Button button = Button.primary(Utilities.Interactions.wrapInteraction("startjail", member), - messages.getMessage("customjail.embed.accept", null, locale)); // Send jail message - return jailChannel.sendMessage(member.getAsMention()) - // Set embeds - .setEmbeds(embed) - // Add accept button - .addActionRow(button) + return jailChannel.sendMessageComponents(container) + // Use V2 + .useComponentsV2() // Publish event on success .onSuccess(m -> { logger.info("{} jailed {} in {} for {} \"{}\"", moderator, member, guild, @@ -237,7 +240,7 @@ public void unjail(long guild, long member, Member moderator, String reason) thr if (!scheduler.removeJailTimer(guild, member)) throw new RuntimeException("Failed to unjail member [" + member + "] in " + guild); - Guild _guild = jda.getGuildById(guild); + Guild _guild = watame.getJda().getGuildById(guild); if (_guild == null) throw new IllegalArgumentException("JDA unable to resolve guild " + guild); @@ -297,43 +300,57 @@ public Optional getJailEndTimestamp(Member member) { return scheduler.getJailEndTimestamp(member); } - private MessageEmbed createJailEmbed(Member member, Member moderator, Optional caseId, CustomTime time, + private Container createJailContainer(Member member, Member moderator, Optional caseId, CustomTime time, String reason, boolean anon, Locale locale) { - // Create the jail embed - LocalizedEmbedBuilder jailEmbedBuilder = new LocalizedEmbedBuilder(messages, locale); - jailEmbedBuilder.setColor(Colors.ERROR); - jailEmbedBuilder.setLocalizedTitle("customjail.embed.jailed"); - jailEmbedBuilder.setThumbnail(member.getEffectiveAvatarUrl()); - - // Row 1 - jailEmbedBuilder.addLocalizedField("customjail.embed.member", member.getAsMention(), true); - if (anon) - jailEmbedBuilder.addLocalizedFieldAndValue("customjail.embed.moderator", "customjail.anonymous", true, - null); - else - jailEmbedBuilder.addLocalizedField("customjail.embed.moderator", moderator.getAsMention(), true); - jailEmbedBuilder.addLocalizedField("customjail.embed.caseid", - caseId.map(id -> "" + id).orElseGet(() -> messages.getMessage("customjail.embed.na", null, locale)), - true); - - // Row 2 - jailEmbedBuilder.addLocalizedField("customjail.embed.duration", - time.getLocalizedDisplayString(messages, locale), true); - - // Row 3 - jailEmbedBuilder.addLocalizedField("customjail.embed.reason", - Optional.ofNullable(reason).filter(r -> !r.isBlank()) - .orElseGet(() -> messages.getMessage("customjail.embed.defaultReason", null, locale)), - false); - - jailEmbedBuilder.setTimestamp(Instant.now()); - jailEmbedBuilder.setLocalizedFooter("customjail.footer"); - - return jailEmbedBuilder.build(); + LocalizedContainerBuilder cb = watame.getContainerBuilder(locale); + LocalizedSectionBuilder sb = cb.getNewLocalizedSectionBuilder(); + cb.setUniqueId(100); + cb.setColor(Colors.ERROR); + + Button acceptButton = sb.newLocalizedButton(ButtonStyle.PRIMARY, + Utilities.Interactions.wrapInteraction("startjail", member), CommonMessages.ACCEPT); + + sb.setThumbnailUrl(member.getEffectiveAvatarUrl()); + sb.addLocalizedFormattedTextDisplay("## %s\n%s", CommonMessages.MEMBER_JAILED, + "Welcome to City 17 " + member.getAsMention() + ".\nPlease hit \"Accept\" to start the timer."); + cb.addSectionAndClear(sb); + + cb.addSmallDividingSeparator(); + + String detailsFormat = """ + **%s:** %s + **%s:** %s + **%s:** %s + **%s:** %s + """; + cb.addLocalizedFormattedTextDisplay(detailsFormat, + // Member + CommonMessages.MEMBER, member.getAsMention(), + // Moderator + CommonMessages.MODERATOR, anon ? CommonMessages.ANONYMOUS : moderator.getAsMention(), + // Case-ID + CommonMessages.CASE_ID, caseId.isPresent() ? caseId.get() : CommonMessages.NA, + // Duration + CommonMessages.DURATION, time.getLocalizedDisplayString(messages(), locale)); + cb.addSmallDividingSeparator(); + + cb.addLocalizedFormattedTextDisplay("**%s**\n%s", CommonMessages.REASON, + StringUtils.nullIfBlank(reason) == null ? CommonMessages.DEFAULT_REASON : reason); + + cb.addSmallDividingSeparator(); + + cb.addActionRow(ActionRow.of(acceptButton)); + + return cb.build(); } // =========================================================================================================== + @Override + public Set getWarnings(long guild, long member) { + return warningDatabase.findByGuildAndMember(guild, member); + } + @Override public int getTotalWarnings(Member member) { return warningDatabase.getWarningCount(member); @@ -381,7 +398,7 @@ public void deleteWarning(Warning warning, Member moderator, String reason) { ifEnabledOrError(warning.getGuild(), config -> { logger.info("Deleting warning {}", warning); warningDatabase.delete(warning); - Guild guild = jda.getGuildById(warning.getGuild()); + Guild guild = watame.getJda().getGuildById(warning.getGuild()); if (guild == null) throw new IllegalArgumentException( @@ -408,7 +425,7 @@ public Warning updateWarningReason(Warning warning, Member moderator, String new warning.setReason(newReason); Warning newW = warningDatabase.save(warning); - Guild guild = jda.getGuildById(warning.getGuild()); + Guild guild = watame.getJda().getGuildById(warning.getGuild()); if (guild == null) throw new IllegalArgumentException( @@ -470,7 +487,7 @@ public void decreaseWarningLevel(long guild, long member, Member moderator, Stri if (moderator.getGuild().getIdLong() != guild) throw new CannotInteractException("customjail.not-from-same-guild"); - Guild _guild = jda.getGuildById(guild); + Guild _guild = watame.getJda().getGuildById(guild); if (_guild == null) throw new IllegalArgumentException("Unknown guild"); @@ -487,10 +504,10 @@ public void fixMember(Member member) { guild.addRoleToMember(member, jailRole).queue(); } else onWarningLevelChanged(config, member, - messages.getMessage("customjail.reason.fix", null, discordLogger.getEffectiveLocale(guild))); + messages().getMessage("customjail.reason.fix", null, messages().getLocaleForGuild(guild))); }); } - + @Override public Optional getWarningEndTimestamp(Member member) { return scheduler.getWarningEndTimestamp(member); @@ -503,12 +520,26 @@ public void onGuildMemberJoin(GuildMemberJoinEvent event) { fixMember(event.getMember()); } + @Override + public void onGuildBan(GuildBanEvent event) { + Guild guild = event.getGuild(); + User user = event.getUser(); + + // Check if banned member is jailed + if (isJailed(guild.getIdLong(), user.getIdLong())) { + logger.info("Member {} banned {} while jail timer running. Removing timer...", user, guild); + scheduler.removeJailTimer(guild.getIdLong(), user.getIdLong()); + } + } + @Override public void onGuildMemberRemove(GuildMemberRemoveEvent event) { - if (scheduler.isWarningTimerRunning(event.getGuild().getIdLong(), event.getUser().getIdLong())) { - logger.info("Member {} left {} while warning timer running. Removing timer...", event.getUser(), - event.getGuild()); - scheduler.removeWarningTimer(event.getGuild().getIdLong(), event.getUser().getIdLong()); + Guild guild = event.getGuild(); + User user = event.getUser(); + + if (scheduler.isWarningTimerRunning(guild.getIdLong(), user.getIdLong())) { + logger.info("Member {} left {} while warning timer running. Removing timer...", user, guild); + scheduler.removeWarningTimer(guild.getIdLong(), user.getIdLong()); } } @@ -518,6 +549,11 @@ public void onGuildLeave(GuildLeaveEvent event) { logger.info("Left guild {}. Removing all timers and warnings"); clearWarnings(guild); service.delete(guild); + try { + scheduler.removeAllTimer(guild); + } catch (SchedulerException e) { + logger.error("Failed to remove all timers for " + guild, e); + } } @Override @@ -539,7 +575,7 @@ public void onButtonInteraction(ButtonInteractionEvent event) { // Check if member is jailed if (!isJailed(member)) { - error(event, "customjail.notJailed").queue(); + error(event, "customjail.notJailed").and(event.editButton(null)).queue(); return; } @@ -549,41 +585,70 @@ public void onButtonInteraction(ButtonInteractionEvent event) { return; } - Locale locale = event.getUserLocale().toLocale(); - Button successButton = Button - .success("jailAccepted", messages.getMessage("customjail.embed.accepted", null, locale)) - .asDisabled(); - + // Create replacer for jail container + Function containerReplacer = endTimestamp -> ComponentReplacer.of( + // Of container + Container.class, + // Container with ID 100 + container -> container.getUniqueId() == 100, + // Update container + container -> { + Locale locale = event.getUserLocale().toLocale(); + + // Add time left to new component + Container newContainer = ComponentUtils.addComponentsToContainer(container, + TextDisplay.ofFormat("-# %s: %s", + messages().getMessage(CommonMessages.TIME_LEFT, locale), endTimestamp)); + + // Replace accept button with accepted + return newContainer.replace(ComponentReplacer.of(Button.class, + button -> button.getCustomId().startsWith("startjail"), + button -> Button + .success("jailAccepted", messages() + .getMessage("customjail.embed.accepted", null, locale)) + .asDisabled())); + }); + + // If timer is already running, update jail container if (scheduler.isJailTimerRunning(member)) { - error(event, "customjail.timerAlreadyStarted").queue(); + error(event, "customjail.timer-already-started").queue(); // Set accepted if not already if (event.getButton().getStyle() != ButtonStyle.SUCCESS) - event.editButton(successButton).queue(); + event.getMessage() + .editMessageComponents(event.getMessage().getComponentTree() + .replace(containerReplacer.apply(getJailEndTimestamp(member).get()))) + .useComponentsV2().queue(); return; } // Display working event.deferReply(true).flatMap(hook -> { - + // Attempt to start timer Date date = startJailTimer(member, null, null); - return hook.editOriginalEmbeds( - Response.success(messages.getMessage("customjail.embed.time-remaining", - new Object[] { TimeFormat.RELATIVE.atInstant(date.toInstant()) }, locale))) - .and(event.editButton(successButton)); + Locale locale = event.getUserLocale().toLocale(); + Timestamp endTimestamp = TimeFormat.RELATIVE.atInstant(date.toInstant()); + + // Create response embed + MessageEmbed successEmbed = Response.success(messages() + .getMessage("customjail.embed.time-remaining", new Object[] { endTimestamp }, locale)); + + // Update jail container + RestAction updateContainer = event.getMessage().editMessageComponents( + event.getMessage().getComponentTree().replace(containerReplacer.apply(endTimestamp))) + .useComponentsV2(); + return hook.editOriginalEmbeds(successEmbed).and(updateContainer); }).queue(); } } }, // Unable to find member button was wrapped to () -> { - MessageEmbed errorMsg = Response.error(messages.getMessage("customjail.embed.no-target", null, - event.getUserLocale().toLocale())); - RestAction edit = (event.isAcknowledged() - ? event.getHook().editOriginalEmbeds(errorMsg).setReplace(true) - : event.replyEmbeds(errorMsg).setEphemeral(true)); - event.editButton(event.getButton().asDisabled()).flatMap(o -> edit).queue(); + MessageEmbed errorMsg = Response.error( + messages().getMessage("customjail.no-target", null, event.getUserLocale().toLocale())); + event.replyEmbeds(errorMsg).setEphemeral(true) + .flatMap(v -> event.editButton(event.getButton().asDisabled())).queue(); }); })) return; @@ -598,7 +663,7 @@ public void onWarningAdded(WarningAddedEvent event) { // Case ID "customjail.embed.caseid", "" + event.getWarning().getId(), // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*')); + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*')); } @@ -610,7 +675,7 @@ public void onWarningRemoved(WarningRemovedEvent event) { // Case ID "customjail.embed.caseid", "" + event.getWarning().getId(), // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*')); + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*')); } @EventListener @@ -626,7 +691,7 @@ public void onWarningLevelDecreased(WarningLevelDecreasedEvent event) { // Warning level "customjail.embed.warning-level", event.getOriginalLevel() + " \u2192 " + event.getNewLevel(), // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*')); + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*')); } @EventListener @@ -634,9 +699,9 @@ public void onJailed(JailedEvent event) { defaultEventHandle(event, true, (locale, guild, user) -> notifyMember(locale, guild, user, "customjail.notify.jailed", Colors.ERROR, // Case ID - "customjail.embed.caseid", event.getCaseId(messages, locale), + "customjail.embed.caseid", event.getCaseId(messages(), locale), // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*')); + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*')); } @EventListener @@ -644,7 +709,7 @@ public void onUnJail(UnjailEvent event) { defaultEventHandle(event, false, (locale, guild, user) -> notifyMember(locale, guild, user, "customjail.notify.unjailed", Colors.NOTICE, // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*')); + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*')); } @EventListener @@ -653,7 +718,7 @@ public void onJailTimerStarted(JailTimerStartedEvent event) { (locale, guild, user) -> notifyMember(locale, guild, user, "customjail.notify.timer-started", Colors.NOTICE, // Reason - "customjail.embed.reason", '*' + event.getReason(messages, locale) + '*', + "customjail.embed.reason", '*' + event.getReason(messages(), locale) + '*', // Time left "customjail.embed.time-left", TimeFormat.RELATIVE.format(event.getEndDate().getTime()))); } @@ -669,14 +734,17 @@ private void defaultEventHandle(E event, boolea ifEnabled(event.getGuild(), config -> { Guild guild = event.getGuild(); Member member = event.getMember(); - Locale locale = discordLogger.getEffectiveLocale(guild); + Locale locale = messages().getLocaleForGuild(guild); // Send DM message to user if (notifyMember != null && config.isNotifyMember() && !(member.getUser().isBot() && member.getUser().isSystem())) notifyMember.accept(locale, guild, member.getUser()); - discordLogger.modlog(guild, config.getLogChannel(), event); + if (useComponentV2Logging) + watame.getDiscordLogger().modlogV2(guild, config.getLogChannel(), event); + else + watame.getDiscordLogger().modlog(guild, config.getLogChannel(), event); }); } @@ -710,7 +778,7 @@ private void notifyMember(Locale locale, Guild guild, User user, String title, i // Send embed if we can talk in the channel .flatMap(PrivateChannel::canTalk, channel -> { // Create embed - LocalizedEmbedBuilder builder = new LocalizedEmbedBuilder(messages, locale); + LocalizedEmbedBuilder builder = watame.getEmbedBuilder(locale); builder.setColor(color); builder.setLocalizedTitle(title, locale); builder.setThumbnail(guild.getIconUrl()); @@ -722,10 +790,10 @@ private void notifyMember(Locale locale, Guild guild, User user, String title, i String guildName = MarkdownUtil.maskedLink(guild.getName(), DiscordUtils.getGuildProtocolLink(guild)); - b.append(field.formatted(messages.getMessage("customjail.notify.in", null, locale), guildName)); + b.append(field.formatted(messages().getMessage("customjail.notify.in", null, locale), guildName)); fields.forEach( - (key, value) -> b.append(field.formatted(messages.getMessage(key, null, locale), value))); + (key, value) -> b.append(field.formatted(messages().getMessage(key, null, locale), value))); return channel.sendMessageEmbeds(builder.build()); }) @@ -820,7 +888,7 @@ private GuildMessageChannel getJailChannel(Guild guild, CustomJailConfiguration // =========================================================================================================== private void fireEvent(ApplicationEvent event) { - CompletableFuture.runAsync(() -> publisher.publishEvent(event)); + publisher.publishEvent(event); } private void ifEnabled(Guild guild, Consumer config) { @@ -865,8 +933,8 @@ private RestAction updateWarningRoles(CustomJailConfiguration config, Memb // Modify roles .modifyMemberRoles(member, modifyWarningRoles(config, member, level)) // Add reason - .reason(reason.orElseGet(() -> messages.getMessage("customjail.embed.defaultReason", null, - discordLogger.getEffectiveLocale(member.getGuild())))); + .reason(reason.orElseGet(() -> messages().getMessage(CommonMessages.DEFAULT_REASON, + messages().getLocaleForGuild(member.getGuild())))); } private Set modifyWarningRoles(CustomJailConfiguration config, Member member, int level) { @@ -899,9 +967,11 @@ private List getWarningRoles(CustomJailConfiguration config, Guild guild) } private ReplyCallbackAction error(IReplyCallback event, String code, Object... args) { - return event - .replyEmbeds(Response.error(messages.getMessage(code, args, code, event.getUserLocale().toLocale()))) - .setEphemeral(true); + return event.replyComponents(watame.getResponseV2().errorResolvable(Localized.resolved(code, args), + event.getUserLocale().toLocale())).useComponentsV2(); +// return event +// .replyEmbeds(Response.error(messages().getMessage(code, args, code, event.getUserLocale().toLocale()))) +// .setEphemeral(true); } private void kickFromVoiceChat(Member member) { @@ -915,13 +985,7 @@ private void kickFromVoiceChat(Member member) { .ifPresent(vcState -> member.getGuild().kickVoiceMember(member).queue()); } - @Override - public void setMessageSource(MessageSource messageSource) { - this.messages = messageSource; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; + private DiscordLocaleMessageSource messages() { + return watame.getMessageSource(); } } diff --git a/src/main/resources/plugins/customjail/lang/messages.properties b/src/main/resources/plugins/customjail/lang/messages.properties index 422f936..b906345 100644 --- a/src/main/resources/plugins/customjail/lang/messages.properties +++ b/src/main/resources/plugins/customjail/lang/messages.properties @@ -3,6 +3,11 @@ customjail.name = Custom Jail customjail.description = A custom timeout system built for the Max0r discord server customjail.footer = CustomJail customjail.anonymous = Anonymous +customjail.h1 = # {0} +customjail.h2 = ## {0} +customjail.h3 = ### {0} +customjail.small-text = -# {0} +customjail.bold-field = **{0}:** {1} # WEB customjail.enabled = Enabled @@ -20,6 +25,11 @@ customjail.notify.jailed = You have been jailed customjail.notify.unjailed = You have been un-jailed customjail.notify.timer-started = Jail Timer Started +# CONTAINER +customjail.container.jaildetails = ## Jail Details +customjail.container.jaildetails-for = -# For: {0} +customjail.container.jailed-by = Jailed By + # EMBED customjail.embed.reason = Reason customjail.embed.old-reason = Old Reason @@ -87,6 +97,11 @@ customjail.embed.set-time = Set Time customjail.embed.anon = Anonymous customjail.embed.non-anon = Public +customjail.embed.with-warning-description = Should this jailing result in a warning +customjail.embed.duration-description = Duration of the jailing +customjail.embed.anonymous-description = Should your name be hidden in the jailing +customjail.embed.reason-description = Reason for jailing user + # WARNINGS PAGE customjail.warnings.empty = No warnings customjail.warnings.footer = Page {1}/{2}\t{0} Warnings