This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/src/main/java/envoy/client/ui/LoginDialog.java

163 lines
5.2 KiB
Java
Raw Normal View History

package envoy.client.ui;
import java.io.IOException;
import java.util.logging.Logger;
import javax.naming.TimeLimitExceededException;
import envoy.client.data.Cache;
import envoy.client.data.ClientConfig;
import envoy.client.data.LocalDB;
import envoy.client.net.Client;
import envoy.data.LoginCredentials;
import envoy.data.Message;
import envoy.data.User;
import envoy.event.EventBus;
import envoy.event.HandshakeRejectionEvent;
import envoy.exception.EnvoyException;
import envoy.util.EnvoyLog;
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;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>LoginDialog.java</strong><br>
* Created: <strong>03.04.2020</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy Client v0.1-beta
*/
public final class LoginDialog extends Dialog<Void> {
@FXML
private TextField userTextField;
@FXML
private PasswordField passwordField;
@FXML
private PasswordField repeatPasswordField;
@FXML
private Label repeatPasswordLabel;
@FXML
private CheckBox registerCheckBox;
private final Client client;
private final LocalDB localDB;
private final Cache<Message> receivedMessageCache;
private static final Logger logger = EnvoyLog.getLogger(LoginDialog.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;
final var loader = new FXMLLoader(getClass().getResource("LoginDialog.fxml"));
loader.setController(this);
final var dialogPane = loader.<DialogPane>load();
// 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
performHandshake(new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(), registerCheckBox.isSelected()));
});
// Perform automatic login if configured
setOnShown(e -> { if (config.hasLoginCredentials()) performHandshake(config.getLoginCredentials()); });
setDialogPane(dialogPane);
}
@FXML
private void initialize() {
// Show an alert after an unsuccessful handshake
eventBus.register(HandshakeRejectionEvent.class,
e -> Platform.runLater(() -> { clearPasswordFields(); new Alert(AlertType.ERROR, e.get()).showAndWait(); }));
// Set initial cursor
userTextField.requestFocus();
}
@FXML
private void registerCheckboxChanged() {
// Make repeat password field and label visible / invisible
repeatPasswordField.setVisible(registerCheckBox.isSelected());
repeatPasswordLabel.setVisible(registerCheckBox.isSelected());
clearPasswordFields();
}
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);
}
} catch (IOException | InterruptedException | TimeLimitExceededException e) {
logger.warning("Could not connect to server. Trying offline mode...");
e.printStackTrace();
try {
// Try entering offline mode
localDB.loadUsers();
User clientUser = (User) localDB.getUsers().get(credentials.getIdentifier());
if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
client.setSender(clientUser);
Platform.runLater(() -> {
new Alert(AlertType.WARNING, "A connection to the server could not be established. Starting in offline mode.\n" + e)
.showAndWait();
hide();
});
} catch (Exception e1) {
Platform.runLater(() -> new Alert(AlertType.ERROR, "Client error: " + e.toString()).showAndWait());
System.exit(1);
}
}
}
private void clearPasswordFields() {
passwordField.clear();
repeatPasswordField.clear();
}
}