diff --git a/client/src/main/java/envoy/client/ui/controller/ChatScene.java b/client/src/main/java/envoy/client/ui/controller/ChatScene.java index 5a55646..ad3caaf 100644 --- a/client/src/main/java/envoy/client/ui/controller/ChatScene.java +++ b/client/src/main/java/envoy/client/ui/controller/ChatScene.java @@ -297,8 +297,9 @@ public final class ChatScene implements EventListener, Restorable { chatList.setCellFactory(new ListCellFactory<>(ChatControl::new)); messageList.setCellFactory(MessageListCell::new); // TODO: cache image - if (currentChat.getRecipient() instanceof User) recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43)); - else recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43)); + if (currentChat != null) + if (currentChat.getRecipient() instanceof User) recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43)); + else recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43)); } @Event(eventType = Logout.class, priority = 200) diff --git a/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java index 4bcb1d8..ae2f04f 100644 --- a/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/DownloadSettingsPane.java @@ -5,8 +5,6 @@ import javafx.scene.control.*; import javafx.scene.layout.HBox; import javafx.stage.DirectoryChooser; -import envoy.client.data.Context; - /** * Displays options for downloading {@link envoy.data.Attachment}s. * @@ -47,7 +45,7 @@ public final class DownloadSettingsPane extends SettingsPane { final var directoryChooser = new DirectoryChooser(); directoryChooser.setTitle("Select the directory where attachments should be saved to"); directoryChooser.setInitialDirectory(settings.getDownloadLocation()); - final var selectedDirectory = directoryChooser.showDialog(Context.getInstance().getSceneContext().getStage()); + final var selectedDirectory = directoryChooser.showDialog(context.getSceneContext().getStage()); if (selectedDirectory != null) { currentPath.setText(selectedDirectory.getAbsolutePath()); diff --git a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java index 2e3786c..d734823 100644 --- a/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java @@ -7,6 +7,7 @@ import envoy.client.event.ThemeChangeEvent; import envoy.client.helper.ShutdownHelper; import envoy.client.ui.StatusTrayIcon; import envoy.data.User.UserStatus; +import envoy.event.UserStatusChange; import dev.kske.eventbus.EventBus; @@ -55,13 +56,23 @@ public final class GeneralSettingsPane extends SettingsPane { combobox.setOnAction(e -> { settings.setCurrentTheme(combobox.getValue()); EventBus.getInstance().dispatch(new ThemeChangeEvent()); }); getChildren().add(combobox); - final var statusComboBox = new ComboBox(); - statusComboBox.getItems().setAll(UserStatus.values()); - statusComboBox.setValue(UserStatus.ONLINE); - statusComboBox.setTooltip(new Tooltip("Change your current status")); - // TODO add action when value is changed - statusComboBox.setOnAction(e -> {}); - getChildren().add(statusComboBox); + if (context.getClient().isOnline()) { + final var statusComboBox = new ComboBox(); + statusComboBox.getItems().setAll(UserStatus.values()); + statusComboBox.setValue(context.getLocalDB().getUser().getStatus()); + statusComboBox.setTooltip(new Tooltip("Change your current status")); + statusComboBox.setOnAction(e -> { + final var status = statusComboBox.getValue(); + if (status == null) return; + else { + final var user = context.getLocalDB().getUser(); + user.setStatus(status); + // TODO update status in ChatScene + context.getClient().send(new UserStatusChange(user.getID(), status)); + } + }); + getChildren().add(statusComboBox); + } final var logoutButton = new Button("Logout"); logoutButton.setOnAction(e -> ShutdownHelper.logout()); diff --git a/client/src/main/java/envoy/client/ui/settings/OnlineOnlySettingsPane.java b/client/src/main/java/envoy/client/ui/settings/OnlineOnlySettingsPane.java index 592b31b..5ba18b4 100644 --- a/client/src/main/java/envoy/client/ui/settings/OnlineOnlySettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/OnlineOnlySettingsPane.java @@ -5,7 +5,6 @@ import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; -import envoy.client.data.Context; import envoy.client.net.Client; /** @@ -20,7 +19,7 @@ import envoy.client.net.Client; */ public abstract class OnlineOnlySettingsPane extends SettingsPane { - protected final Client client = Context.getInstance().getClient(); + protected final Client client = context.getClient(); private final Tooltip beOnlineReminder = new Tooltip("You need to be online to modify your account."); diff --git a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java index 5dc9796..ed80f20 100644 --- a/client/src/main/java/envoy/client/ui/settings/SettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/SettingsPane.java @@ -2,7 +2,7 @@ package envoy.client.ui.settings; import javafx.scene.layout.VBox; -import envoy.client.data.Settings; +import envoy.client.data.*; /** * @author Kai S. K. Engelbart @@ -12,7 +12,8 @@ public abstract class SettingsPane extends VBox { protected String title; - protected static final Settings settings = Settings.getInstance(); + protected static final Settings settings = Settings.getInstance(); + protected static final Context context = Context.getInstance(); protected SettingsPane(String title) { this.title = title; } diff --git a/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java index 5c6e730..fdf751e 100644 --- a/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java +++ b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java @@ -14,7 +14,6 @@ import javafx.scene.input.InputEvent; import javafx.scene.layout.HBox; import javafx.stage.FileChooser; -import envoy.client.data.Context; import envoy.client.ui.control.ProfilePicImageView; import envoy.client.util.IconUtil; import envoy.event.*; @@ -66,7 +65,7 @@ public final class UserSettingsPane extends OnlineOnlySettingsPane { pictureChooser.setInitialDirectory(new File(System.getProperty("user.home"))); pictureChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Pictures", "*.png", "*.jpg", "*.bmp", "*.gif")); - final var file = pictureChooser.showOpenDialog(Context.getInstance().getSceneContext().getStage()); + final var file = pictureChooser.showOpenDialog(context.getSceneContext().getStage()); if (file != null) { diff --git a/client/src/main/resources/css/base.css b/client/src/main/resources/css/base.css index be559b7..28d276c 100644 --- a/client/src/main/resources/css/base.css +++ b/client/src/main/resources/css/base.css @@ -6,7 +6,7 @@ -fx-background-radius: 15.0px; } -.list-cell:selected, .menu-item:hover { +.list-cell:selected, .menu-item:hover, .combo-box-popup .list-view .list-cell:selected { -fx-background-color: #454c4f; } diff --git a/client/src/main/resources/css/dark.css b/client/src/main/resources/css/dark.css index 0ed2997..8b28f80 100644 --- a/client/src/main/resources/css/dark.css +++ b/client/src/main/resources/css/dark.css @@ -18,7 +18,7 @@ -fx-background-color: lightgray; } -#message-list, .text-field, .password-field, .tooltip, .pane, .pane .content, .vbox, .titled-pane > .title, .titled-pane > *.content, .context-menu, .menu-item, #quick-select-list { +#message-list, .text-field, .password-field, .tooltip, .pane, .pane .content, .vbox, .titled-pane > .title, .titled-pane > *.content, .context-menu, .menu-item, .combo-box-popup .list-view .list-cell, #quick-select-list { -fx-background-color: #222222; } diff --git a/server/src/main/java/envoy/server/net/ConnectionManager.java b/server/src/main/java/envoy/server/net/ConnectionManager.java index 2dc7d2d..581a10f 100755 --- a/server/src/main/java/envoy/server/net/ConnectionManager.java +++ b/server/src/main/java/envoy/server/net/ConnectionManager.java @@ -22,14 +22,14 @@ public final class ConnectionManager implements ISocketIdListener { * * @since Envoy Server Standalone v0.1-alpha */ - private Set pendingSockets = new HashSet<>(); + private final Set pendingSockets = new HashSet<>(); /** * Contains all socket IDs that have acquired a user ID as keys to these IDs. * * @since Envoy Server Standalone v0.1-alpha */ - private Map sockets = new HashMap<>(); + private final Map sockets = new HashMap<>(); private static ConnectionManager connectionManager = new ConnectionManager(); @@ -44,11 +44,11 @@ public final class ConnectionManager implements ISocketIdListener { @Override public void socketCancelled(long socketID) { if (!pendingSockets.remove(socketID)) { + // Notify contacts of this users offline-going - envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID)); - user.setStatus(UserStatus.OFFLINE); + final envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID)); user.setLastSeen(Instant.now()); - UserStatusChangeProcessor.updateUserStatus(user); + UserStatusChangeProcessor.updateUserStatus(user, UserStatus.OFFLINE); // Remove the socket sockets.entrySet().removeIf(e -> e.getValue() == socketID); diff --git a/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index fdd83bf..3e91a7f 100755 --- a/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/server/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -46,42 +46,40 @@ public final class LoginCredentialProcessor implements ObjectProcessor pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync()); + final List pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user, credentials.getLastSync()); logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "..."); - for (var gmsg : pendingGroupMessages) { + for (final var gmsg : pendingGroupMessages) { final var gmsgCommon = gmsg.toCommon(); // Deliver the message to the user if he hasn't received it yet @@ -189,20 +186,18 @@ public final class LoginCredentialProcessor implements ObjectProcessor writeProxy.write(socketID, new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID))); - } // Deliver just a status change instead of the whole message if (gmsg.getStatus() == RECEIVED && user.getLastSeen().isBefore(gmsg.getReceivedDate()) diff --git a/server/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java b/server/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java index 9350af0..c551513 100755 --- a/server/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java +++ b/server/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java @@ -28,18 +28,20 @@ public final class UserStatusChangeProcessor implements ObjectProcessor