diff --git a/src/main/java/envoy/client/data/PersistentLocalDB.java b/src/main/java/envoy/client/data/PersistentLocalDB.java index 66bf167..9548516 100644 --- a/src/main/java/envoy/client/data/PersistentLocalDB.java +++ b/src/main/java/envoy/client/data/PersistentLocalDB.java @@ -49,7 +49,7 @@ public class PersistentLocalDB extends LocalDB { // Initialize local database directory if (localDBDir.exists() && !localDBDir.isDirectory()) - throw new IOException(String.format("LocalDbDir '%s' is not a directory!", localDBDir.getAbsolutePath())); + throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); usersFile = new File(localDBDir, "users.db"); idGeneratorFile = new File(localDBDir, "id_generator.db"); } diff --git a/src/main/java/envoy/client/net/Client.java b/src/main/java/envoy/client/net/Client.java index ce9b3a6..e36f9ee 100644 --- a/src/main/java/envoy/client/net/Client.java +++ b/src/main/java/envoy/client/net/Client.java @@ -74,7 +74,7 @@ public class Client implements Closeable { socket = new Socket(config.getServer(), config.getPort()); logger.fine("Successfully established TCP connection to server"); - // Create message receiver + // Create object receiver receiver = new Receiver(socket.getInputStream()); // Register user creation processor, contact list processor and message cache @@ -108,7 +108,7 @@ public class Client implements Closeable { online = true; - // Remove user creation processor + // Remove all processors as they are only used during the handshake receiver.removeAllProcessors(); logger.info("Handshake completed."); diff --git a/src/main/java/envoy/client/net/Receiver.java b/src/main/java/envoy/client/net/Receiver.java index b3dd763..5926e1e 100644 --- a/src/main/java/envoy/client/net/Receiver.java +++ b/src/main/java/envoy/client/net/Receiver.java @@ -14,6 +14,9 @@ import envoy.util.EnvoyLog; import envoy.util.SerializationUtils; /** + * Receives objects from the server and passes them to processor objects based + * on their class. + *

* Project: envoy-client
* File: Receiver.java
* Created: 30.12.2019
@@ -32,12 +35,19 @@ public class Receiver extends Thread { * Creates an instance of {@link Receiver}. * * @param in the {@link InputStream} to parse objects from + * @since Envoy Client v0.3-alpha */ public Receiver(InputStream in) { super("Receiver"); this.in = in; } + /** + * Starts the receiver loop. When an object is read, it is passed to the + * appropriate processor. + * + * @since Envoy Client v0.3-alpha + */ @Override public void run() { @@ -65,7 +75,7 @@ public class Receiver extends Thread { } } } catch (SocketException e) { - logger.info("Connection probably closed by client. Exiting receiver thread..."); + // Connection probably closed by client. } catch (Exception e) { logger.log(Level.SEVERE, "Error on receiver thread", e); e.printStackTrace(); @@ -78,11 +88,14 @@ public class Receiver extends Thread { * * @param processorClass the object class accepted by the processor * @param processor the object processor + * @since Envoy Client v0.3-alpha */ public void registerProcessor(Class processorClass, Consumer processor) { processors.put(processorClass, processor); } /** * Removes all object processors registered at this {@link Receiver}. + * + * @since Envoy Client v0.3-alpha */ public void removeAllProcessors() { processors.clear(); } } diff --git a/src/main/java/envoy/client/ui/controller/ChatScene.java b/src/main/java/envoy/client/ui/controller/ChatScene.java index 7074774..76c0c3b 100644 --- a/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -96,28 +96,27 @@ public final class ChatScene { message.setStatus(e.get()); // Update UI if in current chat - if (currentChat != null && message.getSenderID() == currentChat.getRecipient().getID()) Platform.runLater(() -> messageList.refresh()); + if (currentChat != null && message.getSenderID() == currentChat.getRecipient().getID()) Platform.runLater(messageList::refresh); }); + // Listen to user status changes eventBus.register(UserStatusChangeEvent.class, e -> Platform.runLater(userList::refresh)); // Listen to contacts changes eventBus.register(ContactOperationEvent.class, e -> { final var contact = e.get(); - Platform.runLater(() -> { - switch (e.getOperationType()) { - case ADD: - localDB.getUsers().put(contact.getName(), contact); - localDB.getChats().add(new Chat(contact)); - userList.getItems().add(contact); - break; - case REMOVE: - localDB.getUsers().remove(contact.getName()); - localDB.getChats().removeIf(c -> c.getRecipient().getID() == contact.getID()); - userList.getItems().removeIf(c -> c.getID() == contact.getID()); - break; - } - }); + switch (e.getOperationType()) { + case ADD: + localDB.getUsers().put(contact.getName(), contact); + localDB.getChats().add(new Chat(contact)); + Platform.runLater(() -> userList.getItems().add(contact)); + break; + case REMOVE: + localDB.getUsers().remove(contact.getName()); + localDB.getChats().removeIf(c -> c.getRecipient().getID() == contact.getID()); + Platform.runLater(() -> userList.getItems().removeIf(c -> c.getID() == contact.getID())); + break; + } }); } diff --git a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java index d6c34b6..f98b016 100644 --- a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java +++ b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java @@ -1,13 +1,12 @@ package envoy.client.ui.controller; -import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; +import javafx.application.Platform; import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.ListView; -import javafx.scene.control.TextField; +import javafx.scene.control.*; +import javafx.scene.control.Alert.AlertType; import envoy.client.event.SendEvent; import envoy.client.ui.SceneContext; @@ -59,7 +58,10 @@ public class ContactSearchScene { @FXML private void initialize() { contactList.setCellFactory(e -> new UserListCell()); - eventBus.register(ContactSearchResult.class, response -> Optional.of(response.get()).ifPresent(list -> contactList.getItems().addAll(list))); + eventBus.register(ContactSearchResult.class, response -> Platform.runLater(() -> { + contactList.getItems().clear(); + contactList.getItems().addAll(response.get()); + })); } /** @@ -104,14 +106,20 @@ public class ContactSearchScene { */ @FXML private void contactListClicked() { - Optional.ofNullable(contactList.getSelectionModel().getSelectedItems()).ifPresent(contacts -> contacts.forEach(contact -> { - final var event = new ContactOperationEvent(contact, ElementOperation.ADD); - // Sends the event to the server - eventBus.dispatch(new SendEvent(event)); - // Updates the UI - eventBus.dispatch(event); - logger.log(Level.INFO, "Added contact " + contact); - })); + final var contact = contactList.getSelectionModel().getSelectedItem(); + if (contact != null) { + final var alert = new Alert(AlertType.CONFIRMATION); + alert.setTitle("Add Contact to Contact List"); + alert.setHeaderText("Add the user " + contact.getName() + " to your contact list?"); + alert.showAndWait().filter(btn -> btn == ButtonType.OK).ifPresent(btn -> { + final var event = new ContactOperationEvent(contact, ElementOperation.ADD); + // Sends the event to the server + eventBus.dispatch(new SendEvent(event)); + // Updates the UI + eventBus.dispatch(event); + logger.log(Level.INFO, "Added contact " + contact); + }); + } } @FXML