diff --git a/client/src/main/java/envoy/client/net/Client.java b/client/src/main/java/envoy/client/net/Client.java index b642141..c395045 100644 --- a/client/src/main/java/envoy/client/net/Client.java +++ b/client/src/main/java/envoy/client/net/Client.java @@ -193,7 +193,7 @@ public class Client implements Closeable { * @param evt the event to send * @throws IOException if the event did not reach the server */ - public void sendEvent(Event evt) throws IOException { writeObject(evt); } + public void sendEvent(Event evt) throws IOException { if (online) writeObject(evt); } /** * Requests a new {@link IDGenerator} from the server. diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index a708dd0..9af7c62 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -147,7 +147,7 @@ public final class ChatScene implements Restorable { // The sender of the message is the recipient of the chat // Exceptions: this user is the sender (sync) or group message (group is // recipient) - final long recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID() + final var recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID() : message.getSenderID(); localDB.getChat(recipientID).ifPresent(chat -> { chat.insert(message); @@ -200,7 +200,7 @@ public final class ChatScene implements Restorable { switch (e.getOperationType()) { case ADD: if (contact instanceof User) localDB.getUsers().put(contact.getName(), (User) contact); - final Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); + final var chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); Platform.runLater(() -> chatList.getItems().add(chat)); break; case REMOVE: @@ -264,7 +264,7 @@ public final class ChatScene implements Restorable { private void chatListClicked() { if (chatList.getSelectionModel().isEmpty()) return; - final Contact user = chatList.getSelectionModel().getSelectedItem().getRecipient(); + final var user = chatList.getSelectionModel().getSelectedItem().getRecipient(); if (user != null && (currentChat == null || !user.equals(currentChat.getRecipient()))) { // LEON: JFC <===> JAVA FRIED CHICKEN <=/=> Java Foundation Classes @@ -311,7 +311,7 @@ public final class ChatScene implements Restorable { @FXML private void settingsButtonClicked() { sceneContext.load(SceneContext.SceneInfo.SETTINGS_SCENE); - sceneContext.getController().initializeData(sceneContext); + sceneContext.getController().initializeData(sceneContext, localDB.getUser()); } /** @@ -377,7 +377,7 @@ public final class ChatScene implements Restorable { } // Get attachment type (default is document) - AttachmentType type = AttachmentType.DOCUMENT; + var type = AttachmentType.DOCUMENT; switch (fileChooser.getSelectedExtensionFilter().getDescription()) { case "Pictures": type = AttachmentType.PICTURE; @@ -452,7 +452,7 @@ public final class ChatScene implements Restorable { messageTextUpdated(); // Sending an IsTyping event if none has been sent for // IsTyping#millisecondsActive - if (client.isOnline() && currentChat.getLastWritingEvent() + IsTyping.millisecondsActive <= System.currentTimeMillis()) { + if (currentChat.getLastWritingEvent() + IsTyping.millisecondsActive <= System.currentTimeMillis()) { eventBus.dispatch(new SendEvent(new IsTyping(getChatID(), currentChat.getRecipient().getID()))); currentChat.lastWritingEventWasNow(); } @@ -461,9 +461,9 @@ public final class ChatScene implements Restorable { } /** - * Returns the id that should be used to send things to the server: - * the id of 'our' {@link User} if the recipient of that object is another User, - * else the id of the {@link Group} 'our' user is sending to. + * Returns the id that should be used to send things to the server: the id of + * 'our' {@link User} if the recipient of that object is another User, else the + * id of the {@link Group} 'our' user is sending to. * * @return an id that can be sent to the server * @since Envoy Client v0.2-beta @@ -517,8 +517,8 @@ public final class ChatScene implements Restorable { * @since Envoy Client v0.1-beta */ private void updateRemainingCharsLabel() { - final int currentLength = messageTextArea.getText().length(); - final int remainingLength = MAX_MESSAGE_LENGTH - currentLength; + final var currentLength = messageTextArea.getText().length(); + final var remainingLength = MAX_MESSAGE_LENGTH - currentLength; remainingChars.setText(String.format("remaining chars: %d/%d", remainingLength, MAX_MESSAGE_LENGTH)); remainingChars.setTextFill(Color.rgb(currentLength, remainingLength, 0, 1)); } @@ -607,9 +607,8 @@ public final class ChatScene implements Restorable { /** * Updates the {@code attachmentView} in terms of visibility.
- * Additionally resets the shown image to - * {@code DEFAULT_ATTACHMENT_VIEW_IMAGE} if another image is currently - * present. + * Additionally resets the shown image to {@code DEFAULT_ATTACHMENT_VIEW_IMAGE} + * if another image is currently present. * * @param visible whether the {@code attachmentView} should be displayed * @since Envoy Client v0.1-beta diff --git a/client/src/main/java/envoy/client/ui/controller/SettingsScene.java b/client/src/main/java/envoy/client/ui/controller/SettingsScene.java index f3358a9..7af8659 100644 --- a/client/src/main/java/envoy/client/ui/controller/SettingsScene.java +++ b/client/src/main/java/envoy/client/ui/controller/SettingsScene.java @@ -4,9 +4,8 @@ import javafx.fxml.FXML; import javafx.scene.control.*; import envoy.client.ui.SceneContext; -import envoy.client.ui.settings.DownloadSettingsPane; -import envoy.client.ui.settings.GeneralSettingsPane; -import envoy.client.ui.settings.SettingsPane; +import envoy.client.ui.settings.*; +import envoy.data.User; /** * Project: envoy-client
@@ -28,10 +27,13 @@ public class SettingsScene { /** * @param sceneContext enables the user to return to the chat scene + * @param client the user who uses Envoy * @since Envoy Client v0.1-beta */ - public void initializeData(SceneContext sceneContext) { + public void initializeData(SceneContext sceneContext, User client) { this.sceneContext = sceneContext; + settingsList.getItems().add(new GeneralSettingsPane()); + settingsList.getItems().add(new UserSettingsPane(sceneContext, client)); settingsList.getItems().add(new DownloadSettingsPane(sceneContext)); } @@ -45,8 +47,6 @@ public class SettingsScene { if (!empty && item != null) setGraphic(new Label(item.getTitle())); } }); - - settingsList.getItems().add(new GeneralSettingsPane()); } @FXML diff --git a/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java index bdc1352..90e06f0 100644 --- a/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java @@ -5,7 +5,6 @@ import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; import javafx.stage.DirectoryChooser; import envoy.client.ui.SceneContext; @@ -31,7 +30,7 @@ public class DownloadSettingsPane extends SettingsPane { */ public DownloadSettingsPane(SceneContext sceneContext) { super("Download"); - final var vbox = new VBox(15); + vbox.setSpacing(15); vbox.setPadding(new Insets(15)); // checkbox to disable asking final var checkBox = new CheckBox(settings.getItems().get("autoSaveDownloads").getUserFriendlyName()); @@ -60,6 +59,5 @@ public class DownloadSettingsPane extends SettingsPane { }); hbox.getChildren().add(button); vbox.getChildren().add(hbox); - getChildren().add(vbox); } } diff --git a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java index af46fbb..20189f4 100644 --- a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java @@ -3,7 +3,6 @@ package envoy.client.ui.settings; import java.util.List; import javafx.scene.control.ComboBox; -import javafx.scene.layout.VBox; import envoy.client.data.SettingsItem; import envoy.client.event.ThemeChangeEvent; @@ -25,7 +24,6 @@ public class GeneralSettingsPane extends SettingsPane { */ public GeneralSettingsPane() { super("General"); - final var vbox = new VBox(); // TODO: Support other value types List.of("hideOnClose", "enterToSend") @@ -48,7 +46,5 @@ public class GeneralSettingsPane extends SettingsPane { // TODO add action when value is changed statusComboBox.setOnAction(e -> {}); vbox.getChildren().add(statusComboBox); - - getChildren().add(vbox); } } diff --git a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java index 49f8abd..e7b884d 100644 --- a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java @@ -1,6 +1,7 @@ package envoy.client.ui.settings; import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; import envoy.client.data.Settings; @@ -14,11 +15,15 @@ import envoy.client.data.Settings; */ public abstract class SettingsPane extends Pane { - protected String title; + protected String title; + protected final VBox vbox = new VBox(); protected static final Settings settings = Settings.getInstance(); - protected SettingsPane(String title) { this.title = title; } + protected SettingsPane(String title) { + this.title = title; + getChildren().add(vbox); + } /** * @return the title of this settings pane diff --git a/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java new file mode 100644 index 0000000..becc699 --- /dev/null +++ b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java @@ -0,0 +1,68 @@ +package envoy.client.ui.settings; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; + +import envoy.client.event.SendEvent; +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"); } + + /** + * 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; + } + } +}