mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 04:01:27 +00:00
Implement update button that updates and respawns the app
This commit is contained in:
@@ -5,12 +5,16 @@ import org.cryptomator.common.SemVerComparator;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.updates.AppUpdateChecker;
|
||||
import org.cryptomator.integrations.common.DistributionChannel;
|
||||
import org.cryptomator.integrations.update.Progress;
|
||||
import org.cryptomator.integrations.update.ProgressListener;
|
||||
import org.cryptomator.integrations.update.UpdateFailedException;
|
||||
import org.cryptomator.ui.preferences.UpdatesPreferencesController;
|
||||
import org.purejava.portal.rest.UpdateCheckerTask;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@@ -44,12 +48,14 @@ public class UpdateChecker {
|
||||
private final BooleanBinding appUpdateAvailable;
|
||||
private final BooleanBinding checkFailed;
|
||||
private final AppUpdateChecker updateChecker;
|
||||
private final FxApplicationTerminator appTerminator;
|
||||
|
||||
@Inject
|
||||
UpdateChecker(Settings settings, //
|
||||
Environment env, //
|
||||
ScheduledService<String> updateCheckerService,
|
||||
AppUpdateChecker updateChecker) {
|
||||
ScheduledService<String> updateCheckerService, //
|
||||
AppUpdateChecker updateChecker, //
|
||||
FxApplicationTerminator appTerminator) {
|
||||
this.env = env;
|
||||
this.settings = settings;
|
||||
this.updateCheckerService = updateCheckerService;
|
||||
@@ -58,23 +64,28 @@ public class UpdateChecker {
|
||||
this.appUpdateAvailable = Bindings.createBooleanBinding(this::isAppUpdateAvailable, latestAppUpdaterVersion);
|
||||
this.checkFailed = Bindings.equal(UpdateCheckState.CHECK_FAILED, state);
|
||||
this.updateChecker = updateChecker;
|
||||
this.appTerminator = appTerminator;
|
||||
}
|
||||
|
||||
public void automaticallyCheckForUpdatesIfEnabled() {
|
||||
if (!env.disableUpdateCheck() && settings.checkForUpdates.get()) {
|
||||
if (updateChecker.isUpdateServiceAvailable(env.getBuildNumber())) { // prefer AppUpdateChecker
|
||||
switch (env.getBuildNumber().get()) {
|
||||
case "flatpak-1" -> startCheckingWithFlatpakUpdater((UpdateCheckerTask) updateChecker.getUpdater(DistributionChannel.Value.LINUX_FLATPAK), AUTO_CHECK_DELAY);
|
||||
default -> LOG.error("Unexpected value 'buildNumber': {}", env.getBuildNumber().get());
|
||||
}
|
||||
} else { // fallback is the "redirect user to website" approach
|
||||
startCheckingForUpdates(AUTO_CHECK_DELAY);
|
||||
}
|
||||
decideOnUpdateChecker();
|
||||
}
|
||||
}
|
||||
|
||||
public void checkForUpdatesNow() {
|
||||
startCheckingForUpdates(Duration.ZERO);
|
||||
decideOnUpdateChecker();
|
||||
}
|
||||
|
||||
private void decideOnUpdateChecker() {
|
||||
if (updateChecker.isUpdateServiceAvailable(env.getBuildNumber())) { // prefer AppUpdateChecker
|
||||
switch (env.getBuildNumber().get()) {
|
||||
case "flatpak-1" -> startCheckingWithFlatpakUpdater((UpdateCheckerTask) updateChecker.getUpdater(DistributionChannel.Value.LINUX_FLATPAK), Duration.ZERO);
|
||||
default -> LOG.error("Unexpected value 'buildNumber': {}", env.getBuildNumber().get());
|
||||
}
|
||||
} else { // fallback is the "redirect user to website" approach
|
||||
startCheckingForUpdates(Duration.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAppNow() throws UpdateFailedException {
|
||||
@@ -82,6 +93,30 @@ public class UpdateChecker {
|
||||
service.triggerUpdate();
|
||||
}
|
||||
|
||||
public void terminateFlatpakOnUpdateCompleted(Runnable onComplete, UpdatesPreferencesController controller) {
|
||||
var service = updateChecker.getServiceForChannel(DistributionChannel.Value.LINUX_FLATPAK);
|
||||
service.addProgressListener(new ProgressListener() {
|
||||
@Override
|
||||
public void onProgress(Progress progress) {
|
||||
LOG.debug("Update progess is at percentage: {} and has status: {}", progress.getProgress(), progress.getStatus());
|
||||
|
||||
if (progress.getStatus() == 0 || progress.getStatus() == 2) {
|
||||
controller.flatpakProgressProperty().set(progress.getProgress() / 100.0);
|
||||
}
|
||||
|
||||
if (progress.getStatus() == 2 && progress.getProgress() == 100) {
|
||||
LOG.debug("Update successfully finished, restarting App now");
|
||||
service.removeProgressListener(this);
|
||||
if (onComplete != null) {
|
||||
Platform.runLater(onComplete);
|
||||
}
|
||||
service.spawnApp();
|
||||
appTerminator.terminate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startCheckingForUpdates(Duration initialDelay) {
|
||||
updateCheckerService.cancel();
|
||||
updateCheckerService.reset();
|
||||
|
||||
@@ -51,7 +51,7 @@ public class MainWindowController implements FxController {
|
||||
this.selectedVault = selectedVault;
|
||||
this.settings = settings;
|
||||
this.appWindows = appWindows;
|
||||
this.updateAvailable = updateChecker.updateAvailableProperty();
|
||||
this.updateAvailable = updateChecker.updateAvailableProperty().or(updateChecker.appUpdateAvailableProperty());
|
||||
this.licenseHolder = licenseHolder;
|
||||
updateChecker.automaticallyCheckForUpdatesIfEnabled();
|
||||
|
||||
|
||||
@@ -2,9 +2,13 @@ package org.cryptomator.ui.preferences;
|
||||
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.updates.AppUpdateChecker;
|
||||
import org.cryptomator.integrations.common.DistributionChannel;
|
||||
import org.cryptomator.integrations.update.UpdateFailedException;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.fxapp.UpdateChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.animation.PauseTransition;
|
||||
@@ -14,12 +18,16 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.binding.ObjectBinding;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
@@ -35,6 +43,7 @@ import java.util.ResourceBundle;
|
||||
@PreferencesScoped
|
||||
public class UpdatesPreferencesController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UpdatesPreferencesController.class);
|
||||
private static final String DOWNLOADS_URI_TEMPLATE = "https://cryptomator.org/downloads/" //
|
||||
+ "?utm_source=cryptomator-desktop" //
|
||||
+ "&utm_medium=update-notification&" //
|
||||
@@ -44,7 +53,9 @@ public class UpdatesPreferencesController implements FxController {
|
||||
private final Environment environment;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final Settings settings;
|
||||
private final Environment env;
|
||||
private final UpdateChecker updateChecker;
|
||||
private final AppUpdateChecker appUpdateChecker;
|
||||
private final ObjectBinding<ContentDisplay> checkForUpdatesButtonState;
|
||||
private final ReadOnlyStringProperty latestVersion;
|
||||
private final ObservableValue<Instant> lastSuccessfulUpdateCheck;
|
||||
@@ -58,17 +69,23 @@ public class UpdatesPreferencesController implements FxController {
|
||||
private final DateTimeFormatter formatter;
|
||||
private final BooleanBinding upToDate;
|
||||
private final String downloadsUri;
|
||||
private final BooleanProperty updatingFlatpak = new SimpleBooleanProperty(false);
|
||||
private final DoubleProperty flatpakProgress = new SimpleDoubleProperty(ProgressBar.INDETERMINATE_PROGRESS);
|
||||
|
||||
/* FXML */
|
||||
public CheckBox checkForUpdatesCheckbox;
|
||||
@FXML
|
||||
public Button flatpakUpdateButton;
|
||||
|
||||
@Inject
|
||||
UpdatesPreferencesController(Application application, Environment environment, ResourceBundle resourceBundle, Settings settings, UpdateChecker updateChecker) {
|
||||
UpdatesPreferencesController(Application application, Environment environment, ResourceBundle resourceBundle, Settings settings, UpdateChecker updateChecker, AppUpdateChecker appUpdateChecker, Environment env) {
|
||||
this.application = application;
|
||||
this.environment = environment;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.settings = settings;
|
||||
this.env = env;
|
||||
this.updateChecker = updateChecker;
|
||||
this.appUpdateChecker = appUpdateChecker;
|
||||
this.checkForUpdatesButtonState = Bindings.when(updateChecker.checkingForUpdatesProperty()).then(ContentDisplay.LEFT).otherwise(ContentDisplay.TEXT_ONLY);
|
||||
this.latestVersion = updateChecker.latestVersionProperty();
|
||||
this.lastSuccessfulUpdateCheck = updateChecker.lastSuccessfulUpdateCheckProperty();
|
||||
@@ -85,6 +102,10 @@ public class UpdatesPreferencesController implements FxController {
|
||||
|
||||
public void initialize() {
|
||||
checkForUpdatesCheckbox.selectedProperty().bindBidirectional(settings.checkForUpdates);
|
||||
switch (env.getBuildNumber().get()) {
|
||||
case "flatpak-1" -> flatpakUpdateButton.setText(appUpdateChecker.getServiceForChannel(DistributionChannel.Value.LINUX_FLATPAK).getDisplayName());
|
||||
default -> LOG.error("Unexpected value 'buildNumber': {}", env.getBuildNumber().get());
|
||||
}
|
||||
|
||||
upToDate.addListener((_, _, newVal) -> {
|
||||
if (newVal) {
|
||||
@@ -102,8 +123,17 @@ public class UpdatesPreferencesController implements FxController {
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void updateNow() throws UpdateFailedException {
|
||||
updateChecker.updateAppNow();
|
||||
public void updateFlatpakNow() {
|
||||
updatingFlatpak.set(true);
|
||||
updateChecker.terminateFlatpakOnUpdateCompleted(
|
||||
() -> updatingFlatpak.set(false), this
|
||||
);
|
||||
|
||||
try {
|
||||
updateChecker.updateAppNow();
|
||||
} catch (UpdateFailedException e) {
|
||||
updatingFlatpak.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -202,4 +232,15 @@ public class UpdatesPreferencesController implements FxController {
|
||||
return checkFailed.getValue();
|
||||
}
|
||||
|
||||
public BooleanProperty updatingFlatpakProperty() {
|
||||
return updatingFlatpak;
|
||||
}
|
||||
|
||||
public boolean isUpdatingFlatpak() {
|
||||
return updatingFlatpak.get();
|
||||
}
|
||||
|
||||
public DoubleProperty flatpakProgressProperty() {
|
||||
return flatpakProgress;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<?import javafx.scene.control.Tooltip?>
|
||||
<?import javafx.scene.text.TextFlow?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
<?import javafx.scene.control.ProgressBar?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.preferences.UpdatesPreferencesController"
|
||||
@@ -52,6 +53,16 @@
|
||||
</graphic>
|
||||
</Label>
|
||||
<Hyperlink text="${linkLabel.value}" onAction="#visitDownloadsPage" textAlignment="CENTER" wrapText="true" styleClass="hyperlink-underline" visible="${controller.updateAvailable}" managed="${controller.updateAvailable}"/>
|
||||
<Button text="Hello Flatpak!" onAction="#updateNow" visible="${controller.appUpdateAvailable}"/>
|
||||
<Button fx:id="flatpakUpdateButton"
|
||||
onAction="#updateFlatpakNow"
|
||||
visible="${controller.appUpdateAvailable}">
|
||||
</Button>
|
||||
|
||||
<ProgressBar fx:id="flatpakProgressBar"
|
||||
maxWidth="200"
|
||||
maxHeight="12"
|
||||
visible="${controller.updatingFlatpak}"
|
||||
managed="${controller.updatingFlatpak}"
|
||||
progress="${controller.flatpakProgress}"/>
|
||||
</VBox>
|
||||
</VBox>
|
||||
|
||||
Reference in New Issue
Block a user