Converted the login dialog into a scene
This commit is contained in:
		@@ -29,10 +29,45 @@ import envoy.event.EventBus;
 | 
			
		||||
 */
 | 
			
		||||
public final class SceneContext {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Contains information about different scenes and their FXML resource files.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @author Kai S. K. Engelbart
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public static enum SceneInfo {
 | 
			
		||||
 | 
			
		||||
		CHAT_SCENE("/fxml/ChatScene.fxml"), SETTINGS_SCENE("/fxml/SettingsScene.fxml"), CONTACT_SEARCH_SCENE("/fxml/ContactSearchScene.fxml");
 | 
			
		||||
		/**
 | 
			
		||||
		 * The main scene in which chats are displayed.
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @since Envoy Client v0.1-beta
 | 
			
		||||
		 */
 | 
			
		||||
		CHAT_SCENE("/fxml/ChatScene.fxml"),
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * The scene in which settings are displayed.
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @since Envoy Client v0.1-beta
 | 
			
		||||
		 */
 | 
			
		||||
		SETTINGS_SCENE("/fxml/SettingsScene.fxml"),
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * The scene in which the contact search is displayed.
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @since Envoy Client v0.1-beta
 | 
			
		||||
		 */
 | 
			
		||||
		CONTACT_SEARCH_SCENE("/fxml/ContactSearchScene.fxml"),
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * The scene in which the login screen is displayed.
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @since Envoy Client v0.1-beta
 | 
			
		||||
		 */
 | 
			
		||||
		LOGIN_SCENE("/fxml/LoginScene.fxml");
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * The path to the FXML resource.
 | 
			
		||||
		 */
 | 
			
		||||
		public final String path;
 | 
			
		||||
 | 
			
		||||
		SceneInfo(String path) { this.path = path; }
 | 
			
		||||
@@ -59,20 +94,24 @@ public final class SceneContext {
 | 
			
		||||
	 * Loads a new scene specified by a scene info.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param sceneInfo specifies the scene to load
 | 
			
		||||
	 * @throws IOException if the loading process fails
 | 
			
		||||
	 * @throws RuntimeException if the loading process fails
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public void load(SceneInfo sceneInfo) throws IOException {
 | 
			
		||||
	public void load(SceneInfo sceneInfo) {
 | 
			
		||||
		loader.setRoot(null);
 | 
			
		||||
		loader.setController(null);
 | 
			
		||||
 | 
			
		||||
		final var	rootNode	= (Parent) loader.load(getClass().getResourceAsStream(sceneInfo.path));
 | 
			
		||||
		final var	scene		= new Scene(rootNode);
 | 
			
		||||
		try {
 | 
			
		||||
			final var	rootNode	= (Parent) loader.load(getClass().getResourceAsStream(sceneInfo.path));
 | 
			
		||||
			final var	scene		= new Scene(rootNode);
 | 
			
		||||
 | 
			
		||||
		sceneStack.push(scene);
 | 
			
		||||
		stage.setScene(scene);
 | 
			
		||||
		applyCSS();
 | 
			
		||||
		stage.show();
 | 
			
		||||
			sceneStack.push(scene);
 | 
			
		||||
			stage.setScene(scene);
 | 
			
		||||
			applyCSS();
 | 
			
		||||
			stage.show();
 | 
			
		||||
		} catch (IOException e) {
 | 
			
		||||
			throw new RuntimeException(e);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -104,4 +143,10 @@ public final class SceneContext {
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public <T> T getController() { return loader.getController(); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return the stage in which the scenes are displayed
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public Stage getStage() { return stage; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package envoy.client.ui;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
@@ -14,11 +13,9 @@ import javafx.stage.Stage;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.*;
 | 
			
		||||
import envoy.client.net.Client;
 | 
			
		||||
import envoy.client.net.WriteProxy;
 | 
			
		||||
import envoy.client.ui.controller.ChatScene;
 | 
			
		||||
import envoy.client.ui.SceneContext.SceneInfo;
 | 
			
		||||
import envoy.client.ui.controller.LoginScene;
 | 
			
		||||
import envoy.data.Message;
 | 
			
		||||
import envoy.data.User;
 | 
			
		||||
import envoy.data.User.UserStatus;
 | 
			
		||||
import envoy.exception.EnvoyException;
 | 
			
		||||
import envoy.util.EnvoyLog;
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +31,6 @@ public final class Startup extends Application {
 | 
			
		||||
 | 
			
		||||
	private LocalDB			localDB;
 | 
			
		||||
	private Client			client;
 | 
			
		||||
	private WriteProxy		writeProxy;
 | 
			
		||||
	private Cache<Message>	cache;
 | 
			
		||||
 | 
			
		||||
	private static final ClientConfig	config	= ClientConfig.getInstance();
 | 
			
		||||
@@ -86,53 +82,12 @@ public final class Startup extends Application {
 | 
			
		||||
		client	= new Client();
 | 
			
		||||
		cache	= new Cache<>();
 | 
			
		||||
 | 
			
		||||
		// Try to connect to the server
 | 
			
		||||
		new LoginDialog(client, localDB, cache).showAndWait();
 | 
			
		||||
 | 
			
		||||
		// Set client user in local database
 | 
			
		||||
		localDB.setUser(client.getSender());
 | 
			
		||||
 | 
			
		||||
		// Initialize chats in local database
 | 
			
		||||
		try {
 | 
			
		||||
			localDB.initializeUserStorage();
 | 
			
		||||
			localDB.loadUserData();
 | 
			
		||||
		} catch (final FileNotFoundException e) {
 | 
			
		||||
			// The local database file has not yet been created, probably first login
 | 
			
		||||
		} catch (final Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
			new Alert(AlertType.ERROR, "Error while loading local database: " + e + "\nChats will not be stored locally.").showAndWait();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Initialize write proxy
 | 
			
		||||
		writeProxy = client.createWriteProxy(localDB);
 | 
			
		||||
 | 
			
		||||
		if (client.isOnline()) {
 | 
			
		||||
 | 
			
		||||
			// Save all users to the local database and flush cache
 | 
			
		||||
			localDB.setUsers(client.getUsers());
 | 
			
		||||
			writeProxy.flushCache();
 | 
			
		||||
		} else
 | 
			
		||||
			// Set all contacts to offline mode
 | 
			
		||||
			localDB.getUsers()
 | 
			
		||||
				.values()
 | 
			
		||||
				.stream()
 | 
			
		||||
				.filter(User.class::isInstance)
 | 
			
		||||
				.map(User.class::cast)
 | 
			
		||||
				.forEach(u -> u.setStatus(UserStatus.OFFLINE));
 | 
			
		||||
 | 
			
		||||
		// Prepare stage and load ChatScene
 | 
			
		||||
		final var sceneContext = new SceneContext(stage);
 | 
			
		||||
		sceneContext.load(SceneContext.SceneInfo.CHAT_SCENE);
 | 
			
		||||
		sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
 | 
			
		||||
 | 
			
		||||
		stage.setTitle("Envoy");
 | 
			
		||||
		stage.setMinHeight(400);
 | 
			
		||||
		stage.setMinWidth(350);
 | 
			
		||||
		stage.getIcons().add(IconUtil.load("/icons/envoy_logo.png"));
 | 
			
		||||
		stage.show();
 | 
			
		||||
 | 
			
		||||
		// Relay unread messages from cache
 | 
			
		||||
		if (cache != null && client.isOnline()) cache.relay();
 | 
			
		||||
		final var sceneContext = new SceneContext(stage);
 | 
			
		||||
		sceneContext.load(SceneInfo.LOGIN_SCENE);
 | 
			
		||||
		sceneContext.<LoginScene>getController().initializeData(client, localDB, cache, sceneContext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
@@ -119,6 +119,14 @@ public final class ChatScene {
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param sceneContext the scene context used to load other scenes
 | 
			
		||||
	 * @param localDB      the local database form which chats and users are loaded
 | 
			
		||||
	 * @param client       the client used to request ID generators
 | 
			
		||||
	 * @param writeProxy   the write proxy used to send messages and other data to
 | 
			
		||||
	 *                     the server
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public void initializeData(SceneContext sceneContext, LocalDB localDB, Client client, WriteProxy writeProxy) {
 | 
			
		||||
		this.sceneContext	= sceneContext;
 | 
			
		||||
		this.localDB		= localDB;
 | 
			
		||||
@@ -158,22 +166,14 @@ public final class ChatScene {
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void settingsButtonClicked() {
 | 
			
		||||
		try {
 | 
			
		||||
			sceneContext.load(SceneContext.SceneInfo.SETTINGS_SCENE);
 | 
			
		||||
			sceneContext.<SettingsScene>getController().initializeData(sceneContext);
 | 
			
		||||
		} catch (final IOException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		sceneContext.load(SceneContext.SceneInfo.SETTINGS_SCENE);
 | 
			
		||||
		sceneContext.<SettingsScene>getController().initializeData(sceneContext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void addContactButtonClicked() {
 | 
			
		||||
		try {
 | 
			
		||||
			sceneContext.load(SceneContext.SceneInfo.CONTACT_SEARCH_SCENE);
 | 
			
		||||
			sceneContext.<ContactSearchScene>getController().initializeData(sceneContext);
 | 
			
		||||
		} catch (final IOException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		sceneContext.load(SceneContext.SceneInfo.CONTACT_SEARCH_SCENE);
 | 
			
		||||
		sceneContext.<ContactSearchScene>getController().initializeData(sceneContext);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,24 @@
 | 
			
		||||
package envoy.client.ui;
 | 
			
		||||
package envoy.client.ui.controller;
 | 
			
		||||
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.concurrent.TimeoutException;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import javafx.application.Platform;
 | 
			
		||||
import javafx.event.ActionEvent;
 | 
			
		||||
import javafx.fxml.FXML;
 | 
			
		||||
import javafx.fxml.FXMLLoader;
 | 
			
		||||
import javafx.scene.control.*;
 | 
			
		||||
import javafx.scene.control.Alert.AlertType;
 | 
			
		||||
import javafx.stage.Stage;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.Cache;
 | 
			
		||||
import envoy.client.data.ClientConfig;
 | 
			
		||||
import envoy.client.data.LocalDB;
 | 
			
		||||
import envoy.client.net.Client;
 | 
			
		||||
import envoy.client.ui.SceneContext;
 | 
			
		||||
import envoy.data.LoginCredentials;
 | 
			
		||||
import envoy.data.Message;
 | 
			
		||||
import envoy.data.User;
 | 
			
		||||
import envoy.data.User.UserStatus;
 | 
			
		||||
import envoy.event.EventBus;
 | 
			
		||||
import envoy.event.HandshakeRejectionEvent;
 | 
			
		||||
import envoy.exception.EnvoyException;
 | 
			
		||||
@@ -32,7 +32,7 @@ import envoy.util.EnvoyLog;
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy Client v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public final class LoginDialog extends Dialog<Void> {
 | 
			
		||||
public final class LoginScene {
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private TextField userTextField;
 | 
			
		||||
@@ -49,77 +49,18 @@ public final class LoginDialog extends Dialog<Void> {
 | 
			
		||||
	@FXML
 | 
			
		||||
	private CheckBox registerCheckBox;
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private CheckBox offlineCheckBox;
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private Label connectionLabel;
 | 
			
		||||
 | 
			
		||||
	private final Client			client;
 | 
			
		||||
	private final LocalDB			localDB;
 | 
			
		||||
	private final Cache<Message>	receivedMessageCache;
 | 
			
		||||
	private Client			client;
 | 
			
		||||
	private LocalDB			localDB;
 | 
			
		||||
	private Cache<Message>	receivedMessageCache;
 | 
			
		||||
	private SceneContext	sceneContext;
 | 
			
		||||
 | 
			
		||||
	private static final Logger			logger		= EnvoyLog.getLogger(LoginDialog.class);
 | 
			
		||||
	private static final Logger			logger		= EnvoyLog.getLogger(LoginScene.class);
 | 
			
		||||
	private static final EventBus		eventBus	= EventBus.getInstance();
 | 
			
		||||
	private static final ClientConfig	config		= ClientConfig.getInstance();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Loads the login dialog using the FXML file {@code LoginDialog.fxml}.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param client               the client used to perform the handshake
 | 
			
		||||
	 * @param localDB              the local database used for offline login
 | 
			
		||||
	 * @param receivedMessageCache the cache storing messages received during
 | 
			
		||||
	 *                             the handshake
 | 
			
		||||
	 * @throws IOException if an exception occurs during loading
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public LoginDialog(Client client, LocalDB localDB, Cache<Message> receivedMessageCache) throws IOException {
 | 
			
		||||
		this.client					= client;
 | 
			
		||||
		this.localDB				= localDB;
 | 
			
		||||
		this.receivedMessageCache	= receivedMessageCache;
 | 
			
		||||
 | 
			
		||||
		// Prepare handshake
 | 
			
		||||
		localDB.loadIDGenerator();
 | 
			
		||||
 | 
			
		||||
		final var loader = new FXMLLoader(getClass().getResource("/fxml/LoginDialog.fxml"));
 | 
			
		||||
		loader.setController(this);
 | 
			
		||||
		final var dialogPane = loader.<DialogPane>load();
 | 
			
		||||
 | 
			
		||||
		((Stage) getDialogPane().getScene().getWindow()).getIcons().add(IconUtil.load("/icons/envoy_logo.png"));
 | 
			
		||||
 | 
			
		||||
		// Configure dialog buttons
 | 
			
		||||
		dialogPane.getButtonTypes().addAll(ButtonType.CLOSE, ButtonType.OK);
 | 
			
		||||
 | 
			
		||||
		// Close button
 | 
			
		||||
		dialogPane.lookupButton(ButtonType.CLOSE).addEventHandler(ActionEvent.ACTION, e -> abortLogin());
 | 
			
		||||
 | 
			
		||||
		// Login button
 | 
			
		||||
		final var loginButton = (Button) dialogPane.lookupButton(ButtonType.OK);
 | 
			
		||||
		loginButton.setText("Login");
 | 
			
		||||
		loginButton.addEventFilter(ActionEvent.ACTION, e -> {
 | 
			
		||||
			e.consume();
 | 
			
		||||
 | 
			
		||||
			// Prevent registration with unequal passwords
 | 
			
		||||
			if (registerCheckBox.isSelected() && !passwordField.getText().equals(repeatPasswordField.getText())) {
 | 
			
		||||
				clearPasswordFields();
 | 
			
		||||
				new Alert(AlertType.ERROR, "The entered password is unequal to the repeated one").showAndWait();
 | 
			
		||||
			} else {
 | 
			
		||||
				final var credentials = new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(),
 | 
			
		||||
						registerCheckBox.isSelected());
 | 
			
		||||
				if (!offlineCheckBox.isSelected()) performHandshake(credentials);
 | 
			
		||||
				else attemptOfflineMode(credentials);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// Perform automatic login if configured
 | 
			
		||||
		setOnShown(e -> { if (config.hasLoginCredentials()) performHandshake(config.getLoginCredentials()); });
 | 
			
		||||
 | 
			
		||||
		setDialogPane(dialogPane);
 | 
			
		||||
 | 
			
		||||
		// Set initial cursor
 | 
			
		||||
		Platform.runLater(userTextField::requestFocus);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void initialize() {
 | 
			
		||||
		connectionLabel.setText("Server: " + config.getServer() + ":" + config.getPort());
 | 
			
		||||
@@ -129,6 +70,50 @@ public final class LoginDialog extends Dialog<Void> {
 | 
			
		||||
				e -> Platform.runLater(() -> { clearPasswordFields(); new Alert(AlertType.ERROR, e.get()).showAndWait(); }));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Loads the login dialog using the FXML file {@code LoginDialog.fxml}.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param client               the client used to perform the handshake
 | 
			
		||||
	 * @param localDB              the local database used for offline login
 | 
			
		||||
	 * @param receivedMessageCache the cache storing messages received during
 | 
			
		||||
	 *                             the 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<Message> receivedMessageCache, SceneContext sceneContext) {
 | 
			
		||||
		this.client					= client;
 | 
			
		||||
		this.localDB				= localDB;
 | 
			
		||||
		this.receivedMessageCache	= receivedMessageCache;
 | 
			
		||||
		this.sceneContext			= sceneContext;
 | 
			
		||||
 | 
			
		||||
		// Prepare handshake
 | 
			
		||||
		localDB.loadIDGenerator();
 | 
			
		||||
 | 
			
		||||
		// Set initial cursor
 | 
			
		||||
		userTextField.requestFocus();
 | 
			
		||||
 | 
			
		||||
		// Perform automatic login if configured
 | 
			
		||||
		if (config.hasLoginCredentials()) performHandshake(config.getLoginCredentials());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void loginButtonPressed() {
 | 
			
		||||
 | 
			
		||||
		// Prevent registration with unequal passwords
 | 
			
		||||
		if (registerCheckBox.isSelected() && !passwordField.getText().equals(repeatPasswordField.getText())) {
 | 
			
		||||
			clearPasswordFields();
 | 
			
		||||
			new Alert(AlertType.ERROR, "The entered password is unequal to the repeated one").showAndWait();
 | 
			
		||||
		} else {
 | 
			
		||||
			performHandshake(new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(), registerCheckBox.isSelected()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void offlineModeButtonPressed() {
 | 
			
		||||
		attemptOfflineMode(new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(), false));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void registerCheckboxChanged() {
 | 
			
		||||
 | 
			
		||||
@@ -139,12 +124,18 @@ public final class LoginDialog extends Dialog<Void> {
 | 
			
		||||
		clearPasswordFields();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void abortLogin() {
 | 
			
		||||
		logger.info("The login process has been cancelled. Exiting...");
 | 
			
		||||
		System.exit(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void performHandshake(LoginCredentials credentials) {
 | 
			
		||||
		try {
 | 
			
		||||
			client.performHandshake(credentials, receivedMessageCache);
 | 
			
		||||
			if (client.isOnline()) {
 | 
			
		||||
				client.initReceiver(localDB, receivedMessageCache);
 | 
			
		||||
				Platform.runLater(this::hide);
 | 
			
		||||
				loadChatScene();
 | 
			
		||||
			}
 | 
			
		||||
		} catch (IOException | InterruptedException | TimeoutException e) {
 | 
			
		||||
			logger.warning("Could not connect to server: " + e);
 | 
			
		||||
@@ -161,20 +152,54 @@ public final class LoginDialog extends Dialog<Void> {
 | 
			
		||||
			if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
 | 
			
		||||
			client.setSender(clientUser);
 | 
			
		||||
			new Alert(AlertType.WARNING, "A connection to the server could not be established. Starting in offline mode.").showAndWait();
 | 
			
		||||
			hide();
 | 
			
		||||
			loadChatScene();
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			new Alert(AlertType.ERROR, "Client error: " + e).showAndWait();
 | 
			
		||||
			System.exit(1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void loadChatScene() {
 | 
			
		||||
 | 
			
		||||
		// Set client user in local database
 | 
			
		||||
		localDB.setUser(client.getSender());
 | 
			
		||||
 | 
			
		||||
		// Initialize chats in local database
 | 
			
		||||
		try {
 | 
			
		||||
			localDB.initializeUserStorage();
 | 
			
		||||
			localDB.loadUserData();
 | 
			
		||||
		} catch (final FileNotFoundException e) {
 | 
			
		||||
			// The local database file has not yet been created, probably first login
 | 
			
		||||
		} catch (final Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
			new Alert(AlertType.ERROR, "Error while loading local database: " + e + "\nChats will not be stored locally.").showAndWait();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Initialize write proxy
 | 
			
		||||
		final var writeProxy = client.createWriteProxy(localDB);
 | 
			
		||||
 | 
			
		||||
		if (client.isOnline()) {
 | 
			
		||||
 | 
			
		||||
			// Save all users to the local database and flush cache
 | 
			
		||||
			localDB.setUsers(client.getUsers());
 | 
			
		||||
			writeProxy.flushCache();
 | 
			
		||||
		} else
 | 
			
		||||
			// Set all contacts to offline mode
 | 
			
		||||
			localDB.getUsers().values().stream().filter(User.class::isInstance).map(User.class::cast).forEach(u -> u.setStatus(UserStatus.OFFLINE));
 | 
			
		||||
 | 
			
		||||
		// Load ChatScene
 | 
			
		||||
		sceneContext.pop();
 | 
			
		||||
		sceneContext.getStage().setMinHeight(400);
 | 
			
		||||
		sceneContext.getStage().setMinWidth(350);
 | 
			
		||||
		sceneContext.load(SceneContext.SceneInfo.CHAT_SCENE);
 | 
			
		||||
		sceneContext.<ChatScene>getController().initializeData(sceneContext, localDB, client, writeProxy);
 | 
			
		||||
 | 
			
		||||
		// Relay unread messages from cache
 | 
			
		||||
		if (receivedMessageCache != null && client.isOnline()) receivedMessageCache.relay();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void clearPasswordFields() {
 | 
			
		||||
		passwordField.clear();
 | 
			
		||||
		repeatPasswordField.clear();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void abortLogin() {
 | 
			
		||||
		logger.info("The login process has been cancelled. Exiting...");
 | 
			
		||||
		System.exit(0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<?import javafx.scene.control.Button?>
 | 
			
		||||
<?import javafx.scene.control.ButtonBar?>
 | 
			
		||||
<?import javafx.scene.control.CheckBox?>
 | 
			
		||||
<?import javafx.scene.control.DialogPane?>
 | 
			
		||||
<?import javafx.scene.control.Label?>
 | 
			
		||||
<?import javafx.scene.control.PasswordField?>
 | 
			
		||||
<?import javafx.scene.control.TextField?>
 | 
			
		||||
@@ -11,10 +12,9 @@
 | 
			
		||||
<?import javafx.scene.layout.VBox?>
 | 
			
		||||
<?import javafx.scene.text.Font?>
 | 
			
		||||
 | 
			
		||||
<DialogPane prefHeight="265.0" prefWidth="545.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
 | 
			
		||||
	<content>
 | 
			
		||||
		<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="217.0" prefWidth="545.0">
 | 
			
		||||
			<children>
 | 
			
		||||
 | 
			
		||||
<VBox prefHeight="206.0" prefWidth="440.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.LoginScene">
 | 
			
		||||
   <children>
 | 
			
		||||
				<Label text="User Login">
 | 
			
		||||
					<font>
 | 
			
		||||
						<Font size="26.0" />
 | 
			
		||||
@@ -40,9 +40,13 @@
 | 
			
		||||
					</children>
 | 
			
		||||
				</GridPane>
 | 
			
		||||
				<CheckBox fx:id="registerCheckBox" mnemonicParsing="true" onAction="#registerCheckboxChanged" prefHeight="17.0" prefWidth="181.0" text="_Register" />
 | 
			
		||||
            <Label fx:id="connectionLabel" />
 | 
			
		||||
            <CheckBox fx:id="offlineCheckBox" layoutX="20.0" layoutY="144.0" mnemonicParsing="true" prefHeight="17.0" prefWidth="181.0" text="_Offline mode" />
 | 
			
		||||
			</children>
 | 
			
		||||
		</VBox>
 | 
			
		||||
	</content>
 | 
			
		||||
</DialogPane>
 | 
			
		||||
      <Label fx:id="connectionLabel" />
 | 
			
		||||
      <ButtonBar prefHeight="40.0" prefWidth="200.0">
 | 
			
		||||
        <buttons>
 | 
			
		||||
            <Button mnemonicParsing="false" onAction="#abortLogin" text="Close" />
 | 
			
		||||
            <Button mnemonicParsing="false" onAction="#offlineModeButtonPressed" text="Offline mode" />
 | 
			
		||||
          <Button defaultButton="true" mnemonicParsing="false" onAction="#loginButtonPressed" text="Login" />
 | 
			
		||||
        </buttons>
 | 
			
		||||
      </ButtonBar>
 | 
			
		||||
   </children>
 | 
			
		||||
</VBox>
 | 
			
		||||
		Reference in New Issue
	
	Block a user