diff --git a/src/main/java/com/softawii/curupira/example/Foo.java b/src/main/java/com/softawii/curupira/example/Foo.java index 599ca53..4f8a661 100644 --- a/src/main/java/com/softawii/curupira/example/Foo.java +++ b/src/main/java/com/softawii/curupira/example/Foo.java @@ -1,12 +1,13 @@ package com.softawii.curupira.example; -import com.softawii.curupira.v2.annotations.DiscordCommand; -import com.softawii.curupira.v2.annotations.DiscordController; -import com.softawii.curupira.v2.annotations.DiscordParameter; -import com.softawii.curupira.v2.annotations.RequestInfo; +import com.softawii.curupira.v2.annotations.*; import com.softawii.curupira.v2.api.TextLocaleResponse; +import com.softawii.curupira.v2.localization.LocalizationManager; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.DiscordLocale; @@ -14,7 +15,7 @@ import org.w3c.dom.Text; @DiscordController(value = "bar", description = "foo foo foo", parent = "foo", permissions = {Permission.ADMINISTRATOR}, - resource = "i18n", locales = {DiscordLocale.ENGLISH_US}, defaultLocale = DiscordLocale.PORTUGUESE_BRAZILIAN) + resource = "i18n", locales = {DiscordLocale.PORTUGUESE_BRAZILIAN}) public class Foo { // @DiscordCommand(name = "baz", description = "baz baz baz", ephemeral = true) @@ -28,14 +29,24 @@ public class Foo { // return "Hello " + name + " you are " + age + " years old"; // } -// @DiscordCommand(name = "qux", description = "qux qux qux") -// public String qux(SlashCommandInteractionEvent event, -// @RequestInfo Member member, -// @DiscordParameter(name = "hello", description = "channel to send hello") MessageChannelUnion channel) { -// channel.sendMessage("hello chat").queue(); -// return "Hello " + member.getEffectiveName(); -// } -// + @DiscordCommand(name = "qux", description = "qux qux qux") + public MessageEmbed qux(JDA jda, + LocalizationManager localization, + @RequestInfo Member member, + @LocaleType DiscordLocale locale, + @DiscordParameter(name = "title", description = "embed title") String title, + @DiscordParameter(name = "description", description = "embed description") String description) { + + String titleMessage = localization.getLocalizedString("foo.bar.qux.embed.title", locale, title, member.getNickname()); + String descriptionMessage = localization.getLocalizedString("foo.bar.qux.embed.description", locale, member.getEffectiveName(), jda.getSelfUser().getEffectiveName()); + + return new EmbedBuilder() + .setTitle(titleMessage) + .setDescription(descriptionMessage) + .addField("Field 1", description, false) + .build(); + } + @DiscordCommand(name = "charlie", description = "charlie charlie charlie") public TextLocaleResponse charlie( @RequestInfo Member member, diff --git a/src/main/java/com/softawii/curupira/v2/annotations/LocaleType.java b/src/main/java/com/softawii/curupira/v2/annotations/LocaleType.java new file mode 100644 index 0000000..e0b11bb --- /dev/null +++ b/src/main/java/com/softawii/curupira/v2/annotations/LocaleType.java @@ -0,0 +1,14 @@ +package com.softawii.curupira.v2.annotations; + +import com.softawii.curupira.v2.enums.LocaleTypeEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface LocaleType { + LocaleTypeEnum value() default LocaleTypeEnum.USER; +} diff --git a/src/main/java/com/softawii/curupira/v2/core/CommandHandler.java b/src/main/java/com/softawii/curupira/v2/core/CommandHandler.java index a0351ad..212934a 100644 --- a/src/main/java/com/softawii/curupira/v2/core/CommandHandler.java +++ b/src/main/java/com/softawii/curupira/v2/core/CommandHandler.java @@ -4,6 +4,8 @@ import com.softawii.curupira.v2.annotations.DiscordController; import com.softawii.curupira.v2.annotations.DiscordParameter; import com.softawii.curupira.v2.api.TextLocaleResponse; +import com.softawii.curupira.v2.localization.LocalizationManager; +import com.softawii.curupira.v2.parser.DiscordToJavaParser; import com.softawii.curupira.v2.parser.JavaToDiscordParser; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent; @@ -22,9 +24,6 @@ import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.List; -import java.util.Map; - -import static com.softawii.curupira.v2.parser.DiscordToJavaParser.getParameterFromEvent; class CommandHandler { private static final Logger logger = LoggerFactory.getLogger(CommandHandler.class); @@ -32,7 +31,7 @@ class CommandHandler { private final Object instance; private final Method method; // i18n - private final LocalizationFunction localization; + private final LocalizationManager localization; private final DiscordLocale defaultLocale; private List options; @@ -42,8 +41,8 @@ public CommandHandler(JDA jda, Object instance, Method method, LocalizationFunct this.jda = jda; this.method = method; this.instance = instance; - this.localization = localization; this.defaultLocale = defaultLocale; + this.localization = new LocalizationManager(localization, defaultLocale); register(); } @@ -110,7 +109,7 @@ private Object[] getParameters(CommandInteractionPayload event) { List parameters = new ArrayList<>(); for(Parameter parameter : method.getParameters()) - parameters.add(getParameterFromEvent(event, parameter)); + parameters.add(DiscordToJavaParser.getParameterFromEvent(event, parameter, localization)); return parameters.toArray(); } @@ -119,17 +118,8 @@ public void execute(GenericCommandInteractionEvent event) throws InvocationTarge // something to reply if(result != null) { if(result instanceof TextLocaleResponse response) { - Map locales = localization.apply(response.code()); - String mask; - if(locales.containsKey(event.getUserLocale())) { - mask = locales.get(event.getUserLocale()); - } else { - mask = locales.get(defaultLocale); - } - - result = String.format(mask, response.args()); + result = localization.getLocalizedString(response.code(), event.getUserLocale(), response.args()); } - JavaToDiscordParser.responseFromCommandEvent(event, result, ephemeral); } } diff --git a/src/main/java/com/softawii/curupira/v2/enums/LocaleTypeEnum.java b/src/main/java/com/softawii/curupira/v2/enums/LocaleTypeEnum.java new file mode 100644 index 0000000..6b1c57a --- /dev/null +++ b/src/main/java/com/softawii/curupira/v2/enums/LocaleTypeEnum.java @@ -0,0 +1,6 @@ +package com.softawii.curupira.v2.enums; + +public enum LocaleTypeEnum { + USER, + GUILD +} diff --git a/src/main/java/com/softawii/curupira/v2/localization/LocalizationManager.java b/src/main/java/com/softawii/curupira/v2/localization/LocalizationManager.java new file mode 100644 index 0000000..4755662 --- /dev/null +++ b/src/main/java/com/softawii/curupira/v2/localization/LocalizationManager.java @@ -0,0 +1,31 @@ +package com.softawii.curupira.v2.localization; + +import net.dv8tion.jda.api.interactions.DiscordLocale; +import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction; +import org.slf4j.helpers.MessageFormatter; + +import java.text.MessageFormat; +import java.util.Map; + +public class LocalizationManager { + private final LocalizationFunction localization; + private final DiscordLocale defaultLocale; + + public LocalizationManager(LocalizationFunction localization, DiscordLocale defaultLocale) { + this.localization = localization; + this.defaultLocale = defaultLocale; + } + + public String getLocalizedString(String key, DiscordLocale userLocale, Object ... args) { + Map locales = localization.apply(key); + String mask; + if(locales.containsKey(userLocale)) { + mask = locales.get(userLocale); + } else { + mask = locales.get(defaultLocale); + } + + String result = MessageFormatter.arrayFormat(mask, args).getMessage(); + return result; + } +} diff --git a/src/main/java/com/softawii/curupira/v2/parser/DiscordToJavaParser.java b/src/main/java/com/softawii/curupira/v2/parser/DiscordToJavaParser.java index b79fdb1..65e58b0 100644 --- a/src/main/java/com/softawii/curupira/v2/parser/DiscordToJavaParser.java +++ b/src/main/java/com/softawii/curupira/v2/parser/DiscordToJavaParser.java @@ -1,12 +1,17 @@ package com.softawii.curupira.v2.parser; import com.softawii.curupira.v2.annotations.DiscordParameter; +import com.softawii.curupira.v2.annotations.LocaleType; import com.softawii.curupira.v2.annotations.RequestInfo; +import com.softawii.curupira.v2.enums.LocaleTypeEnum; +import com.softawii.curupira.v2.localization.LocalizationManager; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.DiscordLocale; import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload; import net.dv8tion.jda.api.interactions.commands.OptionMapping; @@ -14,8 +19,18 @@ public class DiscordToJavaParser { - public static Object getParameterFromEvent(CommandInteractionPayload event, Parameter parameter) { - if(parameter.getType().equals(SlashCommandInteractionEvent.class)) { + public static Object getParameterFromEvent(CommandInteractionPayload event, Parameter parameter, LocalizationManager localization) { + if(LocalizationManager.class.isAssignableFrom(parameter.getType())) { + return localization; + } + else if(JDA.class.isAssignableFrom(parameter.getType())) { + return event.getJDA(); + } + else if(parameter.getType().equals(DiscordLocale.class) && parameter.isAnnotationPresent(LocaleType.class)) { + if(parameter.getAnnotation(LocaleType.class).value() == LocaleTypeEnum.GUILD) return event.getGuildLocale(); + else return event.getUserLocale(); + } + else if(parameter.getType().equals(SlashCommandInteractionEvent.class)) { return event; } else if(parameter.getType().equals(String.class)) { diff --git a/src/main/resources/i18n_en_US.properties b/src/main/resources/i18n_en_US.properties index bcd2134..c5ee03f 100644 --- a/src/main/resources/i18n_en_US.properties +++ b/src/main/resources/i18n_en_US.properties @@ -10,4 +10,18 @@ foo.bar.charlie.description = charlie charlie charlie foo.bar.charlie.poll.name = poll foo.bar.charlie.poll.description = poll poll poll -foo.bar.charlie.response.ok = "It's ok bro, %s" \ No newline at end of file +foo.bar.charlie.response.ok = "It's ok bro, {}" + +# Qux Command + +foo.bar.qux.name = qux +foo.bar.qux.description = qux qux qux + +foo.bar.qux.title.name = title +foo.bar.qux.title.description = title description + +foo.bar.qux.description.name = description +foo.bar.qux.description.description = description description + +foo.bar.qux.embed.title = dear {} {} +foo.bar.qux.embed.description = noble {}, please call me {}, nice to meet you! \ No newline at end of file diff --git a/src/main/resources/i18n_pt_BR.properties b/src/main/resources/i18n_pt_BR.properties index f94260a..1d78628 100644 --- a/src/main/resources/i18n_pt_BR.properties +++ b/src/main/resources/i18n_pt_BR.properties @@ -1,13 +1,30 @@ +# Base Command foo.name = fernando foo.description = fernando pessoa +# Base Command 2 foo.bar.name = bares foo.bar.description = bares e afins +# Charlie Command foo.bar.charlie.name = charles foo.bar.charlie.description = charles trismegistus foo.bar.charlie.poll.name = piscina foo.bar.charlie.poll.description = piscina de bolinhas -foo.bar.charlie.response.ok = "tudo certo, %s" \ No newline at end of file +foo.bar.charlie.response.ok = "tudo certo, {}" + +# Qux Command + +foo.bar.qux.name = quixote +foo.bar.qux.description = quixote de la mancha + +foo.bar.qux.title.name = titulo +foo.bar.qux.title.description = titulo de nobreza + +foo.bar.qux.description.name = descricao +foo.bar.qux.description.description = descricao de nobreza + +foo.bar.qux.embed.title = caro {} {} +foo.bar.qux.embed.description = nobre {}, peço que me chame de {}, prazer! \ No newline at end of file