diff --git a/src/main/java/envoy/client/data/Chat.java b/src/main/java/envoy/client/data/Chat.java index 739d335..68d55fd 100644 --- a/src/main/java/envoy/client/data/Chat.java +++ b/src/main/java/envoy/client/data/Chat.java @@ -111,6 +111,15 @@ public class Chat implements Serializable { messages.add(0, message); } + public int getUnreadAmount() { + int unreadMessagesAmount = 0; + for (int i = messages.size() - 1; i >= 0; i--) { + if (messages.get(i).getStatus() == MessageStatus.RECEIVED) unreadMessagesAmount++; + else break; + } + return unreadMessagesAmount; + } + /** * @return all messages in the current chat * @since Envoy Client v0.1-beta diff --git a/src/main/java/envoy/client/ui/controller/ChatScene.java b/src/main/java/envoy/client/ui/controller/ChatScene.java index 2cf116b..d3940eb 100644 --- a/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -52,7 +52,7 @@ public final class ChatScene implements Restorable { private ListView messageList; @FXML - private ListView userList; + private ListView userList; @FXML private Button postButton; @@ -121,7 +121,7 @@ public final class ChatScene implements Restorable { logger.log(Level.WARNING, "Could not read current chat: ", e1); } Platform.runLater(() -> { messageList.refresh(); scrollToMessageListEnd(); }); - } + } // TODO set lable to getunreadmessages return value }); }); @@ -143,8 +143,9 @@ public final class ChatScene implements Restorable { eventBus.register(UserStatusChange.class, e -> userList.getItems() .stream() - .filter(c -> c.getID() == e.getID()) + .filter(c -> c.getRecipient().getID() == e.getID()) .findAny() + .map(u -> u.getRecipient()) .ifPresent(u -> { ((User) u).setStatus(e.get()); Platform.runLater(userList::refresh); })); // Listen to contacts changes @@ -153,13 +154,14 @@ public final class ChatScene implements Restorable { switch (e.getOperationType()) { case ADD: localDB.getUsers().put(contact.getName(), contact); - localDB.getChats().add(contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact)); - Platform.runLater(() -> userList.getItems().add(contact)); + Chat chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact); + localDB.getChats().add(chat); + Platform.runLater(() -> userList.getItems().add(chat)); 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())); + Platform.runLater(() -> userList.getItems().removeIf(c -> c.getRecipient().getID() == contact.getID())); break; } }); @@ -181,7 +183,7 @@ public final class ChatScene implements Restorable { this.client = client; this.writeProxy = writeProxy; - userList.setItems(FXCollections.observableList(localDB.getChats().stream().map(Chat::getRecipient).collect(Collectors.toList()))); + userList.setItems(FXCollections.observableList(localDB.getChats().stream().collect(Collectors.toList()))); contactLabel.setText(localDB.getUser().getName()); MessageControl.setUser(localDB.getUser()); if (!client.isOnline()) updateInfoLabel("You are offline", "infoLabel-info"); @@ -199,7 +201,7 @@ public final class ChatScene implements Restorable { */ @FXML private void userListClicked() { - final Contact user = userList.getSelectionModel().getSelectedItem(); + final Contact user = userList.getSelectionModel().getSelectedItem().getRecipient(); if (user != null && (currentChat == null || !user.equals(currentChat.getRecipient()))) { // LEON: JFC <===> JAVA FRIED CHICKEN <=/=> Java Foundation Classes diff --git a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java index 4fe48d2..f7ac941 100644 --- a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java +++ b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java @@ -1,5 +1,7 @@ package envoy.client.ui.controller; +import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -10,12 +12,12 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; import javafx.scene.control.ListView; +import envoy.client.data.Chat; import envoy.client.data.LocalDB; import envoy.client.event.SendEvent; import envoy.client.ui.ClearableTextField; import envoy.client.ui.SceneContext; import envoy.client.ui.listcell.ContactListCellFactory; -import envoy.data.Contact; import envoy.event.ElementOperation; import envoy.event.EventBus; import envoy.event.contact.ContactOperation; @@ -37,7 +39,7 @@ public class ContactSearchScene { private ClearableTextField searchBar; @FXML - private ListView contactList; + private ListView contactList; private SceneContext sceneContext; @@ -61,7 +63,12 @@ public class ContactSearchScene { contactList.setCellFactory(ContactListCellFactory::new); searchBar.setClearButtonListener(e -> { searchBar.getTextField().clear(); contactList.getItems().clear(); }); eventBus.register(ContactSearchResult.class, - response -> Platform.runLater(() -> { contactList.getItems().clear(); contactList.getItems().addAll(response.get()); })); + response -> Platform.runLater(() -> { + List chats = new ArrayList(); + response.get().stream().forEach(r -> chats.add(new Chat(r))); + contactList.getItems().clear(); + contactList.getItems().addAll(chats); + })); } /** @@ -96,21 +103,21 @@ public class ContactSearchScene { */ @FXML private void contactListClicked() { - final var contact = contactList.getSelectionModel().getSelectedItem(); - if (contact != null) { + final var chat = contactList.getSelectionModel().getSelectedItem(); + if (chat != 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.setHeaderText("Add the user " + chat.getRecipient().getName() + " to your contact list?"); // Normally, this would be total BS (we are already on the FX Thread), however // it could be proven that the creation of this dialog wrapped in // Platform.runLater is less error-prone than without it Platform.runLater(() -> alert.showAndWait().filter(btn -> btn == ButtonType.OK).ifPresent(btn -> { - final var event = new ContactOperation(contact, ElementOperation.ADD); + final var event = new ContactOperation(chat.getRecipient(), 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); + logger.log(Level.INFO, "Added contact " + chat); })); } } diff --git a/src/main/java/envoy/client/ui/controller/GroupCreationScene.java b/src/main/java/envoy/client/ui/controller/GroupCreationScene.java index 76573b8..da88370 100644 --- a/src/main/java/envoy/client/ui/controller/GroupCreationScene.java +++ b/src/main/java/envoy/client/ui/controller/GroupCreationScene.java @@ -7,12 +7,13 @@ import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.control.Alert.AlertType; +import envoy.client.data.Chat; import envoy.client.data.LocalDB; import envoy.client.event.SendEvent; import envoy.client.ui.ClearableTextField; import envoy.client.ui.SceneContext; import envoy.client.ui.listcell.ContactListCellFactory; -import envoy.data.Contact; +import envoy.data.Group; import envoy.event.EventBus; import envoy.event.GroupCreation; import envoy.util.Bounds; @@ -34,7 +35,7 @@ public class GroupCreationScene { private ClearableTextField groupNameField; @FXML - private ListView contactList; + private ListView contactList; private SceneContext sceneContext; @@ -56,7 +57,11 @@ public class GroupCreationScene { public void initializeData(SceneContext sceneContext, LocalDB localDB) { this.sceneContext = sceneContext; Platform.runLater(() -> contactList.getItems() - .addAll(localDB.getUsers().values().stream().filter(c -> c.getID() != localDB.getUser().getID()).collect(Collectors.toList()))); + .addAll(localDB.getChats() + .stream() + .filter(c -> !(c.getRecipient() instanceof Group)) + .filter(c -> c.getRecipient().getID() != localDB.getUser().getID()) + .collect(Collectors.toList()))); } /** @@ -93,7 +98,7 @@ public class GroupCreationScene { groupNameField.getTextField().clear(); } else { eventBus.dispatch(new SendEvent(new GroupCreation(name, - contactList.getSelectionModel().getSelectedItems().stream().map(Contact::getID).collect(Collectors.toSet())))); + contactList.getSelectionModel().getSelectedItems().stream().map(c -> c.getRecipient().getID()).collect(Collectors.toSet())))); new Alert(AlertType.INFORMATION, String.format("Group '%s' successfully created.", name)).showAndWait(); sceneContext.pop(); } diff --git a/src/main/java/envoy/client/ui/listcell/ContactControl.java b/src/main/java/envoy/client/ui/listcell/ContactControl.java index 2a802fc..077068c 100644 --- a/src/main/java/envoy/client/ui/listcell/ContactControl.java +++ b/src/main/java/envoy/client/ui/listcell/ContactControl.java @@ -36,5 +36,8 @@ public class ContactControl extends VBox { getChildren().add(statusLabel); } else // Member count getChildren().add(new Label(((Group) contact).getContacts().size() + " members")); + + final var unreadMessagesLabel = new Label("5"); + getChildren().add(unreadMessagesLabel); } } diff --git a/src/main/java/envoy/client/ui/listcell/ContactListCellFactory.java b/src/main/java/envoy/client/ui/listcell/ContactListCellFactory.java index 8f8d3f0..fd0b1b9 100644 --- a/src/main/java/envoy/client/ui/listcell/ContactListCellFactory.java +++ b/src/main/java/envoy/client/ui/listcell/ContactListCellFactory.java @@ -3,7 +3,7 @@ package envoy.client.ui.listcell; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; -import envoy.data.Contact; +import envoy.client.data.Chat; /** * Project: envoy-client
@@ -13,15 +13,15 @@ import envoy.data.Contact; * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ -public class ContactListCellFactory extends ListCell { +public class ContactListCellFactory extends ListCell { - private final ListView listView; + private final ListView listView; /** * @param listView the list view inside which this cell is contained * @since Envoy Client v0.1-beta */ - public ContactListCellFactory(ListView listView) { this.listView = listView; } + public ContactListCellFactory(ListView listView) { this.listView = listView; } /** * Displays the name of a contact. If the contact is a user, their online status @@ -30,13 +30,13 @@ public class ContactListCellFactory extends ListCell { * @since Envoy Client v0.1-beta */ @Override - protected void updateItem(Contact contact, boolean empty) { - super.updateItem(contact, empty); - if (empty || contact == null) { + protected void updateItem(Chat chat, boolean empty) { + super.updateItem(chat, empty); + if (empty || chat.getRecipient() == null) { setText(null); setGraphic(null); } else { - final var control = new ContactControl(contact); + final var control = new ContactControl(chat.getRecipient()); prefWidthProperty().bind(listView.widthProperty().subtract(40)); setGraphic(control); }