Browse Source

Added “unmount without lock” to UnlockedController

Sebastian Stenzel 7 years ago
parent
commit
c8dadca564

+ 69 - 53
main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockedController.java

@@ -10,10 +10,12 @@ package org.cryptomator.ui.controllers;
 
 import static java.lang.String.format;
 
+import java.io.IOException;
 import java.util.Optional;
 
 import javax.inject.Inject;
 
+import org.cryptomator.frontend.webdav.ServerLifecycleException;
 import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
 import org.cryptomator.ui.l10n.Localization;
 import org.cryptomator.ui.model.Vault;
@@ -23,6 +25,8 @@ import org.fxmisc.easybind.EasyBind;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.util.concurrent.Runnables;
+
 import javafx.animation.Animation;
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
@@ -82,6 +86,9 @@ public class UnlockedController implements ViewController {
 	@FXML
 	private MenuItem mountVaultMenuItem;
 
+	@FXML
+	private MenuItem unmountVaultMenuItem;
+
 	@FXML
 	private MenuItem revealVaultMenuItem;
 
@@ -96,8 +103,9 @@ public class UnlockedController implements ViewController {
 
 	@Override
 	public void initialize() {
-		revealVaultMenuItem.disableProperty().bind(vaultMounted.not());
 		mountVaultMenuItem.disableProperty().bind(vaultMounted);
+		unmountVaultMenuItem.disableProperty().bind(vaultMounted.not());
+		revealVaultMenuItem.disableProperty().bind(vaultMounted.not());
 
 		EasyBind.subscribe(vault, this::vaultChanged);
 		EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected);
@@ -124,61 +132,16 @@ public class UnlockedController implements ViewController {
 
 	@FXML
 	private void didClickLockVault(ActionEvent event) {
-		regularLockVault();
-	}
-
-	private void regularLockVault() {
-		asyncTaskService.asyncTaskOf(() -> {
-			vault.get().unmount();
-			vault.get().lock();
-		}).onSuccess(() -> {
-			listener.ifPresent(listener -> listener.didLock(this));
-			LOG.trace("Regular lock succeeded");
-		}).onError(Exception.class, e -> {
-			onRegularLockVaultFailed(e);
-		}).run();
+		regularUnmountVault(this::lockVault);
 	}
 
-	private void forcedLockVault() {
-		asyncTaskService.asyncTaskOf(() -> {
-			vault.get().unmountForced();
+	private void lockVault() {
+		try {
 			vault.get().lock();
-		}).onSuccess(() -> {
-			listener.ifPresent(listener -> listener.didLock(this));
-			LOG.trace("Forced lock succeeded");
-		}).onError(Exception.class, e -> {
-			onForcedLockVaultFailed(e);
-		}).run();
-	}
-
-	private void onRegularLockVaultFailed(Exception e) {
-		if (vault.get().supportsForcedUnmount()) {
-			LOG.trace("Regular unmount failed", e);
-			Alert confirmDialog = DialogBuilderUtil.buildYesNoDialog( //
-					format(localization.getString("unlocked.lock.force.confirmation.title"), vault.get().name().getValue()), //
-					localization.getString("unlocked.lock.force.confirmation.header"), //
-					localization.getString("unlocked.lock.force.confirmation.content"), //
-					ButtonType.NO);
-
-			Optional<ButtonType> choice = confirmDialog.showAndWait();
-			if (ButtonType.YES.equals(choice.get())) {
-				forcedLockVault();
-			} else {
-				LOG.trace("Unmount cancelled", e);
-			}
-		} else {
-			LOG.error("Regular unmount failed", e);
-			showUnmountFailedMessage();
+		} catch (ServerLifecycleException | IOException e) {
+			LOG.error("Lock failed", e);
 		}
-	}
-
-	private void onForcedLockVaultFailed(Exception e) {
-		LOG.error("Forced unmount failed", e);
-		showUnmountFailedMessage();
-	}
-
-	private void showUnmountFailedMessage() {
-		messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
+		listener.ifPresent(listener -> listener.didLock(this));
 	}
 
 	@FXML
@@ -200,16 +163,67 @@ public class UnlockedController implements ViewController {
 		asyncTaskService.asyncTaskOf(() -> {
 			vault.mount();
 		}).onSuccess(() -> {
+			LOG.trace("Mount succeeded.");
 			messageLabel.setText(null);
 			if (vault.getVaultSettings().revealAfterMount().get()) {
 				revealVault(vault);
 			}
 		}).onError(CommandFailedException.class, e -> {
+			LOG.error("Mount failed.", e);
 			// TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas?
 			messageLabel.setText(localization.getString("unlocked.label.mountFailed"));
 		}).run();
 	}
 
+	@FXML
+	public void didClickUnmountVault(ActionEvent event) {
+		regularUnmountVault(Runnables.doNothing());
+	}
+
+	private void regularUnmountVault(Runnable onSuccess) {
+		asyncTaskService.asyncTaskOf(() -> {
+			vault.get().unmount();
+		}).onSuccess(() -> {
+			LOG.trace("Regular unmount succeeded.");
+			onSuccess.run();
+		}).onError(Exception.class, e -> {
+			onRegularUnmountVaultFailed(e, onSuccess);
+		}).run();
+	}
+
+	private void forcedUnmountVault(Runnable onSuccess) {
+		asyncTaskService.asyncTaskOf(() -> {
+			vault.get().unmountForced();
+		}).onSuccess(() -> {
+			LOG.trace("Forced unmount succeeded.");
+			onSuccess.run();
+		}).onError(Exception.class, e -> {
+			LOG.error("Forced unmount failed.", e);
+			messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
+		}).run();
+	}
+
+	private void onRegularUnmountVaultFailed(Exception e, Runnable onSuccess) {
+		if (vault.get().supportsForcedUnmount()) {
+			LOG.trace("Regular unmount failed.", e);
+			Alert confirmDialog = DialogBuilderUtil.buildYesNoDialog( //
+					format(localization.getString("unlocked.lock.force.confirmation.title"), vault.get().name().getValue()), //
+					localization.getString("unlocked.lock.force.confirmation.header"), //
+					localization.getString("unlocked.lock.force.confirmation.content"), //
+					ButtonType.NO);
+
+			Optional<ButtonType> choice = confirmDialog.showAndWait();
+			if (ButtonType.YES.equals(choice.get())) {
+				forcedUnmountVault(onSuccess);
+			} else {
+				LOG.trace("Unmount cancelled.", e);
+			}
+		} else {
+			LOG.error("Regular unmount failed.", e);
+			messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
+		}
+	}
+
 	@FXML
 	private void didClickRevealVault(ActionEvent event) {
 		revealVault(vault.get());
@@ -219,8 +233,10 @@ public class UnlockedController implements ViewController {
 		asyncTaskService.asyncTaskOf(() -> {
 			vault.reveal();
 		}).onSuccess(() -> {
+			LOG.trace("Reveal succeeded.");
 			messageLabel.setText(null);
-		}).onError(CommandFailedException.class, () -> {
+		}).onError(CommandFailedException.class, e -> {
+			LOG.error("Reveal failed.", e);
 			messageLabel.setText(localization.getString("unlocked.label.revealFailed"));
 		}).run();
 	}

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/model/Vault.java

@@ -162,7 +162,7 @@ public class Vault {
 		return mount != null && mount.forced().isPresent();
 	}
 
-	public synchronized void lock() throws Exception {
+	public synchronized void lock() throws ServerLifecycleException, IOException {
 		if (servlet != null) {
 			servlet.stop();
 		}

+ 3 - 0
main/ui/src/main/resources/fxml/unlocked.fxml

@@ -31,6 +31,9 @@
 				<MenuItem fx:id="mountVaultMenuItem" text="%unlocked.moreOptions.mount" onAction="#didClickMountVault">
 					<graphic><Label text="&#xf139;" styleClass="ionicons"/></graphic>
 				</MenuItem>
+				<MenuItem fx:id="unmountVaultMenuItem" text="%unlocked.moreOptions.unmount" onAction="#didClickUnmountVault">
+					<graphic><Label text="&#xf131;" styleClass="ionicons"/></graphic>
+				</MenuItem>
 				<MenuItem fx:id="revealVaultMenuItem" text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
 					<graphic><Label text="&#xf133;" styleClass="ionicons"/></graphic>
 				</MenuItem>

+ 1 - 0
main/ui/src/main/resources/localization/en.txt

@@ -90,6 +90,7 @@ changePassword.errorMessage.decryptionFailed=Decryption failed
 # unlocked.fxml
 unlocked.button.lock=Lock Vault
 unlocked.moreOptions.mount=Mount Drive
+unlocked.moreOptions.unmount=Eject Drive
 unlocked.moreOptions.reveal=Reveal Drive
 unlocked.moreOptions.copyUrl=Copy WebDAV URL
 unlocked.label.mountFailed=Connecting drive failed