Various sftp improvements

This commit is contained in:
crschnick
2025-11-19 15:49:57 +00:00
parent 28a72bd9b4
commit 8b486c8d84
4 changed files with 63 additions and 46 deletions
@@ -302,25 +302,28 @@ public class BrowserFileListCompEntry {
.setValue(item == null || item.getRawFileEntry().getKind() != FileKind.DIRECTORY);
model.getDraggedOverDirectory().setValue(item);
if (item != null) {
var timestamp = Instant.now();
lastHoverUpdate = timestamp;
// Reduce printed window updates
GlobalTimer.delay(
() -> {
if (!timestamp.equals(lastHoverUpdate)) {
return;
}
if (item != model.getDraggedOverDirectory().getValue()) {
return;
}
model.getFileSystemModel()
.cdAsync(item.getRawFileEntry().getPath());
},
Duration.ofMillis(500));
if (item == null || item.getRawFileEntry().getKind() != FileKind.DIRECTORY) {
return;
}
var timestamp = Instant.now();
lastHoverUpdate = timestamp;
// Reduce printed window updates
GlobalTimer.delay(
() -> {
if (!timestamp.equals(lastHoverUpdate)) {
return;
}
if (item != model.getDraggedOverDirectory().getValue()) {
return;
}
model.getFileSystemModel()
.cdAsync(item.getRawFileEntry().getPath());
},
Duration.ofMillis(500));
}
public void onDragOver(DragEvent event) {
@@ -10,6 +10,7 @@ import io.xpipe.app.issue.ErrorEventFactory;
import io.xpipe.app.platform.DerivedObservableList;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.FilePath;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
@@ -46,22 +47,22 @@ public class BrowserOverviewComp extends SimpleComp {
var commonPlatform = FXCollections.<FileEntry>synchronizedObservableList(FXCollections.observableArrayList());
ThreadHelper.runFailableAsync(() -> {
var common = model.getFileSystem().listCommonDirectories().stream()
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
.filter(entry -> {
var fs = model.getFileSystem();
try {
return fs.directoryExists(entry.getPath());
} catch (Exception e) {
ErrorEventFactory.fromThrowable(e).handle();
return false;
}
})
.toList();
Platform.runLater(() -> {
commonPlatform.setAll(common);
});
try {
var all = new ArrayList<FileEntry>();
for (FilePath cd : model.getFileSystem().listCommonDirectories()) {
var entry = FileEntry.ofDirectory(model.getFileSystem(), cd);
var fs = model.getFileSystem();
if (fs.directoryExists(entry.getPath())) {
all.add(entry);
}
}
Platform.runLater(() -> {
commonPlatform.setAll(all);
});
} catch (Exception e) {
// The file system can die
ErrorEventFactory.fromThrowable(e).expected().omit().handle();
}
});
var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false);
var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview, false)
@@ -12,6 +12,8 @@ import io.xpipe.core.OsType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
@@ -232,7 +234,7 @@ public class ConnectionFileSystem implements FileSystem {
@Override
public InputStream openInput(FilePath file) throws Exception {
if (shellControl.isLocal()) {
return Files.newInputStream(file.asLocalPath());
return new BufferedInputStream(Files.newInputStream(file.asLocalPath()));
}
return shellControl
@@ -244,7 +246,7 @@ public class ConnectionFileSystem implements FileSystem {
@Override
public OutputStream openOutput(FilePath file, long totalBytes) throws Exception {
if (shellControl.isLocal()) {
return Files.newOutputStream(file.asLocalPath());
return new BufferedOutputStream(Files.newOutputStream(file.asLocalPath()));
}
var cmd =
@@ -12,6 +12,7 @@ import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageListener;
import io.xpipe.app.util.ThreadHelper;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
@@ -228,21 +229,31 @@ public class StoreViewState {
}
private void initFilterListener() {
var all = getAllConnectionsCategory();
filter.addListener((observable, oldValue, newValue) -> {
categories.getList().forEach(e -> e.update());
var matchingCats = categories.getList().stream()
.filter(storeCategoryWrapper ->
storeCategoryWrapper.getRoot().equals(all))
.filter(storeCategoryWrapper -> storeCategoryWrapper.getDirectContainedEntries().getList().stream()
.anyMatch(wrapper -> wrapper.matchesFilter(newValue)))
.toList();
if (matchingCats.size() == 1) {
activeCategory.setValue(matchingCats.getFirst());
}
ThreadHelper.runAsync(() -> {
onFilterUpdate(newValue);
});
});
}
private void onFilterUpdate(String newValue) {
var all = getAllConnectionsCategory();
categories.getList().forEach(e -> {
Platform.runLater(() -> {
e.update();
});
});
var matchingCats = categories.getList().stream()
.filter(storeCategoryWrapper ->
storeCategoryWrapper.getRoot().equals(all))
.filter(storeCategoryWrapper -> storeCategoryWrapper.getDirectContainedEntries().getList().stream()
.anyMatch(wrapper -> wrapper.matchesFilter(newValue)))
.toList();
if (matchingCats.size() == 1) {
activeCategory.setValue(matchingCats.getFirst());
}
}
private void initBatchListeners() {
batchModeSelection.getList().addListener((ListChangeListener<? super StoreEntryWrapper>) c -> {
if (c.getList().isEmpty()) {