introduced new dependency

removed latestVersion from Settings
changed SettingsJson from Date to Instant
new UpdateChecker Property checkFailed
optimized naming
changed wordning
refactoring
This commit is contained in:
Jan-Peter Klein 2024-04-29 10:34:17 +02:00
parent ae697d7b73
commit b16f32ca83
No known key found for this signature in database
GPG Key ID: 90EDA3A7C822FD0E
10 changed files with 46 additions and 37 deletions

View File

@ -164,11 +164,18 @@
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose.version}</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- EasyBind -->
<dependency>

View File

@ -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;

View File

@ -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<VaultSettings> directories;
public final BooleanProperty askedForUpdateCheck;
public final BooleanProperty checkForUpdates;
@ -71,7 +69,6 @@ public class Settings {
public final StringProperty mountService;
public final ObjectProperty<Instant> lastUpdateReminder;
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
public final StringProperty latestVersion;
private Consumer<Settings> 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;
}

View File

@ -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;
}

View File

@ -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<Settings> {
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;

View File

@ -35,6 +35,7 @@ public class UpdateChecker {
private final ObjectProperty<Instant> lastSuccessfulUpdateCheck = new SimpleObjectProperty<>();
private final Comparator<String> 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();

View File

@ -47,10 +47,11 @@ public class UpdatesPreferencesController implements FxController {
private final ObservableValue<String> timeDifferenceMessage;
private final String currentVersion;
private final BooleanBinding updateAvailable;
private final BooleanBinding checkFailed;
private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false);
private final ObjectProperty<UpdateChecker.UpdateCheckState> 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();
}
}

View File

@ -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());

View File

@ -12,6 +12,8 @@
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.text.TextFlow?>
<?import javafx.scene.text.Text?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.preferences.UpdatesPreferencesController"
@ -34,12 +36,13 @@
</Button>
<HBox fx:id="checkFailedHBox" spacing="12" alignment="CENTER" visible="${controller.checkFailed}" managed="${controller.checkFailed}">
<Label text="%preferences.updates.checkFailed" wrapText="true">
<graphic>
<FontAwesome5IconView glyphSize="12" styleClass="glyph-icon-orange" glyph="EXCLAMATION_TRIANGLE"/>
</graphic>
</Label>
<Hyperlink styleClass="hyperlink-underline" text="%preferences.general.debugDirectory" onAction="#showLogfileDirectory"/>
<TextFlow styleClass="text-flow" textAlignment="CENTER">
<FontAwesome5IconView glyphSize="12" styleClass="glyph-icon-orange" glyph="EXCLAMATION_TRIANGLE"/>
<Text text=" "/>
<Text text="%preferences.updates.checkFailed"/>
<Text text=" "/>
<Hyperlink styleClass="hyperlink-underline" text="%preferences.general.debugDirectory" onAction="#showLogfileDirectory"/>
</TextFlow>
</HBox>
<FormattedLabel format="%preferences.updates.lastUpdateCheck" arg1="${controller.timeDifferenceMessage}" textAlignment="CENTER" wrapText="true">
<tooltip>

View File

@ -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