浏览代码

Merge pull request #2245 from cryptomator/feature/location-preset-enum

Enumeenize well-known local cloud storage paths
Armin Schrenk 3 年之前
父节点
当前提交
4ecb98a5e6

+ 64 - 0
src/main/java/org/cryptomator/common/LocationPreset.java

@@ -0,0 +1,64 @@
+package org.cryptomator.common;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Enum of common cloud providers and their default local storage location path.
+ */
+public enum LocationPreset {
+
+	DROPBOX("Dropbox", "~/Dropbox"),
+	ICLOUDDRIVE("iCloud Drive", "~/Library/Mobile Documents/com~apple~CloudDocs", "~/iCloudDrive"),
+	GDRIVE("Google Drive", "~/Google Drive/My Drive", "~/Google Drive"),
+	MEGA("MEGA", "~/MEGA"),
+	ONEDRIVE("OneDrive", "~/OneDrive"),
+	PCLOUD("pCloud", "~/pCloudDrive"),
+
+	LOCAL("local");
+
+	private final String name;
+	private final List<Path> candidates;
+
+	LocationPreset(String name, String... candidates) {
+		this.name = name;
+		this.candidates = Arrays.stream(candidates).map(UserHome::resolve).map(Path::of).toList();
+	}
+
+	/**
+	 * Checks for this LocationPreset if any of the associated paths exist.
+	 *
+	 * @return the first existing path or null, if none exists.
+	 */
+	public Path existingPath() {
+		return candidates.stream().filter(Files::isDirectory).findFirst().orElse(null);
+	}
+
+	public String getDisplayName() {
+		return name;
+	}
+
+	@Override
+	public String toString() {
+		return getDisplayName();
+	}
+
+	//this contruct is needed, since static members are initialized after every enum member is initialized
+	//TODO: refactor this to normal class and use this also in different parts of the project
+	private static class UserHome {
+
+		private static final String USER_HOME = System.getProperty("user.home");
+
+		private static String resolve(String path) {
+			if (path.startsWith("~/")) {
+				return UserHome.USER_HOME + path.substring(1);
+			} else {
+				return path;
+			}
+		}
+	}
+
+}
+

+ 3 - 3
src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java

