From 78a5aa509f2c7e79cd0adeaeb8f69c0f99d3701b Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 31 Aug 2025 23:39:52 +0000 Subject: [PATCH] Rework for more file systems --- .../BrowseInNativeManagerActionProvider.java | 4 ++ .../action/impl/ChgrpActionProvider.java | 4 ++ .../action/impl/ChmodActionProvider.java | 4 ++ .../action/impl/ChownActionProvider.java | 4 ++ .../browser/file/BrowserBreadcrumbBar.java | 27 ++++---- .../app/browser/file/BrowserFileListComp.java | 9 ++- .../file/BrowserFileSystemTabModel.java | 5 +- .../app/browser/file/BrowserOverviewComp.java | 68 ++++++++++--------- .../BrowserApplicationPathMenuProvider.java | 4 ++ .../browser/menu/BrowserMenuProviders.java | 4 +- .../browser/menu/impl/ChgrpMenuProvider.java | 8 +++ .../browser/menu/impl/ChmodMenuProvider.java | 4 ++ .../browser/menu/impl/ChownMenuProvider.java | 8 +++ .../impl/compress/CompressMenuProvider.java | 10 +++ .../script/RunFileScriptMenuProvider.java | 5 ++ 15 files changed, 116 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/action/impl/BrowseInNativeManagerActionProvider.java b/app/src/main/java/io/xpipe/app/browser/action/impl/BrowseInNativeManagerActionProvider.java index 684f1b8cd..bb97d20d2 100644 --- a/app/src/main/java/io/xpipe/app/browser/action/impl/BrowseInNativeManagerActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/action/impl/BrowseInNativeManagerActionProvider.java @@ -17,6 +17,10 @@ public class BrowseInNativeManagerActionProvider implements BrowserActionProvide @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return false; + } + return model.getFileSystem() .getShell() .orElseThrow() diff --git a/app/src/main/java/io/xpipe/app/browser/action/impl/ChgrpActionProvider.java b/app/src/main/java/io/xpipe/app/browser/action/impl/ChgrpActionProvider.java index 93a1b580c..300d9e453 100644 --- a/app/src/main/java/io/xpipe/app/browser/action/impl/ChgrpActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/action/impl/ChgrpActionProvider.java @@ -17,6 +17,10 @@ public class ChgrpActionProvider implements BrowserActionProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + var os = model.getFileSystem().getShell().orElseThrow().getOsType(); return os != OsType.WINDOWS && os != OsType.MACOS; } diff --git a/app/src/main/java/io/xpipe/app/browser/action/impl/ChmodActionProvider.java b/app/src/main/java/io/xpipe/app/browser/action/impl/ChmodActionProvider.java index a7475aef6..aa3129521 100644 --- a/app/src/main/java/io/xpipe/app/browser/action/impl/ChmodActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/action/impl/ChmodActionProvider.java @@ -17,6 +17,10 @@ public class ChmodActionProvider implements BrowserActionProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS; } diff --git a/app/src/main/java/io/xpipe/app/browser/action/impl/ChownActionProvider.java b/app/src/main/java/io/xpipe/app/browser/action/impl/ChownActionProvider.java index 0cf7e5128..21049fd76 100644 --- a/app/src/main/java/io/xpipe/app/browser/action/impl/ChownActionProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/action/impl/ChownActionProvider.java @@ -17,6 +17,10 @@ public class ChownActionProvider implements BrowserActionProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + var os = model.getFileSystem().getShell().orElseThrow().getOsType(); return os != OsType.WINDOWS && os != OsType.MACOS; } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java index 2b3c2505e..06739f2fe 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java @@ -13,6 +13,7 @@ import javafx.scene.layout.Region; import javafx.util.Callback; import atlantafx.base.controls.Breadcrumbs; +import lombok.val; import java.util.ArrayList; import java.util.List; @@ -53,21 +54,21 @@ public class BrowserBreadcrumbBar extends SimpleComp { } var sc = model.getFileSystem().getShell(); - if (sc.isEmpty()) { - breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label("/") : null); - } else { - breadcrumbs.setDividerFactory(item -> { - if (item == null) { - return null; - } + breadcrumbs.setDividerFactory(item -> { + if (item == null) { + return null; + } - if (item.isFirst() && item.getValue().equals("/")) { - return new Label(""); - } + if (item.isFirst() && item.getValue().equals("/")) { + return new Label(""); + } - return new Label(OsFileSystem.of(sc.get().getOsType()).getFileSystemSeparator()); - }); - } + if (sc.isEmpty()) { + return new Label("/"); + } + + return new Label(OsFileSystem.of(sc.get().getOsType()).getFileSystemSeparator()); + }); var elements = createBreadcumbHierarchy(val); var modifiedElements = new ArrayList<>(elements); diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java index 94789d8c2..6032dc497 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileListComp.java @@ -193,8 +193,8 @@ public final class BrowserFileListComp extends SimpleComp { ownerCol.setVisible(newValue.doubleValue() > 1000); } - var shell = fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow(); - if (!OsType.WINDOWS.equals(shell.getOsType()) && !OsType.MACOS.equals(shell.getOsType())) { + var shell = fileList.getFileSystemModel().getFileSystem().getShell(); + if (shell.isEmpty() || (!OsType.WINDOWS.equals(shell.get().getOsType()) && !OsType.MACOS.equals(shell.get().getOsType()))) { modeCol.setVisible(newValue.doubleValue() > 600); } @@ -579,9 +579,8 @@ public final class BrowserFileListComp extends SimpleComp { ownerCol.setPrefWidth(0); } - var shell = - fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow(); - if (OsType.WINDOWS.equals(shell.getOsType()) || OsType.MACOS.equals(shell.getOsType())) { + var shell = fileList.getFileSystemModel().getFileSystem().getShell(); + if (shell.isPresent() && (OsType.WINDOWS.equals(shell.get().getOsType()) || OsType.MACOS.equals(shell.get().getOsType()))) { modeCol.setVisible(false); ownerCol.setVisible(false); } else { diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java index 8cb3225e6..8010f8e1b 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabModel.java @@ -165,7 +165,10 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTabsynchronizedObservableList(FXCollections.observableArrayList()); - ThreadHelper.runFailableAsync(() -> { - var common = OsFileSystem.of(sc.getOsType()).determineInterestingPaths(sc).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); - }); - }); - var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false); - var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview, false) - .apply(struc -> VBox.setVgrow(struc.get(), Priority.NEVER)); - - var roots = model.getFileSystem().listRoots().stream() - .map(s -> FileEntry.ofDirectory(model.getFileSystem(), s)) - .toList(); - var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false); - var rootsPane = new SimpleTitledPaneComp(AppI18n.observable("roots"), rootsOverview, false); + var list = new ArrayList>(); var recent = DerivedObservableList.wrap(model.getSavedState().getRecentDirectories(), true) .mapped(s -> FileEntry.ofDirectory(model.getFileSystem(), s.getDirectory())) .getList(); var recentOverview = new BrowserFileOverviewComp(model, recent, true); var recentPane = new SimpleTitledPaneComp(AppI18n.observable("recent"), recentOverview, false); + list.add(recentPane); - var vbox = new VerticalComp(List.of(recentPane, commonPane, rootsPane)).styleClass("overview"); + var sc = model.getFileSystem().getShell(); + if (sc.isPresent()) { + var commonPlatform = FXCollections.synchronizedObservableList(FXCollections.observableArrayList()); + ThreadHelper.runFailableAsync(() -> { + var common = OsFileSystem.of(sc.get().getOsType()).determineInterestingPaths(sc.get()).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); + }); + }); + var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false); + var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview, false).apply( + struc -> VBox.setVgrow(struc.get(), Priority.NEVER)); + list.add(commonPane); + } + + var roots = model.getFileSystem().listRoots().stream() + .map(s -> FileEntry.ofDirectory(model.getFileSystem(), s)) + .toList(); + var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false); + var rootsPane = new SimpleTitledPaneComp(AppI18n.observable("roots"), rootsOverview, false); + list.add(rootsPane); + + var vbox = new VerticalComp(list).styleClass("overview"); var r = vbox.createRegion(); return r; } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/BrowserApplicationPathMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/BrowserApplicationPathMenuProvider.java index 7d53c6076..a14b19658 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/BrowserApplicationPathMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/BrowserApplicationPathMenuProvider.java @@ -11,6 +11,10 @@ public interface BrowserApplicationPathMenuProvider extends BrowserMenuItemProvi @Override default void init(BrowserFileSystemTabModel model) { + if (model.getFileSystem().getShell().isEmpty()) { + return; + } + // Cache result for later calls model.getCache().isApplicationInPath(getExecutable()); } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/BrowserMenuProviders.java b/app/src/main/java/io/xpipe/app/browser/menu/BrowserMenuProviders.java index c97fa544c..63c61b5f0 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/BrowserMenuProviders.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/BrowserMenuProviders.java @@ -22,11 +22,11 @@ public class BrowserMenuProviders { BrowserMenuItemProvider browserAction, BrowserFileSystemTabModel model, List entries) { return browserAction instanceof BrowserMenuLeafProvider ? List.of((BrowserMenuLeafProvider) browserAction) - : ((BrowserMenuBranchProvider) browserAction) + : browserAction.isApplicable(model, entries) ? ((BrowserMenuBranchProvider) browserAction) .getBranchingActions(model, entries).stream() .map(action -> getFlattened(action, model, entries)) .flatMap(List::stream) - .toList(); + .toList() : List.of(); } public static BrowserMenuLeafProvider byId(String id, BrowserFileSystemTabModel model, List entries) { diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChgrpMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChgrpMenuProvider.java index ade93739b..29c1b918c 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChgrpMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChgrpMenuProvider.java @@ -24,6 +24,10 @@ import java.util.stream.Stream; public class ChgrpMenuProvider implements BrowserMenuBranchProvider { private static List getLeafActions(BrowserFileSystemTabModel model, boolean recursive) { + if (model.getFileSystem().getShell().isEmpty()) { + return List.of(new CustomProvider(recursive)); + } + List actions = Stream.concat( model.getCache().getGroups().entrySet().stream() .filter(e -> !e.getValue().equals("nohome") @@ -54,6 +58,10 @@ public class ChgrpMenuProvider implements BrowserMenuBranchProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + var os = model.getFileSystem().getShell().orElseThrow().getOsType(); return os != OsType.WINDOWS && os != OsType.MACOS; } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChmodMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChmodMenuProvider.java index 140ef54f0..550af4e21 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChmodMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChmodMenuProvider.java @@ -53,6 +53,10 @@ public class ChmodMenuProvider implements BrowserMenuBranchProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS; } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChownMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChownMenuProvider.java index e3a54628b..be29f67e5 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/ChownMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/ChownMenuProvider.java @@ -24,6 +24,10 @@ import java.util.stream.Stream; public class ChownMenuProvider implements BrowserMenuBranchProvider { private static List getLeafActions(BrowserFileSystemTabModel model, boolean recursive) { + if (model.getFileSystem().getShell().isEmpty()) { + return List.of(new CustomProvider(recursive)); + } + var actions = Stream.concat( model.getCache().getUsers().entrySet().stream() .filter(e -> !e.getValue().equals("nohome") @@ -53,6 +57,10 @@ public class ChownMenuProvider implements BrowserMenuBranchProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return true; + } + var os = model.getFileSystem().getShell().orElseThrow().getOsType(); return os != OsType.WINDOWS && os != OsType.MACOS; } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/CompressMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/CompressMenuProvider.java index 028df247b..435d2caef 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/CompressMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/CompressMenuProvider.java @@ -19,8 +19,14 @@ import java.util.List; public class CompressMenuProvider implements BrowserMenuBranchProvider { + + @Override public void init(BrowserFileSystemTabModel model) throws Exception { + if (model.getFileSystem().getShell().isEmpty()) { + return; + } + var sc = model.getFileSystem().getShell().orElseThrow(); var foundTar = CommandSupport.findProgram(sc, "tar"); @@ -49,6 +55,10 @@ public class CompressMenuProvider implements BrowserMenuBranchProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return false; + } + var ext = List.of("zip", "tar", "tar.gz", "tgz", "rar", "xar"); if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry .getRawFileEntry() diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java index 0e4f4ab71..e5561fb94 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java @@ -4,6 +4,7 @@ import io.xpipe.app.browser.BrowserFullSessionModel; import io.xpipe.app.browser.file.BrowserEntry; import io.xpipe.app.browser.file.BrowserFileSystemTabModel; import io.xpipe.app.browser.menu.*; +import io.xpipe.app.browser.menu.impl.ChownMenuProvider; import io.xpipe.app.comp.base.PrettyImageHelper; import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppLayoutModel; @@ -38,6 +39,10 @@ public class RunFileScriptMenuProvider implements BrowserMenuBranchProvider { @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (model.getFileSystem().getShell().isEmpty()) { + return false; + } + return model.getBrowserModel() instanceof BrowserFullSessionModel; }