mirror of
https://github.com/cryptomator/cryptomator.git
synced 2025-12-24 01:00:20 +00:00
reveal OR copy mount point depending on chosen mounter
This commit is contained in:
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -45,7 +45,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="JavacSettings">
|
<component name="JavacSettings">
|
||||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
<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>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
1
pom.xml
1
pom.xml
@@ -313,6 +313,7 @@
|
|||||||
<compilerArgs>
|
<compilerArgs>
|
||||||
<arg>-Adagger.fastInit=enabled</arg>
|
<arg>-Adagger.fastInit=enabled</arg>
|
||||||
<arg>-Adagger.formatGeneratedSource=enabled</arg>
|
<arg>-Adagger.formatGeneratedSource=enabled</arg>
|
||||||
|
<arg>--enable-preview</arg>
|
||||||
</compilerArgs>
|
</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import javax.inject.Named;
|
|||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
|
import javafx.beans.binding.ObjectBinding;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
@@ -81,7 +82,7 @@ public class Vault {
|
|||||||
private final BooleanBinding missing;
|
private final BooleanBinding missing;
|
||||||
private final BooleanBinding needsMigration;
|
private final BooleanBinding needsMigration;
|
||||||
private final BooleanBinding unknownError;
|
private final BooleanBinding unknownError;
|
||||||
private final StringBinding accessPoint;
|
private final ObjectBinding<Mountpoint> mountPoint;
|
||||||
private final BooleanProperty showingStats;
|
private final BooleanProperty showingStats;
|
||||||
|
|
||||||
private AtomicReference<MountHandle> mountHandle = new AtomicReference<>(null);
|
private AtomicReference<MountHandle> mountHandle = new AtomicReference<>(null);
|
||||||
@@ -105,7 +106,7 @@ public class Vault {
|
|||||||
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
||||||
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
||||||
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, 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);
|
this.showingStats = new SimpleBooleanProperty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,17 +318,13 @@ public class Vault {
|
|||||||
return vaultSettings.displayName().get();
|
return vaultSettings.displayName().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBinding accessPointProperty() {
|
public ObjectBinding<Mountpoint> mountPointProperty() {
|
||||||
return accessPoint;
|
return mountPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAccessPoint() {
|
public Mountpoint getMountPoint() {
|
||||||
var mountPoint = mountHandle.get().mount.getMountpoint();
|
var handle = mountHandle.get();
|
||||||
if (mountPoint instanceof Mountpoint.WithPath m) {
|
return handle == null ? null : handle.mount.getMountpoint();
|
||||||
return m.path().toString();
|
|
||||||
} else {
|
|
||||||
return mountPoint.uri().toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBinding displayablePathProperty() {
|
public StringBinding displayablePathProperty() {
|
||||||
|
|||||||
@@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.common;
|
||||||
|
|
||||||
|
import dagger.Lazy;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.common.vaults.VaultState;
|
import org.cryptomator.common.vaults.VaultState;
|
||||||
|
import org.cryptomator.integrations.mount.Mountpoint;
|
||||||
import org.cryptomator.integrations.mount.UnmountFailedException;
|
import org.cryptomator.integrations.mount.UnmountFailedException;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationScoped;
|
import org.cryptomator.ui.fxapp.FxApplicationScoped;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.application.HostServices;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -24,13 +28,13 @@ public class VaultService {
|
|||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(VaultService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(VaultService.class);
|
||||||
|
|
||||||
|
private final Lazy<Application> application;
|
||||||
private final ExecutorService executorService;
|
private final ExecutorService executorService;
|
||||||
private final HostServiceRevealer vaultRevealer;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VaultService(ExecutorService executorService, HostServiceRevealer vaultRevealer) {
|
public VaultService(Lazy<Application> application, ExecutorService executorService) {
|
||||||
|
this.application = application;
|
||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
this.vaultRevealer = vaultRevealer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reveal(Vault vault) {
|
public void reveal(Vault vault) {
|
||||||
@@ -43,7 +47,7 @@ public class VaultService {
|
|||||||
* @param vault The vault to reveal
|
* @param vault The vault to reveal
|
||||||
*/
|
*/
|
||||||
public Task<Vault> createRevealTask(Vault vault) {
|
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.setOnSucceeded(evt -> LOG.info("Revealed {}", vault.getDisplayName()));
|
||||||
task.setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), evt.getSource().getException()));
|
task.setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), evt.getSource().getException()));
|
||||||
return task;
|
return task;
|
||||||
@@ -106,20 +110,21 @@ public class VaultService {
|
|||||||
private static class RevealVaultTask extends Task<Vault> {
|
private static class RevealVaultTask extends Task<Vault> {
|
||||||
|
|
||||||
private final Vault vault;
|
private final Vault vault;
|
||||||
|
private final HostServices hostServices;
|
||||||
|
|
||||||
/**
|
public RevealVaultTask(Vault vault, HostServices hostServices) {
|
||||||
* @param vault The vault to lock
|
|
||||||
*/
|
|
||||||
public RevealVaultTask(Vault vault) {
|
|
||||||
this.vault = vault;
|
this.vault = vault;
|
||||||
|
this.hostServices = hostServices;
|
||||||
setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), getException()));
|
setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), getException()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vault call() {
|
protected Vault call() {
|
||||||
//vault.reveal(revealer); //TODO: just call hostApplication service
|
switch (vault.getMountPoint()) {
|
||||||
//application.get().getHostServices().showDocument(p.toUri().toString());
|
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;
|
return vault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,24 @@ import com.google.common.cache.CacheBuilder;
|
|||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
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.FxController;
|
||||||
import org.cryptomator.ui.common.VaultService;
|
import org.cryptomator.ui.common.VaultService;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
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.ObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@MainWindowScoped
|
@MainWindowScoped
|
||||||
public class VaultDetailUnlockedController implements FxController {
|
public class VaultDetailUnlockedController implements FxController {
|
||||||
@@ -24,6 +32,10 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
private final Stage mainWindow;
|
private final Stage mainWindow;
|
||||||
private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
|
private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
|
||||||
private final VaultStatisticsComponent.Builder vaultStatsBuilder;
|
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
|
@Inject
|
||||||
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultService vaultService, VaultStatisticsComponent.Builder vaultStatsBuilder, @MainWindow Stage mainWindow) {
|
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.mainWindow = mainWindow;
|
||||||
this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
|
this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
|
||||||
this.vaultStatsBuilder = vaultStatsBuilder;
|
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) {
|
private VaultStatisticsComponent buildVaultStats(Vault vault) {
|
||||||
@@ -44,6 +60,11 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
vaultService.reveal(vault.get());
|
vaultService.reveal(vault.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void copyMountUri() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void lock() {
|
public void lock() {
|
||||||
appWindows.startLockWorkflow(vault.get(), mainWindow);
|
appWindows.startLockWorkflow(vault.get(), mainWindow);
|
||||||
@@ -64,4 +85,29 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
return vault.get();
|
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,21 +12,26 @@
|
|||||||
alignment="TOP_CENTER"
|
alignment="TOP_CENTER"
|
||||||
spacing="9">
|
spacing="9">
|
||||||
<Label text="%main.vaultDetail.accessLocation"/>
|
<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>
|
<graphic>
|
||||||
<HBox spacing="12" alignment="CENTER">
|
<HBox spacing="12" alignment="CENTER">
|
||||||
<FontAwesome5IconView glyph="HDD" glyphSize="24"/>
|
<FontAwesome5IconView glyph="HDD" glyphSize="24"/>
|
||||||
<VBox spacing="4" alignment="CENTER_LEFT">
|
<VBox spacing="4" alignment="CENTER_LEFT">
|
||||||
<Label text="%main.vaultDetail.revealBtn"/>
|
<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>
|
</VBox>
|
||||||
</HBox>
|
</HBox>
|
||||||
</graphic>
|
</graphic>
|
||||||
<!--tooltip>
|
</Button>
|
||||||
<Tooltip text="${controller.vault.accessPoint}"/>
|
<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#copyMountUri" defaultButton="${controller.accessibleViaUri}" visible="${controller.accessibleViaUri}" managed="${controller.accessibleViaUri}">
|
||||||
</tooltip -->
|
<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>
|
||||||
<Button text="%main.vaultDetail.lockBtn" minWidth="120" onAction="#lock">
|
<Button text="%main.vaultDetail.lockBtn" minWidth="120" onAction="#lock">
|
||||||
<graphic>
|
<graphic>
|
||||||
|
|||||||
Reference in New Issue
Block a user