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 37b40b2f2..26733cb64 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 @@ -45,7 +45,7 @@ public class StoreEntryWrapper { this.entry = entry; this.name = new SimpleStringProperty(entry.getName()); this.lastAccess = new SimpleObjectProperty<>(entry.getLastAccess().minus(Duration.ofMillis(500))); - ActionProvider.ALL.stream() + ActionProvider.ALL_STANDALONE.stream() .filter(dataStoreActionProvider -> { return !entry.isDisabled() && dataStoreActionProvider.getLeafDataStoreCallSite() != null @@ -163,7 +163,7 @@ public class StoreEntryWrapper { defaultActionProvider.setValue(null); } else { try { - var defaultProvider = ActionProvider.ALL.stream() + var defaultProvider = ActionProvider.ALL_STANDALONE.stream() .filter(e -> entry.getStore() != null && e.getDefaultDataStoreCallSite() != null && e.getDefaultDataStoreCallSite() @@ -174,7 +174,7 @@ public class StoreEntryWrapper { .orElse(null); this.defaultActionProvider.setValue(defaultProvider); - var newProviders = ActionProvider.ALL.stream() + var newProviders = ActionProvider.ALL_STANDALONE.stream() .filter(dataStoreActionProvider -> { return showActionProvider(dataStoreActionProvider); }) diff --git a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java index 4e8291b68..6e4584262 100644 --- a/app/src/main/java/io/xpipe/app/ext/ActionProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/ActionProvider.java @@ -16,6 +16,7 @@ import java.util.ServiceLoader; public interface ActionProvider { List ALL = new ArrayList<>(); + List ALL_STANDALONE = new ArrayList<>(); static void initProviders() { for (ActionProvider actionProvider : ALL) { @@ -111,7 +112,7 @@ public interface ActionProvider { String getIcon(DataStoreEntryRef store); - Class getApplicableClass(); + Class getApplicableClass(); default boolean showBusy() { return true; @@ -120,9 +121,7 @@ public interface ActionProvider { interface BranchDataStoreCallSite extends DataStoreCallSite { - default List getChildren() { - return List.of(); - } + List getChildren(); } interface LeafDataStoreCallSite extends DataStoreCallSite { @@ -145,6 +144,10 @@ public interface ActionProvider { ALL.addAll(ServiceLoader.load(layer, ActionProvider.class).stream() .map(actionProviderProvider -> actionProviderProvider.get()) .toList()); + + var menuProviders = ALL.stream().map(actionProvider -> actionProvider.getBranchDataStoreCallSite() != null ? + actionProvider.getBranchDataStoreCallSite().getChildren() : List.of()).flatMap(List::stream).toList(); + ALL_STANDALONE.addAll(ALL.stream().filter(actionProvider -> menuProviders.stream().noneMatch(menuItem -> menuItem.getClass().equals(actionProvider.getClass()))).toList()); } } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java index 1863f4776..42de55289 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenAction.java @@ -3,31 +3,29 @@ package io.xpipe.ext.base.service; import io.xpipe.app.core.AppI18n; import io.xpipe.app.ext.ActionProvider; import io.xpipe.app.storage.DataStoreEntryRef; -import io.xpipe.app.util.Hyperlinks; - +import io.xpipe.core.store.DataStore; import javafx.beans.value.ObservableValue; -import lombok.Value; +import java.util.List; public class ServiceOpenAction implements ActionProvider { @Override - public LeafDataStoreCallSite getLeafDataStoreCallSite() { - return new LeafDataStoreCallSite() { - + public BranchDataStoreCallSite getBranchDataStoreCallSite() { + return new BranchDataStoreCallSite() { @Override - public boolean isMajor(DataStoreEntryRef o) { + public boolean isMajor(DataStoreEntryRef o) { return true; } @Override - public boolean canLinkTo() { - return true; + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("openWebsite"); } @Override - public ActionProvider.Action createAction(DataStoreEntryRef store) { - return new Action(store.getStore()); + public String getIcon(DataStoreEntryRef store) { + return "mdi2s-search-web"; } @Override @@ -36,27 +34,9 @@ public class ServiceOpenAction implements ActionProvider { } @Override - public ObservableValue getName(DataStoreEntryRef store) { - return AppI18n.observable("openWebsite"); - } - - @Override - public String getIcon(DataStoreEntryRef store) { - return "mdi2s-search-web"; + public List getChildren() { + return List.of(new ServiceOpenHttpAction(), new ServiceOpenHttpsAction()); } }; } - - @Value - static class Action implements ActionProvider.Action { - - AbstractServiceStore serviceStore; - - @Override - public void execute() throws Exception { - serviceStore.startSessionIfNeeded(); - var l = serviceStore.getSession().getLocalPort(); - Hyperlinks.open("http://localhost:" + l); - } - } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpAction.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpAction.java new file mode 100644 index 000000000..d0936fbca --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpAction.java @@ -0,0 +1,60 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Hyperlinks; +import javafx.beans.value.ObservableValue; +import lombok.Value; + +public class ServiceOpenHttpAction implements ActionProvider { + + @Override + public String getId() { + return "serviceOpenHttp"; + } + + @Override + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { + + @Override + public boolean canLinkTo() { + return true; + } + + @Override + public ActionProvider.Action createAction(DataStoreEntryRef store) { + return new Action(store.getStore()); + } + + @Override + public Class getApplicableClass() { + return AbstractServiceStore.class; + } + + @Override + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("openHttp"); + } + + @Override + public String getIcon(DataStoreEntryRef store) { + return "mdi2s-shield-off-outline"; + } + }; + } + + @Value + static class Action implements ActionProvider.Action { + + AbstractServiceStore serviceStore; + + @Override + public void execute() throws Exception { + serviceStore.startSessionIfNeeded(); + var l = serviceStore.getSession().getLocalPort(); + Hyperlinks.open("http://localhost:" + l); + } + } +} diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpsAction.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpsAction.java new file mode 100644 index 000000000..31fc95d22 --- /dev/null +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceOpenHttpsAction.java @@ -0,0 +1,60 @@ +package io.xpipe.ext.base.service; + +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ActionProvider; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.Hyperlinks; +import javafx.beans.value.ObservableValue; +import lombok.Value; + +public class ServiceOpenHttpsAction implements ActionProvider { + + @Override + public String getId() { + return "serviceOpenHttps"; + } + + @Override + public LeafDataStoreCallSite getLeafDataStoreCallSite() { + return new LeafDataStoreCallSite() { + + @Override + public boolean canLinkTo() { + return true; + } + + @Override + public ActionProvider.Action createAction(DataStoreEntryRef store) { + return new Action(store.getStore()); + } + + @Override + public Class getApplicableClass() { + return AbstractServiceStore.class; + } + + @Override + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("openHttps"); + } + + @Override + public String getIcon(DataStoreEntryRef store) { + return "mdi2s-shield-lock-outline"; + } + }; + } + + @Value + static class Action implements ActionProvider.Action { + + AbstractServiceStore serviceStore; + + @Override + public void execute() throws Exception { + serviceStore.startSessionIfNeeded(); + var l = serviceStore.getSession().getLocalPort(); + Hyperlinks.open("https://localhost:" + l); + } + } +} diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index 91b56b2d1..fca233aac 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -61,6 +61,8 @@ open module io.xpipe.ext.base { JarAction; provides ActionProvider with ServiceOpenAction, + ServiceOpenHttpAction, + ServiceOpenHttpsAction, ServiceCopyUrlAction, CloneStoreAction, RefreshChildrenStoreAction, diff --git a/lang/base/strings/translations_da.properties b/lang/base/strings/translations_da.properties index a8c3ea780..569e01334 100644 --- a/lang/base/strings/translations_da.properties +++ b/lang/base/strings/translations_da.properties @@ -170,3 +170,5 @@ fixedService.displayDescription=Brug en foruddefineret tjeneste noServices=Ingen tilgængelige tjenester hasServices=$COUNT$ tilgængelige tjenester hasService=$COUNT$ tilgængelig tjeneste +openHttp=Åben HTTP-tjeneste +openHttps=Åben HTTPS-tjeneste diff --git a/lang/base/strings/translations_de.properties b/lang/base/strings/translations_de.properties index 9669d8ec6..9741c7a2a 100644 --- a/lang/base/strings/translations_de.properties +++ b/lang/base/strings/translations_de.properties @@ -161,3 +161,5 @@ fixedService.displayDescription=Einen vordefinierten Dienst verwenden noServices=Keine verfügbaren Dienste hasServices=$COUNT$ verfügbare Dienste hasService=$COUNT$ verfügbarer Dienst +openHttp=Offener HTTP-Dienst +openHttps=HTTPS-Dienst öffnen diff --git a/lang/base/strings/translations_en.properties b/lang/base/strings/translations_en.properties index 38afa7820..64820c513 100644 --- a/lang/base/strings/translations_en.properties +++ b/lang/base/strings/translations_en.properties @@ -159,5 +159,7 @@ fixedService.displayDescription=Use a predefined service noServices=No available services hasServices=$COUNT$ available services hasService=$COUNT$ available service +openHttp=Open HTTP service +openHttps=Open HTTPS service diff --git a/lang/base/strings/translations_es.properties b/lang/base/strings/translations_es.properties index 1281887b1..7d307d5e0 100644 --- a/lang/base/strings/translations_es.properties +++ b/lang/base/strings/translations_es.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Utilizar un servicio predefinido noServices=No hay servicios disponibles hasServices=$COUNT$ servicios disponibles hasService=$COUNT$ servicio disponible +openHttp=Servicio HTTP abierto +openHttps=Abrir servicio HTTPS diff --git a/lang/base/strings/translations_fr.properties b/lang/base/strings/translations_fr.properties index 80a30b1bb..6c54623f8 100644 --- a/lang/base/strings/translations_fr.properties +++ b/lang/base/strings/translations_fr.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Utiliser un service prédéfini noServices=Aucun service disponible hasServices=$COUNT$ services disponibles hasService=$COUNT$ service disponible +openHttp=Service HTTP ouvert +openHttps=Service HTTPS ouvert diff --git a/lang/base/strings/translations_it.properties b/lang/base/strings/translations_it.properties index 79e3e065e..c9f20c3f6 100644 --- a/lang/base/strings/translations_it.properties +++ b/lang/base/strings/translations_it.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Utilizzare un servizio predefinito noServices=Nessun servizio disponibile hasServices=$COUNT$ servizi disponibili hasService=$COUNT$ servizio disponibile +openHttp=Servizio HTTP aperto +openHttps=Servizio HTTPS aperto diff --git a/lang/base/strings/translations_ja.properties b/lang/base/strings/translations_ja.properties index e33d06fcc..003114b6e 100644 --- a/lang/base/strings/translations_ja.properties +++ b/lang/base/strings/translations_ja.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=定義済みのサービスを使う noServices=利用可能なサービスはない hasServices=$COUNT$ 利用可能なサービス hasService=$COUNT$ 利用可能なサービス +openHttp=オープンHTTPサービス +openHttps=HTTPSサービスを開く diff --git a/lang/base/strings/translations_nl.properties b/lang/base/strings/translations_nl.properties index 634935425..982011b9c 100644 --- a/lang/base/strings/translations_nl.properties +++ b/lang/base/strings/translations_nl.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Een vooraf gedefinieerde service gebruiken noServices=Geen beschikbare diensten hasServices=$COUNT$ beschikbare diensten hasService=$COUNT$ beschikbare dienst +openHttp=Open HTTP service +openHttps=Open HTTPS service diff --git a/lang/base/strings/translations_pt.properties b/lang/base/strings/translations_pt.properties index bdf43d927..98bbeb973 100644 --- a/lang/base/strings/translations_pt.properties +++ b/lang/base/strings/translations_pt.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Utiliza um serviço predefinido noServices=Não há serviços disponíveis hasServices=$COUNT$ serviços disponíveis hasService=$COUNT$ serviço disponível +openHttp=Abre o serviço HTTP +openHttps=Abre o serviço HTTPS diff --git a/lang/base/strings/translations_ru.properties b/lang/base/strings/translations_ru.properties index d88194bdb..adefc507a 100644 --- a/lang/base/strings/translations_ru.properties +++ b/lang/base/strings/translations_ru.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Использовать предопредел noServices=Нет доступных сервисов hasServices=$COUNT$ доступные сервисы hasService=$COUNT$ доступный сервис +openHttp=Открытый HTTP-сервис +openHttps=Открытая служба HTTPS diff --git a/lang/base/strings/translations_tr.properties b/lang/base/strings/translations_tr.properties index 2b43eb831..820412a3a 100644 --- a/lang/base/strings/translations_tr.properties +++ b/lang/base/strings/translations_tr.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=Önceden tanımlanmış bir hizmet kullanın noServices=Mevcut hizmet yok hasServices=$COUNT$ mevcut hi̇zmetler hasService=$COUNT$ mevcut hizmet +openHttp=Açık HTTP hizmeti +openHttps=HTTPS hizmetini açın diff --git a/lang/base/strings/translations_zh.properties b/lang/base/strings/translations_zh.properties index 0cd88e0b8..9b059a776 100644 --- a/lang/base/strings/translations_zh.properties +++ b/lang/base/strings/translations_zh.properties @@ -159,3 +159,5 @@ fixedService.displayDescription=使用预定义服务 noServices=无可用服务 hasServices=$COUNT$ 可用服务 hasService=$COUNT$ 可用服务 +openHttp=开放式 HTTP 服务 +openHttps=打开 HTTPS 服务