From 8838961f3756e4a39fe7cca3785f6f1897be5a5b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 15 Sep 2023 22:15:00 +0200 Subject: [PATCH] feat(i18n): admin gui --- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 7 +-- .../gui/items/admin/ManageCacheItem.java | 23 +++++----- .../gui/items/admin/ManagePlayerItem.java | 38 ++++++++-------- .../admin/cache/CacheStatisticsItem.java | 1 - .../nicko/gui/items/common/LoadingItem.java | 27 ++++++++++++ .../nicko/gui/items/home/ResetItem.java | 9 ++-- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 5 +-- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 3 +- src/main/resources/en.yml | 4 +- src/main/resources/fr.yml | 12 ++--- ...tionTest.java => ItemTranslationTest.java} | 12 ++--- .../nicko/test/i18n/TranslationTest.java | 44 +++++++++++++++++++ 12 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java rename src/test/java/xyz/atnrch/nicko/test/i18n/{I18NItemTranslationTest.java => ItemTranslationTest.java} (74%) create mode 100644 src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 92f5aeb..3c10319 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -22,16 +22,17 @@ public class AdminGUI { final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); final UnavailableItem unavailableItem = new UnavailableItem(player); + final ManagePlayerItem managePlayerItem = new ManagePlayerItem(i18n, player); this.gui = Gui.normal() .setStructure( "# # # # # # # # #", - "# # # S C U # # #", + "# # # S C X # # #", "B # # # # # # # #" ) - .addIngredient('S', new ManageCacheItem()) + .addIngredient('S', new ManageCacheItem(i18n)) + .addIngredient('C', managePlayerItem.get()) .addIngredient('U', unavailableItem.get()) - .addIngredient('C', new ManagePlayerItem()) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); this.player = player; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java index 0a65cc9..9e1a2d6 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java @@ -1,24 +1,25 @@ package xyz.atnrch.nicko.gui.items.admin; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.builder.SkullBuilder; -import xyz.xenondevs.invui.item.impl.AsyncItem; -import xyz.atnrch.nicko.gui.CacheManagementGUI; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; +import xyz.atnrch.nicko.gui.CacheManagementGUI; +import xyz.atnrch.nicko.gui.items.common.LoadingItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.impl.AsyncItem; public class ManageCacheItem extends AsyncItem { - public ManageCacheItem() { - super(new ItemBuilder(Material.PAINTING) - .setDisplayName("Manage §6skin §fcache...") - .addLoreLines("§7Access the skin cache management panel."), + public ManageCacheItem(I18N i18n) { + super(new LoadingItem(i18n).get(), () -> { final SkullBuilder builder = new SkullBuilder("Notch"); - builder.setDisplayName("Manage §6skin §fcache..."); - builder.addLoreLines("§7Access the skin cache management panel."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java index dcf133f..0736036 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java @@ -2,30 +2,32 @@ package xyz.atnrch.nicko.gui.items.admin; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.gui.PlayerCheckGUI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ManagePlayerItem extends SuppliedItem { - public ManagePlayerItem() { - super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); - builder.setDisplayName("Check a player..."); - builder.addLoreLines("§7See players' disguise information."); - return builder; - }, - click -> true); +public class ManagePlayerItem { + private final Player player; + private final I18N i18n; + + public ManagePlayerItem(I18N i18n, Player player) { + this.i18n = i18n; + this.player = player; } - @Override - public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent - event) { - if (clickType.isLeftClick() || clickType.isRightClick()) { - event.getView().close(); + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_PLAYER); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, click -> { new PlayerCheckGUI(player).open(); - } + return true; + }); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java index c759ea5..027100e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java @@ -31,7 +31,6 @@ public class CacheStatisticsItem { stats.requestCount(), Math.round(cache.size()) ); - translation.getLore().forEach(System.out::println); // TODO (Ineanto, 9/11/23): This doesn't work. builder.setDisplayName(translation.getName()); translation.getLore().forEach(builder::addLoreLines); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java new file mode 100644 index 0000000..c305b4a --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java @@ -0,0 +1,27 @@ +package xyz.atnrch.nicko.gui.items.common; + +import org.bukkit.Material; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class LoadingItem { + private final I18N i18n; + + public LoadingItem(I18N i18n) { + this.i18n = i18n; + } + + public ItemProvider get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.PAINTING); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.LOADING); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, (click -> true)).getItemProvider(); + } +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java index e142dba..ff9df25 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java @@ -12,7 +12,6 @@ import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; public class ResetItem { private final I18N i18n; @@ -33,25 +32,23 @@ public class ResetItem { final ClickType clickType = event.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { final Optional optionalProfile = NickoProfile.get(player); - final AtomicBoolean result = new AtomicBoolean(false); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); event.getEvent().getView().close(); - result.set(true); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.reset().isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); - result.set(false); } else { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); - result.set(true); + profile.setSkin(null); + profile.setName(null); } }); - return result.get(); + return true; } return false; }); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index f0b7385..0087468 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -18,7 +18,7 @@ public class I18N { private final MessageFormat formatter = new MessageFormat(""); private final Logger logger = Logger.getLogger("I18N"); private final NickoBukkit instance = NickoBukkit.getInstance(); - private final Pattern replacementPattern = Pattern.compile("\\{\\d+}"); + private final Pattern replacementPattern = Pattern.compile("\\{\\d+}$", Pattern.DOTALL); private final YamlConfig yamlConfig; private final Player player; private final Locale playerLocale; @@ -67,14 +67,13 @@ public class I18N { // If the line doesn't contain {i}, skip it final Matcher matcher = replacementPattern.matcher(currentLine); - if (!matcher.matches()) { + if (!matcher.find()) { lineIndex++; continue; } // If it does, replace the content with the args at position replacementIndex if (replacementIndex < args.length && args[replacementIndex] != null) { - System.out.println("replacing..."); // Replace with the corresponding varargs index toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); replacementIndex++; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index f8df6b8..0878f2b 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -67,8 +67,9 @@ public class I18NDict { private static final String GUI_KEY = "gui."; public static final String EXIT = GUI_KEY + "exit"; - public static final String UNAVAILABLE = GUI_KEY + "unavailable"; public static final String GO_BACK = GUI_KEY + "go_back"; + public static final String UNAVAILABLE = GUI_KEY + "unavailable"; + public static final String LOADING = GUI_KEY + "loading"; public static class Choice { private static final String CHOICE_KEY = GUI_KEY + "choice."; diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index d9658f3..3e904af 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -36,6 +36,8 @@ gui: name: "Unavailable" lore: - "§7§oThis button is disabled." + loading: + name: "§7§oLoading..." choice: confirm: name: "§aConfirm" @@ -68,7 +70,7 @@ gui: manage_cache: name: "Manage §6skin §fcache..." lore: - - "§7Access the skin cache management panel." + - "§7View and manage the skin cache." manage_player: name: "Check a player..." lore: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 9543229..ebf2428 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -13,14 +13,14 @@ event: error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" appearance: set: - error: "§cImpossible d'appliquer votre déguisement. §7§o({0})" + error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" ok: "§fDéguisement appliqué." restore: - error: "§cImpossible d'appliquer votre précédent déguisement. §7§o({0})" + error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" ok: "§aVotre précédent déguisement a été appliqué." remove: error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." - missing: "§cVous n'avez pas de déguisement." + missing: "§cVous n''avez pas de déguisement." ok: "§fDéguisement retiré." admin: cache: @@ -36,6 +36,8 @@ gui: name: "Indisponible" lore: - "§7§oCe boutton est désactivé." + loading: + name: "§7§oChargement..." choice: confirm: name: "§aConfirmer" @@ -66,9 +68,9 @@ gui: admin: title: "Nicko > Administration" manage_cache: - name: "Gérer le cache d'§6skin..." + name: "Gérer le cache de §6skin..." lore: - - "§7Accédez à la gestion du cache de skin." + - "§7Consultez et gérez le cache de skin." manage_player: name: "Vérifier un joueur..." lore: diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java similarity index 74% rename from src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java rename to src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java index 6e55d99..a1b6e55 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -14,10 +14,9 @@ import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.atnrch.nicko.i18n.Locale; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; -public class I18NItemTranslationTest { +public class ItemTranslationTest { private static PlayerMock player; @BeforeAll @@ -44,8 +43,11 @@ public class I18NItemTranslationTest { @DisplayName("Translate Item") public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test!"); - assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test!)", translation); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + assertFalse(translation.getLore().isEmpty()); + assertEquals("§fNombre de requêtes: §b1", translation.getLore().get(0)); + assertEquals("§fNb. de skin dans le cache: §b1", translation.getLore().get(1)); + assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.getLore().get(2)); } @AfterAll diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java new file mode 100644 index 0000000..6e16840 --- /dev/null +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java @@ -0,0 +1,44 @@ +package xyz.atnrch.nicko.test.i18n; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.Locale; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TranslationTest { + private static PlayerMock player; + + @BeforeAll + public static void setup() { + final Configuration config = new Configuration( + DataSourceConfiguration.SQL_EMPTY, + DataSourceConfiguration.REDIS_EMPTY, + "", + false); + MockBukkit.mock(); + MockBukkit.load(NickoBukkit.class, config); + } + + @Test + @DisplayName("Translate Line With Replacement") + public void translateItemTranslationWithoutLore() { + final I18N i18n = new I18N(Locale.FRENCH); + final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test"); + assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +}