diff --git a/pom.xml b/pom.xml index b11524a5e..24f35de0a 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 2.9.0 - 1.8.0-SNAPSHOT + 1.8.0-beta1 1.5.1 1.5.0-beta1 1.7.0-beta1 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a74e4b903..450cd4ca7 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,7 +1,4 @@ import ch.qos.logback.classic.spi.Configurator; -import org.cryptomator.integrations.notify.NotifyService2; -import org.cryptomator.integrationsbase.JavaFXNotifyService; -import org.cryptomator.networking.SSLContextWithPKCS12TrustStore; import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider; import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider; import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider; @@ -16,11 +13,12 @@ import org.cryptomator.common.locationpresets.OneDriveLinuxLocationPresetsProvid import org.cryptomator.common.locationpresets.OneDriveMacLocationPresetsProvider; import org.cryptomator.common.locationpresets.OneDriveWindowsLocationPresetsProvider; import org.cryptomator.common.locationpresets.PCloudLocationPresetsProvider; -import org.cryptomator.networking.SSLContextWithMacKeychain; -import org.cryptomator.networking.SSLContextProvider; -import org.cryptomator.networking.SSLContextWithWindowsCertStore; import org.cryptomator.integrations.tray.TrayMenuController; import org.cryptomator.logging.LogbackConfiguratorFactory; +import org.cryptomator.networking.SSLContextProvider; +import org.cryptomator.networking.SSLContextWithMacKeychain; +import org.cryptomator.networking.SSLContextWithPKCS12TrustStore; +import org.cryptomator.networking.SSLContextWithWindowsCertStore; import org.cryptomator.ui.traymenu.AwtTrayMenuController; open module org.cryptomator.desktop { @@ -66,7 +64,6 @@ open module org.cryptomator.desktop { provides TrayMenuController with AwtTrayMenuController; provides Configurator with LogbackConfiguratorFactory; provides SSLContextProvider with SSLContextWithWindowsCertStore, SSLContextWithMacKeychain, SSLContextWithPKCS12TrustStore; - provides NotifyService2 with JavaFXNotifyService; provides LocationPresetsProvider with // DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, // GoogleDriveMacLocationPresetsProvider, GoogleDriveWindowsLocationPresetsProvider, // diff --git a/src/main/java/org/cryptomator/integrationsbase/JavaFXNotifyService.java b/src/main/java/org/cryptomator/integrationsbase/JavaFXNotifyService.java deleted file mode 100644 index a9b822d99..000000000 --- a/src/main/java/org/cryptomator/integrationsbase/JavaFXNotifyService.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.cryptomator.integrationsbase; - -import org.cryptomator.integrations.common.DisplayName; -import org.cryptomator.integrations.common.Priority; -import org.cryptomator.integrations.notify.NotifyService; -import org.cryptomator.integrations.notify.NotifyService2; -import org.cryptomator.integrations.notify.NotifyServiceException; - -import java.util.ArrayList; - -@Priority(Priority.FALLBACK) -//@LocalizedDisplayName(bundle = "strings", key ="") -@DisplayName("Cryptomator App Window") -public class JavaFXNotifyService implements NotifyService2 { - - //TODO: ipcMessageFile! - - @Override - public void sendNotification(String header, String description, NotifyService2.Action... actions) throws NotifyServiceException { - var argList = new ArrayList(); - argList.add(header); - argList.add(description); - for(var action: actions) { - argList.add(action.label()); - argList.add(action.returnMessage()); - } - NotificationApp.main(argList.toArray(new String[] {})); - } - -} diff --git a/src/main/java/org/cryptomator/integrationsbase/NotificationApp.java b/src/main/java/org/cryptomator/integrationsbase/NotificationApp.java deleted file mode 100644 index c02a0057a..000000000 --- a/src/main/java/org/cryptomator/integrationsbase/NotificationApp.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.cryptomator.integrationsbase; - -import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.ui.common.FxmlLoaderFactory; - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; -import javafx.scene.control.Label; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.StackPane; -import javafx.stage.Stage; -import javafx.util.BuilderFactory; -import java.io.IOException; -import java.util.ResourceBundle; - - -public class NotificationApp extends Application { - - - private static final KeyCodeCombination ALT_F4 = new KeyCodeCombination(KeyCode.F4, KeyCombination.ALT_DOWN); - private static final KeyCodeCombination SHORTCUT_W = new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN); - - @Override - public void start(Stage stage) throws IOException { - var args = getParameters(); - String javaVersion = System.getProperty("java.version"); - var url = getClass().getResource("/fxml/notification_window.fxml"); - var root = FXMLLoader.load(url, ResourceBundle.getBundle("i18n.strings")); - var scene = new Scene(root); - stage.setScene(scene); - setupDefaultAccelerators(scene, stage); - stage.show(); - stage.requestFocus(); - } - - public static void main(String[] args) { - //assert args.length >= 2; - launch(args); - } - - private void setupDefaultAccelerators(Scene scene, Stage stage) { - if (SystemUtils.IS_OS_WINDOWS) { - scene.getAccelerators().put(ALT_F4, stage::close); - } else { - scene.getAccelerators().put(SHORTCUT_W, stage::close); - } - } -} diff --git a/src/main/java/org/cryptomator/integrationsbase/NotificationWindowController.java b/src/main/java/org/cryptomator/integrationsbase/NotificationWindowController.java deleted file mode 100644 index e6aca952a..000000000 --- a/src/main/java/org/cryptomator/integrationsbase/NotificationWindowController.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.cryptomator.integrationsbase; - -import javafx.event.ActionEvent; -import javafx.fxml.FXML; - -public class NotificationWindowController { - - public NotificationWindowController() { - - } - - @FXML - public void initialize() { - System.out.println("Hello"); - } - - public void handleButtonAction(ActionEvent actionEvent) { - System.out.println("OKAY"); - } -} diff --git a/src/main/java/org/cryptomator/ui/common/FxmlFile.java b/src/main/java/org/cryptomator/ui/common/FxmlFile.java index 68607808d..7278ddb99 100644 --- a/src/main/java/org/cryptomator/ui/common/FxmlFile.java +++ b/src/main/java/org/cryptomator/ui/common/FxmlFile.java @@ -57,7 +57,8 @@ public enum FxmlFile { UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), // VAULT_OPTIONS("/fxml/vault_options.fxml"), // VAULT_STATISTICS("/fxml/stats.fxml"), // - WRONGFILEALERT("/fxml/wrongfilealert.fxml"); + WRONGFILEALERT("/fxml/wrongfilealert.fxml"), + NOTIFICATION("/fxml/notification.fxml"); private final String ressourcePathString; diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index ccc0684af..0c660422a 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -89,6 +89,7 @@ public class FxApplication { launchEventHandler.startHandlingLaunchEvents(); fxFSEventList.schedulePollForUpdates(); autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES); + //TODO: init the NotificationListener } private void migrateAndInformDokanyRemoval() { diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java index 70319df5b..90a48039a 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java @@ -13,6 +13,7 @@ import org.cryptomator.ui.eventview.EventViewComponent; import org.cryptomator.ui.health.HealthCheckComponent; import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent; +import org.cryptomator.ui.notification.NotificationComponent; import org.cryptomator.ui.preferences.PreferencesComponent; import org.cryptomator.ui.quit.QuitComponent; import org.cryptomator.ui.recoverykey.RecoveryKeyComponent; @@ -39,7 +40,8 @@ import java.io.InputStream; UpdateReminderComponent.class, // ShareVaultComponent.class, // EventViewComponent.class, // - RecoveryKeyComponent.class}) + RecoveryKeyComponent.class, // + NotificationComponent.class }) abstract class FxApplicationModule { private static Image createImageFromResource(String resourceName) throws IOException { diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java index c8a870fd8..ebc7cb635 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import dagger.Lazy; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultState; +import org.cryptomator.integrations.notify.NotifyService; import org.cryptomator.integrations.tray.TrayIntegrationProvider; import org.cryptomator.ui.dialogs.Dialogs; import org.cryptomator.ui.dialogs.SimpleDialog; @@ -11,6 +12,7 @@ import org.cryptomator.ui.error.ErrorComponent; import org.cryptomator.ui.eventview.EventViewComponent; import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent; +import org.cryptomator.ui.notification.NotificationComponent; import org.cryptomator.ui.preferences.PreferencesComponent; import org.cryptomator.ui.preferences.SelectedPreferencesTab; import org.cryptomator.ui.quit.QuitComponent; @@ -54,6 +56,7 @@ public class FxApplicationWindows { private final LockComponent.Factory lockWorkflowFactory; private final ErrorComponent.Factory errorWindowFactory; private final Lazy eventViewWindow; + private final NotificationComponent.Factory notificationWindow; private final ExecutorService executor; private final VaultOptionsComponent.Factory vaultOptionsWindow; private final ShareVaultComponent.Factory shareVaultWindow; @@ -73,6 +76,7 @@ public class FxApplicationWindows { VaultOptionsComponent.Factory vaultOptionsWindow, // ShareVaultComponent.Factory shareVaultWindow, // Lazy eventViewWindow, // + NotificationComponent.Factory notificationWindow, ExecutorService executor, // Dialogs dialogs) { this.primaryStage = primaryStage; @@ -85,6 +89,7 @@ public class FxApplicationWindows { this.lockWorkflowFactory = lockWorkflowFactory; this.errorWindowFactory = errorWindowFactory; this.eventViewWindow = eventViewWindow; + this.notificationWindow = notificationWindow; this.executor = executor; this.vaultOptionsWindow = vaultOptionsWindow; this.shareVaultWindow = shareVaultWindow; @@ -193,6 +198,10 @@ public class FxApplicationWindows { return CompletableFuture.supplyAsync(() -> eventViewWindow.get().showEventViewerWindow(), Platform::runLater).whenComplete(this::reportErrors); } + public CompletionStage showNotification(Runnable action) { + return CompletableFuture.supplyAsync(() -> notificationWindow.create(message, description, action).showNotification(), Platform::runLater).whenComplete(this::reportErrors); + } + /** * Displays the generic error scene in the given window. * @@ -210,4 +219,5 @@ public class FxApplicationWindows { LOG.error("Failed to display stage", error); } } + } diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxNotificationRadar.java b/src/main/java/org/cryptomator/ui/fxapp/FxNotificationRadar.java new file mode 100644 index 000000000..66bd08488 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/fxapp/FxNotificationRadar.java @@ -0,0 +1,21 @@ +package org.cryptomator.ui.fxapp; + +import javax.inject.Inject; + +/** + * Scans the event list for events requiring a notification + */ +@FxApplicationScoped +public class FxNotificationRadar { + + private final FxFSEventList eventList; + + @Inject + FxNotificationRadar(FxFSEventList eventList) { + this.eventList = eventList; + eventList.getObservableList() + + } + + +} diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index f25528498..dfdc8f338 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -11,6 +11,8 @@ import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.DirStructure; import org.cryptomator.cryptofs.common.Constants; import org.cryptomator.integrations.mount.MountService; +import org.cryptomator.integrations.notify.NotifyService; +import org.cryptomator.integrations.notify.NotifyServiceException; import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.VaultService; @@ -205,11 +207,22 @@ public class VaultListController implements FxController { @FXML private void toggleMenu() { + /* if (addVaultContextMenu.isShowing()) { addVaultContextMenu.hide(); } else { addVaultContextMenu.show(addVaultButton, Side.BOTTOM, 0.0, 0.0); } + */ + NotifyService.loadAll().findFirst().ifPresent( + s -> { + try { + s.sendNotification("Hello", "Lindsay"); + } catch (NotifyServiceException e) { + throw new RuntimeException(e); + } + } + ); } private void deselect(MouseEvent released) { diff --git a/src/main/java/org/cryptomator/ui/notification/NotificationComponent.java b/src/main/java/org/cryptomator/ui/notification/NotificationComponent.java new file mode 100644 index 000000000..7a9d2c0b9 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotificationComponent.java @@ -0,0 +1,26 @@ +package org.cryptomator.ui.notification; + +import dagger.BindsInstance; +import dagger.Subcomponent; + +import javafx.stage.Stage; + +@NotificationScoped +@Subcomponent(modules = {NotificationModule.class}) +public interface NotificationComponent { + + @NotificationWindow + Stage notificationWindow(); + + default Stage showNotification(){ + var window = notificationWindow(); + window.show(); + return window; + } + + @Subcomponent.Factory + interface Factory { + NotificationComponent create(@BindsInstance Runnable action); + } + +} diff --git a/src/main/java/org/cryptomator/ui/notification/NotificationController.java b/src/main/java/org/cryptomator/ui/notification/NotificationController.java new file mode 100644 index 000000000..c35a754f6 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotificationController.java @@ -0,0 +1,56 @@ +package org.cryptomator.ui.notification; + +import org.cryptomator.common.Nullable; +import org.cryptomator.integrations.notify.NotifyService; +import org.cryptomator.ui.common.FxController; + +import javax.inject.Inject; +import javax.inject.Named; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import java.util.concurrent.ExecutorService; + +@NotificationScoped +public class NotificationController implements FxController { + + private final String message; + private final String description; + private final NotifyAction callback; + private final ExecutorService executorService; + + @FXML + Button button; + + @Inject + public NotificationController(@Named("Message") String message, @Named("Description") String description, @Nullable NotifyAction callback, ExecutorService executorService) { + this.message = message; + this.description = description; + this.callback = callback; + this.executorService = executorService; + } + + + //FXML bindings + + public String getMessage() { + return message; + } + + public String getDescription() { + return description; + } + + public String getButtonText() { + return callback == null? "" : callback.label(); + } + + public boolean isButtonVisible() { + return callback != null; + } + + @FXML + public void handleButtonAction(ActionEvent actionEvent) { + executorService.submit(callback.action()); + } +} diff --git a/src/main/java/org/cryptomator/ui/notification/NotificationModule.java b/src/main/java/org/cryptomator/ui/notification/NotificationModule.java new file mode 100644 index 000000000..3540e7636 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotificationModule.java @@ -0,0 +1,62 @@ +package org.cryptomator.ui.notification; + +import dagger.Binds; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoMap; +import org.cryptomator.ui.common.DefaultSceneFactory; +import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.common.FxControllerKey; +import org.cryptomator.ui.common.FxmlFile; +import org.cryptomator.ui.common.FxmlLoaderFactory; +import org.cryptomator.ui.common.FxmlScene; +import org.cryptomator.ui.common.StageInitializer; +import org.cryptomator.ui.quit.QuitForcedController; + +import javax.inject.Provider; +import javafx.scene.Scene; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import java.util.Map; +import java.util.ResourceBundle; + +@Module +abstract class NotificationModule { + + @Provides + @NotificationWindow + @NotificationScoped + static Stage provideStage(StageInitializer initializer, @FxmlScene(FxmlFile.NOTIFICATION) Scene notificationScene) { + Stage stage = new Stage(StageStyle.UTILITY); + stage.setTitle("Filesystem notification"); //TODO: translate + stage.setResizable(false); + stage.initModality(Modality.NONE); + initializer.accept(stage); + stage.setScene(notificationScene); + stage.sizeToScene(); + return stage; + } + + + // javafx setup + + @Provides + @FxmlScene(FxmlFile.NOTIFICATION) + @NotificationScoped + static Scene provideNotificationScene(FxmlLoaderFactory fxmlLoaders) { + return fxmlLoaders.createScene(FxmlFile.NOTIFICATION); + } + + @Provides + @NotificationScoped + static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) { + return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle); + } + + @Binds + @IntoMap + @FxControllerKey(NotificationController.class) + abstract FxController bindNotificationController(NotificationController controller); + +} diff --git a/src/main/java/org/cryptomator/ui/notification/NotificationScoped.java b/src/main/java/org/cryptomator/ui/notification/NotificationScoped.java new file mode 100644 index 000000000..ca2b9d4b5 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotificationScoped.java @@ -0,0 +1,11 @@ +package org.cryptomator.ui.notification; + +import javax.inject.Scope; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Scope +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface NotificationScoped {} diff --git a/src/main/java/org/cryptomator/ui/notification/NotificationWindow.java b/src/main/java/org/cryptomator/ui/notification/NotificationWindow.java new file mode 100644 index 000000000..5b541cee7 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotificationWindow.java @@ -0,0 +1,12 @@ +package org.cryptomator.ui.notification; + +import javax.inject.Qualifier; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface NotificationWindow {} diff --git a/src/main/java/org/cryptomator/ui/notification/NotifyAction.java b/src/main/java/org/cryptomator/ui/notification/NotifyAction.java new file mode 100644 index 000000000..6e894cf17 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/notification/NotifyAction.java @@ -0,0 +1,3 @@ +package org.cryptomator.ui.notification; + +public record NotifyAction(String label, Runnable action) {} diff --git a/src/main/resources/fxml/notification.fxml b/src/main/resources/fxml/notification.fxml new file mode 100644 index 000000000..f291d0c79 --- /dev/null +++ b/src/main/resources/fxml/notification.fxml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +