Jan-Peter Klein hai 11 meses
pai
achega
919dac6caa

+ 11 - 6
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<VaultSettings> 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<Date> lastUpdateReminder;
+	public final ObjectProperty<Date> lastSuccessfulUpdateCheck;
 	public final StringProperty latestVersion;
 
 	private Consumer<Settings> 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());

+ 7 - 2
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;

+ 25 - 23
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<String> updateCheckerService;
 	private final ObjectProperty<UpdateCheckState> state = new SimpleObjectProperty<>(UpdateCheckState.NOT_CHECKED);
-	private final ObjectProperty<LocalDateTime> updateCheckTimeProperty = new SimpleObjectProperty<>();
-	private final StringProperty timeDifferenceMessageProperty = new SimpleStringProperty();
+	private final ObjectProperty<Date> lastSuccessfulUpdateCheck = new SimpleObjectProperty<>();
+	private final StringProperty timeDifferenceMessage = new SimpleStringProperty();
 	private final Comparator<String> 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<LocalDateTime> updateCheckTimeProperty() {
-		return updateCheckTimeProperty;
+	public ObjectProperty<Date> lastSuccessfulUpdateCheckProperty() {
+		return lastSuccessfulUpdateCheck;
 	}
 
 	public StringProperty timeDifferenceMessageProperty() {
-		return timeDifferenceMessageProperty;
+		return timeDifferenceMessage;
 	}
 
 	public ObjectProperty<UpdateCheckState> updateCheckStateProperty() {

+ 20 - 12
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<ContentDisplay> checkForUpdatesButtonState;
 	private final ReadOnlyStringProperty latestVersion;
-	private final ObjectProperty<LocalDateTime> updateCheckDate;
+	private final ObjectProperty<Date> lastSuccessfulUpdateCheck;
 	private final ReadOnlyStringProperty timeDifferenceMessage;
 	private final String currentVersion;
 	private final BooleanBinding updateAvailable;
 	private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false);
-	private final ObjectProperty<UpdateChecker.UpdateCheckState> updateCheckStateProperty;
+	private final ObjectProperty<UpdateChecker.UpdateCheckState> 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<LocalDateTime> updateCheckDateProperty() {
-		return updateCheckDate;
+	public ObjectProperty<Date> 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() {

+ 5 - 3
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();

+ 1 - 1
src/main/resources/fxml/preferences_updates.fxml

@@ -43,7 +43,7 @@
 		</HBox>
 		<FormattedLabel format="%preferences.updates.lastUpdateCheck" arg1="${controller.timeDifferenceMessage}" textAlignment="CENTER" wrapText="true">
 			<tooltip>
-				<Tooltip text="${controller.updateCheckDate}" showDelay="10ms"/>
+				<Tooltip text="${controller.lastSuccessfulUpdateCheck}" showDelay="10ms"/>
 			</tooltip>
 		</FormattedLabel>
 		<Label fx:id="upToDateLabel" text="%preferences.updates.upToDate" visible="${controller.upToDateLabelVisible}" managed="${controller.upToDateLabelVisible}">