rework convert button logic

This commit is contained in:
Armin Schrenk
2023-04-04 12:42:23 +02:00
parent 65eca31d26
commit 3a50c32e50
4 changed files with 37 additions and 15 deletions

View File

@@ -21,16 +21,20 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
@@ -52,13 +56,15 @@ public class HubToLocalConvertController implements FxController {
private final RecoveryKeyFactory recoveryKeyFactory;
private final MasterkeyFileAccess masterkeyFileAccess;
private final ExecutorService backgroundExecutorService;
private final BooleanProperty isConverting;
private final ResourceBundle resourceBundle;
private final BooleanProperty conversionStarted;
@FXML
NewPasswordController newPasswordController;
public Button convertBtn;
@Inject
public HubToLocalConvertController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOLOCAL_SUCCESS) Lazy<Scene> successScene, FxApplicationWindows applicationWindows, @ConvertVaultWindow Vault vault, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess, ExecutorService backgroundExecutorService) {
public HubToLocalConvertController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOLOCAL_SUCCESS) Lazy<Scene> successScene, FxApplicationWindows applicationWindows, @ConvertVaultWindow Vault vault, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess, ExecutorService backgroundExecutorService, ResourceBundle resourceBundle) {
this.window = window;
this.successScene = successScene;
this.applicationWindows = applicationWindows;
@@ -67,11 +73,23 @@ public class HubToLocalConvertController implements FxController {
this.recoveryKeyFactory = recoveryKeyFactory;
this.masterkeyFileAccess = masterkeyFileAccess;
this.backgroundExecutorService = backgroundExecutorService;
this.isConverting = new SimpleBooleanProperty(false);
this.resourceBundle = resourceBundle;
this.conversionStarted = new SimpleBooleanProperty(false);
}
@FXML
public void initialize() {
convertBtn.disableProperty().bind(Bindings.createBooleanBinding( //
() -> !newPasswordController.isGoodPassword() || conversionStarted.get(), //
newPasswordController.goodPasswordProperty(), //
conversionStarted));
convertBtn.contentDisplayProperty().bind(Bindings.createObjectBinding( //
() -> conversionStarted.getValue() ? ContentDisplay.LEFT : ContentDisplay.TEXT_ONLY, //
conversionStarted));
convertBtn.textProperty().bind(Bindings.createStringBinding( //
() -> resourceBundle.getString("convertVault.convert.convertBtn." + (conversionStarted.get() ? "processing" : "before")), //
conversionStarted));
}
@FXML
@@ -83,10 +101,9 @@ public class HubToLocalConvertController implements FxController {
public void convert() {
Preconditions.checkState(newPasswordController.isGoodPassword());
LOG.info("Converting hub vault {} to local", vault.getPath());
CompletableFuture.runAsync(() -> isConverting.setValue(true), Platform::runLater) //
CompletableFuture.runAsync(() -> conversionStarted.setValue(true), Platform::runLater) //
.thenRunAsync(this::convertInternal, backgroundExecutorService) //TODO: which executor is used?
.whenCompleteAsync((result, exception) -> {
isConverting.setValue(false);
if (exception == null) { //TODO: check, how the exceptions are wrapped
LOG.info("Conversion of vault {} succeeded.", vault.getPath());
window.setScene(successScene.get());
@@ -138,8 +155,4 @@ public class HubToLocalConvertController implements FxController {
/* Getter/Setter */
public NewPasswordController getNewPasswordController() {
return newPasswordController;
}
}

View File

@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5Spinner?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.convertvault.HubToLocalConvertController"
@@ -25,7 +26,11 @@
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
<buttons>
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
<Button text="%convertVault.convert.convertBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#convert" disable="${!controller.newPasswordController.goodPassword}"/>
<Button fx:id="convertBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#convert"> <!-- for button logic, see controller -->
<graphic>
<FontAwesome5Spinner glyphSize="12"/>
</graphic>
</Button>
</buttons>
</ButtonBar>
</VBox>

View File

@@ -462,7 +462,8 @@ recoveryKey.recover.resetSuccess.description=You can unlock your vault with the
# Convert Vault
convertVault.title=Convert vault
convertVault.convert.convertBtn=Convert vault
convertVault.convert.convertBtn.before=Convert vault
convertVault.convert.convertBtn.processing=Converting…
convertVault.success.message=Conversion successful
convertVault.success.description=You can now unlock the vault with the chosen password without requiring authentication or internet access.

View File

@@ -26,6 +26,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
@@ -41,6 +42,7 @@ public class HubToLocalConvertControllerTest {
RecoveryKeyFactory recoveryKeyFactory;
MasterkeyFileAccess masterkeyFileAccess;
ExecutorService backgroundExecutorService;
ResourceBundle resourceBundle;
BooleanProperty isConverting;
FxApplicationWindows appWindows;
Lazy<Scene> successScene;
@@ -57,11 +59,12 @@ public class HubToLocalConvertControllerTest {
recoveryKeyFactory = Mockito.mock(RecoveryKeyFactory.class);
masterkeyFileAccess = Mockito.mock(MasterkeyFileAccess.class);
backgroundExecutorService = Mockito.mock(ExecutorService.class);
resourceBundle = Mockito.mock(ResourceBundle.class);
isConverting = Mockito.mock(BooleanProperty.class);
appWindows = Mockito.mock(FxApplicationWindows.class);
successScene = Mockito.mock(Lazy.class);
newPasswordController = Mockito.mock(NewPasswordController.class);
inTest = new HubToLocalConvertController(window, successScene, appWindows, vault, recoveryKey, recoveryKeyFactory, masterkeyFileAccess, backgroundExecutorService);
inTest = new HubToLocalConvertController(window, successScene, appWindows, vault, recoveryKey, recoveryKeyFactory, masterkeyFileAccess, backgroundExecutorService, resourceBundle);
inTest.newPasswordController = newPasswordController;
}
@@ -136,7 +139,7 @@ public class HubToLocalConvertControllerTest {
@Test
public void testConvertInternalNotWrapsIAE() throws IOException {
Mockito.doThrow(new IllegalArgumentException("yudu")).when(recoveryKeyFactory).newMasterkeyFileWithPassphrase(any(),anyString(),any());
Mockito.doThrow(new IllegalArgumentException("yudu")).when(recoveryKeyFactory).newMasterkeyFileWithPassphrase(any(), anyString(), any());
Assertions.assertThrows(IllegalArgumentException.class, inSpy::convertInternal);