Browse Source

reveal OR copy mount point depending on chosen mounter

Sebastian Stenzel 2 years ago
parent
commit
4029f86a0d

+ 1 - 1
.idea/compiler.xml

@@ -45,7 +45,7 @@
   </component>
   <component name="JavacSettings">
     <option name="ADDITIONAL_OPTIONS_OVERRIDE">
-      <module name="cryptomator" options="-Adagger.fastInit=enabled -Adagger.formatGeneratedSource=enabled" />
+      <module name="cryptomator" options="-Adagger.fastInit=enabled -Adagger.formatGeneratedSource=enabled --enable-preview" />
     </option>
   </component>
 </project>

+ 1 - 0
pom.xml

@@ -313,6 +313,7 @@
 					<compilerArgs>
 						<arg>-Adagger.fastInit=enabled</arg>
 						<arg>-Adagger.formatGeneratedSource=enabled</arg>
+						<arg>--enable-preview</arg>
 					</compilerArgs>
 				</configuration>
 			</plugin>

+ 8 - 11
src/main/java/org/cryptomator/common/vaults/Vault.java

@@ -37,6 +37,7 @@ import javax.inject.Named;
 import javafx.beans.Observable;
 import javafx.beans.binding.Bindings;
 import javafx.beans.binding.BooleanBinding;
+import javafx.beans.binding.ObjectBinding;
 import javafx.beans.binding.StringBinding;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.ObjectProperty;
@@ -81,7 +82,7 @@ public class Vault {
 	private final BooleanBinding missing;
 	private final BooleanBinding needsMigration;
 	private final BooleanBinding unknownError;
-	private final StringBinding accessPoint;
+	private final ObjectBinding<Mountpoint> mountPoint;
 	private final BooleanProperty showingStats;
 
 	private AtomicReference<MountHandle> mountHandle = new AtomicReference<>(null);
@@ -105,7 +106,7 @@ public class Vault {
 		this.missing = Bindings.createBooleanBinding(this::isMissing, state);
 		this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
 		this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
-		this.accessPoint = Bindings.createStringBinding(this::getAccessPoint, state);
+		this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
 		this.showingStats = new SimpleBooleanProperty(false);
 	}
 
@@ -317,17 +318,13 @@ public class Vault {
 		return vaultSettings.displayName().get();
 	}
 
-	public StringBinding accessPointProperty() {
-		return accessPoint;
+	public ObjectBinding<Mountpoint> mountPointProperty() {
+		return mountPoint;
 	}
 
-	public String getAccessPoint() {
-		var mountPoint = mountHandle.get().mount.getMountpoint();
-		if (mountPoint instanceof Mountpoint.WithPath m) {
-			return m.path().toString();
-		} else {
-			return mountPoint.uri().toString();
-		}
+	public Mountpoint getMountPoint() {
+		var handle = mountHandle.get();
+		return handle == null ? null : handle.mount.getMountpoint();
 	}
 
 	public StringBinding displayablePathProperty() {

+ 0 - 23
src/main/java/org/cryptomator/ui/common/HostServiceRevealer.java

@@ -1,23 +0,0 @@
-package org.cryptomator.ui.common;
-
-import dagger.Lazy;
-import org.cryptomator.ui.fxapp.FxApplicationScoped;
-
-import javax.inject.Inject;
-import javafx.application.Application;
-import java.nio.file.Path;
-
-@FxApplicationScoped
-public class HostServiceRevealer {
-
-	private final Lazy<Application> application;
-
-	@Inject
-	public HostServiceRevealer(Lazy<Application> application) {
-		this.application = application;
-	}
-
-	public void reveal(Path p) {
-		application.get().getHostServices().showDocument(p.toUri().toString());
-	}
-}

+ 16 - 11
src/main/java/org/cryptomator/ui/common/VaultService.java

@@ -1,13 +1,17 @@
 package org.cryptomator.ui.common;
 
+import dagger.Lazy;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultState;
+import org.cryptomator.integrations.mount.Mountpoint;
 import org.cryptomator.integrations.mount.UnmountFailedException;
 import org.cryptomator.ui.fxapp.FxApplicationScoped;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
+import javafx.application.Application;
+import javafx.application.HostServices;
 import javafx.concurrent.Task;
 import javafx.stage.Stage;
 import java.io.IOException;
@@ -24,13 +28,13 @@ public class VaultService {
 
 	private static final Logger LOG = LoggerFactory.getLogger(VaultService.class);
 
+	private final Lazy<Application> application;
 	private final ExecutorService executorService;
-	private final HostServiceRevealer vaultRevealer;
 
 	@Inject
-	public VaultService(ExecutorService executorService, HostServiceRevealer vaultRevealer) {
+	public VaultService(Lazy<Application> application, ExecutorService executorService) {
+		this.application = application;
 		this.executorService = executorService;
-		this.vaultRevealer = vaultRevealer;
 	}
 
 	public void reveal(Vault vault) {
@@ -43,7 +47,7 @@ public class VaultService {
 	 * @param vault The vault to reveal
 	 */
 	public Task<Vault> createRevealTask(Vault vault) {
-		Task<Vault> task = new RevealVaultTask(vault);
+		Task<Vault> task = new RevealVaultTask(vault, application.get().getHostServices());
 		task.setOnSucceeded(evt -> LOG.info("Revealed {}", vault.getDisplayName()));
 		task.setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), evt.getSource().getException()));
 		return task;
@@ -106,20 +110,21 @@ public class VaultService {
 	private static class RevealVaultTask extends Task<Vault> {
 
 		private final Vault vault;
+		private final HostServices hostServices;
 
-		/**
-		 * @param vault The vault to lock
-		 */
-		public RevealVaultTask(Vault vault) {
+		public RevealVaultTask(Vault vault, HostServices hostServices) {
 			this.vault = vault;
-
+			this.hostServices = hostServices;
 			setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), getException()));
 		}
 
 		@Override
 		protected Vault call() {
-			//vault.reveal(revealer); //TODO: just call hostApplication service
-			//application.get().getHostServices().showDocument(p.toUri().toString());
+			switch (vault.getMountPoint()) {
+				case null -> LOG.warn("Not currently mounted");
+				case Mountpoint.WithPath m -> hostServices.showDocument(m.uri().toString());
+				case Mountpoint.WithUri m -> LOG.info("Vault mounted at {}", m.uri()); // TODO show in UI?
+			}
 			return vault;
 		}
 	}

+ 46 - 0
src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java

@@ -4,16 +4,24 @@ import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.common.vaults.VaultState;
+import org.cryptomator.integrations.mount.Mountpoint;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.VaultService;
 import org.cryptomator.ui.fxapp.FxApplicationWindows;
 import org.cryptomator.ui.stats.VaultStatisticsComponent;
 
 import javax.inject.Inject;
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.binding.StringBinding;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.value.ObservableValue;
 import javafx.fxml.FXML;
 import javafx.stage.Stage;
+import java.net.URI;
+import java.util.Optional;
 
 @MainWindowScoped
 public class VaultDetailUnlockedController implements FxController {
@@ -24,6 +32,10 @@ public class VaultDetailUnlockedController implements FxController {
 	private final Stage mainWindow;
 	private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
 	private final VaultStatisticsComponent.Builder vaultStatsBuilder;
+	private final ObservableValue<Mountpoint> mountPoint;
+	private final ObservableValue<Boolean> accessibleViaPath;
+	private final ObservableValue<Boolean> accessibleViaUri;
+	private final ObservableValue<String> mountUri;
 
 	@Inject
 	public VaultDetailUnlockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultService vaultService, VaultStatisticsComponent.Builder vaultStatsBuilder, @MainWindow Stage mainWindow) {
@@ -33,6 +45,10 @@ public class VaultDetailUnlockedController implements FxController {
 		this.mainWindow = mainWindow;
 		this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
 		this.vaultStatsBuilder = vaultStatsBuilder;
+		this.mountPoint = vault.flatMap(Vault::mountPointProperty);
+		this.accessibleViaPath = mountPoint.map(m -> m instanceof Mountpoint.WithPath).orElse(false);
+		this.accessibleViaUri = mountPoint.map(m -> m instanceof Mountpoint.WithUri).orElse(false);
+		this.mountUri = mountPoint.map(Mountpoint::uri).map(URI::toASCIIString).orElse("");
 	}
 
 	private VaultStatisticsComponent buildVaultStats(Vault vault) {
@@ -44,6 +60,11 @@ public class VaultDetailUnlockedController implements FxController {
 		vaultService.reveal(vault.get());
 	}
 
+	@FXML
+	public void copyMountUri() {
+		// TODO
+	}
+
 	@FXML
 	public void lock() {
 		appWindows.startLockWorkflow(vault.get(), mainWindow);
@@ -64,4 +85,29 @@ public class VaultDetailUnlockedController implements FxController {
 		return vault.get();
 	}
 
+	public ObservableValue<Boolean> accessibleViaPathProperty() {
+		return accessibleViaPath;
+	}
+
+	public boolean isAccessibleViaPath() {
+		return accessibleViaPath.getValue();
+	}
+
+	public ObservableValue<Boolean> accessibleViaUriProperty() {
+		return accessibleViaUri;
+	}
+
+	public boolean isAccessibleViaUri() {
+		return accessibleViaUri.getValue();
+	}
+
+	public ObservableValue<String> mountUriProperty() {
+		return mountUri;
+	}
+
+	public String getMountUri() {
+		return mountUri.getValue();
+	}
+
+
 }

+ 12 - 7
src/main/resources/fxml/vault_detail_unlocked.fxml

@@ -12,21 +12,26 @@
 	  alignment="TOP_CENTER"
 	  spacing="9">
 	<Label text="%main.vaultDetail.accessLocation"/>
-	<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#revealAccessLocation" defaultButton="${controller.vault.unlocked}">
+	<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#revealAccessLocation" defaultButton="${controller.accessibleViaPath}" visible="${controller.accessibleViaPath}" managed="${controller.accessibleViaPath}">
 		<graphic>
 			<HBox spacing="12" alignment="CENTER">
 				<FontAwesome5IconView glyph="HDD" glyphSize="24"/>
 				<VBox spacing="4" alignment="CENTER_LEFT">
 					<Label text="%main.vaultDetail.revealBtn"/>
-					<!-- TODO -->
-					<!--Label styleClass="label-extra-small" text="${controller.vault.accessPoint}" textOverrun="CENTER_ELLIPSIS"
-						   visible="${controller.vault.accessPoint.empty}" managed="${controller.vault.accessPoint.empty}"/-->
 				</VBox>
 			</HBox>
 		</graphic>
-		<!--tooltip>
-			<Tooltip text="${controller.vault.accessPoint}"/>
-		</tooltip -->
+	</Button>
+	<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#copyMountUri" defaultButton="${controller.accessibleViaUri}" visible="${controller.accessibleViaUri}" managed="${controller.accessibleViaUri}">
+		<graphic>
+			<HBox spacing="12" alignment="CENTER">
+				<FontAwesome5IconView glyph="LINK" glyphSize="24"/>
+				<VBox spacing="4" alignment="CENTER_LEFT">
+					<Label text="%generic.button.copy"/> <!-- TODO -->
+					<Label styleClass="label-extra-small" text="${controller.mountUri}" textOverrun="CENTER_ELLIPSIS"/>
+				</VBox>
+			</HBox>
+		</graphic>
 	</Button>
 	<Button text="%main.vaultDetail.lockBtn" minWidth="120" onAction="#lock">
 		<graphic>