mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
File browser refinements
This commit is contained in:
parent
5845abb481
commit
d0ca3e8a27
7 changed files with 78 additions and 65 deletions
|
@ -44,7 +44,7 @@ final class BookmarkList extends SimpleComp {
|
|||
|
||||
button.setOnAction(event -> {
|
||||
var fileSystem = ((ShellStore) e.getEntry().getStore());
|
||||
model.openFileSystem(fileSystem);
|
||||
model.openFileSystemAsync(fileSystem);
|
||||
event.consume();
|
||||
});
|
||||
GrowAugment.create(true, false).augment(new SimpleCompStructure<>(button));
|
||||
|
|
|
@ -71,14 +71,14 @@ public class FileBrowserModel {
|
|||
if (found.isPresent()) {
|
||||
selected.setValue(found.get());
|
||||
} else {
|
||||
openFileSystem(store);
|
||||
openFileSystemAsync(store);
|
||||
}
|
||||
}
|
||||
|
||||
public void openFileSystem(ShellStore store) {
|
||||
public void openFileSystemAsync(ShellStore store) {
|
||||
// Prevent multiple tabs in non browser modes
|
||||
if (!mode.equals(Mode.BROWSER)) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
var open = openFileSystems.size() > 0 ? openFileSystems.get(0) : null;
|
||||
if (open != null) {
|
||||
open.closeSync();
|
||||
|
@ -88,23 +88,16 @@ public class FileBrowserModel {
|
|||
var model = new OpenFileSystemModel(this);
|
||||
openFileSystems.add(model);
|
||||
selected.setValue(model);
|
||||
model.switchAsync(store);
|
||||
model.switchSync(store);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Duplication protection (Not needed for now)
|
||||
// var found = openFileSystems.stream()
|
||||
// .filter(fileSystemModel -> fileSystemModel.getStore().getValue().equals(store))
|
||||
// .findFirst();
|
||||
// if (found.isPresent()) {
|
||||
// selected.setValue(found.get());
|
||||
// return;
|
||||
// }
|
||||
|
||||
var model = new OpenFileSystemModel(this);
|
||||
openFileSystems.add(model);
|
||||
selected.setValue(model);
|
||||
model.switchAsync(store);
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
var model = new OpenFileSystemModel(this);
|
||||
openFileSystems.add(model);
|
||||
selected.setValue(model);
|
||||
model.switchSync(store);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,11 @@ import io.xpipe.app.fxcomps.util.PlatformThread;
|
|||
import javafx.beans.binding.Bindings;
|
||||
import javafx.scene.control.ToolBar;
|
||||
import javafx.scene.layout.Region;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FileBrowserStatusBarComp extends SimpleComp {
|
||||
|
||||
OpenFileSystemModel model;
|
||||
|
@ -20,7 +22,7 @@ public class FileBrowserStatusBarComp extends SimpleComp {
|
|||
var cc = PlatformThread.sync(FileBrowserClipboard.currentCopyClipboard);
|
||||
var ccCount = Bindings.createStringBinding(() -> {
|
||||
if (cc.getValue() != null && cc.getValue().getEntries().size() > 0) {
|
||||
return String.valueOf(cc.getValue().getEntries().size()) + " file" + (cc.getValue().getEntries().size() > 1 ? "s" : "") + " in clipboard";
|
||||
return cc.getValue().getEntries().size() + " file" + (cc.getValue().getEntries().size() > 1 ? "s" : "") + " in clipboard";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,13 @@ final class FileListComp extends AnchorPane {
|
|||
}
|
||||
});
|
||||
|
||||
prepareTableEntries(table);
|
||||
prepareTableChanges(table, mtimeCol, modeCol);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private void prepareTableEntries(TableView<FileSystem.FileEntry> table) {
|
||||
var emptyEntry = new FileListCompEntry(table, null, fileList);
|
||||
table.setOnDragOver(event -> {
|
||||
emptyEntry.onDragOver(event);
|
||||
|
@ -242,16 +249,17 @@ final class FileListComp extends AnchorPane {
|
|||
|
||||
return row;
|
||||
});
|
||||
|
||||
}
|
||||
private void prepareTableChanges(TableView<FileSystem.FileEntry> table, TableColumn<FileSystem.FileEntry, Instant> mtimeCol, TableColumn<FileSystem.FileEntry, String> modeCol) {
|
||||
var lastDir = new SimpleObjectProperty<FileSystem.FileEntry>();
|
||||
SimpleChangeListener.apply(fileList.getShown(), (newValue) -> {
|
||||
Runnable updateHandler = () -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
var newItems = new ArrayList<FileSystem.FileEntry>();
|
||||
var parentEntry = fileList.getFileSystemModel().getCurrentParentDirectory();
|
||||
if (parentEntry != null) {
|
||||
newItems.add(parentEntry);
|
||||
}
|
||||
newItems.addAll(newValue);
|
||||
newItems.addAll(fileList.getShown().getValue());
|
||||
|
||||
var hasModifiedDate =
|
||||
newItems.size() == 0 || newItems.stream().anyMatch(entry -> entry.getDate() != null);
|
||||
|
@ -278,7 +286,9 @@ final class FileListComp extends AnchorPane {
|
|||
}
|
||||
}
|
||||
|
||||
table.getItems().setAll(newItems);
|
||||
if (!table.getItems().equals(newItems)) {
|
||||
table.getItems().setAll(newItems);
|
||||
}
|
||||
|
||||
var currentDirectory = fileList.getFileSystemModel().getCurrentDirectory();
|
||||
if (!Objects.equals(lastDir.get(), currentDirectory)) {
|
||||
|
@ -295,9 +305,16 @@ final class FileListComp extends AnchorPane {
|
|||
}
|
||||
lastDir.setValue(currentDirectory);
|
||||
});
|
||||
};
|
||||
updateHandler.run();
|
||||
fileList.getShown().addListener((observable, oldValue, newValue) -> {
|
||||
updateHandler.run();
|
||||
});
|
||||
fileList.getFileSystemModel().getCurrentPath().addListener((observable, oldValue, newValue) -> {
|
||||
if (oldValue == null) {
|
||||
updateHandler.run();
|
||||
}
|
||||
});
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private void borderScroll(TableView<?> tableView, DragEvent event) {
|
||||
|
|
|
@ -84,7 +84,10 @@ public class OpenFileSystemComp extends SimpleComp {
|
|||
|
||||
FileListComp directoryView = new FileListComp(model.getFileList());
|
||||
|
||||
var root = new VBox(topBar, directoryView, new FileBrowserStatusBarComp(model).createRegion());
|
||||
var root = new VBox(topBar, directoryView);
|
||||
if (model.getBrowserModel().getMode() == FileBrowserModel.Mode.BROWSER) {
|
||||
root.getChildren().add(new FileBrowserStatusBarComp(model).createRegion());
|
||||
}
|
||||
VBox.setVgrow(directoryView, Priority.ALWAYS);
|
||||
root.setPadding(Insets.EMPTY);
|
||||
model.getFileList().predicateProperty().set(PREDICATE_NOT_HIDDEN);
|
||||
|
|
|
@ -75,28 +75,28 @@ final class OpenFileSystemModel {
|
|||
}
|
||||
|
||||
public Optional<String> cd(String path) {
|
||||
if (Objects.equals(path, currentPath.get())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String newPath = null;
|
||||
try {
|
||||
newPath = FileSystemHelper.resolveDirectoryPath(this, path);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
return Optional.of(currentPath.get());
|
||||
}
|
||||
|
||||
if (!Objects.equals(path, newPath)) {
|
||||
return Optional.of(newPath);
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
try (var ignored = new BusyProperty(busy)) {
|
||||
cdSync(path);
|
||||
}
|
||||
});
|
||||
if (Objects.equals(path, currentPath.get())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String newPath = null;
|
||||
try {
|
||||
newPath = FileSystemHelper.resolveDirectoryPath(this, path);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
return Optional.of(currentPath.get());
|
||||
}
|
||||
|
||||
if (!Objects.equals(path, newPath)) {
|
||||
return Optional.of(newPath);
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
try (var ignored = new BusyProperty(busy)) {
|
||||
cdSync(path);
|
||||
}
|
||||
});
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void cdSync(String path) throws Exception {
|
||||
|
@ -123,7 +123,8 @@ final class OpenFileSystemModel {
|
|||
fileList.setAll(stream);
|
||||
} else {
|
||||
var stream = getFileSystem().listRoots().stream()
|
||||
.map(s -> new FileSystem.FileEntry(getFileSystem(), s, Instant.now(), true, false, false, 0, null));
|
||||
.map(s -> new FileSystem.FileEntry(
|
||||
getFileSystem(), s, Instant.now(), true, false, false, 0, null));
|
||||
noDirectory.set(true);
|
||||
fileList.setAll(stream);
|
||||
}
|
||||
|
@ -248,22 +249,16 @@ final class OpenFileSystemModel {
|
|||
store = null;
|
||||
}
|
||||
|
||||
private void switchSync(FileSystemStore fileSystem) throws Exception {
|
||||
closeSync();
|
||||
this.store.setValue(fileSystem);
|
||||
var fs = fileSystem.createFileSystem();
|
||||
fs.open();
|
||||
this.fileSystem = fs;
|
||||
public void switchSync(FileSystemStore fileSystem) throws Exception {
|
||||
BusyProperty.execute(busy, () -> {
|
||||
closeSync();
|
||||
this.store.setValue(fileSystem);
|
||||
var fs = fileSystem.createFileSystem();
|
||||
fs.open();
|
||||
this.fileSystem = fs;
|
||||
|
||||
var current = FileSystemHelper.getStartDirectory(this);
|
||||
cdSync(current);
|
||||
}
|
||||
|
||||
public void switchAsync(FileSystemStore fileSystem) {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BusyProperty.execute(busy, () -> {
|
||||
switchSync(fileSystem);
|
||||
});
|
||||
var current = FileSystemHelper.getStartDirectory(this);
|
||||
cdSync(current);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -278,7 +273,10 @@ final class OpenFileSystemModel {
|
|||
var connection = ((ConnectionFileSystem) fileSystem).getShellControl();
|
||||
var command = s.control()
|
||||
.initWith(connection.getShellDialect().getCdCommand(directory))
|
||||
.prepareTerminalOpen(directory + " - " + XPipeDaemon.getInstance().getStoreName(store.getValue()).orElse("?"));
|
||||
.prepareTerminalOpen(directory + " - "
|
||||
+ XPipeDaemon.getInstance()
|
||||
.getStoreName(store.getValue())
|
||||
.orElse("?"));
|
||||
TerminalHelper.open(directory, command);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
|
|||
.filter(e -> e.equals(s))
|
||||
.findAny()
|
||||
.flatMap(store -> {
|
||||
if (ShellStore.isLocal(store.asNeeded()) && mode == Mode.PROXY) {
|
||||
if (mode == Mode.PROXY && ShellStore.isLocal(store.asNeeded())) {
|
||||
return Optional.of(AppI18n.get("none"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue