mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-06-22 06:19:02 -04:00
Properly implement storage directory switching
This commit is contained in:
@@ -205,24 +205,19 @@ public class AppPrefs {
|
||||
|
||||
private final BooleanProperty confirmDeletions = typed(new SimpleBooleanProperty(true), Boolean.class);
|
||||
|
||||
// External startup behaviour
|
||||
// ==========================
|
||||
private final ObjectProperty<Path> internalStorageDirectory =
|
||||
// Storage
|
||||
// =======
|
||||
private final ObjectProperty<Path> storageDirectory =
|
||||
typed(new SimpleObjectProperty<>(DEFAULT_STORAGE_DIR), Path.class);
|
||||
private final ObjectProperty<Path> effectiveStorageDirectory = STORAGE_DIR_FIXED
|
||||
? new SimpleObjectProperty<>(AppProperties.get().getDataDir().resolve("storage"))
|
||||
: internalStorageDirectory;
|
||||
private final StringField storageDirectoryControl = PrefFields.ofPath(effectiveStorageDirectory)
|
||||
.editable(!STORAGE_DIR_FIXED)
|
||||
private final StringField storageDirectoryControl = PrefFields.ofPath(storageDirectory)
|
||||
.validate(
|
||||
CustomValidators.absolutePath(),
|
||||
CustomValidators.directory(),
|
||||
CustomValidators.emptyStorageDirectory());
|
||||
private final ObjectProperty<String> internalLogLevel =
|
||||
typed(new SimpleObjectProperty<>(DEFAULT_LOG_LEVEL), String.class);
|
||||
CustomValidators.directory());
|
||||
|
||||
// Log level
|
||||
// =========
|
||||
private final ObjectProperty<String> internalLogLevel =
|
||||
typed(new SimpleObjectProperty<>(DEFAULT_LOG_LEVEL), String.class);
|
||||
private final ObjectProperty<String> effectiveLogLevel = LOG_LEVEL_FIXED
|
||||
? new SimpleObjectProperty<>(System.getProperty(LOG_LEVEL_PROP).toLowerCase())
|
||||
: internalLogLevel;
|
||||
@@ -230,6 +225,7 @@ public class AppPrefs {
|
||||
logLevelList, effectiveLogLevel)
|
||||
.editable(!LOG_LEVEL_FIXED)
|
||||
.render(() -> new SimpleComboBoxControl<>());
|
||||
|
||||
// Developer mode
|
||||
// ==============
|
||||
private final BooleanProperty internalDeveloperMode = typed(new SimpleBooleanProperty(false), Boolean.class);
|
||||
@@ -335,7 +331,7 @@ public class AppPrefs {
|
||||
}
|
||||
|
||||
public ObservableValue<Path> storageDirectory() {
|
||||
return effectiveStorageDirectory;
|
||||
return storageDirectory;
|
||||
}
|
||||
|
||||
public ReadOnlyProperty<String> logLevel() {
|
||||
@@ -535,9 +531,9 @@ public class AppPrefs {
|
||||
automaticallyCheckForUpdatesField,
|
||||
automaticallyCheckForUpdates),
|
||||
Setting.of("updateToPrereleases", checkForPrereleasesField, checkForPrereleases)),
|
||||
Group.of(
|
||||
group(
|
||||
"advanced",
|
||||
Setting.of("storageDirectory", storageDirectoryControl, internalStorageDirectory),
|
||||
STORAGE_DIR_FIXED ? null : Setting.of("storageDirectory", storageDirectoryControl, storageDirectory),
|
||||
Setting.of("logLevel", logLevelField, internalLogLevel),
|
||||
Setting.of("developerMode", developerModeField, internalDeveloperMode))),
|
||||
Category.of(
|
||||
@@ -602,6 +598,10 @@ public class AppPrefs {
|
||||
return AppPreferencesFx.of(cats);
|
||||
}
|
||||
|
||||
private Group group(String name, Setting<?,?>... settings) {
|
||||
return Group.of(name, Arrays.stream(settings).filter(setting -> setting != null).toArray(Setting[]::new));
|
||||
}
|
||||
|
||||
private class PrefsHandlerImpl implements PrefsHandler {
|
||||
|
||||
private final List<Category> categories;
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.xpipe.app.prefs;
|
||||
import com.dlsc.formsfx.model.validators.CustomValidator;
|
||||
import com.dlsc.formsfx.model.validators.Validator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@@ -30,25 +29,4 @@ public class CustomValidators {
|
||||
},
|
||||
"notADirectory");
|
||||
}
|
||||
|
||||
public static Validator<String> emptyStorageDirectory() {
|
||||
return CustomValidator.forPredicate(
|
||||
(String s) -> {
|
||||
var p = Path.of(s);
|
||||
if (AppPrefs.get() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (p.equals(AppPrefs.get().storageDirectory().getValue())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
return Files.list(p).findAny().isEmpty();
|
||||
} catch (IOException ignored) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
"notAnEmptyDirectory");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,34 +3,39 @@ package io.xpipe.app.prefs;
|
||||
import com.dlsc.formsfx.model.structure.StringField;
|
||||
import com.dlsc.preferencesfx.formsfx.view.controls.SimpleChooserControl;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PrefFields {
|
||||
|
||||
public static StringField ofPath(ObjectProperty<Path> fileProperty) {
|
||||
StringProperty stringProperty = new SimpleStringProperty();
|
||||
stringProperty.bindBidirectional(fileProperty, new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Path file) {
|
||||
if (Objects.isNull(file)) {
|
||||
return "";
|
||||
}
|
||||
return file.toString();
|
||||
}
|
||||
StringProperty stringProperty = new SimpleStringProperty(fileProperty.getValue().toString());
|
||||
|
||||
@Override
|
||||
public Path fromString(String value) {
|
||||
return Path.of(value);
|
||||
}
|
||||
// Prevent garbage collection of this due to how preferencesfx handles properties via bindings
|
||||
BindingsHelper.linkPersistently(fileProperty, stringProperty);
|
||||
|
||||
stringProperty.addListener((observable, oldValue, newValue) -> {
|
||||
fileProperty.setValue(newValue != null ? Path.of(newValue) : null);
|
||||
});
|
||||
|
||||
fileProperty.addListener((observable, oldValue, newValue) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
stringProperty.setValue(newValue != null ? newValue.toString() : "");
|
||||
});
|
||||
});
|
||||
|
||||
return StringField.ofStringType(stringProperty)
|
||||
.render(() -> new SimpleChooserControl(
|
||||
AppI18n.get("browse"), fileProperty.getValue().toFile(), true));
|
||||
.render(() -> {
|
||||
var c = new SimpleChooserControl(
|
||||
AppI18n.get("browse"), fileProperty.getValue().toFile(), true);
|
||||
c.setMinWidth(600);
|
||||
c.setPrefWidth(600);
|
||||
return c;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,10 +145,6 @@ public abstract class DataStorage {
|
||||
}
|
||||
}
|
||||
|
||||
protected Path getSourcesDir() {
|
||||
return dir.resolve("sources");
|
||||
}
|
||||
|
||||
protected Path getStoresDir() {
|
||||
return dir.resolve("stores");
|
||||
}
|
||||
|
||||
@@ -17,14 +17,10 @@ public class ImpersistentStorage extends DataStorage {
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
var sourcesDir = getSourcesDir();
|
||||
var storesDir = getStoresDir();
|
||||
|
||||
TrackEvent.info("Storage persistence is disabled. Deleting storage contents ...");
|
||||
try {
|
||||
if (Files.exists(sourcesDir)) {
|
||||
FileUtils.cleanDirectory(sourcesDir.toFile());
|
||||
}
|
||||
if (Files.exists(storesDir)) {
|
||||
FileUtils.cleanDirectory(storesDir.toFile());
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
private void deleteLeftovers() {
|
||||
var entriesDir = getSourcesDir().resolve("entries");
|
||||
var collectionsDir = getSourcesDir().resolve("collections");
|
||||
var storesDir = getStoresDir();
|
||||
|
||||
// Delete leftover directories in entries dir
|
||||
@@ -63,14 +61,10 @@ public class StandardStorage extends DataStorage {
|
||||
|
||||
public synchronized void load() {
|
||||
var newSession = isNewSession();
|
||||
var entriesDir = getSourcesDir().resolve("entries");
|
||||
var collectionsDir = getSourcesDir().resolve("collections");
|
||||
var storesDir = getStoresDir();
|
||||
var streamsDir = getStreamsDir();
|
||||
|
||||
try {
|
||||
FileUtils.forceMkdir(entriesDir.toFile());
|
||||
FileUtils.forceMkdir(collectionsDir.toFile());
|
||||
FileUtils.forceMkdir(storesDir.toFile());
|
||||
FileUtils.forceMkdir(streamsDir.toFile());
|
||||
} catch (Exception e) {
|
||||
@@ -120,14 +114,10 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
public synchronized void save() {
|
||||
var entriesDir = getSourcesDir().resolve("entries");
|
||||
var collectionsDir = getSourcesDir().resolve("collections");
|
||||
|
||||
try {
|
||||
FileUtils.forceMkdir(entriesDir.toFile());
|
||||
FileUtils.forceMkdir(collectionsDir.toFile());
|
||||
FileUtils.forceMkdir(getStoresDir().toFile());
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).terminal(true).build().handle();
|
||||
ErrorEvent.fromThrowable(e).description("Unable to create storage directory " + getStoresDir()).terminal(true).build().handle();
|
||||
}
|
||||
|
||||
// Save stores
|
||||
|
||||
Reference in New Issue
Block a user