From c65781b7bdb8bb6c97aac6a8b806e786baa01e9d Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sat, 8 Jun 2024 16:08:23 +0200 Subject: [PATCH] Add sorting and filter options for SMod Menu --- .../event/CustomInventoryEvents.java | 2 +- .../inventory/CustomInventory.java | 3 +- .../inventory/PageableCustomInventory.java | 3 +- .../smoderation/inventory/SModMenu.java | 157 +++++++++++++++++- 4 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/shiewk/smoderation/event/CustomInventoryEvents.java b/src/main/java/de/shiewk/smoderation/event/CustomInventoryEvents.java index efe398b..3cf21ec 100644 --- a/src/main/java/de/shiewk/smoderation/event/CustomInventoryEvents.java +++ b/src/main/java/de/shiewk/smoderation/event/CustomInventoryEvents.java @@ -10,7 +10,7 @@ public class CustomInventoryEvents implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onInventoryClick(InventoryClickEvent event){ if (event.getInventory().getHolder() instanceof CustomInventory customInventory){ - customInventory.click(event.getCurrentItem()); + customInventory.click(event.getCurrentItem(), event); event.setCancelled(true); } } diff --git a/src/main/java/de/shiewk/smoderation/inventory/CustomInventory.java b/src/main/java/de/shiewk/smoderation/inventory/CustomInventory.java index 629dbed..2d5df48 100644 --- a/src/main/java/de/shiewk/smoderation/inventory/CustomInventory.java +++ b/src/main/java/de/shiewk/smoderation/inventory/CustomInventory.java @@ -3,6 +3,7 @@ package de.shiewk.smoderation.inventory; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @@ -10,7 +11,7 @@ public interface CustomInventory extends InventoryHolder { void refresh(); void open(); - void click(ItemStack stack); + void click(ItemStack stack, InventoryClickEvent event); default ItemStack createEmptyStack(){ ItemStack stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE); diff --git a/src/main/java/de/shiewk/smoderation/inventory/PageableCustomInventory.java b/src/main/java/de/shiewk/smoderation/inventory/PageableCustomInventory.java index aaa408c..e82f199 100644 --- a/src/main/java/de/shiewk/smoderation/inventory/PageableCustomInventory.java +++ b/src/main/java/de/shiewk/smoderation/inventory/PageableCustomInventory.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; public abstract class PageableCustomInventory implements CustomInventory { @@ -18,7 +19,7 @@ public abstract class PageableCustomInventory implements CustomInventory { } @Override - public void click(ItemStack stack) { + public void click(ItemStack stack, InventoryClickEvent event) { if (stack != null){ if (stack.equals(previousStack)){ previousPage(); diff --git a/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java b/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java index f0948d8..bd91bc1 100644 --- a/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java +++ b/src/main/java/de/shiewk/smoderation/inventory/SModMenu.java @@ -12,23 +12,81 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Predicate; public class SModMenu extends PageableCustomInventory { + public enum Filter { + ACTIVE("Active punishments", p -> p.until > System.currentTimeMillis()), + OLD("Expired punishments", p -> p.until < System.currentTimeMillis()), + ALL("All punishments", p -> true); + + public static final Material ICON = Material.HOPPER; + + public final String name; + public final Predicate filter; + Filter(String name, Predicate filter) { + this.name = name; + this.filter = filter; + } + } + + public enum Sort { + EXPIRY("Expiry", Comparator.comparingLong(p -> p.until)), + TIME("Date", Comparator.comparingLong(p -> p.time)), + PLAYER_NAME("Player name", (p1, p2) -> String.CASE_INSENSITIVE_ORDER.compare(PlayerUtil.offlinePlayerName(p1.to), PlayerUtil.offlinePlayerName(p2.to))), + MODERATOR_NAME("Moderator name", (p1, p2) -> String.CASE_INSENSITIVE_ORDER.compare(PlayerUtil.offlinePlayerName(p1.by), PlayerUtil.offlinePlayerName(p2.by))); + + public static final Material ICON = Material.COMPARATOR; + + public final String name; + public final Comparator comparator; + + Sort(String name, Comparator comparator) { + this.name = name; + this.comparator = comparator; + } + } + + public static final NamedTextColor PRIMARY_COLOR = NamedTextColor.AQUA; + public static final NamedTextColor SECONDARY_COLOR = NamedTextColor.GREEN; + public static final NamedTextColor INACTIVE_COLOR = NamedTextColor.GRAY; + private final Inventory inventory; private final Player player; - private final ArrayList punishments; + private final PunishmentContainer container; + private List punishments; + private ItemStack sortStack = null; + private ItemStack filterStack = null; + private int sort = 0; + private int filter = 0; public SModMenu(Player player, PunishmentContainer container) { this.player = player; + this.container = container; this.inventory = Bukkit.createInventory(this, 54, Component.text("SMod Menu")); - punishments = container.copy(); + reload(); + } + + public Sort getSort(){ + return Sort.values()[sort]; + } + + public Filter getFilter(){ + return Filter.values()[filter]; + } + + private void reload(){ + this.punishments = container.copy().stream().filter(getFilter().filter).sorted(getSort().comparator).toList(); } @Override @@ -36,14 +94,90 @@ public class SModMenu extends PageableCustomInventory { return Math.max((punishments.size() - 1) / 45, 0); } + public void cycleFilter(boolean backwards){ + player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, backwards ? 0.8f : 2f); + if (backwards){ + if (filter <= 0){ + filter = Filter.values().length-1; + } else { + filter--; + } + } else { + if (filter >= Filter.values().length-1){ + filter = 0; + } else { + filter++; + } + } + reload(); + refresh(); + } + + public void cycleSort(boolean backwards){ + player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, backwards ? 0.8f : 2f); + if (backwards){ + if (sort <= 0){ + sort = Sort.values().length-1; + } else { + sort--; + } + } else { + if (sort >= Sort.values().length-1){ + sort = 0; + } else { + sort++; + } + } + reload(); + refresh(); + } + @Override public void switchPage() { player.playSound(player, Sound.BLOCK_STONE_HIT, 0.75f, 1f); } + private ItemStack createFilterItem(){ + final Filter filter = getFilter(); + final ItemStack stack = new ItemStack(Filter.ICON); + stack.editMeta(meta -> { + meta.displayName(applyFormatting(Component.text("Filter: " + filter.name).color(SECONDARY_COLOR))); + ArrayList lore = new ArrayList<>(); + lore.add(Component.empty()); + for (Filter value : Filter.values()) { + final boolean selected = filter == value; + Component filterText = applyFormatting(Component.text((selected ? "\u00BB " : "") + value.name).color(selected ? PRIMARY_COLOR : INACTIVE_COLOR)); + lore.add(filterText); + } + lore.add(Component.empty()); + lore.add(applyFormatting(Component.text("\u00BB Click to switch filter").color(NamedTextColor.GOLD))); + meta.lore(lore); + }); + filterStack = stack; + return stack; + } + + private ItemStack createSortItem(){ + final Sort sort = getSort(); + final ItemStack stack = new ItemStack(Sort.ICON); + stack.editMeta(meta -> { + meta.displayName(applyFormatting(Component.text("Sort by: " + sort.name).color(PRIMARY_COLOR))); + ArrayList lore = new ArrayList<>(); + lore.add(Component.empty()); + for (Sort value : Sort.values()) { + final boolean selected = sort == value; + Component sortText = applyFormatting(Component.text((selected ? "\u00BB " : "") + value.name).color(selected ? SECONDARY_COLOR : INACTIVE_COLOR)); + lore.add(sortText); + } + lore.add(Component.empty()); + lore.add(applyFormatting(Component.text("\u00BB Click to switch sorting option").color(NamedTextColor.GOLD))); + meta.lore(lore); + }); + sortStack = stack; + return stack; + } + private ItemStack createPunishmentItem(Punishment punishment){ - final NamedTextColor PRIMARY_COLOR = NamedTextColor.AQUA; - final NamedTextColor SECONDARY_COLOR = NamedTextColor.GREEN; ItemStack stack = new ItemStack(Material.PLAYER_HEAD); stack.editMeta(meta -> { if (meta instanceof SkullMeta skullMeta){ @@ -79,6 +213,8 @@ public class SModMenu extends PageableCustomInventory { } inventory.setItem(45, createPreviousPageStack()); inventory.setItem(53, createNextPageStack()); + inventory.setItem(50, createFilterItem()); + inventory.setItem(48, createSortItem()); for (int i = 0; i < 45; i++) { int ci = i + (getPage() * 45); @@ -90,8 +226,21 @@ public class SModMenu extends PageableCustomInventory { } } + @Override + public void click(ItemStack stack, InventoryClickEvent event) { + super.click(stack, event); + if (stack != null) { + if (stack.equals(filterStack)){ + cycleFilter(event.isRightClick()); + } else if (stack.equals(sortStack)){ + cycleSort(event.isRightClick()); + } + } + } + @Override public void open() { + reload(); refresh(); player.openInventory(this.inventory); }