This commit is contained in:
crschnick
2025-08-26 15:34:58 +00:00
parent 961d10bf71
commit 7fc7e6a096
27 changed files with 88 additions and 84 deletions
@@ -55,8 +55,9 @@ public class BrowserFileChooserSessionComp extends ModalOverlayContentComp {
model.setOnFinish(fileStores -> {
file.accept(fileStores.size() > 0 ? fileStores.getFirst() : null);
});
var comp =
new BrowserFileChooserSessionComp(model, filter).styleClass("browser").styleClass("chooser");
var comp = new BrowserFileChooserSessionComp(model, filter)
.styleClass("browser")
.styleClass("chooser");
var selection = new SimpleStringProperty();
model.getFileSelection().addListener((ListChangeListener<? super BrowserEntry>) c -> {
selection.set(
@@ -90,7 +91,8 @@ public class BrowserFileChooserSessionComp extends ModalOverlayContentComp {
protected Region createSimple() {
Predicate<StoreEntryWrapper> applicable = storeEntryWrapper -> {
return (storeEntryWrapper.getEntry().getStore() instanceof ShellStore)
&& storeEntryWrapper.getEntry().getValidity().isUsable() && filter.test(storeEntryWrapper.getEntry());
&& storeEntryWrapper.getEntry().getValidity().isUsable()
&& filter.test(storeEntryWrapper.getEntry());
};
BiConsumer<StoreEntryWrapper, BooleanProperty> action = (w, busy) -> {
ThreadHelper.runFailableAsync(() -> {
@@ -116,8 +116,10 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
if (!typedSelection.get().isEmpty()) {
var selection = typedSelection.get() + " ";
var found = fileList.getShown().getValue().stream().filter(
browserEntry -> browserEntry.getFileName().toLowerCase().startsWith(selection)).findFirst();
var found = fileList.getShown().getValue().stream()
.filter(browserEntry ->
browserEntry.getFileName().toLowerCase().startsWith(selection))
.findFirst();
// Ugly fix to prevent space from showing the menu when there is a file matching
// Due to the table view input map, these events always get sent and consumed, not allowing us to
// differentiate between these cases
@@ -14,10 +14,8 @@ import io.xpipe.app.util.InputHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.FilePath;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.MenuButton;
@@ -229,19 +227,15 @@ public class BrowserFileSystemTabComp extends SimpleComp {
// Not perfect, but covers most of the cases of small directories
var showOverview = new SimpleBooleanProperty(true);
model.getCurrentPath().subscribe(path -> {
GlobalTimer.delay(() -> {
showOverview.setValue(path == null);
}, Duration.ofMillis(250));
GlobalTimer.delay(
() -> {
showOverview.setValue(path == null);
},
Duration.ofMillis(250));
});
var home = new BrowserOverviewComp(model).styleClass("browser-overview");
var stack = new MultiContentComp(
Map.of(
home,
showOverview,
fileList,
showOverview.not()),
false);
var stack = new MultiContentComp(Map.of(home, showOverview, fileList, showOverview.not()), false);
var r = stack.styleClass("browser-content-container").createRegion();
r.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
@@ -29,8 +29,8 @@ import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.SelectionMode;
import lombok.Getter;
import lombok.NonNull;
@@ -236,7 +236,9 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
all.addAll(entries);
for (BrowserEntry browserEntry : fileList.getAll().getValue()) {
var fe = browserEntry.getRawFileEntry();
if (fe.getKind() == FileKind.LINK && entries.stream().anyMatch(o -> o.getPath().equals(fe.resolved().getPath()))) {
if (fe.getKind() == FileKind.LINK
&& entries.stream()
.anyMatch(o -> o.getPath().equals(fe.resolved().getPath()))) {
all.add(fe);
}
}
@@ -312,11 +312,7 @@ public class BrowserFileTransferOperation {
return false;
}
var rel = fileEntry
.getPath()
.relativize(baseRelative)
.toUnix()
.toString();
var rel = fileEntry.getPath().relativize(baseRelative).toUnix().toString();
flatFiles.put(fileEntry, rel);
if (fileEntry.getKind() == FileKind.FILE) {
// This one is up-to-date and does not need to be recalculated
@@ -333,11 +329,7 @@ public class BrowserFileTransferOperation {
return;
}
var rel = fileEntry
.getPath()
.relativize(baseRelative)
.toUnix()
.toString();
var rel = fileEntry.getPath().relativize(baseRelative).toUnix().toString();
flatFiles.put(fileEntry, rel);
if (fileEntry.getKind() == FileKind.FILE) {
// This one is up-to-date and does not need to be recalculated
@@ -12,7 +12,6 @@ import io.xpipe.core.FileKind;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
@@ -32,9 +32,7 @@ public class TarActionProvider implements BrowserActionProvider {
public void executeImpl() throws Exception {
var sc = model.getFileSystem().getShell().orElseThrow();
var args = "c" + (gz ? "z" : "") + "f";
var tar = CommandBuilder.of()
.add("tar", args)
.addFile(target);
var tar = CommandBuilder.of().add("tar", args).addFile(target);
var base = model.getCurrentDirectory().getPath();
if (directoryContentOnly) {
@@ -8,7 +8,6 @@ import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.window.AppDialog;
import io.xpipe.app.ext.FileSystemStore;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.hub.comp.StoreEntryWrapper;
import io.xpipe.app.issue.ErrorEventFactory;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.ContextualFileReference;
@@ -55,8 +54,8 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
Property<DataStoreEntryRef<T>> fileSystem,
Property<FilePath> filePath,
ContextualFileReferenceSync sync,
List<PreviousFileReference> previousFileReferences, Predicate<DataStoreEntry> filter
) {
List<PreviousFileReference> previousFileReferences,
Predicate<DataStoreEntry> filter) {
this.sync = sync;
this.previousFileReferences = previousFileReferences;
this.filter = filter;
@@ -5,7 +5,6 @@ import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.ext.StatefulDataStore;
import io.xpipe.app.process.ShellScript;
import io.xpipe.app.process.ShellStoreState;
import io.xpipe.app.process.SystemState;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.FileOpener;
@@ -10,7 +10,6 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -58,7 +57,8 @@ public interface FileSystem extends Closeable, AutoCloseable {
return all;
}
default void traverseFilesRecursively(FileSystem system, FilePath file, Predicate<FileEntry> visitor) throws Exception {
default void traverseFilesRecursively(FileSystem system, FilePath file, Predicate<FileEntry> visitor)
throws Exception {
List<FileEntry> base;
try (var filesStream = listFiles(system, file)) {
base = filesStream.toList();
@@ -4,8 +4,8 @@ import io.xpipe.app.util.OptionsBuilder;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import lombok.Builder;
import lombok.Value;
@@ -35,7 +35,9 @@ public class HostAddressChoice {
} else {
options.name(translationKey);
}
options.addComp(new HostAddressChoiceComp(val, list, allowMutation)).addProperty(val).addProperty(sizeProp);
options.addComp(new HostAddressChoiceComp(val, list, allowMutation))
.addProperty(val)
.addProperty(sizeProp);
options.bind(
() -> {
var fullList = new ArrayList<>(list);
@@ -49,8 +49,6 @@ public class CloneHubLeafProvider implements HubLeafProvider<DataStore> {
return "cloneStore";
}
@Jacksonized
@SuperBuilder
public static class Action extends StoreAction<DataStore> {
@@ -6,8 +6,8 @@ import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.core.AppResources;
import io.xpipe.app.process.SystemState;
import io.xpipe.core.FilePath;
import io.xpipe.core.OsType;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.Region;
@@ -5,7 +5,6 @@ import io.xpipe.app.comp.base.ChoiceComp;
import io.xpipe.app.comp.base.ModalButton;
import io.xpipe.app.comp.base.ModalOverlay;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppTheme;
import io.xpipe.app.ext.DataStore;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategoryConfig;
@@ -14,19 +13,14 @@ import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.OptionsBuilder;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ListCell;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import lombok.AllArgsConstructor;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.function.Supplier;
@@ -211,7 +211,9 @@ public class StoreEntryWrapper {
if (storeChanged || !information.isBound()) {
information.unbind();
shownInformation.unbind();
if (entry.getValidity().isUsable() || (entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED && entry.getProvider().showIncompleteInfo())) {
if (entry.getValidity().isUsable()
|| (entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED
&& entry.getProvider().showIncompleteInfo())) {
var section = StoreViewState.get().getSectionForWrapper(this);
if (section.isPresent()) {
try {
@@ -220,7 +222,9 @@ public class StoreEntryWrapper {
shownInformation.bind(Bindings.createStringBinding(
() -> {
// Might have changed validity meanwhile
var showInfo = entry.getValidity().isUsable() || (entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED && entry.getProvider().showIncompleteInfo());
var showInfo = entry.getValidity().isUsable()
|| (entry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED
&& entry.getProvider().showIncompleteInfo());
if (!showInfo) {
return null;
}
@@ -666,9 +666,9 @@ public final class AppPrefs {
if (OsType.getLocal() == OsType.MACOS
&& AppProperties.get()
.getCanonicalVersion()
.map(appVersion -> appVersion.getMajor() == 18)
.orElse(false)) {
.getCanonicalVersion()
.map(appVersion -> appVersion.getMajor() == 18)
.orElse(false)) {
useSystemFont.set(false);
}
@@ -3,7 +3,6 @@ package io.xpipe.app.prefs;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.ContextualFileReferenceChoiceComp;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.OptionsBuilder;
@@ -42,7 +41,7 @@ public class FileBrowserCategory extends AppPrefsCategory {
prefs.downloadsDirectory,
null,
List.of(),
e -> e.equals(DataStorage.get().local()))
e -> e.equals(DataStorage.get().local()))
.maxWidth(getCompWidth()),
prefs.downloadsDirectory)
.pref(prefs.pinLocalMachineOnStartup)
@@ -122,7 +122,7 @@ public class IconsCategory extends AppPrefsCategory {
dir,
null,
List.of(),
en -> en.equals(DataStorage.get().local()))
en -> en.equals(DataStorage.get().local()))
.prefWidth(350));
modal.withDefaultButtons(() -> {
if (dir.get() == null) {
@@ -10,11 +10,9 @@ import io.xpipe.app.terminal.TerminalLaunch;
import io.xpipe.app.util.*;
import io.xpipe.core.InPlaceSecretValue;
import io.xpipe.core.JacksonMapper;
import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.core.OsType;
import java.nio.file.Files;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeName("bitwarden")
public class BitwardenPasswordManager implements PasswordManager {
@@ -28,7 +26,10 @@ public class BitwardenPasswordManager implements PasswordManager {
if (moveAppDir()) {
SHELL.view().unsetEnvironmentVariable("BW_SESSION");
SHELL.view().setEnvironmentVariable("BITWARDENCLI_APPDATA_DIR", AppCache.getBasePath().toString());
SHELL.view()
.setEnvironmentVariable(
"BITWARDENCLI_APPDATA_DIR",
AppCache.getBasePath().toString());
}
}
SHELL.start();
@@ -37,7 +38,9 @@ public class BitwardenPasswordManager implements PasswordManager {
private static boolean moveAppDir() throws Exception {
var path = SHELL.view().findProgram("bw");
return OsType.getLocal() != OsType.LINUX || path.isEmpty() || !path.get().toString().contains("snap");
return OsType.getLocal() != OsType.LINUX
|| path.isEmpty()
|| !path.get().toString().contains("snap");
}
@Override
@@ -58,10 +61,12 @@ public class BitwardenPasswordManager implements PasswordManager {
// Check for data file as bw seemingly breaks if it doesn't exist yet
if (r[1].contains("You are not logged in")) {
var script = ShellScript.lines(
moveAppDir() ? LocalShell.getDialect()
.getSetEnvironmentVariableCommand(
"BITWARDENCLI_APPDATA_DIR",
AppCache.getBasePath().toString()) : null,
moveAppDir()
? LocalShell.getDialect()
.getSetEnvironmentVariableCommand(
"BITWARDENCLI_APPDATA_DIR",
AppCache.getBasePath().toString())
: null,
sc.getShellDialect().getEchoCommand("Log in into your Bitwarden account from the CLI:", false),
"bw login --quiet",
sc.getShellDialect()
@@ -52,7 +52,10 @@ public class EnpassPasswordManager implements PasswordManager {
public static OptionsBuilder createOptions(Property<EnpassPasswordManager> p) {
var prop = new SimpleObjectProperty<>(p.getValue().getVaultPath());
var comp = new ContextualFileReferenceChoiceComp(
new SimpleObjectProperty<>(DataStorage.get().local().ref()), prop, null, List.of(),
new SimpleObjectProperty<>(DataStorage.get().local().ref()),
prop,
null,
List.of(),
e -> e.equals(DataStorage.get().local()));
comp.apply(struc -> {
var text = (TextField) struc.get().getChildren().getFirst();
@@ -4,9 +4,9 @@ import javafx.scene.Node;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import com.fasterxml.jackson.annotation.JsonProperty;
import javafx.scene.shape.Rectangle;
import lombok.Getter;
import java.util.ArrayList;
@@ -198,9 +198,7 @@ public class TerminalLauncher {
.add("terminal-register", "--request", request.toString())
.buildFull(LocalShell.getShell());
var bellLine = "printf \"\\a\"";
var lines = ShellScript.lines(
registerLine,
OsType.getLocal() != OsType.WINDOWS ? bellLine : null);
var lines = ShellScript.lines(registerLine, OsType.getLocal() != OsType.WINDOWS ? bellLine : null);
return lines.toString();
}
@@ -51,7 +51,10 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm
var spaces = configuration.getScriptFile().toString().contains(" ");
cmd.add(configuration
.getScriptDialect()
.getOpenScriptCommand(spaces ? configuration.getScriptFile().getFileName() : configuration.getScriptFile().toString()));
.getOpenScriptCommand(
spaces
? configuration.getScriptFile().getFileName()
: configuration.getScriptFile().toString()));
return cmd;
}
@@ -138,11 +141,13 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm
if (spaces) {
var wd = sc.view().pwd();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration))).withWorkingDirectory(
configuration.getScriptFile().getParent()).execute();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration)))
.withWorkingDirectory(configuration.getScriptFile().getParent())
.execute();
sc.view().cd(wd);
} else {
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration))).execute();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration)))
.execute();
}
}
}
@@ -197,7 +202,8 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm
.execute();
sc.view().cd(wd);
} else {
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration))).execute();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration)))
.execute();
}
}
}
@@ -248,11 +254,13 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm
if (spaces) {
var wd = sc.view().pwd();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration))).withWorkingDirectory(
configuration.getScriptFile().getParent()).execute();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration)))
.withWorkingDirectory(configuration.getScriptFile().getParent())
.execute();
sc.view().cd(wd);
} else {
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration))).execute();
sc.command(CommandBuilder.of().addFile(exec).add(toCommand(configuration)))
.execute();
}
}
}
@@ -12,7 +12,6 @@ import io.xpipe.app.storage.DataStoreEntryRef;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.beans.value.ObservableBooleanValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
@@ -101,7 +101,10 @@ public class ShellTemp {
"-Force"))
.executeAndCheck();
} else {
sc.command(CommandBuilder.of().add("rm", "-f").add("\"" + prefix.toString() + "\"*").add("2>/dev/null"))
sc.command(CommandBuilder.of()
.add("rm", "-f")
.add("\"" + prefix.toString() + "\"*")
.add("2>/dev/null"))
.executeAndCheck();
}
}
@@ -71,7 +71,10 @@ public class KeyFileStrategy implements SshIdentityStrategy {
.description("locationDescription")
.addComp(
new ContextualFileReferenceChoiceComp(
config.getProxy(), keyPath, config.isAllowKeyFileSync() ? sync : null, List.of(),
config.getProxy(),
keyPath,
config.isAllowKeyFileSync() ? sync : null,
List.of(),
e -> e.equals(DataStorage.get().local())),
keyPath)
.nonNull()
@@ -60,7 +60,8 @@ public class SimpleScriptStore extends ScriptStore implements SelfReferentialSto
shellControl.getShellDialect().getNewLine().getNewLineString()));
var targetType = shellControl.getOriginalShellDialect();
var script = ScriptHelper.createExecScript(targetType, shellControl, fixedCommands);
return targetType.sourceScriptCommand(shellControl, script.toString()) + " " + targetType.getCatchAllVariable();
return targetType.sourceScriptCommand(shellControl, script.toString()) + " "
+ targetType.getCatchAllVariable();
}
return null;