From ce561f057bd20714337d26b6254781599e7d2044 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 19 Jun 2025 15:31:21 +0200 Subject: [PATCH] fancydialogs: Implemented confirmation dialog api --- .../fancydialogs/api/ConfirmationDialog.java | 141 +++++++++++------- .../fancydialogs/api/data/DialogButton.java | 5 +- .../api/events/DialogButtonClickedEvent.java | 4 + .../fancydialogs/FancyDialogsPlugin.java | 2 + .../commands/FancyDialogsCMD.java | 25 +++- .../CustomClickActionPacketListener.java | 4 + .../listener/DialogButtonClickedListener.java | 28 ++++ .../src/main/resources/languages/default.yml | 1 + 8 files changed, 155 insertions(+), 55 deletions(-) create mode 100644 plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java index 1a1e67b7..aa345706 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java @@ -6,83 +6,124 @@ import com.fancyinnovations.fancydialogs.api.data.DialogData; import org.bukkit.entity.Player; import java.util.List; +import java.util.Map; import java.util.UUID; -import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; public class ConfirmationDialog { - private final String title; + public static final Map CACHE = new ConcurrentHashMap<>(); + private final String question; - private final String confirmText; - private final String cancelText; + private String title; + private String confirmText; + private String cancelText; - private final DialogData dialogData; + private Dialog dialog; + private String confirmButtonId; + private String cancelButtonId; + private Runnable onConfirm; + private Runnable onCancel; - public ConfirmationDialog(String title, String question, String confirmText, String cancelText) { + public ConfirmationDialog(String title, String question, String confirmText, String cancelText, Runnable onConfirm, Runnable onCancel) { this.title = title; this.question = question; this.confirmText = confirmText; this.cancelText = cancelText; - - this.dialogData = new DialogData( - "confirmation_dialog_" + UUID.randomUUID(), - this.title, - false, - List.of( - new DialogBodyData(this.question) - ), - List.of( - new DialogButton( - this.confirmText, - this.confirmText, - List.of() - ), - new DialogButton( - this.cancelText, - this.cancelText, - List.of() - ) - ) - ); + this.onConfirm = onConfirm; + this.onCancel = onCancel; } public ConfirmationDialog(String question) { - this("Confirmation", question, "Confirm", "Cancel"); + this.question = question; } - public ConfirmationDialog(String title, String question) { - this(title, question, "Confirm", "Cancel"); + public ConfirmationDialog withTitle(String title) { + this.title = title; + return this; } - public static boolean ask(Player player, String question) { - return new ConfirmationDialog(question).ask(player).join(); + public ConfirmationDialog withConfirmText(String confirmText) { + this.confirmText = confirmText; + return this; } - public CompletableFuture ask(Player player) { - CompletableFuture future = new CompletableFuture<>(); - FancyDialogs.get() - .createDialog(dialogData) - .open(player); - - // TODO wait for user response - - future.complete(true); - return future; + public ConfirmationDialog withCancelText(String cancelText) { + this.cancelText = cancelText; + return this; } - public String getTitle() { - return title; + public ConfirmationDialog withOnConfirm(Runnable onConfirm) { + this.onConfirm = onConfirm; + return this; } - public String getQuestion() { - return question; + public ConfirmationDialog withOnCancel(Runnable onCancel) { + this.onCancel = onCancel; + return this; } - public String getConfirmText() { - return confirmText; + public void ask(Player player) { + buildDialog(); + dialog.open(player); + CACHE.put(dialog.getId(), this); } - public String getCancelText() { - return cancelText; + private void buildDialog() { + if (title == null || title.isEmpty()) { + title = "Confirmation"; + } + + if (confirmText == null || confirmText.isEmpty()) { + confirmText = "Yes"; + } + + if (cancelText == null || cancelText.isEmpty()) { + cancelText = "No"; + } + + DialogButton confirmBtn = new DialogButton( + confirmText, + confirmText, + List.of( + new DialogButton.DialogAction("confirm", "") + ) + ); + this.confirmButtonId = confirmBtn.id(); + + DialogButton cancelBtn = new DialogButton( + cancelText, + cancelText, + List.of( + new DialogButton.DialogAction("cancel", "") + ) + ); + this.cancelButtonId = cancelBtn.id(); + + DialogData dialogData = new DialogData( + "confirmation_dialog_" + UUID.randomUUID(), + title, + false, + List.of(new DialogBodyData(question)), + List.of(confirmBtn, cancelBtn) + ); + + this.dialog = FancyDialogs.get().createDialog(dialogData); + } + + public String getConfirmButtonId() { + return confirmButtonId; + } + + public String getCancelButtonId() { + return cancelButtonId; + } + + public Runnable getOnConfirm() { + return onConfirm; + } + + public Runnable getOnCancel() { + return onCancel; } } diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/data/DialogButton.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/data/DialogButton.java index c957389c..bc02e25d 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/data/DialogButton.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/data/DialogButton.java @@ -5,10 +5,10 @@ import java.util.UUID; public class DialogButton { - private final transient String id; private final String label; private final String tooltip; private final List actions; + private transient String id; public DialogButton(String label, String tooltip, List actions) { this.id = UUID.randomUUID().toString(); @@ -18,6 +18,9 @@ public class DialogButton { } public String id() { + if (id == null || id.isEmpty()) { + id = UUID.randomUUID().toString(); + } return id; } diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java index 6405ee3d..b97d01f9 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java @@ -21,6 +21,10 @@ public class DialogButtonClickedEvent extends Event { this.buttonId = buttonId; } + public static HandlerList getHandlerList() { + return handlerList; + } + public Player getPlayer() { return player; } diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java index 88a4ce98..ee22cf3a 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java @@ -12,6 +12,7 @@ import com.fancyinnovations.fancydialogs.config.FDFeatureFlags; import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig; import com.fancyinnovations.fancydialogs.dialog.DialogImpl; import com.fancyinnovations.fancydialogs.fancynpcs.OpenDialogNpcAction; +import com.fancyinnovations.fancydialogs.listener.DialogButtonClickedListener; import com.fancyinnovations.fancydialogs.listener.PlayerJoinListener; import com.fancyinnovations.fancydialogs.registry.DefaultDialogs; import com.fancyinnovations.fancydialogs.registry.DialogRegistry; @@ -163,6 +164,7 @@ public class FancyDialogsPlugin extends JavaPlugin implements FancyDialogs { private void registerListeners() { Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this); + Bukkit.getPluginManager().registerEvents(new DialogButtonClickedListener(), this); } private void registerCommands() { diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java index a8b36c2b..7244d1e2 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java @@ -46,6 +46,18 @@ public final class FancyDialogsCMD { public void configReload( final BukkitCommandActor actor ) { + if (actor.isPlayer()) { + new ConfirmationDialog("Are you sure you want to reload the configuration? This will reset all changes made to the config file.") + .withTitle("Confirm reload") + .withOnConfirm(() -> reloadConfig(actor)) + .withOnCancel(() -> translator.translate("commands.fancydialogs.config.reload.cancelled").send(actor.sender())) + .ask(actor.asPlayer()); + } else { + reloadConfig(actor); + } + } + + private void reloadConfig(BukkitCommandActor actor) { FancyDialogsConfig config = plugin.getFancyDialogsConfig(); config.load(); @@ -85,12 +97,17 @@ public final class FancyDialogsCMD { final BukkitCommandActor actor ) { if (actor.isPlayer()) { - if (!ConfirmationDialog.ask(actor.asPlayer(), "Are you sure you want to load all dialogs from storage? This will clear the current registry.")) { - translator.translate("commands.fancydialogs.storage.load.cancelled").send(actor.sender()); - return; - } + new ConfirmationDialog("Are you sure you want to load all dialog data from the storage? This will overwrite any existing dialogs.") + .withTitle("Confirm load") + .withOnConfirm(() -> loadStorage(actor)) + .withOnCancel(() -> translator.translate("commands.fancydialogs.storage.load.cancelled").send(actor.sender())) + .ask(actor.asPlayer()); + } else { + loadStorage(actor); } + } + private void loadStorage(BukkitCommandActor actor) { Collection dialogs = plugin.getDialogStorage().loadAll(); for (DialogData dialogData : dialogs) { diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java index dd4c47b9..259fec4f 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java @@ -42,6 +42,10 @@ public class CustomClickActionPacketListener { new DialogButtonClickedEvent(event.player(), dialogId, buttonId).callEvent(); + if (dialogId.startsWith("confirmation_dialog_")) { + return; // Ignore confirmation dialog actions, handled separately + } + Dialog dialog = FancyDialogsPlugin.get().getDialogRegistry().get(dialogId); if (dialog == null) { FancyDialogsPlugin.get().getFancyLogger().warn("Received action for unknown dialog: " + dialogId); diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java new file mode 100644 index 00000000..b1a406aa --- /dev/null +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java @@ -0,0 +1,28 @@ +package com.fancyinnovations.fancydialogs.listener; + +import com.fancyinnovations.fancydialogs.api.ConfirmationDialog; +import com.fancyinnovations.fancydialogs.api.events.DialogButtonClickedEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class DialogButtonClickedListener implements Listener { + + @EventHandler + public void onButtonClicked(DialogButtonClickedEvent event) { + if (event.getDialogId().startsWith("confirmation_dialog_")) { + ConfirmationDialog dialog = ConfirmationDialog.CACHE.get(event.getDialogId()); + if (dialog == null) { + return; + } + + if (event.getButtonId().equals(dialog.getConfirmButtonId())) { + dialog.getOnConfirm().run(); + ConfirmationDialog.CACHE.remove(event.getDialogId()); + } else if (event.getButtonId().equals(dialog.getCancelButtonId())) { + dialog.getOnCancel().run(); + ConfirmationDialog.CACHE.remove(event.getDialogId()); + } + } + } + +} diff --git a/plugins/fancydialogs/src/main/resources/languages/default.yml b/plugins/fancydialogs/src/main/resources/languages/default.yml index 26ba70e4..abaf8980 100644 --- a/plugins/fancydialogs/src/main/resources/languages/default.yml +++ b/plugins/fancydialogs/src/main/resources/languages/default.yml @@ -16,6 +16,7 @@ messages: config: reload: success: "Successfully reloaded the configuration." + cancelled: "Reloading the configuration was cancelled." storage: save: success: "Successfully saved {warningColor}{count} dialogs to the storage."