فهرست منبع

Merge branch 'develop' into feature/event-view

Armin Schrenk 4 ماه پیش
والد
کامیت
f953be6237

+ 1 - 1
README.md

@@ -1,6 +1,6 @@
 [![cryptomator](cryptomator.png)](https://cryptomator.org/)
 
-[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
+[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions/workflows/build.yml?query=branch%3Adevelop)
 [![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg)](https://snyk.io/test/github/cryptomator/cryptomator)
 [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=cryptomator_cryptomator&metric=alert_status)](https://sonarcloud.io/dashboard?id=cryptomator_cryptomator)
 [![Mastodon](https://img.shields.io/mastodon/follow/176112?domain=mastodon.online&style=flat)](https://mastodon.online/@cryptomator)

+ 1 - 1
pom.xml

@@ -61,7 +61,7 @@
 
 		<!-- build-time dependencies -->
 		<jetbrains.annotations.version>26.0.1</jetbrains.annotations.version>
-		<dependency-check.version>12.0.1</dependency-check.version>
+		<dependency-check.version>12.1.0</dependency-check.version>
 		<jacoco.version>0.8.12</jacoco.version>
 		<license-generator.version>2.5.0</license-generator.version>
 		<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>

+ 2 - 2
src/main/java/org/cryptomator/ui/fxapp/AutoUnlocker.java

@@ -43,8 +43,8 @@ public class AutoUnlocker {
 	private CompletionStage<Void> unlockSequentially(Stream<Vault> vaultStream) {
 		// this is an attempt to run all the unlock workflows sequentially, i.e. start the next workflow only after completing/failing the previous workflow.
 		return vaultStream.filter(Vault::isLocked).reduce(CompletableFuture.completedFuture(null),
-				(prevUnlock, nextVault) -> prevUnlock.thenCompose(unused -> appWindows.startUnlockWorkflow(nextVault, null)),
-				(prevUnlock, nextUnlock) -> nextUnlock.exceptionally(e -> null) // we don't care here about the exception, logged elsewhere
+				(prevUnlock, nextVault) -> prevUnlock.thenCompose(_ -> appWindows.startUnlockWorkflow(nextVault, null)),
+				(_, nextUnlock) -> nextUnlock.exceptionally(_ -> null) // we don't care here about the exception, logged elsewhere
 				);
 	}
 

+ 16 - 14
src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java

@@ -6,6 +6,7 @@ import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.common.vaults.VaultState;
 import org.cryptomator.integrations.tray.TrayIntegrationProvider;
 import org.cryptomator.ui.dialogs.Dialogs;
+import org.cryptomator.ui.dialogs.SimpleDialog;
 import org.cryptomator.ui.error.ErrorComponent;
 import org.cryptomator.ui.eventview.EventViewComponent;
 import org.cryptomator.ui.lock.LockComponent;
@@ -97,17 +98,17 @@ public class FxApplicationWindows {
 
 		// register preferences shortcut
 		if (desktop.isSupported(Desktop.Action.APP_PREFERENCES)) {
-			desktop.setPreferencesHandler(evt -> showPreferencesWindow(SelectedPreferencesTab.ANY));
+			desktop.setPreferencesHandler(_ -> showPreferencesWindow(SelectedPreferencesTab.ANY));
 		}
 
 		// register preferences shortcut
 		if (desktop.isSupported(Desktop.Action.APP_ABOUT)) {
-			desktop.setAboutHandler(evt -> showPreferencesWindow(SelectedPreferencesTab.ABOUT));
+			desktop.setAboutHandler(_ -> showPreferencesWindow(SelectedPreferencesTab.ABOUT));
 		}
 
 		// register app reopen listener
 		if (desktop.isSupported(Desktop.Action.APP_EVENT_REOPENED)) {
-			desktop.addAppEventListener((AppReopenedListener) e -> showMainWindow());
+			desktop.addAppEventListener((AppReopenedListener) _ -> showMainWindow());
 		}
 
 		// observe visible windows
@@ -139,11 +140,12 @@ public class FxApplicationWindows {
 	}
 
 	public CompletionStage<Stage> showVaultOptionsWindow(Vault vault, SelectedVaultOptionsTab tab) {
-		return showMainWindow().thenApplyAsync((window) -> vaultOptionsWindow.create(vault).showVaultOptionsWindow(tab), Platform::runLater).whenComplete(this::reportErrors);
+		return showMainWindow().thenApplyAsync(_ -> vaultOptionsWindow.create(vault).showVaultOptionsWindow(tab), Platform::runLater) //
+				.whenComplete(this::reportErrors);
 	}
 
 	public void showQuitWindow(QuitResponse response, boolean forced) {
-			CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater);
+		CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response, forced), Platform::runLater);
 	}
 
 	public void showUpdateReminderWindow() {
@@ -151,13 +153,14 @@ public class FxApplicationWindows {
 	}
 
 	public void showDokanySupportEndWindow() {
-		CompletableFuture.runAsync(() -> dialogs.prepareDokanySupportEndDialog(
-				mainWindow.get().window(),
-				stage -> {
-					showPreferencesWindow(SelectedPreferencesTab.VOLUME);
-					stage.close();
-				}
-		).build().showAndWait(), Platform::runLater);
+		CompletableFuture.runAsync(() -> createDokanySupportEndDialog().showAndWait(), Platform::runLater);
+	}
+
+	private SimpleDialog createDokanySupportEndDialog() {
+		return dialogs.prepareDokanySupportEndDialog(mainWindow.get().window(), stage -> {
+			showPreferencesWindow(SelectedPreferencesTab.VOLUME);
+			stage.close();
+		}).build();
 	}
 
 	public CompletionStage<Void> startUnlockWorkflow(Vault vault, @Nullable Stage owner) {
@@ -166,8 +169,7 @@ public class FxApplicationWindows {
 					LOG.debug("Start unlock workflow for {}", vault.getDisplayName());
 					return unlockWorkflowFactory.create(vault, owner).unlockWorkflow();
 				}, Platform::runLater) //
-				.thenAcceptAsync(UnlockWorkflow::run, executor)
-				.exceptionally(e -> {
+				.thenAcceptAsync(UnlockWorkflow::run, executor).exceptionally(e -> {
 					showErrorWindow(e, owner == null ? primaryStage : owner, null);
 					return null;
 				});

+ 12 - 1
src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -1,6 +1,7 @@
 package org.cryptomator.ui.mainwindow;
 
 import dagger.Binds;
+import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
 import dagger.multibindings.IntoMap;
@@ -14,9 +15,11 @@ import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.common.StageFactory;
 import org.cryptomator.ui.common.StageInitializer;
 import org.cryptomator.ui.error.ErrorComponent;
+import org.cryptomator.ui.fxapp.FxApplicationTerminator;
 import org.cryptomator.ui.fxapp.PrimaryStage;
 import org.cryptomator.ui.migration.MigrationComponent;
 import org.cryptomator.ui.stats.VaultStatisticsComponent;
+import org.cryptomator.ui.traymenu.TrayMenuComponent;
 import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
 
 import javax.inject.Named;
@@ -35,11 +38,19 @@ abstract class MainWindowModule {
 	@Provides
 	@MainWindow
 	@MainWindowScoped
-	static Stage provideMainWindow(@PrimaryStage Stage stage, StageInitializer initializer) {
+	static Stage provideMainWindow(@PrimaryStage Stage stage, StageInitializer initializer, FxApplicationTerminator terminator, Lazy<TrayMenuComponent> trayMenu) {
 		initializer.accept(stage);
 		stage.setTitle("Cryptomator");
 		stage.setMinWidth(650);
 		stage.setMinHeight(498);
+		stage.setOnCloseRequest(e -> {
+			if (!trayMenu.get().isInitialized()) {
+				terminator.terminate();
+				e.consume();
+			} else {
+				stage.close();
+			}
+		});
 		return stage;
 	}
 

+ 10 - 3
src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java

@@ -19,6 +19,8 @@ import javafx.beans.value.ObservableValue;
 import javafx.fxml.FXML;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.ContentDisplay;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDateTime;
@@ -32,7 +34,10 @@ import java.util.ResourceBundle;
 @PreferencesScoped
 public class UpdatesPreferencesController implements FxController {
 
-	private static final String DOWNLOADS_URI = "https://cryptomator.org/downloads";
+	private static final String DOWNLOADS_URI_TEMPLATE = "https://cryptomator.org/downloads/" //
+			+ "?utm_source=cryptomator-desktop" //
+			+ "&utm_medium=update-notification&" //
+			+ "utm_campaign=app-update-%s";
 
 	private final Application application;
 	private final Environment environment;
@@ -50,6 +55,7 @@ public class UpdatesPreferencesController implements FxController {
 	private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false);
 	private final DateTimeFormatter formatter;
 	private final BooleanBinding upToDate;
+	private final String downloadsUri;
 
 	/* FXML */
 	public CheckBox checkForUpdatesCheckbox;
@@ -65,12 +71,13 @@ public class UpdatesPreferencesController implements FxController {
 		this.latestVersion = updateChecker.latestVersionProperty();
 		this.lastSuccessfulUpdateCheck = updateChecker.lastSuccessfulUpdateCheckProperty();
 		this.timeDifferenceMessage = Bindings.createStringBinding(this::getTimeDifferenceMessage, lastSuccessfulUpdateCheck);
-		this.currentVersion = updateChecker.getCurrentVersion();
+		this.currentVersion = environment.getAppVersion();
 		this.updateAvailable = updateChecker.updateAvailableProperty();
 		this.formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault());
 		this.upToDate = updateChecker.updateCheckStateProperty().isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion));
 		this.checkFailed = updateChecker.checkFailedProperty();
 		this.lastUpdateCheckMessage = Bindings.createStringBinding(this::getLastUpdateCheckMessage, lastSuccessfulUpdateCheck);
+		this.downloadsUri = DOWNLOADS_URI_TEMPLATE.formatted(URLEncoder.encode(currentVersion, StandardCharsets.US_ASCII));
 	}
 
 	public void initialize() {
@@ -93,7 +100,7 @@ public class UpdatesPreferencesController implements FxController {
 
 	@FXML
 	public void visitDownloadsPage() {
-		application.getHostServices().showDocument(DOWNLOADS_URI);
+		application.getHostServices().showDocument(downloadsUri);
 	}
 
 	@FXML