mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-06 13:03:29 +13:00
More service rework
This commit is contained in:
parent
c1b91f942d
commit
07540e6779
21 changed files with 256 additions and 107 deletions
|
@ -65,7 +65,9 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
VBox listView, List<? extends T> shown, List<? extends T> all, Map<T, Region> cache, boolean asynchronous) {
|
||||
Runnable update = () -> {
|
||||
// Clear cache of unused values
|
||||
cache.keySet().removeIf(t -> !all.contains(t));
|
||||
if (cache.keySet().removeIf(t -> !all.contains(t))) {
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
var newShown = shown.stream()
|
||||
.map(v -> {
|
||||
|
@ -80,6 +82,10 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
.limit(limit)
|
||||
.toList();
|
||||
|
||||
if (listView.getChildren().equals(newShown)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < newShown.size(); i++) {
|
||||
var r = newShown.get(i);
|
||||
r.pseudoClassStateChanged(ODD, false);
|
||||
|
@ -87,10 +93,8 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
r.pseudoClassStateChanged(i % 2 == 0 ? EVEN : ODD, true);
|
||||
}
|
||||
|
||||
if (!listView.getChildren().equals(newShown)) {
|
||||
var d = new DerivedObservableList<>(listView.getChildren(), true);
|
||||
d.setContent(newShown);
|
||||
}
|
||||
var d = new DerivedObservableList<>(listView.getChildren(), true);
|
||||
d.setContent(newShown);
|
||||
};
|
||||
|
||||
if (asynchronous) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.store.StoreSection;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
|
@ -52,6 +53,7 @@ public class StoreToggleComp extends SimpleComp {
|
|||
initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),
|
||||
v -> {
|
||||
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v);
|
||||
StoreViewState.get().toggleStoreListUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public class StoreEntryListStatusComp extends SimpleComp {
|
|||
StoreViewState.get().getActiveCategory());
|
||||
var shownList = all.filtered(
|
||||
storeEntryWrapper -> {
|
||||
return storeEntryWrapper.shouldShow(
|
||||
return storeEntryWrapper.matchesFilter(
|
||||
StoreViewState.get().getFilterString().getValue());
|
||||
},
|
||||
StoreViewState.get().getFilterString());
|
||||
|
|
|
@ -9,13 +9,15 @@ import io.xpipe.app.storage.DataStoreCategory;
|
|||
import io.xpipe.app.storage.DataStoreColor;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.*;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public class StoreEntryWrapper {
|
||||
|
@ -61,10 +63,6 @@ public class StoreEntryWrapper {
|
|||
setupListeners();
|
||||
}
|
||||
|
||||
public List<Observable> getUpdateObservables() {
|
||||
return List.of(category);
|
||||
}
|
||||
|
||||
public void moveTo(DataStoreCategory category) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
DataStorage.get().updateCategory(entry, category);
|
||||
|
@ -230,7 +228,7 @@ public class StoreEntryWrapper {
|
|||
this.expanded.set(!expanded.getValue());
|
||||
}
|
||||
|
||||
public boolean shouldShow(String filter) {
|
||||
public boolean matchesFilter(String filter) {
|
||||
if (filter == null || nameProperty().getValue().toLowerCase().contains(filter.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -163,8 +163,7 @@ public class StoreSection {
|
|||
|
||||
// This check is fast as the children are cached in the storage
|
||||
var isChildren = DataStorage.get().getStoreChildren(e.getEntry()).contains(other.getEntry());
|
||||
var showProvider = !other.getEntry().getValidity().isUsable() ||
|
||||
other.getEntry().getProvider().shouldShow(other);
|
||||
var showProvider = !other.getEntry().getValidity().isUsable() || other.getEntry().getProvider().shouldShow(other);
|
||||
return isChildren && showProvider;
|
||||
}, e.getPersistentState(), e.getCache(), StoreViewState.get().getEntriesListChangeObservable());
|
||||
var cached = allChildren.mapped(
|
||||
|
@ -182,9 +181,7 @@ public class StoreSection {
|
|||
// again here
|
||||
var notRoot =
|
||||
!DataStorage.get().isRootEntry(section.getWrapper().getEntry());
|
||||
var showProvider = section.getWrapper().getEntry().getProvider() == null ||
|
||||
section.getWrapper().getEntry().getProvider().shouldShow(section.getWrapper());
|
||||
return matchesSelector && showCategory && notRoot && showProvider;
|
||||
return matchesSelector && showCategory && notRoot;
|
||||
},
|
||||
category,
|
||||
filterString,
|
||||
|
@ -213,7 +210,7 @@ public class StoreSection {
|
|||
}
|
||||
|
||||
public boolean matchesFilter(String filter) {
|
||||
return anyMatches(storeEntryWrapper -> storeEntryWrapper.shouldShow(filter));
|
||||
return anyMatches(storeEntryWrapper -> storeEntryWrapper.matchesFilter(filter));
|
||||
}
|
||||
|
||||
public boolean anyMatches(Predicate<StoreEntryWrapper> c) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.comp.store;
|
|||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
|
@ -117,6 +118,18 @@ public class StoreViewState {
|
|||
.orElseThrow()));
|
||||
}
|
||||
|
||||
public void toggleStoreOrderUpdate() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
entriesOrderChangeObservable.set(entriesOrderChangeObservable.get() + 1);
|
||||
});
|
||||
}
|
||||
|
||||
public void toggleStoreListUpdate() {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
entriesListChangeObservable.set(entriesListChangeObservable.get() + 1);
|
||||
});
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
if (AppPrefs.get() != null) {
|
||||
AppPrefs.get().condenseConnectionDisplay().addListener((observable, oldValue, newValue) -> {
|
||||
|
@ -136,14 +149,14 @@ public class StoreViewState {
|
|||
@Override
|
||||
public void onStoreOrderUpdate() {
|
||||
Platform.runLater(() -> {
|
||||
entriesOrderChangeObservable.set(entriesOrderChangeObservable.get() + 1);
|
||||
toggleStoreOrderUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStoreListUpdate() {
|
||||
Platform.runLater(() -> {
|
||||
entriesListChangeObservable.set(entriesListChangeObservable.get() + 1);
|
||||
toggleStoreListUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,8 @@ import io.xpipe.app.fxcomps.Comp;
|
|||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.dialog.Dialog;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.Property;
|
||||
|
@ -198,10 +196,6 @@ public interface DataStoreProvider {
|
|||
return getModuleName() + ":" + getId() + "_icon.svg";
|
||||
}
|
||||
|
||||
default Dialog dialogForStore(DataStore store) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default DataStore defaultStore() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public class StoreCategoryComp extends SimpleComp {
|
|||
}));
|
||||
var shownList = new DerivedObservableList<>(category.getContainedEntries(), true).filtered(
|
||||
storeEntryWrapper -> {
|
||||
return storeEntryWrapper.shouldShow(
|
||||
return storeEntryWrapper.matchesFilter(
|
||||
StoreViewState.get().getFilterString().getValue());
|
||||
},
|
||||
StoreViewState.get().getFilterString()).getList();
|
||||
|
|
|
@ -129,9 +129,17 @@ public class DerivedObservableList<T> {
|
|||
}
|
||||
|
||||
public <V> DerivedObservableList<V> mapped(Function<T, V> map) {
|
||||
var cache = new HashMap<T, V>();
|
||||
var l1 = this.<V>createNewDerived();
|
||||
Runnable runnable = () -> {
|
||||
l1.setContent(list.stream().map(map).toList());
|
||||
cache.keySet().removeIf(t -> !getList().contains(t));
|
||||
l1.setContent(list.stream().map(v -> {
|
||||
if (!cache.containsKey(v)) {
|
||||
cache.put(v, map.apply(v));
|
||||
}
|
||||
|
||||
return cache.get(v);
|
||||
}).toList());
|
||||
};
|
||||
runnable.run();
|
||||
list.addListener((ListChangeListener<? super T>) c -> {
|
||||
|
|
|
@ -58,6 +58,8 @@ public abstract class DataStorage {
|
|||
@Setter
|
||||
protected DataStoreCategory selectedCategory;
|
||||
|
||||
private final Map<DataStore, DataStoreEntry> storeEntryMapCache = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
public DataStorage() {
|
||||
var prefsDir = AppPrefs.get().storageDirectory().getValue();
|
||||
this.dir = !Files.exists(prefsDir) || !Files.isDirectory(prefsDir) ? AppPrefs.DEFAULT_STORAGE_DIR : prefsDir;
|
||||
|
@ -784,12 +786,25 @@ public abstract class DataStorage {
|
|||
}
|
||||
|
||||
public Optional<DataStoreEntry> getStoreEntryIfPresent(@NonNull DataStore store, boolean identityOnly) {
|
||||
return storeEntriesSet.stream()
|
||||
synchronized (storeEntryMapCache) {
|
||||
var found = storeEntryMapCache.get(store);
|
||||
if (found != null) {
|
||||
return Optional.of(found);
|
||||
}
|
||||
}
|
||||
|
||||
var found = storeEntriesSet.stream()
|
||||
.filter(n -> n.getStore() == store || (!identityOnly && (n.getStore() != null
|
||||
&& Objects.equals(
|
||||
store.getClass(), n.getStore().getClass())
|
||||
&& store.equals(n.getStore()))))
|
||||
.findFirst();
|
||||
if (found.isPresent()) {
|
||||
synchronized (storeEntryMapCache) {
|
||||
storeEntryMapCache.put(store, found.get());
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public DataStoreCategory getRootCategory(DataStoreCategory category) {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import io.xpipe.ext.base.GroupStore;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
@SuperBuilder
|
||||
public abstract class AbstractServiceGroupStore<T extends DataStore> extends JacksonizedValue implements DataStore, GroupStore<T> {
|
||||
|
||||
DataStoreEntryRef<T> parent;
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(parent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.comp.base.StoreToggleComp;
|
||||
import io.xpipe.app.comp.base.SystemStateComp;
|
||||
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.StoreViewState;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||
var t = createToggleComp(sec);
|
||||
return StoreEntryComp.create(sec.getWrapper(), t, preferLarge);
|
||||
}
|
||||
|
||||
private StoreToggleComp createToggleComp(StoreSection sec) {
|
||||
var enabled = new SimpleBooleanProperty();
|
||||
var t = new StoreToggleComp(null, sec, enabled, aBoolean -> {
|
||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
for (DataStoreEntry child : children) {
|
||||
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
||||
if (aBoolean) {
|
||||
serviceStore.startSessionIfNeeded();
|
||||
} else {
|
||||
serviceStore.stopSessionIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
t.setCustomVisibility(Bindings.createBooleanBinding(() -> {
|
||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||
for (DataStoreEntry child : children) {
|
||||
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
||||
if (serviceStore.getHost().getStore().requiresTunnel()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, StoreViewState.get().getAllEntries().getList()));
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comp<?> stateDisplay(StoreEntryWrapper w) {
|
||||
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayIconFileName(DataStore store) {
|
||||
return "base:serviceGroup_icon.svg";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreEntry getDisplayParent(DataStoreEntry store) {
|
||||
AbstractServiceGroupStore<?> s = store.getStore().asNeeded();
|
||||
return s.getParent().get();
|
||||
}
|
||||
}
|
|
@ -10,8 +10,8 @@ import lombok.extern.jackson.Jacksonized;
|
|||
@SuperBuilder
|
||||
@Getter
|
||||
@Jacksonized
|
||||
@JsonTypeName("service")
|
||||
public class CustomServiceStore extends AbstractServiceStore {
|
||||
@JsonTypeName("customService")
|
||||
public final class CustomServiceStore extends AbstractServiceStore {
|
||||
|
||||
private final DataStoreEntryRef<NetworkTunnelStore> host;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class CustomServiceStoreProvider extends AbstractServiceStoreProvider {
|
|||
|
||||
@Override
|
||||
public List<String> getPossibleNames() {
|
||||
return List.of("service");
|
||||
return List.of("customService");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface FixedServiceCreatorStore extends DataStore {
|
||||
|
||||
List<? extends DataStoreEntryRef<? extends AbstractServiceStore>> createFixedServices() throws Exception;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.FixedHierarchyStore;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FixedChildStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import io.xpipe.ext.base.GroupStore;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@JsonTypeName("fixedServiceGroup")
|
||||
public class FixedServiceGroupStore extends JacksonizedValue implements DataStore, GroupStore<FixedServiceCreatorStore>, FixedHierarchyStore {
|
||||
|
||||
DataStoreEntryRef<? extends FixedServiceCreatorStore> parent;
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<? extends DataStoreEntryRef<? extends FixedChildStore>> listChildren(DataStoreEntry self) throws Exception {
|
||||
return (List<? extends DataStoreEntryRef<? extends FixedChildStore>>) parent.getStore().createFixedServices();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FixedServiceGroupStoreProvider extends AbstractServiceGroupStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return FixedServiceGroupStore.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreEntry getDisplayParent(DataStoreEntry store) {
|
||||
FixedServiceGroupStore s = store.getStore().asNeeded();
|
||||
return s.getParent().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleNames() {
|
||||
return List.of("fixedServiceGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getStoreClasses() {
|
||||
return List.of(FixedServiceGroupStore.class);
|
||||
}
|
||||
}
|
|
@ -3,22 +3,30 @@ package io.xpipe.ext.base.service;
|
|||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FixedChildStore;
|
||||
import io.xpipe.core.store.NetworkTunnelStore;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
@SuperBuilder
|
||||
@Getter
|
||||
@Jacksonized
|
||||
@JsonTypeName("fixedService")
|
||||
public class FixedServiceStore extends AbstractServiceStore {
|
||||
public class FixedServiceStore extends AbstractServiceStore implements FixedChildStore {
|
||||
|
||||
private final DataStoreEntryRef<NetworkTunnelStore> host;
|
||||
private final DataStoreEntryRef<? extends DataStore> parent;
|
||||
private final DataStoreEntryRef<? extends DataStore> displayParent;
|
||||
|
||||
@Override
|
||||
public DataStoreEntryRef<NetworkTunnelStore> getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt getFixedId() {
|
||||
return OptionalInt.of(getRemotePort());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -10,9 +11,9 @@ import java.util.List;
|
|||
public class FixedServiceStoreProvider extends AbstractServiceStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStoreEntry getDisplayParent(DataStoreEntry store) {
|
||||
public DataStoreEntry getSyntheticParent(DataStoreEntry store) {
|
||||
FixedServiceStore s = store.getStore().asNeeded();
|
||||
return s.getParent().get();
|
||||
return DataStorage.get().getOrCreateNewSyntheticEntry(s.getHost().get(), "Services", FixedServiceGroupStore.builder().parent(s.getDisplayParent().get().ref()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,70 +1,11 @@
|
|||
package io.xpipe.ext.base.service;
|
||||
|
||||
import io.xpipe.app.comp.base.StoreToggleComp;
|
||||
import io.xpipe.app.comp.base.SystemStateComp;
|
||||
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.StoreViewState;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ServiceGroupStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||
var t = createToggleComp(sec);
|
||||
return StoreEntryComp.create(sec.getWrapper(), t, preferLarge);
|
||||
}
|
||||
|
||||
private StoreToggleComp createToggleComp(StoreSection sec) {
|
||||
var enabled = new SimpleBooleanProperty();
|
||||
var t = new StoreToggleComp(null, sec, enabled, aBoolean -> {
|
||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
for (DataStoreEntry child : children) {
|
||||
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
||||
if (aBoolean) {
|
||||
serviceStore.startSessionIfNeeded();
|
||||
} else {
|
||||
serviceStore.stopSessionIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
t.setCustomVisibility(Bindings.createBooleanBinding(() -> {
|
||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||
for (DataStoreEntry child : children) {
|
||||
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
||||
if (serviceStore.getHost().getStore().requiresTunnel()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, StoreViewState.get().getAllEntries().getList()));
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comp<?> stateDisplay(StoreEntryWrapper w) {
|
||||
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayIconFileName(DataStore store) {
|
||||
return "base:serviceGroup_icon.svg";
|
||||
}
|
||||
public class ServiceGroupStoreProvider extends AbstractServiceGroupStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
|
|
|
@ -10,10 +10,7 @@ import io.xpipe.ext.base.desktop.DesktopEnvironmentStoreProvider;
|
|||
import io.xpipe.ext.base.script.ScriptDataStorageProvider;
|
||||
import io.xpipe.ext.base.script.ScriptGroupStoreProvider;
|
||||
import io.xpipe.ext.base.script.SimpleScriptStoreProvider;
|
||||
import io.xpipe.ext.base.service.FixedServiceStoreProvider;
|
||||
import io.xpipe.ext.base.service.ServiceGroupStoreProvider;
|
||||
import io.xpipe.ext.base.service.ServiceOpenAction;
|
||||
import io.xpipe.ext.base.service.CustomServiceStoreProvider;
|
||||
import io.xpipe.ext.base.service.*;
|
||||
import io.xpipe.ext.base.store.StorePauseAction;
|
||||
import io.xpipe.ext.base.store.StoreStartAction;
|
||||
import io.xpipe.ext.base.store.StoreStopAction;
|
||||
|
@ -75,11 +72,6 @@ open module io.xpipe.ext.base {
|
|||
EditStoreAction,
|
||||
DeleteStoreChildrenAction,
|
||||
BrowseStoreAction;
|
||||
provides DataStoreProvider with ServiceGroupStoreProvider, CustomServiceStoreProvider, FixedServiceStoreProvider,
|
||||
SimpleScriptStoreProvider,
|
||||
DesktopEnvironmentStoreProvider,
|
||||
DesktopApplicationStoreProvider,
|
||||
DesktopCommandStoreProvider,
|
||||
ScriptGroupStoreProvider;
|
||||
provides DataStoreProvider with FixedServiceGroupStoreProvider, ServiceGroupStoreProvider, CustomServiceStoreProvider, FixedServiceStoreProvider, SimpleScriptStoreProvider, DesktopEnvironmentStoreProvider, DesktopApplicationStoreProvider, DesktopCommandStoreProvider, ScriptGroupStoreProvider;
|
||||
provides DataStorageExtensionProvider with ScriptDataStorageProvider;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue