~exprez135/cryptomator-libre

d9677fe7c4a10705cc2dcbf01fc468c3f77d89a2 — Sebastian Stenzel 2 years ago fa7421b
Split up vault detail view
M main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +15 -0
@@ 87,6 87,21 @@ abstract class MainWindowModule {

	@Binds
	@IntoMap
	@FxControllerKey(VaultDetailLockedController.class)
	abstract FxController bindVaultDetailLockedController(VaultDetailLockedController controller);

	@Binds
	@IntoMap
	@FxControllerKey(VaultDetailUnlockedController.class)
	abstract FxController bindVaultDetailUnlockedController(VaultDetailUnlockedController controller);

	@Binds
	@IntoMap
	@FxControllerKey(VaultDetailNeedsMigrationController.class)
	abstract FxController bindVaultDetailNeedsMigrationController(VaultDetailNeedsMigrationController controller);

	@Binds
	@IntoMap
	@FxControllerKey(VaultListCellController.class)
	abstract FxController bindVaultListCellController(VaultListCellController controller);


M main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailController.java +3 -59
@@ 4,46 4,30 @@ import javafx.beans.binding.Binding;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.common.vaults.Volume;
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;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.util.concurrent.ExecutorService;

@MainWindowScoped
public class VaultDetailController implements FxController {

	private static final Logger LOG = LoggerFactory.getLogger(VaultDetailController.class);

	private final ReadOnlyObjectProperty<Vault> vault;
	private final FxApplication application;
	private final Binding<FontAwesome5Icon> glyph;
	private final BooleanBinding anyVaultSelected;
	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, MigrationComponent.Builder vaultMigrationWindow) {
	VaultDetailController(ObjectProperty<Vault> vault, FxApplication application) {
		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.glyph = EasyBind.select(vault).selectObject(Vault::stateProperty).map(this::getGlyphForVaultState).orElse(FontAwesome5Icon.EXCLAMATION_TRIANGLE);
		this.anyVaultSelected = vault.isNotNull();
		this.vaultMigrationWindow = vaultMigrationWindow;
	}

	private FontAwesome5Icon getGlyphForVaultState(VaultState state) {


@@ 60,50 44,10 @@ public class VaultDetailController implements FxController {
	}

	@FXML
	public void unlock() {
		application.showUnlockWindow(vault.get());
	}

	@FXML
	public void lock() {
		Vault v = vault.get();
		v.setState(VaultState.PROCESSING);
		Tasks.create(() -> {
			v.lock(false);
		}).onSuccess(() -> {
			LOG.trace("Regular unmount succeeded.");
			v.setState(VaultState.LOCKED);
		}).onError(Exception.class, e -> {
			v.setState(VaultState.UNLOCKED);
			LOG.error("Regular unmount failed.", e);
			// TODO
		}).runOnce(executor);
	}

	@FXML
	public void showVaultOptions() {
		vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow();
	}

	@FXML
	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() {
		try {
			vault.get().reveal();
		} catch (Volume.VolumeException e) {
			LOG.error("Failed to reveal vault.", e);
		}
	}

	/* Observable Properties */

	public ReadOnlyObjectProperty<Vault> vaultProperty() {

A main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailLockedController.java +46 -0
@@ 0,0 1,46 @@
package org.cryptomator.ui.mainwindow;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.fxapp.FxApplication;
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;

import javax.inject.Inject;

@MainWindowScoped
public class VaultDetailLockedController implements FxController {

	private final ReadOnlyObjectProperty<Vault> vault;
	private final FxApplication application;
	private final VaultOptionsComponent.Builder vaultOptionsWindow;

	@Inject
	VaultDetailLockedController(ObjectProperty<Vault> vault, FxApplication application, VaultOptionsComponent.Builder vaultOptionsWindow) {
		this.vault = vault;
		this.application = application;
		this.vaultOptionsWindow = vaultOptionsWindow;
	}

	@FXML
	public void unlock() {
		application.showUnlockWindow(vault.get());
	}

	@FXML
	public void showVaultOptions() {
		vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow();
	}
	
	/* Getter/Setter */

	public ReadOnlyObjectProperty<Vault> vaultProperty() {
		return vault;
	}

	public Vault getVault() {
		return vault.get();
	}
}

A main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailNeedsMigrationController.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailNeedsMigrationController.java +28 -0
@@ 0,0 1,28 @@
package org.cryptomator.ui.mainwindow;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.migration.MigrationComponent;

import javax.inject.Inject;

@MainWindowScoped
public class VaultDetailNeedsMigrationController implements FxController {

	private final ReadOnlyObjectProperty<Vault> vault;
	private final MigrationComponent.Builder vaultMigrationWindow;

	@Inject
	public VaultDetailNeedsMigrationController(ObjectProperty<Vault> vault, MigrationComponent.Builder vaultMigrationWindow) {
		this.vault = vault;
		this.vaultMigrationWindow = vaultMigrationWindow;
	}

	@FXML
	public void showVaultMigrator() {
		vaultMigrationWindow.vault(vault.get()).build().showMigrationWindow();
	}
}

A main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java => main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java +66 -0
@@ 0,0 1,66 @@
package org.cryptomator.ui.mainwindow;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.common.vaults.Volume;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.Tasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.util.concurrent.ExecutorService;

@MainWindowScoped
public class VaultDetailUnlockedController implements FxController {

	private static final Logger LOG = LoggerFactory.getLogger(VaultDetailUnlockedController.class);

	private final ReadOnlyObjectProperty<Vault> vault;
	private final ExecutorService executor;

	@Inject
	public VaultDetailUnlockedController(ObjectProperty<Vault> vault, ExecutorService executor) {
		this.vault = vault;
		this.executor = executor;
	}

	@FXML
	public void revealAccessLocation() {
		try {
			vault.get().reveal();
		} catch (Volume.VolumeException e) {
			LOG.error("Failed to reveal vault.", e);
		}
	}

	@FXML
	public void lock() {
		Vault v = vault.get();
		v.setState(VaultState.PROCESSING);
		Tasks.create(() -> {
			v.lock(false);
		}).onSuccess(() -> {
			LOG.trace("Regular unmount succeeded.");
			v.setState(VaultState.LOCKED);
		}).onError(Exception.class, e -> {
			v.setState(VaultState.UNLOCKED);
			LOG.error("Regular unmount failed.", e);
			// TODO
		}).runOnce(executor);
	}

	/* Getter/Setter */

	public ReadOnlyObjectProperty<Vault> vaultProperty() {
		return vault;
	}

	public Vault getVault() {
		return vault.get();
	}

}

M main/ui/src/main/resources/fxml/vault_detail.fxml => main/ui/src/main/resources/fxml/vault_detail.fxml +3 -58
@@ 1,7 1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tooltip?>


@@ 11,7 10,6 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.ThrougputLabel?>
<VBox xmlns="http://javafx.com/javafx"
	  xmlns:fx="http://javafx.com/fxml"
	  fx:controller="org.cryptomator.ui.mainwindow.VaultDetailController"


@@ 52,61 50,8 @@

		<Region prefHeight="12" VBox.vgrow="NEVER"/>

		<VBox alignment="CENTER" spacing="9" visible="${controller.vault.locked}" managed="${controller.vault.locked}">
			<Button styleClass="button-large" text="%main.vaultDetail.unlockBtn" minWidth="120" onAction="#unlock" defaultButton="${controller.vault.locked}">
				<graphic>
					<FontAwesome5IconView glyph="KEY" glyphSize="15"/>
				</graphic>
			</Button>
			<Hyperlink text="%main.vaultDetail.optionsBtn" onAction="#showVaultOptions">
				<graphic>
					<FontAwesome5IconView glyph="COG"/>
				</graphic>
			</Hyperlink>
		</VBox>
		<VBox alignment="CENTER" spacing="9" visible="${controller.vault.unlocked}" managed="${controller.vault.unlocked}">
			<Label text="%main.vaultDetail.accessLocation"/>
			<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#revealAccessLocation" defaultButton="${controller.vault.unlocked}">
				<graphic>
					<HBox spacing="12" alignment="CENTER">
						<FontAwesome5IconView glyph="HDD" glyphSize="24"/>
						<VBox spacing="4" alignment="CENTER_LEFT">
							<Label text="%main.vaultDetail.revealBtn"/>
							<Label styleClass="label-small" text="${controller.vault.accessPoint}" textOverrun="CENTER_ELLIPSIS"/>
						</VBox>
					</HBox>
				</graphic>
				<tooltip>
					<Tooltip text="${controller.vault.accessPoint}"/>
				</tooltip>
			</Button>
			<Button text="%main.vaultDetail.lockBtn" minWidth="120" onAction="#lock">
				<graphic>
					<FontAwesome5IconView glyph="KEY"/>
				</graphic>
			</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}">
			<HBox alignment="CENTER_RIGHT" spacing="6">
				<Label styleClass="label-small" text="%main.vaultDetail.bytesPerSecondRead"/>
				<ThrougputLabel styleClass="label-small" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
								mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.vault.stats.bytesPerSecondRead}"/>
			</HBox>
			<HBox alignment="CENTER_RIGHT" spacing="6">
				<Label styleClass="label-small" text="%main.vaultDetail.bytesPerSecondWritten"/>
				<ThrougputLabel styleClass="label-small" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
								mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.vault.stats.bytesPerSecondWritten}"/>
			</HBox>
		</VBox>
		<fx:include VBox.vgrow="ALWAYS" source="vault_detail_locked.fxml" visible="${controller.vault.locked}" managed="${controller.vault.locked}"/>
		<fx:include VBox.vgrow="ALWAYS" source="vault_detail_unlocked.fxml" visible="${controller.vault.unlocked}" managed="${controller.vault.unlocked}"/>
		<fx:include VBox.vgrow="ALWAYS" source="vault_detail_needsmigration.fxml" visible="${controller.vault.needsMigration}" managed="${controller.vault.needsMigration}"/>
	</children>
</VBox>

A main/ui/src/main/resources/fxml/vault_detail_locked.fxml => main/ui/src/main/resources/fxml/vault_detail_locked.fxml +28 -0
@@ 0,0 1,28 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<VBox xmlns="http://javafx.com/javafx"
	  xmlns:fx="http://javafx.com/fxml"
	  fx:controller="org.cryptomator.ui.mainwindow.VaultDetailLockedController"
	  alignment="TOP_CENTER"
	  spacing="9">
	<padding>
		<Insets topRightBottomLeft="24"/>
	</padding>
	<children>
		<Button styleClass="button-large" text="%main.vaultDetail.unlockBtn" minWidth="120" onAction="#unlock" defaultButton="${controller.vault.locked}">
			<graphic>
				<FontAwesome5IconView glyph="KEY" glyphSize="15"/>
			</graphic>
		</Button>
		<Hyperlink text="%main.vaultDetail.optionsBtn" onAction="#showVaultOptions">
			<graphic>
				<FontAwesome5IconView glyph="COG"/>
			</graphic>
		</Hyperlink>
	</children>
</VBox>

A main/ui/src/main/resources/fxml/vault_detail_needsmigration.fxml => main/ui/src/main/resources/fxml/vault_detail_needsmigration.fxml +20 -0
@@ 0,0 1,20 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<VBox xmlns="http://javafx.com/javafx"
	  xmlns:fx="http://javafx.com/fxml"
	  fx:controller="org.cryptomator.ui.mainwindow.VaultDetailNeedsMigrationController"
	  alignment="TOP_CENTER"
	  spacing="9">
	<padding>
		<Insets topRightBottomLeft="24"/>
	</padding>
	<children>
		<Button styleClass="button-large" text="TODO Upgrade Vault" minWidth="120" onAction="#showVaultMigrator">
			<graphic>
				<FontAwesome5IconView glyph="FILE_IMPORT" glyphSize="15"/>
			</graphic>
		</Button>
	</children>
</VBox>
\ No newline at end of file

A main/ui/src/main/resources/fxml/vault_detail_unlocked.fxml => main/ui/src/main/resources/fxml/vault_detail_unlocked.fxml +47 -0
@@ 0,0 1,47 @@
<?import javafx.scene.layout.HBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Region?>
<?import org.cryptomator.ui.controls.ThrougputLabel?>
<VBox xmlns="http://javafx.com/javafx"
	  xmlns:fx="http://javafx.com/fxml"
	  fx:controller="org.cryptomator.ui.mainwindow.VaultDetailUnlockedController"
	  alignment="TOP_CENTER"
	  spacing="9">
	<Label text="%main.vaultDetail.accessLocation"/>
	<Button styleClass="button-large" contentDisplay="GRAPHIC_ONLY" minWidth="120" onAction="#revealAccessLocation" defaultButton="${controller.vault.unlocked}">
		<graphic>
			<HBox spacing="12" alignment="CENTER">
				<FontAwesome5IconView glyph="HDD" glyphSize="24"/>
				<VBox spacing="4" alignment="CENTER_LEFT">
					<Label text="%main.vaultDetail.revealBtn"/>
					<Label styleClass="label-small" text="${controller.vault.accessPoint}" textOverrun="CENTER_ELLIPSIS"/>
				</VBox>
			</HBox>
		</graphic>
		<tooltip>
			<Tooltip text="${controller.vault.accessPoint}"/>
		</tooltip>
	</Button>
	<Button text="%main.vaultDetail.lockBtn" minWidth="120" onAction="#lock">
		<graphic>
			<FontAwesome5IconView glyph="KEY"/>
		</graphic>
	</Button>

	<Region VBox.vgrow="ALWAYS"/>

	<HBox alignment="CENTER_RIGHT" spacing="6">
		<Label styleClass="label-small" text="%main.vaultDetail.bytesPerSecondRead"/>
		<ThrougputLabel styleClass="label-small" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
						mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.vault.stats.bytesPerSecondRead}"/>
	</HBox>
	<HBox alignment="CENTER_RIGHT" spacing="6">
		<Label styleClass="label-small" text="%main.vaultDetail.bytesPerSecondWritten"/>
		<ThrougputLabel styleClass="label-small" alignment="CENTER_RIGHT" minWidth="60" idleFormat="%main.vaultDetail.throughput.idle" kibsFormat="%main.vaultDetail.throughput.kbps"
						mibsFormat="%main.vaultDetail.throughput.mbps" bytesPerSecond="${controller.vault.stats.bytesPerSecondWritten}"/>
	</HBox>
</VBox>
\ No newline at end of file