From 1faff72321ac3d0e0b3d6a750f327190a13c9ce8 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 22 Oct 2023 14:10:08 +0000 Subject: [PATCH] Category choice comp fixes and storage dirty optimizations --- .../app/browser/BrowserBookmarkList.java | 12 ++--- .../app/comp/store/StoreCategoryWrapper.java | 5 +- .../xpipe/app/comp/store/StoreEntryComp.java | 2 +- .../comp/store/StoreEntryListStatusComp.java | 6 +-- .../app/comp/store/StoreEntryWrapper.java | 12 ++--- .../io/xpipe/app/comp/store/StoreSection.java | 2 +- .../xpipe/app/comp/store/StoreViewState.java | 15 ++++-- .../app/fxcomps/impl/DataStoreChoiceComp.java | 3 +- .../io/xpipe/app/storage/DataStoreEntry.java | 46 ++++++++----------- .../io/xpipe/app/storage/StandardStorage.java | 5 +- .../app/util/DataStoreCategoryChoiceComp.java | 35 ++++++++++---- .../io/xpipe/core/util/XPipeInstallation.java | 15 +++--- dist/changelogs/1.7.2.md | 12 ++++- .../base/script/ScriptGroupStoreProvider.java | 3 ++ .../ext/base/script/SimpleScriptStore.java | 1 + .../script/SimpleScriptStoreProvider.java | 4 ++ 16 files changed, 103 insertions(+), 75 deletions(-) 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 0188dfe5..40648e37 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserBookmarkList.java @@ -1,16 +1,12 @@ package io.xpipe.app.browser; import atlantafx.base.theme.Styles; -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.comp.store.*; 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; @@ -20,6 +16,7 @@ import io.xpipe.core.store.ShellStore; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.css.PseudoClass; import javafx.geometry.Point2D; @@ -55,9 +52,10 @@ final class BrowserBookmarkList extends SimpleComp { || storeEntryWrapper.getEntry().getStore() instanceof FixedHierarchyStore) && storeEntryWrapper.getEntry().getValidity().isUsable(); }; + var selectedCategory = new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue()); var section = StoreSectionMiniComp.createList( StoreSection.createTopLevel( - StoreViewState.get().getAllEntries(), applicable, filterText, StoreViewState.get().getActiveCategory()), + StoreViewState.get().getAllEntries(), applicable, filterText, selectedCategory), (s, comp) -> { BooleanProperty busy = new SimpleBooleanProperty(false); comp.disable(Bindings.createBooleanBinding(() -> { @@ -92,7 +90,7 @@ final class BrowserBookmarkList extends SimpleComp { }); }); }); - var category = new DataStoreCategoryChoiceComp(DataStorage.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory()) + var category = new DataStoreCategoryChoiceComp(StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(), selectedCategory) .styleClass(Styles.LEFT_PILL) .grow(false, true); var filter = diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java index 4674ac15..fd3d74b8 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCategoryWrapper.java @@ -53,6 +53,10 @@ public class StoreCategoryWrapper { update(); } + public StoreCategoryWrapper getRoot() { + return StoreViewState.get().getCategoryWrapper(root); + } + public StoreCategoryWrapper getParent() { return StoreViewState.get().getCategories().stream() .filter(storeCategoryWrapper -> @@ -122,7 +126,6 @@ public class StoreCategoryWrapper { .getUuid() .equals(storeCategoryWrapper.getCategory().getParentCategory())) .toList()); - Optional.ofNullable(getParent()) .ifPresent(storeCategoryWrapper -> { storeCategoryWrapper.update(); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index 2386bc86..6c2feef2 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -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(DataStorage.get().getRootCategory(DataStorage.get().getStoreCategoryIfPresent(wrapper.getEntry().getCategoryUuid()).orElseThrow())).forEach(storeCategoryWrapper -> { + StoreViewState.get().getSortedCategories(wrapper.getCategory().getValue()).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/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index 77818352..1c4febc3 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -7,7 +7,6 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.impl.FilterComp; import io.xpipe.app.fxcomps.util.BindingsHelper; -import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; @@ -25,15 +24,14 @@ public class StoreEntryListStatusComp extends SimpleComp { private Region createGroupListHeader() { var label = new Label(); label.textProperty().bind(Bindings.createStringBinding(() -> { - return StoreViewState.get().getActiveCategory().getValue().getRoot().equals(StoreViewState.get().getAllConnectionsCategory().getCategory()) ? "Connections" : "Scripts"; + return StoreViewState.get().getActiveCategory().getValue().getRoot().equals(StoreViewState.get().getAllConnectionsCategory()) ? "Connections" : "Scripts"; }, StoreViewState.get().getActiveCategory())); label.getStyleClass().add("name"); var all = BindingsHelper.filteredContentBinding( StoreViewState.get().getAllEntries(), storeEntryWrapper -> { - var cat = DataStorage.get().getStoreCategoryIfPresent(storeEntryWrapper.getEntry().getCategoryUuid()).orElse(null); - var storeRoot = cat != null ? DataStorage.get().getRootCategory(cat) : null; + var storeRoot = storeEntryWrapper.getCategory().getValue().getRoot(); return StoreViewState.get().getActiveCategory().getValue().getRoot().equals(storeRoot); }, StoreViewState.get().getActiveCategory()); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index a4b01d62..e4a88455 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -1,6 +1,5 @@ package io.xpipe.app.comp.store; -import io.xpipe.app.comp.store.GuiDsStoreCreator; import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.issue.ErrorEvent; @@ -39,6 +38,7 @@ public class StoreEntryWrapper { private final Property persistentState = new SimpleObjectProperty<>(); private final MapProperty cache = new SimpleMapProperty<>(FXCollections.observableHashMap()); private final Property color = new SimpleObjectProperty<>(); + private final Property category = new SimpleObjectProperty<>(); public StoreEntryWrapper(DataStoreEntry entry) { this.entry = entry; @@ -118,12 +118,6 @@ public class StoreEntryWrapper { } public void update() { - // var cat = StoreViewState.get().getCategories().stream() - // .filter(storeCategoryWrapper -> - // Objects.equals(storeCategoryWrapper.getCategory().getUuid(), entry.getCategoryUuid())) - // .findFirst(); - // category.setValue(cat.orElseThrow()); - // Avoid reupdating name when changed from the name property! if (!entry.getName().equals(name.getValue())) { name.setValue(entry.getName()); @@ -142,6 +136,10 @@ public class StoreEntryWrapper { deletable.setValue(entry.getConfiguration().isDeletable() || AppPrefs.get().developerDisableGuiRestrictions().getValue()); + if (StoreViewState.get() != null) { + category.setValue(StoreViewState.get().getCategoryWrapper(DataStorage.get().getStoreCategoryIfPresent(entry.getCategoryUuid()).orElseThrow())); + } + actionProviders.keySet().forEach(dataStoreActionProvider -> { if (!isInStorage()) { actionProviders.get(dataStoreActionProvider).set(false); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java index 5811144c..29cf83f1 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSection.java @@ -98,7 +98,7 @@ public class StoreSection { section -> { var showFilter = filterString == null || section.shouldShow(filterString.get()); var matchesSelector = section.anyMatches(entryFilter); - var sameCategory = category == null || category.getValue().contains(section.getWrapper().getEntry()); + var sameCategory = category == null || category.getValue() == null || category.getValue().contains(section.getWrapper().getEntry()); return showFilter && matchesSelector && sameCategory; }, category, diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java index b7186126..1e75e6f9 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreViewState.java @@ -55,18 +55,18 @@ public class StoreViewState { currentTopLevelSection = tl; } - public ObservableList getSortedCategories(DataStoreCategory root) { + public ObservableList getSortedCategories(StoreCategoryWrapper root) { Comparator comparator = new Comparator<>() { @Override public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) { var o1Root = o1.getRoot(); var o2Root = o2.getRoot(); - if (o1Root.equals(getAllConnectionsCategory().getCategory()) && !o1Root.equals(o2Root)) { + if (o1Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) { return -1; } - if (o2Root.equals(getAllConnectionsCategory().getCategory()) && !o1Root.equals(o2Root)) { + if (o2Root.equals(getAllConnectionsCategory()) && !o1Root.equals(o2Root)) { return 1; } @@ -117,6 +117,15 @@ public class StoreViewState { .orElseThrow(); } + public StoreCategoryWrapper getCategoryWrapper(DataStoreCategory entry) { + return categories.stream() + .filter(storeCategoryWrapper -> + storeCategoryWrapper.getCategory().equals(entry)) + .findFirst() + .orElseThrow(); + } + + public static void init() { if (INSTANCE != null) { return; 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 47ab2db0..919059f5 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 @@ -106,7 +106,8 @@ public class DataStoreChoiceComp extends SimpleComp { comp.disable(new SimpleBooleanProperty(true)); } }); - var category = new DataStoreCategoryChoiceComp(initialCategory != null ? initialCategory.getRoot() : null, selectedCategory).styleClass(Styles.LEFT_PILL); + var category = new DataStoreCategoryChoiceComp(initialCategory != null ? initialCategory.getRoot() : null, StoreViewState.get().getActiveCategory(), + 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/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index 28f8814f..0c1444a0 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -135,7 +135,6 @@ public class DataStoreEntry extends StorageElement { null, false, null ); - entry.refresh(); return entry; } @@ -294,7 +293,7 @@ public class DataStoreEntry extends StorageElement { public void setConfiguration(Configuration configuration) { this.configuration = configuration; this.dirty = true; - refresh(); + notifyUpdate(); } public void setCategoryUuid(UUID categoryUuid) { @@ -339,10 +338,16 @@ public class DataStoreEntry extends StorageElement { dirty = true; provider = e.provider; childrenCache = null; - refresh(); + validity = store == null ? Validity.LOAD_FAILED : store.isComplete() ? Validity.COMPLETE : Validity.INCOMPLETE; + notifyUpdate(); } public void setStoreInternal(DataStore store, boolean updateTime) { + var changed = !Objects.equals(this.store, store); + if (!changed) { + return; + } + this.store = store; this.storeNode = DataStorageWriter.storeToNode(store); if (updateTime) { @@ -384,6 +389,12 @@ public class DataStoreEntry extends StorageElement { return false; } + store = DataStorageParser.storeFromNode(storeNode); + if (store == null) { + validity = Validity.LOAD_FAILED; + return false; + } + var newComplete = store.isComplete(); if (!newComplete) { return false; @@ -403,6 +414,12 @@ public class DataStoreEntry extends StorageElement { return false; } + store = DataStorageParser.storeFromNode(storeNode); + if (store == null) { + validity = Validity.LOAD_FAILED; + return false; + } + var newComplete = store.isComplete(); if (newComplete) { return false; @@ -413,29 +430,6 @@ public class DataStoreEntry extends StorageElement { return true; } - public void refresh() { - var oldStore = store; - DataStore newStore = DataStorageParser.storeFromNode(storeNode); - if (newStore == null - || DataStoreProviders.byStoreClass(newStore.getClass()).isEmpty()) { - store = null; - validity = Validity.LOAD_FAILED; - provider = null; - dirty = dirty || oldStore != null; - notifyUpdate(); - } else { - dirty = dirty || !oldStore.equals(newStore); - store = newStore; - var complete = newStore.isComplete(); - if (complete) { - validity = Validity.COMPLETE; - } else { - validity = Validity.INCOMPLETE; - } - notifyUpdate(); - } - } - @SneakyThrows public void initializeEntry() { if (store instanceof ExpandedLifecycleStore lifecycleStore) { 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 8608d330..81b1948d 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -269,16 +269,13 @@ public class StandardStorage extends DataStorage { local.setColor(DataStoreColor.BLUE); } - // Refresh to update state - storeEntries.forEach(dataStoreEntry -> dataStoreEntry.refresh()); - + refreshValidities(true); storeEntries.forEach(entry -> { var syntheticParent = getSyntheticParent(entry); syntheticParent.ifPresent(entry1 -> { addStoreEntryIfNotPresent(entry1); }); }); - refreshValidities(true); // Save to apply changes 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 7f08100c..82fd90cb 100644 --- a/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/util/DataStoreCategoryChoiceComp.java @@ -4,7 +4,7 @@ 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 io.xpipe.app.fxcomps.util.SimpleChangeListener; import javafx.beans.property.Property; import javafx.geometry.Insets; import javafx.scene.control.ComboBox; @@ -15,22 +15,35 @@ import lombok.Value; public class DataStoreCategoryChoiceComp extends SimpleComp { - private final DataStoreCategory root; - private final Property selected; + private final StoreCategoryWrapper root; + private final Property external; + private final Property value; - public DataStoreCategoryChoiceComp(DataStoreCategory root, Property selected) { + public DataStoreCategoryChoiceComp(StoreCategoryWrapper root, Property external, Property value) { this.root = root; - this.selected = selected; + this.external = external; + this.value = value; } @Override protected Region createSimple() { - var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root)); - box.setValue(selected.getValue()); - box.valueProperty().addListener((observable, oldValue, newValue) -> { - selected.setValue(newValue); + SimpleChangeListener.apply(external, newValue -> { + if (newValue == null) { + value.setValue(root); + } else if (root == null) { + value.setValue(newValue); + } else if (!newValue.getRoot().equals(root)) { + value.setValue(root); + } else { + value.setValue(newValue); + } }); - selected.addListener((observable, oldValue, newValue) -> { + var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root)); + box.setValue(value.getValue()); + box.valueProperty().addListener((observable, oldValue, newValue) -> { + value.setValue(newValue); + }); + value.addListener((observable, oldValue, newValue) -> { PlatformThread.runLaterIfNeeded(() -> box.setValue(newValue)); }); box.setCellFactory(param -> { @@ -54,6 +67,8 @@ public class DataStoreCategoryChoiceComp extends SimpleComp { if (w != null) { textProperty().bind(w.nameProperty()); setPadding(new Insets(6, 6, 6, 8 + (indent ? w.getDepth() * 8 : 0))); + } else { + setText("None"); } } } diff --git a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java index 4b44bd76..a5992d03 100644 --- a/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java +++ b/core/src/main/java/io/xpipe/core/util/XPipeInstallation.java @@ -1,10 +1,7 @@ package io.xpipe.core.util; +import io.xpipe.core.process.*; import io.xpipe.core.store.FileNames; -import io.xpipe.core.process.CommandControl; -import io.xpipe.core.process.OsType; -import io.xpipe.core.process.ProcessOutputException; -import io.xpipe.core.process.ShellControl; import lombok.Getter; import lombok.SneakyThrows; @@ -58,20 +55,22 @@ public class XPipeInstallation { public static String createExternalAsyncLaunchCommand( String installationBase, XPipeDaemonMode mode, String arguments) { var suffix = (arguments != null ? " " + arguments : ""); + var modeOption = mode != null ? " --mode " + mode.getDisplayName() : null; if (OsType.getLocal().equals(OsType.LINUX)) { - return "nohup \"" + installationBase + "/app/bin/xpiped\" --mode " + mode.getDisplayName() + suffix + return "nohup \"" + installationBase + "/app/bin/xpiped\"" + modeOption + suffix + " & disown"; } else if (OsType.getLocal().equals(OsType.MACOS)) { - return "open \"" + installationBase + "\" --args --mode " + mode.getDisplayName() + suffix; + return "open \"" + installationBase + "\" --args" + modeOption + suffix; } return "\"" + FileNames.join(installationBase, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal())) - + "\" --mode " + mode.getDisplayName() + suffix; + + "\"" + modeOption + suffix; } public static String createExternalLaunchCommand(String command, String arguments, XPipeDaemonMode mode) { var suffix = (arguments != null ? " " + arguments : ""); - return "\"" + command + "\" --mode " + mode.getDisplayName() + suffix; + var modeOption = mode != null ? " --mode " + mode.getDisplayName() : null; + return "\"" + command + "\"" + modeOption + suffix; } @SneakyThrows diff --git a/dist/changelogs/1.7.2.md b/dist/changelogs/1.7.2.md index 6c583b64..60bc5d62 100644 --- a/dist/changelogs/1.7.2.md +++ b/dist/changelogs/1.7.2.md @@ -1,11 +1,19 @@ # 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 do not try to click the install button in XPipe**! -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. Installing a newer version of XPipe also automatically uninstalls any old ones, so you don't have to manually uninstall it. +You have to install it manually from https://github.com/xpipe-io/xpipe/releases/tag/1.7.2. You can easily do this as uninstalling the old version does not delete any user data. Installing a newer version of XPipe also automatically uninstalls any old ones, so you don't have to manually uninstall it. ## Changes in 1.7.2 -- Fix tray mode not working on newer Gnome desktop environments +### Bring your scripts with you + +This update introduces a new toggle available for all scripts that if enabled, will automatically copy these scripts to the target system and put them into the PATH when launching a new terminal session. This allows you to easily call your scripts on any system without any setup. + +### Other changes + +- Improve startup time on Linux and macOS by skipping tray initialization +- Add support for tray icon on newer Gnome desktop environments +- Fix application not starting up on newer Gnome desktop environments - Fix killing of local unresponsive shell leading to further errors ## Changes in 1.7.0 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 aba69a8b..0d930164 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 @@ -27,6 +27,9 @@ public class ScriptGroupStoreProvider implements DataStoreProvider { @Override public Comp customEntryComp(StoreSection sec, boolean preferLarge) { ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded(); + if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { + return new DenseStoreEntryComp(sec.getWrapper(), true, null); + } var def = new StoreToggleComp("base.isDefaultGroup", sec, s.getState().isDefault(), aBoolean -> { var state = s.getState(); 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 ecb7ec40..9860188b 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 @@ -87,6 +87,7 @@ public class SimpleScriptStore extends ScriptStore { @Override public void checkComplete() throws Exception { + Validators.nonNull(group); super.checkComplete(); Validators.nonNull(executionType); Validators.nonNull(minimumDialect); 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 a1367a7b..988c6998 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 @@ -43,6 +43,10 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { @Override public Comp customEntryComp(StoreSection sec, boolean preferLarge) { SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded(); + if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { + return new DenseStoreEntryComp(sec.getWrapper(), true, null); + } + var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry()); var def = new StoreToggleComp("base.isDefault", sec, s.getState().isDefault(), aBoolean -> {