mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-02 18:17:27 +13:00
Properly implement storage directory switching
This commit is contained in:
parent
4c08385098
commit
b2d685f523
7 changed files with 40 additions and 75 deletions
|
@ -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
|
||||
|
|
|
@ -56,7 +56,7 @@ automaticallyUpdateDescription=When enabled, new release information is automati
|
|||
sendAnonymousErrorReports=Send anonymous error reports
|
||||
sendUsageStatistics=Send anonymous usage statistics
|
||||
storageDirectory=Storage directory
|
||||
storageDirectoryDescription=The location where XPipe should store all connection and data source information.
|
||||
storageDirectoryDescription=The location where XPipe should store all connection information. This setting will only be applied at the next restart. When changing this, the data in the old directory is not copied to the new one.
|
||||
logLevel=Log level
|
||||
appBehaviour=Application behaviour
|
||||
logLevelDescription=The log level that should be used when writing log files.
|
||||
|
|
Loading…
Reference in a new issue