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 org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap;
public class ConfirmationDialog { public class ConfirmationDialog {
private final String title; public static final Map<String, ConfirmationDialog> CACHE = new ConcurrentHashMap<>();
private final String question; private final String question;
private final String confirmText; private String title;
private final String cancelText; 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.title = title;
this.question = question; this.question = question;
this.confirmText = confirmText; this.confirmText = confirmText;
this.cancelText = cancelText; this.cancelText = cancelText;
this.onConfirm = onConfirm;
this.dialogData = new DialogData( this.onCancel = onCancel;
"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()
)
)
);
} }
public ConfirmationDialog(String question) { public ConfirmationDialog(String question) {
this("Confirmation", question, "Confirm", "Cancel"); this.question = question;
} }
public ConfirmationDialog(String title, String question) { public ConfirmationDialog withTitle(String title) {
this(title, question, "Confirm", "Cancel"); this.title = title;
return this;
} }
public static boolean ask(Player player, String question) { public ConfirmationDialog withConfirmText(String confirmText) {
return new ConfirmationDialog(question).ask(player).join(); this.confirmText = confirmText;
return this;
} }
public CompletableFuture<Boolean> ask(Player player) { public ConfirmationDialog withCancelText(String cancelText) {
CompletableFuture<Boolean> future = new CompletableFuture<>(); this.cancelText = cancelText;
FancyDialogs.get() return this;
.createDialog(dialogData)
.open(player);
// TODO wait for user response
future.complete(true);
return future;
} }
public String getTitle() { public ConfirmationDialog withOnConfirm(Runnable onConfirm) {
return title; this.onConfirm = onConfirm;
return this;
} }
public String getQuestion() { public ConfirmationDialog withOnCancel(Runnable onCancel) {
return question; this.onCancel = onCancel;
return this;
} }
public String getConfirmText() { public void ask(Player player) {
return confirmText; buildDialog();
dialog.open(player);
CACHE.put(dialog.getId(), this);
} }
public String getCancelText() { private void buildDialog() {
return cancelText; 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 { public class DialogButton {
private final transient String id;
private final String label; private final String label;
private final String tooltip; private final String tooltip;
private final List<DialogAction> actions; private final List<DialogAction> actions;
private transient String id;
public DialogButton(String label, String tooltip, List<DialogAction> actions) { public DialogButton(String label, String tooltip, List<DialogAction> actions) {
this.id = UUID.randomUUID().toString(); this.id = UUID.randomUUID().toString();
@@ -18,6 +18,9 @@ public class DialogButton {
} }
public String id() { public String id() {
if (id == null || id.isEmpty()) {
id = UUID.randomUUID().toString();
}
return id; return id;
} }

View File

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

View File

@@ -12,6 +12,7 @@ import com.fancyinnovations.fancydialogs.config.FDFeatureFlags;
import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig; import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig;
import com.fancyinnovations.fancydialogs.dialog.DialogImpl; import com.fancyinnovations.fancydialogs.dialog.DialogImpl;
import com.fancyinnovations.fancydialogs.fancynpcs.OpenDialogNpcAction; import com.fancyinnovations.fancydialogs.fancynpcs.OpenDialogNpcAction;
import com.fancyinnovations.fancydialogs.listener.DialogButtonClickedListener;
import com.fancyinnovations.fancydialogs.listener.PlayerJoinListener; import com.fancyinnovations.fancydialogs.listener.PlayerJoinListener;
import com.fancyinnovations.fancydialogs.registry.DefaultDialogs; import com.fancyinnovations.fancydialogs.registry.DefaultDialogs;
import com.fancyinnovations.fancydialogs.registry.DialogRegistry; import com.fancyinnovations.fancydialogs.registry.DialogRegistry;
@@ -163,6 +164,7 @@ public class FancyDialogsPlugin extends JavaPlugin implements FancyDialogs {
private void registerListeners() { private void registerListeners() {
Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this);
Bukkit.getPluginManager().registerEvents(new DialogButtonClickedListener(), this);
} }
private void registerCommands() { private void registerCommands() {

View File

@@ -46,6 +46,18 @@ public final class FancyDialogsCMD {
public void configReload( public void configReload(
final BukkitCommandActor actor 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(); FancyDialogsConfig config = plugin.getFancyDialogsConfig();
config.load(); config.load();
@@ -85,12 +97,17 @@ public final class FancyDialogsCMD {
final BukkitCommandActor actor final BukkitCommandActor actor
) { ) {
if (actor.isPlayer()) { 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.")) { new ConfirmationDialog("Are you sure you want to load all dialog data from the storage? This will overwrite any existing dialogs.")
translator.translate("commands.fancydialogs.storage.load.cancelled").send(actor.sender()); .withTitle("Confirm load")
return; .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(); Collection<DialogData> dialogs = plugin.getDialogStorage().loadAll();
for (DialogData dialogData : dialogs) { for (DialogData dialogData : dialogs) {

View File

@@ -42,6 +42,10 @@ public class CustomClickActionPacketListener {
new DialogButtonClickedEvent(event.player(), dialogId, buttonId).callEvent(); 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); Dialog dialog = FancyDialogsPlugin.get().getDialogRegistry().get(dialogId);
if (dialog == null) { if (dialog == null) {
FancyDialogsPlugin.get().getFancyLogger().warn("Received action for unknown dialog: " + dialogId); 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: config:
reload: reload:
success: "<dark_gray> <gray>Successfully reloaded the configuration." success: "<dark_gray> <gray>Successfully reloaded the configuration."
cancelled: "<dark_gray> <gray>Reloading the configuration was cancelled."
storage: storage:
save: save:
success: "<dark_gray> <gray>Successfully saved {warningColor}{count}<gray> dialogs to the storage." success: "<dark_gray> <gray>Successfully saved {warningColor}{count}<gray> dialogs to the storage."