Explorar el Código

Hook up migration window

Sebastian Stenzel hace 5 años
padre
commit
f35f04851e

+ 10 - 0
main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java

@@ -68,6 +68,7 @@ public class Vault {
 	private final BooleanBinding locked;
 	private final BooleanBinding processing;
 	private final BooleanBinding unlocked;
+	private final BooleanBinding needsMigration;
 	private final ObjectBinding<Path> accessPoint;
 
 	private volatile Volume volume;
@@ -85,6 +86,7 @@ public class Vault {
 		this.locked = Bindings.createBooleanBinding(this::isLocked, state);
 		this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
 		this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
+		this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
 		this.accessPoint = Bindings.createObjectBinding(this::getAccessPoint, state);
 	}
 
@@ -215,6 +217,14 @@ public class Vault {
 	public boolean isUnlocked() {
 		return state.get() == VaultState.UNLOCKED;
 	}
+	
+	public BooleanBinding needsMigrationProperty() {
+		return needsMigration;
+	}
+	
+	public boolean isNeedsMigration() {
+		return state.get() == VaultState.NEEDS_MIGRATION;
+	}
 
 	public StringBinding displayableNameProperty() {
 		return displayableName;

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -9,6 +9,7 @@ public enum FxmlFile {
 	ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
 	CHANGEPASSWORD("/fxml/changepassword.fxml"), //
 	MAIN_WINDOW("/fxml/main_window.fxml"), //
+	MIGRATION_START("/fxml/migration_start.fxml"), //
 	PREFERENCES("/fxml/preferences.fxml"), //
 	QUIT("/fxml/quit.fxml"), //
 	REMOVE_VAULT("/fxml/remove_vault.fxml"), //

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java

@@ -12,6 +12,7 @@ public enum FontAwesome5Icon {
 	EXCLAMATION_TRIANGLE("\uF071"), //
 	EYE("\uF06E"), //
 	EYE_SLASH("\uF070"), //
+	FILE_IMPORT("\uF56F"), //
 	FOLDER_OPEN("\uF07C"), //
 	HDD("\uF0A0"), //
 	KEY("\uF084"), //

+ 2 - 1
main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java

@@ -17,6 +17,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.migration.MigrationComponent;
 import org.cryptomator.ui.removevault.RemoveVaultComponent;
 import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
 import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
@@ -27,7 +28,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.ResourceBundle;
 
-@Module(subcomponents = {AddVaultWizardComponent.class, RemoveVaultComponent.class, VaultOptionsComponent.class, WrongFileAlertComponent.class})
+@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, RemoveVaultComponent.class, VaultOptionsComponent.class, WrongFileAlertComponent.class})
 abstract class MainWindowModule {
 
 	@Provides

+ 11 - 3
main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java

@@ -13,6 +13,7 @@ import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.Tasks;
 import org.cryptomator.ui.controls.FontAwesome5Icon;
 import org.cryptomator.ui.fxapp.FxApplication;
+import org.cryptomator.ui.migration.MigrationComponent;
 import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
 import org.fxmisc.easybind.EasyBind;
 import org.slf4j.Logger;
@@ -32,15 +33,17 @@ public class VaultDetailController implements FxController {
 	private final ExecutorService executor;
 	private final FxApplication application;
 	private final VaultOptionsComponent.Builder vaultOptionsWindow;
+	private final MigrationComponent.Builder vaultMigrationWindow;
 
 	@Inject
-	VaultDetailController(ObjectProperty<Vault> vault, ExecutorService executor, FxApplication application, VaultOptionsComponent.Builder vaultOptionsWindow) {
+	VaultDetailController(ObjectProperty<Vault> vault, ExecutorService executor, FxApplication application, VaultOptionsComponent.Builder vaultOptionsWindow, MigrationComponent.Builder vaultMigrationWindow) {
 		this.vault = vault;
 		this.glyph = EasyBind.select(vault).selectObject(Vault::stateProperty).map(this::getGlyphForVaultState).orElse(FontAwesome5Icon.EXCLAMATION_TRIANGLE);
 		this.executor = executor;
 		this.application = application;
 		this.vaultOptionsWindow = vaultOptionsWindow;
 		this.anyVaultSelected = vault.isNotNull();
+		this.vaultMigrationWindow = vaultMigrationWindow;
 	}
 
 	private FontAwesome5Icon getGlyphForVaultState(VaultState state) {
@@ -83,12 +86,17 @@ public class VaultDetailController implements FxController {
 	}
 
 	@FXML
-	public void revealStorageLocation(ActionEvent actionEvent) {
+	public void showVaultMigrator() {
+		vaultMigrationWindow.vault(vault.get()).build().showMigrationWindow();
+	}
+
+	@FXML
+	public void revealStorageLocation() {
 		application.getHostServices().showDocument(vault.get().getPath().toUri().toString());
 	}
 
 	@FXML
-	public void revealAccessLocation(ActionEvent actionEvent) {
+	public void revealAccessLocation() {
 		try {
 			vault.get().reveal();
 		} catch (Volume.VolumeException e) {

+ 38 - 0
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationComponent.java

@@ -0,0 +1,38 @@
+package org.cryptomator.ui.migration;
+
+import dagger.BindsInstance;
+import dagger.Lazy;
+import dagger.Subcomponent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
+
+@MigrationScoped
+@Subcomponent(modules = {MigrationModule.class})
+public interface MigrationComponent {
+
+	@MigrationWindow
+	Stage window();
+
+	@FxmlScene(FxmlFile.MIGRATION_START)
+	Lazy<Scene> scene();
+
+	default Stage showMigrationWindow() {
+		Stage stage = window();
+		stage.setScene(scene().get());
+		stage.show();
+		return stage;
+	}
+
+	@Subcomponent.Builder
+	interface Builder {
+
+		@BindsInstance
+		Builder vault(@MigrationWindow Vault vault);
+
+		MigrationComponent build();
+	}
+
+}

+ 71 - 0
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationModule.java

@@ -0,0 +1,71 @@
+package org.cryptomator.ui.migration;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.IntoMap;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import org.cryptomator.ui.common.FXMLLoaderFactory;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.FxControllerKey;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
+import org.cryptomator.ui.mainwindow.MainWindow;
+
+import javax.inject.Named;
+import javax.inject.Provider;
+import java.util.Map;
+import java.util.Optional;
+import java.util.ResourceBundle;
+
+@Module
+abstract class MigrationModule {
+
+	@Provides
+	@MigrationWindow
+	@MigrationScoped
+	static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, ResourceBundle resourceBundle) {
+		return new FXMLLoaderFactory(factories, resourceBundle);
+	}
+
+	@Provides
+	@MigrationWindow
+	@MigrationScoped
+	static Stage provideStage(@MainWindow Stage owner, ResourceBundle resourceBundle, @Named("windowIcon") Optional<Image> windowIcon) {
+		Stage stage = new Stage();
+		stage.setTitle(resourceBundle.getString("unlock.title"));
+		stage.setResizable(false);
+		stage.initModality(Modality.WINDOW_MODAL);
+		stage.initOwner(owner);
+		windowIcon.ifPresent(stage.getIcons()::add);
+		return stage;
+	}
+
+	@Provides
+	@FxmlScene(FxmlFile.MIGRATION_START)
+	@MigrationScoped
+	static Scene provideMigrationStartScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders, @MigrationWindow Stage window) {
+		Scene scene = fxmlLoaders.createScene("/fxml/migration_start.fxml"); // TODO rename fxml file
+
+		KeyCombination cmdW = new KeyCodeCombination(KeyCode.W, KeyCombination.SHORTCUT_DOWN);
+		scene.getAccelerators().put(cmdW, window::close);
+
+		return scene;
+	}
+
+
+	// ------------------
+
+	@Binds
+	@IntoMap
+	@FxControllerKey(MigrationStartController.class)
+	abstract FxController bindMigrationStartController(MigrationStartController controller);
+
+
+}

+ 13 - 0
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationScoped.java

@@ -0,0 +1,13 @@
+package org.cryptomator.ui.migration;
+
+import javax.inject.Scope;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Scope
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@interface MigrationScoped {
+
+}

+ 46 - 0
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationStartController.java

@@ -0,0 +1,46 @@
+package org.cryptomator.ui.migration;
+
+import dagger.Lazy;
+import javafx.fxml.FXML;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
+
+import javax.inject.Inject;
+
+@MigrationScoped
+public class MigrationStartController implements FxController {
+
+	private final Stage window;
+	private final Vault vault;
+	private final Lazy<Scene> successScene;
+
+	@Inject
+	public MigrationStartController(@MigrationWindow Stage window, @MigrationWindow Vault vault, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> successScene) {
+		this.window = window;
+		this.vault = vault;
+		this.successScene = successScene;
+	}
+
+	public void initialize() {
+	}
+
+	@FXML
+	public void cancel() {
+		window.close();
+	}
+
+	@FXML
+	public void proceed() {
+
+	}
+
+	/* Getter/Setter */
+
+	public Vault getVault() {
+		return vault;
+	}
+}

+ 14 - 0
main/ui/src/main/java/org/cryptomator/ui/migration/MigrationWindow.java

@@ -0,0 +1,14 @@
+package org.cryptomator.ui.migration;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface MigrationWindow {
+
+}

+ 45 - 0
main/ui/src/main/resources/fxml/migration_start.fxml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.CheckBox?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.shape.Circle?>
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<?import org.cryptomator.ui.controls.FormattedLabel?>
+<VBox xmlns="http://javafx.com/javafx"
+	  xmlns:fx="http://javafx.com/fxml"
+	  fx:controller="org.cryptomator.ui.migration.MigrationStartController"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145"
+	  spacing="12">
+	<padding>
+		<Insets topRightBottomLeft="12"/>
+	</padding>
+	<children>
+		<HBox spacing="12" alignment="CENTER_LEFT" VBox.vgrow="ALWAYS">
+			<StackPane alignment="CENTER" HBox.hgrow="NEVER">
+				<Circle styleClass="glyph-icon-primary" radius="24"/>
+				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="FILE_IMPORT" glyphSize="24"/>
+			</StackPane>
+
+			<VBox spacing="6" HBox.hgrow="ALWAYS">
+				<FormattedLabel format="TODO Your vault &quot;%s&quot; needs to be updated to a newer format. Before proceeding, make sure there is no pending synchronization affecting this vault." arg1="${controller.vault.displayableName}" wrapText="true" />
+				<CheckBox fx:id="confirmSyncDone" text="TODO Yes, my vault is fully synced"/>
+			</VBox>
+		</HBox>
+
+		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
+			<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
+				<buttons>
+					<Button text="%generic.button.done" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel"/>
+					<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#proceed" disable="${!confirmSyncDone.selected}"/>
+				</buttons>
+			</ButtonBar>
+		</VBox>
+	</children>
+</VBox>

+ 7 - 0
main/ui/src/main/resources/fxml/vault_detail.fxml

@@ -87,6 +87,13 @@
 			</Button>
 		</VBox>
 
+		<!-- TODO we might want to split this fxml file into one file per vault state -->
+		<Button styleClass="button-large" text="TODO Upgrade Vault" minWidth="120" onAction="#showVaultMigrator" visible="${controller.vault.needsMigration}">
+			<graphic>
+				<FontAwesome5IconView glyph="FILE_IMPORT" glyphSize="15"/>
+			</graphic>
+		</Button>
+
 		<Region VBox.vgrow="ALWAYS"/>
 
 		<VBox spacing="6" visible="${controller.vault.unlocked}" managed="${controller.vault.unlocked}">