Browse Source

Added unlock success message (references #939)

Sebastian Stenzel 5 years ago
parent
commit
4afb9d86c7

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -6,6 +6,7 @@ public enum FxmlFile {
 	ADDVAULT_EXISTING("/fxml/addvault_existing.fxml"), //
 	PREFERENCES("/fxml/preferences.fxml"), //
 	UNLOCK("/fxml/unlock2.fxml"), // TODO rename
+	UNLOCK_SUCCESS("/fxml/unlock_success.fxml"),
 	;
 
 	private final String filename;

+ 24 - 3
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockController.java

@@ -1,21 +1,28 @@
 package org.cryptomator.ui.unlock;
 
+import dagger.Lazy;
 import javafx.beans.binding.Bindings;
 import javafx.beans.binding.ObjectBinding;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
 import javafx.fxml.FXML;
+import javafx.scene.Scene;
 import javafx.scene.control.Alert;
 import javafx.scene.control.ButtonType;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.ContentDisplay;
 import javafx.stage.Stage;
 import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.cryptolib.api.InvalidPassphraseException;
 import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
 import org.cryptomator.keychain.KeychainAccess;
 import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.common.Tasks;
 import org.cryptomator.ui.controls.SecPasswordField;
-import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.ui.util.DialogBuilderUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,17 +46,21 @@ public class UnlockController implements FxController {
 	private final ObjectBinding<ContentDisplay> unlockButtonState;
 	private final Optional<KeychainAccess> keychainAccess;
 	private final ResourceBundle resourceBundle;
+	private final Lazy<Scene> successScene;
+	private final BooleanProperty unlockButtonDisabled;
 	public SecPasswordField passwordField;
 	public CheckBox savePassword;
 
 	@Inject
-	public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, ResourceBundle resourceBundle) {
+	public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, Optional<KeychainAccess> keychainAccess, ResourceBundle resourceBundle, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene) {
 		this.window = window;
 		this.vault = vault;
 		this.executor = executor;
 		this.unlockButtonState = Bindings.createObjectBinding(this::getUnlockButtonState, vault.stateProperty());
 		this.keychainAccess = keychainAccess;
 		this.resourceBundle = resourceBundle;
+		this.successScene = successScene;
+		this.unlockButtonDisabled = new SimpleBooleanProperty();
 	}
 
 	public void initialize() {
@@ -58,6 +69,7 @@ public class UnlockController implements FxController {
 		} else {
 			savePassword.setDisable(true);
 		}
+		unlockButtonDisabled.bind(vault.stateProperty().isNotEqualTo(Vault.State.LOCKED).or(passwordField.textProperty().isEmpty()));
 	}
 
 	@FXML
@@ -68,6 +80,7 @@ public class UnlockController implements FxController {
 
 	@FXML
 	public void unlock() {
+		LOG.trace("UnlockController.unlock()");
 		CharSequence password = passwordField.getCharacters();
 		vault.setState(Vault.State.PROCESSING);
 		Tasks.create(() -> {
@@ -79,7 +92,7 @@ public class UnlockController implements FxController {
 			vault.setState(Vault.State.UNLOCKED);
 			passwordField.swipe();
 			LOG.info("Unlock of '{}' succeeded.", vault.getDisplayableName());
-			window.close();
+			window.setScene(successScene.get());
 		}).onError(InvalidPassphraseException.class, e -> {
 			passwordField.selectAll();
 			passwordField.requestFocus();
@@ -160,4 +173,12 @@ public class UnlockController implements FxController {
 				return ContentDisplay.TEXT_ONLY;
 		}
 	}
+
+	public ReadOnlyBooleanProperty unlockButtonDisabledProperty() {
+		return unlockButtonDisabled;
+	}
+
+	public boolean isUnlockButtonDisabled() {
+		return unlockButtonDisabled.get();
+	}
 }

+ 14 - 1
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java

@@ -44,7 +44,15 @@ abstract class UnlockModule {
 	static Scene provideUnlockScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
 		return fxmlLoaders.createScene("/fxml/unlock2.fxml"); // TODO rename fxml file
 	}
-	
+
+	@Provides
+	@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
+	@UnlockScoped
+	static Scene provideUnlockSuccessScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene("/fxml/unlock_success.fxml");
+	}
+
+
 	// ------------------
 
 	@Binds
@@ -52,5 +60,10 @@ abstract class UnlockModule {
 	@FxControllerKey(UnlockController.class)
 	abstract FxController bindUnlockController(UnlockController controller);
 
+	@Binds
+	@IntoMap
+	@FxControllerKey(UnlockSuccessController.class)
+	abstract FxController bindUnlockSuccessController(UnlockSuccessController controller);
+
 
 }

+ 71 - 0
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSuccessController.java

@@ -0,0 +1,71 @@
+package org.cryptomator.ui.unlock;
+
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.scene.control.ContentDisplay;
+import javafx.stage.Stage;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.Tasks;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.util.concurrent.ExecutorService;
+
+@UnlockScoped
+public class UnlockSuccessController implements FxController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(UnlockSuccessController.class);
+
+	private final Stage window;
+	private final Vault vault;
+	private final ExecutorService executor;
+	private final ObjectProperty<ContentDisplay> revealButtonState;
+
+	@Inject
+	public UnlockSuccessController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor) {
+		this.window = window;
+		this.vault = vault;
+		this.executor = executor;
+		this.revealButtonState = new SimpleObjectProperty<>(ContentDisplay.TEXT_ONLY);
+	}
+
+
+	public void close() {
+		LOG.trace("UnlockSuccessController.close()");
+		window.close();
+	}
+
+	public void revealAndClose() {
+		LOG.trace("UnlockSuccessController.revealAndClose()");
+		revealButtonState.set(ContentDisplay.LEFT);
+		Tasks.create(() -> {
+			vault.reveal();
+		}).onSuccess(() -> {
+			window.close();
+		}).onError(InvalidPassphraseException.class, e -> {
+			// TODO
+			LOG.warn("Reveal failed.", e);
+		}).andFinally(() -> {
+			revealButtonState.set(ContentDisplay.TEXT_ONLY);
+		}).runOnce(executor);
+	}
+
+	/* Getter/Setter */
+
+	public Vault getVault() {
+		return vault;
+	}
+
+	public ReadOnlyObjectProperty<ContentDisplay> revealButtonStateProperty() {
+		return revealButtonState;
+	}
+
+	public ContentDisplay getRevealButtonState() {
+		return revealButtonState.get();
+	}
+
+}

+ 1 - 1
main/ui/src/main/resources/fxml/unlock2.fxml

@@ -28,7 +28,7 @@
 		<HBox>
 			<Button text="TODO cancel" cancelButton="true" onAction="#cancel"/>
 			<Region HBox.hgrow="ALWAYS"/>
-			<Button text="TODO unlock" defaultButton="true" onAction="#unlock" contentDisplay="${controller.unlockButtonState}" disable="${passwordField.text.empty}">
+			<Button text="TODO unlock" defaultButton="true" onAction="#unlock" contentDisplay="${controller.unlockButtonState}" disable="${controller.unlockButtonDisabled}">
 				<graphic>
 					<ProgressIndicator progress="-1" prefWidth="12" prefHeight="12"/>
 				</graphic>

+ 34 - 0
main/ui/src/main/resources/fxml/unlock_success.fxml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ProgressIndicator?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Region?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Text?>
+<?import javafx.scene.text.TextFlow?>
+<VBox xmlns="http://javafx.com/javafx"
+	  xmlns:fx="http://javafx.com/fxml"
+	  fx:controller="org.cryptomator.ui.unlock.UnlockSuccessController"
+	  minWidth="300"
+	  spacing="6">
+	<padding>
+		<Insets bottom="6.0" left="6.0" right="6.0" top="6.0"/>
+	</padding>
+	<children>
+		<TextFlow styleClass="text-flow">
+			<Text text="${controller.vault.displayableName}"/>
+			<Text text="TODO unlocked successfully! "/>
+		</TextFlow>
+		<HBox>
+			<Button text="TODO done" cancelButton="true" onAction="#close"/>
+			<Region HBox.hgrow="ALWAYS"/>
+			<Button text="TODO show me!" defaultButton="true" onAction="#revealAndClose" contentDisplay="${controller.revealButtonState}">
+				<graphic>
+					<ProgressIndicator progress="-1" prefWidth="12" prefHeight="12"/>
+				</graphic>
+			</Button>
+		</HBox>
+	</children>
+</VBox>