Split up vault detail view

This commit is contained in:
Sebastian Stenzel
2019-09-06 19:25:25 +02:00
parent fa7421b1b0
commit d9677fe7c4
9 changed files with 256 additions and 117 deletions

View File

@@ -85,6 +85,21 @@ abstract class MainWindowModule {
@FxControllerKey(VaultDetailController.class)
abstract FxController bindVaultDetailController(VaultDetailController controller);
@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)

View File

@@ -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) {
@@ -59,51 +43,11 @@ 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() {

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>