Add Ability to Change the User Status Freely #90
@ -293,6 +293,9 @@ public final class LocalDB implements EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Event(priority = 500)
|
||||||
|
private void onOwnStatusChange(OwnStatusChange statusChange) { user.setStatus(statusChange.get()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a {@code Map<String, User>} of all users stored locally with their
|
* @return a {@code Map<String, User>} of all users stored locally with their
|
||||||
* user names as keys
|
* user names as keys
|
||||||
|
23
client/src/main/java/envoy/client/event/OwnStatusChange.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package envoy.client.event;
|
||||||
|
|
||||||
|
import envoy.data.User;
|
||||||
|
import envoy.data.User.UserStatus;
|
||||||
|
import envoy.event.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conveys the action that the currently logged in {@link User} has changed his
|
||||||
delvh marked this conversation as resolved
|
|||||||
|
* status (manually).
|
||||||
|
*
|
||||||
|
* @author Leon Hofmeister
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public class OwnStatusChange extends Event<UserStatus> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value the new user status of the currently logged in user
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public OwnStatusChange(UserStatus value) { super(value); }
|
||||||
|
}
|
@ -1,15 +1,8 @@
|
|||||||
package envoy.client.helper;
|
package envoy.client.helper;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Alert.AlertType;
|
|
||||||
|
|
||||||
import envoy.client.data.*;
|
import envoy.client.data.*;
|
||||||
import envoy.client.event.*;
|
import envoy.client.event.EnvoyCloseEvent;
|
||||||
import envoy.client.ui.SceneContext.SceneInfo;
|
|
||||||
import envoy.client.ui.StatusTrayIcon;
|
import envoy.client.ui.StatusTrayIcon;
|
||||||
import envoy.util.EnvoyLog;
|
|
||||||
|
|
||||||
import dev.kske.eventbus.EventBus;
|
import dev.kske.eventbus.EventBus;
|
||||||
|
|
||||||
@ -36,23 +29,4 @@ public final class ShutdownHelper {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs the current user out and reopens
|
|
||||||
* {@link envoy.client.ui.controller.LoginScene}.
|
|
||||||
*
|
|
||||||
* @since Envoy Client v0.2-beta
|
|
||||||
*/
|
|
||||||
public static void logout() {
|
|
||||||
final var alert = new Alert(AlertType.CONFIRMATION);
|
|
||||||
alert.setTitle("Logout?");
|
|
||||||
alert.setContentText("Are you sure you want to log out?");
|
|
||||||
|
|
||||||
AlertHelper.confirmAction(alert, () -> {
|
|
||||||
EnvoyLog.getLogger(ShutdownHelper.class).log(Level.INFO, "A logout was requested");
|
|
||||||
EventBus.getInstance().dispatch(new EnvoyCloseEvent());
|
|
||||||
EventBus.getInstance().dispatch(new Logout());
|
|
||||||
Context.getInstance().getSceneContext().load(SceneInfo.LOGIN_SCENE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import javafx.stage.Stage;
|
|||||||
import envoy.client.data.Settings;
|
import envoy.client.data.Settings;
|
||||||
import envoy.client.event.*;
|
import envoy.client.event.*;
|
||||||
import envoy.client.helper.ShutdownHelper;
|
import envoy.client.helper.ShutdownHelper;
|
||||||
|
import envoy.client.util.UserUtil;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
import dev.kske.eventbus.*;
|
import dev.kske.eventbus.*;
|
||||||
@ -128,7 +129,7 @@ public final class SceneContext implements EventListener {
|
|||||||
|
|
||||||
// Add the option to logout using "Control"+"Shift"+"L" if not in login scene
|
// Add the option to logout using "Control"+"Shift"+"L" if not in login scene
|
||||||
if (sceneInfo != SceneInfo.LOGIN_SCENE)
|
if (sceneInfo != SceneInfo.LOGIN_SCENE)
|
||||||
kske marked this conversation as resolved
kske
commented
(yes, these are both rhetorical questions) 1. Are these key combinations documented anywhere?
2. Can we stop putting scene specific code inside `SceneContext`, that could be completely generic as to what scenes it displays, except for being littered with code specific to `LoginScene` which nobody would expect here?
(yes, these are both rhetorical questions)
delvh
commented
to 1. While I know what you mean, I'd still say that this goes beyond the scope of this branch. It seems as if one of the next branches should cleanup that in SceneContext. I could do it in that branch, but than this branch will have two completely separate tasks on it (and it would be eve larger than it already is). to 1. While I know what you mean, I'd still say that this goes beyond the scope of this branch.
to 2. While I know what you mean, I'd still say that this goes beyond the scope of this branch.
It seems as if one of the next branches should cleanup that in SceneContext. I could do it in that branch, but than this branch will have two completely separate tasks on it (and it would be eve larger than it already is).
kske
commented
No, I think you are right. The cleanup should be performed inside a separate branch. No, I think you are right. The cleanup should be performed inside a separate branch.
delvh
commented
See #91 See #91
|
|||||||
accelerators.put(new KeyCodeCombination(KeyCode.L, KeyCombination.CONTROL_DOWN, KeyCombination.SHIFT_DOWN), ShutdownHelper::logout);
|
accelerators.put(new KeyCodeCombination(KeyCode.L, KeyCombination.CONTROL_DOWN, KeyCombination.SHIFT_DOWN), UserUtil::logout);
|
||||||
|
|
||||||
// Add the option to open the settings scene with "Control"+"S", if being in
|
// Add the option to open the settings scene with "Control"+"S", if being in
|
||||||
// chat scene
|
// chat scene
|
||||||
|
@ -12,7 +12,7 @@ import envoy.client.data.commands.*;
|
|||||||
import envoy.client.helper.ShutdownHelper;
|
import envoy.client.helper.ShutdownHelper;
|
||||||
import envoy.client.ui.SceneContext.SceneInfo;
|
import envoy.client.ui.SceneContext.SceneInfo;
|
||||||
import envoy.client.ui.controller.ChatScene;
|
import envoy.client.ui.controller.ChatScene;
|
||||||
import envoy.client.util.MessageUtil;
|
import envoy.client.util.*;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.util.EnvoyLog;
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public final class ChatSceneCommands {
|
|||||||
.build("dabr");
|
.build("dabr");
|
||||||
|
|
||||||
// Logout initialization
|
// Logout initialization
|
||||||
builder.setAction(text -> ShutdownHelper.logout()).setDescription("Logs you out.").buildNoArg("logout");
|
builder.setAction(text -> UserUtil.logout()).setDescription("Logs you out.").buildNoArg("logout");
|
||||||
|
|
||||||
// Exit initialization
|
// Exit initialization
|
||||||
builder.setAction(text -> ShutdownHelper.exit()).setNumberOfArguments(0).setDescription("Exits the program.").build("exit", false);
|
builder.setAction(text -> ShutdownHelper.exit()).setNumberOfArguments(0).setDescription("Exits the program.").build("exit", false);
|
||||||
|
@ -13,6 +13,7 @@ import javafx.application.Platform;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.collections.transformation.FilteredList;
|
import javafx.collections.transformation.FilteredList;
|
||||||
import javafx.fxml.*;
|
import javafx.fxml.*;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
import javafx.scene.control.Alert.AlertType;
|
||||||
import javafx.scene.image.*;
|
import javafx.scene.image.*;
|
||||||
@ -29,7 +30,7 @@ import envoy.client.event.*;
|
|||||||
import envoy.client.net.*;
|
import envoy.client.net.*;
|
||||||
import envoy.client.ui.*;
|
import envoy.client.ui.*;
|
||||||
import envoy.client.ui.chatscene.*;
|
import envoy.client.ui.chatscene.*;
|
||||||
import envoy.client.ui.control.ChatControl;
|
import envoy.client.ui.control.*;
|
||||||
import envoy.client.ui.listcell.*;
|
import envoy.client.ui.listcell.*;
|
||||||
import envoy.client.util.*;
|
import envoy.client.util.*;
|
||||||
import envoy.data.*;
|
import envoy.data.*;
|
||||||
@ -78,9 +79,6 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button newContactButton;
|
private Button newContactButton;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Label contactLabel;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label remainingChars;
|
private Label remainingChars;
|
||||||
|
|
||||||
@ -126,6 +124,12 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
@FXML
|
@FXML
|
||||||
private HBox contactSpecificOnlineOperations;
|
private HBox contactSpecificOnlineOperations;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private HBox ownContactControl;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Region spaceBetweenUserAndSettingsButton;
|
||||||
|
|
||||||
private Chat currentChat;
|
private Chat currentChat;
|
||||||
private FilteredList<Chat> chats;
|
private FilteredList<Chat> chats;
|
||||||
private boolean recording;
|
private boolean recording;
|
||||||
@ -185,10 +189,16 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
clientProfilePic.setClip(clip);
|
clientProfilePic.setClip(clip);
|
||||||
|
|
||||||
chatList.setItems(chats = new FilteredList<>(localDB.getChats()));
|
chatList.setItems(chats = new FilteredList<>(localDB.getChats()));
|
||||||
contactLabel.setText(localDB.getUser().getName());
|
|
||||||
|
// Set the design of the box in the upper-left corner
|
||||||
|
settingsButton.setAlignment(Pos.BOTTOM_RIGHT);
|
||||||
|
HBox.setHgrow(spaceBetweenUserAndSettingsButton, Priority.ALWAYS);
|
||||||
delvh marked this conversation as resolved
delvh
commented
@DieGurke The region you requested is already here, but for some strange reason it doesn't work as expected. @DieGurke The region you requested is already here, but for some strange reason it doesn't work as expected.
Any idea why?
Feel free to take on that challenge, because I've tried it for about twenty minutes and could not get it to work.
mpk
commented
I could't fix it neither. Preferably you open an issue for that. I could't fix it neither. Preferably you open an issue for that.
|
|||||||
|
generateOwnStatusControl();
|
||||||
|
System.out.println(ownContactControl.getChildren());
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
final var online = client.isOnline();
|
final var online = client.isOnline();
|
||||||
|
|
||||||
// no check will be performed in case it has already been disabled - a negative
|
// no check will be performed in case it has already been disabled - a negative
|
||||||
// GroupCreationResult might have been returned
|
// GroupCreationResult might have been returned
|
||||||
if (!newGroupButton.isDisabled()) newGroupButton.setDisable(!online);
|
if (!newGroupButton.isDisabled()) newGroupButton.setDisable(!online);
|
||||||
@ -260,6 +270,9 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Event(eventType = OwnStatusChange.class, priority = 50)
|
||||||
|
private void onOwnStatusChange() { generateOwnStatusControl(); }
|
||||||
|
|
||||||
@Event
|
@Event
|
||||||
private void onContactOperation(ContactOperation operation) {
|
private void onContactOperation(ContactOperation operation) {
|
||||||
final var contact = operation.get();
|
final var contact = operation.get();
|
||||||
@ -706,6 +719,13 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
attachmentView.setVisible(visible);
|
attachmentView.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateOwnStatusControl() {
|
||||||
delvh marked this conversation as resolved
kske
commented
You could annotate this as an event handler directly. You could annotate this as an event handler directly.
|
|||||||
|
final var ownUserControl = new ContactControl(localDB.getUser());
|
||||||
|
ownUserControl.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
if (ownContactControl.getChildren().get(0) instanceof ContactControl) ownContactControl.getChildren().set(0, ownUserControl);
|
||||||
|
else ownContactControl.getChildren().add(0, ownUserControl);
|
||||||
|
}
|
||||||
|
|
||||||
// Context menu actions
|
// Context menu actions
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
@ -4,10 +4,9 @@ import javafx.scene.control.*;
|
|||||||
|
|
||||||
import envoy.client.data.SettingsItem;
|
import envoy.client.data.SettingsItem;
|
||||||
import envoy.client.event.ThemeChangeEvent;
|
import envoy.client.event.ThemeChangeEvent;
|
||||||
import envoy.client.helper.ShutdownHelper;
|
|
||||||
import envoy.client.ui.StatusTrayIcon;
|
import envoy.client.ui.StatusTrayIcon;
|
||||||
|
import envoy.client.util.UserUtil;
|
||||||
import envoy.data.User.UserStatus;
|
import envoy.data.User.UserStatus;
|
||||||
import envoy.event.UserStatusChange;
|
|
||||||
|
|
||||||
import dev.kske.eventbus.EventBus;
|
import dev.kske.eventbus.EventBus;
|
||||||
|
|
||||||
@ -64,18 +63,13 @@ public final class GeneralSettingsPane extends SettingsPane {
|
|||||||
statusComboBox.setOnAction(e -> {
|
statusComboBox.setOnAction(e -> {
|
||||||
final var status = statusComboBox.getValue();
|
final var status = statusComboBox.getValue();
|
||||||
if (status == null) return;
|
if (status == null) return;
|
||||||
else {
|
else UserUtil.changeStatus(status);
|
||||||
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);
|
getChildren().add(statusComboBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
final var logoutButton = new Button("Logout");
|
final var logoutButton = new Button("Logout");
|
||||||
logoutButton.setOnAction(e -> ShutdownHelper.logout());
|
logoutButton.setOnAction(e -> UserUtil.logout());
|
||||||
final var logoutTooltip = new Tooltip("Brings you back to the login screen and removes \"remember me\" status from this account");
|
final var logoutTooltip = new Tooltip("Brings you back to the login screen and removes \"remember me\" status from this account");
|
||||||
logoutTooltip.setWrapText(true);
|
logoutTooltip.setWrapText(true);
|
||||||
logoutButton.setTooltip(logoutTooltip);
|
logoutButton.setTooltip(logoutTooltip);
|
||||||
|
58
client/src/main/java/envoy/client/util/UserUtil.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package envoy.client.util;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.Alert.AlertType;
|
||||||
|
|
||||||
|
import envoy.client.data.Context;
|
||||||
|
import envoy.client.event.*;
|
||||||
|
import envoy.client.helper.*;
|
||||||
|
import envoy.client.ui.SceneContext.SceneInfo;
|
||||||
|
import envoy.data.User.UserStatus;
|
||||||
|
import envoy.event.UserStatusChange;
|
||||||
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
|
import dev.kske.eventbus.EventBus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains methods that change something about the currently logged in user.
|
||||||
|
*
|
||||||
|
* @author Leon Hofmeister
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public final class UserUtil {
|
||||||
|
|
||||||
|
private UserUtil() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the current user out and reopens
|
||||||
|
* {@link envoy.client.ui.controller.LoginScene}.
|
||||||
|
*
|
||||||
|
* @since Envoy Client v0.2-beta
|
||||||
|
*/
|
||||||
|
public static void logout() {
|
||||||
|
final var alert = new Alert(AlertType.CONFIRMATION);
|
||||||
|
alert.setTitle("Logout?");
|
||||||
|
alert.setContentText("Are you sure you want to log out?");
|
||||||
|
|
||||||
|
AlertHelper.confirmAction(alert, () -> {
|
||||||
|
EnvoyLog.getLogger(ShutdownHelper.class).log(Level.INFO, "A logout was requested");
|
||||||
|
EventBus.getInstance().dispatch(new EnvoyCloseEvent());
|
||||||
|
EventBus.getInstance().dispatch(new Logout());
|
||||||
|
Context.getInstance().getSceneContext().load(SceneInfo.LOGIN_SCENE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the application that the status of the currently logged in user has
|
||||||
|
* changed
|
||||||
|
*
|
||||||
|
* @param newStatus the new status
|
||||||
|
* @since Envoy Client v0.3-beta
|
||||||
|
*/
|
||||||
|
public static void changeStatus(UserStatus newStatus) {
|
||||||
|
EventBus.getInstance().dispatch(new OwnStatusChange(newStatus));
|
||||||
|
Context.getInstance().getClient().send(new UserStatusChange(Context.getInstance().getLocalDB().getUser().getID(), newStatus));
|
||||||
|
}
|
||||||
|
}
|
@ -161,44 +161,25 @@
|
|||||||
fitHeight="43.0" fitWidth="43.0" pickOnBounds="true"
|
fitHeight="43.0" fitWidth="43.0" pickOnBounds="true"
|
||||||
preserveRatio="true">
|
preserveRatio="true">
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets left="15.0" top="5.0" />
|
<Insets left="15.0" top="5.0" right="10.0" />
|
||||||
</HBox.margin>
|
</HBox.margin>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<Label id="transparent-background" fx:id="contactLabel"
|
<HBox id="transparent-background" fx:id="ownContactControl">
|
||||||
prefHeight="27.0" prefWidth="134.0">
|
|
||||||
<padding>
|
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
|
||||||
</padding>
|
|
||||||
<font>
|
|
||||||
<Font size="18.0" />
|
|
||||||
</font>
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets left="10.0" top="5.0" />
|
|
||||||
</HBox.margin>
|
|
||||||
</Label>
|
|
||||||
<Region id="transparent-background" prefHeight="77.0"
|
|
||||||
prefWidth="115.0" />
|
|
||||||
<VBox id="transparent-background" alignment="CENTER_RIGHT"
|
|
||||||
prefHeight="200.0" prefWidth="100.0" spacing="5.0">
|
|
||||||
<children>
|
<children>
|
||||||
<Button fx:id="settingsButton" mnemonicParsing="true"
|
<Region id="transparent-background" prefWidth="120"
|
||||||
|
fx:id="spaceBetweenUserAndSettingsButton" />
|
||||||
|
<Button fx:id="settingsButton" mnemonicParsing="false"
|
||||||
onAction="#settingsButtonClicked" prefHeight="30.0"
|
onAction="#settingsButtonClicked" prefHeight="30.0"
|
||||||
prefWidth="30.0" text="">
|
prefWidth="30.0" text="" alignment="CENTER">
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
<VBox.margin>
|
<HBox.margin>
|
||||||
<Insets />
|
<Insets bottom="35.0" left="5.0" top="35.0"/>
|
||||||
</VBox.margin>
|
</HBox.margin>
|
||||||
</Button>
|
</Button>
|
||||||
</children>
|
</children>
|
||||||
<HBox.margin>
|
</HBox>
|
||||||
<Insets right="10.0" />
|
|
||||||
</HBox.margin>
|
|
||||||
<opaqueInsets>
|
|
||||||
<Insets />
|
|
||||||
</opaqueInsets>
|
|
||||||
</VBox>
|
|
||||||
</children>
|
</children>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets bottom="1.0" right="1.0" />
|
<Insets bottom="1.0" right="1.0" />
|
||||||
|
This construction is complicated even for my standards.
What about "Signifies a manual status change of the client user".