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/controller/GroupCreationTab.java

250 lines
7.1 KiB
Java

package envoy.client.ui.controller;
import static java.util.function.Predicate.not;
import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import envoy.client.data.*;
import envoy.client.event.BackEvent;
import envoy.client.ui.control.*;
import envoy.client.ui.listcell.ListCellFactory;
import envoy.data.*;
import envoy.event.GroupCreation;
import envoy.event.contact.ContactOperation;
import envoy.util.Bounds;
import dev.kske.eventbus.*;
/**
* Provides a group creation interface. A group name can be entered in the text
* field at the top. Available users (local chat recipients) are displayed
* inside a list and can be selected (multiple selection available).
* <p>
* When the group creation button is pressed, a {@link GroupCreation} is sent to
* the server. This controller enforces a valid group name and a non-empty
* member list (excluding the client user).
*
* @author Maximilian K&auml;fer
* @since Envoy Client v0.1-beta
*/
public class GroupCreationTab implements EventListener {
@FXML
private Button createButton;
@FXML
private Button cancelButton;
@FXML
private TextArea groupNameField;
@FXML
private ListView<User> userList;
@FXML
private Label errorMessageLabel;
@FXML
private Button proceedDuplicateButton;
@FXML
private Button cancelDuplicateButton;
@FXML
private HBox errorProceedBox;
@FXML
private ListView<QuickSelectControl> quickSelectList;
private String name;
private final LocalDB localDB = Context.getInstance().getLocalDB();
private static final EventBus eventBus = EventBus.getInstance();
@FXML
private void initialize() {
userList.setCellFactory(new ListCellFactory<>(ContactControl::new));
createButton.setDisable(true);
eventBus.registerListener(this);
userList.getItems()
.addAll(localDB.getChats()
.stream()
.map(Chat::getRecipient)
.filter(User.class::isInstance)
.filter(not(localDB.getUser()::equals))
.map(User.class::cast)
.collect(Collectors.toList()));
resizeQuickSelectSpace(0);
quickSelectList.addEventFilter(MouseEvent.MOUSE_PRESSED, evt -> evt.consume());
}
/**
* Enables the {@code createButton} if at least one contact is selected.
*
* @since Envoy Client v0.1-beta
*/
@FXML
private void userListClicked() {
if (userList.getSelectionModel().getSelectedItem() != null) {
quickSelectList.getItems().add(new QuickSelectControl(userList.getSelectionModel().getSelectedItem(), this::removeFromQuickSelection));
createButton.setDisable(quickSelectList.getItems().isEmpty() || groupNameField.getText().isBlank());
resizeQuickSelectSpace(60);
userList.getItems().remove(userList.getSelectionModel().getSelectedItem());
userList.getSelectionModel().clearSelection();
}
}
/**
* Checks, whether the {@code createButton} can be enabled because text is
* present in the text field.
*
* @since Envoy Client v0.1-beta
*/
@FXML
private void textUpdated() { createButton.setDisable(quickSelectList.getItems().isEmpty() || groupNameField.getText().isBlank()); }
/**
* Sends a {@link GroupCreation} to the server and closes this scene.
* <p>
* If the given group name is not valid, an error is displayed instead.
*
* @since Envoy Client v0.1-beta
*/
@FXML
private void createButtonClicked() {
name = groupNameField.getText();
if (!Bounds.isValidContactName(name)) {
setErrorMessageLabelSize(30);
errorMessageLabel.setText("The group name is not valid!");
groupNameField.clear();
} else if (groupNameAlreadyPresent(name)) {
setErrorMessageLabelSize(30);
errorMessageLabel.setText("Name does already exist! Proceed anyways?");
setProcessPaneSize(30);
createButton.setDisable(true);
cancelButton.setDisable(true);
} else {
createGroup(name);
eventBus.dispatch(new BackEvent());
// Restoring the original design as tabs will always be reused
setErrorMessageLabelSize(0);
groupNameField.clear();
quickSelectList.getItems().forEach(q -> userList.getItems().add(q.getUser()));
quickSelectList.getItems().clear();
resizeQuickSelectSpace(0);
}
}
/**
* Creates a new group with the given name and all selected members.<br>
* Additionally pops the scene automatically.
*
* @param name the chosen group name
* @since Envoy Client v0.1-beta
*/
private void createGroup(String name) {
Context.getInstance()
.getClient()
.send(new GroupCreation(name, quickSelectList.getItems().stream().map(q -> q.getUser().getID()).collect(Collectors.toSet())));
}
/**
* Returns true if the proposed group name is already present in the users
* {@code LocalDB}.
*
* @param newName the chosen group name
* @return true if this name is already present
* @since Envoy Client v0.1-beta
*/
public boolean groupNameAlreadyPresent(String newName) {
return localDB.getChats().stream().map(Chat::getRecipient).filter(Group.class::isInstance).map(Contact::getName).anyMatch(newName::equals);
}
/**
* Removes an element from the quickSelectList.
*
* @param element the element to be removed.
* @since Envoy Client v0.3-beta
*/
public void removeFromQuickSelection(QuickSelectControl element) {
quickSelectList.getItems().remove(element);
userList.getItems().add(element.getUser());
if (quickSelectList.getItems().isEmpty()) {
resizeQuickSelectSpace(0);
createButton.setDisable(true);
}
}
private void resizeQuickSelectSpace(int value) {
quickSelectList.setPrefHeight(value);
quickSelectList.setMaxHeight(value);
quickSelectList.setMinHeight(value);
}
@FXML
private void backButtonClicked() {
eventBus.dispatch(new BackEvent());
setErrorMessageLabelSize(0);
setProcessPaneSize(0);
}
@FXML
private void proceedOnNameDuplication() {
createButton.setDisable(false);
cancelButton.setDisable(false);
createGroup(name);
eventBus.dispatch(new BackEvent());
setErrorMessageLabelSize(0);
setProcessPaneSize(0);
groupNameField.clear();
}
@FXML
private void cancelOnNameDuplication() {
createButton.setDisable(false);
cancelButton.setDisable(false);
setErrorMessageLabelSize(0);
setProcessPaneSize(0);
groupNameField.clear();
}
private void setErrorMessageLabelSize(int value) {
errorMessageLabel.setPrefHeight(value);
errorMessageLabel.setMinHeight(value);
errorMessageLabel.setMaxHeight(value);
}
private void setProcessPaneSize(int value) {
proceedDuplicateButton.setPrefHeight(value);
proceedDuplicateButton.setMinHeight(value);
proceedDuplicateButton.setMaxHeight(value);
cancelDuplicateButton.setPrefHeight(value);
cancelDuplicateButton.setMinHeight(value);
cancelDuplicateButton.setMaxHeight(value);
errorProceedBox.setPrefHeight(value);
errorProceedBox.setMinHeight(value);
errorProceedBox.setMaxHeight(value);
}
@Event
private void onContactOperation(ContactOperation operation) {
if (operation.get() instanceof User) Platform.runLater(() -> {
switch (operation.getOperationType()) {
case ADD:
userList.getItems().add((User) operation.get());
break;
case REMOVE:
userList.getItems().removeIf(operation.get()::equals);
break;
}
});
}
}