From 919dac6caa926ef665afe4b9e5578a22e31284e8 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 22 Apr 2024 16:35:20 +0200 Subject: [PATCH] refactoring --- .../cryptomator/common/settings/Settings.java | 17 ++++--- .../common/settings/SettingsJson.java | 9 +++- .../cryptomator/ui/fxapp/UpdateChecker.java | 48 ++++++++++--------- .../UpdatesPreferencesController.java | 32 ++++++++----- .../UpdateReminderComponent.java | 8 ++-- .../resources/fxml/preferences_updates.fxml | 2 +- 6 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java index 3932dcb72..ef8398b01 100644 --- a/src/main/java/org/cryptomator/common/settings/Settings.java +++ b/src/main/java/org/cryptomator/common/settings/Settings.java @@ -25,6 +25,11 @@ import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.geometry.NodeOrientation; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Date; import java.util.function.Consumer; public class Settings { @@ -44,8 +49,8 @@ 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 String DEFAULT_LAST_UPDATE_REMINDER = "2000-01-01"; - public static final String DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK = "2000-01-01T00:00:00"; + static final Date DEFAULT_LAST_UPDATE_REMINDER = Date.from(LocalDate.of(2000,1,1).atStartOfDay(ZoneId.systemDefault()).toInstant()); + public static final Date DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK = Date.from(LocalDateTime.of(2000,1,1,1,0,0).toInstant(ZoneOffset.UTC)); public final ObservableList directories; public final BooleanProperty askedForUpdateCheck; public final BooleanProperty checkForUpdates; @@ -67,8 +72,8 @@ public class Settings { public final IntegerProperty windowHeight; public final StringProperty language; public final StringProperty mountService; - public final StringProperty lastUpdateReminder; - public final StringProperty lastSuccessfulUpdateCheck; + public final ObjectProperty lastUpdateReminder; + public final ObjectProperty lastSuccessfulUpdateCheck; public final StringProperty latestVersion; private Consumer saveCmd; @@ -106,8 +111,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 SimpleStringProperty(this, "lastUpdateReminder", json.lastUpdateReminder); - this.lastSuccessfulUpdateCheck = new SimpleStringProperty(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck); + this.lastUpdateReminder = new SimpleObjectProperty<>(this, "lastUpdateReminder", json.lastUpdateReminder); + this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck); this.latestVersion = new SimpleStringProperty(this, "latestVersion", json.latestVersion); this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList()); diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJson.java b/src/main/java/org/cryptomator/common/settings/SettingsJson.java index 4337089ae..e136e6f60 100644 --- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java +++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java @@ -1,9 +1,12 @@ package org.cryptomator.common.settings; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.LocalDate; +import java.util.Date; import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) @@ -81,10 +84,12 @@ class SettingsJson { String preferredVolumeImpl; @JsonProperty("lastUpdateReminder") - String lastUpdateReminder = Settings.DEFAULT_LAST_UPDATE_REMINDER; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + Date lastUpdateReminder = Settings.DEFAULT_LAST_UPDATE_REMINDER; @JsonProperty("lastSuccessfulUpdateCheck") - String lastSuccessfulUpdateCheck = Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") + Date lastSuccessfulUpdateCheck = Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK; @JsonProperty("latestVersion") String latestVersion; diff --git a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java index f9bb65719..d0768b1a8 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java +++ b/src/main/java/org/cryptomator/ui/fxapp/UpdateChecker.java @@ -18,8 +18,11 @@ import javafx.concurrent.ScheduledService; import javafx.concurrent.Worker; import javafx.concurrent.WorkerStateEvent; import javafx.util.Duration; + import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.Comparator; +import java.util.Date; import java.util.ResourceBundle; @FxApplicationScoped @@ -31,11 +34,11 @@ public class UpdateChecker { private final Environment env; private final Settings settings; private final ResourceBundle resourceBundle; - private final StringProperty latestVersionProperty = new SimpleStringProperty(); + private final StringProperty latestVersion = new SimpleStringProperty(); private final ScheduledService updateCheckerService; private final ObjectProperty state = new SimpleObjectProperty<>(UpdateCheckState.NOT_CHECKED); - private final ObjectProperty updateCheckTimeProperty = new SimpleObjectProperty<>(); - private final StringProperty timeDifferenceMessageProperty = new SimpleStringProperty(); + private final ObjectProperty lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(); + private final StringProperty timeDifferenceMessage = new SimpleStringProperty(); private final Comparator versionComparator = new SemVerComparator(); private final BooleanBinding updateAvailable; @@ -48,18 +51,18 @@ public class UpdateChecker { this.settings = settings; this.resourceBundle = resourceBundle; this.updateCheckerService = updateCheckerService; - this.latestVersionProperty.set(settings.latestVersion.get()); - this.updateCheckTimeProperty.set(LocalDateTime.parse(settings.lastSuccessfulUpdateCheck.get())); + this.latestVersion.set(settings.latestVersion.get()); + this.lastSuccessfulUpdateCheck.set(settings.lastSuccessfulUpdateCheck.get()); this.updateAvailable = Bindings.createBooleanBinding(() -> { - var latestVersion = latestVersionProperty.get(); + var latestVersion = this.latestVersion.get(); return latestVersion != null && versionComparator.compare(getCurrentVersion(), latestVersion) < 0; - }, latestVersionProperty); + }, latestVersion); updateTimeDifferenceMessage(); - this.latestVersionProperty.addListener((_, _, newValue) -> settings.latestVersion.set(newValue)); - this.updateCheckTimeProperty.addListener((_, _, newValue) -> settings.lastSuccessfulUpdateCheck.set(newValue.toString())); + this.latestVersion.addListener((_, _, newValue) -> settings.latestVersion.set(newValue)); + this.lastSuccessfulUpdateCheck.addListener((_, _, newValue) -> settings.lastSuccessfulUpdateCheck.set(newValue)); } public void automaticallyCheckForUpdatesIfEnabled() { @@ -83,23 +86,22 @@ public class UpdateChecker { } private void updateTimeDifferenceMessage() { - LocalDateTime updateCheckDate = updateCheckTimeProperty.get(); - if (updateCheckDate == null || updateCheckDate.equals(LocalDateTime.parse(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK))) { - timeDifferenceMessageProperty.set(resourceBundle.getString("preferences.updates.lastUpdateCheck.never")); + Date updateCheckDate = lastSuccessfulUpdateCheck.get(); + if (updateCheckDate == null || updateCheckDate.equals(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK)) { + timeDifferenceMessage.set(resourceBundle.getString("preferences.updates.lastUpdateCheck.never")); return; } - var duration = java.time.Duration.between(updateCheckDate, LocalDateTime.now()); + var duration = java.time.Duration.between(LocalDateTime.ofInstant(updateCheckDate.toInstant(), ZoneId.systemDefault()), LocalDateTime.now()); var hours = duration.toHours(); - var days = duration.toDays(); if (hours < 1) { - timeDifferenceMessageProperty.set(resourceBundle.getString("preferences.updates.lastUpdateCheck.recently")); + timeDifferenceMessage.set(resourceBundle.getString("preferences.updates.lastUpdateCheck.recently")); } else if (hours < 24) { - timeDifferenceMessageProperty.set(String.format(resourceBundle.getString("preferences.updates.lastUpdateCheck.hoursAgo"), hours)); + timeDifferenceMessage.set(String.format(resourceBundle.getString("preferences.updates.lastUpdateCheck.hoursAgo"), hours)); } else { - timeDifferenceMessageProperty.set(String.format(resourceBundle.getString("preferences.updates.lastUpdateCheck.daysAgo"), days)); + timeDifferenceMessage.set(String.format(resourceBundle.getString("preferences.updates.lastUpdateCheck.daysAgo"), duration.toDays())); } } @@ -111,9 +113,9 @@ public class UpdateChecker { private void checkSucceeded(WorkerStateEvent event) { String latestVersion = updateCheckerService.getValue(); LOG.info("Current version: {}, latest version: {}", getCurrentVersion(), latestVersion); - updateCheckTimeProperty.set(LocalDateTime.now()); + lastSuccessfulUpdateCheck.set(new Date()); updateTimeDifferenceMessage(); - latestVersionProperty.set(latestVersion); + this.latestVersion.set(latestVersion); state.set(UpdateCheckState.CHECK_SUCCESSFUL); } @@ -135,7 +137,7 @@ public class UpdateChecker { } public ReadOnlyStringProperty latestVersionProperty() { - return latestVersionProperty; + return latestVersion; } public BooleanBinding updateAvailableProperty(){ @@ -145,12 +147,12 @@ public class UpdateChecker { return updateAvailable.get(); } - public ObjectProperty updateCheckTimeProperty() { - return updateCheckTimeProperty; + public ObjectProperty lastSuccessfulUpdateCheckProperty() { + return lastSuccessfulUpdateCheck; } public StringProperty timeDifferenceMessageProperty() { - return timeDifferenceMessageProperty; + return timeDifferenceMessage; } public ObjectProperty updateCheckStateProperty() { diff --git a/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java index cc70fd66d..7463d5a19 100644 --- a/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/UpdatesPreferencesController.java @@ -22,8 +22,10 @@ import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.util.Duration; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; +import java.util.Date; import java.util.Locale; @@ -38,12 +40,12 @@ public class UpdatesPreferencesController implements FxController { private final UpdateChecker updateChecker; private final ObjectBinding checkForUpdatesButtonState; private final ReadOnlyStringProperty latestVersion; - private final ObjectProperty updateCheckDate; + private final ObjectProperty lastSuccessfulUpdateCheck; private final ReadOnlyStringProperty timeDifferenceMessage; private final String currentVersion; private final BooleanBinding updateAvailable; private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false); - private final ObjectProperty updateCheckStateProperty; + private final ObjectProperty updateCheckState; /* FXML */ public CheckBox checkForUpdatesCheckbox; @@ -58,19 +60,19 @@ public class UpdatesPreferencesController implements FxController { this.updateChecker = updateChecker; this.checkForUpdatesButtonState = Bindings.when(updateChecker.checkingForUpdatesProperty()).then(ContentDisplay.LEFT).otherwise(ContentDisplay.TEXT_ONLY); this.latestVersion = updateChecker.latestVersionProperty(); - this.updateCheckDate = updateChecker.updateCheckTimeProperty(); + this.lastSuccessfulUpdateCheck = updateChecker.lastSuccessfulUpdateCheckProperty(); this.timeDifferenceMessage = updateChecker.timeDifferenceMessageProperty(); this.currentVersion = updateChecker.getCurrentVersion(); this.updateAvailable = updateChecker.updateAvailableProperty(); - this.updateCheckStateProperty = updateChecker.updateCheckStateProperty(); + this.updateCheckState = updateChecker.updateCheckStateProperty(); } public void initialize() { checkForUpdatesCheckbox.selectedProperty().bindBidirectional(settings.checkForUpdates); - BooleanBinding isUpdateSuccessfulAndCurrent = updateCheckStateProperty.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion)); + BooleanBinding isUpdateSuccessfulAndCurrent = updateCheckState.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion)); - updateCheckStateProperty.addListener((_, _, _) -> { + updateCheckState.addListener((_, _, _) -> { if (isUpdateSuccessfulAndCurrent.get()) { upToDateLabelVisible.set(true); PauseTransition delay = new PauseTransition(Duration.seconds(5)); @@ -117,13 +119,19 @@ public class UpdatesPreferencesController implements FxController { return currentVersion; } - public ObjectProperty updateCheckDateProperty() { - return updateCheckDate; + public ObjectProperty lastSuccessfulUpdateCheckProperty() { + return lastSuccessfulUpdateCheck; } - public String getUpdateCheckDate() { - DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault()); - return !updateCheckDate.get().equals(LocalDateTime.parse(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK)) ? updateCheckDate.get().format(formatter) : "-"; + public String getLastSuccessfulUpdateCheck() { + Date date = lastSuccessfulUpdateCheck.get(); + if (date != null && !date.equals(Settings.DEFAULT_LAST_SUCCESSFUL_UPDATE_CHECK)) { + LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault()); + return formatter.format(localDateTime); + } else { + return "-"; + } } public ReadOnlyStringProperty timeDifferenceMessageProperty(){ @@ -151,7 +159,7 @@ public class UpdatesPreferencesController implements FxController { } public BooleanBinding checkFailedProperty() { - return updateCheckStateProperty.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED); + return updateCheckState.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED); } public boolean isCheckFailed() { diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java index 319a3e152..ef0381064 100644 --- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java +++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java @@ -10,7 +10,9 @@ import org.slf4j.LoggerFactory; import javafx.scene.Scene; import javafx.stage.Stage; -import java.time.LocalDate; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; @UpdateReminderScoped @Subcomponent(modules = {UpdateReminderModule.class}) @@ -27,8 +29,8 @@ public interface UpdateReminderComponent { Settings settings(); default void checkAndShowUpdateReminderWindow() { - if (LocalDate.parse(settings().lastUpdateReminder.get()).isBefore(LocalDate.now().minusDays(14)) && !settings().checkForUpdates.getValue()) { - settings().lastUpdateReminder.set(LocalDate.now().toString()); + if (settings().lastUpdateReminder.get().before(Date.from(Instant.now().minus(Duration.ofDays(14)))) && !settings().checkForUpdates.getValue()) { + settings().lastUpdateReminder.set(new Date()); Stage stage = window(); stage.setScene(updateReminderScene().get()); stage.sizeToScene(); diff --git a/src/main/resources/fxml/preferences_updates.fxml b/src/main/resources/fxml/preferences_updates.fxml index 398800e49..66e15d695 100644 --- a/src/main/resources/fxml/preferences_updates.fxml +++ b/src/main/resources/fxml/preferences_updates.fxml @@ -43,7 +43,7 @@ - +