diff --git a/pom.xml b/pom.xml
index 59bb365..d036d0d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
com.github.informatik-ag-ngl
envoy-common
- f~groups-SNAPSHOT
+ develop-SNAPSHOT
org.openjfx
diff --git a/src/main/java/envoy/client/data/LocalDB.java b/src/main/java/envoy/client/data/LocalDB.java
index 60bf7c0..38aeea4 100644
--- a/src/main/java/envoy/client/data/LocalDB.java
+++ b/src/main/java/envoy/client/data/LocalDB.java
@@ -200,4 +200,13 @@ public abstract class LocalDB {
}
});
}
+
+ /**
+ * Creates a new {@link Chat} for all {@link Contact}s that do not have a chat.
+ *
+ * @since Envoy Client v0.1-beta
+ */
+ public void createMissingChats() {
+ users.values().stream().filter(u -> !u.equals(user) && getChat(u.getID()).isEmpty()).map(Chat::new).forEach(chats::add);
+ }
}
diff --git a/src/main/java/envoy/client/net/Client.java b/src/main/java/envoy/client/net/Client.java
index 7aaf28b..9f9dad7 100644
--- a/src/main/java/envoy/client/net/Client.java
+++ b/src/main/java/envoy/client/net/Client.java
@@ -60,13 +60,15 @@ public class Client implements Closeable {
* @param receivedMessageCache a message cache containing all unread messages
* from the server that can be relayed after
* initialization
+ * @param receivedMessageStatusChangeEventCache an event cache containing all received messageStatusChangeEvents from the server that can be relayed after initialization
* @throws TimeoutException if the server could not be reached
* @throws IOException if the login credentials could not be
* written
* @throws InterruptedException if the current thread is interrupted while
* waiting for the handshake response
*/
- public void performHandshake(LoginCredentials credentials, Cache receivedMessageCache)
+ public void performHandshake(LoginCredentials credentials, Cache receivedMessageCache,
+ Cache receivedMessageStatusChangeEventCache)
throws TimeoutException, IOException, InterruptedException {
if (online) throw new IllegalStateException("Handshake has already been performed successfully");
// Establish TCP connection
@@ -80,6 +82,7 @@ public class Client implements Closeable {
// Register user creation processor, contact list processor and message cache
receiver.registerProcessor(User.class, sender -> { this.sender = sender; contacts = sender.getContacts(); });
receiver.registerProcessor(Message.class, receivedMessageCache);
+ receiver.registerProcessor(MessageStatusChangeEvent.class, receivedMessageStatusChangeEventCache);
receiver.registerProcessor(HandshakeRejectionEvent.class, evt -> { rejected = true; eventBus.dispatch(evt); });
rejected = false;
@@ -123,22 +126,27 @@ public class Client implements Closeable {
* @param receivedMessageCache a message cache containing all unread messages
* from the server that can be relayed after
* initialization
+ * @param receivedMessageStatusChangeEventCache an event cache containing all received messageStatusChangeEvents from the server that can be relayed after initialization
* @throws IOException if no {@link IDGenerator} is present and none could be
* requested from the server
* @since Envoy Client v0.2-alpha
*/
- public void initReceiver(LocalDB localDB, Cache receivedMessageCache) throws IOException {
+ public void initReceiver(LocalDB localDB, Cache receivedMessageCache,
+ Cache receivedMessageStatusChangeEventCache) throws IOException {
checkOnline();
// Process incoming messages
final ReceivedMessageProcessor receivedMessageProcessor = new ReceivedMessageProcessor();
+ final MessageStatusChangeEventProcessor messageStatusChangeEventProcessor = new MessageStatusChangeEventProcessor();
+
receiver.registerProcessor(Message.class, receivedMessageProcessor);
// Relay cached unread messages
receivedMessageCache.setProcessor(receivedMessageProcessor);
// Process message status changes
- receiver.registerProcessor(MessageStatusChangeEvent.class, new MessageStatusChangeEventProcessor());
+ receiver.registerProcessor(MessageStatusChangeEvent.class, messageStatusChangeEventProcessor);
+ receivedMessageStatusChangeEventCache.setProcessor(messageStatusChangeEventProcessor);
// Process user status changes
receiver.registerProcessor(UserStatusChangeEvent.class, eventBus::dispatch);
diff --git a/src/main/java/envoy/client/ui/SceneContext.java b/src/main/java/envoy/client/ui/SceneContext.java
index c191d8e..ea3b4b2 100644
--- a/src/main/java/envoy/client/ui/SceneContext.java
+++ b/src/main/java/envoy/client/ui/SceneContext.java
@@ -58,6 +58,13 @@ public final class SceneContext {
*/
CONTACT_SEARCH_SCENE("/fxml/ContactSearchScene.fxml"),
+ /**
+ * The scene in which the group creation screen is displayed.
+ *
+ * @since Envoy Client v0.1-beta
+ */
+ GROUP_CREATION_SCENE("/fxml/GroupCreationScene.fxml"),
+
/**
* The scene in which the login screen is displayed.
*
diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java
index aff8801..dbadfc3 100644
--- a/src/main/java/envoy/client/ui/Startup.java
+++ b/src/main/java/envoy/client/ui/Startup.java
@@ -16,6 +16,7 @@ import envoy.client.net.Client;
import envoy.client.ui.SceneContext.SceneInfo;
import envoy.client.ui.controller.LoginScene;
import envoy.data.Message;
+import envoy.event.MessageStatusChangeEvent;
import envoy.exception.EnvoyException;
import envoy.util.EnvoyLog;
@@ -27,13 +28,15 @@ import envoy.util.EnvoyLog;
* Created: 26.03.2020
*
* @author Kai S. K. Engelbart
+ * @author Maximilian Käfer
* @since Envoy Client v0.1-beta
*/
public final class Startup extends Application {
private LocalDB localDB;
private Client client;
- private Cache cache;
+ private Cache messageCache;
+ private Cache messageStatusCache;
private static final ClientConfig config = ClientConfig.getInstance();
private static final Logger logger = EnvoyLog.getLogger(Startup.class);
@@ -87,14 +90,15 @@ public final class Startup extends Application {
// Initialize client and unread message cache
client = new Client();
- cache = new Cache<>();
+ messageCache = new Cache<>();
+ messageStatusCache = new Cache<>();
stage.setTitle("Envoy");
stage.getIcons().add(IconUtil.load("/icons/envoy_logo.png"));
final var sceneContext = new SceneContext(stage);
sceneContext.load(SceneInfo.LOGIN_SCENE);
- sceneContext.getController().initializeData(client, localDB, cache, sceneContext);
+ sceneContext.getController().initializeData(client, localDB, messageCache, messageStatusCache, sceneContext);
}
/**
diff --git a/src/main/java/envoy/client/ui/controller/ChatScene.java b/src/main/java/envoy/client/ui/controller/ChatScene.java
index d74b82f..8f7b487 100644
--- a/src/main/java/envoy/client/ui/controller/ChatScene.java
+++ b/src/main/java/envoy/client/ui/controller/ChatScene.java
@@ -201,7 +201,7 @@ public final class ChatScene {
@FXML
private void addContactButtonClicked() {
sceneContext.load(SceneContext.SceneInfo.CONTACT_SEARCH_SCENE);
- sceneContext.getController().initializeData(sceneContext);
+ sceneContext.getController().initializeData(sceneContext, localDB);
}
/**
diff --git a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java
index 9fc495d..f2976c9 100644
--- a/src/main/java/envoy/client/ui/controller/ContactSearchScene.java
+++ b/src/main/java/envoy/client/ui/controller/ContactSearchScene.java
@@ -8,9 +8,10 @@ import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
+import envoy.client.data.LocalDB;
import envoy.client.event.SendEvent;
-import envoy.client.ui.SceneContext;
import envoy.client.ui.ContactListCell;
+import envoy.client.ui.SceneContext;
import envoy.data.Contact;
import envoy.event.ElementOperation;
import envoy.event.EventBus;
@@ -38,6 +39,9 @@ public class ContactSearchScene {
@FXML
private Button searchButton;
+ @FXML
+ private Button newGroupButton;
+
@FXML
private TextField searchBar;
@@ -46,6 +50,8 @@ public class ContactSearchScene {
private SceneContext sceneContext;
+ private LocalDB localDB;
+
private static EventBus eventBus = EventBus.getInstance();
private static final Logger logger = EnvoyLog.getLogger(ChatScene.class);
@@ -53,7 +59,10 @@ public class ContactSearchScene {
* @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; }
+ public void initializeData(SceneContext sceneContext, LocalDB localDB) {
+ this.sceneContext = sceneContext;
+ this.localDB = localDB;
+ }
@FXML
private void initialize() {
@@ -122,6 +131,12 @@ public class ContactSearchScene {
}
}
+ @FXML
+ private void newGroupButtonClicked() {
+ sceneContext.load(SceneContext.SceneInfo.GROUP_CREATION_SCENE);
+ sceneContext.getController().initializeData(sceneContext, localDB);
+ }
+
@FXML
private void backButtonClicked() { sceneContext.pop(); }
}
diff --git a/src/main/java/envoy/client/ui/controller/GroupCreationScene.java b/src/main/java/envoy/client/ui/controller/GroupCreationScene.java
new file mode 100644
index 0000000..af91d91
--- /dev/null
+++ b/src/main/java/envoy/client/ui/controller/GroupCreationScene.java
@@ -0,0 +1,77 @@
+package envoy.client.ui.controller;
+
+import java.util.stream.Collectors;
+
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.scene.control.*;
+
+import envoy.client.data.LocalDB;
+import envoy.client.event.SendEvent;
+import envoy.client.ui.ContactListCell;
+import envoy.client.ui.SceneContext;
+import envoy.data.Contact;
+import envoy.data.User;
+import envoy.event.EventBus;
+import envoy.event.GroupCreationEvent;
+
+/**
+ * Project: envoy-client
+ * File: ContactSearchSceneController.java
+ * Created: 07.06.2020
+ *
+ * @author Maximilian Käfer
+ * @since Envoy Client v0.1-beta
+ */
+public class GroupCreationScene {
+
+ @FXML
+ private Button backButton;
+
+ @FXML
+ private Button createButton;
+
+ @FXML
+ private TextField groupNameBar;
+
+ @FXML
+ private ListView contactList;
+
+ private SceneContext sceneContext;
+
+ private static EventBus eventBus = EventBus.getInstance();
+
+ @FXML
+ private void initialize() {
+ contactList.setCellFactory(e -> new ContactListCell());
+ contactList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+
+ /**
+ * @param sceneContext enables the user to return to the chat scene
+ * @since Envoy Client v0.1-beta
+ */
+ public void initializeData(SceneContext sceneContext, LocalDB localDB) {
+ this.sceneContext = sceneContext;
+ Platform.runLater(() -> contactList.getItems()
+ .addAll(localDB.getUsers()
+ .values()
+ .stream()
+ .filter(c -> c instanceof User && c.getID() != localDB.getUser().getID())
+ .collect(Collectors.toList())));
+ }
+
+ /**
+ * Sends a {@link GroupCreationEvent} to the server.
+ *
+ * @since Envoy Client v0.1-beta
+ */
+ @FXML
+ private void sendGroupObject() {
+ eventBus.dispatch(new SendEvent(new GroupCreationEvent(groupNameBar.getText(),
+ contactList.getSelectionModel().getSelectedItems().stream().map(Contact::getID).collect(Collectors.toSet()))));
+ }
+
+ @FXML
+ private void backButtonClicked() { sceneContext.pop(); }
+}
diff --git a/src/main/java/envoy/client/ui/controller/LoginScene.java b/src/main/java/envoy/client/ui/controller/LoginScene.java
index 5f6c5aa..f015b6e 100644
--- a/src/main/java/envoy/client/ui/controller/LoginScene.java
+++ b/src/main/java/envoy/client/ui/controller/LoginScene.java
@@ -21,6 +21,7 @@ import envoy.data.User;
import envoy.data.User.UserStatus;
import envoy.event.EventBus;
import envoy.event.HandshakeRejectionEvent;
+import envoy.event.MessageStatusChangeEvent;
import envoy.exception.EnvoyException;
import envoy.util.EnvoyLog;
@@ -30,6 +31,7 @@ import envoy.util.EnvoyLog;
* Created: 03.04.2020
*
* @author Kai S. K. Engelbart
+ * @author Maximilian Käfer
* @since Envoy Client v0.1-beta
*/
public final class LoginScene {
@@ -55,6 +57,7 @@ public final class LoginScene {
private Client client;
private LocalDB localDB;
private Cache receivedMessageCache;
+ private Cache receivedMessageStatusChangeEventCache;
private SceneContext sceneContext;
private static final Logger logger = EnvoyLog.getLogger(LoginScene.class);
@@ -77,14 +80,17 @@ public final class LoginScene {
* @param localDB the local database used for offline login
* @param receivedMessageCache the cache storing messages received during
* the handshake
+ * @param receivedMessageStatusChangeEventCache the cache storing messageStatusChangeEvents received during handshake
* @param sceneContext the scene context used to initialize the chat
* scene
* @since Envoy Client v0.1-beta
*/
- public void initializeData(Client client, LocalDB localDB, Cache receivedMessageCache, SceneContext sceneContext) {
+ public void initializeData(Client client, LocalDB localDB, Cache receivedMessageCache,
+ Cache receivedMessageStatusChangeEventCache, SceneContext sceneContext) {
this.client = client;
this.localDB = localDB;
this.receivedMessageCache = receivedMessageCache;
+ this.receivedMessageStatusChangeEventCache = receivedMessageStatusChangeEventCache;
this.sceneContext = sceneContext;
// Prepare handshake
@@ -129,9 +135,9 @@ public final class LoginScene {
private void performHandshake(LoginCredentials credentials) {
try {
- client.performHandshake(credentials, receivedMessageCache);
+ client.performHandshake(credentials, receivedMessageCache, receivedMessageStatusChangeEventCache);
if (client.isOnline()) {
- client.initReceiver(localDB, receivedMessageCache);
+ client.initReceiver(localDB, receivedMessageCache, receivedMessageStatusChangeEventCache);
loadChatScene();
}
} catch (IOException | InterruptedException | TimeoutException e) {
@@ -179,6 +185,7 @@ public final class LoginScene {
// Save all users to the local database and flush cache
localDB.setUsers(client.getUsers());
+ localDB.createMissingChats();
writeProxy.flushCache();
} else
// Set all contacts to offline mode
@@ -193,6 +200,7 @@ public final class LoginScene {
// Relay unread messages from cache
if (receivedMessageCache != null && client.isOnline()) receivedMessageCache.relay();
+ if (receivedMessageStatusChangeEventCache != null && client.isOnline()) receivedMessageStatusChangeEventCache.relay();
}
private void clearPasswordFields() {
diff --git a/src/main/resources/fxml/ContactSearchScene.fxml b/src/main/resources/fxml/ContactSearchScene.fxml
index c1fe70b..517b3e5 100644
--- a/src/main/resources/fxml/ContactSearchScene.fxml
+++ b/src/main/resources/fxml/ContactSearchScene.fxml
@@ -6,10 +6,8 @@
-
-
@@ -30,15 +28,7 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/fxml/GroupCreationScene.fxml b/src/main/resources/fxml/GroupCreationScene.fxml
new file mode 100644
index 0000000..53900d5
--- /dev/null
+++ b/src/main/resources/fxml/GroupCreationScene.fxml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+