diff --git a/main/ui/src/main/java/org/cryptomator/ui/common/VaultService.java b/main/ui/src/main/java/org/cryptomator/ui/common/VaultService.java index 4b9226acd..4baa9526c 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/common/VaultService.java +++ b/main/ui/src/main/java/org/cryptomator/ui/common/VaultService.java @@ -25,20 +25,13 @@ public class VaultService { private final ExecutorService executorService; - private AtomicReference vaultRevealer; - @Inject public VaultService(ExecutorService executorService) { this.executorService = executorService; - this.vaultRevealer = new AtomicReference<>(p -> {}); //the inital revealer does nuthin } - public void reveal(Vault vault) { - executorService.execute(createRevealTask(vault)); - } - - public void setVaultRevealer(Volume.RevealerFacade revealer) { - this.vaultRevealer.set(revealer); + public void reveal(Vault vault, Volume.RevealerFacade vaultRevealCmd) { + executorService.execute(createRevealTask(vault, vaultRevealCmd)); } /** @@ -46,8 +39,8 @@ public class VaultService { * * @param vault The vault to reveal */ - public Task createRevealTask(Vault vault) { - Task task = new RevealVaultTask(vault, vaultRevealer.get()); + public Task createRevealTask(Vault vault, Volume.RevealerFacade vaultRevealCmd) { + Task task = new RevealVaultTask(vault, vaultRevealCmd); task.setOnSucceeded(evt -> LOG.info("Revealed {}", vault.getDisplayName())); task.setOnFailed(evt -> LOG.error("Failed to reveal " + vault.getDisplayName(), evt.getSource().getException())); return task; diff --git a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 8633b6e8b..65e6d1c6c 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -68,8 +68,6 @@ public class FxApplication extends Application { this.licenseHolder = licenseHolder; this.visibleWindows = Stage.getWindows().filtered(Window::isShowing); this.hasVisibleWindows = Bindings.isNotEmpty(visibleWindows); - - vaultService.setVaultRevealer(p -> this.getHostServices().showDocument(p.toUri().toString())); } public void start() { diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java index 0af909bbc..b85fa8bda 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java @@ -42,7 +42,7 @@ public class VaultDetailUnlockedController implements FxController { @FXML public void revealAccessLocation() { - vaultService.reveal(vault.get()); + vaultService.reveal(vault.get(), p -> application.getHostServices().showDocument(p.toUri().toString())); } @FXML diff --git a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java index a4e068f8d..75e1b793c 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java +++ b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuComponent.java @@ -7,11 +7,10 @@ package org.cryptomator.ui.traymenu; import dagger.Lazy; import dagger.Subcomponent; - import java.awt.SystemTray; @TrayMenuScoped -@Subcomponent +@Subcomponent(modules = TrayMenuModule.class) public interface TrayMenuComponent { Lazy trayIconController(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java index 96529c5fb..fada2b061 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuController.java @@ -1,6 +1,7 @@ package org.cryptomator.ui.traymenu; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.common.vaults.Volume; import org.cryptomator.ui.fxapp.FxApplication; import org.cryptomator.ui.launcher.AppLifecycleListener; import org.cryptomator.ui.launcher.FxApplicationStarter; @@ -27,14 +28,16 @@ class TrayMenuController { private final AppLifecycleListener appLifecycle; private final FxApplicationStarter fxApplicationStarter; private final ObservableList vaults; + private final Volume.RevealerFacade revealer; private final PopupMenu menu; @Inject - TrayMenuController(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults) { + TrayMenuController(ResourceBundle resourceBundle, AppLifecycleListener appLifecycle, FxApplicationStarter fxApplicationStarter, ObservableList vaults, Volume.RevealerFacade revealer) { this.resourceBundle = resourceBundle; this.appLifecycle = appLifecycle; this.fxApplicationStarter = fxApplicationStarter; this.vaults = vaults; + this.revealer = revealer; this.menu = new PopupMenu(); } @@ -121,7 +124,7 @@ class TrayMenuController { } private void revealVault(Vault vault) { - showMainAppAndThen(app -> app.getVaultService().reveal(vault)); + showMainAppAndThen(app -> app.getVaultService().reveal(vault, revealer)); } void showMainWindow(@SuppressWarnings("unused") ActionEvent actionEvent) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java new file mode 100644 index 000000000..65227a880 --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayMenuModule.java @@ -0,0 +1,27 @@ +package org.cryptomator.ui.traymenu; + +import dagger.Module; +import dagger.Provides; +import org.cryptomator.common.vaults.Volume; + +import java.awt.Desktop; +import java.io.IOException; + +@Module +abstract class TrayMenuModule { + + @Provides + static Volume.RevealerFacade provideAwtRevealer(){ + return p -> { + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) { + try { + Desktop.getDesktop().open(p.toFile()); + } catch (IOException e) { + throw new Volume.VolumeException(e); + } + } else { + throw new Volume.VolumeException("API to browse files not supported. Please try again from inside the application."); + } + }; + } +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSuccessController.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSuccessController.java index ee3ffc5ae..ef1d4fdf3 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSuccessController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSuccessController.java @@ -4,6 +4,7 @@ import org.cryptomator.common.settings.WhenUnlocked; import org.cryptomator.common.vaults.Vault; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.VaultService; +import org.cryptomator.ui.fxapp.FxApplication; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,17 +30,19 @@ public class UnlockSuccessController implements FxController { private final Vault vault; private final ExecutorService executor; private final VaultService vaultService; + private final FxApplication application; private final ObjectProperty revealButtonState; private final BooleanProperty revealButtonDisabled; public CheckBox rememberChoiceCheckbox; @Inject - public UnlockSuccessController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, VaultService vaultService) { + public UnlockSuccessController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, VaultService vaultService, FxApplication application) { this.window = window; this.vault = vault; this.executor = executor; this.vaultService = vaultService; + this.application = application; this.revealButtonState = new SimpleObjectProperty<>(ContentDisplay.TEXT_ONLY); this.revealButtonDisabled = new SimpleBooleanProperty(); } @@ -59,7 +62,7 @@ public class UnlockSuccessController implements FxController { revealButtonState.set(ContentDisplay.LEFT); revealButtonDisabled.set(true); - Task revealTask = vaultService.createRevealTask(vault); + Task revealTask = vaultService.createRevealTask(vault, p -> application.getHostServices().showDocument(p.toUri().toString())); revealTask.setOnSucceeded(evt -> { revealButtonState.set(ContentDisplay.TEXT_ONLY); revealButtonDisabled.set(false); diff --git a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java index 8cb7e0752..87e666f2d 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java +++ b/main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java @@ -15,6 +15,7 @@ import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.UserInteractionLock; import org.cryptomator.ui.common.VaultService; +import org.cryptomator.ui.fxapp.FxApplication; import org.cryptomator.ui.unlock.UnlockModule.PasswordEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,9 +59,10 @@ public class UnlockWorkflow extends Task { private final Lazy successScene; private final Lazy invalidMountPointScene; private final ErrorComponent.Builder errorComponent; + private final FxApplication application; @Inject - UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional savedPassword, UserInteractionLock passwordEntryLock, KeychainManager keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy invalidMountPointScene, ErrorComponent.Builder errorComponent) { + UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional savedPassword, UserInteractionLock passwordEntryLock, KeychainManager keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy invalidMountPointScene, ErrorComponent.Builder errorComponent, FxApplication application) { this.window = window; this.vault = vault; this.vaultService = vaultService; @@ -73,6 +75,7 @@ public class UnlockWorkflow extends Task { this.successScene = successScene; this.invalidMountPointScene = invalidMountPointScene; this.errorComponent = errorComponent; + this.application = application; setOnFailed(event -> { Throwable throwable = event.getSource().getException(); @@ -143,7 +146,7 @@ public class UnlockWorkflow extends Task { }); case REVEAL -> { Platform.runLater(window::close); - vaultService.reveal(vault); + vaultService.reveal(vault, p -> application.getHostServices().showDocument(p.toUri().toString())); } case IGNORE -> Platform.runLater(window::close); }