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:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user