From 8aed6045a01aaf2932ad1d3a62107fb0cec042d5 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 15 Nov 2024 18:14:57 +0100 Subject: [PATCH] Feature: Show update reminder every 14 days (#3597) fixes #3596 only show update reminder every 14 days --- .../cryptomator/common/settings/Settings.java | 18 +++++++++--------- .../common/settings/SettingsJson.java | 13 +++++++------ .../cryptomator/ui/fxapp/FxApplication.java | 10 ++++++++-- .../ui/fxapp/FxApplicationWindows.java | 10 +++++----- .../UpdateReminderComponent.java | 18 +++++------------- .../UpdateReminderController.java | 6 ++++++ 6 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java index e30389360..907d99885 100644 --- a/src/main/java/org/cryptomator/common/settings/Settings.java +++ b/src/main/java/org/cryptomator/common/settings/Settings.java @@ -32,7 +32,6 @@ public class Settings { private static final Logger LOG = LoggerFactory.getLogger(Settings.class); - static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false; static final boolean DEFAULT_CHECK_FOR_UPDATES = false; static final boolean DEFAULT_START_HIDDEN = false; static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false; @@ -51,9 +50,8 @@ public class Settings { static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name(); public static final Instant DEFAULT_TIMESTAMP = Instant.parse("2000-01-01T00:00:00Z"); + public final ObservableList directories; - public final BooleanProperty askedForUpdateCheck; - public final BooleanProperty checkForUpdates; public final BooleanProperty startHidden; public final BooleanProperty autoCloseVaults; public final BooleanProperty useKeychain; @@ -74,6 +72,8 @@ public class Settings { public final IntegerProperty windowHeight; public final StringProperty language; public final StringProperty mountService; + public final BooleanProperty checkForUpdates; + public final ObjectProperty lastUpdateCheckReminder; public final ObjectProperty lastSuccessfulUpdateCheck; private Consumer saveCmd; @@ -91,8 +91,6 @@ public class Settings { */ Settings(SettingsJson json) { this.directories = FXCollections.observableArrayList(VaultSettings::observables); - this.askedForUpdateCheck = new SimpleBooleanProperty(this, "askedForUpdateCheck", json.askedForUpdateCheck); - this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled); this.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden); this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults); this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain); @@ -113,6 +111,8 @@ public class Settings { this.language = new SimpleStringProperty(this, "language", json.language); this.mountService = new SimpleStringProperty(this, "mountService", json.mountService); this.quickAccessService = new SimpleStringProperty(this, "quickAccessService", json.quickAccessService); + this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled); + this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck); this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck); this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList()); @@ -120,8 +120,6 @@ public class Settings { migrateLegacySettings(json); directories.addListener(this::somethingChanged); - askedForUpdateCheck.addListener(this::somethingChanged); - checkForUpdates.addListener(this::somethingChanged); startHidden.addListener(this::somethingChanged); autoCloseVaults.addListener(this::somethingChanged); useKeychain.addListener(this::somethingChanged); @@ -142,6 +140,8 @@ public class Settings { language.addListener(this::somethingChanged); mountService.addListener(this::somethingChanged); quickAccessService.addListener(this::somethingChanged); + checkForUpdates.addListener(this::somethingChanged); + lastUpdateCheckReminder.addListener(this::somethingChanged); lastSuccessfulUpdateCheck.addListener(this::somethingChanged); } @@ -176,8 +176,6 @@ public class Settings { SettingsJson serialized() { var json = new SettingsJson(); json.directories = directories.stream().map(VaultSettings::serialized).toList(); - json.askedForUpdateCheck = askedForUpdateCheck.get(); - json.checkForUpdatesEnabled = checkForUpdates.get(); json.startHidden = startHidden.get(); json.autoCloseVaults = autoCloseVaults.get(); json.useKeychain = useKeychain.get(); @@ -198,6 +196,8 @@ public class Settings { json.language = language.get(); json.mountService = mountService.get(); json.quickAccessService = quickAccessService.get(); + json.checkForUpdatesEnabled = checkForUpdates.get(); + json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get(); json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get(); return json; } diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJson.java b/src/main/java/org/cryptomator/common/settings/SettingsJson.java index 5a98ca91c..15f5f2790 100644 --- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java +++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java @@ -18,15 +18,9 @@ class SettingsJson { @JsonProperty("writtenByVersion") String writtenByVersion; - @JsonProperty("askedForUpdateCheck") - boolean askedForUpdateCheck = Settings.DEFAULT_ASKED_FOR_UPDATE_CHECK; - @JsonProperty("autoCloseVaults") boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS; - @JsonProperty("checkForUpdatesEnabled") - boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES; - @JsonProperty("debugMode") boolean debugMode = Settings.DEFAULT_DEBUG_MODE; @@ -82,6 +76,13 @@ class SettingsJson { @JsonProperty(value = "preferredVolumeImpl", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233 String preferredVolumeImpl; + @JsonProperty("checkForUpdatesEnabled") + boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES; + + @JsonProperty("lastReminderForUpdateCheck") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC") + Instant lastReminderForUpdateCheck = Settings.DEFAULT_TIMESTAMP; + @JsonProperty("lastSuccessfulUpdateCheck") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC") Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP; diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 30e40ea8c..fd480033c 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -11,6 +11,8 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import javafx.application.Platform; +import java.time.Duration; +import java.time.Instant; import java.util.concurrent.TimeUnit; @FxApplicationScoped @@ -72,8 +74,12 @@ public class FxApplication { return null; }); - if (!environment.disableUpdateCheck()) { - appWindows.checkAndShowUpdateReminderWindow(); + var time14DaysAgo = Instant.now().minus(Duration.ofDays(14)); + if (!environment.disableUpdateCheck() // + && !settings.checkForUpdates.getValue() // + && settings.lastSuccessfulUpdateCheck.get().isBefore(time14DaysAgo) // + && settings.lastUpdateCheckReminder.get().isBefore(time14DaysAgo)) { + appWindows.showUpdateReminderWindow(); } migrateAndInformDokanyRemoval(); diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java index 33d8491a7..fcea61df6 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java @@ -48,7 +48,7 @@ public class FxApplicationWindows { private final Lazy preferencesWindow; private final QuitComponent.Builder quitWindowBuilder; private final UnlockComponent.Factory unlockWorkflowFactory; - private final UpdateReminderComponent.Factory updateReminderWindowBuilder; + private final UpdateReminderComponent.Factory updateReminderWindowFactory; private final DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder; private final LockComponent.Factory lockWorkflowFactory; private final ErrorComponent.Factory errorWindowFactory; @@ -64,7 +64,7 @@ public class FxApplicationWindows { Lazy preferencesWindow, // QuitComponent.Builder quitWindowBuilder, // UnlockComponent.Factory unlockWorkflowFactory, // - UpdateReminderComponent.Factory updateReminderWindowBuilder, // + UpdateReminderComponent.Factory updateReminderWindowFactory, // DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder, // LockComponent.Factory lockWorkflowFactory, // ErrorComponent.Factory errorWindowFactory, // @@ -77,7 +77,7 @@ public class FxApplicationWindows { this.preferencesWindow = preferencesWindow; this.quitWindowBuilder = quitWindowBuilder; this.unlockWorkflowFactory = unlockWorkflowFactory; - this.updateReminderWindowBuilder = updateReminderWindowBuilder; + this.updateReminderWindowFactory = updateReminderWindowFactory; this.dokanySupportEndWindowBuilder = dokanySupportEndWindowBuilder; this.lockWorkflowFactory = lockWorkflowFactory; this.errorWindowFactory = errorWindowFactory; @@ -142,8 +142,8 @@ public class FxApplicationWindows { CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater); } - public void checkAndShowUpdateReminderWindow() { - CompletableFuture.runAsync(() -> updateReminderWindowBuilder.create().checkAndShowUpdateReminderWindow(), Platform::runLater); + public void showUpdateReminderWindow() { + CompletableFuture.runAsync(() -> updateReminderWindowFactory.create().showUpdateReminderWindow(), Platform::runLater); } public void showDokanySupportEndWindow() { diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java index d2c10f8fd..c27c98382 100644 --- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java +++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java @@ -2,14 +2,11 @@ package org.cryptomator.ui.updatereminder; import dagger.Lazy; import dagger.Subcomponent; -import org.cryptomator.common.settings.Settings; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; import javafx.scene.Scene; import javafx.stage.Stage; -import java.time.Duration; -import java.time.Instant; @UpdateReminderScoped @Subcomponent(modules = {UpdateReminderModule.class}) @@ -21,16 +18,11 @@ public interface UpdateReminderComponent { @FxmlScene(FxmlFile.UPDATE_REMINDER) Lazy updateReminderScene(); - Settings settings(); - - default void checkAndShowUpdateReminderWindow() { - var now = Instant.now(); - if (!settings().checkForUpdates.getValue() && settings().lastSuccessfulUpdateCheck.get().isBefore(now.minus(Duration.ofDays(14)))) { - Stage stage = window(); - stage.setScene(updateReminderScene().get()); - stage.sizeToScene(); - stage.show(); - } + default void showUpdateReminderWindow() { + Stage stage = window(); + stage.setScene(updateReminderScene().get()); + stage.sizeToScene(); + stage.show(); } @Subcomponent.Factory diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java index 183298c44..a6fce0b79 100644 --- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java +++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java @@ -7,6 +7,7 @@ import org.cryptomator.ui.fxapp.UpdateChecker; import javax.inject.Inject; import javafx.fxml.FXML; import javafx.stage.Stage; +import java.time.Instant; @UpdateReminderScoped public class UpdateReminderController implements FxController { @@ -23,6 +24,11 @@ public class UpdateReminderController implements FxController { this.updateChecker = updateChecker; } + @FXML + public void initialize() { + settings.lastUpdateCheckReminder.set(Instant.now()); + } + @FXML public void cancel() { window.close();