~exprez135/cryptomator-libre

f35f04851e5d8865e32043acbbc8b64fb84064af — Sebastian Stenzel 2 years ago cb4717b
Hook up migration window
M main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java => main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java +10 -0
@@ 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;

M main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java => main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java +1 -0
@@ 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"), //

M main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java => main/ui/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java +1 -0
@@ 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"), //

M main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +2 -1
@@ 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

M main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java +11 -3
@@ 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) {

A main/ui/src/main/java/org/cryptomator/ui/migration/MigrationComponent.java => main/ui/src/main/java/org/cryptomator/ui/migration/MigrationComponent.java +38 -0
@@ 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();
	}

}

A main/ui/src/main/java/org/cryptomator/ui/migration/MigrationModule.java => main/ui/src/main/java/org/cryptomator/ui/migration/MigrationModule.java +71 -0
@@ 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);


}

A main/ui/src/main/java/org/cryptomator/ui/migration/MigrationScoped.java => main/ui/src/main/java/org/cryptomator/ui/migration/MigrationScoped.java +13 -0
@@ 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 {

}

A main/ui/src/main/java/org/cryptomator/ui/migration/MigrationStartController.java => main/ui/src/main/java/org/cryptomator/ui/migration/MigrationStartController.java +46 -0
@@ 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;
	}
}

A main/ui/src/main/java/org/cryptomator/ui/migration/MigrationWindow.java => main/ui/src/main/java/org/cryptomator/ui/migration/MigrationWindow.java +14 -0
@@ 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 {

}

A main/ui/src/main/resources/fxml/migration_start.fxml => main/ui/src/main/resources/fxml/migration_start.fxml +45 -0
@@ 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>
\ No newline at end of file

M main/ui/src/main/resources/fxml/vault_detail.fxml => main/ui/src/main/resources/fxml/vault_detail.fxml +7 -0
@@ 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}">