diff --git a/src/main/java/envoy/client/ui/ChatSceneController.java b/src/main/java/envoy/client/ui/ChatSceneController.java index 56fbe2c..bcf8a19 100644 --- a/src/main/java/envoy/client/ui/ChatSceneController.java +++ b/src/main/java/envoy/client/ui/ChatSceneController.java @@ -25,6 +25,7 @@ import envoy.data.MessageBuilder; import envoy.event.EventBus; import envoy.event.MessageStatusChangeEvent; import envoy.event.UserStatusChangeEvent; +import envoy.event.contact.ContactOperationEvent; import envoy.util.EnvoyLog; /** @@ -90,9 +91,25 @@ public final class ChatSceneController { // Update UI if in current chat 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())); + 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);// TODO might cause contact duplication + break; + case REMOVE: + // TODO add deletion capability + break; + } + }); + }); } void initializeData(SceneContext sceneContext, LocalDB localDB, Client client, WriteProxy writeProxy) { @@ -118,10 +135,11 @@ public final class ChatSceneController { .stream() .filter(c -> c.getRecipient().getID() == user.getID()) .findAny() - .orElseGet(() -> { var chat = new Chat(user); localDB.getChats().add(chat); return chat; }); + .orElseGet(() -> { final var chat = new Chat(user); localDB.getChats().add(chat); return chat; }); messageList.setItems(FXCollections.observableList(currentChat.getMessages())); } + messageTextArea.setDisable(currentChat == null); } @FXML @@ -132,7 +150,17 @@ public final class ChatSceneController { try { sceneContext.load(SceneContext.SceneInfo.SETTINGS_SCENE); sceneContext.getController().initializeData(sceneContext); - } catch (IOException e) { + } catch (final IOException e) { + e.printStackTrace(); + } + } + + @FXML + private void addContactButtonClicked() { + try { + sceneContext.load(SceneContext.SceneInfo.CONTACT_SEARCH_SCENE); + sceneContext.getController().initializeData(sceneContext); + } catch (final IOException e) { e.printStackTrace(); } } @@ -182,7 +210,7 @@ public final class ChatSceneController { // Request a new ID generator if all IDs were used if (!localDB.getIDGenerator().hasNext() && client.isOnline()) client.requestIdGenerator(); - } catch (IOException e) { + } catch (final IOException e) { logger.log(Level.SEVERE, "Error sending message", e); } } diff --git a/src/main/java/envoy/client/ui/ContactSearchSceneController.java b/src/main/java/envoy/client/ui/ContactSearchSceneController.java new file mode 100644 index 0000000..da4e2c0 --- /dev/null +++ b/src/main/java/envoy/client/ui/ContactSearchSceneController.java @@ -0,0 +1,117 @@ +package envoy.client.ui; + +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.TextField; + +import envoy.client.event.SendEvent; +import envoy.data.Contact; +import envoy.event.ElementOperation; +import envoy.event.EventBus; +import envoy.event.contact.ContactOperationEvent; +import envoy.event.contact.ContactSearchRequest; +import envoy.event.contact.ContactSearchResult; +import envoy.util.EnvoyLog; + +/** + * Project: envoy-client
+ * File: ContactSearchSceneController.java
+ * Created: 07.06.2020
+ * + * @author Leon Hofmeister + * @since Envoy Client v0.1-beta + */ +public class ContactSearchSceneController { + + @FXML + private Button backButton; + + @FXML + private Button clearButton; + + @FXML + private Button searchButton; + + @FXML + private TextField searchBar; + + @FXML + private ListView contactList; + + private SceneContext sceneContext; + + private static EventBus eventBus = EventBus.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(ChatSceneController.class); + + /** + * @param sceneContext enables the user to return to the chat scene + * @since Envoy Client v0.1-beta + */ + public void initializeData(SceneContext sceneContext) { this.sceneContext = sceneContext; } + + @FXML + private void initialize() { + contactList.setCellFactory(e -> new UserListCell()); + eventBus.register(ContactSearchResult.class, response -> Optional.of(response.get()).ifPresent(list -> contactList.getItems().addAll(list))); + } + + /** + * Disables the clear and search button if no text is present in the search bar. + * + * @since Envoy Client v0.1-beta + */ + @FXML + private void checkClearButton() { + final var containsContent = searchBar.getText().strip().isEmpty(); + clearButton.setDisable(containsContent); + searchButton.setDisable(containsContent); + } + + /** + * Sends a {@link ContactSearchRequest} to the server. + * + * @since Envoy Client v0.1-beta + */ + @FXML + private void suggestContacts() { eventBus.dispatch(new SendEvent(new ContactSearchRequest(searchBar.getText()))); } + + /** + * Clears the text in the search bar and the items shown in the list. + * Additionally disables both clear and search button. + * + * @since Envoy Client v0.1-beta + */ + @FXML + private void clear() { + searchBar.setText(null); + contactList.getItems().clear(); + clearButton.setDisable(true); + searchButton.setDisable(true); + } + + /** + * Sends an {@link ContactOperationEvent} for every selected contact to the + * server. + * + * @since Envoy Client v0.1-beta + */ + @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); + })); + } + + @FXML + private void backButtonClicked() { sceneContext.pop(); } +} diff --git a/src/main/resources/fxml/ChatScene.fxml b/src/main/resources/fxml/ChatScene.fxml index fa234ca..cd18dd8 100644 --- a/src/main/resources/fxml/ChatScene.fxml +++ b/src/main/resources/fxml/ChatScene.fxml @@ -24,14 +24,17 @@