This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/client/src/main/java/envoy/client/ui/chatscene/ChatSceneCommands.java

145 lines
6.4 KiB
Java
Raw Normal View History

package envoy.client.ui.chatscene;
import java.util.Random;
import java.util.function.*;
import java.util.logging.Level;
import javafx.scene.control.ListView;
import javafx.scene.control.skin.VirtualFlow;
import envoy.client.data.Context;
import envoy.client.data.commands.*;
import envoy.client.helper.ShutdownHelper;
import envoy.client.ui.SceneContext.SceneInfo;
import envoy.client.ui.controller.ChatScene;
import envoy.client.util.MessageUtil;
import envoy.data.Message;
import envoy.util.EnvoyLog;
/**
* Contains all {@link SystemCommand}s used for
* {@link envoy.client.ui.controller.ChatScene}.
*
* @author Leon Hofmeister
* @since Envoy Client v0.3-beta
*/
public final class ChatSceneCommands {
private final ListView<Message> messageList;
private final SystemCommandMap messageTextAreaCommands = new SystemCommandMap();
private final SystemCommandBuilder builder = new SystemCommandBuilder(messageTextAreaCommands);
private static final String messageDependantCommandDescription = " the given message. Use s/S to use the selected message. Otherwise expects a number relative to the uppermost completely visible message.";
/**
*
* @param messageList the message list to use for some commands
* @param chatScene the instance of {@code ChatScene} that uses this object
* @since Envoy Client v0.3-beta
*/
public ChatSceneCommands(ListView<Message> messageList, ChatScene chatScene) {
this.messageList = messageList;
// Do A Barrel roll initialization
final var random = new Random();
builder.setAction(text -> chatScene.doABarrelRoll(Integer.parseInt(text.get(0)), Double.parseDouble(text.get(1))))
.setDefaults(Integer.toString(random.nextInt(3) + 1), Double.toString(random.nextDouble() * 3 + 1))
.setDescription("See for yourself :)")
.setNumberOfArguments(2)
.build("dabr");
// Logout initialization
builder.setAction(text -> ShutdownHelper.logout()).setDescription("Logs you out.").buildNoArg("logout");
// Exit initialization
builder.setAction(text -> ShutdownHelper.exit()).setNumberOfArguments(0).setDescription("Exits the program.").build("exit", false);
builder.build("q");
// Open settings scene initialization
builder.setAction(text -> Context.getInstance().getSceneContext().load(SceneInfo.SETTINGS_SCENE))
.setDescription("Opens the settings screen")
.buildNoArg("settings");
// Selection of a new message initialization
messageDependantAction("s",
m -> { messageList.getSelectionModel().clearSelection(); messageList.getSelectionModel().select(m); },
m -> true,
"Selects");
// Copy text of selection initialization
messageDependantAction("cp", MessageUtil::copyMessageText, m -> !m.getText().isEmpty(), "Copies the text of");
// Delete selection initialization
messageDependantAction("del", MessageUtil::deleteMessage, m -> true, "Deletes");
// Save attachment of selection initialization
messageDependantAction("save-att", MessageUtil::saveAttachment, Message::hasAttachment, "Saves the attachment of");
}
private void messageDependantAction(String command, Consumer<Message> action, Predicate<Message> additionalCheck, String description) {
builder.setAction(text -> {
final var positionalArgument = text.get(0).toLowerCase();
// the currently selected message was requested
if (positionalArgument.startsWith("s")) {
final var relativeString = positionalArgument.length() == 1 ? "" : positionalArgument.substring(1);
// Only s has been used as input
if (positionalArgument.length() == 1) {
final var selectedMessage = messageList.getSelectionModel().getSelectedItem();
if (selectedMessage != null && additionalCheck.test(selectedMessage)) action.accept(selectedMessage);
return;
// Either s++ or s-- has been requested
} else if (relativeString.equals("++") || relativeString.equals("--")) selectionNeighbor(action, additionalCheck, positionalArgument);
// A message relative to the currently selected message should be used (i.e.
// s+4)
else useRelativeMessage(command, action, additionalCheck, relativeString, true);
// Either ++s or --s has been requested
} else if (positionalArgument.equals("--s") || positionalArgument.equals("++s"))
selectionNeighbor(action, additionalCheck, positionalArgument);
// Just a number is expected: ((+)4)
else useRelativeMessage(command, action, additionalCheck, positionalArgument, false);
}).setDefaults("s").setNumberOfArguments(1).setDescription(description.concat(messageDependantCommandDescription)).build(command);
}
private void selectionNeighbor(Consumer<Message> action, Predicate<Message> additionalCheck, final String positionalArgument) {
final var wantedIndex = messageList.getSelectionModel().getSelectedIndex() + (positionalArgument.contains("+") ? 1 : -1);
messageList.getSelectionModel().clearAndSelect(wantedIndex);
final var selectedMessage = messageList.getItems().get(wantedIndex);
if (selectedMessage != null && additionalCheck.test(selectedMessage)) action.accept(selectedMessage);
}
private void useRelativeMessage(String command, Consumer<Message> action, Predicate<Message> additionalCheck, final String positionalArgument,
boolean useSelectedMessage) throws NumberFormatException {
final var stripPlus = positionalArgument.startsWith("+") ? positionalArgument.substring(1) : positionalArgument;
final var incDec = Integer.valueOf(stripPlus);
try {
// The currently selected message is the base message
if (useSelectedMessage) {
final var messageToUse = messageList.getItems().get(messageList.getSelectionModel().getSelectedIndex() + incDec);
if (messageToUse != null && additionalCheck.test(messageToUse)) action.accept(messageToUse);
// The currently upmost completely visible message is the base message
} else {
final var messageToUse = messageList.getItems()
.get(((VirtualFlow<?>) messageList.lookup(".virtual-flow")).getFirstVisibleCell().getIndex() + 1 + incDec);
if (messageToUse != null && additionalCheck.test(messageToUse)) action.accept(messageToUse);
}
} catch (final IndexOutOfBoundsException e) {
EnvoyLog.getLogger(ChatSceneCommands.class)
.log(Level.INFO, " A non-existing message was requested by the user for System command " + command);
}
}
/**
* @return the map used by this {@code ChatSceneCommands}
* @since Envoy Client v0.3-beta
*/
public SystemCommandMap getChatSceneCommands() { return messageTextAreaCommands; }
}