Service fixes

This commit is contained in:
crschnick
2025-01-04 10:06:52 +00:00
parent 2b495f6a61
commit 315e8350eb
6 changed files with 87 additions and 31 deletions

View File

@@ -138,11 +138,7 @@ public abstract class StoreEntryComp extends SimpleComp {
var loading = LoadingOverlayComp.noProgress(
Comp.of(() -> button),
getWrapper().getEntry().getValidity().isUsable()
? getWrapper()
.getBusy()
.or(getWrapper().getEntry().getProvider().busy(getWrapper()))
: getWrapper().getBusy());
getWrapper().getEffectiveBusy());
AppFont.normal(button);
return loading.createRegion();
}

View File

@@ -14,7 +14,9 @@ import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.SingletonSessionStore;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.*;
import javafx.beans.value.ObservableBooleanValue;
import javafx.beans.value.ObservableStringValue;
import javafx.collections.FXCollections;
@@ -54,6 +56,9 @@ public class StoreEntryWrapper {
private final Property<String> information = new SimpleStringProperty();
private final BooleanProperty perUser = new SimpleBooleanProperty();
private boolean effectiveBusyProviderBound = false;
private final BooleanProperty effectiveBusy = new SimpleBooleanProperty();
public StoreEntryWrapper(DataStoreEntry entry) {
this.entry = entry;
this.name = new SimpleStringProperty(entry.getName());
@@ -146,6 +151,12 @@ public class StoreEntryWrapper {
name.setValue(entry.getName());
}
if (effectiveBusyProviderBound && !getValidity().getValue().isUsable()) {
this.effectiveBusyProviderBound = false;
this.effectiveBusy.unbind();
this.effectiveBusy.bind(busy);
}
var storeChanged = store.getValue() != entry.getStore();
store.setValue(entry.getStore());
if (storeChanged || !information.isBound()) {
@@ -229,6 +240,16 @@ public class StoreEntryWrapper {
ErrorEvent.fromThrowable(ex).handle();
}
}
if (!effectiveBusyProviderBound && getValidity().getValue().isUsable()) {
this.effectiveBusyProviderBound = true;
this.effectiveBusy.unbind();
this.effectiveBusy.bind(busy.or(getEntry().getProvider().busy(this)));
}
if (!this.effectiveBusy.isBound() && !getValidity().getValue().isUsable()) {
this.effectiveBusy.bind(busy);
}
}
public boolean showActionProvider(ActionProvider p) {

View File

@@ -31,17 +31,6 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
return DataStoreUsageCategory.TUNNEL;
}
@Override
public ActionProvider.Action launchAction(DataStoreEntry store) {
return new ActionProvider.Action() {
@Override
public void execute() throws Exception {
AbstractServiceStore s = store.getStore().asNeeded();
s.startSessionIfNeeded();
}
};
}
@Override
public DataStoreEntry getSyntheticParent(DataStoreEntry store) {
AbstractServiceStore s = store.getStore().asNeeded();
@@ -106,11 +95,7 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
AbstractServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
return Bindings.createStringBinding(
() -> {
var desc = s.getLocalPort() != null
? "localhost:" + s.getLocalPort() + " <- :" + s.getRemotePort()
: s.isSessionRunning()
? "localhost:" + s.getSession().getLocalPort() + " <- :" + s.getRemotePort()
: AppI18n.get("remotePort", s.getRemotePort());
var desc = formatService(s);
var type = s.getServiceProtocolType() != null
&& !(s.getServiceProtocolType() instanceof ServiceProtocolType.None)
? AppI18n.get(s.getServiceProtocolType().getTranslationKey())
@@ -126,6 +111,15 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
AppPrefs.get().language());
}
protected String formatService(AbstractServiceStore s) {
var desc = s.getLocalPort() != null
? "localhost:" + s.getLocalPort() + " <- :" + s.getRemotePort()
: s.isSessionRunning()
? "localhost:" + s.getSession().getLocalPort() + " <- :" + s.getRemotePort()
: AppI18n.get("servicePort", s.getRemotePort());
return desc;
}
@Override
public String getDisplayIconFileName(DataStore store) {
return "base:service_icon.svg";

View File

@@ -3,6 +3,7 @@ package io.xpipe.ext.base.service;
import io.xpipe.app.comp.store.StoreChoiceComp;
import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.comp.store.StoreViewState;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.GuiDialog;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
@@ -36,12 +37,6 @@ public class FixedServiceStoreProvider extends AbstractServiceStoreProvider {
return List.of("fixedService");
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
FixedServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
return new SimpleStringProperty("Port " + s.getRemotePort());
}
@Override
public List<Class<?>> getStoreClasses() {
return List.of(FixedServiceStore.class);

View File

@@ -1,9 +1,18 @@
package io.xpipe.ext.base.service;
import io.xpipe.app.comp.store.StoreChoiceComp;
import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.comp.store.StoreViewState;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.GuiDialog;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.OptionsBuilder;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.NetworkTunnelStore;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
@@ -21,14 +30,54 @@ public class MappedServiceStoreProvider extends FixedServiceStoreProvider {
return List.of("mappedService");
}
@Override
public ObservableValue<String> informationString(StoreSection section) {
MappedServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
return new SimpleStringProperty("Port " + s.getRemotePort() + " -> " + s.getContainerPort());
protected String formatService(AbstractServiceStore s) {
var m = (MappedServiceStore) s;
var desc = s.getLocalPort() != null
? "localhost:" + s.getLocalPort() + " <- :" + m.getRemotePort() + " <- :" + m.getContainerPort()
: s.isSessionRunning()
? "localhost:" + s.getSession().getLocalPort() + " <- :" + m.getRemotePort() + " <- :" + m.getContainerPort()
: ":" + m.getRemotePort() + " <- :" + m.getContainerPort();
return desc;
}
@Override
public List<Class<?>> getStoreClasses() {
return List.of(MappedServiceStore.class);
}
@Override
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
MappedServiceStore st = store.getValue().asNeeded();
var host = new SimpleObjectProperty<>(st.getHost());
var localPort = new SimpleObjectProperty<>(st.getLocalPort());
var serviceProtocolType = new SimpleObjectProperty<>(st.getServiceProtocolType());
var q = new OptionsBuilder()
.nameAndDescription("serviceHost")
.addComp(
StoreChoiceComp.other(
host,
NetworkTunnelStore.class,
n -> n.getStore().isLocallyTunnelable(),
StoreViewState.get().getAllConnectionsCategory()),
host)
.nonNull()
.sub(ServiceProtocolTypeHelper.choice(serviceProtocolType), serviceProtocolType)
.nonNull()
.nameAndDescription("serviceLocalPort")
.addInteger(localPort)
.bind(
() -> {
return MappedServiceStore.builder()
.host(host.get())
.displayParent(st.getDisplayParent())
.localPort(localPort.get())
.remotePort(st.getRemotePort())
.serviceProtocolType(serviceProtocolType.get())
.containerPort(st.getContainerPort())
.build();
},
store);
return q.buildDialog();
}
}

View File

@@ -98,3 +98,4 @@ preview=Preview
ghostty=Ghostty
http=HTTP
https=HTTPS
servicePort=Port $PORT$