From ca8e267fb355235962d04a7485a3e9969698b251 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Wed, 2 Dec 2020 12:16:30 +0100 Subject: [PATCH] feat: sync chat with user selection --- .../fr/insa/clavardator/chat/ChatHistory.java | 78 ++++++++++++------- .../fr/insa/clavardator/chat/Message.java | 3 +- .../clavardator/db/DatabaseController.java | 2 +- .../insa/clavardator/ui/MainController.java | 4 + .../clavardator/ui/UserSelectedEvent.java | 4 +- .../clavardator/ui/chat/ChatController.java | 28 ++++--- .../ui/chat/ChatFooterController.java | 9 +++ .../ui/chat/ChatHeaderController.java | 27 +++++++ .../users/UserActiveIndicatorController.java | 4 + .../ui/users/UserListController.java | 6 +- .../ui/users/UserListItemCell.java | 6 +- .../insa/clavardator/ui/chat/chatFooter.fxml | 2 +- .../insa/clavardator/ui/chat/chatHeader.fxml | 6 +- .../ui/users/userActiveIndicator.fxml | 11 +-- 14 files changed, 131 insertions(+), 59 deletions(-) diff --git a/src/main/java/fr/insa/clavardator/chat/ChatHistory.java b/src/main/java/fr/insa/clavardator/chat/ChatHistory.java index 38ff199..5abc524 100644 --- a/src/main/java/fr/insa/clavardator/chat/ChatHistory.java +++ b/src/main/java/fr/insa/clavardator/chat/ChatHistory.java @@ -1,42 +1,60 @@ package fr.insa.clavardator.chat; import fr.insa.clavardator.db.DatabaseController; -import fr.insa.clavardator.users.User; +import fr.insa.clavardator.users.CurrentUser; +import fr.insa.clavardator.users.PeerUser; +import fr.insa.clavardator.users.UserList; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.util.ArrayList; -import java.util.Date; public class ChatHistory { private final DatabaseController db; - private final User user; - private ArrayList history = new ArrayList<>(); + private final PeerUser user; + private final ArrayList historyListener; + private final ArrayList messageListener; + private ArrayList history; - public ChatHistory(User user) { + public ChatHistory(PeerUser user) { this.user = user; db = new DatabaseController(user); + this.historyListener = new ArrayList<>(); + this.messageListener = new ArrayList<>(); } - // Make this class observable - private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); - - public void addObserver(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); + public void addHistoryLoadedListener(HistoryLoadedCallback listener) { + historyListener.add(listener); } - public void removeObserver(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); + public void addMessageAddedListener(MessageAddedCallback listener) { + messageListener.add(listener); } + private void notifyHistoryLoaded() { + historyListener.forEach(l -> l.onHistoryLoaded(history)); + } - private void getHistory() { - db.getChatHistory(new Date(), new Date(), // TODO: put actual date - newHistory -> { - ArrayList oldHistory = history; - history = newHistory; - pcs.firePropertyChange("history", oldHistory, history); // Does this work? - }); + private void notifyMessageAdded(Message message) { + messageListener.forEach(l -> l.onMessageAdded(message)); + } + + public void load() { + if (history == null) { + // TODO remove after tests + CurrentUser currentUser = new CurrentUser("Moi", new UserList()); + history = new ArrayList<>(); + history.add(new Message(user, currentUser, "Coucou toi")); + history.add(new Message(currentUser, user, "Coucou " + user.getUsername())); + history.add(new Message(user, currentUser, "oui")); + history.add(new Message(currentUser, user, "merci")); + notifyHistoryLoaded(); +// db.getChatHistory(new Date(), new Date(), // TODO: put actual date +// newHistory -> { +// history = newHistory; +// notifyHistoryLoaded(); +// }); + } else { + notifyHistoryLoaded(); + } } @@ -44,12 +62,18 @@ public class ChatHistory { * @param message */ public void addMessage(Message message) { - db.addMessage(message, new DatabaseController.MessageCallback() { - @Override - public void onMessageSaved(Message savedMessage) { - history.add(savedMessage); - pcs.firePropertyChange("history", null, history); - } + db.addMessage(message, () -> { + history.add(message); + notifyMessageAdded(message); }); } + + public interface MessageAddedCallback { + void onMessageAdded(Message message); + } + + public interface HistoryLoadedCallback { + void onHistoryLoaded(ArrayList history); + } + } diff --git a/src/main/java/fr/insa/clavardator/chat/Message.java b/src/main/java/fr/insa/clavardator/chat/Message.java index 54ecaa9..9587c04 100644 --- a/src/main/java/fr/insa/clavardator/chat/Message.java +++ b/src/main/java/fr/insa/clavardator/chat/Message.java @@ -1,14 +1,13 @@ package fr.insa.clavardator.chat; -import fr.insa.clavardator.users.CurrentUser; import fr.insa.clavardator.users.User; import java.io.Serializable; public class Message implements Serializable { - private String text; private final User recipient; private final User sender; + private final String text; public Message(User sender, User recipient) { this(sender, recipient, ""); diff --git a/src/main/java/fr/insa/clavardator/db/DatabaseController.java b/src/main/java/fr/insa/clavardator/db/DatabaseController.java index 48420f6..2cd9197 100644 --- a/src/main/java/fr/insa/clavardator/db/DatabaseController.java +++ b/src/main/java/fr/insa/clavardator/db/DatabaseController.java @@ -57,6 +57,6 @@ public class DatabaseController { } public interface MessageCallback { - void onMessageSaved(Message history); + void onMessageSaved(); } } diff --git a/src/main/java/fr/insa/clavardator/ui/MainController.java b/src/main/java/fr/insa/clavardator/ui/MainController.java index 19cea06..047cf9b 100644 --- a/src/main/java/fr/insa/clavardator/ui/MainController.java +++ b/src/main/java/fr/insa/clavardator/ui/MainController.java @@ -2,6 +2,8 @@ package fr.insa.clavardator.ui; import fr.insa.clavardator.ui.chat.ChatController; import fr.insa.clavardator.ui.users.UserListController; +import fr.insa.clavardator.users.CurrentUser; +import fr.insa.clavardator.users.UserList; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -17,11 +19,13 @@ public class MainController implements Initializable { @Override public void initialize(URL url, ResourceBundle rb) { + chatController.setCurrentUser(new CurrentUser("Moi", new UserList())); userListController.addRefreshUserListener(() -> { System.out.println("refresh event"); }); userListController.addUserSelectedListener((user) -> { System.out.println(user.getUsername()); + chatController.setRemoteUser(user); }); chatController.addAttachmentListener(() -> { System.out.println("attach event"); diff --git a/src/main/java/fr/insa/clavardator/ui/UserSelectedEvent.java b/src/main/java/fr/insa/clavardator/ui/UserSelectedEvent.java index ee2aba5..4ec8526 100644 --- a/src/main/java/fr/insa/clavardator/ui/UserSelectedEvent.java +++ b/src/main/java/fr/insa/clavardator/ui/UserSelectedEvent.java @@ -1,7 +1,7 @@ package fr.insa.clavardator.ui; -import fr.insa.clavardator.users.User; +import fr.insa.clavardator.users.PeerUser; public interface UserSelectedEvent { - public void onSelected(User user); + void onSelected(PeerUser user); } diff --git a/src/main/java/fr/insa/clavardator/ui/chat/ChatController.java b/src/main/java/fr/insa/clavardator/ui/chat/ChatController.java index c9479da..9ab9948 100644 --- a/src/main/java/fr/insa/clavardator/ui/chat/ChatController.java +++ b/src/main/java/fr/insa/clavardator/ui/chat/ChatController.java @@ -1,8 +1,10 @@ package fr.insa.clavardator.ui.chat; +import fr.insa.clavardator.chat.ChatHistory; import fr.insa.clavardator.chat.Message; import fr.insa.clavardator.ui.ButtonPressEvent; import fr.insa.clavardator.ui.NoSelectionModel; +import fr.insa.clavardator.users.ActiveUser; import fr.insa.clavardator.users.CurrentUser; import fr.insa.clavardator.users.PeerUser; import javafx.collections.FXCollections; @@ -12,6 +14,7 @@ import javafx.fxml.Initializable; import javafx.scene.control.ListView; import java.net.URL; +import java.util.ArrayList; import java.util.ResourceBundle; public class ChatController implements Initializable { @@ -40,25 +43,32 @@ public class ChatController implements Initializable { public void setCurrentUser(CurrentUser currentUser) { + this.chatHeaderController.setCurrentUser(currentUser); this.currentUser = currentUser; } public void setRemoteUser(PeerUser remoteUser) { this.remoteUser = remoteUser; - loadMessageList(); + this.chatHeaderController.setRemoteUser(remoteUser); + this.chatFooterController.setEnabled(remoteUser instanceof ActiveUser); + + final ChatHistory history = remoteUser.getHistory(); + history.addHistoryLoadedListener(this::onHistoryLoaded); + history.addMessageAddedListener(this::onMessageAdded); + history.load(); } - private void loadMessageList() { - ObservableList messages = FXCollections.observableArrayList( - new Message(remoteUser, currentUser, "Messsssage 1"), - new Message(remoteUser, currentUser, "Messsssage 2"), - new Message(currentUser, remoteUser, "Messsssage 3"), - new Message(remoteUser, currentUser, "Messsssage 4") - ); - messageList.setItems(messages); + private void onHistoryLoaded(ArrayList messages) { + messageList.setItems(FXCollections.observableArrayList(messages)); messageList.scrollTo(messageList.getItems().size() - 1); } + private void onMessageAdded(Message message) { + messageList.getItems().add(message); + messageList.scrollTo(messageList.getItems().size() - 1); + } + + @Override public void initialize(URL url, ResourceBundle rb) { messageList.setItems(null); diff --git a/src/main/java/fr/insa/clavardator/ui/chat/ChatFooterController.java b/src/main/java/fr/insa/clavardator/ui/chat/ChatFooterController.java index 0e3dc65..5385f48 100644 --- a/src/main/java/fr/insa/clavardator/ui/chat/ChatFooterController.java +++ b/src/main/java/fr/insa/clavardator/ui/chat/ChatFooterController.java @@ -1,7 +1,9 @@ package fr.insa.clavardator.ui.chat; import fr.insa.clavardator.ui.ButtonPressEvent; +import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.layout.HBox; import java.net.URL; import java.util.ArrayList; @@ -10,6 +12,9 @@ import java.util.ResourceBundle; public class ChatFooterController implements Initializable { + @FXML + private HBox container; + private List attachmentListeners; private List sendListeners; @@ -27,6 +32,10 @@ public class ChatFooterController implements Initializable { sendListeners.forEach(ButtonPressEvent::onPress); } + public void setEnabled(boolean enabled) { + container.setDisable(!enabled); + } + @Override public void initialize(URL location, ResourceBundle resources) { attachmentListeners = new ArrayList<>(); diff --git a/src/main/java/fr/insa/clavardator/ui/chat/ChatHeaderController.java b/src/main/java/fr/insa/clavardator/ui/chat/ChatHeaderController.java index 4894eb1..a8328f0 100644 --- a/src/main/java/fr/insa/clavardator/ui/chat/ChatHeaderController.java +++ b/src/main/java/fr/insa/clavardator/ui/chat/ChatHeaderController.java @@ -1,7 +1,12 @@ package fr.insa.clavardator.ui.chat; import fr.insa.clavardator.ui.ButtonPressEvent; +import fr.insa.clavardator.ui.users.UserActiveIndicatorController; +import fr.insa.clavardator.users.CurrentUser; +import fr.insa.clavardator.users.PeerUser; +import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Label; import java.net.URL; import java.util.ArrayList; @@ -10,8 +15,18 @@ import java.util.ResourceBundle; public class ChatHeaderController implements Initializable { + @FXML + private Label currentUsernameLabel; + @FXML + private Label remoteUsernameLabel; + @FXML + private UserActiveIndicatorController indicatorController; + private List editListeners; + private CurrentUser currentUser; + private PeerUser remoteUser; + public void addEditListener(ButtonPressEvent listener) { editListeners.add(listener); } @@ -27,4 +42,16 @@ public class ChatHeaderController implements Initializable { public void initialize(URL location, ResourceBundle resources) { editListeners = new ArrayList<>(); } + + public void setCurrentUser(CurrentUser currentUser) { + this.currentUser = currentUser; + currentUsernameLabel.setText(currentUser.getUsername()); + } + + public void setRemoteUser(PeerUser remoteUser) { + this.remoteUser = remoteUser; + remoteUsernameLabel.setText(remoteUser.getUsername()); + indicatorController.setUser(remoteUser); + indicatorController.setSize(10.0); + } } diff --git a/src/main/java/fr/insa/clavardator/ui/users/UserActiveIndicatorController.java b/src/main/java/fr/insa/clavardator/ui/users/UserActiveIndicatorController.java index 9a5c448..ff96e65 100644 --- a/src/main/java/fr/insa/clavardator/ui/users/UserActiveIndicatorController.java +++ b/src/main/java/fr/insa/clavardator/ui/users/UserActiveIndicatorController.java @@ -28,4 +28,8 @@ public class UserActiveIndicatorController implements Initializable { } } + public void setSize(double value) { + circle.setRadius(value); + } + } diff --git a/src/main/java/fr/insa/clavardator/ui/users/UserListController.java b/src/main/java/fr/insa/clavardator/ui/users/UserListController.java index 1dcd74c..5693462 100644 --- a/src/main/java/fr/insa/clavardator/ui/users/UserListController.java +++ b/src/main/java/fr/insa/clavardator/ui/users/UserListController.java @@ -23,7 +23,7 @@ public class UserListController implements Initializable { final private List refreshUserListeners; final private List userSelectedListeners; @FXML - private ListView userList; + private ListView userList; public UserListController() { super(); @@ -43,7 +43,7 @@ public class UserListController implements Initializable { refreshUserListeners.forEach(ButtonPressEvent::onPress); } - private void onUserSelected(@org.jetbrains.annotations.NotNull User user) { + private void onUserSelected(@org.jetbrains.annotations.NotNull PeerUser user) { final User currentSelectedUser = userList.getSelectionModel().getSelectedItem(); if (!user.equals(currentSelectedUser)) { userList.getSelectionModel().select(user); @@ -53,7 +53,7 @@ public class UserListController implements Initializable { @Override public void initialize(URL url, ResourceBundle rb) { - ObservableList activeList = null; + ObservableList activeList = null; try { activeList = FXCollections.observableArrayList( new PeerUser("Dodo0"), diff --git a/src/main/java/fr/insa/clavardator/ui/users/UserListItemCell.java b/src/main/java/fr/insa/clavardator/ui/users/UserListItemCell.java index 382028e..db9e6a4 100644 --- a/src/main/java/fr/insa/clavardator/ui/users/UserListItemCell.java +++ b/src/main/java/fr/insa/clavardator/ui/users/UserListItemCell.java @@ -1,13 +1,13 @@ package fr.insa.clavardator.ui.users; import fr.insa.clavardator.ui.UserSelectedEvent; -import fr.insa.clavardator.users.User; +import fr.insa.clavardator.users.PeerUser; import javafx.fxml.FXMLLoader; import javafx.scene.control.ListCell; import java.io.IOException; -public class UserListItemCell extends ListCell { +public class UserListItemCell extends ListCell { private UserSelectedEvent listener; @@ -20,7 +20,7 @@ public class UserListItemCell extends ListCell { } @Override - protected void updateItem(User item, boolean empty) { + protected void updateItem(PeerUser item, boolean empty) { super.updateItem(item, empty); if (!empty && item != null) { final FXMLLoader cellLoader = new FXMLLoader(getClass().getResource("userListItem.fxml")); diff --git a/src/main/resources/fr/insa/clavardator/ui/chat/chatFooter.fxml b/src/main/resources/fr/insa/clavardator/ui/chat/chatFooter.fxml index 5482087..141d155 100644 --- a/src/main/resources/fr/insa/clavardator/ui/chat/chatFooter.fxml +++ b/src/main/resources/fr/insa/clavardator/ui/chat/chatFooter.fxml @@ -8,7 +8,7 @@ + stylesheets="@../styles.css" styleClass="container" alignment="CENTER" spacing="10.0" fx:id="container"> diff --git a/src/main/resources/fr/insa/clavardator/ui/chat/chatHeader.fxml b/src/main/resources/fr/insa/clavardator/ui/chat/chatHeader.fxml index 308018f..454a824 100644 --- a/src/main/resources/fr/insa/clavardator/ui/chat/chatHeader.fxml +++ b/src/main/resources/fr/insa/clavardator/ui/chat/chatHeader.fxml @@ -15,7 +15,7 @@ diff --git a/src/main/resources/fr/insa/clavardator/ui/users/userActiveIndicator.fxml b/src/main/resources/fr/insa/clavardator/ui/users/userActiveIndicator.fxml index 2001804..9558aa1 100644 --- a/src/main/resources/fr/insa/clavardator/ui/users/userActiveIndicator.fxml +++ b/src/main/resources/fr/insa/clavardator/ui/users/userActiveIndicator.fxml @@ -1,16 +1,11 @@ - - - - - + stylesheets="@../styles.css" alignment="CENTER"> - +