This commit is contained in:
crschnick
2026-01-23 16:41:14 +00:00
parent ded364ab7b
commit f20edc9ee5
18 changed files with 251 additions and 84 deletions

View File

@@ -23,6 +23,7 @@ import lombok.Getter;
import org.int4.fx.builders.common.AbstractRegionBuilder;
import io.xpipe.app.comp.BaseRegionBuilder;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
public class AppDialog {
@@ -30,6 +31,14 @@ public class AppDialog {
@Getter
private static final ObservableList<ModalOverlay> modalOverlays = FXCollections.observableArrayList();
public static Optional<ModalOverlay> getCurrentModalOverlay() {
if (modalOverlays.isEmpty()) {
return Optional.empty();
}
return Optional.of(modalOverlays.getLast());
}
public static void closeDialog(ModalOverlay overlay) {
PlatformThread.runLaterIfNeeded(() -> {
synchronized (modalOverlays) {

View File

@@ -65,7 +65,11 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
category.getName().setValue(newValue);
}
});
var name = new LazyTextFieldComp(prop).style("name").build();
var name = new LazyTextFieldComp(prop).style("name").apply(sp -> {
category.getRenameTrigger().onFire(() -> {
sp.requestFocus();
});
}).build();
var showing = new SimpleBooleanProperty();
var expandIcon = Bindings.createObjectBinding(
@@ -121,7 +125,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
})
.apply(new ContextMenuAugment<>(
mouseEvent -> mouseEvent.getButton() == MouseButton.PRIMARY, null, () -> {
var cm = createContextMenu(name);
var cm = createContextMenu();
showing.bind(cm.showingProperty());
return cm;
}))
@@ -158,7 +162,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
categoryButton.apply(new ContextMenuAugment<>(
mouseEvent -> mouseEvent.getButton() == MouseButton.SECONDARY,
keyEvent -> keyEvent.getCode() == KeyCode.SPACE,
() -> createContextMenu(name)));
() -> createContextMenu()));
categoryButton.apply(struc -> {
struc.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.SPACE) {
@@ -200,7 +204,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
return v.build();
}
private ContextMenu createContextMenu(Region text) {
private ContextMenu createContextMenu() {
var contextMenu = MenuHelper.createContextMenu();
if (AppPrefs.get().enableHttpApi().get()) {
@@ -219,9 +223,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
var newCategory = new MenuItem(AppI18n.get("createNewCategory"), new FontIcon("mdi2p-plus-thick"));
newCategory.setOnAction(event -> {
DataStorage.get()
.addStoreCategory(
DataStoreCategory.createNew(category.getCategory().getUuid(), AppI18n.get("newCategory")));
StoreViewState.get().createNewCategory(category);
});
contextMenu.getItems().add(newCategory);
@@ -235,8 +237,8 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
var rename = new MenuItem(AppI18n.get("rename"), new FontIcon("mdal-edit"));
rename.setOnAction(event -> {
text.setDisable(false);
text.requestFocus();
category.getRenameTrigger().fire(null);
event.consume();
});
contextMenu.getItems().add(rename);

View File

@@ -13,6 +13,7 @@ import javafx.beans.property.*;
import javafx.beans.value.ObservableStringValue;
import lombok.Getter;
import org.int4.fx.values.util.Trigger;
import java.time.Duration;
import java.time.Instant;
@@ -35,6 +36,7 @@ public class StoreCategoryWrapper {
private final BooleanProperty expanded = new SimpleBooleanProperty();
private final Property<DataStoreColor> color = new SimpleObjectProperty<>();
private final BooleanProperty largeCategoryOptimizations = new SimpleBooleanProperty();
private final Trigger<Void> renameTrigger = Trigger.of();
private StoreCategoryWrapper cachedParent;
public StoreCategoryWrapper(DataStoreCategory category) {

View File

@@ -166,6 +166,7 @@ public class StoreChoiceComp<T extends DataStore> extends SimpleRegionBuilder {
AnchorPane.setBottomAnchor(struc, 3.0);
});
pane.getChildren().add(clearButton.build());
pane.getStyleClass().add("store-choice-comp");
return pane;
}

View File

@@ -1,6 +1,7 @@
package io.xpipe.app.hub.comp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.mode.AppOperationMode;
import io.xpipe.app.ext.DataStoreUsageCategory;
import io.xpipe.app.issue.ErrorEventFactory;
@@ -12,6 +13,7 @@ import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageListener;
import io.xpipe.app.util.GlobalTimer;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
@@ -23,6 +25,7 @@ import javafx.collections.ListChangeListener;
import lombok.Getter;
import java.time.Duration;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -344,6 +347,18 @@ public class StoreViewState {
});
}
public void createNewCategory(StoreCategoryWrapper parent) {
var cat = DataStoreCategory.createNew(parent.getCategory().getUuid(), AppI18n.get("newCategory"));
DataStorage.get().addStoreCategory(cat);
// Ugly solution to ensure that the category is added to the scene
GlobalTimer.delay(() -> {
var wrapper = getCategoryWrapper(cat);
Platform.runLater(() -> {
wrapper.getRenameTrigger().fire(null);
});
}, Duration.ofMillis(500));
}
private void addListeners() {
if (AppPrefs.get() != null) {
AppPrefs.get().condenseConnectionDisplay().addListener((observable, oldValue, newValue) -> {

View File

@@ -11,6 +11,10 @@ public class ShellScript {
String value;
public static ShellScript empty() {
return new ShellScript("");
}
public static ShellScript of(String s) {
return s != null ? new ShellScript(s) : null;
}

View File

@@ -208,15 +208,6 @@ public abstract class DataStorage {
localIdentities.get().setParentCategory(ALL_IDENTITIES_CATEGORY_UUID);
}
// var allMacros = getStoreCategoryIfPresent(ALL_MACROS_CATEGORY_UUID);
// if (allMacros.isEmpty()) {
// var cat = DataStoreCategory.createNew(null, ALL_MACROS_CATEGORY_UUID, "All macros");
// cat.setDirectory(categoriesDir.resolve(ALL_MACROS_CATEGORY_UUID.toString()));
// storeCategories.add(cat);
// } else {
// allMacros.get().setParentCategory(null);
// }
if (supportsSync()) {
var sharedIdentities = getStoreCategoryIfPresent(SYNCED_IDENTITIES_CATEGORY_UUID);
if (sharedIdentities.isEmpty()) {
@@ -230,17 +221,13 @@ public abstract class DataStorage {
}
}
if (getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID).isEmpty()) {
storeCategories.add(new DataStoreCategory(
categoriesDir.resolve(DEFAULT_CATEGORY_UUID.toString()),
DEFAULT_CATEGORY_UUID,
"Default",
Instant.now(),
Instant.now(),
true,
ALL_CONNECTIONS_CATEGORY_UUID,
true,
DataStoreCategoryConfig.empty()));
var def = getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID);
if (def.isEmpty()) {
DataStoreCategory cat = new DataStoreCategory(categoriesDir.resolve(DEFAULT_CATEGORY_UUID.toString()), DEFAULT_CATEGORY_UUID,
"Default", Instant.now(), Instant.now(), true, ALL_CONNECTIONS_CATEGORY_UUID, true, DataStoreCategoryConfig.empty());
storeCategories.add(cat);
} else {
def.get().setParentCategory(ALL_CONNECTIONS_CATEGORY_UUID);
}
storeCategories.forEach(dataStoreCategory -> {

View File

@@ -23,6 +23,11 @@
-fx-icon-color: -color-fg-default;
}
.store-choice-comp.left-pill .choice-comp {
-fx-background-radius: 4 0 0 4;
-fx-border-radius: 4 0 0 4;
}
.choice-comp-content > .top {
-fx-padding: 0.4em;
-fx-background-color: -color-neutral-subtle;

View File

@@ -36,7 +36,7 @@ import java.util.UUID;
public class ScriptCollectionSourceImportDialog {
private final ScriptCollectionSource source;
private final DataStoreEntryRef<ScriptCollectionSourceStore> source;
private final ObservableList<ScriptCollectionSourceEntry> available = FXCollections.observableArrayList();
private final ObservableList<ScriptCollectionSourceEntry> shown = FXCollections.observableArrayList();
private final ObservableList<ScriptCollectionSourceEntry> selected = FXCollections.observableArrayList();
@@ -45,9 +45,9 @@ public class ScriptCollectionSourceImportDialog {
private final IntegerProperty count = new SimpleIntegerProperty();
private final ObjectProperty<DataStoreEntryRef<ScriptGroupStore>> targetGroup = new SimpleObjectProperty<>();
public ScriptCollectionSourceImportDialog(ScriptCollectionSource source) {
public ScriptCollectionSourceImportDialog(DataStoreEntryRef<ScriptCollectionSourceStore> source) {
this.source = source;
available.setAll(source.listScripts());
available.setAll(source.getStore().getSource().listScripts());
update();
filter.addListener((observable, oldValue, newValue) -> {
@@ -74,8 +74,8 @@ public class ScriptCollectionSourceImportDialog {
var refresh = new ButtonComp(null, new FontIcon("mdmz-refresh"), () -> {
ThreadHelper.runAsync(() -> {
try (var ignored = new BooleanScope(busy).exclusive().start()) {
source.prepare();
var all = source.listScripts();
source.getStore().getSource().prepare();
var all = source.getStore().getSource().listScripts();
available.setAll(all);
update();
} catch (Exception e) {
@@ -151,7 +151,7 @@ public class ScriptCollectionSourceImportDialog {
var added = new ArrayList<DataStoreEntry>();
for (ScriptCollectionSourceEntry e : selected) {
var name = FilePath.of(e.getName()).getBaseName().toString();
var textSource = ScriptTextSource.SourceReference.builder().entry(e).build();
var textSource = ScriptTextSource.SourceReference.builder().ref(source).name(e.getName()).build();
var alreadyAdded = DataStorage.get().getStoreEntries().stream().anyMatch(entry -> entry.getStore() instanceof ScriptStore ss &&
textSource.equals(ss.getTextSource()));

View File

@@ -48,7 +48,7 @@ public class ScriptCollectionSourceImportHubProvider implements HubLeafProvider<
@Override
public void executeImpl() {
var dialog = new ScriptCollectionSourceImportDialog(ref.getStore().getSource());
var dialog = new ScriptCollectionSourceImportDialog(ref);
dialog.show();
}
}

View File

@@ -32,7 +32,7 @@ public class ScriptCollectionSourceStore implements DataStore, StatefulDataStore
@Override
public void validate() throws Exception {
source.prepare();
refresh();
}
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)

View File

@@ -13,6 +13,7 @@ import io.xpipe.app.util.Validators;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Singular;
import lombok.SneakyThrows;
import lombok.Value;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
@@ -75,9 +76,15 @@ public class ScriptStore implements SelfReferentialStore, StatefulDataStore<Enab
return null;
}
@SneakyThrows
public String assembleScriptChain(ShellControl shellControl, boolean args) {
var nl = shellControl.getShellDialect().getNewLine().getNewLineString();
var all = queryFlattenedScripts();
for (DataStoreEntryRef<ScriptStore> ref : all) {
ref.getStore().getTextSource().checkAvailable();
}
var r = all.stream()
.map(ref -> ref.getStore().assembleScript(shellControl, args))
.filter(s -> s != null)
@@ -91,6 +98,7 @@ public class ScriptStore implements SelfReferentialStore, StatefulDataStore<Enab
@Override
public void checkComplete() throws Throwable {
Validators.nonNull(textSource);
textSource.checkComplete();
Validators.nonNull(group);
Validators.isType(group, ScriptGroupStore.class);
if (!initScript && !shellScript && !fileScript && !runnableScript) {

View File

@@ -16,10 +16,7 @@ import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.*;
import io.xpipe.core.OsType;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
@@ -195,18 +192,10 @@ public class ScriptStoreProvider implements EnabledParentStoreProvider, DataStor
var file = st.isFileScript() ? AppI18n.get("fileBrowser") : null;
var shell = st.isShellScript() ? AppI18n.get("shell") : null;
var runnable = st.isRunnableScript() ? AppI18n.get("hub") : null;
var type = st.getMinimumDialect() != null
? st.getMinimumDialect().getDisplayName() + " " + AppI18n.get("script")
: AppI18n.get("genericScript");
var suffix = String.join(
" / ",
Stream.of(init, shell, file, runnable).filter(s -> s != null).toList());
if (!suffix.isEmpty()) {
suffix = "(" + suffix + ")";
} else {
suffix = null;
}
return new SimpleStringProperty(DataStoreFormatter.join(type, suffix));
var generic = st.getMinimumDialect() == null ? AppI18n.get("genericScript") : null;
var dialect = st.getMinimumDialect() != null ? st.getMinimumDialect().getScriptFileEnding() : null;
return new ReadOnlyObjectWrapper<>(new StoreStateFormat(
List.of(), st.getTextSource().toSummary(), init, file, shell, runnable, generic, dialect).format());
}
@SneakyThrows

View File

@@ -6,6 +6,7 @@ import io.xpipe.app.process.*;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.core.FilePath;
import lombok.SneakyThrows;
import java.util.*;
@@ -101,6 +102,7 @@ public class ScriptStoreSetup {
}
}
@SneakyThrows
private static FilePath initScriptsDirectory(ShellControl sc, List<DataStoreEntryRef<ScriptStore>> refs)
throws Exception {
if (refs.isEmpty()) {
@@ -138,6 +140,10 @@ public class ScriptStoreSetup {
}
sc.view().mkdir(targetDir);
for (DataStoreEntryRef<ScriptStore> ref : refs) {
ref.getStore().getTextSource().checkAvailable();
}
var d = sc.getShellDialect();
for (DataStoreEntryRef<ScriptStore> scriptStore : refs) {
var src = scriptStore.getStore().getTextSource();

View File

@@ -4,18 +4,21 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.app.comp.base.ContextualFileReferenceChoiceComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.InputGroupComp;
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.core.window.AppDialog;
import io.xpipe.app.ext.ShellDialectChoiceComp;
import io.xpipe.app.ext.ValidationException;
import io.xpipe.app.hub.comp.StoreChoiceComp;
import io.xpipe.app.hub.comp.StoreViewState;
import io.xpipe.app.issue.ErrorEventFactory;
import io.xpipe.app.platform.LabelGraphic;
import io.xpipe.app.platform.OptionsBuilder;
import io.xpipe.app.process.ShellDialect;
import io.xpipe.app.process.ShellScript;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.DocumentationLink;
import io.xpipe.app.util.HttpHelper;
import io.xpipe.app.util.Validators;
@@ -23,7 +26,6 @@ import io.xpipe.core.FilePath;
import io.xpipe.core.UuidHelper;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Builder;
@@ -33,10 +35,9 @@ import lombok.extern.jackson.Jacksonized;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.URISyntaxException;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -45,8 +46,8 @@ import java.util.List;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ScriptTextSource.InPlace.class),
@JsonSubTypes.Type(value = ScriptTextSource.Url.class),
@JsonSubTypes.Type(value = ScriptTextSource.SourceReference.class)
@JsonSubTypes.Type(value = ScriptTextSource.SourceReference.class),
@JsonSubTypes.Type(value = ScriptTextSource.Url.class)
})
public interface ScriptTextSource {
@@ -94,9 +95,12 @@ public interface ScriptTextSource {
Validators.nonNull(text);
}
@Override
public void checkAvailable() throws Exception {}
@Override
public String toSummary() {
return dialect.getDisplayName();
return null;
}
}
@@ -108,7 +112,6 @@ public interface ScriptTextSource {
ShellDialect dialect;
String url;
ShellScript lastText;
@SuppressWarnings("unused")
public static String getOptionsNameKey() {
@@ -132,7 +135,7 @@ public interface ScriptTextSource {
() -> Url.builder().dialect(dialect.get()).url(url.get()).build(), property);
}
private void prepare() throws Exception {
public void refresh() throws Exception {
var path = getLocalPath();
if (Files.exists(path)) {
return;
@@ -163,18 +166,31 @@ public interface ScriptTextSource {
@Override
public void checkComplete() throws ValidationException {
Validators.nonNull(url);
Validators.nonNull(lastText);
}
@Override
public void checkAvailable() throws Exception {
if (!Files.exists(getLocalPath())) {
throw ErrorEventFactory.expected(new IllegalStateException("Script URL " + url + " has not been initialized"));
}
}
@Override
public String toSummary() {
return url;
try {
var uri = URI.create(url);
return FilePath.of(uri.getPath()).getFileName();
} catch (IllegalArgumentException ignored) {
return null;
}
}
@Override
@SneakyThrows
public ShellScript getText() {
return lastText;
var path = getLocalPath();
var s = Files.readString(path);
return ShellScript.of(s);
}
}
@@ -184,7 +200,8 @@ public interface ScriptTextSource {
@Builder
class SourceReference implements ScriptTextSource {
ScriptCollectionSourceEntry entry;
DataStoreEntryRef<ScriptCollectionSourceStore> ref;
String name;
@SuppressWarnings("unused")
public static String getOptionsNameKey() {
@@ -193,38 +210,96 @@ public interface ScriptTextSource {
@SuppressWarnings("unused")
static OptionsBuilder createOptions(Property<SourceReference> property) {
var entry = new SimpleObjectProperty<>(property.getValue().getEntry());
var ref = new SimpleObjectProperty<>(property.getValue().getRef());
var name = new SimpleStringProperty(property.getValue().getName());
return new OptionsBuilder().bind(
() -> SourceReference.builder().entry(entry.get()).build(), property);
var sourceChoice = new StoreChoiceComp<>(null, ref, ScriptCollectionSourceStore.class,
ignored -> true,
StoreViewState.get().getAllScriptsCategory(),
StoreViewState.get().getScriptSourcesCategory());
var importButton = new ButtonComp(null, new LabelGraphic.IconGraphic("mdi2i-import"), () -> {
var current = AppDialog.getCurrentModalOverlay();
current.ifPresent(modalOverlay -> modalOverlay.close());
var dialog = new ScriptCollectionSourceImportDialog(ref.get());
dialog.show();
});
importButton.disable(ref.isNull());
return new OptionsBuilder()
.nameAndDescription("scriptCollectionSourceType")
.addComp(new InputGroupComp(List.of(sourceChoice, importButton)).setMainReference(0), ref)
.nonNull()
.nameAndDescription("scriptSourceName")
.addString(name)
.nonNull()
.bind(
() -> SourceReference.builder().ref(ref.getValue()).name(name.getValue()).build(), property);
}
@Override
@SneakyThrows
public void checkComplete() throws ValidationException {
Validators.nonNull(entry);
entry.getSource().checkComplete();
Validators.nonNull(ref);
ref.checkComplete();
}
@Override
public void checkAvailable() throws Exception {
var cached = ref.getStore().getState().getEntries();
if (cached == null) {
throw ErrorEventFactory.expected(new IllegalStateException("Source " + ref.get().getName() + " has not been initialized"));
}
var found = cached.stream().filter(e -> e.getName().equals(name)).findFirst().orElse(null);
if (found == null) {
throw ErrorEventFactory.expected(new IllegalStateException("Script " + name + " not found in local source " + ref.get().getName()));
}
}
@Override
public String toSummary() {
return entry.getName();
return ref.get().getName() + "/" + name;
}
@Override
public ShellDialect getDialect() {
return entry.getDialect();
var found = findSourceEntryIfPossible();
return found != null ? found.getDialect() : null;
}
@Override
@SneakyThrows
public ShellScript getText() {
var r = Files.readString(entry.getLocalFile());
var found = findSourceEntryIfPossible();
if (found == null) {
return ShellScript.empty();
}
var r = Files.readString(found.getLocalFile());
return ShellScript.of(r);
}
private ScriptCollectionSourceEntry findSourceEntryIfPossible() {
var cached = ref.getStore().getState().getEntries();
if (cached == null) {
return null;
}
var found = cached.stream().filter(e -> e.getName().equals(name)).findFirst().orElse(null);
if (found == null) {
return null;
}
return found;
}
}
void checkComplete() throws ValidationException;
void checkAvailable() throws Exception;
String toSummary();
ShellDialect getDialect();
@@ -234,8 +309,8 @@ public interface ScriptTextSource {
static List<Class<?>> getClasses() {
var l = new ArrayList<Class<?>>();
l.add(InPlace.class);
l.add(Url.class);
l.add(SourceReference.class);
l.add(Url.class);
return l;
}
}

View File

@@ -0,0 +1,60 @@
package io.xpipe.ext.base.script;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.hub.action.HubLeafProvider;
import io.xpipe.app.hub.action.StoreAction;
import io.xpipe.app.hub.action.StoreActionCategory;
import io.xpipe.app.platform.LabelGraphic;
import io.xpipe.app.storage.DataStoreEntryRef;
import javafx.beans.value.ObservableValue;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
public class ScriptUrlSourceRefreshHubProvider implements HubLeafProvider<ScriptStore> {
@Override
public StoreActionCategory getCategory() {
return StoreActionCategory.CUSTOM;
}
@Override
public boolean isApplicable(DataStoreEntryRef<ScriptStore> o) {
return o.getStore().getTextSource() instanceof ScriptTextSource.Url;
}
@Override
public boolean isMajor() {
return true;
}
@Override
public ObservableValue<String> getName(DataStoreEntryRef<ScriptStore> store) {
return AppI18n.observable("refreshSource");
}
@Override
public LabelGraphic getIcon(DataStoreEntryRef<ScriptStore> store) {
return new LabelGraphic.IconGraphic("mdi2r-refresh");
}
@Override
public Class<?> getApplicableClass() {
return ScriptStore.class;
}
@Override
public String getId() {
return "refreshScriptUrlSource";
}
@Jacksonized
@SuperBuilder
public static class Action extends StoreAction<ScriptStore> {
@Override
public void executeImpl() throws Exception {
var url = (ScriptTextSource.Url) ref.getStore().getTextSource();
url.refresh();
}
}
}

View File

@@ -43,7 +43,7 @@ open module io.xpipe.ext.base {
RunBackgroundScriptActionProvider,
RunHubBatchScriptActionProvider,
RunHubScriptActionProvider,
RunTerminalScriptActionProvider, ScriptCollectionSourceImportHubProvider, ScriptCollectionSourceRefreshHubProvider, ScriptCollectionSourceBrowseActionProvider, ScriptQuickEditHubLeafProvider,
RunTerminalScriptActionProvider, ScriptCollectionSourceImportHubProvider, ScriptUrlSourceRefreshHubProvider, ScriptCollectionSourceRefreshHubProvider, ScriptCollectionSourceBrowseActionProvider, ScriptQuickEditHubLeafProvider,
StoreStartActionProvider,
StoreStopActionProvider,
StorePauseActionProvider,

View File

@@ -679,7 +679,8 @@ scriptGroup.displayName=Script group
scriptGroup.displayDescription=Group scripts together and organize them within
scriptGroup=Group
scriptGroupDescription=The group to assign this script to
scriptGroupGroupDescription=The group to assign this script group to
#force
scriptGroupGroupDescription=The optional parent group to assign this script group to
openInNewTab=Open in new tab
executeInBackground=in background
executeInTerminal=in $TERM$
@@ -778,7 +779,8 @@ shell=Shell
hub=Hub
#context: Computer script
script=script
genericScript=Generic script
#force
genericScript=Generic
archiveName=Archive name
compress=Compress
compressContents=Compress contents
@@ -1922,9 +1924,9 @@ scriptTextSourceUrl=Script URL
scriptTextSourceUrlDescription=The URL to retrieve the script file from
scriptSourceType=Script source
scriptSourceTypeDescription=From where to source the script
scriptSourceTypeInPlace=In-place
scriptSourceTypeUrl=URL
scriptSourceTypeSource=Source
scriptSourceTypeInPlace=In-place script
scriptSourceTypeUrl=External URL
scriptSourceTypeSource=Script collection source
importScripts=Import scripts
scriptsContained=$NUMBER$ scripts
scriptSourceCollectionImportTitle=Import scripts from source ($COUNT$)
@@ -1932,3 +1934,5 @@ noScriptsFound=No scripts found
tunnel=Tunnel
notInitialized=Not initialized
selectCategory=Select category ...
scriptSourceName=Script name
scriptSourceNameDescription=The file name of the script in the source