mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 04:31:27 +00:00
fixes #1083
This commit is contained in:
@@ -35,6 +35,7 @@ public class VaultSettings {
|
||||
public static final boolean DEFAULT_USES_READONLY_MODE = false;
|
||||
public static final String DEFAULT_MOUNT_FLAGS = "";
|
||||
public static final int DEFAULT_FILENAME_LENGTH_LIMIT = -1;
|
||||
public static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK;
|
||||
|
||||
private static final Random RNG = new Random();
|
||||
|
||||
@@ -49,6 +50,7 @@ public class VaultSettings {
|
||||
private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE);
|
||||
private final StringProperty mountFlags = new SimpleStringProperty(DEFAULT_MOUNT_FLAGS);
|
||||
private final IntegerProperty filenameLengthLimit = new SimpleIntegerProperty(DEFAULT_FILENAME_LENGTH_LIMIT);
|
||||
private final ObjectProperty<WhenUnlocked> actionAfterUnlock = new SimpleObjectProperty<>(DEFAULT_ACTION_AFTER_UNLOCK);
|
||||
|
||||
public VaultSettings(String id) {
|
||||
this.id = Objects.requireNonNull(id);
|
||||
@@ -57,7 +59,7 @@ public class VaultSettings {
|
||||
}
|
||||
|
||||
Observable[] observables() {
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath, usesReadOnlyMode, mountFlags, filenameLengthLimit};
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, useCustomMountPath, customMountPath, usesReadOnlyMode, mountFlags, filenameLengthLimit, actionAfterUnlock};
|
||||
}
|
||||
|
||||
private void deriveMountNameFromPath(Path path) {
|
||||
@@ -149,6 +151,14 @@ public class VaultSettings {
|
||||
return filenameLengthLimit;
|
||||
}
|
||||
|
||||
public ObjectProperty<WhenUnlocked> actionAfterUnlock() {
|
||||
return actionAfterUnlock;
|
||||
}
|
||||
|
||||
public WhenUnlocked getActionAfterUnlock() {
|
||||
return actionAfterUnlock.get();
|
||||
}
|
||||
|
||||
/* Hashcode/Equals */
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,6 +30,7 @@ class VaultSettingsJsonAdapter {
|
||||
out.name("usesReadOnlyMode").value(value.usesReadOnlyMode().get());
|
||||
out.name("mountFlags").value(value.mountFlags().get());
|
||||
out.name("filenameLengthLimit").value(value.filenameLengthLimit().get());
|
||||
out.name("actionAfterUnlock").value(value.actionAfterUnlock().get().name());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
@@ -45,6 +46,7 @@ class VaultSettingsJsonAdapter {
|
||||
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
|
||||
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;
|
||||
int filenameLengthLimit = VaultSettings.DEFAULT_FILENAME_LENGTH_LIMIT;
|
||||
WhenUnlocked actionAfterUnlock = VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
@@ -85,6 +87,9 @@ class VaultSettingsJsonAdapter {
|
||||
case "filenameLengthLimit":
|
||||
filenameLengthLimit = in.nextInt();
|
||||
break;
|
||||
case "actionAfterUnlock":
|
||||
actionAfterUnlock = parseActionAfterUnlock(in.nextString());
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unsupported vault setting found in JSON: " + name);
|
||||
in.skipValue();
|
||||
@@ -104,7 +109,17 @@ class VaultSettingsJsonAdapter {
|
||||
vaultSettings.usesReadOnlyMode().set(usesReadOnlyMode);
|
||||
vaultSettings.mountFlags().set(mountFlags);
|
||||
vaultSettings.filenameLengthLimit().set(filenameLengthLimit);
|
||||
vaultSettings.actionAfterUnlock().set(actionAfterUnlock);
|
||||
return vaultSettings;
|
||||
}
|
||||
|
||||
private WhenUnlocked parseActionAfterUnlock(String actionAfterUnlockName) {
|
||||
try {
|
||||
return WhenUnlocked.valueOf(actionAfterUnlockName.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.warn("Invalid action after unlock {}. Defaulting to {}.", actionAfterUnlockName, VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK);
|
||||
return VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
public enum WhenUnlocked {
|
||||
IGNORE("vaultOptions.general.actionAfterUnlock.ignore"),
|
||||
REVEAL("vaultOptions.general.actionAfterUnlock.reveal"),
|
||||
ASK("vaultOptions.general.actionAfterUnlock.ask");
|
||||
|
||||
private String displayName;
|
||||
|
||||
WhenUnlocked(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,10 @@ import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.settings.WhenUnlocked;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
@@ -29,6 +31,8 @@ public class UnlockSuccessController implements FxController {
|
||||
private final VaultService vaultService;
|
||||
private final ObjectProperty<ContentDisplay> revealButtonState;
|
||||
private final BooleanProperty revealButtonDisabled;
|
||||
|
||||
public CheckBox rememberChoiceCheckbox;
|
||||
|
||||
@Inject
|
||||
public UnlockSuccessController(@UnlockWindow Stage window, @UnlockWindow Vault vault, ExecutorService executor, VaultService vaultService) {
|
||||
@@ -44,6 +48,9 @@ public class UnlockSuccessController implements FxController {
|
||||
public void close() {
|
||||
LOG.trace("UnlockSuccessController.close()");
|
||||
window.close();
|
||||
if (rememberChoiceCheckbox.isSelected()) {
|
||||
vault.getVaultSettings().actionAfterUnlock().setValue(WhenUnlocked.IGNORE);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -64,6 +71,9 @@ public class UnlockSuccessController implements FxController {
|
||||
revealButtonDisabled.set(false);
|
||||
});
|
||||
executor.execute(revealTask);
|
||||
if (rememberChoiceCheckbox.isSelected()) {
|
||||
vault.getVaultSettings().actionAfterUnlock().setValue(WhenUnlocked.REVEAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
@@ -5,6 +5,7 @@ import javafx.application.Platform;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.common.settings.WhenUnlocked;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.common.vaults.Volume;
|
||||
@@ -121,9 +122,12 @@ public class UnlockWorkflow extends Task<Boolean> {
|
||||
if (savePassword.get()) {
|
||||
savePasswordToSystemkeychain();
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
window.setScene(successScene.get()); // TODO only if enabled (see issue #1083)
|
||||
});
|
||||
if (vault.getVaultSettings().actionAfterUnlock().get() == WhenUnlocked.ASK) {
|
||||
Platform.runLater(() -> {
|
||||
window.setScene(successScene.get());
|
||||
window.show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void savePasswordToSystemkeychain() {
|
||||
|
||||
@@ -2,24 +2,56 @@ package org.cryptomator.ui.vaultoptions;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.util.StringConverter;
|
||||
import org.cryptomator.common.settings.UiTheme;
|
||||
import org.cryptomator.common.settings.WhenUnlocked;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@VaultOptionsScoped
|
||||
public class GeneralVaultOptionsController implements FxController {
|
||||
|
||||
private final Vault vault;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
public CheckBox unlockOnStartupCheckbox;
|
||||
public ChoiceBox<WhenUnlocked> actionAfterUnlockChoiceBox;
|
||||
|
||||
@Inject
|
||||
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault) {
|
||||
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, ResourceBundle resourceBundle) {
|
||||
this.vault = vault;
|
||||
this.resourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
unlockOnStartupCheckbox.selectedProperty().bindBidirectional(vault.getVaultSettings().unlockAfterStartup());
|
||||
actionAfterUnlockChoiceBox.getItems().addAll(WhenUnlocked.values());
|
||||
actionAfterUnlockChoiceBox.valueProperty().bindBidirectional(vault.getVaultSettings().actionAfterUnlock());
|
||||
actionAfterUnlockChoiceBox.setConverter(new WhenUnlockedConverter(resourceBundle));
|
||||
}
|
||||
|
||||
private static class WhenUnlockedConverter extends StringConverter<WhenUnlocked> {
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
public WhenUnlockedConverter(ResourceBundle resourceBundle) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(WhenUnlocked obj) {
|
||||
return resourceBundle.getString(obj.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenUnlocked fromString(String string) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<VBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.unlock.UnlockSuccessController"
|
||||
@@ -26,7 +27,10 @@
|
||||
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="24"/>
|
||||
</StackPane>
|
||||
<FormattedLabel format="%unlock.success.message" arg1="${controller.vault.displayableName}" wrapText="true" HBox.hgrow="ALWAYS"/>
|
||||
<VBox spacing="6">
|
||||
<FormattedLabel format="%unlock.success.message" arg1="${controller.vault.displayableName}" wrapText="true" HBox.hgrow="ALWAYS"/>
|
||||
<CheckBox text="%unlock.success.rememberChoice" fx:id="rememberChoiceCheckbox"/>
|
||||
</VBox>
|
||||
</HBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<VBox xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="org.cryptomator.ui.vaultoptions.GeneralVaultOptionsController"
|
||||
@@ -12,5 +15,10 @@
|
||||
</padding>
|
||||
<children>
|
||||
<CheckBox text="%vaultOptions.general.unlockAfterStartup" fx:id="unlockOnStartupCheckbox"/>
|
||||
|
||||
<HBox spacing="6" alignment="CENTER_LEFT">
|
||||
<Label text="%vaultOptions.general.actionAfterUnlock"/>
|
||||
<ChoiceBox fx:id="actionAfterUnlockChoiceBox"/>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
@@ -96,6 +96,7 @@ unlock.savePassword=Save Password
|
||||
unlock.unlockBtn=Unlock
|
||||
## Success
|
||||
unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible.
|
||||
unlock.success.rememberChoice=Remember choice, don't show this again
|
||||
unlock.success.revealBtn=Reveal Vault
|
||||
## Invalid Mount Point
|
||||
unlock.error.invalidMountPoint=Mount point is not an empty directory: %s
|
||||
@@ -206,6 +207,10 @@ wrongFileAlert.link=For further assistance, visit
|
||||
## General
|
||||
vaultOptions.general=General
|
||||
vaultOptions.general.unlockAfterStartup=Unlock vault when starting Cryptomator
|
||||
vaultOptions.general.actionAfterUnlock=After successful unlock
|
||||
vaultOptions.general.actionAfterUnlock.ignore=Do nothing
|
||||
vaultOptions.general.actionAfterUnlock.reveal=Reveal Drive
|
||||
vaultOptions.general.actionAfterUnlock.ask=Ask
|
||||
## Mount
|
||||
vaultOptions.mount=Mounting
|
||||
vaultOptions.mount.readonly=Read-Only
|
||||
|
||||
Reference in New Issue
Block a user