From cc4f9751fd992c22753f8c717fcedc6cfe4cc237 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sat, 19 Apr 2025 06:40:41 +0000 Subject: [PATCH] Rework --- .../file/BrowserHistorySavedStateImpl.java | 13 +- .../app/comp/store/StoreCreationModel.java | 2 +- .../io/xpipe/app/comp/store/StoreSection.java | 7 +- .../io/xpipe/app/ext/DataStoreProvider.java | 12 +- .../io/xpipe/app/ext/DataStoreProviders.java | 4 - .../io/xpipe/app/prefs/TerminalCategory.java | 5 +- .../app/terminal/ExternalTerminalType.java | 3 +- .../xpipe/app/util/DerivedObservableList.java | 186 ++++++++++-------- .../io/xpipe/app/util/DocumentationLink.java | 5 + .../DesktopApplicationStoreProvider.java | 6 + .../base/script/ScriptGroupStoreProvider.java | 6 + .../script/SimpleScriptStoreProvider.java | 4 +- .../AbstractServiceGroupStoreProvider.java | 6 + .../service/AbstractServiceStoreProvider.java | 6 + .../incus/IncusContainerStoreProvider.java | 5 + .../incus/IncusInstallStoreProvider.java | 7 + .../ext/system/lxd/LxdCmdStoreProvider.java | 6 + .../system/lxd/LxdContainerStoreProvider.java | 6 + .../system/podman/PodmanCmdStoreProvider.java | 6 + .../ext/system/podman/PodmanCommandView.java | 6 + .../system/podman/PodmanContainerStore.java | 22 ++- .../podman/PodmanContainerStoreProvider.java | 10 +- lang/strings/translations_da.properties | 2 +- lang/strings/translations_de.properties | 2 +- lang/strings/translations_en.properties | 3 +- lang/strings/translations_es.properties | 2 +- lang/strings/translations_fr.properties | 2 +- lang/strings/translations_id.properties | 2 +- lang/strings/translations_it.properties | 2 +- lang/strings/translations_ja.properties | 2 +- lang/strings/translations_nl.properties | 2 +- lang/strings/translations_pl.properties | 2 +- lang/strings/translations_pt.properties | 2 +- lang/strings/translations_ru.properties | 2 +- lang/strings/translations_sv.properties | 2 +- lang/strings/translations_tr.properties | 2 +- 36 files changed, 216 insertions(+), 146 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserHistorySavedStateImpl.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserHistorySavedStateImpl.java index 96f15952a..3748c06e1 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserHistorySavedStateImpl.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserHistorySavedStateImpl.java @@ -48,16 +48,13 @@ public class BrowserHistorySavedStateImpl implements BrowserHistorySavedState { @Override public synchronized void add(BrowserHistorySavedState.Entry entry) { - var copy = new ArrayList<>(lastSystems); - for (Entry e : copy) { - if (e.getUuid().equals(entry.getUuid())) { - lastSystems.remove(e); + synchronized (lastSystems) { + lastSystems.removeIf(e -> e == null || e.getUuid().equals(entry.getUuid())); + lastSystems.addFirst(entry); + if (lastSystems.size() > 15) { + lastSystems.removeLast(); } } - lastSystems.addFirst(entry); - if (lastSystems.size() > 15) { - lastSystems.removeLast(); - } } @Override diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java index c1dbeb870..c037085c1 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java @@ -238,7 +238,7 @@ public class StoreCreationModel { } void showDocs() { - Hyperlinks.open(provider.getValue().getHelpLink()); + Hyperlinks.open(provider.getValue().getHelpLink().getLink()); } ObservableBooleanValue canShowDocs() { 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 5ee8c5579..900e5c87e 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 @@ -54,12 +54,7 @@ public class StoreSection { } public static Comp customSection(StoreSection e) { - var prov = e.getWrapper().getEntry().getProvider(); - if (prov != null) { - return prov.customSectionComp(e); - } else { - return new StoreSectionComp(e); - } + return new StoreSectionComp(e); } private static DerivedObservableList sorted( 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 a47de0b75..a1e6889fe 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -5,11 +5,11 @@ import io.xpipe.app.comp.Comp; 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.resources.AppImages; import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.core.store.DataStore; import javafx.beans.property.BooleanProperty; @@ -24,7 +24,7 @@ import java.util.UUID; public interface DataStoreProvider { - default String getHelpLink() { + default DocumentationLink getHelpLink() { return null; } @@ -95,10 +95,6 @@ public interface DataStoreProvider { return StoreEntryComp.create(s, null, preferLarge); } - default StoreSectionComp customSectionComp(StoreSection section) { - return new StoreSectionComp(section); - } - default boolean shouldShowScan() { return true; } @@ -152,10 +148,6 @@ public interface DataStoreProvider { return null; } - default boolean preInit() { - return true; - } - default void init() {} default void reset() {} diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java index e52346bce..f66b6a896 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProviders.java @@ -71,10 +71,6 @@ public class DataStoreProviders { .collect(Collectors.toList()); ALL.removeIf(p -> { try { - if (!p.preInit()) { - return true; - } - p.validate(); return false; } catch (Throwable e) { diff --git a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java index 08b2992bb..94d594664 100644 --- a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java @@ -65,8 +65,9 @@ public class TerminalCategory extends AppPrefsCategory { .sub(new OptionsBuilder() .pref(prefs.clearTerminalOnInit) .addToggle(prefs.clearTerminalOnInit) - .pref(prefs.terminalPromptForRestart) - .addToggle(prefs.terminalPromptForRestart)) +// .pref(prefs.terminalPromptForRestart) +// .addToggle(prefs.terminalPromptForRestart) + ) .buildComp(); } diff --git a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java index 4e06f3643..adf359e88 100644 --- a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java @@ -59,7 +59,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue { // }; static ExternalTerminalType determineFallbackTerminalToOpen(ExternalTerminalType type) { - if (type != XSHELL + if (type != null + && type != XSHELL && type != MOBAXTERM && type != SECURECRT && type != TERMIUS diff --git a/app/src/main/java/io/xpipe/app/util/DerivedObservableList.java b/app/src/main/java/io/xpipe/app/util/DerivedObservableList.java index c19093d5d..775548b7c 100644 --- a/app/src/main/java/io/xpipe/app/util/DerivedObservableList.java +++ b/app/src/main/java/io/xpipe/app/util/DerivedObservableList.java @@ -55,56 +55,64 @@ public class DerivedObservableList { } public void setContent(List newList) { - if (list.equals(newList)) { - return; - } + synchronized (newList) { + synchronized (list) { + if (list.equals(newList)) { + return; + } - if (list.size() == 0) { - list.addAll(newList); - return; - } + if (list.size() == 0) { + list.addAll(newList); + return; + } - if (newList.size() == 0) { - list.clear(); - return; - } + if (newList.size() == 0) { + list.clear(); + return; + } + } - if (unique) { - setContentUnique(newList); - } else { - setContentNonUnique(newList); + if (unique) { + setContentUnique(newList); + } else { + setContentNonUnique(newList); + } } } private void setContentNonUnique(List newList) { var target = list; - var targetSet = new HashSet<>(target); - var newSet = new HashSet<>(newList); + var targetSet = new HashSet(); + synchronized (target) { + targetSet.addAll(target); - // Only add missing element - if (target.size() + 1 == newList.size() && newSet.containsAll(targetSet)) { - var l = new HashSet<>(newSet); - l.removeAll(targetSet); - if (l.size() > 0) { - var found = l.iterator().next(); - var index = newList.indexOf(found); - target.add(index, found); - return; + var newSet = new HashSet<>(newList); + + // Only add missing element + if (target.size() + 1 == newList.size() && newSet.containsAll(targetSet)) { + var l = new HashSet<>(newSet); + l.removeAll(targetSet); + if (l.size() > 0) { + var found = l.iterator().next(); + var index = newList.indexOf(found); + target.add(index, found); + return; + } } - } - // Only remove not needed element - if (target.size() - 1 == newList.size() && targetSet.containsAll(newSet)) { - var l = new HashSet<>(targetSet); - l.removeAll(newSet); - if (l.size() > 0) { - target.remove(l.iterator().next()); - return; + // Only remove not needed element + if (target.size() - 1 == newList.size() && targetSet.containsAll(newSet)) { + var l = new HashSet<>(targetSet); + l.removeAll(newSet); + if (l.size() > 0) { + target.remove(l.iterator().next()); + return; + } } - } - // Other cases are more difficult - target.setAll(newList); + // Other cases are more difficult + target.setAll(newList); + } } private int indexOfFromStart(List list, T value, int start) { @@ -117,48 +125,51 @@ public class DerivedObservableList { } private void setContentUnique(List newList) { - var listSet = new HashSet<>(list); - var newSet = new HashSet<>(newList); + var listSet = new HashSet<>(); + synchronized (list) { + listSet.addAll(list); + var newSet = new HashSet<>(newList); - // Addition - if (newSet.containsAll(list)) { - var l = new ArrayList<>(newList); - l.removeIf(t -> !listSet.contains(t)); - // Reordering occurred - if (!l.equals(list)) { - list.setAll(newList); - return; - } - - var start = 0; - for (int end = 0; end <= list.size(); end++) { - var index = end < list.size() ? indexOfFromStart(newList, list.get(end), end) : newList.size(); - for (; start < index; start++) { - list.add(start, newList.get(start)); + // Addition + if (newSet.containsAll(list)) { + var l = new ArrayList<>(newList); + l.removeIf(t -> !listSet.contains(t)); + // Reordering occurred + if (!l.equals(list)) { + list.setAll(newList); + return; } - start = index + 1; - } - return; - } - // Removal - if (listSet.containsAll(newList)) { - var l = new ArrayList<>(list); - l.removeIf(t -> !newSet.contains(t)); - // Reordering occurred - if (!l.equals(newList)) { - list.setAll(newList); + var start = 0; + for (int end = 0; end <= list.size(); end++) { + var index = end < list.size() ? indexOfFromStart(newList, list.get(end), end) : newList.size(); + for (; start < index; start++) { + list.add(start, newList.get(start)); + } + start = index + 1; + } return; } - var toRemove = new ArrayList<>(list); - toRemove.removeIf(t -> newSet.contains(t)); - list.removeAll(toRemove); - return; - } + // Removal + if (listSet.containsAll(newList)) { + var l = new ArrayList<>(list); + l.removeIf(t -> !newSet.contains(t)); + // Reordering occurred + if (!l.equals(newList)) { + list.setAll(newList); + return; + } - // Other cases are more difficult - list.setAll(newList); + var toRemove = new ArrayList<>(list); + toRemove.removeIf(t -> newSet.contains(t)); + list.removeAll(toRemove); + return; + } + + // Other cases are more difficult + list.setAll(newList); + } } private Stream listStream() { @@ -173,17 +184,17 @@ public class DerivedObservableList { var cache = new HashMap(); var l1 = this.createNewDerived(); Runnable runnable = () -> { - var listSet = new HashSet<>(list); - cache.keySet().removeIf(t -> !listSet.contains(t)); - l1.setContent(listStream() - .map(v -> { - if (!cache.containsKey(v)) { - cache.put(v, map.apply(v)); - } + synchronized (list) { + var listSet = new HashSet<>(list); + cache.keySet().removeIf(t -> !listSet.contains(t)); + l1.setContent(listStream().map(v -> { + if (!cache.containsKey(v)) { + cache.put(v, map.apply(v)); + } - return cache.get(v); - }) - .toList()); + return cache.get(v); + }).toList()); + } }; runnable.run(); list.addListener((ListChangeListener) c -> { @@ -219,10 +230,9 @@ public class DerivedObservableList { public DerivedObservableList filtered(ObservableValue> predicate) { var d = this.createNewDerived(); Runnable runnable = () -> { - d.setContent( - predicate.getValue() != null - ? listStream().filter(predicate.getValue()).toList() - : list); + synchronized (list) { + d.setContent(predicate.getValue() != null ? listStream().filter(predicate.getValue()).toList() : list); + } }; runnable.run(); list.addListener((ListChangeListener) c -> { @@ -250,7 +260,9 @@ public class DerivedObservableList { public DerivedObservableList sorted(ObservableValue> comp) { var d = this.createNewDerived(); Runnable runnable = () -> { - d.setContent(listStream().sorted(comp.getValue()).toList()); + synchronized (list) { + d.setContent(listStream().sorted(comp.getValue()).toList()); + } }; runnable.run(); list.addListener((ListChangeListener) c -> { diff --git a/app/src/main/java/io/xpipe/app/util/DocumentationLink.java b/app/src/main/java/io/xpipe/app/util/DocumentationLink.java index 44e600977..33e09ef0b 100644 --- a/app/src/main/java/io/xpipe/app/util/DocumentationLink.java +++ b/app/src/main/java/io/xpipe/app/util/DocumentationLink.java @@ -13,6 +13,8 @@ public enum DocumentationLink { EULA("legal/eula"), WEBTOP_UPDATE("guide/webtop#updating"), SYNC("guide/sync"), + DESKTOPS("guide/desktops"), + SERVICES("guide/services"), SCRIPTING("guide/scripting"), SCRIPTING_COMPATIBILITY("guide/scripting#shell-compatibility"), SCRIPTING_EDITING("guide/scripting#editing"), @@ -30,6 +32,9 @@ public enum DocumentationLink { VMWARE("guide/vmware"), VNC("guide/vnc"), SSH("guide/ssh"), + PSSESSION("guide/pssession"), + RDP("guide/rdp"), + HYPERV("guide/hyperv"), SSH_MACS("guide/ssh#no-matching-mac-found"), KEEPASSXC("guide/password-manager#keepassxc"), PASSWORD_MANAGER("guide/password-manager"); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java index 34f13d121..d8275d08b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java @@ -8,6 +8,7 @@ import io.xpipe.app.ext.*; import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; @@ -20,6 +21,11 @@ import java.util.List; public class DesktopApplicationStoreProvider implements DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.DESKTOPS; + } + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.DESKTOP; 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 fac6d4c69..45831657b 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 @@ -5,6 +5,7 @@ import io.xpipe.app.comp.store.*; import io.xpipe.app.ext.*; import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.core.store.DataStore; @@ -19,6 +20,11 @@ import java.util.List; public class ScriptGroupStoreProvider implements EnabledParentStoreProvider, DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.SCRIPTING; + } + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.GROUP; 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 1e28bb133..261c2cec2 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 @@ -38,8 +38,8 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da } @Override - public String getHelpLink() { - return DocumentationLink.SCRIPTING.getLink(); + public DocumentationLink getHelpLink() { + return DocumentationLink.SCRIPTING; } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java index 1107e1ef8..d24c092ad 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceGroupStoreProvider.java @@ -7,6 +7,7 @@ import io.xpipe.app.ext.DataStoreProvider; import io.xpipe.app.ext.DataStoreUsageCategory; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.store.DataStore; @@ -17,6 +18,11 @@ import javafx.beans.value.ObservableValue; public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.SERVICES; + } + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.GROUP; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java index c18f62987..1998dd054 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java @@ -10,6 +10,7 @@ import io.xpipe.app.ext.SingletonSessionStoreProvider; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.app.util.StoreStateFormat; import io.xpipe.core.store.DataStore; @@ -20,6 +21,11 @@ import java.util.List; public abstract class AbstractServiceStoreProvider implements SingletonSessionStoreProvider, DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.SERVICES; + } + @Override public ActionProvider.Action launchAction(DataStoreEntry store) { return new ActionProvider.Action() { diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java index 7fbb2a2b5..7f5a51598 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java @@ -20,6 +20,11 @@ import java.util.List; public class IncusContainerStoreProvider implements ShellStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.LXC; + } + @Override public String getDisplayIconFileName(DataStore store) { return "system:lxd_icon.svg"; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java index fd9b1bbf7..7682fe945 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java @@ -9,6 +9,7 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.BindingsHelper; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.core.store.DataStore; import javafx.beans.value.ObservableValue; @@ -17,6 +18,12 @@ import java.util.List; public class IncusInstallStoreProvider implements DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.LXC; + } + + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.GROUP; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java index 03edc8e36..02b645d08 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java @@ -9,6 +9,7 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.BindingsHelper; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.core.store.DataStore; import javafx.beans.value.ObservableValue; @@ -17,6 +18,11 @@ import java.util.List; public class LxdCmdStoreProvider implements DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.LXC; + } + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.GROUP; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java index 853b4659a..b3baf509c 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java @@ -8,6 +8,7 @@ import io.xpipe.app.ext.ContainerStoreState; import io.xpipe.app.ext.GuiDialog; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.app.util.OptionsBuilder; import io.xpipe.app.util.StoreStateFormat; import io.xpipe.core.store.DataStore; @@ -22,6 +23,11 @@ import java.util.List; public class LxdContainerStoreProvider implements ShellStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.LXC; + } + @Override public boolean shouldShow(StoreEntryWrapper w) { LxdContainerStore s = w.getEntry().getStore().asNeeded(); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java index 4bfdfaaeb..41eb1e214 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java @@ -11,6 +11,7 @@ import io.xpipe.app.ext.DataStoreUsageCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.BindingsHelper; import io.xpipe.app.util.DataStoreFormatter; +import io.xpipe.app.util.DocumentationLink; import io.xpipe.core.store.DataStore; import javafx.beans.value.ObservableValue; @@ -19,6 +20,11 @@ import java.util.List; public class PodmanCmdStoreProvider implements DataStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.PODMAN; + } + @Override public DataStoreUsageCategory getUsageCategory() { return DataStoreUsageCategory.GROUP; diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCommandView.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCommandView.java index ad4a134bb..109efb845 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCommandView.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCommandView.java @@ -75,6 +75,12 @@ public class PodmanCommandView extends CommandViewBase { return this; } + public String queryState(String container) throws Exception { + return build(commandBuilder -> commandBuilder.add( + "ls", "-a", "-f", "name=\"^" + container + "$\"", "--format=\"{{.Status}}\"")) + .readStdoutOrThrow(); + } + @Override protected CommandControl build(Consumer builder) { return PodmanCommandView.this.build((b) -> { diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java index 590012a29..da95ee440 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStore.java @@ -61,19 +61,18 @@ public class PodmanContainerStore @Override public void start() throws Exception { - var view = commandView(getCmd().getStore().getHost().getStore().getOrStartSession()); + var sc = getCmd().getStore().getHost().getStore().getOrStartSession(); + var view = commandView(sc); view.start(containerName); - var state = getState().toBuilder().running(true).containerState("Up").build(); - setState(state); + refreshContainerState(sc); } @Override public void stop() throws Exception { - var view = commandView(getCmd().getStore().getHost().getStore().getOrStartSession()); + var sc = getCmd().getStore().getHost().getStore().getOrStartSession(); + var view = commandView(sc); view.stop(containerName); - var state = - getState().toBuilder().running(false).containerState("Exited").build(); - setState(state); + refreshContainerState(sc); } @Override @@ -157,4 +156,13 @@ public class PodmanContainerStore } }; } + + private void refreshContainerState(ShellControl sc) throws Exception { + var state = getState(); + var view = new PodmanCommandView(sc).container(); + var displayState = view.queryState(containerName); + var running = displayState.startsWith("Up"); + var newState = state.toBuilder().containerState(displayState).running(running).build(); + setState(newState); + } } diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java index ff7f2f917..a3041c7d9 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java @@ -8,10 +8,7 @@ import io.xpipe.app.ext.ContainerStoreState; import io.xpipe.app.ext.GuiDialog; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; -import io.xpipe.app.util.DataStoreFormatter; -import io.xpipe.app.util.OptionsBuilder; -import io.xpipe.app.util.SimpleValidator; -import io.xpipe.app.util.StoreStateFormat; +import io.xpipe.app.util.*; import io.xpipe.core.store.DataStore; import io.xpipe.ext.base.service.FixedServiceGroupStore; import io.xpipe.ext.base.store.ShellStoreProvider; @@ -24,6 +21,11 @@ import java.util.List; public class PodmanContainerStoreProvider implements ShellStoreProvider { + @Override + public DocumentationLink getHelpLink() { + return DocumentationLink.PODMAN; + } + public void onParentRefresh(DataStoreEntry entry) { var services = FixedServiceGroupStore.builder().parent(entry.ref()).build(); var servicesEntry = DataStorage.get().getStoreEntryIfPresent(services, false); diff --git a/lang/strings/translations_da.properties b/lang/strings/translations_da.properties index eb8314a93..097566b1e 100644 --- a/lang/strings/translations_da.properties +++ b/lang/strings/translations_da.properties @@ -1197,7 +1197,7 @@ addUserDescription=Opret en ny bruger til denne boks skip=Spring over userChangePasswordAlertTitle=Ændring af adgangskode userChangePasswordAlertHeader=Indstil ny adgangskode til bruger -docs=Dokumenter +docs=Dokumentation lxd.displayName=LXD-container lxd.displayDescription=Opret forbindelse til en LXD-container via lxc lxdCmd.displayName=LXD CLI-klient diff --git a/lang/strings/translations_de.properties b/lang/strings/translations_de.properties index bc6d78cbc..e3f1a2e9c 100644 --- a/lang/strings/translations_de.properties +++ b/lang/strings/translations_de.properties @@ -1183,7 +1183,7 @@ addUserDescription=Einen neuen Benutzer für diesen Tresor erstellen skip=Überspringen userChangePasswordAlertTitle=Passwort ändern userChangePasswordAlertHeader=Neues Passwort für Benutzer festlegen -docs=Docs +docs=Dokumentation lxd.displayName=LXD-Container lxd.displayDescription=Verbindung zu einem LXD-Container über lxc lxdCmd.displayName=LXD CLI-Client diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index ac2285f78..c15be40cb 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -1203,7 +1203,8 @@ addUserDescription=Create a new user for this vault skip=Skip userChangePasswordAlertTitle=Password change userChangePasswordAlertHeader=Set new password for user -docs=Docs +#force +docs=Documentation lxd.displayName=LXD Container lxd.displayDescription=Connect to a LXD container via lxc lxdCmd.displayName=LXD CLI client diff --git a/lang/strings/translations_es.properties b/lang/strings/translations_es.properties index ccc0dc8a5..26e9be835 100644 --- a/lang/strings/translations_es.properties +++ b/lang/strings/translations_es.properties @@ -1154,7 +1154,7 @@ addUserDescription=Crear un nuevo usuario para este almacén skip=Saltar userChangePasswordAlertTitle=Cambio de contraseña userChangePasswordAlertHeader=Establecer una nueva contraseña para el usuario -docs=Docs +docs=Documentación lxd.displayName=Contenedor LXD lxd.displayDescription=Conectarse a un contenedor LXD mediante lxc lxdCmd.displayName=Cliente CLI LXD diff --git a/lang/strings/translations_fr.properties b/lang/strings/translations_fr.properties index f5aff0376..a84769521 100644 --- a/lang/strings/translations_fr.properties +++ b/lang/strings/translations_fr.properties @@ -1193,7 +1193,7 @@ addUserDescription=Créer un nouvel utilisateur pour ce coffre-fort skip=Sauter userChangePasswordAlertTitle=Changement de mot de passe userChangePasswordAlertHeader=Définir un nouveau mot de passe pour l'utilisateur -docs=Docs +docs=Documentation lxd.displayName=Conteneur LXD lxd.displayDescription=Se connecter à un conteneur LXD via lxc lxdCmd.displayName=Client CLI LXD diff --git a/lang/strings/translations_id.properties b/lang/strings/translations_id.properties index 3cb530b29..f81dea887 100644 --- a/lang/strings/translations_id.properties +++ b/lang/strings/translations_id.properties @@ -1154,7 +1154,7 @@ addUserDescription=Membuat pengguna baru untuk brankas ini skip=Lewati userChangePasswordAlertTitle=Perubahan kata sandi userChangePasswordAlertHeader=Mengatur kata sandi baru untuk pengguna -docs=Dokumen +docs=Dokumentasi lxd.displayName=Wadah LXD lxd.displayDescription=Menghubungkan ke wadah LXD melalui lxc lxdCmd.displayName=Klien CLI LXD diff --git a/lang/strings/translations_it.properties b/lang/strings/translations_it.properties index fdb04b28f..977303afd 100644 --- a/lang/strings/translations_it.properties +++ b/lang/strings/translations_it.properties @@ -1154,7 +1154,7 @@ addUserDescription=Crea un nuovo utente per questo vault skip=Salto userChangePasswordAlertTitle=Modifica della password userChangePasswordAlertHeader=Imposta una nuova password per l'utente -docs=Documenti +docs=Documentazione lxd.displayName=Contenitore LXD lxd.displayDescription=Connettersi a un contenitore LXD tramite lxc lxdCmd.displayName=Client CLI LXD diff --git a/lang/strings/translations_ja.properties b/lang/strings/translations_ja.properties index ae4b44394..f0f292e6f 100644 --- a/lang/strings/translations_ja.properties +++ b/lang/strings/translations_ja.properties @@ -1154,7 +1154,7 @@ addUserDescription=この保管庫の新しいユーザーを作成する skip=スキップする userChangePasswordAlertTitle=パスワードの変更 userChangePasswordAlertHeader=ユーザーに新しいパスワードを設定する -docs=ドキュメント +docs=ドキュメンテーション lxd.displayName=LXDコンテナ lxd.displayDescription=lxc経由でLXDコンテナに接続する lxdCmd.displayName=LXD CLIクライアント diff --git a/lang/strings/translations_nl.properties b/lang/strings/translations_nl.properties index 6d8cc695b..30a857dd9 100644 --- a/lang/strings/translations_nl.properties +++ b/lang/strings/translations_nl.properties @@ -1154,7 +1154,7 @@ addUserDescription=Maak een nieuwe gebruiker voor deze kluis skip=Overslaan userChangePasswordAlertTitle=Wachtwoord wijzigen userChangePasswordAlertHeader=Nieuw wachtwoord instellen voor gebruiker -docs=Docs +docs=Documentatie lxd.displayName=LXD-container lxd.displayDescription=Verbinding maken met een LXD-container via lxc lxdCmd.displayName=LXD CLI-client diff --git a/lang/strings/translations_pl.properties b/lang/strings/translations_pl.properties index b093ab0e3..ce99d8f42 100644 --- a/lang/strings/translations_pl.properties +++ b/lang/strings/translations_pl.properties @@ -1155,7 +1155,7 @@ addUserDescription=Utwórz nowego użytkownika dla tego skarbca skip=Pomiń userChangePasswordAlertTitle=Zmiana hasła userChangePasswordAlertHeader=Ustaw nowe hasło dla użytkownika -docs=Dokumenty +docs=Dokumentacja lxd.displayName=Kontener LXD lxd.displayDescription=Połącz się z kontenerem LXD przez lxc lxdCmd.displayName=Klient LXD CLI diff --git a/lang/strings/translations_pt.properties b/lang/strings/translations_pt.properties index a1971bddd..ec21a0137 100644 --- a/lang/strings/translations_pt.properties +++ b/lang/strings/translations_pt.properties @@ -1154,7 +1154,7 @@ addUserDescription=Cria um novo utilizador para esta abóbada skip=Salta userChangePasswordAlertTitle=Alteração da palavra-passe userChangePasswordAlertHeader=Define uma nova palavra-passe para o utilizador -docs=Docs +docs=Documentação lxd.displayName=Contentor LXD lxd.displayDescription=Liga-te a um contentor LXD através do lxc lxdCmd.displayName=Cliente CLI LXD diff --git a/lang/strings/translations_ru.properties b/lang/strings/translations_ru.properties index 2bc811c86..658c7409d 100644 --- a/lang/strings/translations_ru.properties +++ b/lang/strings/translations_ru.properties @@ -1154,7 +1154,7 @@ addUserDescription=Создайте нового пользователя для skip=Пропустить userChangePasswordAlertTitle=Смена пароля userChangePasswordAlertHeader=Установите новый пароль для пользователя -docs=Docs +docs=Документация lxd.displayName=LXD-контейнер lxd.displayDescription=Подключение к контейнеру LXD через lxc lxdCmd.displayName=Клиент LXD CLI diff --git a/lang/strings/translations_sv.properties b/lang/strings/translations_sv.properties index eb58f8677..08aa35bc0 100644 --- a/lang/strings/translations_sv.properties +++ b/lang/strings/translations_sv.properties @@ -1154,7 +1154,7 @@ addUserDescription=Skapa en ny användare för detta valv skip=Hoppa över userChangePasswordAlertTitle=Ändra lösenord userChangePasswordAlertHeader=Ange nytt lösenord för användare -docs=Dokument +docs=Dokumentation lxd.displayName=LXD-behållare lxd.displayDescription=Anslut till en LXD-container via lxc lxdCmd.displayName=LXD CLI-klient diff --git a/lang/strings/translations_tr.properties b/lang/strings/translations_tr.properties index ab2ce36cb..6cb2e150e 100644 --- a/lang/strings/translations_tr.properties +++ b/lang/strings/translations_tr.properties @@ -1154,7 +1154,7 @@ addUserDescription=Bu kasa için yeni bir kullanıcı oluşturun skip=Atla userChangePasswordAlertTitle=Şifre değişikliği userChangePasswordAlertHeader=Kullanıcı için yeni şifre belirleme -docs=Dokümanlar +docs=Dokümantasyon lxd.displayName=LXD Konteyner lxd.displayDescription=Lxc aracılığıyla bir LXD konteynerine bağlanma lxdCmd.displayName=LXD CLI istemcisi