Add option to quit from conversation by writing "cancel" in chat.

Move sanitizeInput to a GuiUtil class.
This commit is contained in:
BONNe 2020-04-22 01:12:46 +03:00
parent 3fd0aa7219
commit 5a0d63a272
7 changed files with 200 additions and 135 deletions

View File

@ -1082,6 +1082,10 @@ public abstract class CommonGUI
} }
}). }).
withLocalEcho(false). withLocalEcho(false).
// On cancel conversation will be closed.
withEscapeSequence("cancel").
// Use null value in consumer to detect if user has abandoned conversation.
addConversationAbandonedListener(abandonedEvent -> consumer.accept(null)).
withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")). withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")).
buildConversation(user.getPlayer()); buildConversation(user.getPlayer());

View File

@ -7,11 +7,7 @@ import java.util.function.Function;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.conversations.Conversation; import org.bukkit.conversations.*;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.ValidatingPrompt;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
@ -252,20 +248,27 @@ public class AdminGUI extends CommonGUI
icon = new ItemStack(Material.BOOK); icon = new ItemStack(Material.BOOK);
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getNewUniqueID(challenge -> { this.getNewUniqueID(challenge ->
String uniqueId = Utils.getGameMode(this.world) + "_" + challenge; {
if (challenge == null)
{
// Build Admin Gui if input is null.
this.build();
}
else
{
String uniqueId = Utils.getGameMode(this.world) + "_" + challenge;
ChallengeTypeGUI.open(user, ChallengeTypeGUI.open(user,
this.addon.getChallengesSettings().getLoreLineLength(), this.addon.getChallengesSettings().getLoreLineLength(),
(type, requirements) -> { (type, requirements) -> new EditChallengeGUI(this.addon,
new EditChallengeGUI(this.addon, this.world,
this.world, this.user,
this.user, this.addon.getChallengesManager().createChallenge(uniqueId, type, requirements),
this.addon.getChallengesManager().createChallenge(uniqueId, type, requirements), this.topLabel,
this.topLabel, this.permissionPrefix,
this.permissionPrefix, this).build());
this).build(); }
});
}, },
input -> { input -> {
String uniqueId = Utils.getGameMode(this.world) + "_" + input; String uniqueId = Utils.getGameMode(this.world) + "_" + input;
@ -287,16 +290,25 @@ public class AdminGUI extends CommonGUI
icon = new ItemStack(Material.BOOK); icon = new ItemStack(Material.BOOK);
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getNewUniqueID(level -> { this.getNewUniqueID(level ->
String newName = Utils.getGameMode(this.world) + "_" + level; {
if (level == null)
{
// Build Admin Gui if input is null.
this.build();
}
else
{
String newName = Utils.getGameMode(this.world) + "_" + level;
new EditLevelGUI(this.addon, new EditLevelGUI(this.addon,
this.world, this.world,
this.user, this.user,
this.addon.getChallengesManager().createLevel(newName, this.world), this.addon.getChallengesManager().createLevel(newName, this.world),
this.topLabel, this.topLabel,
this.permissionPrefix, this.permissionPrefix,
this).build(); this).build();
}
}, },
input -> { input -> {
String newName = Utils.getGameMode(this.world) + "_" + input; String newName = Utils.getGameMode(this.world) + "_" + input;
@ -660,7 +672,7 @@ public class AdminGUI extends CommonGUI
@Override @Override
protected boolean isInputValid(ConversationContext context, String input) protected boolean isInputValid(ConversationContext context, String input)
{ {
return stringValidation.apply(sanitizeInput(input)); return stringValidation.apply(GuiUtils.sanitizeInput(input));
} }
@ -680,7 +692,7 @@ public class AdminGUI extends CommonGUI
protected String getFailedValidationText(ConversationContext context, protected String getFailedValidationText(ConversationContext context,
String invalidInput) String invalidInput)
{ {
return user.getTranslation("challenges.errors.unique-id", "[id]", sanitizeInput(invalidInput)); return user.getTranslation("challenges.errors.unique-id", "[id]", GuiUtils.sanitizeInput(invalidInput));
} }
@ -700,25 +712,19 @@ public class AdminGUI extends CommonGUI
protected Prompt acceptValidatedInput(ConversationContext context, String input) protected Prompt acceptValidatedInput(ConversationContext context, String input)
{ {
// Add answer to consumer. // Add answer to consumer.
consumer.accept(sanitizeInput(input)); consumer.accept(GuiUtils.sanitizeInput(input));
// End conversation // End conversation
return Prompt.END_OF_CONVERSATION; return Prompt.END_OF_CONVERSATION;
} }
}). }).
// On cancel conversation will be closed.
withEscapeSequence("cancel").
// Use null value in consumer to detect if user has abandoned conversation.
addConversationAbandonedListener(abandonedEvent -> consumer.accept(null)).
withLocalEcho(false). withLocalEcho(false).
withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")). withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")).
buildConversation(user.getPlayer()); buildConversation(user.getPlayer());
conversation.begin(); conversation.begin();
} }
/**
* Sanitizes the provided input.
* It replaces spaces and hyphens with underscores and lowercases the input.
* @param input input to sanitize
* @return sanitized input
*/
private String sanitizeInput(String input) {
return input.toLowerCase(Locale.ENGLISH).replace(" ", "_").replace("-", "_");
}
} }

View File

@ -500,7 +500,11 @@ public class EditChallengeGUI extends CommonGUI
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getFriendlyName(reply -> { this.getFriendlyName(reply -> {
this.challenge.setFriendlyName(reply); if (reply != null)
{
this.challenge.setFriendlyName(reply);
}
this.build(); this.build();
}, },
this.user.getTranslation("challenges.gui.questions.admin.challenge-name"), this.user.getTranslation("challenges.gui.questions.admin.challenge-name"),

View File

@ -338,9 +338,13 @@ public class EditLevelGUI extends CommonGUI
icon = new ItemStack(Material.DROPPER); icon = new ItemStack(Material.DROPPER);
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getFriendlyName(reply -> { this.getFriendlyName(reply ->
this.challengeLevel.setFriendlyName(reply); {
this.build(); if (reply != null)
{
this.challengeLevel.setFriendlyName(reply);
}
this.build();
}, },
this.user.getTranslation("challenges.gui.questions.admin.level-name"), this.user.getTranslation("challenges.gui.questions.admin.level-name"),
this.challengeLevel.getFriendlyName() this.challengeLevel.getFriendlyName()

View File

@ -148,7 +148,12 @@ public class NumberGUI
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getNumberInput(number -> { this.getNumberInput(number -> {
this.value = number.intValue(); if (number != null)
{
// Null value is passed if user write cancel.
this.value = number.intValue();
}
this.build(); this.build();
}, },
this.user.getTranslation("challenges.gui.questions.admin.number")); this.user.getTranslation("challenges.gui.questions.admin.number"));
@ -370,99 +375,114 @@ public class NumberGUI
final User user = this.user; final User user = this.user;
Conversation conversation = Conversation conversation =
new ConversationFactory(BentoBox.getInstance()).withFirstPrompt( new ConversationFactory(BentoBox.getInstance()).withFirstPrompt(
new NumericPrompt() new NumericPrompt()
{ {
/** /**
* Override this method to perform some action * Override this method to perform some action with
* with the user's integer response. * the user's integer response.
* *
* @param context Context information about the * @param context Context information about the
* conversation. * conversation.
* @param input The user's response as a {@link * @param input The user's response as a {@link
* Number}. * Number}.
* @return The next {@link Prompt} in the prompt * @return The next {@link Prompt} in the prompt
* graph. * graph.
*/ */
@Override @Override
protected Prompt acceptValidatedInput(ConversationContext context, Number input) protected Prompt acceptValidatedInput(ConversationContext context, Number input)
{ {
// Add answer to consumer. // Add answer to consumer.
consumer.accept(input); consumer.accept(input);
// Reopen GUI // Reopen GUI
NumberGUI.this.build(); NumberGUI.this.build();
// End conversation // End conversation
return Prompt.END_OF_CONVERSATION; return Prompt.END_OF_CONVERSATION;
} }
/** /**
* Override this method to do further validation on the numeric player * Override this method to do further validation on
* input after the input has been determined to actually be a number. * the numeric player input after the input has been
* * determined to actually be a number.
* @param context Context information about the conversation. *
* @param input The number the player provided. * @param context Context information about the
* @return The validity of the player's input. * conversation.
*/ * @param input The number the player provided.
@Override * @return The validity of the player's input.
protected boolean isNumberValid(ConversationContext context, Number input) */
{ @Override
return input.intValue() >= NumberGUI.this.minValue && protected boolean isNumberValid(ConversationContext context, Number input)
input.intValue() <= NumberGUI.this.maxValue; {
} return input.intValue() >= NumberGUI.this.minValue &&
input.intValue() <= NumberGUI.this.maxValue;
}
/** /**
* Optionally override this method to display an additional message if the * Optionally override this method to display an
* user enters an invalid number. * additional message if the user enters an invalid
* * number.
* @param context Context information about the conversation. *
* @param invalidInput The invalid input provided by the user. * @param context Context information about the
* @return A message explaining how to correct the input. * conversation.
*/ * @param invalidInput The invalid input provided by
@Override * the user.
protected String getInputNotNumericText(ConversationContext context, * @return A message explaining how to correct the
String invalidInput) * input.
{ */
return NumberGUI.this.user.getTranslation("challenges.errors.not-a-integer", "[value]", invalidInput); @Override
} protected String getInputNotNumericText(ConversationContext context,
String invalidInput)
{
return NumberGUI.this.user
.getTranslation("challenges.errors.not-a-integer", "[value]", invalidInput);
}
/** /**
* Optionally override this method to display an additional message if the * Optionally override this method to display an
* user enters an invalid numeric input. * additional message if the user enters an invalid
* * numeric input.
* @param context Context information about the conversation. *
* @param invalidInput The invalid input provided by the user. * @param context Context information about the
* @return A message explaining how to correct the input. * conversation.
*/ * @param invalidInput The invalid input provided by
@Override * the user.
protected String getFailedValidationText(ConversationContext context, * @return A message explaining how to correct the
Number invalidInput) * input.
{ */
return NumberGUI.this.user.getTranslation("challenges.errors.not-valid-integer", @Override
"[value]", invalidInput.toString(), protected String getFailedValidationText(ConversationContext context,
"[min]", Integer.toString(NumberGUI.this.minValue), Number invalidInput)
"[max]", Integer.toString(NumberGUI.this.maxValue)); {
} return NumberGUI.this.user.getTranslation("challenges.errors.not-valid-integer",
"[value]", invalidInput.toString(),
"[min]", Integer.toString(NumberGUI.this.minValue),
"[max]", Integer.toString(NumberGUI.this.maxValue));
}
/** /**
* @see Prompt#getPromptText(ConversationContext) * @see Prompt#getPromptText(ConversationContext)
*/ */
@Override @Override
public String getPromptText(ConversationContext conversationContext) public String getPromptText(ConversationContext conversationContext)
{ {
// Close input GUI. // Close input GUI.
user.closeInventory(); user.closeInventory();
// There are no editable message. Just return question. // There are no editable message. Just return question.
return question; return question;
} }
}). }).
withLocalEcho(false). withLocalEcho(false).
// On cancel conversation will be closed.
withEscapeSequence("cancel").
// Use null value in consumer to detect if user has abandoned conversation.
addConversationAbandonedListener(abandonedEvent -> consumer.accept(null)).
withPrefix(context -> withPrefix(context ->
NumberGUI.this.user.getTranslation("challenges.gui.questions.prefix")). NumberGUI.this.user.getTranslation("challenges.gui.questions.prefix")).
buildConversation(user.getPlayer()); buildConversation(user.getPlayer());
conversation.begin(); conversation.begin();

View File

@ -156,7 +156,15 @@ public class StringListGUI
icon = new ItemStack(Material.WHITE_STAINED_GLASS_PANE); icon = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
clickHandler = (panel, user, clickType, slot) -> { clickHandler = (panel, user, clickType, slot) -> {
this.getStringInput(value -> this.value.add(value), this.getStringInput(value -> {
if (value != null)
{
this.value.add(value);
}
// Reopen GUI.
this.build();
},
this.user.getTranslation("challenges.gui.descriptions.admin.add-text-line")); this.user.getTranslation("challenges.gui.descriptions.admin.add-text-line"));
return true; return true;
@ -215,7 +223,15 @@ public class StringListGUI
clickHandler((panel, user1, clickType, i) -> { clickHandler((panel, user1, clickType, i) -> {
this.getStringInput( this.getStringInput(
value -> this.value.set(stringIndex, value), value -> {
if (value != null)
{
this.value.set(stringIndex, value);
}
// Reopen GUI
this.build();
},
this.user.getTranslation("challenges.gui.descriptions.admin.edit-text-line"), this.user.getTranslation("challenges.gui.descriptions.admin.edit-text-line"),
element); element);
@ -282,12 +298,14 @@ public class StringListGUI
{ {
// Add answer to consumer. // Add answer to consumer.
consumer.accept(answer); consumer.accept(answer);
// Reopen GUI
StringListGUI.this.build();
// End conversation // End conversation
return Prompt.END_OF_CONVERSATION; return Prompt.END_OF_CONVERSATION;
} }
}). }).
// On cancel conversation will be closed.
withEscapeSequence("cancel").
// Use null value in consumer to detect if user has abandoned conversation.
addConversationAbandonedListener(abandonedEvent -> consumer.accept(null)).
withLocalEcho(false). withLocalEcho(false).
withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")). withPrefix(context -> user.getTranslation("challenges.gui.questions.prefix")).
buildConversation(user.getPlayer()); buildConversation(user.getPlayer());

View File

@ -1,10 +1,7 @@
package world.bentobox.challenges.utils; package world.bentobox.challenges.utils;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.WordUtils; import org.apache.commons.lang.WordUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -424,4 +421,16 @@ public class GuiUtils
stringList.stream().map(string -> GuiUtils.stringSplit(string, warpLength)).forEach(newList::addAll); stringList.stream().map(string -> GuiUtils.stringSplit(string, warpLength)).forEach(newList::addAll);
return newList; return newList;
} }
/**
* Sanitizes the provided input.
* It replaces spaces and hyphens with underscores and lower cases the input.
* @param input input to sanitize
* @return sanitized input
*/
public static String sanitizeInput(String input)
{
return input.toLowerCase(Locale.ENGLISH).replace(" ", "_").replace("-", "_");
}
} }