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.scene.Cursor; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.TextField; 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: envoy-client
* File: UserSettingsPane.java
* Created: 31.07.2020
* * @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(); final var usernameTextField = new TextField(username); final EventHandler textChanged = e -> { newUsername = usernameTextField.getText(); usernameChanged = newUsername != username; }; usernameTextField.setOnInputMethodTextChanged(textChanged); usernameTextField.setOnKeyTyped(textChanged); hbox.getChildren().add(usernameTextField); vbox.getChildren().add(hbox); } /** * 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 != null && 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; } } }