1
mirror of https://github.com/Shiewk/SModeration.git synced 2026-04-28 05:54:16 +02:00

Add sorting and filter options for SMod Menu

This commit is contained in:
Shy
2024-06-08 16:08:23 +02:00
parent 1f85d65bdd
commit c65781b7bd
4 changed files with 158 additions and 7 deletions
@@ -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);
}
}
@@ -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);
@@ -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();
@@ -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<Punishment> filter;
Filter(String name, Predicate<Punishment> 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<Punishment> comparator;
Sort(String name, Comparator<Punishment> 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<Punishment> punishments;
private final PunishmentContainer container;
private List<Punishment> 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<Component> 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<Component> 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);
}