diff --git a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java index 447a5e02..8e643556 100644 --- a/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/storage/store/StoreEntryComp.java @@ -351,6 +351,10 @@ public abstract class StoreEntryComp extends SimpleComp { wrapper.moveTo(storeCategoryWrapper.getCategory()); event.consume(); }); + if (storeCategoryWrapper.getParent() == null) { + m.setDisable(true); + } + move.getItems().add(m); }); contextMenu.getItems().add(move); 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 4e0bb7bf..0af4b7e2 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -101,6 +101,10 @@ 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/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 3ba24c9e..a73c7f53 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -125,7 +125,7 @@ public abstract class DataStorage { return false; } - var oldChildren = getStoreChildren(e, false); + var oldChildren = getStoreEntries().stream().filter(other -> e.equals(other.getProvider().getLogicalParent(other))).toList(); var toRemove = oldChildren.stream() .filter(entry -> newChildren.entrySet().stream() .noneMatch( @@ -245,29 +245,6 @@ public abstract class DataStorage { } } - public Optional findEntry(DataStore store) { - if (store == null) { - return Optional.empty(); - } - - for (DataStoreEntry entry : storeEntries) { - if (entry.getStore() == null) { - continue; - } - - if (!entry.getStore() - .getClass() - .equals(store.getClass())) { - continue; - } - - if (entry.getStore().equals(store)) { - return Optional.of(entry); - } - } - return Optional.empty(); - } - public List getStoreChildren(DataStoreEntry entry, boolean deep) { if (entry.getValidity() == DataStoreEntry.Validity.LOAD_FAILED) { return List.of(); @@ -286,10 +263,7 @@ public abstract class DataStorage { var parent = getDisplayParent(other); return parent.isPresent() - && entry.getStore() - .getClass() - .equals(parent.get().getStore().getClass()) - && entry.getStore().equals(parent.get().getStore()); + && parent.get().equals(entry); }) .toList()); @@ -358,15 +332,6 @@ public abstract class DataStorage { return DataStoreId.create(names.toArray(String[]::new)); } - public DataStoreEntry getStoreEntry(@NonNull DataStore store) { - return storeEntries.stream() - .filter(n -> n.getStore() != null - && Objects.equals(store.getClass(), n.getStore().getClass()) - && store.equals(n.getStore())) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Store not found")); - } - public Optional getStoreEntryIfPresent(@NonNull DataStoreId id) { var current = getStoreEntryIfPresent(id.getNames().get(0)); if (current.isPresent()) { @@ -390,13 +355,16 @@ public abstract class DataStorage { return Optional.empty(); } + public DataStoreEntry getStoreEntry(@NonNull DataStore store) { + return getStoreEntryIfPresent(store) + .orElseThrow(() -> new IllegalArgumentException("Store not found")); + } + public Optional getStoreEntryIfPresent(@NonNull DataStore store) { return storeEntries.stream() - .filter(n -> { - return n.getStore() != null - && store.getClass().equals(n.getStore().getClass()) - && store.equals(n.getStore()); - }) + .filter(n -> n.getStore() == store || (n.getStore() != null + && Objects.equals(store.getClass(), n.getStore().getClass()) + && store.equals(n.getStore()))) .findFirst(); } @@ -538,7 +506,7 @@ public abstract class DataStorage { } public DataStoreEntry getOrCreateNewEntry(String name, DataStore store) { - var found = findEntry(store); + var found = getStoreEntryIfPresent(store); if (found.isPresent()) { return found.get(); } @@ -548,7 +516,7 @@ public abstract class DataStorage { public void addStoreEntriesIfNotPresent(@NonNull DataStoreEntry... es) { for (DataStoreEntry e : es) { - if (storeEntries.contains(e) || findEntry(e.getStore()).isPresent()) { + if (storeEntries.contains(e) || getStoreEntryIfPresent(e.getStore()).isPresent()) { return; } @@ -569,7 +537,7 @@ public abstract class DataStorage { } public DataStoreEntry addStoreIfNotPresent(@NonNull String name, DataStore store) { - var f = findEntry(store); + var f = getStoreEntryIfPresent(store); if (f.isPresent()) { return f.get(); } @@ -584,7 +552,7 @@ public abstract class DataStorage { return Optional.empty(); } - return findEntry(store).map(dataStoreEntry -> dataStoreEntry.getName()); + return getStoreEntryIfPresent(store).map(dataStoreEntry -> dataStoreEntry.getName()); } public String getStoreDisplayName(DataStoreEntry store) { diff --git a/dist/changelogs/1.7.0.md b/dist/changelogs/1.7.0.md index d3643efb..faac9af6 100644 --- a/dist/changelogs/1.7.0.md +++ b/dist/changelogs/1.7.0.md @@ -2,24 +2,28 @@ ### Scripts -Have you ever set up all kinds of shell integrations and neat profile scripts to create your perfect local shell environment just as you want, but then realized that you can't apply it easily as well to your remote shell connections without copying profiles and installing the required packages everywhere? - -As XPipe 1.7 comes with a new scripting system, you now can take your environment everywhere. +XPipe 1.7 comes with a new scripting system, you now can take your environment everywhere. The idea is to create modular and reusable init scripts in XPipe that will be run on login but are independent of your profile files. You can set certain scripts to be executed for every connection, allowing you to create a consistent environment across all remote systems. As of now, there is only one set of scripts for enabling starship in your shell connections as a proof of concept. However, you can contribute custom scripts [here](https://github.com/xpipe-io/xpipe/tree/master/ext/base/src/main/java/io/xpipe/ext/base/script/PredefinedScriptStore.java) and [here](https://github.com/xpipe-io/xpipe/tree/master/ext/base/src/main/resources/io/xpipe/ext/base/resources/scripts). -### States +### Connection states The second big change is a rework of the state system. This merges the process of validating/refreshing with the process of establishing a connection, allowing for a much faster creation and launch of new connections. 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. + +### Colors + +For organization purposes when many connections are opened in the file base and terminals at the same time, you can now assign colors to connections. +These colors will be shown to identify tabs both within and outside XPipe for example in terminals. ### Other changes -- Add support for bsd-based servers +- Add support for bsd-based systems - Fix OPNsense shells timing out - Make window transparency setting a slider - Save configuration data more frequently to avoid any data loss diff --git a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java index 2b15c755..604105c8 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/action/RefreshStoreAction.java @@ -26,6 +26,27 @@ public class RefreshStoreAction implements ActionProvider { } } + @Override + public DefaultDataStoreCallSite getDefaultDataStoreCallSite() { + return new DefaultDataStoreCallSite<>() { + + @Override + public boolean isApplicable(FixedHierarchyStore o) { + return DataStorage.get().getStoreChildren(DataStorage.get().getStoreEntry(o), true).size() == 0; + } + + @Override + public ActionProvider.Action createAction(FixedHierarchyStore store) { + return new Action(DataStorage.get().getStoreEntry(store)); + } + + @Override + public Class getApplicableClass() { + return FixedHierarchyStore.class; + } + }; + } + @Override public ActionProvider.DataStoreCallSite getDataStoreCallSite() { return new ActionProvider.DataStoreCallSite() { diff --git a/version b/version index 74dc47e3..787aa40f 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.7.0-3 \ No newline at end of file +1.7.0-4 \ No newline at end of file