From b16f32ca8390798ec6fddbf01d85100be409135f Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 29 Apr 2024 10:34:17 +0200 Subject: [PATCH] introduced new dependency removed latestVersion from Settings changed SettingsJson from Date to Instant new UpdateChecker Property checkFailed optimized naming changed wordning refactoring --- pom.xml | 7 +++++++ src/main/java/module-info.java | 1 + .../cryptomator/common/settings/Settings.java | 16 +++++----------- .../common/settings/SettingsJson.java | 13 +++++-------- .../common/settings/SettingsProvider.java | 3 ++- .../org/cryptomator/ui/fxapp/UpdateChecker.java | 7 +++++-- .../UpdatesPreferencesController.java | 16 +++++++++------- .../updatereminder/UpdateReminderComponent.java | 3 ++- src/main/resources/fxml/preferences_updates.fxml | 15 +++++++++------ src/main/resources/i18n/strings.properties | 2 +- 10 files changed, 46 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index 0ddf03d29..f50685384 100644 --- a/pom.xml +++ b/pom.xml @@ -164,11 +164,18 @@ nimbus-jose-jwt ${nimbus-jose.version} + + com.fasterxml.jackson.core jackson-databind ${jackson.version} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index b353b7a8a..cfac6bbeb 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -39,6 +39,7 @@ open module org.cryptomator.desktop { requires com.auth0.jwt; requires com.google.common; requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.datatype.jsr310; requires com.nimbusds.jose.jwt; requires com.nulabinc.zxcvbn; requires com.tobiasdiez.easybind; diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java index f17a1f802..be0361153 100644 --- a/src/main/java/org/cryptomator/common/settings/Settings.java +++ b/src/main/java/org/cryptomator/common/settings/Settings.java @@ -26,7 +26,6 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.geometry.NodeOrientation; import java.time.Instant; -import java.util.Date; import java.util.function.Consumer; public class Settings { @@ -46,8 +45,7 @@ public class Settings { static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess"; static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name(); static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false; - static final Instant DEFAULT_LAST_UPDATE_REMINDER = Instant.ofEpochSecond(946681200); //2000-01-01T00:00:00Z - public static final Instant DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK = Instant.ofEpochSecond(946681200); //2000-01-01T00:00:00Z + 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; @@ -71,7 +69,6 @@ public class Settings { public final StringProperty mountService; public final ObjectProperty lastUpdateReminder; public final ObjectProperty lastSuccessfulUpdateCheck; - public final StringProperty latestVersion; private Consumer saveCmd; @@ -108,9 +105,8 @@ public class Settings { this.windowHeight = new SimpleIntegerProperty(this, "windowHeight", json.windowHeight); this.language = new SimpleStringProperty(this, "language", json.language); this.mountService = new SimpleStringProperty(this, "mountService", json.mountService); - this.lastUpdateReminder = new SimpleObjectProperty<>(this, "lastUpdateReminder", json.lastUpdateReminder.toInstant()); - this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck.toInstant()); - this.latestVersion = new SimpleStringProperty(this, "latestVersion", json.latestVersion); + this.lastUpdateReminder = new SimpleObjectProperty<>(this, "lastUpdateReminder", json.lastUpdateReminder); + this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck); this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList()); @@ -139,7 +135,6 @@ public class Settings { mountService.addListener(this::somethingChanged); lastUpdateReminder.addListener(this::somethingChanged); lastSuccessfulUpdateCheck.addListener(this::somethingChanged); - latestVersion.addListener(this::somethingChanged); } @SuppressWarnings("deprecation") @@ -193,9 +188,8 @@ public class Settings { json.windowHeight = windowHeight.get(); json.language = language.get(); json.mountService = mountService.get(); - json.lastUpdateReminder = Date.from(lastUpdateReminder.get()); - json.lastSuccessfulUpdateCheck = Date.from(lastSuccessfulUpdateCheck.get()); - json.latestVersion = latestVersion.get(); + json.lastUpdateReminder = lastUpdateReminder.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 ebaf841ed..0acd72fe7 100644 --- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java +++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Date; +import java.time.Instant; import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) @@ -83,14 +83,11 @@ class SettingsJson { String preferredVolumeImpl; @JsonProperty("lastUpdateReminder") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - Date lastUpdateReminder = Date.from(Settings.DEFAULT_LAST_UPDATE_REMINDER); + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC") + Instant lastUpdateReminder = Settings.DEFAULT_TIMESTAMP; @JsonProperty("lastSuccessfulUpdateCheck") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss z") - Date lastSuccessfulUpdateCheck = Date.from(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK); - - @JsonProperty("latestVersion") - String latestVersion; + @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/common/settings/SettingsProvider.java b/src/main/java/org/cryptomator/common/settings/SettingsProvider.java index 586708ed1..a33b51027 100644 --- a/src/main/java/org/cryptomator/common/settings/SettingsProvider.java +++ b/src/main/java/org/cryptomator/common/settings/SettingsProvider.java @@ -10,6 +10,7 @@ package org.cryptomator.common.settings; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.google.common.base.Suppliers; import org.cryptomator.common.Environment; import org.slf4j.Logger; @@ -36,7 +37,7 @@ import java.util.stream.Stream; @Singleton public class SettingsProvider implements Supplier { - private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true); + private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true).registerModule(new JavaTimeModule()); private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class); private static final long SAVE_DELAY_MS = 1000; diff --git a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java index 32267f27c..0d266dd02 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java +++ b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java @@ -35,6 +35,7 @@ public class UpdateChecker { private final ObjectProperty lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(); private final Comparator versionComparator = new SemVerComparator(); private final BooleanBinding updateAvailable; + private final BooleanBinding checkFailed; @Inject UpdateChecker(Settings settings, // @@ -43,13 +44,13 @@ public class UpdateChecker { this.env = env; this.settings = settings; this.updateCheckerService = updateCheckerService; - this.latestVersion.bindBidirectional(settings.latestVersion); this.lastSuccessfulUpdateCheck.bindBidirectional(settings.lastSuccessfulUpdateCheck); this.updateAvailable = Bindings.createBooleanBinding(() -> { var latestVersion = this.latestVersion.get(); return latestVersion != null && versionComparator.compare(getCurrentVersion(), latestVersion) < 0; }, latestVersion); + this.checkFailed = Bindings.createBooleanBinding(() -> state.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED).get(), state); } public void automaticallyCheckForUpdatesIfEnabled() { @@ -87,7 +88,6 @@ public class UpdateChecker { private void checkFailed(WorkerStateEvent event) { state.set(UpdateCheckState.CHECK_FAILED); - LOG.warn("Error checking for updates", event.getSource().getException()); } public enum UpdateCheckState { @@ -109,6 +109,9 @@ public class UpdateChecker { public BooleanBinding updateAvailableProperty() { return updateAvailable; } + public BooleanBinding checkFailedProperty() { + return checkFailed; + } public boolean isUpdateAvailable() { return updateAvailable.get(); diff --git a/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java index e5597db08..ebfee8689 100644 --- a/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java @@ -47,10 +47,11 @@ public class UpdatesPreferencesController implements FxController { private final ObservableValue timeDifferenceMessage; private final String currentVersion; private final BooleanBinding updateAvailable; + private final BooleanBinding checkFailed; private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false); private final ObjectProperty updateCheckState; private final DateTimeFormatter formatter; - private final BooleanBinding isUpdateSuccessfulAndCurrent; + private final BooleanBinding upToDate; /* FXML */ public CheckBox checkForUpdatesCheckbox; @@ -72,13 +73,14 @@ public class UpdatesPreferencesController implements FxController { this.updateAvailable = updateChecker.updateAvailableProperty(); this.updateCheckState = updateChecker.updateCheckStateProperty(); this.formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault()); - this.isUpdateSuccessfulAndCurrent = updateCheckState.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion)); + this.upToDate = updateCheckState.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion)); + this.checkFailed = updateChecker.checkFailedProperty(); } public void initialize() { checkForUpdatesCheckbox.selectedProperty().bindBidirectional(settings.checkForUpdates); - isUpdateSuccessfulAndCurrent.addListener((_, _, newVal) -> { + upToDate.addListener((_, _, newVal) -> { if (newVal) { upToDateLabelVisible.set(true); PauseTransition delay = new PauseTransition(javafx.util.Duration.seconds(5)); @@ -131,7 +133,7 @@ public class UpdatesPreferencesController implements FxController { public String getLastSuccessfulUpdateCheck() { Instant lastCheck = lastSuccessfulUpdateCheck.getValue(); - if (lastCheck != null && !lastCheck.equals(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK)) { + if (lastCheck != null && !lastCheck.equals(Settings.DEFAULT_TIMESTAMP)) { return formatter.format(LocalDateTime.ofInstant(lastCheck, ZoneId.systemDefault())); } else { return "-"; @@ -139,7 +141,7 @@ public class UpdatesPreferencesController implements FxController { } private String updateTimeDifferenceMessage(Instant lastSuccessCheck) { - if (lastSuccessCheck.equals(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK)) { + if (lastSuccessCheck.equals(Settings.DEFAULT_TIMESTAMP)) { return resourceBundle.getString("preferences.updates.lastUpdateCheck.never"); } @@ -180,11 +182,11 @@ public class UpdatesPreferencesController implements FxController { } public BooleanBinding checkFailedProperty() { - return updateCheckState.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED); + return checkFailed; } public boolean isCheckFailed() { - return checkFailedProperty().get(); + return checkFailed.get(); } } diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java index ffd127451..dfa1e5484 100644 --- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java +++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java @@ -25,7 +25,8 @@ public interface UpdateReminderComponent { default void checkAndShowUpdateReminderWindow() { var now = Instant.now(); - if (settings().lastUpdateReminder.get().isBefore(now.minus(Duration.ofDays(14))) && !settings().checkForUpdates.getValue()) { + var twoWeeksAgo = now.minus(Duration.ofDays(14)); + if (settings().lastUpdateReminder.get().isBefore(twoWeeksAgo) && !settings().checkForUpdates.getValue() && settings().lastSuccessfulUpdateCheck.get().isBefore(twoWeeksAgo)) { settings().lastUpdateReminder.set(now); Stage stage = window(); stage.setScene(updateReminderScene().get()); diff --git a/src/main/resources/fxml/preferences_updates.fxml b/src/main/resources/fxml/preferences_updates.fxml index 66e15d695..97c917603 100644 --- a/src/main/resources/fxml/preferences_updates.fxml +++ b/src/main/resources/fxml/preferences_updates.fxml @@ -12,6 +12,8 @@ + + - - + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index cbefacd21..0fbe68ca8 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -326,7 +326,7 @@ preferences.updates.lastUpdateCheck.never=never preferences.updates.lastUpdateCheck.recently=recently preferences.updates.lastUpdateCheck.daysAgo=%s days ago preferences.updates.lastUpdateCheck.hoursAgo=%s hours ago -preferences.updates.checkFailed=Check failed +preferences.updates.checkFailed=Looking for updates failed. Please check your internet connection and try again later. preferences.updates.upToDate=Cryptomator is up-to-date. ## Contribution