Asking user once before enabling update check

This commit is contained in:
Markus Kreusch
2018-05-22 11:35:45 +02:00
parent 525b0a7982
commit 458866f7d6
5 changed files with 95 additions and 43 deletions

View File

@@ -8,26 +8,20 @@
******************************************************************************/
package org.cryptomator.common.settings;
import java.util.function.Consumer;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.function.Consumer;
public class Settings {
public static final int MIN_PORT = 1024;
public static final int MAX_PORT = 65535;
public static final boolean DEFAULT_CHECK_FOR_UDPATES = true;
public static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
public static final boolean DEFAULT_CHECK_FOR_UDPATES = false;
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final String DEFAULT_GVFS_SCHEME = "dav";
@@ -35,6 +29,7 @@ public class Settings {
public static final VolumeImpl DEFAULT_VOLUME_IMPL = VolumeImpl.FUSE;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
@@ -49,6 +44,7 @@ public class Settings {
*/
Settings() {
directories.addListener((ListChangeListener.Change<? extends VaultSettings> change) -> this.save());
askedForUpdateCheck.addListener(this::somethingChanged);
checkForUpdates.addListener(this::somethingChanged);
port.addListener(this::somethingChanged);
numTrayNotifications.addListener(this::somethingChanged);
@@ -77,6 +73,10 @@ public class Settings {
return directories;
}
public BooleanProperty askedForUpdateCheck() {
return askedForUpdateCheck;
}
public BooleanProperty checkForUpdates() {
return checkForUpdates;
}

View File

@@ -5,17 +5,16 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SettingsJsonAdapter extends TypeAdapter<Settings> {
@@ -28,6 +27,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
out.beginObject();
out.name("directories");
writeVaultSettingsArray(out, value.getDirectories());
out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get());
out.name("checkForUpdatesEnabled").value(value.checkForUpdates().get());
out.name("port").value(value.port().get());
out.name("numTrayNotifications").value(value.numTrayNotifications().get());
@@ -56,6 +56,9 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
case "directories":
settings.getDirectories().addAll(readVaultSettingsArray(in));
break;
case "askedForUpdateCheck":
settings.askedForUpdateCheck().set(in.nextBoolean());
break;
case "checkForUpdatesEnabled":
settings.checkForUpdates().set(in.nextBoolean());
break;

View File

@@ -2,25 +2,12 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@@ -30,6 +17,7 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
@@ -44,6 +32,21 @@ import org.cryptomator.ui.util.AsyncTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.TimeUnit;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildYesNoDialog;
@Singleton
public class WelcomeController implements ViewController {
@@ -58,7 +61,7 @@ public class WelcomeController implements ViewController {
@Inject
public WelcomeController(Application app, @Named("applicationVersion") Optional<String> applicationVersion, Localization localization, Settings settings, @Named("SemVer") Comparator<String> semVerComparator,
AsyncTaskService asyncTaskService) {
AsyncTaskService asyncTaskService) {
this.app = app;
this.applicationVersion = applicationVersion;
this.localization = localization;
@@ -86,6 +89,8 @@ public class WelcomeController implements ViewController {
public void initialize(URL location, ResourceBundle resources) {
if (areUpdatesManagedExternally()) {
checkForUpdatesContainer.setVisible(false);
} else if (!settings.askedForUpdateCheck().get()) {
this.askForUpdateCheck();
} else if (settings.checkForUpdates().get()) {
this.checkForUpdates();
}
@@ -104,6 +109,23 @@ public class WelcomeController implements ViewController {
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
}
private void askForUpdateCheck() {
asyncTaskService.runDelayedOnUiThread(1, TimeUnit.SECONDS, () -> {
Optional<ButtonType> result = buildYesNoDialog(
localization.getString("welcome.askForUpdateCheck.dialog.title"),
localization.getString("welcome.askForUpdateCheck.dialog.header"),
localization.getString("welcome.askForUpdateCheck.dialog.content"),
ButtonType.YES).showAndWait();
if (result.isPresent()) {
settings.askedForUpdateCheck().set(true);
settings.checkForUpdates().set(result.get().equals(ButtonType.YES));
}
if (settings.checkForUpdates().get()) {
this.checkForUpdates();
}
});
}
private void checkForUpdates() {
checkForUpdatesStatus.setText(localization.getString("welcome.checkForUpdates.label.currentlyChecking"));
checkForUpdatesIndicator.setVisible(true);

View File

@@ -5,20 +5,22 @@
*******************************************************************************/
package org.cryptomator.ui.util;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.application.Platform;
import org.cryptomator.common.ConsumerThrowingException;
import org.cryptomator.common.RunnableThrowingException;
import org.cryptomator.common.SupplierThrowingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@Singleton
public class AsyncTaskService {
@@ -34,7 +36,7 @@ public class AsyncTaskService {
/**
* Creates a new async task
*
*
* @param task Tasks to be invoked in a background thread.
* @return The async task
*/
@@ -45,9 +47,13 @@ public class AsyncTaskService {
});
}
public void runDelayedOnUiThread(long duration, TimeUnit unit, RunnableThrowingException<?> task) {
asyncTaskOf(() -> null).onSuccess(task).runDelayedBy(duration, unit);
}
/**
* Creates a new async task
*
*
* @param task Tasks to be invoked in a background thread.
* @return The async task
*/
@@ -100,9 +106,21 @@ public class AsyncTaskService {
@Override
public void run() {
runDelayedBy(0, MILLISECONDS);
}
@Override
public void runDelayedBy(long duration, TimeUnit unit) {
requireNonNull(unit, "unit must not be null");
if (duration < 0) {
throw new IllegalArgumentException("duration must not be negative");
}
errorHandlers.add(ErrorHandler.LOGGING_HANDLER);
executor.execute(() -> logExceptions(() -> {
try {
if (duration > 0) {
Thread.sleep(unit.toMillis(duration));
}
ResultType result = task.get();
Platform.runLater(() -> {
try {
@@ -214,6 +232,12 @@ public class AsyncTaskService {
*/
@Override
void run();
/**
* Starts the async task delayed by {@code duration unit}
*/
void runDelayedBy(long duration, TimeUnit unit);
}
}

View File

@@ -23,6 +23,9 @@ main.createVault.nonEmptyDir.content=The selected directory already contains fil
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking=Checking for Updates...
welcome.newVersionMessage=Version %1$s can be downloaded.\nThis is %2$s.
welcome.askForUpdateCheck.dialog.title=Update check
welcome.askForUpdateCheck.dialog.header=Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content=To check for updates, Cryptomator will fetch the current version from the Cryptomator servers and display a hint to you if a newer version is available.\n\nWe recommend to enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed. If you do not enable the update check you may check and download the current version from https://cryptomator.org/downloads/.\n\nYou can change this at any time from within the settings.
# initialize.fxml
initialize.label.password=Password