@@ -46,7 +46,7 @@ public class CreateNewVaultLocationController implements FxController {
 	private final Stage window;
 	private final Lazy<Scene> chooseNameScene;
 	private final Lazy<Scene> choosePasswordScene;
-	private final LocationPresets locationPresets;
+	private final ObservedLocationPresets locationPresets;
 	private final ObjectProperty<Path> vaultPath;
 	private final StringProperty vaultName;
 	private final ResourceBundle resourceBundle;
@@ -71,7 +71,7 @@ public class CreateNewVaultLocationController implements FxController {
 	public FontAwesome5IconView badLocation;
 
 	@Inject
-	CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
+	CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, ObservedLocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
 		this.window = window;
 		this.chooseNameScene = chooseNameScene;
 		this.choosePasswordScene = choosePasswordScene;
@@ -197,7 +197,7 @@ public class CreateNewVaultLocationController implements FxController {
 		return validVaultPath.get();
 	}
 
-	public LocationPresets getLocationPresets() {
+	public ObservedLocationPresets getObservedLocationPresets() {
 		return locationPresets;
 	}
 

+ 10 - 36
src/main/java/org/cryptomator/ui/addvaultwizard/LocationPresets.java

@@ -1,23 +1,15 @@
 package org.cryptomator.ui.addvaultwizard;
 
+import org.cryptomator.common.LocationPreset;
+
 import javax.inject.Inject;
 import javafx.beans.binding.BooleanBinding;
 import javafx.beans.property.ReadOnlyObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
-import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 
 @AddVaultWizardScoped
-public class LocationPresets {
-
-	private static final String USER_HOME = System.getProperty("user.home");
-	private static final String[] ICLOUDDRIVE_LOCATIONS = {"~/Library/Mobile Documents/iCloud~com~setolabs~Cryptomator/Documents", "~/iCloudDrive/iCloud~com~setolabs~Cryptomator"};
-	private static final String[] DROPBOX_LOCATIONS = {"~/Dropbox"};
-	private static final String[] GDRIVE_LOCATIONS = {"~/Google Drive/My Drive", "~/Google Drive"};
-	private static final String[] ONEDRIVE_LOCATIONS = {"~/OneDrive"};
-	private static final String[] MEGA_LOCATIONS = {"~/MEGA"};
-	private static final String[] PCLOUD_LOCATIONS = {"~/pCloudDrive"};
+public class ObservedLocationPresets {
 
 	private final ReadOnlyObjectProperty<Path> iclouddriveLocation;
 	private final ReadOnlyObjectProperty<Path> dropboxLocation;
@@ -33,13 +25,13 @@ public class LocationPresets {
 	private final BooleanBinding foundPcloud;
 
 	@Inject
-	public LocationPresets() {
-		this.iclouddriveLocation = new SimpleObjectProperty<>(existingWritablePath(ICLOUDDRIVE_LOCATIONS));
-		this.dropboxLocation = new SimpleObjectProperty<>(existingWritablePath(DROPBOX_LOCATIONS));
-		this.gdriveLocation = new SimpleObjectProperty<>(existingWritablePath(GDRIVE_LOCATIONS));
-		this.onedriveLocation = new SimpleObjectProperty<>(existingWritablePath(ONEDRIVE_LOCATIONS));
-		this.megaLocation = new SimpleObjectProperty<>(existingWritablePath(MEGA_LOCATIONS));
-		this.pcloudLocation = new SimpleObjectProperty<>(existingWritablePath(PCLOUD_LOCATIONS));
+	public ObservedLocationPresets() {
+		this.iclouddriveLocation = new SimpleObjectProperty<>(LocationPreset.ICLOUDDRIVE.existingPath());
+		this.dropboxLocation = new SimpleObjectProperty<>(LocationPreset.DROPBOX.existingPath());
+		this.gdriveLocation = new SimpleObjectProperty<>(LocationPreset.GDRIVE.existingPath());
+		this.onedriveLocation = new SimpleObjectProperty<>(LocationPreset.ONEDRIVE.existingPath());
+		this.megaLocation = new SimpleObjectProperty<>(LocationPreset.MEGA.existingPath());
+		this.pcloudLocation = new SimpleObjectProperty<>(LocationPreset.PCLOUD.existingPath());
 		this.foundIclouddrive = iclouddriveLocation.isNotNull();
 		this.foundDropbox = dropboxLocation.isNotNull();
 		this.foundGdrive = gdriveLocation.isNotNull();
@@ -48,24 +40,6 @@ public class LocationPresets {
 		this.foundPcloud = pcloudLocation.isNotNull();
 	}
 
-	private static Path existingWritablePath(String... candidates) {
-		for (String candidate : candidates) {
-			Path path = Paths.get(resolveHomePath(candidate));
-			if (Files.isDirectory(path)) {
-				return path;
-			}
-		}
-		return null;
-	}
-
-	private static String resolveHomePath(String path) {
-		if (path.startsWith("~/")) {
-			return USER_HOME + path.substring(1);
-		} else {
-			return path;
-		}
-	}
-
 	/* Observables */
 
 	public ReadOnlyObjectProperty<Path> iclouddriveLocationProperty() {

+ 6 - 6
src/main/resources/fxml/addvault_new_location.fxml

@@ -31,12 +31,12 @@
 
 		<VBox spacing="6">
 			<Label wrapText="true" text="%addvaultwizard.new.locationInstruction"/>
-			<RadioButton fx:id="iclouddriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="iCloud Drive" visible="${controller.locationPresets.foundIclouddrive}" managed="${controller.locationPresets.foundIclouddrive}"/>
-			<RadioButton fx:id="dropboxRadioButton" toggleGroup="${predefinedLocationToggler}" text="Dropbox" visible="${controller.locationPresets.foundDropbox}" managed="${controller.locationPresets.foundDropbox}"/>
-			<RadioButton fx:id="gdriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="Google Drive" visible="${controller.locationPresets.foundGdrive}" managed="${controller.locationPresets.foundGdrive}"/>
-			<RadioButton fx:id="onedriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="OneDrive" visible="${controller.locationPresets.foundOnedrive}" managed="${controller.locationPresets.foundOnedrive}"/>
-			<RadioButton fx:id="megaRadioButton" toggleGroup="${predefinedLocationToggler}" text="MEGA" visible="${controller.locationPresets.foundMega}" managed="${controller.locationPresets.foundMega}"/>
-			<RadioButton fx:id="pcloudRadioButton" toggleGroup="${predefinedLocationToggler}" text="pCloud" visible="${controller.locationPresets.foundPcloud}" managed="${controller.locationPresets.foundPcloud}"/>
+			<RadioButton fx:id="iclouddriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="iCloud Drive" visible="${controller.observedLocationPresets.foundIclouddrive}" managed="${controller.observedLocationPresets.foundIclouddrive}"/>
+			<RadioButton fx:id="dropboxRadioButton" toggleGroup="${predefinedLocationToggler}" text="Dropbox" visible="${controller.observedLocationPresets.foundDropbox}" managed="${controller.observedLocationPresets.foundDropbox}"/>
+			<RadioButton fx:id="gdriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="Google Drive" visible="${controller.observedLocationPresets.foundGdrive}" managed="${controller.observedLocationPresets.foundGdrive}"/>
+			<RadioButton fx:id="onedriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="OneDrive" visible="${controller.observedLocationPresets.foundOnedrive}" managed="${controller.observedLocationPresets.foundOnedrive}"/>
+			<RadioButton fx:id="megaRadioButton" toggleGroup="${predefinedLocationToggler}" text="MEGA" visible="${controller.observedLocationPresets.foundMega}" managed="${controller.observedLocationPresets.foundMega}"/>
+			<RadioButton fx:id="pcloudRadioButton" toggleGroup="${predefinedLocationToggler}" text="pCloud" visible="${controller.observedLocationPresets.foundPcloud}" managed="${controller.observedLocationPresets.foundPcloud}"/>
 			<HBox spacing="12" alignment="CENTER_LEFT">
 				<RadioButton fx:id="customRadioButton" toggleGroup="${predefinedLocationToggler}" text="%addvaultwizard.new.directoryPickerLabel"/>
 				<Button contentDisplay="LEFT" text="%addvaultwizard.new.directoryPickerButton" onAction="#chooseCustomVaultPath" disable="${controller.usePresetPath}">