mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Reformat
This commit is contained in:
parent
c718f8d3f6
commit
51196f15bb
95 changed files with 414 additions and 286 deletions
|
@ -1,8 +1,8 @@
|
|||
package io.xpipe.app.beacon;
|
||||
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.app.util.MarkdownHelper;
|
||||
import io.xpipe.beacon.BeaconConfig;
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
|
|
|
@ -39,7 +39,8 @@ public class BeaconRequestHandler<T> implements HttpHandler {
|
|||
}
|
||||
}
|
||||
|
||||
if (beaconInterface.requiresEnabledApi() && !AppPrefs.get().enableHttpApi().get()) {
|
||||
if (beaconInterface.requiresEnabledApi()
|
||||
&& !AppPrefs.get().enableHttpApi().get()) {
|
||||
var ex = new BeaconServerException("HTTP API is not enabled in the settings menu");
|
||||
writeError(exchange, ex, 403);
|
||||
return;
|
||||
|
|
|
@ -43,7 +43,6 @@ public class FsReadExchangeImpl extends FsReadExchange {
|
|||
var out = exchange.getResponseBody()) {
|
||||
fileIn.transferTo(out);
|
||||
}
|
||||
return Response.builder().build();
|
||||
} else {
|
||||
byte[] bytes;
|
||||
try (var in = fs.openInput(msg.getPath().toString())) {
|
||||
|
@ -55,7 +54,7 @@ public class FsReadExchangeImpl extends FsReadExchange {
|
|||
try (var out = exchange.getResponseBody()) {
|
||||
out.write(bytes);
|
||||
}
|
||||
return Response.builder().build();
|
||||
}
|
||||
return Response.builder().build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.beacon.AppBeaconServer;
|
||||
import io.xpipe.app.beacon.BeaconShellSession;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.ShellStartExchange;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
public class ShellStartExchangeImpl extends ShellStartExchange {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.util.TerminalLauncherManager;
|
||||
import io.xpipe.beacon.api.SshLaunchExchange;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SshLaunchExchangeImpl extends SshLaunchExchange {
|
||||
|
|
|
@ -3,9 +3,9 @@ package io.xpipe.app.browser;
|
|||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
import io.xpipe.app.browser.file.LocalFileSystem;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
|
||||
|
|
|
@ -10,12 +10,14 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
import io.xpipe.app.util.DesktopHelper;
|
||||
import io.xpipe.app.util.ShellTemp;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import lombok.Value;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ public class BrowserAlerts {
|
|||
}
|
||||
|
||||
public static boolean showDeleteAlert(List<FileEntry> source) {
|
||||
if (!AppPrefs.get().confirmDeletions().get() && source.stream().noneMatch(entry -> entry.getKind() == FileKind.DIRECTORY)) {
|
||||
if (!AppPrefs.get().confirmDeletions().get()
|
||||
&& source.stream().noneMatch(entry -> entry.getKind() == FileKind.DIRECTORY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,9 +194,9 @@ public final class BrowserFileListComp extends SimpleComp {
|
|||
? unix.getGroup()
|
||||
: m.getCache().getGroups().getOrDefault(unix.getGid(), "?");
|
||||
var uid = String.valueOf(
|
||||
unix.getUid() != null ? unix.getUid() : m.getCache().getUidForUser(user));
|
||||
unix.getUid() != null ? unix.getUid() : m.getCache().getUidForUser(user));
|
||||
var gid = String.valueOf(
|
||||
unix.getGid() != null ? unix.getGid() : m.getCache().getGidForGroup(group));
|
||||
unix.getGid() != null ? unix.getGid() : m.getCache().getGidForGroup(group));
|
||||
if (uid.equals(gid) && user.equals(group)) {
|
||||
return user + " [" + uid + "]";
|
||||
}
|
||||
|
@ -248,7 +248,6 @@ public final class BrowserFileListComp extends SimpleComp {
|
|||
if (inCooldown) {
|
||||
lastType.set(Instant.now());
|
||||
event.consume();
|
||||
return;
|
||||
} else {
|
||||
lastType.set(null);
|
||||
typedSelection.set("");
|
||||
|
@ -256,8 +255,8 @@ public final class BrowserFileListComp extends SimpleComp {
|
|||
if (!recursive) {
|
||||
updateTypedSelection(table, lastType, event, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
lastType.set(Instant.now());
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileSystem;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
|
|
@ -60,7 +60,8 @@ public class OpenFileSystemCache extends ShellControlCache {
|
|||
var split = s.split(":");
|
||||
try {
|
||||
users.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
if (users.isEmpty()) {
|
||||
|
@ -81,7 +82,8 @@ public class OpenFileSystemCache extends ShellControlCache {
|
|||
var split = s.split(":");
|
||||
try {
|
||||
groups.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
if (groups.isEmpty()) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import io.xpipe.app.browser.file.FileSystemHelper;
|
|||
import io.xpipe.app.browser.session.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionTab;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
|
@ -18,7 +19,6 @@ import io.xpipe.app.storage.DataStoreEntryRef;
|
|||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.TerminalLauncher;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.process.ShellOpenFunction;
|
||||
|
@ -453,7 +453,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
|||
return fileSystem == null;
|
||||
}
|
||||
|
||||
public void initWithGivenDirectory(String dir) throws Exception {
|
||||
public void initWithGivenDirectory(String dir) {
|
||||
cdSync(dir);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ public class BrowserChooserComp extends SimpleComp {
|
|||
return;
|
||||
}
|
||||
|
||||
if (entry.getStore() instanceof ShellStore fileSystem) {
|
||||
if (entry.getStore() instanceof ShellStore) {
|
||||
model.openFileSystemAsync(entry.ref(), null, busy);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -238,7 +238,6 @@ public class BrowserSessionTabsComp extends SimpleComp {
|
|||
% tabs.getTabs().size();
|
||||
tabs.getSelectionModel().select(previous);
|
||||
keyEvent.consume();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ public class AppLayoutComp extends Comp<CompStructure<Pane>> {
|
|||
if (shortcut != null && shortcut.match(event)) {
|
||||
((ButtonBase) ((Parent) node).getChildrenUnmodifiable().get(1)).fire();
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.app.util.MarkdownHelper;
|
||||
import io.xpipe.app.util.ShellTemp;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.core.process.OsNameState;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import atlantafx.base.controls.Spacer;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.comp.base.DialogComp;
|
||||
import io.xpipe.app.comp.base.ErrorOverlayComp;
|
||||
|
@ -23,6 +22,7 @@ import io.xpipe.app.util.*;
|
|||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.ValidationContext;
|
||||
import io.xpipe.core.util.ValidationException;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
|
@ -34,6 +34,8 @@ import javafx.scene.layout.BorderPane;
|
|||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import atlantafx.base.controls.Spacer;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import net.synedra.validatorfx.GraphicDecorationStackPane;
|
||||
|
@ -209,7 +211,7 @@ public class StoreCreationComp extends DialogComp {
|
|||
null);
|
||||
}
|
||||
|
||||
private static interface CreationConsumer {
|
||||
public interface CreationConsumer {
|
||||
|
||||
void consume(DataStoreEntry entry, ValidationContext<?> validationContext, boolean validated);
|
||||
}
|
||||
|
@ -318,7 +320,7 @@ public class StoreCreationComp extends DialogComp {
|
|||
return;
|
||||
}
|
||||
|
||||
try (var b = new BooleanScope(busy).start()) {
|
||||
try (var ignored = new BooleanScope(busy).start()) {
|
||||
DataStorage.get().addStoreEntryInProgress(entry.getValue());
|
||||
var context = entry.getValue().validateOrThrow(false);
|
||||
commit(context, true);
|
||||
|
|
|
@ -32,17 +32,21 @@ public class StoreCreationMenu {
|
|||
|
||||
menu.getItems().add(category("addDesktop", "mdi2c-camera-plus", DataStoreCreationCategory.DESKTOP, null));
|
||||
|
||||
menu.getItems().add(category("addShell", "mdi2t-text-box-multiple", DataStoreCreationCategory.SHELL, "shellEnvironment"));
|
||||
menu.getItems()
|
||||
.add(category(
|
||||
"addShell", "mdi2t-text-box-multiple", DataStoreCreationCategory.SHELL, "shellEnvironment"));
|
||||
|
||||
menu.getItems()
|
||||
.add(category("addScript", "mdi2s-script-text-outline", DataStoreCreationCategory.SCRIPT, "script"));
|
||||
|
||||
menu.getItems()
|
||||
.add(category("addTunnel", "mdi2v-vector-polyline-plus", DataStoreCreationCategory.TUNNEL, "customService"));
|
||||
.add(category(
|
||||
"addTunnel", "mdi2v-vector-polyline-plus", DataStoreCreationCategory.TUNNEL, "customService"));
|
||||
|
||||
menu.getItems().add(category("addSerial", "mdi2s-serial-port", DataStoreCreationCategory.SERIAL, "serial"));
|
||||
|
||||
// menu.getItems().add(category("addDatabase", "mdi2d-database-plus", DataStoreCreationCategory.DATABASE, null));
|
||||
// menu.getItems().add(category("addDatabase", "mdi2d-database-plus", DataStoreCreationCategory.DATABASE,
|
||||
// null));
|
||||
}
|
||||
|
||||
private static MenuItem category(
|
||||
|
@ -85,8 +89,7 @@ public class StoreCreationMenu {
|
|||
.sorted(Comparator.comparingInt(dataStoreProvider -> dataStoreProvider.getOrderPriority()))
|
||||
.toList();
|
||||
int lastOrder = providers.getFirst().getOrderPriority();
|
||||
for (int i = 0; i < providers.size(); i++) {
|
||||
var dataStoreProvider = providers.get(i);
|
||||
for (io.xpipe.app.ext.DataStoreProvider dataStoreProvider : providers) {
|
||||
if (dataStoreProvider.getOrderPriority() != lastOrder) {
|
||||
menu.getItems().add(new SeparatorMenuItem());
|
||||
lastOrder = dataStoreProvider.getOrderPriority();
|
||||
|
@ -94,8 +97,7 @@ public class StoreCreationMenu {
|
|||
|
||||
var item = new MenuItem();
|
||||
item.textProperty().bind(dataStoreProvider.displayName());
|
||||
item.setGraphic(PrettyImageHelper.ofFixedSizeSquare(dataStoreProvider.getDisplayIconFileName(null), 16)
|
||||
.createRegion());
|
||||
item.setGraphic(PrettyImageHelper.ofFixedSizeSquare(dataStoreProvider.getDisplayIconFileName(null), 16).createRegion());
|
||||
item.setOnAction(event -> {
|
||||
StoreCreationComp.showCreation(dataStoreProvider, category);
|
||||
event.consume();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import atlantafx.base.layout.InputGroup;
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
|
@ -23,6 +21,7 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.update.XPipeDistributionType;
|
||||
import io.xpipe.app.util.*;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableDoubleValue;
|
||||
|
@ -34,6 +33,9 @@ import javafx.scene.control.*;
|
|||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.layout.InputGroup;
|
||||
import atlantafx.base.theme.Styles;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
|
|
@ -51,7 +51,8 @@ public class StoreEntryListComp extends SimpleComp {
|
|||
() -> {
|
||||
var allCat = StoreViewState.get().getAllConnectionsCategory();
|
||||
var connections = StoreViewState.get().getAllEntries().getList().stream()
|
||||
.filter(wrapper -> allCat.equals(wrapper.getCategory().getValue().getRoot()))
|
||||
.filter(wrapper -> allCat.equals(
|
||||
wrapper.getCategory().getValue().getRoot()))
|
||||
.toList();
|
||||
return initialCount == connections.size()
|
||||
&& StoreViewState.get()
|
||||
|
|
|
@ -72,8 +72,13 @@ public class StoreEntryListOverviewComp extends SimpleComp {
|
|||
// But it is good enough.
|
||||
var showProvider = true;
|
||||
try {
|
||||
showProvider = storeEntryWrapper.getEntry().getProvider() == null || storeEntryWrapper.getEntry().getProvider().shouldShow(storeEntryWrapper);
|
||||
} catch (Exception ignored) {}
|
||||
showProvider = storeEntryWrapper.getEntry().getProvider() == null
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.shouldShow(storeEntryWrapper);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return inRootCategory && showProvider;
|
||||
},
|
||||
StoreViewState.get().getActiveCategory());
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import atlantafx.base.theme.Tweaks;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.resources.SystemIcon;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -12,6 +12,8 @@ import javafx.scene.control.*;
|
|||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.theme.Tweaks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -27,7 +29,12 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
private final SimpleStringProperty filter;
|
||||
private final Runnable doubleClick;
|
||||
|
||||
public StoreIconChoiceComp(Property<SystemIcon> selected, List<SystemIcon> icons, int columns, SimpleStringProperty filter, Runnable doubleClick) {
|
||||
public StoreIconChoiceComp(
|
||||
Property<SystemIcon> selected,
|
||||
List<SystemIcon> icons,
|
||||
int columns,
|
||||
SimpleStringProperty filter,
|
||||
Runnable doubleClick) {
|
||||
this.selected = selected;
|
||||
this.icons = icons;
|
||||
this.columns = columns;
|
||||
|
@ -44,7 +51,6 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
return table;
|
||||
}
|
||||
|
||||
|
||||
private void initTable(TableView<List<SystemIcon>> table) {
|
||||
for (int i = 0; i < columns; i++) {
|
||||
var col = new TableColumn<List<SystemIcon>, SystemIcon>("col" + i);
|
||||
|
@ -65,8 +71,11 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
}
|
||||
|
||||
private void updateData(TableView<List<SystemIcon>> table, String filterString) {
|
||||
var displayedIcons = filterString == null || filterString.isBlank() || filterString.length() < 2 ? icons : icons.stream().filter(
|
||||
icon -> containsString(icon.getDisplayName(), filterString)).toList();
|
||||
var displayedIcons = filterString == null || filterString.isBlank() || filterString.length() < 2
|
||||
? icons
|
||||
: icons.stream()
|
||||
.filter(icon -> containsString(icon.getDisplayName(), filterString))
|
||||
.toList();
|
||||
|
||||
var data = partitionList(displayedIcons, columns);
|
||||
table.getItems().setAll(data);
|
||||
|
@ -97,12 +106,12 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
|
||||
private final Label root = new Label();
|
||||
private final StringProperty image = new SimpleStringProperty();
|
||||
private final Region imageView = PrettyImageHelper.ofFixedSize(image, 40, 40).createRegion();
|
||||
|
||||
public IconCell() {
|
||||
super();
|
||||
|
||||
root.setContentDisplay(ContentDisplay.TOP);
|
||||
Region imageView = PrettyImageHelper.ofFixedSize(image, 40, 40).createRegion();
|
||||
root.setGraphic(imageView);
|
||||
root.setGraphicTextGap(10);
|
||||
root.getStyleClass().addAll("icon-label", TEXT_SMALL);
|
||||
|
|
|
@ -12,12 +12,14 @@ import io.xpipe.app.resources.SystemIcon;
|
|||
import io.xpipe.app.resources.SystemIcons;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -26,7 +28,8 @@ public class StoreIconChoiceDialogComp extends SimpleComp {
|
|||
|
||||
public static void show(DataStoreEntry entry) {
|
||||
SystemIcons.load();
|
||||
var window = AppWindowHelper.sideWindow(AppI18n.get("chooseCustomIcon"), stage -> new StoreIconChoiceDialogComp(entry,stage),false,null);
|
||||
var window = AppWindowHelper.sideWindow(
|
||||
AppI18n.get("chooseCustomIcon"), stage -> new StoreIconChoiceDialogComp(entry, stage), false, null);
|
||||
window.initModality(Modality.APPLICATION_MODAL);
|
||||
window.show();
|
||||
}
|
||||
|
@ -50,8 +53,9 @@ public class StoreIconChoiceDialogComp extends SimpleComp {
|
|||
});
|
||||
});
|
||||
var github = new ButtonComp(null, new FontIcon("mdi2g-github"), () -> {
|
||||
Hyperlinks.open(Hyperlinks.SELFHST_ICONS);
|
||||
}).grow(false, true);
|
||||
Hyperlinks.open(Hyperlinks.SELFHST_ICONS);
|
||||
})
|
||||
.grow(false, true);
|
||||
var dialog = new DialogComp() {
|
||||
@Override
|
||||
protected void finish() {
|
||||
|
@ -68,10 +72,11 @@ public class StoreIconChoiceDialogComp extends SimpleComp {
|
|||
|
||||
@Override
|
||||
public Comp<?> bottom() {
|
||||
var clear = new ButtonComp(AppI18n.observable("clear"),() -> {
|
||||
selected.setValue(null);
|
||||
finish();
|
||||
}).grow(false, true);
|
||||
var clear = new ButtonComp(AppI18n.observable("clear"), () -> {
|
||||
selected.setValue(null);
|
||||
finish();
|
||||
})
|
||||
.grow(false, true);
|
||||
return new HorizontalComp(List.of(github, filter.hgrow(), clear)).spacing(10);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,27 +4,31 @@ import io.xpipe.app.fxcomps.SimpleComp;
|
|||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.resources.SystemIcons;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class StoreIconComp extends SimpleComp {
|
||||
|
||||
|
||||
private final StoreEntryWrapper wrapper;
|
||||
private final int w;
|
||||
private final int h;
|
||||
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var icon = Bindings.createStringBinding(() -> {
|
||||
return getImage();
|
||||
}, wrapper.getIcon());
|
||||
var icon = Bindings.createStringBinding(
|
||||
() -> {
|
||||
return getImage();
|
||||
},
|
||||
wrapper.getIcon());
|
||||
var imageComp = PrettyImageHelper.ofFixedSize(icon, w, h);
|
||||
var storeIcon = imageComp.createRegion();
|
||||
if (wrapper.getValidity().getValue().isUsable()) {
|
||||
|
@ -43,17 +47,21 @@ public class StoreIconComp extends SimpleComp {
|
|||
stack.setAlignment(Pos.CENTER);
|
||||
|
||||
dots.visibleProperty().bind(stack.hoverProperty());
|
||||
storeIcon.opacityProperty().bind(Bindings.createDoubleBinding(() -> {
|
||||
return stack.isHover() ? 0.5 : 1.0;
|
||||
}, stack.hoverProperty()));
|
||||
storeIcon
|
||||
.opacityProperty()
|
||||
.bind(Bindings.createDoubleBinding(
|
||||
() -> {
|
||||
return stack.isHover() ? 0.5 : 1.0;
|
||||
},
|
||||
stack.hoverProperty()));
|
||||
|
||||
stack.addEventFilter(MouseEvent.MOUSE_PRESSED,event -> {
|
||||
stack.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
|
||||
if (event.getButton() == MouseButton.PRIMARY) {
|
||||
StoreIconChoiceDialogComp.show(wrapper.getEntry());
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
@ -63,8 +71,7 @@ public class StoreIconComp extends SimpleComp {
|
|||
}
|
||||
|
||||
if (wrapper.getIcon().getValue() == null) {
|
||||
return wrapper
|
||||
.getEntry()
|
||||
return wrapper.getEntry()
|
||||
.getProvider()
|
||||
.getDisplayIconFileName(wrapper.getEntry().getStore());
|
||||
}
|
||||
|
|
|
@ -176,7 +176,8 @@ public class StoreSection {
|
|||
var showProvider = true;
|
||||
try {
|
||||
showProvider = other.getEntry().getProvider().shouldShow(other);
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return showProvider;
|
||||
},
|
||||
e.getPersistentState(),
|
||||
|
|
|
@ -98,10 +98,11 @@ public class StoreViewState {
|
|||
private void initFilterJump() {
|
||||
var all = getAllConnectionsCategory();
|
||||
filter.addListener((observable, oldValue, newValue) -> {
|
||||
var matchingCats = categories.getList().stream().filter(storeCategoryWrapper -> storeCategoryWrapper.getRoot().equals(all))
|
||||
.filter(storeCategoryWrapper -> storeCategoryWrapper.getDirectContainedEntries()
|
||||
.stream()
|
||||
.anyMatch(wrapper -> wrapper.matchesFilter(newValue)))
|
||||
var matchingCats = categories.getList().stream()
|
||||
.filter(storeCategoryWrapper ->
|
||||
storeCategoryWrapper.getRoot().equals(all))
|
||||
.filter(storeCategoryWrapper -> storeCategoryWrapper.getDirectContainedEntries().stream()
|
||||
.anyMatch(wrapper -> wrapper.matchesFilter(newValue)))
|
||||
.toList();
|
||||
if (matchingCats.size() == 1) {
|
||||
activeCategory.setValue(matchingCats.getFirst());
|
||||
|
|
|
@ -9,10 +9,10 @@ import io.xpipe.app.util.PlatformState;
|
|||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.process.OsType;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.desktop.*;
|
||||
import java.util.List;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class AppDesktopIntegration {
|
||||
|
||||
|
@ -36,7 +36,8 @@ public class AppDesktopIntegration {
|
|||
ThreadHelper.sleep(1000);
|
||||
OperationMode.close();
|
||||
});
|
||||
}}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package io.xpipe.app.core;
|
||||
|
||||
import io.xpipe.app.ext.ExtensionException;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.util.ModuleHelper;
|
||||
import io.xpipe.core.util.ModuleLayerLoader;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
|
|
@ -4,8 +4,8 @@ import io.xpipe.app.comp.base.MarkdownComp;
|
|||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.core;
|
|||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
|
||||
import javafx.scene.Scene;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -8,7 +8,9 @@ import java.util.concurrent.TimeUnit;
|
|||
public class AppBundledToolsCheck {
|
||||
|
||||
private static boolean getResult() {
|
||||
var fc = new ProcessBuilder("where", "ssh").redirectErrorStream(true).redirectOutput(ProcessBuilder.Redirect.DISCARD);
|
||||
var fc = new ProcessBuilder("where", "ssh")
|
||||
.redirectErrorStream(true)
|
||||
.redirectOutput(ProcessBuilder.Redirect.DISCARD);
|
||||
try {
|
||||
var proc = fc.start();
|
||||
proc.waitFor(2, TimeUnit.SECONDS);
|
||||
|
|
|
@ -4,14 +4,17 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
|
||||
public class AppJavaOptionsCheck {
|
||||
|
||||
public static void check() throws Exception {
|
||||
public static void check() {
|
||||
var env = System.getenv("_JAVA_OPTIONS");
|
||||
if (env == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorEvent.fromMessage("You have configured the environment variable _JAVA_OPTIONS=%s on your system.".formatted(env) +
|
||||
" This will forcefully apply all custom JVM options to XPipe as well and can cause a variety of different issues." +
|
||||
" Please remove this global environment variable and use local configuration instead for your other JVM programs.").expected().handle();
|
||||
ErrorEvent.fromMessage(
|
||||
"You have configured the environment variable _JAVA_OPTIONS=%s on your system.".formatted(env)
|
||||
+ " This will forcefully apply all custom JVM options to XPipe as well and can cause a variety of different issues."
|
||||
+ " Please remove this global environment variable and use local configuration instead for your other JVM programs.")
|
||||
.expected()
|
||||
.handle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ public class AppRosettaCheck {
|
|||
|
||||
if (ret.get().equals("1")) {
|
||||
ErrorEvent.fromMessage("You are running the Intel version of XPipe on an Apple Silicon system."
|
||||
+ " There is a native build available that comes with much better performance."
|
||||
+ " Please install that one instead.").expected().handle();
|
||||
+ " There is a native build available that comes with much better performance."
|
||||
+ " Please install that one instead.")
|
||||
.expected()
|
||||
.handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.core.check;
|
||||
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.LocalShell;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.process.ProcessOutputException;
|
||||
|
||||
import lombok.Value;
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.xpipe.app.resources.AppImages;
|
|||
import io.xpipe.app.update.UpdateAvailableAlert;
|
||||
import io.xpipe.app.util.PlatformState;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.application.Application;
|
||||
|
||||
public abstract class PlatformMode extends OperationMode {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.xpipe.app.core.window;
|
||||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppTheme;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
|
@ -10,8 +9,10 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.CloseBehaviourAlert;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.process.OsType;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
|
@ -24,17 +25,18 @@ import javafx.scene.layout.Region;
|
|||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class AppMainWindow {
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.xpipe.app.core.window;
|
||||
|
||||
import com.sun.jna.NativeLong;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.NativeBridge;
|
||||
import io.xpipe.core.util.ModuleHelper;
|
||||
|
||||
import javafx.stage.Window;
|
||||
|
||||
import com.sun.jna.NativeLong;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ 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.fxcomps.Comp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.ext;
|
|||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.comp.base.ButtonComp;
|
|||
import io.xpipe.app.comp.store.*;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.resources.SystemIcons;
|
||||
|
@ -12,7 +13,6 @@ import io.xpipe.app.storage.DataStoreEntry;
|
|||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.DataStoreCategoryChoiceComp;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
@ -217,7 +217,8 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
|
|||
}
|
||||
|
||||
SystemIcons.load();
|
||||
return "app:system/" + selected.getValue().get().getIcon() + ".svg";
|
||||
return "app:system/"
|
||||
+ selected.getValue().get().getIcon() + ".svg";
|
||||
},
|
||||
selected),
|
||||
16,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package io.xpipe.app.fxcomps.impl;
|
||||
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.fxcomps.impl;
|
||||
|
||||
import io.xpipe.app.core.App;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
@ -34,27 +34,29 @@ public class PrettyImageHelper {
|
|||
}
|
||||
|
||||
private static ObservableValue<String> rasterizedImageIfExistsScaled(String img, int height) {
|
||||
return Bindings.createStringBinding(() -> {
|
||||
if (img == null) {
|
||||
return null;
|
||||
}
|
||||
return Bindings.createStringBinding(
|
||||
() -> {
|
||||
if (img == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!img.endsWith(".svg")) {
|
||||
return rasterizedImageIfExists(img, height).orElse(null);
|
||||
}
|
||||
if (!img.endsWith(".svg")) {
|
||||
return rasterizedImageIfExists(img, height).orElse(null);
|
||||
}
|
||||
|
||||
var sizes = List.of(16, 24, 40, 80);
|
||||
var mult = Math.round(App.getApp().displayScale().get() * height);
|
||||
var base = FileNames.getBaseName(img);
|
||||
var available = sizes.stream()
|
||||
.filter(integer -> AppImages.hasNormalImage(base + "-" + integer + ".png"))
|
||||
.toList();
|
||||
var closest = available.stream()
|
||||
.filter(integer -> integer >= mult)
|
||||
.findFirst()
|
||||
.orElse(available.size() > 0 ? available.getLast() : 0);
|
||||
return rasterizedImageIfExists(img, closest).orElse(null);
|
||||
}, App.getApp().displayScale());
|
||||
var sizes = List.of(16, 24, 40, 80);
|
||||
var mult = Math.round(App.getApp().displayScale().get() * height);
|
||||
var base = FileNames.getBaseName(img);
|
||||
var available = sizes.stream()
|
||||
.filter(integer -> AppImages.hasNormalImage(base + "-" + integer + ".png"))
|
||||
.toList();
|
||||
var closest = available.stream()
|
||||
.filter(integer -> integer >= mult)
|
||||
.findFirst()
|
||||
.orElse(available.size() > 0 ? available.getLast() : 0);
|
||||
return rasterizedImageIfExists(img, closest).orElse(null);
|
||||
},
|
||||
App.getApp().displayScale());
|
||||
}
|
||||
|
||||
public static Comp<?> ofFixedSizeSquare(String img, int size) {
|
||||
|
@ -62,7 +64,7 @@ public class PrettyImageHelper {
|
|||
}
|
||||
|
||||
public static Comp<?> ofFixedSize(String img, int w, int h) {
|
||||
return ofFixedSize(new SimpleStringProperty(img), w,h);
|
||||
return ofFixedSize(new SimpleStringProperty(img), w, h);
|
||||
}
|
||||
|
||||
public static Comp<?> ofFixedSize(ObservableValue<String> img, int w, int h) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.fxcomps.impl;
|
||||
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
|
|
@ -8,8 +8,8 @@ import io.xpipe.app.core.*;
|
|||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
|
|
@ -112,17 +112,21 @@ public class LauncherCommand implements Callable<Integer> {
|
|||
}
|
||||
|
||||
try {
|
||||
client.get().performRequest(DaemonFocusExchange.Request.builder()
|
||||
.mode(getEffectiveMode())
|
||||
.build());
|
||||
client.get()
|
||||
.performRequest(DaemonFocusExchange.Request.builder()
|
||||
.mode(getEffectiveMode())
|
||||
.build());
|
||||
if (!inputs.isEmpty()) {
|
||||
client.get().performRequest(DaemonOpenExchange.Request.builder()
|
||||
.arguments(inputs)
|
||||
.build());
|
||||
client.get()
|
||||
.performRequest(DaemonOpenExchange.Request.builder()
|
||||
.arguments(inputs)
|
||||
.build());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// Wait until shutdown has completed
|
||||
if (ex.getMessage() != null && ex.getMessage().contains("Daemon is currently in shutdown") && attemptCounter < 10) {
|
||||
if (ex.getMessage() != null
|
||||
&& ex.getMessage().contains("Daemon is currently in shutdown")
|
||||
&& attemptCounter < 10) {
|
||||
ThreadHelper.sleep(1000);
|
||||
checkStart(++attemptCounter);
|
||||
return;
|
||||
|
|
|
@ -45,8 +45,12 @@ public class AppPrefs {
|
|||
mapVaultSpecific(new SimpleBooleanProperty(false), "dontAutomaticallyStartVmSshServer", Boolean.class);
|
||||
final BooleanProperty dontAcceptNewHostKeys =
|
||||
mapVaultSpecific(new SimpleBooleanProperty(false), "dontAcceptNewHostKeys", Boolean.class);
|
||||
final BooleanProperty performanceMode = map(new SimpleBooleanProperty(XPipeDistributionType.get() == XPipeDistributionType.WEBTOP), "performanceMode", Boolean.class);
|
||||
public final BooleanProperty useBundledTools = map(new SimpleBooleanProperty(false), "useBundledTools", Boolean.class);
|
||||
final BooleanProperty performanceMode = map(
|
||||
new SimpleBooleanProperty(XPipeDistributionType.get() == XPipeDistributionType.WEBTOP),
|
||||
"performanceMode",
|
||||
Boolean.class);
|
||||
public final BooleanProperty useBundledTools =
|
||||
map(new SimpleBooleanProperty(false), "useBundledTools", Boolean.class);
|
||||
public final ObjectProperty<AppTheme.Theme> theme =
|
||||
map(new SimpleObjectProperty<>(), "theme", AppTheme.Theme.class);
|
||||
final BooleanProperty useSystemFont = map(new SimpleBooleanProperty(true), "useSystemFont", Boolean.class);
|
||||
|
@ -76,7 +80,8 @@ public class AppPrefs {
|
|||
mapVaultSpecific(new SimpleBooleanProperty(false), "dontCachePasswords", Boolean.class);
|
||||
public final BooleanProperty denyTempScriptCreation =
|
||||
mapVaultSpecific(new SimpleBooleanProperty(false), "denyTempScriptCreation", Boolean.class);
|
||||
final Property<ExternalPasswordManager> passwordManager = mapVaultSpecific(new SimpleObjectProperty<>(), "passwordManager", ExternalPasswordManager.class);
|
||||
final Property<ExternalPasswordManager> passwordManager =
|
||||
mapVaultSpecific(new SimpleObjectProperty<>(), "passwordManager", ExternalPasswordManager.class);
|
||||
final StringProperty passwordManagerCommand =
|
||||
map(new SimpleStringProperty(""), "passwordManagerCommand", String.class);
|
||||
final ObjectProperty<StartupBehaviour> startupBehaviour =
|
||||
|
|
|
@ -79,7 +79,10 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
LinuxPathType VSCODE_LINUX = new LinuxPathType("app.vscode", "code") {
|
||||
@Override
|
||||
public void launch(Path file) throws Exception {
|
||||
var builder = CommandBuilder.of().fixedEnvrironment("DONT_PROMPT_WSL_INSTALL", "No_Prompt_please").addFile(executable).addFile(file.toString());
|
||||
var builder = CommandBuilder.of()
|
||||
.fixedEnvrironment("DONT_PROMPT_WSL_INSTALL", "No_Prompt_please")
|
||||
.addFile(executable)
|
||||
.addFile(file.toString());
|
||||
ExternalApplicationHelper.startAsync(builder);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -45,14 +45,15 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
|
|||
@Override
|
||||
public synchronized String retrievePassword(String key) {
|
||||
try {
|
||||
if (!loaded) {
|
||||
loaded = true;
|
||||
var cmd = """
|
||||
if (!loaded) {
|
||||
loaded = true;
|
||||
var cmd =
|
||||
"""
|
||||
$code = @"
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace CredManager {
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct CredentialMem
|
||||
|
@ -70,16 +71,16 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
|
|||
public string targetAlias;
|
||||
public string userName;
|
||||
}
|
||||
|
||||
|
||||
public class Credential {
|
||||
[DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern bool CredRead(string target, int type, int reservedFlag, out IntPtr credentialPtr);
|
||||
|
||||
|
||||
public static string GetUserPassword(string target)
|
||||
{
|
||||
CredentialMem credMem;
|
||||
IntPtr credPtr;
|
||||
|
||||
|
||||
if (CredRead(target, 1, 0, out credPtr))
|
||||
{
|
||||
credMem = Marshal.PtrToStructure<CredentialMem>(credPtr);
|
||||
|
@ -95,14 +96,14 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
|
|||
"@
|
||||
Add-Type -TypeDefinition $code -Language CSharp
|
||||
""";
|
||||
LocalShell.getLocalPowershell().command(cmd).execute();
|
||||
}
|
||||
LocalShell.getLocalPowershell().command(cmd).execute();
|
||||
}
|
||||
|
||||
return LocalShell.getLocalPowershell().command("[CredManager.Credential]::GetUserPassword(\"" + key.replaceAll("\"", "`\"") + "\")").readStdoutOrThrow();
|
||||
return LocalShell.getLocalPowershell()
|
||||
.command("[CredManager.Credential]::GetUserPassword(\"" + key.replaceAll("\"", "`\"") + "\")")
|
||||
.readStdoutOrThrow();
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex)
|
||||
.expected()
|
||||
.handle();
|
||||
ErrorEvent.fromThrowable(ex).expected().handle();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
|
@ -13,6 +12,7 @@ import io.xpipe.app.fxcomps.impl.VerticalComp;
|
|||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -21,6 +21,8 @@ import javafx.scene.control.MenuButton;
|
|||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import lombok.Value;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
|
@ -45,11 +47,16 @@ public class PasswordManagerCategory extends AppPrefsCategory {
|
|||
protected Comp<?> create() {
|
||||
var choices = new ArrayList<Choice>();
|
||||
ExternalPasswordManagerTemplate.ALL.forEach(externalPasswordManagerTemplate -> {
|
||||
choices.add(new Choice(externalPasswordManagerTemplate.getId(), externalPasswordManagerTemplate.getTemplate(), ExternalPasswordManager.COMMAND));
|
||||
});
|
||||
ExternalPasswordManager.ALL.stream().filter(externalPasswordManager -> externalPasswordManager != ExternalPasswordManager.COMMAND).forEach(externalPasswordManager -> {
|
||||
choices.add(new Choice(externalPasswordManager.getId(), null, externalPasswordManager));
|
||||
choices.add(new Choice(
|
||||
externalPasswordManagerTemplate.getId(),
|
||||
externalPasswordManagerTemplate.getTemplate(),
|
||||
ExternalPasswordManager.COMMAND));
|
||||
});
|
||||
ExternalPasswordManager.ALL.stream()
|
||||
.filter(externalPasswordManager -> externalPasswordManager != ExternalPasswordManager.COMMAND)
|
||||
.forEach(externalPasswordManager -> {
|
||||
choices.add(new Choice(externalPasswordManager.getId(), null, externalPasswordManager));
|
||||
});
|
||||
|
||||
var prefs = AppPrefs.get();
|
||||
var testPasswordManagerValue = new SimpleStringProperty();
|
||||
|
@ -89,8 +96,10 @@ public class PasswordManagerCategory extends AppPrefsCategory {
|
|||
.minHeight(120);
|
||||
var templates = Comp.of(() -> {
|
||||
var cb = new MenuButton();
|
||||
cb.textProperty().bind(BindingsHelper.flatMap(prefs.passwordManager,externalPasswordManager -> {
|
||||
return externalPasswordManager != null ? AppI18n.observable(externalPasswordManager.getId()) : AppI18n.observable("selectType");
|
||||
cb.textProperty().bind(BindingsHelper.flatMap(prefs.passwordManager, externalPasswordManager -> {
|
||||
return externalPasswordManager != null
|
||||
? AppI18n.observable(externalPasswordManager.getId())
|
||||
: AppI18n.observable("selectType");
|
||||
}));
|
||||
choices.forEach(e -> {
|
||||
var m = new MenuItem();
|
||||
|
@ -119,17 +128,16 @@ public class PasswordManagerCategory extends AppPrefsCategory {
|
|||
event.consume();
|
||||
}
|
||||
})),
|
||||
new ButtonComp(null, new FontIcon("mdi2p-play"), test)
|
||||
.styleClass(Styles.RIGHT_PILL)));
|
||||
new ButtonComp(null, new FontIcon("mdi2p-play"), test).styleClass(Styles.RIGHT_PILL)));
|
||||
testInput.apply(struc -> {
|
||||
var first = ((Region) struc.get().getChildren().get(0));
|
||||
var second = ((Region) struc.get().getChildren().get(1));
|
||||
second.prefHeightProperty().bind(first.heightProperty());
|
||||
});
|
||||
|
||||
var testPasswordManager = new HorizontalComp(List.of(testInput,
|
||||
Comp.hspacer(25),
|
||||
new LabelComp(testPasswordManagerResult).apply(struc -> struc.get().setOpacity(0.5))))
|
||||
var testPasswordManager = new HorizontalComp(List.of(
|
||||
testInput, Comp.hspacer(25), new LabelComp(testPasswordManagerResult).apply(struc -> struc.get()
|
||||
.setOpacity(0.5))))
|
||||
.padding(new Insets(10, 0, 0, 0))
|
||||
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT))
|
||||
.apply(struc -> struc.get().setFillHeight(true));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
|
@ -14,6 +13,7 @@ import io.xpipe.app.storage.DataStorageSyncHandler;
|
|||
import io.xpipe.app.util.DesktopHelper;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -21,6 +21,8 @@ import javafx.geometry.Pos;
|
|||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -33,7 +35,6 @@ public class SyncCategory extends AppPrefsCategory {
|
|||
return "sync";
|
||||
}
|
||||
|
||||
|
||||
private static void showHelpAlert() {
|
||||
AppWindowHelper.showAlert(
|
||||
alert -> {
|
||||
|
@ -76,8 +77,7 @@ public class SyncCategory extends AppPrefsCategory {
|
|||
restartButton.visible(canRestart);
|
||||
restartButton.padding(new Insets(6, 10, 6, 6));
|
||||
|
||||
var testRow = new HorizontalComp(
|
||||
List.of(testButton, restartButton))
|
||||
var testRow = new HorizontalComp(List.of(testButton, restartButton))
|
||||
.spacing(10)
|
||||
.padding(new Insets(10, 0, 0, 0))
|
||||
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT));
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.prefs;
|
|||
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.impl.ChoiceComp;
|
||||
|
@ -13,7 +14,6 @@ import io.xpipe.app.util.Hyperlinks;
|
|||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.app.util.TerminalLauncher;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Insets;
|
||||
|
|
|
@ -47,9 +47,12 @@ public class TroubleshootCategory extends AppPrefsCategory {
|
|||
.toString(),
|
||||
XPipeInstallation.getDaemonDebugScriptPath(OsType.getLocal()));
|
||||
// We can't use the SSH bridge
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue());
|
||||
TerminalLauncher.openDirect("XPipe Debug", sc -> sc.getShellDialect()
|
||||
.runScriptCommand(sc, script), type);
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(
|
||||
AppPrefs.get().terminalType().getValue());
|
||||
TerminalLauncher.openDirect(
|
||||
"XPipe Debug",
|
||||
sc -> sc.getShellDialect().runScriptCommand(sc, script),
|
||||
type);
|
||||
});
|
||||
e.consume();
|
||||
})
|
||||
|
|
|
@ -10,8 +10,8 @@ import io.xpipe.core.util.XPipeInstallation;
|
|||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
public class VaultCategory extends AppPrefsCategory {
|
||||
|
@ -39,8 +39,11 @@ public class VaultCategory extends AppPrefsCategory {
|
|||
|
||||
var encryptVault = new SimpleBooleanProperty(prefs.encryptAllVaultData().get());
|
||||
encryptVault.addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue && !AppWindowHelper.showConfirmationAlert(
|
||||
"confirmVaultUnencryptTitle", "confirmVaultUnencryptHeader", "confirmVaultUnencryptContent")) {
|
||||
if (!newValue
|
||||
&& !AppWindowHelper.showConfirmationAlert(
|
||||
"confirmVaultUnencryptTitle",
|
||||
"confirmVaultUnencryptHeader",
|
||||
"confirmVaultUnencryptContent")) {
|
||||
Platform.runLater(() -> {
|
||||
encryptVault.set(true);
|
||||
});
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.xpipe.app.core.window.AppWindowHelper;
|
|||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.ButtonType;
|
||||
|
|
|
@ -3,13 +3,14 @@ package io.xpipe.app.resources;
|
|||
import io.xpipe.app.ext.ContainerImageStore;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper=true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ContainerAutoSystemIcon extends SystemIcon {
|
||||
|
||||
Predicate<String> imageCheck;
|
||||
|
@ -20,7 +21,7 @@ public class ContainerAutoSystemIcon extends SystemIcon {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(ShellControl sc) throws Exception {
|
||||
public boolean isApplicable(ShellControl sc) {
|
||||
var source = sc.getSourceStore();
|
||||
if (source.isEmpty()) {
|
||||
return false;
|
||||
|
|
|
@ -2,11 +2,12 @@ package io.xpipe.app.resources;
|
|||
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper=true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FileAutoSystemIcon extends SystemIcon {
|
||||
|
||||
OsType.Any osType;
|
||||
|
@ -29,7 +30,7 @@ public class FileAutoSystemIcon extends SystemIcon {
|
|||
return false;
|
||||
}
|
||||
|
||||
return sc.getShellDialect().createFileExistsCommand(sc, abs.get()).executeAndCheck() ||
|
||||
sc.getShellDialect().directoryExists(sc, abs.get()).executeAndCheck();
|
||||
return sc.getShellDialect().createFileExistsCommand(sc, abs.get()).executeAndCheck()
|
||||
|| sc.getShellDialect().directoryExists(sc, abs.get()).executeAndCheck();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,18 @@ package io.xpipe.app.resources;
|
|||
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper=true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ShellAutoSystemIcon extends SystemIcon {
|
||||
|
||||
FailableFunction<ShellControl, Boolean, Exception> applicable;
|
||||
|
||||
public ShellAutoSystemIcon(String iconName, String displayName, FailableFunction<ShellControl, Boolean, Exception> applicable) {
|
||||
public ShellAutoSystemIcon(
|
||||
String iconName, String displayName, FailableFunction<ShellControl, Boolean, Exception> applicable) {
|
||||
super(iconName, displayName);
|
||||
this.applicable = applicable;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.resources;
|
|||
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.xpipe.core.process.ShellDialects;
|
|||
import io.xpipe.core.process.ShellStoreState;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.StatefulDataStore;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
@ -21,22 +22,21 @@ public class SystemIcons {
|
|||
new SystemIcon("opnsense", "opnsense") {
|
||||
@Override
|
||||
public boolean isApplicable(DataStore store) {
|
||||
return store instanceof StatefulDataStore<?> statefulDataStore &&
|
||||
statefulDataStore.getState() instanceof ShellStoreState shellStoreState &&
|
||||
shellStoreState.getShellDialect() == ShellDialects.OPNSENSE;
|
||||
return store instanceof StatefulDataStore<?> statefulDataStore
|
||||
&& statefulDataStore.getState() instanceof ShellStoreState shellStoreState
|
||||
&& shellStoreState.getShellDialect() == ShellDialects.OPNSENSE;
|
||||
}
|
||||
},
|
||||
new SystemIcon("pfsense", "pfsense") {
|
||||
new SystemIcon("pfsense", "pfsense") {
|
||||
@Override
|
||||
public boolean isApplicable(DataStore store) {
|
||||
return store instanceof StatefulDataStore<?> statefulDataStore &&
|
||||
statefulDataStore.getState() instanceof ShellStoreState shellStoreState &&
|
||||
shellStoreState.getShellDialect() == ShellDialects.PFSENSE;
|
||||
return store instanceof StatefulDataStore<?> statefulDataStore
|
||||
&& statefulDataStore.getState() instanceof ShellStoreState shellStoreState
|
||||
&& shellStoreState.getShellDialect() == ShellDialects.PFSENSE;
|
||||
}
|
||||
},
|
||||
new ContainerAutoSystemIcon("file-browser", "file browser", name -> name.contains("filebrowser")),
|
||||
new FileAutoSystemIcon("syncthing", "syncthing", OsType.LINUX, "~/.local/state/syncthing")
|
||||
);
|
||||
new FileAutoSystemIcon("syncthing", "syncthing", OsType.LINUX, "~/.local/state/syncthing"));
|
||||
|
||||
private static final List<SystemIcon> SYSTEM_ICONS = new ArrayList<>();
|
||||
private static boolean loaded = false;
|
||||
|
@ -56,7 +56,9 @@ public class SystemIcons {
|
|||
continue;
|
||||
}
|
||||
var base = name.replaceAll("-40", "");
|
||||
if (AUTO_SYSTEM_ICONS.stream().anyMatch(autoSystemIcon -> autoSystemIcon.getIconName().equals(base))) {
|
||||
if (AUTO_SYSTEM_ICONS.stream()
|
||||
.anyMatch(autoSystemIcon ->
|
||||
autoSystemIcon.getIconName().equals(base))) {
|
||||
continue;
|
||||
}
|
||||
var displayName = base.replaceAll("-", " ");
|
||||
|
@ -64,7 +66,7 @@ public class SystemIcons {
|
|||
}
|
||||
}
|
||||
});
|
||||
SYSTEM_ICONS.sort(Comparator.<SystemIcon, String>comparing(systemIcon -> systemIcon.getIconName()));
|
||||
SYSTEM_ICONS.sort(Comparator.comparing(systemIcon -> systemIcon.getIconName()));
|
||||
}
|
||||
|
||||
public static synchronized void load() {
|
||||
|
@ -72,7 +74,7 @@ public class SystemIcons {
|
|||
return;
|
||||
}
|
||||
|
||||
AppImages.loadDirectory(AppResources.XPIPE_MODULE,"img/system", true, false);
|
||||
AppImages.loadDirectory(AppResources.XPIPE_MODULE, "img/system", true, false);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.storage;
|
||||
|
||||
import io.xpipe.app.comp.store.StoreSortMode;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
|
@ -8,7 +9,6 @@ import io.xpipe.app.util.FixedHierarchyStore;
|
|||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FixedChildStore;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.store.StorePath;
|
||||
import io.xpipe.core.util.UuidHelper;
|
||||
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
package io.xpipe.app.storage;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.ext.DataStoreProviders;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
|
@ -13,6 +7,13 @@ import io.xpipe.app.resources.SystemIcons;
|
|||
import io.xpipe.app.util.FixedHierarchyStore;
|
||||
import io.xpipe.core.store.*;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.*;
|
||||
import lombok.experimental.NonFinal;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
@ -89,8 +90,7 @@ public class DataStoreEntry extends StorageElement {
|
|||
DataColor color,
|
||||
String notes,
|
||||
Order explicitOrder,
|
||||
String icon
|
||||
) {
|
||||
String icon) {
|
||||
super(directory, uuid, name, lastUsed, lastModified, color, expanded, dirty);
|
||||
this.categoryUuid = categoryUuid;
|
||||
this.store = store;
|
||||
|
@ -113,8 +113,7 @@ public class DataStoreEntry extends StorageElement {
|
|||
Instant lastModified,
|
||||
DataStore store,
|
||||
Order explicitOrder,
|
||||
String icon
|
||||
) {
|
||||
String icon) {
|
||||
super(directory, uuid, name, lastUsed, lastModified, null, false, false);
|
||||
this.categoryUuid = categoryUuid;
|
||||
this.store = store;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package io.xpipe.app.storage;
|
||||
|
||||
import io.xpipe.app.ext.DataStorageExtensionProvider;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
|
@ -176,13 +176,11 @@ public class StandardStorage extends DataStorage {
|
|||
|
||||
storeEntriesSet.forEach(e -> {
|
||||
if (e.getCategoryUuid() == null
|
||||
|| getStoreCategoryIfPresent(e.getCategoryUuid())
|
||||
.isEmpty()) {
|
||||
|| getStoreCategoryIfPresent(e.getCategoryUuid()).isEmpty()) {
|
||||
e.setCategoryUuid(DEFAULT_CATEGORY_UUID);
|
||||
}
|
||||
|
||||
if (e.getCategoryUuid() != null
|
||||
&& e.getCategoryUuid().equals(ALL_CONNECTIONS_CATEGORY_UUID)) {
|
||||
if (e.getCategoryUuid() != null && e.getCategoryUuid().equals(ALL_CONNECTIONS_CATEGORY_UUID)) {
|
||||
e.setCategoryUuid(DEFAULT_CATEGORY_UUID);
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,6 @@ public abstract class StorageElement {
|
|||
notifyUpdate(false, false);
|
||||
}
|
||||
|
||||
|
||||
public void setLastUsed(Instant lastUsed) {
|
||||
if (lastUsed.equals(this.lastUsed)) {
|
||||
return;
|
||||
|
|
|
@ -13,9 +13,11 @@ import io.xpipe.app.util.*;
|
|||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonBar;
|
||||
import javafx.scene.control.ButtonType;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
@ -275,10 +277,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
var rawCommand = command.buildSimple();
|
||||
var script = ScriptHelper.getExecScriptFile(sc, "sh");
|
||||
Files.writeString(Path.of(script.toString()), rawCommand);
|
||||
var fixedFile = script
|
||||
.toString()
|
||||
.replaceAll("\\\\", "/")
|
||||
.replaceAll("\\s", "\\$0");
|
||||
var fixedFile = script.toString().replaceAll("\\\\", "/").replaceAll("\\s", "\\$0");
|
||||
sc.command(CommandBuilder.of()
|
||||
.addFile(file.toString())
|
||||
.add("-newtab")
|
||||
|
@ -1032,8 +1031,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
DEEPIN_TERMINAL,
|
||||
FOOT,
|
||||
Q_TERMINAL,
|
||||
TERMIUS
|
||||
);
|
||||
TERMIUS);
|
||||
List<ExternalTerminalType> MACOS_TERMINALS = List.of(
|
||||
WARP,
|
||||
ITERM2,
|
||||
|
|
|
@ -124,12 +124,13 @@ public interface WezTerminalType extends ExternalTerminalType {
|
|||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
try (var sc = LocalShell.getShell()) {
|
||||
var path = sc.command(String.format(
|
||||
var pathOut = sc.command(String.format(
|
||||
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
|
||||
applicationName))
|
||||
.readStdoutOrThrow();
|
||||
var path = Path.of(pathOut);
|
||||
var spawn = sc.command(CommandBuilder.of()
|
||||
.addFile(Path.of(path)
|
||||
.addFile(path
|
||||
.resolve("Contents")
|
||||
.resolve("MacOS")
|
||||
.resolve("wezterm")
|
||||
|
@ -139,7 +140,7 @@ public interface WezTerminalType extends ExternalTerminalType {
|
|||
.executeAndCheck();
|
||||
if (!spawn) {
|
||||
ExternalApplicationHelper.startAsync(CommandBuilder.of()
|
||||
.addFile(Path.of(path)
|
||||
.addFile(path
|
||||
.resolve("Contents")
|
||||
.resolve("MacOS")
|
||||
.resolve("wezterm-gui")
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.update;
|
|||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.util.LocalShell;
|
||||
|
@ -12,7 +13,6 @@ import io.xpipe.app.util.ThreadHelper;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
|
@ -165,7 +165,8 @@ public class AppInstaller {
|
|||
|
||||
runAndClose(() -> {
|
||||
// We can't use the SSH bridge
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue());
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(
|
||||
AppPrefs.get().terminalType().getValue());
|
||||
TerminalLauncher.openDirect("XPipe Updater", sc -> command, type);
|
||||
});
|
||||
}
|
||||
|
@ -205,7 +206,8 @@ public class AppInstaller {
|
|||
|
||||
runAndClose(() -> {
|
||||
// We can't use the SSH bridge
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue());
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(
|
||||
AppPrefs.get().terminalType().getValue());
|
||||
TerminalLauncher.openDirect("XPipe Updater", sc -> command, type);
|
||||
});
|
||||
}
|
||||
|
@ -245,7 +247,8 @@ public class AppInstaller {
|
|||
|
||||
runAndClose(() -> {
|
||||
// We can't use the SSH bridge
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(AppPrefs.get().terminalType().getValue());
|
||||
var type = ExternalTerminalType.determineNonSshBridgeFallback(
|
||||
AppPrefs.get().terminalType().getValue());
|
||||
TerminalLauncher.openDirect("XPipe Updater", sc -> command, type);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.update;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.fxcomps.impl.CodeSnippet;
|
||||
import io.xpipe.app.fxcomps.impl.CodeSnippetComp;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.layout.Region;
|
||||
|
|
|
@ -98,7 +98,9 @@ public enum XPipeDistributionType {
|
|||
return UNKNOWN;
|
||||
}
|
||||
|
||||
if (OsType.getLocal() == OsType.LINUX && "/config".equals(System.getProperty("user.home")) && Files.isDirectory(Path.of("/kclient"))) {
|
||||
if (OsType.getLocal() == OsType.LINUX
|
||||
&& "/config".equals(System.getProperty("user.home"))
|
||||
&& Files.isDirectory(Path.of("/kclient"))) {
|
||||
return WEBTOP;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.util.EncryptedSecretValue;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
|
|
@ -72,7 +72,10 @@ public class DesktopHelper {
|
|||
}
|
||||
|
||||
var file = new FilePath(path);
|
||||
sc.command(CommandBuilder.of().add("xdg-open").addFile(kind == FileKind.DIRECTORY ? file : file.getParent())).execute();
|
||||
sc.command(CommandBuilder.of()
|
||||
.add("xdg-open")
|
||||
.addFile(kind == FileKind.DIRECTORY ? file : file.getParent()))
|
||||
.execute();
|
||||
}
|
||||
case OsType.MacOs macOs -> {
|
||||
sc.executeSimpleCommand("open " + (kind == FileKind.DIRECTORY ? "" : "-R ") + d.fileArgument(path));
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
|
|
|
@ -58,7 +58,9 @@ public final class HumanReadableFormat {
|
|||
|
||||
// not this year
|
||||
if (x.getYear() != now.getYear()) {
|
||||
return DAY_MONTH_YEAR.withLocale(AppI18n.get().getLoaded().getLocale()).format(x);
|
||||
return DAY_MONTH_YEAR
|
||||
.withLocale(AppI18n.get().getLoaded().getLocale())
|
||||
.format(x);
|
||||
}
|
||||
|
||||
// not this week
|
||||
|
|
|
@ -137,26 +137,21 @@ public enum PlatformState {
|
|||
try {
|
||||
latch.await();
|
||||
PlatformState.setCurrent(PlatformState.RUNNING);
|
||||
return;
|
||||
} catch (InterruptedException e) {
|
||||
lastError = e;
|
||||
return;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Check if we already exited
|
||||
if ("Platform.exit has been called".equals(t.getMessage())) {
|
||||
PlatformState.setCurrent(PlatformState.EXITED);
|
||||
lastError = t;
|
||||
return;
|
||||
} else if ("Toolkit already initialized".equals(t.getMessage())) {
|
||||
PlatformState.setCurrent(PlatformState.RUNNING);
|
||||
return;
|
||||
} else {
|
||||
// Platform initialization has failed in this case
|
||||
PlatformState.setCurrent(PlatformState.EXITED);
|
||||
TrackEvent.error(t.getMessage());
|
||||
lastError = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import io.xpipe.core.process.ShellControl;
|
|||
import io.xpipe.core.process.ShellStoreState;
|
||||
import io.xpipe.core.process.ShellTtyState;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
||||
import io.xpipe.core.store.ShellValidationContext;
|
||||
import io.xpipe.core.store.ValidationContext;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -50,35 +50,38 @@ public class ScanAlert {
|
|||
}
|
||||
|
||||
public static void showForShellStore(DataStoreEntry initial, ShellValidationContext context) {
|
||||
show(initial, (DataStoreEntry entry, ShellControl sc) -> {
|
||||
if (!sc.canHaveSubshells()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!sc.getShellDialect().getDumbMode().supportsAnyPossibleInteraction()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sc.getTtyState() != ShellTtyState.NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var providers = ScanProvider.getAll();
|
||||
var applicable = new ArrayList<ScanProvider.ScanOperation>();
|
||||
for (ScanProvider scanProvider : providers) {
|
||||
try {
|
||||
// Previous scan operation could have exited the shell
|
||||
sc.start();
|
||||
ScanProvider.ScanOperation operation = scanProvider.create(entry, sc);
|
||||
if (operation != null) {
|
||||
applicable.add(operation);
|
||||
show(
|
||||
initial,
|
||||
(DataStoreEntry entry, ShellControl sc) -> {
|
||||
if (!sc.canHaveSubshells()) {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
}
|
||||
}
|
||||
return applicable;
|
||||
}, context);
|
||||
|
||||
if (!sc.getShellDialect().getDumbMode().supportsAnyPossibleInteraction()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sc.getTtyState() != ShellTtyState.NONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var providers = ScanProvider.getAll();
|
||||
var applicable = new ArrayList<ScanProvider.ScanOperation>();
|
||||
for (ScanProvider scanProvider : providers) {
|
||||
try {
|
||||
// Previous scan operation could have exited the shell
|
||||
sc.start();
|
||||
ScanProvider.ScanOperation operation = scanProvider.create(entry, sc);
|
||||
if (operation != null) {
|
||||
applicable.add(operation);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
}
|
||||
}
|
||||
return applicable;
|
||||
},
|
||||
context);
|
||||
}
|
||||
|
||||
private static void show(
|
||||
|
@ -87,7 +90,8 @@ public class ScanAlert {
|
|||
ShellValidationContext shellValidationContext) {
|
||||
DialogComp.showWindow(
|
||||
"scanAlertTitle",
|
||||
stage -> new Dialog(stage, initialStore != null ? initialStore.ref() : null, applicable, shellValidationContext));
|
||||
stage -> new Dialog(
|
||||
stage, initialStore != null ? initialStore.ref() : null, applicable, shellValidationContext));
|
||||
}
|
||||
|
||||
private static class Dialog extends DialogComp {
|
||||
|
@ -104,8 +108,8 @@ public class ScanAlert {
|
|||
private Dialog(
|
||||
Stage window,
|
||||
DataStoreEntryRef<ShellStore> entry,
|
||||
BiFunction<DataStoreEntry, ShellControl, List<ScanProvider.ScanOperation>> applicable, ShellValidationContext shellValidationContext
|
||||
) {
|
||||
BiFunction<DataStoreEntry, ShellControl, List<ScanProvider.ScanOperation>> applicable,
|
||||
ShellValidationContext shellValidationContext) {
|
||||
this.window = window;
|
||||
this.initialStore = entry;
|
||||
this.entry = new SimpleObjectProperty<>(entry);
|
||||
|
@ -206,7 +210,10 @@ public class ScanAlert {
|
|||
shellValidationContext = null;
|
||||
}
|
||||
|
||||
shellValidationContext = new ShellValidationContext(newValue.getStore().control().withoutLicenseCheck().start());
|
||||
shellValidationContext = new ShellValidationContext(newValue.getStore()
|
||||
.control()
|
||||
.withoutLicenseCheck()
|
||||
.start());
|
||||
var a = applicable.apply(entry.get().get(), shellValidationContext.get());
|
||||
|
||||
Platform.runLater(() -> {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.DataStoreSecret;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.util.InPlaceSecretValue;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
|
|
|
@ -121,7 +121,6 @@ public class SecretRetrievalStrategyHelper {
|
|||
case 2 -> passwordManager;
|
||||
case 3 -> customCommand;
|
||||
case 4 -> new SimpleObjectProperty<>(new SecretRetrievalStrategy.Prompt());
|
||||
case 5 -> new SimpleObjectProperty<>();
|
||||
default -> new SimpleObjectProperty<>();
|
||||
};
|
||||
},
|
||||
|
|
|
@ -63,7 +63,8 @@ public class ShellTemp {
|
|||
var systemTemp = proc.getSystemTemporaryDirectory();
|
||||
if (!d.directoryExists(proc, systemTemp.toString()).executeAndCheck()
|
||||
|| !checkDirectoryPermissions(proc, systemTemp.toString())) {
|
||||
throw ErrorEvent.expected(new IOException("No permissions to access system temporary directory %s".formatted(systemTemp)));
|
||||
throw ErrorEvent.expected(
|
||||
new IOException("No permissions to access system temporary directory %s".formatted(systemTemp)));
|
||||
}
|
||||
|
||||
// We don't do this anymore, we hope that all the legacy directories have been cleared now
|
||||
|
|
|
@ -2,10 +2,10 @@ package io.xpipe.app.util;
|
|||
|
||||
import io.xpipe.app.beacon.AppBeaconServer;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
|
@ -180,7 +180,8 @@ public class SshLocalBridge {
|
|||
} else {
|
||||
var exec = sc.command(sc.getShellDialect().getWhichCommand("sshd")).readStdoutIfPossible();
|
||||
if (exec.isEmpty()) {
|
||||
throw ErrorEvent.expected(new IllegalStateException("No sshd executable found in PATH. The SSH terminal bridge requires a local ssh server"));
|
||||
throw ErrorEvent.expected(new IllegalStateException(
|
||||
"No sshd executable found in PATH. The SSH terminal bridge requires a local ssh server"));
|
||||
}
|
||||
return exec.get().lines().findFirst().orElseThrow();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ public class TerminalLauncher {
|
|||
openDirect(title, command, type);
|
||||
}
|
||||
|
||||
public static void openDirect(String title, FailableFunction<ShellControl, String, Exception> command, ExternalTerminalType type)
|
||||
public static void openDirect(
|
||||
String title, FailableFunction<ShellControl, String, Exception> command, ExternalTerminalType type)
|
||||
throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
var script = ScriptHelper.constructTerminalInitFile(
|
||||
|
|
|
@ -75,7 +75,10 @@ public class TerminalLauncherManager {
|
|||
public static Path waitForNextLaunch() throws BeaconClientException, BeaconServerException {
|
||||
Entry first;
|
||||
synchronized (entries) {
|
||||
first = entries.values().stream().filter(entry -> !entry.isLaunched()).findFirst().orElse(null);
|
||||
first = entries.values().stream()
|
||||
.filter(entry -> !entry.isLaunched())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (first == null) {
|
||||
throw new BeaconClientException("Unknown launch request");
|
||||
}
|
||||
|
@ -116,7 +119,10 @@ public class TerminalLauncherManager {
|
|||
|
||||
public static Path performLaunch(UUID request) throws BeaconClientException {
|
||||
synchronized (entries) {
|
||||
var e = entries.values().stream().filter(entry -> entry.getRequest().equals(request)).findFirst().orElse(null);
|
||||
var e = entries.values().stream()
|
||||
.filter(entry -> entry.getRequest().equals(request))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (e == null) {
|
||||
throw new BeaconClientException("Unknown launch request " + request);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import com.fasterxml.jackson.databind.Module;
|
||||
import io.xpipe.app.beacon.impl.*;
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
|
@ -13,6 +12,8 @@ import io.xpipe.beacon.BeaconInterface;
|
|||
import io.xpipe.core.util.DataStateProvider;
|
||||
import io.xpipe.core.util.ModuleLayerLoader;
|
||||
import io.xpipe.core.util.ProxyFunction;
|
||||
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import org.slf4j.spi.SLF4JServiceProvider;
|
||||
|
||||
open module io.xpipe.app {
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
-fx-text-fill: #ee4829;
|
||||
}
|
||||
|
||||
.store-entry-grid:incomplete .name {
|
||||
-fx-text-fill: #ee4829;
|
||||
.root:dark .store-entry-grid:incomplete .name {
|
||||
-fx-text-fill: #b2271a;
|
||||
}
|
||||
|
||||
.root:light .store-entry-grid:incomplete .name {
|
||||
-fx-text-fill: #981400;
|
||||
}
|
||||
|
||||
.store-entry-grid:incomplete .icon {
|
||||
|
|
|
@ -21,6 +21,8 @@ public class ShellEnvironmentStoreState extends ShellStoreState {
|
|||
var n = (ShellEnvironmentStoreState) newer;
|
||||
var b = toBuilder();
|
||||
mergeBuilder(n, b);
|
||||
return b.shellName(useNewer(shellName, n.shellName)).setDefault(useNewer(setDefault,n.setDefault)).build();
|
||||
return b.shellName(useNewer(shellName, n.shellName))
|
||||
.setDefault(useNewer(setDefault, n.setDefault))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
|||
try {
|
||||
var list = new ArrayList<FileEntry>();
|
||||
list.add(fileEntry);
|
||||
list.addAll(listFilesRecursively(fileEntry.getPath().toString()));
|
||||
list.addAll(listFilesRecursively(fileEntry.getPath()));
|
||||
return list.stream();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
|
@ -17,6 +18,7 @@ public class ShellValidationContext implements ValidationContext<ShellControl> {
|
|||
public void close() {
|
||||
try {
|
||||
shellControl.close();
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import io.xpipe.core.dialog.BaseQueryElement;
|
||||
import io.xpipe.core.dialog.BusyElement;
|
||||
import io.xpipe.core.dialog.ChoiceElement;
|
||||
|
@ -18,6 +10,15 @@ import io.xpipe.core.process.ShellDialects;
|
|||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.StorePath;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
|
|
|
@ -55,7 +55,8 @@ public class BrowseStoreAction implements ActionProvider {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
DataStoreEntryRef<FileSystemStore> replacement = ProcessControlProvider.get().replace(entry.ref());
|
||||
DataStoreEntryRef<FileSystemStore> replacement =
|
||||
ProcessControlProvider.get().replace(entry.ref());
|
||||
BrowserSessionModel.DEFAULT.openFileSystemAsync(replacement, null, new SimpleBooleanProperty());
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,10 @@ import io.xpipe.app.ext.ActionProvider;
|
|||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
public class ChangeStoreIconAction implements ActionProvider {
|
||||
|
|
|
@ -6,7 +6,9 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.time.Duration;
|
||||
|
|
|
@ -2,13 +2,13 @@ package io.xpipe.ext.base.action;
|
|||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.process.CommandControl;
|
||||
import io.xpipe.core.process.ElevationFunction;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
|
|
@ -10,8 +10,8 @@ import io.xpipe.core.process.OsType;
|
|||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
|
@ -59,7 +59,13 @@ public class OpenNativeFileDetailsAction implements LeafAction {
|
|||
}
|
||||
|
||||
var file = new FilePath(e);
|
||||
sc.command(CommandBuilder.of().add("xdg-open").addFile(entry.getRawFileEntry().getKind() == FileKind.DIRECTORY ? file : file.getParent())).execute();
|
||||
sc.command(CommandBuilder.of()
|
||||
.add("xdg-open")
|
||||
.addFile(
|
||||
entry.getRawFileEntry().getKind() == FileKind.DIRECTORY
|
||||
? file
|
||||
: file.getParent()))
|
||||
.execute();
|
||||
}
|
||||
case OsType.MacOs macOs -> {
|
||||
sc.osascriptCommand(String.format(
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.ext.ActionProvider;
|
|||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
import io.xpipe.core.process.OsType;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
public class SimpleScriptQuickEditAction implements ActionProvider {
|
||||
|
@ -33,13 +34,9 @@ public class SimpleScriptQuickEditAction implements ActionProvider {
|
|||
var dialect = script.getMinimumDialect();
|
||||
var ext = dialect.getScriptFileEnding();
|
||||
var name = OsType.getLocal().makeFileSystemCompatible(ref.get().getName());
|
||||
FileOpener.openString(
|
||||
name + "." + ext,
|
||||
this,
|
||||
script.getCommands(),
|
||||
(s) -> {
|
||||
ref.get().setStoreInternal(script.toBuilder().commands(s).build(), true);
|
||||
});
|
||||
FileOpener.openString(name + "." + ext, this, script.getCommands(), (s) -> {
|
||||
ref.get().setStoreInternal(script.toBuilder().commands(s).build(), true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import io.xpipe.app.util.TerminalLauncher;
|
|||
import io.xpipe.core.process.ShellStoreState;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
import io.xpipe.ext.base.script.ScriptStore;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
|
@ -32,7 +33,8 @@ public interface ShellStoreProvider extends DataStoreProvider {
|
|||
ShellStore store = replacement.getStore().asNeeded();
|
||||
var control = ScriptStore.controlWithDefaultScripts(store.control());
|
||||
control.onInit(sc -> {
|
||||
if (entry.getStorePersistentState() instanceof ShellStoreState shellStoreState && shellStoreState.getShellDialect() == null) {
|
||||
if (entry.getStorePersistentState() instanceof ShellStoreState shellStoreState
|
||||
&& shellStoreState.getShellDialect() == null) {
|
||||
var found = SystemIcons.detectForSystem(sc);
|
||||
if (found.isPresent()) {
|
||||
entry.setIcon(found.get().getIconName(), false);
|
||||
|
@ -42,7 +44,8 @@ public interface ShellStoreProvider extends DataStoreProvider {
|
|||
TerminalLauncher.open(
|
||||
replacement.get(),
|
||||
DataStorage.get().getStoreEntryDisplayName(replacement.get()),
|
||||
null, control);
|
||||
null,
|
||||
control);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue