adjusted code as per PR suggestions

This commit is contained in:
Jan-Peter Klein 2024-04-04 12:37:56 +02:00
parent 6a3a256c0b
commit 43d0dd99ec
No known key found for this signature in database
GPG Key ID: 90EDA3A7C822FD0E
7 changed files with 99 additions and 64 deletions

View File

@ -25,6 +25,10 @@ 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.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.function.Consumer;
public class Settings {
@ -163,6 +167,20 @@ public class Settings {
}
});
}
var dateTimeString = !lastUpdateCheck.get().isEmpty() ? lastUpdateCheck.get() : DEFAULT_LAST_UPDATE_CHECK;
try {
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_DATE_TIME);
lastUpdateCheck.set(dateTime.toString());
} catch (DateTimeParseException e) {
try {
LocalDate date = LocalDate.parse(dateTimeString, DateTimeFormatter.ISO_DATE);
lastUpdateCheck.set(LocalDateTime.of(date, LocalDate.MIN.atStartOfDay().toLocalTime()).toString());
} catch (DateTimeParseException ex) {
LOG.error("The date/time format is invalid:" + dateTimeString, ex);
}
}
}
SettingsJson serialized() {

View File

@ -1,11 +1,13 @@
package org.cryptomator.ui.fxapp;
import org.cryptomator.common.Environment;
import org.cryptomator.common.SemVerComparator;
import org.cryptomator.common.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
@ -16,10 +18,8 @@ import javafx.concurrent.ScheduledService;
import javafx.concurrent.Worker;
import javafx.concurrent.WorkerStateEvent;
import javafx.util.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Comparator;
@FxApplicationScoped
public class UpdateChecker {
@ -33,6 +33,8 @@ public class UpdateChecker {
private final ScheduledService<String> updateCheckerService;
private final ObjectProperty<UpdateCheckState> state = new SimpleObjectProperty<>(UpdateCheckState.NOT_CHECKED);
private final ObjectProperty<LocalDateTime> updateCheckTimeProperty = new SimpleObjectProperty<>();
private final Comparator<String> versionComparator = new SemVerComparator();
private final BooleanBinding updateAvailable;
@Inject
UpdateChecker(Settings settings, //
@ -42,20 +44,14 @@ public class UpdateChecker {
this.settings = settings;
this.updateCheckerService = updateCheckerService;
this.latestVersionProperty.set(settings.latestVersion.get());
var dateTimeString = !settings.lastUpdateCheck.get().isEmpty() ? settings.lastUpdateCheck.get() : Settings.DEFAULT_LAST_UPDATE_CHECK;
try {
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, DateTimeFormatter.ISO_DATE_TIME);
this.updateCheckTimeProperty.set(dateTime);
} catch (DateTimeParseException e) {
try {
LocalDate date = LocalDate.parse(dateTimeString, DateTimeFormatter.ISO_DATE);
this.updateCheckTimeProperty.set(LocalDateTime.of(date, LocalDate.MIN.atStartOfDay().toLocalTime()));
} catch (DateTimeParseException ex) {
LOG.error("The date/time format is invalid:" + dateTimeString, ex);
}
}
this.latestVersionProperty().addListener((_, _, newValue) -> settings.latestVersion.set(newValue));
this.updateCheckTimeProperty().addListener((_,_,newValue) -> settings.lastUpdateCheck.set(newValue.toString()));
this.updateCheckTimeProperty.set(LocalDateTime.parse(settings.lastUpdateCheck.get()));
this.updateAvailable = Bindings.createBooleanBinding(() -> {
var latestVersion = latestVersionProperty.get();
return latestVersion != null && versionComparator.compare(getCurrentVersion(), latestVersion) < 0;
}, latestVersionProperty);
this.latestVersionProperty.addListener((_, _, newValue) -> settings.latestVersion.set(newValue));
this.updateCheckTimeProperty.addListener((_, _, newValue) -> settings.lastUpdateCheck.set(newValue.toString()));
}
public void automaticallyCheckForUpdatesIfEnabled() {
@ -112,8 +108,12 @@ public class UpdateChecker {
return latestVersionProperty;
}
public String getCurrentVersion() {
return env.getAppVersion();
public BooleanBinding updateAvailableProperty(){
return updateAvailable;
}
public boolean isUpdateAvailable(){
return updateAvailable.get();
}
public ObjectProperty<LocalDateTime> updateCheckTimeProperty() {
@ -124,4 +124,7 @@ public class UpdateChecker {
return state;
}
public String getCurrentVersion() {
return env.getAppVersion();
}
}

View File

@ -46,7 +46,7 @@ public class MainWindowTitleController implements FxController {
this.appWindows = appWindows;
this.trayMenuInitialized = trayMenu.isInitialized();
this.updateChecker = updateChecker;
this.updateAvailable = updateChecker.updateCheckStateProperty().isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(updateChecker.latestVersionProperty().isNotEqualTo(updateChecker.getCurrentVersion()));
this.updateAvailable = updateChecker.updateAvailableProperty();
this.licenseHolder = licenseHolder;
this.settings = settings;
this.showMinimizeButton = Bindings.createBooleanBinding(this::isShowMinimizeButton, settings.showMinimizeButton, settings.showTrayIcon);

View File

@ -1,10 +1,8 @@
package org.cryptomator.ui.preferences;
import org.cryptomator.common.Environment;
import org.cryptomator.common.SemVerComparator;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.FormattedLabel;
import org.cryptomator.ui.fxapp.UpdateChecker;
import javax.inject.Inject;
@ -13,8 +11,10 @@ import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
@ -24,7 +24,6 @@ import javafx.util.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Comparator;
import java.util.Locale;
@ -39,17 +38,15 @@ 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 String currentVersion;
private final BooleanBinding updateAvailable;
private final ObjectProperty<LocalDateTime> updateCheckDateProperty;
private final Comparator<String> versionComparator = new SemVerComparator();
private final BooleanProperty upToDateLabelVisible = new SimpleBooleanProperty(false);
private final ObjectProperty<UpdateChecker.UpdateCheckState> updateCheckStateProperty;
/* FXML */
public CheckBox checkForUpdatesCheckbox;
public FormattedLabel updateCheckDateFormattedLabel;
public HBox checkFailedHBox;
public FormattedLabel latestVersionFormattedLabel;
public Label upToDateLabel;
@Inject
@ -60,42 +57,23 @@ 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.currentVersion = updateChecker.getCurrentVersion();
this.updateAvailable = Bindings.createBooleanBinding(() -> {
if (latestVersion.get() != null) {
return versionComparator.compare(currentVersion, latestVersion.get()) < 0;
} else {
return false;
}
}, latestVersion);
this.updateCheckDateProperty = updateChecker.updateCheckTimeProperty();
this.updateAvailable = updateChecker.updateAvailableProperty();
this.updateCheckStateProperty = updateChecker.updateCheckStateProperty();
}
public void initialize() {
checkForUpdatesCheckbox.selectedProperty().bindBidirectional(settings.checkForUpdates);
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault());
updateCheckDateFormattedLabel.arg1Property().bind(Bindings.createStringBinding(() -> (!updateCheckDateProperty.get().equals(LocalDateTime.parse(Settings.DEFAULT_LAST_UPDATE_CHECK)) && latestVersionProperty().isNotNull().get()) ? updateCheckDateProperty.get().format(formatter) : "-", updateCheckDateProperty, latestVersionProperty()));
BooleanBinding isUpdateCheckFailed = updateCheckStateProperty.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED);
checkFailedHBox.managedProperty().bind(isUpdateCheckFailed);
checkFailedHBox.visibleProperty().bind(isUpdateCheckFailed);
latestVersionFormattedLabel.arg1Property().bind(Bindings.createStringBinding(() -> (latestVersion.get() != null) ? latestVersion.get() : "-", latestVersion));
BooleanBinding isUpdateSuccessfulAndCurrent = updateCheckStateProperty.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_SUCCESSFUL).and(latestVersion.isEqualTo(currentVersion));
updateCheckStateProperty.addListener((_, _, _) -> {
if (isUpdateSuccessfulAndCurrent.get()) {
upToDateLabel.setVisible(true);
upToDateLabel.setManaged(true);
upToDateLabelVisibleProperty().set(true);
PauseTransition delay = new PauseTransition(Duration.seconds(5));
delay.setOnFinished(_ -> {
upToDateLabel.setVisible(false);
upToDateLabel.setManaged(false);
});
delay.setOnFinished(_ -> upToDateLabelVisibleProperty().set(false));
delay.play();
}
});
@ -131,13 +109,30 @@ public class UpdatesPreferencesController implements FxController {
}
public String getLatestVersion() {
return latestVersion.get();
return latestVersion.isNotNull().get() ? latestVersion.get() : "-";
}
public String getCurrentVersion() {
return currentVersion;
}
public ObjectProperty<LocalDateTime> updateCheckDateProperty() {
return updateCheckDate;
}
public String getUpdateCheckDate() {
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault());
return !updateCheckDate.get().equals(LocalDateTime.parse(Settings.DEFAULT_LAST_UPDATE_CHECK)) ? updateCheckDate.get().format(formatter) : "-";
}
public BooleanProperty upToDateLabelVisibleProperty() {
return upToDateLabelVisible;
}
public final boolean isUpToDateLabelVisible() {
return upToDateLabelVisibleProperty().get();
}
public BooleanBinding updateAvailableProperty() {
return updateAvailable;
}
@ -145,4 +140,13 @@ public class UpdatesPreferencesController implements FxController {
public boolean isUpdateAvailable() {
return updateAvailable.get();
}
public BooleanBinding checkFailedProperty() {
return updateCheckStateProperty.isEqualTo(UpdateChecker.UpdateCheckState.CHECK_FAILED);
}
public boolean isCheckFailed() {
return checkFailedProperty().get();
}
}

View File

@ -5,16 +5,21 @@ import dagger.Subcomponent;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.fxapp.UpdateChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@UpdateReminderScoped
@Subcomponent(modules = {UpdateReminderModule.class})
public interface UpdateReminderComponent {
Logger LOG = LoggerFactory.getLogger(UpdateReminderComponent.class);
@UpdateReminderWindow
Stage window();
@ -22,19 +27,24 @@ public interface UpdateReminderComponent {
Lazy<Scene> updateReminderScene();
Settings settings();
UpdateChecker updateChecker();
default void checkAndShowUpdateReminderWindow() {
if (updateChecker().updateCheckTimeProperty().get().isBefore(LocalDateTime.now().minusDays(14)) && !settings().checkForUpdates.getValue()) {
Stage stage = window();
stage.setScene(updateReminderScene().get());
stage.sizeToScene();
stage.show();
try {
var dateTime = LocalDateTime.parse(settings().lastUpdateCheck.get(), DateTimeFormatter.ISO_DATE_TIME);
if (dateTime.isBefore(LocalDateTime.now().minusDays(14)) && !settings().checkForUpdates.getValue()) {
Stage stage = window();
stage.setScene(updateReminderScene().get());
stage.sizeToScene();
stage.show();
}
} catch (DateTimeParseException e) {
LOG.error("The date/time format is invalid:" + settings().lastUpdateCheck.get(), e);
}
}
@Subcomponent.Factory
interface Factory {
UpdateReminderComponent create();
}
}

View File

@ -22,8 +22,8 @@
<Insets topRightBottomLeft="24"/>
</padding>
<FormattedLabel format="%preferences.updates.currentVersion" arg1="${controller.currentVersion}" textAlignment="CENTER" wrapText="true"/>
<FormattedLabel fx:id="latestVersionFormattedLabel" format="%preferences.updates.latestVersion" arg1="-" textAlignment="CENTER" wrapText="true"/>
<FormattedLabel fx:id="updateCheckDateFormattedLabel" format="%preferences.updates.lastUpdateCheck" arg1="-" textAlignment="CENTER" wrapText="true"/>
<FormattedLabel format="%preferences.updates.latestVersion" arg1="${controller.latestVersion}" textAlignment="CENTER" wrapText="true"/>
<FormattedLabel format="%preferences.updates.lastUpdateCheck" arg1="${controller.updateCheckDate}" textAlignment="CENTER" wrapText="true"/>
<CheckBox fx:id="checkForUpdatesCheckbox" text="%preferences.updates.autoUpdateCheck"/>
@ -34,7 +34,7 @@
</graphic>
</Button>
<HBox fx:id="checkFailedHBox" spacing="12" alignment="CENTER">
<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"/>
@ -42,7 +42,7 @@
</Label>
<Hyperlink styleClass="hyperlink-underline" text="%preferences.general.debugDirectory" onAction="#showLogfileDirectory"/>
</HBox>
<Label fx:id="upToDateLabel" text="%preferences.updates.upToDate" managed="false" visible="false">
<Label fx:id="upToDateLabel" text="%preferences.updates.upToDate" visible="${controller.upToDateLabelVisible}" managed="${controller.upToDateLabelVisible}">
<graphic>
<FontAwesome5IconView glyphSize="12" styleClass="glyph-icon-primary" glyph="CHECK"/>
</graphic>

View File

@ -322,7 +322,7 @@ preferences.updates.latestVersion=Latest Version: %s
preferences.updates.autoUpdateCheck=Check for updates automatically
preferences.updates.checkNowBtn=Check Now
preferences.updates.updateAvailable=Update to version %s available.
preferences.updates.lastUpdateCheck=The last update check was performed on: %s
preferences.updates.lastUpdateCheck=Last update check: %s
preferences.updates.checkFailed=Check failed
preferences.updates.upToDate=Cryptomator is up-to-date.