diff --git a/src/main/java/org/cryptomator/ui/health/StartController.java b/src/main/java/org/cryptomator/ui/health/StartController.java index 3e9cc5b07..84de35f4b 100644 --- a/src/main/java/org/cryptomator/ui/health/StartController.java +++ b/src/main/java/org/cryptomator/ui/health/StartController.java @@ -18,11 +18,15 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Platform; +import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; -import java.util.Optional; +import java.io.UncheckedIOException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; @@ -31,38 +35,40 @@ public class StartController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(StartController.class); + private final Vault vault; private final Stage window; - private final Optional unverifiedVaultConfig; + private final CompletableFuture unverifiedVaultConfig; private final KeyLoadingStrategy keyLoadingStrategy; private final ExecutorService executor; private final AtomicReference masterkeyRef; private final AtomicReference vaultConfigRef; private final Lazy checkScene; private final Lazy errorComponent; + private final ObjectProperty state = new SimpleObjectProperty<>(State.LOADING); + private final BooleanBinding loading = state.isEqualTo(State.LOADING); + private final BooleanBinding failed = state.isEqualTo(State.FAILED); + private final BooleanBinding loaded = state.isEqualTo(State.LOADED); + + public enum State { + LOADING, + FAILED, + LOADED + } /* FXML */ @Inject public StartController(@HealthCheckWindow Vault vault, @HealthCheckWindow Stage window, @HealthCheckWindow KeyLoadingStrategy keyLoadingStrategy, ExecutorService executor, AtomicReference masterkeyRef, AtomicReference vaultConfigRef, @FxmlScene(FxmlFile.HEALTH_CHECK_LIST) Lazy checkScene, Lazy errorComponent) { + this.vault = vault; this.window = window; + this.unverifiedVaultConfig = CompletableFuture.supplyAsync(this::loadConfig, executor); this.keyLoadingStrategy = keyLoadingStrategy; this.executor = executor; this.masterkeyRef = masterkeyRef; this.vaultConfigRef = vaultConfigRef; this.checkScene = checkScene; this.errorComponent = errorComponent; - - //TODO: this is ugly - //idea: delay the loading of the vault config and show a spinner (something like "check/load config") and react to the result of the loading - //or: load vault config in a previous step to see if it is loadable. - VaultConfig.UnverifiedVaultConfig tmp; - try { - tmp = vault.getUnverifiedVaultConfig(); - } catch (IOException e) { - e.printStackTrace(); - tmp = null; - } - this.unverifiedVaultConfig = Optional.ofNullable(tmp); + this.unverifiedVaultConfig.whenCompleteAsync(this::loadedConfig, Platform::runLater); } @FXML @@ -77,11 +83,29 @@ public class StartController implements FxController { executor.submit(this::loadKey); } + private VaultConfig.UnverifiedVaultConfig loadConfig() { + try { + return this.vault.getUnverifiedVaultConfig(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private void loadedConfig(VaultConfig.UnverifiedVaultConfig cfg, Throwable exception) { + assert Platform.isFxApplicationThread(); + if (exception != null) { + state.set(State.FAILED); + } else { + assert cfg != null; + state.set(State.LOADED); + } + } + private void loadKey() { assert !Platform.isFxApplicationThread(); - assert unverifiedVaultConfig.isPresent(); - try (var masterkey = keyLoadingStrategy.loadKey(unverifiedVaultConfig.orElseThrow().getKeyId())) { - var unverifiedCfg = unverifiedVaultConfig.get(); + assert unverifiedVaultConfig.isDone(); + var unverifiedCfg = unverifiedVaultConfig.join(); + try (var masterkey = keyLoadingStrategy.loadKey(unverifiedCfg.getKeyId())) { var verifiedCfg = unverifiedCfg.verify(masterkey.getEncoded(), unverifiedCfg.allegedVaultVersion()); vaultConfigRef.set(verifiedCfg); var old = masterkeyRef.getAndSet(masterkey.clone()); @@ -96,8 +120,6 @@ public class StartController implements FxController { } else { Platform.runLater(() -> loadingKeyFailed(e)); } - } catch (VaultKeyInvalidException e) { - Platform.runLater(() -> loadingKeyFailed(e)); } catch (VaultConfigLoadException e) { Platform.runLater(() -> loadingKeyFailed(e)); } @@ -120,8 +142,29 @@ public class StartController implements FxController { } } - public boolean isInvalidConfig() { - return unverifiedVaultConfig.isEmpty(); + /* Getter */ + + public BooleanBinding loadingProperty() { + return loading; } + public boolean isLoading() { + return loading.get(); + } + + public BooleanBinding failedProperty() { + return failed; + } + + public boolean isFailed() { + return failed.get(); + } + + public BooleanBinding loadedProperty() { + return loaded; + } + + public boolean isLoaded() { + return loaded.get(); + } } diff --git a/src/main/resources/fxml/health_start.fxml b/src/main/resources/fxml/health_start.fxml index 63db32ce8..24b256fa8 100644 --- a/src/main/resources/fxml/health_start.fxml +++ b/src/main/resources/fxml/health_start.fxml @@ -17,22 +17,25 @@ - - -