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)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void onInventoryClick(InventoryClickEvent event){
|
public void onInventoryClick(InventoryClickEvent event){
|
||||||
if (event.getInventory().getHolder() instanceof CustomInventory customInventory){
|
if (event.getInventory().getHolder() instanceof CustomInventory customInventory){
|
||||||
customInventory.click(event.getCurrentItem());
|
customInventory.click(event.getCurrentItem(), event);
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.shiewk.smoderation.inventory;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ public interface CustomInventory extends InventoryHolder {
|
|||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
void open();
|
void open();
|
||||||
void click(ItemStack stack);
|
void click(ItemStack stack, InventoryClickEvent event);
|
||||||
|
|
||||||
default ItemStack createEmptyStack(){
|
default ItemStack createEmptyStack(){
|
||||||
ItemStack stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
|
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.NamedTextColor;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public abstract class PageableCustomInventory implements CustomInventory {
|
public abstract class PageableCustomInventory implements CustomInventory {
|
||||||
@@ -18,7 +19,7 @@ public abstract class PageableCustomInventory implements CustomInventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void click(ItemStack stack) {
|
public void click(ItemStack stack, InventoryClickEvent event) {
|
||||||
if (stack != null){
|
if (stack != null){
|
||||||
if (stack.equals(previousStack)){
|
if (stack.equals(previousStack)){
|
||||||
previousPage();
|
previousPage();
|
||||||
|
|||||||
@@ -12,23 +12,81 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class SModMenu extends PageableCustomInventory {
|
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 Inventory inventory;
|
||||||
private final Player player;
|
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) {
|
public SModMenu(Player player, PunishmentContainer container) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.container = container;
|
||||||
this.inventory = Bukkit.createInventory(this, 54, Component.text("SMod Menu"));
|
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
|
@Override
|
||||||
@@ -36,14 +94,90 @@ public class SModMenu extends PageableCustomInventory {
|
|||||||
return Math.max((punishments.size() - 1) / 45, 0);
|
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
|
@Override
|
||||||
public void switchPage() {
|
public void switchPage() {
|
||||||
player.playSound(player, Sound.BLOCK_STONE_HIT, 0.75f, 1f);
|
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){
|
private ItemStack createPunishmentItem(Punishment punishment){
|
||||||
final NamedTextColor PRIMARY_COLOR = NamedTextColor.AQUA;
|
|
||||||
final NamedTextColor SECONDARY_COLOR = NamedTextColor.GREEN;
|
|
||||||
ItemStack stack = new ItemStack(Material.PLAYER_HEAD);
|
ItemStack stack = new ItemStack(Material.PLAYER_HEAD);
|
||||||
stack.editMeta(meta -> {
|
stack.editMeta(meta -> {
|
||||||
if (meta instanceof SkullMeta skullMeta){
|
if (meta instanceof SkullMeta skullMeta){
|
||||||
@@ -79,6 +213,8 @@ public class SModMenu extends PageableCustomInventory {
|
|||||||
}
|
}
|
||||||
inventory.setItem(45, createPreviousPageStack());
|
inventory.setItem(45, createPreviousPageStack());
|
||||||
inventory.setItem(53, createNextPageStack());
|
inventory.setItem(53, createNextPageStack());
|
||||||
|
inventory.setItem(50, createFilterItem());
|
||||||
|
inventory.setItem(48, createSortItem());
|
||||||
|
|
||||||
for (int i = 0; i < 45; i++) {
|
for (int i = 0; i < 45; i++) {
|
||||||
int ci = i + (getPage() * 45);
|
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
|
@Override
|
||||||
public void open() {
|
public void open() {
|
||||||
|
reload();
|
||||||
refresh();
|
refresh();
|
||||||
player.openInventory(this.inventory);
|
player.openInventory(this.inventory);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user