From ca2f80024a4dd39a406f3a5668db3f03289e75b0 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 11 Feb 2025 15:38:18 +0100 Subject: [PATCH 001/139] impl draft --- pom.xml | 2 +- src/main/java/module-info.java | 1 + .../org/cryptomator/common/CommonsModule.java | 9 +++++++++ .../java/org/cryptomator/common/vaults/Vault.java | 15 ++++++++++++++- src/main/java/org/cryptomator/notify/Answer.java | 14 ++++++++++++++ .../java/org/cryptomator/notify/AppEvent.java | 3 +++ src/main/java/org/cryptomator/notify/Event.java | 5 +++++ .../cryptomator/notify/NotificationHandler.java | 15 +++++++++++++++ .../java/org/cryptomator/notify/VaultEvent.java | 7 +++++++ .../ui/eventviewer/EventViewerComponent.java | 3 +++ 10 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/cryptomator/notify/Answer.java create mode 100644 src/main/java/org/cryptomator/notify/AppEvent.java create mode 100644 src/main/java/org/cryptomator/notify/Event.java create mode 100644 src/main/java/org/cryptomator/notify/NotificationHandler.java create mode 100644 src/main/java/org/cryptomator/notify/VaultEvent.java create mode 100644 src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java diff --git a/pom.xml b/pom.xml index cea4bc575..e6f1e96e4 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents - 2.8.0 + 2.9.0-SNAPSHOT 1.5.0 1.3.0 1.2.4 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 4dd4242b3..f43e6599d 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -59,6 +59,7 @@ open module org.cryptomator.desktop { uses org.cryptomator.common.locationpresets.LocationPresetsProvider; uses SSLContextProvider; + uses org.cryptomator.notify.NotificationHandler; provides TrayMenuController with AwtTrayMenuController; provides Configurator with LogbackConfiguratorFactory; diff --git a/src/main/java/org/cryptomator/common/CommonsModule.java b/src/main/java/org/cryptomator/common/CommonsModule.java index a1e3c0950..a3f8f29a6 100644 --- a/src/main/java/org/cryptomator/common/CommonsModule.java +++ b/src/main/java/org/cryptomator/common/CommonsModule.java @@ -15,11 +15,14 @@ import org.cryptomator.common.vaults.VaultComponent; import org.cryptomator.common.vaults.VaultListModule; import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.cryptomator.integrations.revealpath.RevealPathService; +import org.cryptomator.notify.Event; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Named; import javax.inject.Singleton; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Comparator; @@ -128,6 +131,12 @@ public abstract class CommonsModule { return executorService; } + @Provides + @Singleton + static ObservableList provideAppEventQueue() { + return FXCollections.observableArrayList(); + } + private static void handleUncaughtExceptionInBackgroundThread(Thread thread, Throwable throwable) { LOG.error("Uncaught exception in " + thread.getName(), throwable); } diff --git a/src/main/java/org/cryptomator/common/vaults/Vault.java b/src/main/java/org/cryptomator/common/vaults/Vault.java index f857d6ba1..6d47c95f5 100644 --- a/src/main/java/org/cryptomator/common/vaults/Vault.java +++ b/src/main/java/org/cryptomator/common/vaults/Vault.java @@ -18,6 +18,7 @@ import org.cryptomator.cryptofs.CryptoFileSystemProperties; import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags; import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker; +import org.cryptomator.cryptofs.event.FilesystemEvent; import org.cryptomator.cryptolib.api.CryptoException; import org.cryptomator.cryptolib.api.MasterkeyLoader; import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; @@ -26,6 +27,8 @@ import org.cryptomator.integrations.mount.Mountpoint; import org.cryptomator.integrations.mount.UnmountFailedException; import org.cryptomator.integrations.quickaccess.QuickAccessService; import org.cryptomator.integrations.quickaccess.QuickAccessServiceException; +import org.cryptomator.notify.Event; +import org.cryptomator.notify.VaultEvent; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +44,7 @@ import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.collections.ObservableList; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @@ -74,6 +78,7 @@ public class Vault { private final ObjectBinding mountPoint; private final Mounter mounter; private final Settings settings; + private final ObservableList eventQueue; private final BooleanProperty showingStats; private final AtomicReference mountHandle = new AtomicReference<>(null); @@ -85,7 +90,9 @@ public class Vault { VaultState state, // @Named("lastKnownException") ObjectProperty lastKnownException, // VaultStats stats, // - Mounter mounter, Settings settings) { + Mounter mounter, Settings settings, // + ObservableList eventQueue + ) { this.vaultSettings = vaultSettings; this.configCache = configCache; this.cryptoFileSystem = cryptoFileSystem; @@ -102,6 +109,7 @@ public class Vault { this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state); this.mounter = mounter; this.settings = settings; + this.eventQueue = eventQueue; this.showingStats = new SimpleBooleanProperty(false); this.quickAccessEntry = new AtomicReference<>(null); } @@ -143,6 +151,7 @@ public class Vault { .withFlags(flags) // .withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength.get()) // .withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) // + .withFilesystemEventConsumer(this::consumeVaultEvent) .build(); return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps); } @@ -251,6 +260,10 @@ public class Vault { } } + private void consumeVaultEvent(FilesystemEvent e) { + eventQueue.addLast(new VaultEvent(vaultSettings.id, vaultSettings.path.get().toString(), e)); + } + // ****************************************************************************** // Observable Properties // ******************************************************************************* diff --git a/src/main/java/org/cryptomator/notify/Answer.java b/src/main/java/org/cryptomator/notify/Answer.java new file mode 100644 index 000000000..8c99b82de --- /dev/null +++ b/src/main/java/org/cryptomator/notify/Answer.java @@ -0,0 +1,14 @@ +package org.cryptomator.notify; + +public sealed interface Answer permits Answer.DoNothing, Answer.DoSomething { + + + record DoNothing() implements Answer {} + + record DoSomething(Runnable action) implements Answer { + + void run() { + action.run(); + } + } +} diff --git a/src/main/java/org/cryptomator/notify/AppEvent.java b/src/main/java/org/cryptomator/notify/AppEvent.java new file mode 100644 index 000000000..afeb829e4 --- /dev/null +++ b/src/main/java/org/cryptomator/notify/AppEvent.java @@ -0,0 +1,3 @@ +package org.cryptomator.notify; + +public record AppEvent() implements Event {} diff --git a/src/main/java/org/cryptomator/notify/Event.java b/src/main/java/org/cryptomator/notify/Event.java new file mode 100644 index 000000000..a2dda9559 --- /dev/null +++ b/src/main/java/org/cryptomator/notify/Event.java @@ -0,0 +1,5 @@ +package org.cryptomator.notify; + +public sealed interface Event permits AppEvent, VaultEvent { + +} diff --git a/src/main/java/org/cryptomator/notify/NotificationHandler.java b/src/main/java/org/cryptomator/notify/NotificationHandler.java new file mode 100644 index 000000000..48936e30b --- /dev/null +++ b/src/main/java/org/cryptomator/notify/NotificationHandler.java @@ -0,0 +1,15 @@ +package org.cryptomator.notify; + +import org.cryptomator.integrations.common.IntegrationsLoader; + +import java.util.ServiceLoader; +import java.util.stream.Stream; + +public interface NotificationHandler { + + Answer handle(Event e); + + static Stream loadAll() { + return IntegrationsLoader.loadAll(ServiceLoader.load(NotificationHandler.class), NotificationHandler.class); + } +} diff --git a/src/main/java/org/cryptomator/notify/VaultEvent.java b/src/main/java/org/cryptomator/notify/VaultEvent.java new file mode 100644 index 000000000..6c2690494 --- /dev/null +++ b/src/main/java/org/cryptomator/notify/VaultEvent.java @@ -0,0 +1,7 @@ +package org.cryptomator.notify; + +import org.cryptomator.cryptofs.event.FilesystemEvent; + +public record VaultEvent(String vaultId, String path, FilesystemEvent actualEvent) implements Event { + +} diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java new file mode 100644 index 000000000..8ac56320b --- /dev/null +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java @@ -0,0 +1,3 @@ +package org.cryptomator.ui.eventviewer; + +public interface EventViewerComponent {} From 44fe4a6f8ad422521f277d8ff241b9e022fadcc1 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 11 Feb 2025 17:37:04 +0100 Subject: [PATCH 002/139] displayable event view window --- .../org/cryptomator/ui/common/FxmlFile.java | 1 + .../ui/controls/FontAwesome5Icon.java | 1 + .../ui/eventviewer/EventViewController.java | 14 +++++ .../ui/eventviewer/EventViewerComponent.java | 34 ++++++++++- .../ui/eventviewer/EventViewerModule.java | 57 +++++++++++++++++++ .../ui/eventviewer/EventViewerScoped.java | 13 +++++ .../ui/eventviewer/EventViewerWindow.java | 14 +++++ .../ui/fxapp/FxApplicationModule.java | 4 +- .../ui/fxapp/FxApplicationWindows.java | 10 ++++ .../ui/mainwindow/VaultListController.java | 4 ++ src/main/resources/fxml/eventviewer.fxml | 32 +++++++++++ src/main/resources/fxml/vault_list.fxml | 5 ++ 12 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/cryptomator/ui/eventviewer/EventViewController.java create mode 100644 src/main/java/org/cryptomator/ui/eventviewer/EventViewerModule.java create mode 100644 src/main/java/org/cryptomator/ui/eventviewer/EventViewerScoped.java create mode 100644 src/main/java/org/cryptomator/ui/eventviewer/EventViewerWindow.java create mode 100644 src/main/resources/fxml/eventviewer.fxml diff --git a/src/main/java/org/cryptomator/ui/common/FxmlFile.java b/src/main/java/org/cryptomator/ui/common/FxmlFile.java index 6bf8ac7db..a45e21307 100644 --- a/src/main/java/org/cryptomator/ui/common/FxmlFile.java +++ b/src/main/java/org/cryptomator/ui/common/FxmlFile.java @@ -13,6 +13,7 @@ public enum FxmlFile { CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), // CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), // ERROR("/fxml/error.fxml"), // + EVENT_VIEWER("/fxml/eventviewer.fxml"), // FORGET_PASSWORD("/fxml/forget_password.fxml"), // HEALTH_START("/fxml/health_start.fxml"), // HEALTH_CHECK_LIST("/fxml/health_check_list.fxml"), // diff --git a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java index 485e89304..b5a736da8 100644 --- a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java +++ b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java @@ -7,6 +7,7 @@ public enum FontAwesome5Icon { ANCHOR("\uF13D"), // ARROW_UP("\uF062"), // BAN("\uF05E"), // + BELL("\uF0F3"), // BUG("\uF188"), // CARET_DOWN("\uF0D7"), // CARET_RIGHT("\uF0Da"), // diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewController.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewController.java new file mode 100644 index 000000000..2a0921921 --- /dev/null +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewController.java @@ -0,0 +1,14 @@ +package org.cryptomator.ui.eventviewer; + +import org.cryptomator.ui.common.FxController; + +import javax.inject.Inject; + +@EventViewerScoped +public class EventViewController implements FxController { + + @Inject + public EventViewController() { + + } +} diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java index 8ac56320b..2aa788e21 100644 --- a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerComponent.java @@ -1,3 +1,35 @@ package org.cryptomator.ui.eventviewer; -public interface EventViewerComponent {} +import dagger.BindsInstance; +import dagger.Lazy; +import dagger.Subcomponent; +import org.cryptomator.ui.common.FxmlFile; +import org.cryptomator.ui.common.FxmlScene; + +import javax.inject.Named; +import javafx.scene.Scene; +import javafx.stage.Stage; + +@EventViewerScoped +@Subcomponent(modules = {EventViewerModule.class}) +public interface EventViewerComponent { + + @EventViewerWindow + Stage window(); + + @FxmlScene(FxmlFile.EVENT_VIEWER) + Lazy scene(); + + default void showEventViewerWindow() { + Stage stage = window(); + stage.setScene(scene().get()); + stage.sizeToScene(); + stage.show(); + } + + @Subcomponent.Factory + interface Factory { + + EventViewerComponent create(@BindsInstance @Named("owner") Stage owner); + } +} diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerModule.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerModule.java new file mode 100644 index 000000000..1b552f41a --- /dev/null +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerModule.java @@ -0,0 +1,57 @@ +package org.cryptomator.ui.eventviewer; + +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.StageFactory; + +import javax.inject.Named; +import javax.inject.Provider; +import javafx.scene.Scene; +import javafx.stage.Modality; +import javafx.stage.Stage; +import java.util.Map; +import java.util.ResourceBundle; + +@Module +abstract class EventViewerModule { + + @Provides + @EventViewerScoped + @EventViewerWindow + static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle, @Named("owner") Stage owner) { + Stage stage = factory.create(); + stage.setTitle("TODO EVENTVIEWER"); + stage.setResizable(true); + stage.initModality(Modality.WINDOW_MODAL); //TODO: or not modal at all? + stage.initOwner(owner); + return stage; + } + + @Provides + @EventViewerScoped + @EventViewerWindow + static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) { + return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle); + } + + @Binds + @IntoMap + @FxControllerKey(EventViewController.class) + abstract FxController bindEventViewController(EventViewController controller); + + @Provides + @FxmlScene(FxmlFile.EVENT_VIEWER) + @EventViewerScoped + static Scene provideEventViewerScene(@EventViewerWindow FxmlLoaderFactory fxmlLoaders) { + return fxmlLoaders.createScene(FxmlFile.EVENT_VIEWER); + } + +} diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerScoped.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerScoped.java new file mode 100644 index 000000000..24570752a --- /dev/null +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerScoped.java @@ -0,0 +1,13 @@ +package org.cryptomator.ui.eventviewer; + +import javax.inject.Scope; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Scope +@Documented +@Retention(RetentionPolicy.RUNTIME) +@interface EventViewerScoped { + +} diff --git a/src/main/java/org/cryptomator/ui/eventviewer/EventViewerWindow.java b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerWindow.java new file mode 100644 index 000000000..eb67184bd --- /dev/null +++ b/src/main/java/org/cryptomator/ui/eventviewer/EventViewerWindow.java @@ -0,0 +1,14 @@ +package org.cryptomator.ui.eventviewer; + +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) +@interface EventViewerWindow { + +} diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java index af98e284c..37fb3e0f3 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java @@ -8,6 +8,7 @@ package org.cryptomator.ui.fxapp; import dagger.Module; import dagger.Provides; import org.cryptomator.ui.error.ErrorComponent; +import org.cryptomator.ui.eventviewer.EventViewerComponent; import org.cryptomator.ui.health.HealthCheckComponent; import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent; @@ -33,7 +34,8 @@ import java.io.InputStream; ErrorComponent.class, // HealthCheckComponent.class, // UpdateReminderComponent.class, // - ShareVaultComponent.class}) + ShareVaultComponent.class, // + EventViewerComponent.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 54acf62a3..b5d2a1973 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java @@ -7,6 +7,7 @@ import org.cryptomator.common.vaults.VaultState; import org.cryptomator.integrations.tray.TrayIntegrationProvider; import org.cryptomator.ui.dialogs.Dialogs; import org.cryptomator.ui.error.ErrorComponent; +import org.cryptomator.ui.eventviewer.EventViewerComponent; import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent; import org.cryptomator.ui.preferences.PreferencesComponent; @@ -51,6 +52,7 @@ public class FxApplicationWindows { private final UpdateReminderComponent.Factory updateReminderWindowFactory; private final LockComponent.Factory lockWorkflowFactory; private final ErrorComponent.Factory errorWindowFactory; + private final EventViewerComponent.Factory eventViewWindow; private final ExecutorService executor; private final VaultOptionsComponent.Factory vaultOptionsWindow; private final ShareVaultComponent.Factory shareVaultWindow; @@ -69,6 +71,7 @@ public class FxApplicationWindows { ErrorComponent.Factory errorWindowFactory, // VaultOptionsComponent.Factory vaultOptionsWindow, // ShareVaultComponent.Factory shareVaultWindow, // + EventViewerComponent.Factory eventViewWindow, // ExecutorService executor, // Dialogs dialogs) { this.primaryStage = primaryStage; @@ -80,6 +83,7 @@ public class FxApplicationWindows { this.updateReminderWindowFactory = updateReminderWindowFactory; this.lockWorkflowFactory = lockWorkflowFactory; this.errorWindowFactory = errorWindowFactory; + this.eventViewWindow = eventViewWindow; this.executor = executor; this.vaultOptionsWindow = vaultOptionsWindow; this.shareVaultWindow = shareVaultWindow; @@ -200,4 +204,10 @@ public class FxApplicationWindows { } } + public CompletionStage showEventViewer(@Nullable Stage owner) { + return CompletableFuture.supplyAsync(() -> { + eventViewWindow.create(owner).showEventViewerWindow(); + return null; + }, Platform::runLater); + } } diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 0c2c46204..8af7befe1 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -264,6 +264,10 @@ public class VaultListController implements FxController { appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY); } + @FXML + public void showEventViewer() { + appWindows.showEventViewer(mainWindow); + } // Getter and Setter public BooleanBinding emptyVaultListProperty() { diff --git a/src/main/resources/fxml/eventviewer.fxml b/src/main/resources/fxml/eventviewer.fxml new file mode 100644 index 000000000..fa268bb45 --- /dev/null +++ b/src/main/resources/fxml/eventviewer.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml index 161a29e87..2a82a514f 100644 --- a/src/main/resources/fxml/vault_list.fxml +++ b/src/main/resources/fxml/vault_list.fxml @@ -42,6 +42,11 @@ +