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/settings/UserSettingsPane.java

164 lines
5.9 KiB
Java

package envoy.client.ui.settings;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.InputEvent;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import envoy.client.event.SendEvent;
import envoy.client.ui.IconUtil;
import envoy.client.ui.SceneContext;
import envoy.data.User;
import envoy.event.*;
import envoy.util.Bounds;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>UserSettingsPane.java</strong><br>
* Created: <strong>31.07.2020</strong><br>
*
* @author Leon Hofmeister
* @since Envoy Client v0.2-beta
*/
public class UserSettingsPane extends SettingsPane {
private boolean profilePicChanged, usernameChanged, passwordChanged, validPassword;
private byte[] currentImageBytes;
private String newUsername, newPassword = "";
/**
* Creates a new {@code UserSettingsPane}.
*
* @param sceneContext the {@code SceneContext} to block input to Envoy
* @param user the user who wants to customize his profile
* @since Envoy Client v0.2-beta
*/
public UserSettingsPane(SceneContext sceneContext, User user) {
super("User");
// Display of profile pic change mechanism
final var hbox = new HBox();
// TODO: display current profile pic
final var profilePic = new ImageView(IconUtil.loadIcon("envoy_logo", 50));
profilePic.setCursor(Cursor.HAND);
profilePic.setOnMouseClicked(e -> {
final var pictureChooser = new FileChooser();
pictureChooser.setTitle("Select a new picture");
pictureChooser.setInitialDirectory(new File(System.getProperty("user.home")));
pictureChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("Pictures", "*.png", "*.jpg", "*.bmp", "*.gif"));
final var file = pictureChooser.showOpenDialog(sceneContext.getStage());
if (file != null) {
// Check max file size
if (file.length() > 5E6) {
new Alert(AlertType.WARNING, "The selected file exceeds the size limit of 5MB!").showAndWait();
return;
}
try {
currentImageBytes = Files.readAllBytes(file.toPath());
profilePic.setImage(new Image(new ByteArrayInputStream(currentImageBytes)));
profilePicChanged = true;
} catch (final IOException e1) {
e1.printStackTrace();
}
}
});
hbox.getChildren().add(profilePic);
// Displaying the username change mechanism
final var username = user.getName();
newUsername = username;
final var usernameTextField = new TextField(username);
final EventHandler<? super InputEvent> textChanged = e -> {
newUsername = usernameTextField.getText();
usernameChanged = newUsername != username;
};
usernameTextField.setOnInputMethodTextChanged(textChanged);
usernameTextField.setOnKeyTyped(textChanged);
hbox.getChildren().add(usernameTextField);
vbox.getChildren().add(hbox);
// "Displaying" the password change mechanism
final HBox[] passwordHBoxes = { new HBox(), new HBox(), new HBox() };
final Label[] passwordLabels = { new Label("Enter current password:"), new Label("Enter new password:"),
new Label("Repeat new password:") };
final var currentPasswordField = new PasswordField();
final var newPasswordField = new PasswordField();
final var repeatNewPasswordField = new PasswordField();
final PasswordField[] passwordFields = { currentPasswordField, newPasswordField, repeatNewPasswordField };
final EventHandler<? super InputEvent> passwordEntered = e -> {
newPassword = newPasswordField.getText();
validPassword = newPassword.equals(repeatNewPasswordField.getText())
&& !newPasswordField.getText().isBlank();
};
newPasswordField.setOnInputMethodTextChanged(passwordEntered);
newPasswordField.setOnKeyTyped(passwordEntered);
repeatNewPasswordField.setOnInputMethodTextChanged(passwordEntered);
repeatNewPasswordField.setOnKeyTyped(passwordEntered);
for (int i = 0; i < passwordHBoxes.length; i++) {
final var hBox2 = passwordHBoxes[i];
hBox2.getChildren().add(passwordLabels[i]);
hBox2.getChildren().add(passwordFields[i]);
vbox.getChildren().add(hBox2);
}
// Displaying the save button
final var saveButton = new Button("Save");
saveButton.setOnAction(e -> save(user.getID(), currentPasswordField.getText()));
saveButton.setAlignment(Pos.BOTTOM_RIGHT);
vbox.getChildren().add(saveButton);
}
/**
* Saves the given input and sends the changed input to the server
*
* @param username the new username
* @since Envoy Client v0.2-beta
*/
private void save(long userID, String oldPassword) {
final var eventbus = EventBus.getInstance();
// The profile pic was changed
if (profilePicChanged) eventbus.dispatch(new SendEvent(new ProfilePicChange(currentImageBytes, userID)));
// The username was changed
final var validContactName = Bounds.isValidContactName(newUsername);
if (usernameChanged && validContactName) eventbus.dispatch(new SendEvent(new NameChange(userID, newUsername)));
else if (!validContactName) {
final var alert = new Alert(AlertType.ERROR);
alert.setTitle("Invalid username");
alert.setContentText("The entered username does not conform with the naming limitations: " + Bounds.CONTACT_NAME_PATTERN);
alert.showAndWait();
return;
}
// The password was changed
if (passwordChanged && validPassword) eventbus.dispatch(new SendEvent(new PasswordChangeRequest(newPassword, oldPassword, userID)));
else if (!(validPassword || newPassword.isBlank())) {
final var alert = new Alert(AlertType.ERROR);
alert.setTitle("Unequal Password");
alert.setContentText("Repeated password is unequal to the chosen new password");
alert.showAndWait();
return;
}
}
}