From 1f3afa3ad445ade79421bf03a1aef3e226ba388b Mon Sep 17 00:00:00 2001 From: crschnick Date: Thu, 19 Oct 2023 16:52:35 +0000 Subject: [PATCH] Small bugfixes and refactor --- .../app/browser/BrowserBookmarkList.java | 11 +-- .../app/browser/OpenFileSystemModel.java | 5 +- .../io/xpipe/app/comp/base/OsLogoComp.java | 2 +- .../xpipe/app/comp/base/SideMenuBarComp.java | 34 ++++++--- .../xpipe/app/comp/base/StoreToggleComp.java | 2 +- .../xpipe/app/comp/base/SystemStateComp.java | 2 +- .../store/DenseStoreEntryComp.java | 2 +- .../app/comp/store/GuiDsStoreCreator.java | 74 +++++++++---------- .../store/StandardStoreEntryComp.java | 2 +- .../store/StoreCategoryWrapper.java | 5 +- .../store/StoreCreationMenu.java | 2 +- .../{storage => }/store/StoreEntryComp.java | 4 +- .../store/StoreEntryListComp.java | 2 +- .../store/StoreEntryListStatusComp.java | 2 +- .../store/StoreEntryWrapper.java | 2 +- .../{storage => }/store/StoreIntroComp.java | 2 +- .../{storage => }/store/StoreLayoutComp.java | 2 +- .../store/StoreNotFoundComp.java | 2 +- .../{storage => }/store/StoreSection.java | 2 +- .../{storage => }/store/StoreSectionComp.java | 2 +- .../store/StoreSectionMiniComp.java | 2 +- .../{storage => }/store/StoreSidebarComp.java | 2 +- .../{storage => }/store/StoreSortComp.java | 2 +- .../{storage => }/store/StoreSortMode.java | 2 +- .../{storage => }/store/StoreViewState.java | 9 ++- .../io/xpipe/app/core/AppLayoutModel.java | 2 +- .../main/java/io/xpipe/app/core/AppTheme.java | 51 +++++++------ .../java/io/xpipe/app/core/mode/BaseMode.java | 2 +- .../io/xpipe/app/core/mode/PlatformMode.java | 2 +- .../io/xpipe/app/ext/DataStoreProvider.java | 12 +-- .../app/fxcomps/impl/DataStoreChoiceComp.java | 4 +- .../fxcomps/impl/DataStoreListChoiceComp.java | 2 +- .../app/fxcomps/impl/StoreCategoryComp.java | 4 +- .../fxcomps/impl/StoreCategoryListComp.java | 2 +- .../io/xpipe/app/storage/DataStorage.java | 50 ++++++++++--- .../xpipe/app/storage/DataStoreCategory.java | 2 +- .../io/xpipe/app/storage/StandardStorage.java | 2 +- .../app/util/DataStoreCategoryChoiceComp.java | 11 ++- .../io/xpipe/app/util/DataStoreFormatter.java | 2 +- .../java/io/xpipe/app/util/ScanAlert.java | 2 +- app/src/main/java/module-info.java | 1 - .../os/{opensuse-color.svg => suse-color.svg} | 0 .../xpipe/app/resources/style/header-bars.css | 6 +- dist/changelogs/1.7.0.md | 12 ++- .../xpipe/ext/base/action/XPipeUrlAction.java | 4 +- .../base/script/ScriptGroupStoreProvider.java | 17 +++-- .../io/xpipe/ext/base/script/ScriptStore.java | 10 ++- .../ext/base/script/SimpleScriptStore.java | 2 +- .../script/SimpleScriptStoreProvider.java | 8 +- .../base/resources/scripts/starship_bash.sh | 2 +- .../base/resources/scripts/starship_fish.fish | 2 +- .../base/resources/scripts/starship_zsh.sh | 2 +- 52 files changed, 227 insertions(+), 167 deletions(-) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/DenseStoreEntryComp.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StandardStoreEntryComp.java (97%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreCategoryWrapper.java (97%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreCreationMenu.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreEntryComp.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreEntryListComp.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreEntryListStatusComp.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreEntryWrapper.java (99%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreIntroComp.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreLayoutComp.java (96%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreNotFoundComp.java (86%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSection.java (99%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSectionComp.java (99%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSectionMiniComp.java (99%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSidebarComp.java (95%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSortComp.java (99%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreSortMode.java (98%) rename app/src/main/java/io/xpipe/app/comp/{storage => }/store/StoreViewState.java (97%) rename app/src/main/resources/io/xpipe/app/resources/img/os/{opensuse-color.svg => suse-color.svg} (100%) diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java b/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java index c8af09b04..0188dfe58 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java @@ -1,15 +1,16 @@ package io.xpipe.app.browser; import atlantafx.base.theme.Styles; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; -import io.xpipe.app.comp.storage.store.StoreSection; -import io.xpipe.app.comp.storage.store.StoreSectionMiniComp; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreSectionMiniComp; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppFont; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.FilterComp; import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.DataStoreCategoryChoiceComp; import io.xpipe.app.util.FixedHierarchyStore; @@ -91,7 +92,7 @@ final class BrowserBookmarkList extends SimpleComp { }); }); }); - var category = new DataStoreCategoryChoiceComp(StoreViewState.get().getActiveCategory()) + var category = new DataStoreCategoryChoiceComp(DataStorage.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory()) .styleClass(Styles.LEFT_PILL) .grow(false, true); var filter = diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java index b8a0a3363..a146a395b 100644 --- a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemModel.java @@ -392,8 +392,11 @@ public final class OpenFileSystemModel { if (entry.getStore() instanceof ShellStore s) { var connection = ((ConnectionFileSystem) fileSystem).getShellControl(); var name = directory + " - " + entry.get().getName(); - var toOpen = ProcessControlProvider.get().withDefaultScripts(s.control()); + var toOpen = ProcessControlProvider.get().withDefaultScripts(connection); TerminalHelper.open(entry.getEntry(), name, toOpen.initWith(connection.getShellDialect().getCdCommand(directory))); + + // Restart connection as we will have to start it anyway, so we speed it up by doing it preemptively + connection.start(); } }); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java b/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java index 0c8e5e37f..9dba52d1a 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/OsLogoComp.java @@ -1,6 +1,6 @@ package io.xpipe.app.comp.base; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.core.AppResources; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; diff --git a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java index 7d1a6f62c..7715b9ddc 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/SideMenuBarComp.java @@ -54,6 +54,23 @@ public class SideMenuBarComp extends Comp> { vbox.getChildren().add(b.createRegion()); }); + { + var b = new IconButtonComp( + "mdal-bug_report", + () -> { + var event = ErrorEvent.fromMessage("User Report"); + if (AppLogs.get().isWriteToFile()) { + event.attachment(AppLogs.get().getSessionLogsDirectory()); + } + UserReportComp.show(event.build()); + }) + .apply(new FancyTooltipAugment<>("reportIssue")); + b.apply(struc -> { + AppFont.setSize(struc.get(), 2); + }); + vbox.getChildren().add(b.createRegion()); + } + { var b = new IconButtonComp("mdi2g-github", () -> Hyperlinks.open(Hyperlinks.GITHUB)) .apply(new FancyTooltipAugment<>("visitGithubRepository")); @@ -64,25 +81,18 @@ public class SideMenuBarComp extends Comp> { } { - var b = new IconButtonComp( - "mdal-bug_report", - () -> { - var event = ErrorEvent.fromMessage("User Report"); - if (AppLogs.get().isWriteToFile()) { - event.attachment(AppLogs.get().getSessionLogsDirectory()); - } - UserReportComp.show(event.build()); - }) - .apply(new FancyTooltipAugment<>("reportIssue")); + var b = new IconButtonComp("mdi2c-comment-processing-outline", () -> Hyperlinks.open(Hyperlinks.ROADMAP)) + .apply(new FancyTooltipAugment<>("roadmap")); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); vbox.getChildren().add(b.createRegion()); } + { - var b = new IconButtonComp("mdi2c-comment-processing-outline", () -> Hyperlinks.open(Hyperlinks.ROADMAP)) - .apply(new FancyTooltipAugment<>("roadmap")); + var b = new IconButtonComp("mdi2d-discord", () -> Hyperlinks.open(Hyperlinks.DISCORD)) + .apply(new FancyTooltipAugment<>("discord")); b.apply(struc -> { AppFont.setSize(struc.get(), 2); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java index 87cfa45fb..b29d2fa53 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java @@ -1,6 +1,6 @@ package io.xpipe.app.comp.base; -import io.xpipe.app.comp.storage.store.StoreSection; +import io.xpipe.app.comp.store.StoreSection; import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.BindingsHelper; diff --git a/app/src/main/java/io/xpipe/app/comp/base/SystemStateComp.java b/app/src/main/java/io/xpipe/app/comp/base/SystemStateComp.java index 0a44d13f1..87289a72d 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/SystemStateComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/SystemStateComp.java @@ -1,7 +1,7 @@ package io.xpipe.app.comp.base; import atlantafx.base.theme.Styles; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.PlatformThread; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/DenseStoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/DenseStoreEntryComp.java rename to app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java index c3e4f473e..a52fc5594 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/DenseStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/DenseStoreEntryComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.core.AppFont; import io.xpipe.app.fxcomps.Comp; diff --git a/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java b/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java index 46e111793..e216110ce 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java +++ b/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java @@ -25,6 +25,7 @@ import io.xpipe.core.store.DataStore; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.*; +import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.scene.control.Alert; import javafx.scene.control.ScrollPane; @@ -52,9 +53,10 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { Property validator = new SimpleObjectProperty<>(new SimpleValidator()); Property messageProp = new SimpleStringProperty(); BooleanProperty finished = new SimpleBooleanProperty(); - Property entry = new SimpleObjectProperty<>(); + ObservableValue entry; BooleanProperty changedSinceError = new SimpleBooleanProperty(); StringProperty name; + DataStoreEntry existingEntry; boolean exists; boolean staticDisplay; @@ -64,13 +66,14 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { Property store, Predicate filter, String initialName, - boolean exists, + DataStoreEntry existingEntry, boolean exists, boolean staticDisplay) { this.parent = parent; this.provider = provider; this.store = store; this.filter = filter; this.name = new SimpleStringProperty(initialName != null && !initialName.isEmpty() ? initialName : null); + this.existingEntry = existingEntry; this.exists = exists; this.staticDisplay = staticDisplay; this.store.addListener((c, o, n) -> { @@ -98,6 +101,27 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { newValue.validate(); }); }); + this.entry = Bindings.createObjectBinding(() -> { + if (name.getValue() == null || store.getValue() == null) { + return null; + } + + var testE = DataStoreEntry.createNew( + UUID.randomUUID(), + DataStorage.get().getSelectedCategory().getUuid(), + name.getValue(), + store.getValue()); + var p = provider.getValue().getDisplayParent(testE); + return DataStoreEntry.createNew( + UUID.randomUUID(), + p != null + ? p.getCategoryUuid() + : DataStorage.get() + .getSelectedCategory() + .getUuid(), + name.getValue(), + store.getValue()); + }, name, store); } public static void showEdit(DataStoreEntry e) { @@ -116,7 +140,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { }); }, true, - true); + true, + e); } public static void showCreation(DataStoreProvider selected, Predicate filter) { @@ -136,17 +161,19 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { } }, false, - false); + false, + null); } - public static void show( + private static void show( String initialName, DataStoreProvider provider, DataStore s, Predicate filter, Consumer con, boolean exists, - boolean staticDisplay) { + boolean staticDisplay, + DataStoreEntry existingEntry) { var prop = new SimpleObjectProperty<>(provider); var store = new SimpleObjectProperty<>(s); var loading = new SimpleBooleanProperty(); @@ -158,7 +185,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { return new MultiStepComp() { private final GuiDsStoreCreator creator = new GuiDsStoreCreator( - this, prop, store, filter, initialName, exists, staticDisplay); + this, prop, store, filter, initialName, existingEntry, exists, staticDisplay); @Override protected List setup() { @@ -223,29 +250,6 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { .description("connectionNameDescription") .addString(name, false) .nonNull(propVal) - .bind( - () -> { - if (name.getValue() == null || store.getValue() == null) { - return null; - } - - var testE = DataStoreEntry.createNew( - UUID.randomUUID(), - DataStorage.get().getSelectedCategory().getUuid(), - name.getValue(), - store.getValue()); - var parent = provider.getValue().getDisplayParent(testE); - return DataStoreEntry.createNew( - UUID.randomUUID(), - parent != null - ? parent.getCategoryUuid() - : DataStorage.get() - .getSelectedCategory() - .getUuid(), - name.getValue(), - store.getValue()); - }, - entry) .build(); } @@ -268,15 +272,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { SimpleChangeListener.apply(provider, n -> { if (n != null) { - // var install = n.getRequiredAdditionalInstallation(); - // if (install != null && AppExtensionManager.getInstance().isInstalled(install)) { - // layout.setCenter(new InstallExtensionComp((DownloadModuleInstall) - // install).createRegion()); - // validator.setValue(new SimpleValidator()); - // return; - // } - - var d = n.guiDialog(entry.getValue(), store); + var d = n.guiDialog(existingEntry, store); var propVal = new SimpleValidator(); var propR = createStoreProperties(d == null || d.getComp() == null ? null : d.getComp(), propVal); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StandardStoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java similarity index 97% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StandardStoreEntryComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java index 7b4d63183..2d256b508 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StandardStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StandardStoreEntryComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.Comp; import javafx.geometry.HPos; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java similarity index 97% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreCategoryWrapper.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java index 16d88f8f5..4674ac157 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java @@ -1,10 +1,9 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; -import javafx.application.Platform; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; @@ -67,7 +66,7 @@ public class StoreCategoryWrapper { } public void select() { - Platform.runLater(() -> { + PlatformThread.runLaterIfNeeded(() -> { StoreViewState.get().getActiveCategory().setValue(this); }); } diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationMenu.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationMenu.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java index 7c30a54e9..2924140fb 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreCreationMenu.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationMenu.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.store.GuiDsStoreCreator; import io.xpipe.app.core.AppI18n; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index ef517f03d..2386bc863 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import atlantafx.base.theme.Styles; import io.xpipe.app.comp.base.LoadingOverlayComp; @@ -345,7 +345,7 @@ public abstract class StoreEntryComp extends SimpleComp { if (wrapper.getEntry().getProvider() != null && wrapper.getEntry().getProvider().canMoveCategories()) { var move = new Menu(AppI18n.get("moveTo"), new FontIcon("mdi2f-folder-move-outline")); - StoreViewState.get().getSortedCategories().forEach(storeCategoryWrapper -> { + StoreViewState.get().getSortedCategories(DataStorage.get().getRootCategory(DataStorage.get().getStoreCategoryIfPresent(wrapper.getEntry().getCategoryUuid()).orElseThrow())).forEach(storeCategoryWrapper -> { MenuItem m = new MenuItem(storeCategoryWrapper.getName()); m.setOnAction(event -> { wrapper.moveTo(storeCategoryWrapper.getCategory()); diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java index db1349e85..a54335b71 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.MultiContentComp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListStatusComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index ef3f0fdc7..778183524 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.core.AppFont; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java similarity index 99% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index 3fec04c3a..a4b01d62a 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.store.GuiDsStoreCreator; import io.xpipe.app.ext.ActionProvider; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreIntroComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreIntroComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java index 728a549be..52b1ac2b0 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreIntroComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreIntroComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java similarity index 96% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java index 49f9c75bc..b14cef275 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.app.fxcomps.SimpleComp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreNotFoundComp.java similarity index 86% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreNotFoundComp.java index 34838ac5c..40bf45b5b 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreNotFoundComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreNotFoundComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.SimpleComp; import javafx.scene.layout.Region; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSection.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java similarity index 99% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSection.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSection.java index 06b7557db..5811144cd 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSection.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.util.BindingsHelper; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java similarity index 99% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java index 019842b5e..cd53e204e 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.fxcomps.Comp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionMiniComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java similarity index 99% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionMiniComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java index 5889fe0d7..464048e20 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSectionMiniComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ListBoxViewComp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java similarity index 95% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java index 3982d87fa..61e5cb984 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSidebarComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSidebarComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java similarity index 99% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortComp.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java index 56a63ae5b..6dee0ed7f 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSortComp.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortMode.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSortMode.java similarity index 98% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortMode.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreSortMode.java index e19d2903d..4c43d2b3f 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreSortMode.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSortMode.java @@ -1,4 +1,4 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.storage.DataStoreEntry; diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java similarity index 97% rename from app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java rename to app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java index 10e749ab3..a3fd031b1 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java @@ -1,6 +1,7 @@ -package io.xpipe.app.comp.storage.store; +package io.xpipe.app.comp.store; import io.xpipe.app.core.AppCache; +import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreCategory; @@ -47,14 +48,14 @@ public class StoreViewState { tl = StoreSection.createTopLevel(allEntries, storeEntryWrapper -> true, filter, activeCategory); } catch (Exception exception) { tl = new StoreSection(null, FXCollections.emptyObservableList(), FXCollections.emptyObservableList(), 0); - categories.setAll(new StoreCategoryWrapper(DataStorage.get().getAllCategory())); + categories.setAll(new StoreCategoryWrapper(DataStorage.get().getAllConnectionsCategory())); activeCategory.setValue(getAllConnectionsCategory()); ErrorEvent.fromThrowable(exception).handle(); } currentTopLevelSection = tl; } - public ObservableList getSortedCategories() { + public ObservableList getSortedCategories(DataStoreCategory root) { Comparator comparator = new Comparator<>() { @Override public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) { @@ -89,7 +90,7 @@ public class StoreViewState { return o1.getName().compareToIgnoreCase(o2.getName()); } }; - return categories.sorted(comparator); + return BindingsHelper.filteredContentBinding(categories, cat-> root == null || cat.getRoot().equals(root)).sorted(comparator); } public StoreCategoryWrapper getAllConnectionsCategory() { diff --git a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java index 09f08ddda..2b69c9af1 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java +++ b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java @@ -3,7 +3,7 @@ package io.xpipe.app.core; import io.xpipe.app.browser.BrowserComp; import io.xpipe.app.browser.BrowserModel; import io.xpipe.app.comp.DeveloperTabComp; -import io.xpipe.app.comp.storage.store.StoreLayoutComp; +import io.xpipe.app.comp.store.StoreLayoutComp; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.prefs.PrefsComp; import io.xpipe.app.util.LicenseProvider; diff --git a/app/src/main/java/io/xpipe/app/core/AppTheme.java b/app/src/main/java/io/xpipe/app/core/AppTheme.java index bcac047a6..ba5f094ef 100644 --- a/app/src/main/java/io/xpipe/app/core/AppTheme.java +++ b/app/src/main/java/io/xpipe/app/core/AppTheme.java @@ -14,6 +14,7 @@ import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.application.Application; +import javafx.application.Platform; import javafx.css.PseudoClass; import javafx.scene.image.Image; import javafx.scene.image.ImageView; @@ -41,7 +42,8 @@ public class AppTheme { } SimpleChangeListener.apply(AppPrefs.get().theme, t -> { - Theme.ALL.forEach(theme -> stage.getScene().getRoot().getStyleClass().remove(theme.getCssId())); + Theme.ALL.forEach( + theme -> stage.getScene().getRoot().getStyleClass().remove(theme.getCssId())); if (t == null) { return; } @@ -51,7 +53,7 @@ public class AppTheme { stage.getScene().getRoot().pseudoClassStateChanged(DARK, t.isDark()); }); - SimpleChangeListener.apply(AppPrefs.get().performanceMode(),val -> { + SimpleChangeListener.apply(AppPrefs.get().performanceMode(), val -> { stage.getScene().getRoot().pseudoClassStateChanged(PRETTY, !val); stage.getScene().getRoot().pseudoClassStateChanged(PERFORMANCE, val); }); @@ -111,29 +113,30 @@ public class AppTheme { } PlatformThread.runLaterIfNeeded(() -> { - for (Window window : Window.getWindows()) { - var scene = window.getScene(); - Image snapshot = scene.snapshot(null); - Pane root = (Pane) scene.getRoot(); + var window = AppMainWindow.getInstance().getStage(); + var scene = window.getScene(); + Pane root = (Pane) scene.getRoot(); + Image snapshot = scene.snapshot(null); + ImageView imageView = new ImageView(snapshot); + root.getChildren().add(imageView); - ImageView imageView = new ImageView(snapshot); - root.getChildren().add(imageView); + newTheme.apply(); + TrackEvent.debug("Set theme " + newTheme.getId() + " for scene"); + Platform.runLater(() -> { // Animate! var transition = new Timeline( new KeyFrame( - Duration.ZERO, new KeyValue(imageView.opacityProperty(), 1, Interpolator.EASE_OUT)), + Duration.millis(0), + new KeyValue(imageView.opacityProperty(), 1, Interpolator.EASE_OUT)), new KeyFrame( - Duration.millis(1250), + Duration.millis(600), new KeyValue(imageView.opacityProperty(), 0, Interpolator.EASE_OUT))); transition.setOnFinished(e -> { root.getChildren().remove(imageView); }); transition.play(); - } - - newTheme.apply(); - TrackEvent.debug("Set theme " + newTheme.getId() + " for scene"); + }); }); } @@ -150,14 +153,18 @@ public class AppTheme { @SneakyThrows public void apply() { var builder = new StringBuilder(); - AppResources.with(AppResources.XPIPE_MODULE, "theme/" + id + ".css", path->{ + AppResources.with(AppResources.XPIPE_MODULE, "theme/" + id + ".css", path -> { var content = Files.readString(path); builder.append(content); }); - AppResources.with("atlantafx.base", theme.getUserAgentStylesheet(), path->{ + AppResources.with("atlantafx.base", theme.getUserAgentStylesheet(), path -> { var baseStyleContent = Files.readString(path); - builder.append("\n").append(baseStyleContent.lines().skip(builder.toString().lines().count()).collect(Collectors.joining("\n"))); + builder.append("\n") + .append(baseStyleContent + .lines() + .skip(builder.toString().lines().count()) + .collect(Collectors.joining("\n"))); }); var out = Files.createTempFile(id, ".css"); @@ -166,7 +173,6 @@ public class AppTheme { Application.setUserAgentStylesheet(out.toUri().toString()); } - @Override public String toTranslatedString() { return name; @@ -188,7 +194,8 @@ public class AppTheme { public static final Theme CUSTOM = new DerivedTheme("custom", "primer", "Custom", new PrimerDark()); // Also include your custom theme here - public static final List ALL = List.of(PRIMER_LIGHT, PRIMER_DARK, NORD_LIGHT, NORD_DARK, CUPERTINO_LIGHT, CUPERTINO_DARK, DRACULA); + public static final List ALL = + List.of(PRIMER_LIGHT, PRIMER_DARK, NORD_LIGHT, NORD_DARK, CUPERTINO_LIGHT, CUPERTINO_DARK, DRACULA); static Theme getDefaultLightTheme() { return switch (OsType.getLocal()) { @@ -207,14 +214,16 @@ public class AppTheme { } protected final String id; + @Getter protected final String cssId; + protected final atlantafx.base.theme.Theme theme; - + public boolean isDark() { return theme.isDarkMode(); } - + public void apply() { Application.setUserAgentStylesheet(theme.getUserAgentStylesheet()); } diff --git a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java index 228cbbeda..21c9d84f6 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/BaseMode.java @@ -1,7 +1,7 @@ package io.xpipe.app.core.mode; import io.xpipe.app.browser.BrowserModel; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.*; import io.xpipe.app.issue.*; import io.xpipe.app.prefs.AppPrefs; diff --git a/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java b/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java index bad75aa50..387bd6550 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/PlatformMode.java @@ -1,6 +1,6 @@ package io.xpipe.app.core.mode; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.*; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 5afc352c7..0c9dbfe4d 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -1,10 +1,10 @@ package io.xpipe.app.ext; import io.xpipe.app.comp.base.MarkdownComp; -import io.xpipe.app.comp.storage.store.StoreEntryComp; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; -import io.xpipe.app.comp.storage.store.StoreSection; -import io.xpipe.app.comp.storage.store.StoreSectionComp; +import io.xpipe.app.comp.store.StoreEntryComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreSectionComp; import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppImages; import io.xpipe.app.fxcomps.Comp; @@ -105,10 +105,6 @@ public interface DataStoreProvider { return null; } - default DataStoreEntry getLogicalParent(DataStoreEntry store) { - return getDisplayParent(store); - } - default GuiDialog guiDialog(DataStoreEntry entry, Property store) { return null; } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java index a628ada97..47ab2db08 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreChoiceComp.java @@ -3,7 +3,7 @@ package io.xpipe.app.fxcomps.impl; import atlantafx.base.controls.Popover; import atlantafx.base.theme.Styles; import io.xpipe.app.comp.base.ButtonComp; -import io.xpipe.app.comp.storage.store.*; +import io.xpipe.app.comp.store.*; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; import io.xpipe.app.ext.DataStoreProviders; @@ -106,7 +106,7 @@ public class DataStoreChoiceComp extends SimpleComp { comp.disable(new SimpleBooleanProperty(true)); } }); - var category = new DataStoreCategoryChoiceComp(selectedCategory).styleClass(Styles.LEFT_PILL); + var category = new DataStoreCategoryChoiceComp(initialCategory != null ? initialCategory.getRoot() : null, selectedCategory).styleClass(Styles.LEFT_PILL); var filter = new FilterComp(filterText) .styleClass(Styles.CENTER_PILL) .hgrow() diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreListChoiceComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreListChoiceComp.java index c5d72c508..946165b61 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreListChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/DataStoreListChoiceComp.java @@ -1,7 +1,7 @@ package io.xpipe.app.fxcomps.impl; import io.xpipe.app.comp.base.ListBoxViewComp; -import io.xpipe.app.comp.storage.store.StoreCategoryWrapper; +import io.xpipe.app.comp.store.StoreCategoryWrapper; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.storage.DataStoreEntryRef; diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java index 0819aef1e..72d2ac204 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryComp.java @@ -3,8 +3,8 @@ package io.xpipe.app.fxcomps.impl; import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.comp.base.LazyTextFieldComp; import io.xpipe.app.comp.base.ListBoxViewComp; -import io.xpipe.app.comp.storage.store.StoreCategoryWrapper; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreCategoryWrapper; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.Comp; diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryListComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryListComp.java index 996732616..7d3caec7b 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryListComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/StoreCategoryListComp.java @@ -1,6 +1,6 @@ package io.xpipe.app.fxcomps.impl; -import io.xpipe.app.comp.storage.store.StoreCategoryWrapper; +import io.xpipe.app.comp.store.StoreCategoryWrapper; import io.xpipe.app.fxcomps.SimpleComp; import javafx.scene.layout.Region; diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index a178ce874..5c378cad1 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -37,8 +37,10 @@ public abstract class DataStorage { private static DataStorage INSTANCE; protected final Path dir; + @Getter protected final List storeCategories; + @Getter protected final Set storeEntries; @@ -59,10 +61,14 @@ public abstract class DataStorage { return getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID).orElseThrow(); } - public DataStoreCategory getAllCategory() { + public DataStoreCategory getAllConnectionsCategory() { return getStoreCategoryIfPresent(ALL_CONNECTIONS_CATEGORY_UUID).orElseThrow(); } + public DataStoreCategory getAllScriptsCategory() { + return getStoreCategoryIfPresent(ALL_SCRIPTS_CATEGORY_UUID).orElseThrow(); + } + private static boolean shouldPersist() { if (System.getProperty(PERSIST_PROP) != null) { return Boolean.parseBoolean(System.getProperty(PERSIST_PROP)); @@ -195,7 +201,7 @@ public abstract class DataStorage { } var oldChildren = getStoreEntries().stream() - .filter(other -> e.equals(other.getProvider().getLogicalParent(other))) + .filter(other -> e.equals(other.getProvider().getDisplayParent(other))) .toList(); var toRemove = oldChildren.stream() .filter(entry -> newChildren.stream() @@ -258,7 +264,6 @@ public abstract class DataStorage { saveAsync(); } - public DataStoreCategory addStoreCategoryIfNotPresent(@NonNull DataStoreCategory cat) { if (storeCategories.contains(cat)) { return cat; @@ -388,7 +393,23 @@ public abstract class DataStorage { .getDisplayParent(entry) .map(p -> !p.getCategoryUuid().equals(entry.getCategoryUuid())) .orElse(false); - return noParent || diffParentCategory; + var loop = isParentLoop(entry); + return noParent || diffParentCategory || loop; + } + + private boolean isParentLoop(DataStoreEntry entry) { + var es = new HashSet(); + + DataStoreEntry current = entry; + while ((current = getDisplayParent(current).orElse(null)) != null) { + if (es.contains(current)) { + return true; + } + + es.add(current); + } + + return false; } public DataStoreEntry getRootForEntry(DataStoreEntry entry) { @@ -469,7 +490,7 @@ public abstract class DataStorage { } var parent = getDisplayParent(other); - return parent.isPresent() && parent.get().equals(entry); + return parent.isPresent() && parent.get().equals(entry) && !isParentLoop(entry); }) .collect(Collectors.toSet()); entry.setChildrenCache(children); @@ -483,20 +504,26 @@ public abstract class DataStorage { .toList()); } - public DataStoreId getId(DataStoreEntry entry) { - var names = new ArrayList(); - names.add(entry.getName().replaceAll(":", "_")); + private List getHierarchy(DataStoreEntry entry) { + var es = new ArrayList(); DataStoreEntry current = entry; while ((current = getDisplayParent(current).orElse(null)) != null) { - if (new LocalStore().equals(current.getStore())) { + if (es.contains(current)) { break; } - names.add(0, current.getName().replaceAll(":", "_")); + es.add(0, current); } - return DataStoreId.create(names.toArray(String[]::new)); + return es; + } + + public DataStoreId getId(DataStoreEntry entry) { + return DataStoreId.create(getHierarchy(entry).stream() + .filter(e -> !(e.getStore() instanceof LocalStore)) + .map(e -> e.getName().replaceAll(":", "_")) + .toArray(String[]::new)); } public Optional getStoreEntryIfPresent(@NonNull DataStoreId id) { @@ -602,5 +629,4 @@ public abstract class DataStorage { public DataStoreEntry local() { return getStoreEntryIfPresent(LOCAL_ID).orElse(null); } - } diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreCategory.java b/app/src/main/java/io/xpipe/app/storage/DataStoreCategory.java index 41a5703c5..df4ae1103 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreCategory.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreCategory.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.xpipe.app.comp.storage.store.StoreSortMode; +import io.xpipe.app.comp.store.StoreSortMode; import io.xpipe.core.util.JacksonMapper; import lombok.EqualsAndHashCode; import lombok.NonNull; diff --git a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java index b9efe6017..db928d42d 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -1,6 +1,6 @@ package io.xpipe.app.storage; -import io.xpipe.app.comp.storage.store.StoreSortMode; +import io.xpipe.app.comp.store.StoreSortMode; import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.prefs.AppPrefs; diff --git a/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java b/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java index 02d94cad6..7f08100cd 100644 --- a/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java @@ -1,9 +1,10 @@ package io.xpipe.app.util; -import io.xpipe.app.comp.storage.store.StoreCategoryWrapper; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreCategoryWrapper; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.PlatformThread; +import io.xpipe.app.storage.DataStoreCategory; import javafx.beans.property.Property; import javafx.geometry.Insets; import javafx.scene.control.ComboBox; @@ -14,15 +15,17 @@ import lombok.Value; public class DataStoreCategoryChoiceComp extends SimpleComp { + private final DataStoreCategory root; private final Property selected; - public DataStoreCategoryChoiceComp(Property selected) { + public DataStoreCategoryChoiceComp(DataStoreCategory root, Property selected) { + this.root = root; this.selected = selected; } @Override protected Region createSimple() { - var box = new ComboBox<>(StoreViewState.get().getSortedCategories()); + var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root)); box.setValue(selected.getValue()); box.valueProperty().addListener((observable, oldValue, newValue) -> { selected.setValue(newValue); diff --git a/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java index dc1d7c01c..2ae948012 100644 --- a/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java +++ b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java @@ -1,6 +1,6 @@ package io.xpipe.app.util; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; diff --git a/app/src/main/java/io/xpipe/app/util/ScanAlert.java b/app/src/main/java/io/xpipe/app/util/ScanAlert.java index 8482b52f8..6c4c414ee 100644 --- a/app/src/main/java/io/xpipe/app/util/ScanAlert.java +++ b/app/src/main/java/io/xpipe/app/util/ScanAlert.java @@ -2,7 +2,7 @@ package io.xpipe.app.util; import io.xpipe.app.comp.base.ListSelectorComp; import io.xpipe.app.comp.base.MultiStepComp; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.ext.ScanProvider; diff --git a/app/src/main/java/module-info.java b/app/src/main/java/module-info.java index b80623bb4..992ffc05c 100644 --- a/app/src/main/java/module-info.java +++ b/app/src/main/java/module-info.java @@ -37,7 +37,6 @@ open module io.xpipe.app { exports io.xpipe.app.browser.action; exports io.xpipe.app.browser; exports io.xpipe.app.browser.icon; - exports io.xpipe.app.comp.storage.store; requires com.sun.jna; requires com.sun.jna.platform; diff --git a/app/src/main/resources/io/xpipe/app/resources/img/os/opensuse-color.svg b/app/src/main/resources/io/xpipe/app/resources/img/os/suse-color.svg similarity index 100% rename from app/src/main/resources/io/xpipe/app/resources/img/os/opensuse-color.svg rename to app/src/main/resources/io/xpipe/app/resources/img/os/suse-color.svg diff --git a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css index e3af39a42..fdaeac523 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/header-bars.css @@ -30,9 +30,9 @@ .store-header-bar .menu-button { -fx-background-radius: 4px; - -fx-border-width: 0.05em; --fx-border-radius: 4px; --fx-padding: -1px; + -fx-border-radius: 4px; + -fx-border-width: 1px; +-fx-padding: 0; -fx-background-color: -color-fg-default; -fx-border-color: -color-bg-default; } diff --git a/dist/changelogs/1.7.0.md b/dist/changelogs/1.7.0.md index f76c4695c..c8c8fbe69 100644 --- a/dist/changelogs/1.7.0.md +++ b/dist/changelogs/1.7.0.md @@ -1,7 +1,7 @@ -## Update procedure +# Update procedure -Note that the automatic updater is broken in version 1.6.0. It will freeze the application and not perform the update. -So you have to install it manually from https://github.com/xpipe-io/xpipe/releases/tag/1.7.0. You can easily do this as uninstalling the old version does not delete any user data. +Note that the automatic updater is broken in version 1.6.0. It will freeze the application and not perform the update. **So do not try to click the install button**! +You have to install it manually from https://github.com/xpipe-io/xpipe/releases/tag/1.7.0. You can easily do this as uninstalling the old version does not delete any user data. ## Changes in 1.7.0 @@ -21,6 +21,11 @@ This merges the process of validating/refreshing with the process of establishin It also enables a custom display and instant updates of the information displayed for a connection. You will definitely notice this change when you connect to a system. +### Performance improvements + +The entire storage and UI handling of connections has been reworked to improve performance. +Especially if you're dealing with a large amount of connections, this will be noticeable. + ### Colors You can now assign colors to connections for organizational purposes to help in situations when many connections are opened in the file browser and terminals at the same time. @@ -28,6 +33,7 @@ These colors will be shown to identify tabs everywhere within XPipe and also out ### Other changes +- Codesign executables on Windows - Fix application not starting up or exiting properly sometimes - Add support for bsd-based systems - Fix OPNsense shells timing out diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java index 2e7a7e6c6..eb06ed0cb 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/XPipeUrlAction.java @@ -1,6 +1,6 @@ package io.xpipe.ext.base.action; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.comp.store.GuiDsStoreCreator; import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.storage.DataStorage; @@ -30,7 +30,7 @@ public class XPipeUrlAction implements ActionProvider { @Override public void execute() throws Exception { - actionProvider.getDataStoreCallSite().createAction(entry.getStore().asNeeded()).execute(); + actionProvider.getDataStoreCallSite().createAction(entry.ref()).execute(); } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java index a7cebba7a..b94650596 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java @@ -3,10 +3,10 @@ package io.xpipe.ext.base.script; import io.xpipe.app.comp.base.DropdownComp; import io.xpipe.app.comp.base.StoreToggleComp; import io.xpipe.app.comp.base.SystemStateComp; -import io.xpipe.app.comp.storage.store.DenseStoreEntryComp; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; -import io.xpipe.app.comp.storage.store.StoreSection; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.DenseStoreEntryComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.ext.GuiDialog; import io.xpipe.app.fxcomps.Comp; @@ -51,9 +51,8 @@ public class ScriptGroupStoreProvider implements DataStoreProvider { .description("scriptGroupDescription") .addComp( new DataStoreChoiceComp<>( - DataStoreChoiceComp.Mode.OTHER, null, group, ScriptGroupStore.class, ref->! ref.getEntry().equals(entry), StoreViewState.get().getAllScriptsCategory()), + DataStoreChoiceComp.Mode.OTHER, entry, group, ScriptGroupStore.class, null, StoreViewState.get().getAllScriptsCategory()), group) - .nonNull() .bind( () -> { return ScriptGroupStore.builder() @@ -65,6 +64,12 @@ public class ScriptGroupStoreProvider implements DataStoreProvider { .buildDialog(); } + @Override + public DataStoreEntry getDisplayParent(DataStoreEntry store) { + ScriptGroupStore scriptStore = store.getStore().asNeeded(); + return scriptStore.getParent() != null ? scriptStore.getParent().get() : null; + } + @Override public DataStore defaultStore() { return ScriptGroupStore.builder().build(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java index 668e03fd4..778cfd493 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStore.java @@ -29,7 +29,8 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, public static ShellControl controlWithScripts(ShellControl pc, List> refs) { pc.onInit(shellControl -> { - var scripts = flatten(refs).stream() + var flattened = flatten(refs); + var scripts = flattened.stream() .map(simpleScriptStore -> simpleScriptStore.prepareDumbScript(shellControl)) .filter(Objects::nonNull) .collect(Collectors.joining("\n")); @@ -37,7 +38,7 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, shellControl.executeSimpleBooleanCommand(scripts); } - var terminalCommands = flatten(refs).stream() + var terminalCommands = flattened.stream() .map(simpleScriptStore -> simpleScriptStore.prepareTerminalScript(shellControl)) .filter(Objects::nonNull) .collect(Collectors.joining("\n")); @@ -90,6 +91,11 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore, if (scripts != null) { Validators.contentNonNull(scripts); } + + // Prevent possible stack overflow +// for (DataStoreEntryRef s : getEffectiveScripts()) { +// s.checkComplete(); +// } } public LinkedHashSet getFlattenedScripts() { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java index cf686e090..ecb7ec403 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStore.java @@ -56,12 +56,12 @@ public class SimpleScriptStore extends ScriptStore { } public void queryFlattenedScripts(LinkedHashSet all) { + all.add(this); getEffectiveScripts().stream() .filter(scriptStoreDataStoreEntryRef -> !all.contains(scriptStoreDataStoreEntryRef.getStore())) .forEach(scriptStoreDataStoreEntryRef -> { scriptStoreDataStoreEntryRef.getStore().queryFlattenedScripts(all); }); - all.add(this); } @Getter diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index 8bab6629d..eff27cc7c 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -4,10 +4,10 @@ import io.xpipe.app.comp.base.DropdownComp; import io.xpipe.app.comp.base.IntegratedTextAreaComp; import io.xpipe.app.comp.base.StoreToggleComp; import io.xpipe.app.comp.base.SystemStateComp; -import io.xpipe.app.comp.storage.store.DenseStoreEntryComp; -import io.xpipe.app.comp.storage.store.StoreEntryWrapper; -import io.xpipe.app.comp.storage.store.StoreSection; -import io.xpipe.app.comp.storage.store.StoreViewState; +import io.xpipe.app.comp.store.DenseStoreEntryComp; +import io.xpipe.app.comp.store.StoreEntryWrapper; +import io.xpipe.app.comp.store.StoreSection; +import io.xpipe.app.comp.store.StoreViewState; import io.xpipe.app.core.AppExtensionManager; import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.ext.GuiDialog; diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_bash.sh b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_bash.sh index 48fcef7ee..a532316f9 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_bash.sh +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_bash.sh @@ -1,6 +1,6 @@ dir=~/.xpipe/scriptdata/starship export PATH="$PATH:$dir" -which starship > /dev/null +which starship > /dev/null 2>&1 if [ "$?" != 0 ]; then mkdir -p "$dir" && \ which curl > /dev/null && \ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_fish.fish b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_fish.fish index 166c093b1..201979284 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_fish.fish +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_fish.fish @@ -1,6 +1,6 @@ set dir ~/.xpipe/scriptdata/starship export PATH="$PATH:$dir" -which starship > /dev/null +which starship > /dev/null 2>&1 if [ $status != 0 ] mkdir -p "$dir" && \ which curl > /dev/null && \ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_zsh.sh b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_zsh.sh index 6f9120dd3..f69997ebe 100644 --- a/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_zsh.sh +++ b/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts/starship_zsh.sh @@ -1,6 +1,6 @@ dir=~/.xpipe/scriptdata/starship export PATH="$PATH:$dir" -which starship > /dev/null +which starship > /dev/null 2>&1 if [ "$?" != 0 ]; then mkdir -p "$dir" && \ which curl > /dev/null && \