diff --git a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java index 8584bc8..42a5afe 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java @@ -95,7 +95,7 @@ public class BooksWithoutBorders extends JavaPlugin { playerBooksList.put(playerUUID, newFiles); playerLetterIndex.put(playerUUID, BookFileHelper.populateLetterIndices(newFiles)); } - return playerBooksList.get(playerUUID); + return new ArrayList<>(playerBooksList.get(playerUUID)); } else { return new ArrayList<>(); } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java index 3ef6894..75e2034 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDelete.java @@ -5,7 +5,6 @@ import net.knarcraft.bookswithoutborders.gui.PagedBookIndex; import net.knarcraft.bookswithoutborders.state.BookDirectory; import net.knarcraft.bookswithoutborders.utility.BookFileHelper; import net.knarcraft.bookswithoutborders.utility.BookHelper; -import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; import net.knarcraft.knarlib.util.TabCompletionHelper; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -23,41 +22,34 @@ import java.util.List; public class CommandDelete implements TabExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] arguments) { if (!(sender instanceof Player)) { BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); return false; } - return deleteBook(sender, args, false); + return deleteBook(sender, arguments, false); } /** * Deletes a book * * @param sender

The sender trying to delete the book

- * @param args

The arguments given

+ * @param arguments

The arguments given

* @param deletePublic

Whether to delete a public book

* @return

True if the book was deleted successfully

*/ - boolean deleteBook(CommandSender sender, String[] args, boolean deletePublic) { + boolean deleteBook(@NotNull CommandSender sender, @NotNull String[] arguments, boolean deletePublic) { String command = deletePublic ? "deletepublicbook" : "deletebook"; - //List deletable files - if (args.length == 0) { - PagedBookIndex.printBooks(sender, deletePublic, command, 1); + if (PagedBookIndex.displayPage(arguments, sender, deletePublic, command)) { return true; } + //Delete the file - if (args.length == 1) { - int page = InputCleaningHelper.parsePageNumber(args[0]); - if (page > 0) { - PagedBookIndex.printBooks(sender, deletePublic, command, page); - return true; - } - + if (arguments.length == 1) { List availableBooks = BooksWithoutBorders.getAvailableBooks(sender, deletePublic); if (!availableBooks.isEmpty()) { - performBookDeletion(sender, args[0], deletePublic); + performBookDeletion(sender, arguments[0], deletePublic); //Update the book list BooksWithoutBorders.updateBooks(sender, deletePublic); return true; diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java index ceb8b6b..7514090 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandDeletePublic.java @@ -13,8 +13,8 @@ import java.util.List; public class CommandDeletePublic extends CommandDelete implements TabExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - return deleteBook(sender, args, true); + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] arguments) { + return deleteBook(sender, arguments, true); } @Override diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java index 28ed22b..587a541 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGive.java @@ -25,55 +25,48 @@ public class CommandGive implements TabExecutor { private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance(); @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] arguments) { if (!(sender instanceof Player)) { BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); return false; } - return giveBook(sender, args, false, "player"); + return giveBook(sender, arguments, false, "player"); } /** * Gives a book to another player * * @param sender

The sender trying to give a book

- * @param args

The arguments given

+ * @param arguments

The arguments given

* @param givePublic

Whether to give a public book

* @param folder

The folder containing the book to load

* @return

True if the book was given successfully

*/ - boolean giveBook(CommandSender sender, String[] args, boolean givePublic, String folder) { + boolean giveBook(@NotNull CommandSender sender, String[] arguments, boolean givePublic, String folder) { String command = givePublic ? "givepublicbook" : "givebook"; - if (args.length == 0) { - PagedBookIndex.printBooks(sender, givePublic, command, 1); + if (PagedBookIndex.displayPage(arguments, sender, givePublic, command)) { return true; - } else if (args.length == 1) { - int page = InputCleaningHelper.parsePageNumber(args[0]); - if (page > 0) { - PagedBookIndex.printBooks(sender, givePublic, command, page); - return true; - } } - if (args.length == 1 || args.length > 4) { + if (arguments.length == 1 || arguments.length > 4) { BooksWithoutBorders.sendErrorMessage(sender, "Incorrect number of arguments for this command!"); return false; } //Organize and parse input - String bookIdentifier = args[0]; - String receivingPlayerName = args[1]; + String bookIdentifier = arguments[0]; + String receivingPlayerName = arguments[1]; String copies = "1"; String isSigned = "true"; - if (args.length == 4) { - copies = args[2]; - isSigned = args[3]; - } else if (args.length == 3) { - if (args[2].equalsIgnoreCase("true") || args[2].equalsIgnoreCase("false")) { - isSigned = args[2]; + if (arguments.length == 4) { + copies = arguments[2]; + isSigned = arguments[3]; + } else if (arguments.length == 3) { + if (arguments[2].equalsIgnoreCase("true") || arguments[2].equalsIgnoreCase("false")) { + isSigned = arguments[2]; } else { - copies = args[2]; + copies = arguments[2]; } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java index 39c50db..5e48dff 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandGivePublic.java @@ -13,8 +13,8 @@ import java.util.List; public class CommandGivePublic extends CommandGive implements TabExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - return giveBook(sender, args, true, "public"); + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] arguments) { + return giveBook(sender, arguments, true, "public"); } @Override diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java index cb01a2b..1827025 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoad.java @@ -22,20 +22,21 @@ import java.util.List; public class CommandLoad implements TabExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - return loadBook(sender, args, "player", false); + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] arguments) { + return loadBook(sender, arguments, "player", false); } /** * Loads a stored book * * @param sender

The sender asking to load the book

- * @param args

The arguments given

+ * @param arguments

The arguments given

* @param directory

The directory to load from (public/player)

* @param loadPublic

Whether to list public files as loadable

* @return

True if the book was loaded successfully

*/ - public boolean loadBook(CommandSender sender, String[] args, String directory, boolean loadPublic) { + public boolean loadBook(@NotNull CommandSender sender, @NotNull String[] arguments, @NotNull String directory, + boolean loadPublic) { if (!(sender instanceof Player player)) { BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!"); return false; @@ -46,33 +47,25 @@ public class CommandLoad implements TabExecutor { return false; } - int argumentCount = args.length; + int argumentCount = arguments.length; - //Show books available to the player String command = loadPublic ? "loadpublicbook" : "loadbook"; - if (argumentCount == 0) { - PagedBookIndex.printBooks(sender, loadPublic, command, 1); + if (PagedBookIndex.displayPage(arguments, sender, loadPublic, command)) { return true; - } else if (argumentCount == 1) { - int page = InputCleaningHelper.parsePageNumber(args[0]); - if (page > 0) { - PagedBookIndex.printBooks(sender, loadPublic, command, page); - return true; - } } //Organize and parse input - String bookIdentifier = args[0]; + String bookIdentifier = arguments[0]; String copies = "1"; String isSigned = "true"; if (argumentCount == 3) { - copies = args[1]; - isSigned = args[2]; + copies = arguments[1]; + isSigned = arguments[2]; } else if (argumentCount == 2) { - if (args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("false")) { - isSigned = args[1]; + if (arguments[1].equalsIgnoreCase("true") || arguments[1].equalsIgnoreCase("false")) { + isSigned = arguments[1]; } else { - copies = args[1]; + copies = arguments[1]; } } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java index 2a756fe..e74e64d 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/command/CommandLoadPublic.java @@ -13,8 +13,8 @@ import java.util.List; public class CommandLoadPublic extends CommandLoad implements CommandExecutor { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - return loadBook(sender, args, "public", true); + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] arguments) { + return loadBook(sender, arguments, "public", true); } @Override diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java new file mode 100644 index 0000000..057a778 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/AuthorBookIndex.java @@ -0,0 +1,86 @@ +package net.knarcraft.bookswithoutborders.gui; + +import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.utility.BookFormatter; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.hover.content.Text; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class AuthorBookIndex extends BookIndex { + + private final static int booksPerPage = 10; + + /** + * Prints the available books + * + * @param sender

The sender to display the books to

+ * @param listPublic

Whether to display public books

+ * @param command

The base command causing this to be called

+ * @param page

The page of the book list to display

+ */ + public static void printBooks(@NotNull CommandSender sender, boolean listPublic, @NotNull String command, int page, + @NotNull String authorName) { + List availableBooks = BooksWithoutBorders.getAvailableBooks(sender, listPublic); + availableBooks.removeIf((bookPath) -> !BookFormatter.stripColor(bookPath.substring(0, bookPath.length() - 4).split(",")[1]).equalsIgnoreCase(authorName)); + + int totalPages = (int) Math.ceil((double) availableBooks.size() / booksPerPage); + if (page > totalPages) { + sender.sendMessage(ChatColor.GRAY + "No such page"); + } else { + showAuthorBooks(sender, command, page, totalPages, availableBooks, authorName); + } + } + + /** + * Shows a menu listing available books from an author + * + * @param sender

The sender wanting to see the book menu

+ * @param command

The main command used to trigger display of the book menu

+ * @param page

The currently selected page

+ * @param totalPages

The total amount of pages

+ * @param availableBooks

All books available to the sender

+ * @param authorName

The name of the author currently shown

+ */ + private static void showAuthorBooks(@NotNull CommandSender sender, @NotNull String command, int page, + int totalPages, @NotNull List availableBooks, @NotNull String authorName) { + ComponentBuilder componentBuilder = new ComponentBuilder(); + + // Display the list of books, with the next and previous buttons + displayPreviousButton(componentBuilder, command + " author" + authorName, page); + displayBookList(componentBuilder, command, page, availableBooks); + displayNextButton(componentBuilder, command + " author" + authorName, page, totalPages); + + // Display total pages and the manual change page command suggestion + componentBuilder.append(" ", ComponentBuilder.FormatRetention.NONE); + displayTotalPages(componentBuilder, page, totalPages); + componentBuilder.append(" ", ComponentBuilder.FormatRetention.NONE); + sender.spigot().sendMessage(componentBuilder.create()); + } + + /** + * Displays the list of books on the current page + * + * @param componentBuilder

The component builder to append to

+ * @param command

The command used for switching pages

+ * @param page

The current page

+ * @param availableBooks

All available books

+ */ + protected static void displayBookList(@NotNull ComponentBuilder componentBuilder, @NotNull String command, int page, + @NotNull List availableBooks) { + int startIndex = (page - 1) * booksPerPage; + for (int bookIndex = startIndex; bookIndex < Math.min(startIndex + booksPerPage, availableBooks.size()); bookIndex++) { + componentBuilder.append(getNiceName(availableBooks.get(bookIndex))).color(ChatColor.WHITE).event( + new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " " + + availableBooks.get(bookIndex))).event( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Select book by path"))); + componentBuilder.append("\n"); + } + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/BookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/BookIndex.java new file mode 100644 index 0000000..bd8ddf9 --- /dev/null +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/BookIndex.java @@ -0,0 +1,153 @@ +package net.knarcraft.bookswithoutborders.gui; + +import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.hover.content.Text; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public abstract class BookIndex { + + protected final static int booksPerPage = 10; + + /** + * Displays the correct GUI, if specified in the given arguments + * + * @param arguments

The arguments given by a command sender

+ * @param sender

The sender executing the command

+ * @param selectPublic

Whether to display public books, or only those available to the command sender

+ * @param command

The command used for changing pages and making the final selection

+ * @return

True if the GUI was displayed

+ */ + public static boolean displayPage(@NotNull String[] arguments, @NotNull CommandSender sender, boolean selectPublic, + @NotNull String command) { + if (arguments.length == 0) { + PagedBookIndex.printBooks(sender, selectPublic, command, 1); + return true; + } else if (arguments.length == 1) { + int page = InputCleaningHelper.parsePageNumber(arguments[0]); + if (page > 0) { + PagedBookIndex.printBooks(sender, selectPublic, command, page); + return true; + } + } else if (arguments.length == 2) { + String author = InputCleaningHelper.parseAuthorSpecifier(arguments[0]); + if (author != null) { + int page = InputCleaningHelper.parsePageNumber(arguments[1]); + if (page > 0) { + AuthorBookIndex.printBooks(sender, selectPublic, command, page, author); + } + return true; + } + } + return false; + } + + /** + * Displays the suggestion for manually going to any page + * + * @param componentBuilder

The component builder to append to

+ * @param command

The command used for switching pages

+ * @param page

The current page

+ */ + protected static void displayPageCommand(@NotNull ComponentBuilder componentBuilder, @NotNull String command, int page) { + componentBuilder.append("[Page Command]", ComponentBuilder.FormatRetention.NONE).event(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, new Text("/" + command + " page" + page))).event( + new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " page" + page)); + } + + /** + * Displays the current page and total amount of pages + * + * @param componentBuilder

The component builder to append to

+ * @param page

The current page

+ * @param totalPages

The total amount of pages

+ */ + protected static void displayTotalPages(@NotNull ComponentBuilder componentBuilder, int page, int totalPages) { + componentBuilder.append("Page " + page + " of " + totalPages, + ComponentBuilder.FormatRetention.NONE).color(ChatColor.GREEN); + } + + /** + * Displays the alphabet-based page index + * + * @param componentBuilder

The component builder to append to

+ * @param command

The command used for switching pages

+ * @param firstInstances

The map of where the first index of a letter is found

+ */ + protected static void displayAlphabetIndex(@NotNull ComponentBuilder componentBuilder, + @NotNull String command, @NotNull Map firstInstances) { + for (int characterIndex = 0; characterIndex <= 25; characterIndex++) { + char character = (char) ('a' + characterIndex); + if (firstInstances.containsKey(character)) { + int pageIndex = (firstInstances.get(character) / booksPerPage) + 1; + componentBuilder.append(character + "").color( + ChatColor.AQUA).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, + "/" + command + " page" + pageIndex)).event(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, new Text("To page " + pageIndex))); + } else { + componentBuilder.append(character + "", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); + } + } + componentBuilder.append("\n"); + } + + /** + * Displays the previous page button + * + * @param componentBuilder

The component builder to append to

+ * @param command

The command used for switching pages

+ * @param page

The current page

+ */ + protected static void displayPreviousButton(@NotNull ComponentBuilder componentBuilder, + @NotNull String command, int page) { + if (page > 1) { + String fullCommand = "/" + command + " page" + (page - 1); + HoverEvent prevPagePreview = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("To page " + (page - 1))); + ClickEvent prevPageClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand); + componentBuilder.append("Previous [<]", ComponentBuilder.FormatRetention.NONE).event(prevPagePreview).event(prevPageClick); + } else { + componentBuilder.append("Previous [<]", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); + } + componentBuilder.append("\n"); + } + + /** + * Displays the next page button + * + * @param componentBuilder

The component builder to append to

+ * @param command

The command used for switching pages

+ * @param page

The current page

+ * @param totalPages

The total amount of pages

+ */ + protected static void displayNextButton(@NotNull ComponentBuilder componentBuilder, + @NotNull String command, int page, int totalPages) { + if (page < totalPages) { + String fullCommand = "/" + command + " page" + (page + 1); + HoverEvent nextPagePreview = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("To page " + (page + 1))); + ClickEvent nextPageClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand); + componentBuilder.append("Next [>]", ComponentBuilder.FormatRetention.NONE).event(nextPagePreview).event(nextPageClick); + } else { + componentBuilder.append("Next [>]", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); + } + } + + /** + * Gets a nice name from a book's path + * + * @param bookPath

The path of a book

+ * @return

The prettified book name

+ */ + @NotNull + protected static String getNiceName(@NotNull String bookPath) { + bookPath = ChatColor.translateAlternateColorCodes('&', bookPath.substring(0, bookPath.length() - 4)); + String[] parts = bookPath.split(","); + return parts[0].replace("_", " ") + ChatColor.RESET + " by " + parts[1] + ChatColor.RESET; + } + +} diff --git a/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java b/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java index 65fef32..9bb45e7 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/gui/PagedBookIndex.java @@ -1,6 +1,7 @@ package net.knarcraft.bookswithoutborders.gui; import net.knarcraft.bookswithoutborders.BooksWithoutBorders; +import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -17,9 +18,7 @@ import java.util.Map; /** * A class for displaying a paged index of all available books */ -public class PagedBookIndex { - - private final static int booksPerPage = 10; +public class PagedBookIndex extends BookIndex { /** * Prints the available books @@ -45,7 +44,7 @@ public class PagedBookIndex { if (page > totalPages) { sender.sendMessage(ChatColor.GRAY + "No such page"); } else { - PagedBookIndex.showBookMenu(sender, command, page, totalPages, availableBooks, firstInstances); + showBookMenu(sender, command, page, totalPages, availableBooks, firstInstances); } } @@ -80,31 +79,6 @@ public class PagedBookIndex { sender.spigot().sendMessage(componentBuilder.create()); } - /** - * Displays the suggestion for manually going to any page - * - * @param componentBuilder

The component builder to append to

- * @param command

The command used for switching pages

- * @param page

The current page

- */ - private static void displayPageCommand(@NotNull ComponentBuilder componentBuilder, @NotNull String command, int page) { - componentBuilder.append("[Page Command]", ComponentBuilder.FormatRetention.NONE).event(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, new Text("/" + command + " page" + page))).event( - new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " page" + page)); - } - - /** - * Displays the current page and total amount of pages - * - * @param componentBuilder

The component builder to append to

- * @param page

The current page

- * @param totalPages

The total amount of pages

- */ - private static void displayTotalPages(@NotNull ComponentBuilder componentBuilder, int page, int totalPages) { - componentBuilder.append("Page " + page + " of " + totalPages, - ComponentBuilder.FormatRetention.NONE).color(ChatColor.GREEN); - } - /** * Displays the list of books on the current page * @@ -113,8 +87,8 @@ public class PagedBookIndex { * @param page

The current page

* @param availableBooks

All available books

*/ - private static void displayBookList(@NotNull ComponentBuilder componentBuilder, @NotNull String command, int page, - @NotNull List availableBooks) { + protected static void displayBookList(@NotNull ComponentBuilder componentBuilder, @NotNull String command, int page, + @NotNull List availableBooks) { int startIndex = (page - 1) * booksPerPage; for (int bookIndex = startIndex; bookIndex < Math.min(startIndex + booksPerPage, availableBooks.size()); bookIndex++) { componentBuilder.append("[" + (bookIndex + 1) + "]").color(ChatColor.GOLD).event( @@ -124,89 +98,18 @@ public class PagedBookIndex { componentBuilder.append(" ", ComponentBuilder.FormatRetention.NONE); - componentBuilder.append(getNiceName(availableBooks.get(bookIndex))).color(ChatColor.WHITE).event( + String[] parts = getNiceName(availableBooks.get(bookIndex)).split(" by "); + componentBuilder.append(parts[0]).color(ChatColor.WHITE).event( new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/" + command + " " + availableBooks.get(bookIndex))).event( new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Select book by path"))); + componentBuilder.append(" by ", ComponentBuilder.FormatRetention.NONE).color(ChatColor.WHITE); + componentBuilder.append(parts[1]).color(ChatColor.WHITE).event( + new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + command + " author" + + BookFormatter.stripColor(parts[1]) + " page1")).event( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Filter by author"))); componentBuilder.append("\n"); } } - /** - * Displays the alphabet-based page index - * - * @param componentBuilder

The component builder to append to

- * @param command

The command used for switching pages

- * @param firstInstances

The map of where the first index of a letter is found

- */ - private static void displayAlphabetIndex(@NotNull ComponentBuilder componentBuilder, - @NotNull String command, @NotNull Map firstInstances) { - for (int characterIndex = 0; characterIndex <= 25; characterIndex++) { - char character = (char) ('a' + characterIndex); - if (firstInstances.containsKey(character)) { - int pageIndex = (firstInstances.get(character) / booksPerPage) + 1; - componentBuilder.append(character + "").color( - ChatColor.AQUA).event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, - "/" + command + " page" + pageIndex)).event(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, new Text("To page " + pageIndex))); - } else { - componentBuilder.append(character + "", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); - } - } - componentBuilder.append("\n"); - } - - /** - * Displays the previous page button - * - * @param componentBuilder

The component builder to append to

- * @param command

The command used for switching pages

- * @param page

The current page

- */ - private static void displayPreviousButton(@NotNull ComponentBuilder componentBuilder, - @NotNull String command, int page) { - if (page > 1) { - String fullCommand = "/" + command + " page" + (page - 1); - HoverEvent prevPagePreview = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("To page " + (page - 1))); - ClickEvent prevPageClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand); - componentBuilder.append("Previous [<]", ComponentBuilder.FormatRetention.NONE).event(prevPagePreview).event(prevPageClick); - } else { - componentBuilder.append("Previous [<]", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); - } - componentBuilder.append("\n"); - } - - /** - * Displays the next page button - * - * @param componentBuilder

The component builder to append to

- * @param command

The command used for switching pages

- * @param page

The current page

- * @param totalPages

The total amount of pages

- */ - private static void displayNextButton(@NotNull ComponentBuilder componentBuilder, - @NotNull String command, int page, int totalPages) { - if (page < totalPages) { - String fullCommand = "/" + command + " page" + (page + 1); - HoverEvent nextPagePreview = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("To page " + (page + 1))); - ClickEvent nextPageClick = new ClickEvent(ClickEvent.Action.RUN_COMMAND, fullCommand); - componentBuilder.append("Next [>]", ComponentBuilder.FormatRetention.NONE).event(nextPagePreview).event(nextPageClick); - } else { - componentBuilder.append("Next [>]", ComponentBuilder.FormatRetention.NONE).color(ChatColor.GRAY); - } - } - - /** - * Gets a nice name from a book's path - * - * @param bookPath

The path of a book

- * @return

The prettified book name

- */ - @NotNull - private static String getNiceName(@NotNull String bookPath) { - bookPath = ChatColor.translateAlternateColorCodes('&', bookPath.substring(0, bookPath.length() - 4)); - String[] parts = bookPath.split(","); - return parts[0].replace("_", " ") + ChatColor.RESET + " by " + parts[1] + ChatColor.RESET; - } - } diff --git a/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java b/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java index ae4ae9a..d1f7fd2 100644 --- a/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java +++ b/src/main/java/net/knarcraft/bookswithoutborders/utility/InputCleaningHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.bookswithoutborders.utility; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -82,4 +83,21 @@ public final class InputCleaningHelper { } } + /** + * Parses an author specifier given in a command + * + * @param input

The input to parse

+ * @return

The author name, or null if not an author specifier

+ */ + @Nullable + public static String parseAuthorSpecifier(@NotNull String input) { + Pattern pattern = Pattern.compile("author([0-9a-zA-Z_]+)"); + Matcher matcher = pattern.matcher(input); + if (matcher.matches()) { + return matcher.group(1); + } else { + return null; + } + } + }