/******************************************************************************* * Copyright (c) 2017 Skymatic UG (haftungsbeschränkt). * All rights reserved. This program and the accompanying materials * are made available under the terms of the accompanying LICENSE file. *******************************************************************************/ package org.cryptomator.ui.controllers; import java.util.Objects; import java.util.Optional; import javax.inject.Inject; import org.cryptomator.ui.controls.SecPasswordField; import org.cryptomator.ui.l10n.Localization; import org.cryptomator.ui.model.UpgradeStrategies; import org.cryptomator.ui.model.UpgradeStrategy; import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException; import org.cryptomator.ui.model.Vault; import org.cryptomator.ui.util.AsyncTaskService; import org.fxmisc.easybind.EasyBind; import javafx.beans.binding.BooleanExpression; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Parent; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.ProgressIndicator; import javafx.scene.layout.GridPane; public class UpgradeController implements ViewController { private final ObjectProperty<UpgradeStrategy> strategy = new SimpleObjectProperty<>(); private final UpgradeStrategies strategies; private final AsyncTaskService asyncTaskService; private Optional<UpgradeListener> listener = Optional.empty(); private Vault vault; @Inject public UpgradeController(Localization localization, UpgradeStrategies strategies, AsyncTaskService asyncTaskService) { this.strategies = strategies; this.asyncTaskService = asyncTaskService; } @FXML private Label upgradeTitleLabel; @FXML private Label upgradeMsgLabel; @FXML private SecPasswordField passwordField; @FXML private CheckBox confirmationCheckbox; @FXML private Button upgradeButton; @FXML private ProgressIndicator progressIndicator; @FXML private Label errorLabel; @FXML private GridPane root; @Override public void initialize() { upgradeTitleLabel.textProperty().bind(EasyBind.monadic(strategy).map(this::upgradeTitle).orElse("")); upgradeMsgLabel.textProperty().bind(EasyBind.monadic(strategy).map(this::upgradeMessage).orElse("")); BooleanExpression passwordProvided = passwordField.textProperty().isNotEmpty().and(passwordField.disabledProperty().not()); BooleanExpression syncFinished = confirmationCheckbox.selectedProperty(); upgradeButton.disableProperty().bind(passwordProvided.not().or(syncFinished.not())); } @Override public Parent getRoot() { return root; } void setVault(Vault vault) { this.vault = Objects.requireNonNull(vault); errorLabel.setText(null); strategy.set(strategies.getUpgradeStrategy(vault)); // trigger "default" change to refresh key bindings: upgradeButton.setDefaultButton(false); upgradeButton.setDefaultButton(true); } // **************************************** // Upgrade label // **************************************** private String upgradeTitle(UpgradeStrategy instruction) { return instruction.getTitle(vault); } private String upgradeMessage(UpgradeStrategy instruction) { return instruction.getMessage(vault); } // **************************************** // Upgrade button // **************************************** @FXML private void didClickUpgradeButton(ActionEvent event) { EasyBind.monadic(strategy).ifPresent(this::upgrade); } private void upgrade(UpgradeStrategy instruction) { passwordField.setDisable(true); progressIndicator.setVisible(true); asyncTaskService // .asyncTaskOf(() -> { if (!instruction.isApplicable(vault)) { throw new IllegalStateException("No ugprade needed for " + vault.getPath()); } instruction.upgrade(vault, passwordField.getCharacters()); }) // .onSuccess(this::showNextUpgrade) // .onError(UpgradeFailedException.class, e -> { errorLabel.setText(e.getLocalizedMessage()); }) // .andFinally(() -> { progressIndicator.setVisible(false); passwordField.setDisable(false); passwordField.swipe(); }).run(); } private void showNextUpgrade() { errorLabel.setText(null); UpgradeStrategy nextStrategy = strategies.getUpgradeStrategy(vault); if (nextStrategy != null) { strategy.set(nextStrategy); } else { listener.ifPresent(UpgradeListener::didUpgrade); } } /* callback */ public void setListener(UpgradeListener listener) { this.listener = Optional.ofNullable(listener); } @FunctionalInterface interface UpgradeListener { void didUpgrade(); } }