fancydialogs: Implemented confirmation dialog api

This commit is contained in:
Oliver
2025-06-19 15:31:21 +02:00
parent c496283b79
commit ce561f057b
8 changed files with 155 additions and 55 deletions

View File

@@ -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<String, ConfirmationDialog> 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<Boolean> ask(Player player) {
CompletableFuture<Boolean> 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;
}
}

View File

@@ -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<DialogAction> actions;
private transient String id;
public DialogButton(String label, String tooltip, List<DialogAction> 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;
}

View File

@@ -21,6 +21,10 @@ public class DialogButtonClickedEvent extends Event {
this.buttonId = buttonId;
}
public static HandlerList getHandlerList() {
return handlerList;
}
public Player getPlayer() {
return player;
}

View File

@@ -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() {

View File

@@ -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<DialogData> dialogs = plugin.getDialogStorage().loadAll();
for (DialogData dialogData : dialogs) {

View File

@@ -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);

View File

@@ -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());
}
}
}
}

View File

@@ -16,6 +16,7 @@ messages:
config:
reload:
success: "<dark_gray> <gray>Successfully reloaded the configuration."
cancelled: "<dark_gray> <gray>Reloading the configuration was cancelled."
storage:
save:
success: "<dark_gray> <gray>Successfully saved {warningColor}{count}<gray> dialogs to the storage."