From ee3d7642e252fe653caee9289d844974c36bb4db Mon Sep 17 00:00:00 2001 From: crschnick Date: Fri, 4 Apr 2025 09:25:47 +0000 Subject: [PATCH] Various fixes --- .../app/browser/file/BrowserFileListComp.java | 19 +++++++++++------- .../browser/file/BrowserFileSystemHelper.java | 2 +- .../file/BrowserFileSystemTabModel.java | 4 ++-- .../file/BrowserFileTransferOperation.java | 11 +++++----- .../browser/file/BrowserLocalFileSystem.java | 2 +- .../browser/file/BrowserStatusBarComp.java | 6 +++++- .../app/browser/file/BrowserTransferComp.java | 4 ++++ .../browser/file/BrowserTransferProgress.java | 4 ++++ .../java/io/xpipe/core/store/FileEntry.java | 20 ++++++++++++++++--- .../java/io/xpipe/core/store/FileInfo.java | 2 +- .../io/xpipe/core/store/LinkFileEntry.java | 2 +- dist/changelogs/16.0.md | 2 ++ 12 files changed, 56 insertions(+), 22 deletions(-) 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 d05ef864e..e54b60f3e 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 @@ -70,9 +70,9 @@ public final class BrowserFileListComp extends SimpleComp { filenameCol.setReorderable(false); filenameCol.setResizable(false); - var sizeCol = new TableColumn(); + var sizeCol = new TableColumn(); sizeCol.textProperty().bind(AppI18n.observable("size")); - sizeCol.setCellValueFactory(param -> new SimpleLongProperty( + sizeCol.setCellValueFactory(param -> new ReadOnlyStringWrapper( param.getValue().getRawFileEntry().resolved().getSize())); sizeCol.setCellFactory(col -> new FileSizeCell()); sizeCol.setResizable(false); @@ -579,19 +579,24 @@ public final class BrowserFileListComp extends SimpleComp { } } - private static class FileSizeCell extends TableCell { + private static class FileSizeCell extends TableCell { @Override - protected void updateItem(Number fileSize, boolean empty) { + protected void updateItem(String fileSize, boolean empty) { super.updateItem(fileSize, empty); if (empty || getTableRow() == null || getTableRow().getItem() == null) { setText(null); } else { var path = getTableRow().getItem(); if (path.getRawFileEntry().resolved().getKind() == FileKind.DIRECTORY) { - setText(""); - } else { - setText(byteCount(fileSize.longValue())); + setText(null); + } else if (fileSize != null) { + try { + var l = Long.parseLong(fileSize); + setText(byteCount(l)); + } catch (NumberFormatException e) { + setText(fileSize); + } } } } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemHelper.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemHelper.java index 96f1e81fa..48814cb51 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemHelper.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemHelper.java @@ -127,7 +127,7 @@ public class BrowserFileSystemHelper { fileSystem, file, Instant.now(), - fileSystem.getFileSize(file), + "" + fileSystem.getFileSize(file), null, fileSystem.directoryExists(file) ? FileKind.DIRECTORY : FileKind.FILE); } 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 d3e24c9d6..905c8e2e1 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 @@ -198,7 +198,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab { try { long readCount = 0; - var bs = (int) Math.min(DEFAULT_BUFFER_SIZE, sourceFile.getSize()); + var bs = (int) Math.min(DEFAULT_BUFFER_SIZE, expectedFileSize); byte[] buffer = new byte[bs]; int read; while ((read = inputStream.read(buffer, 0, bs)) > 0) { diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserLocalFileSystem.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserLocalFileSystem.java index a88811843..c261cdcd6 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserLocalFileSystem.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserLocalFileSystem.java @@ -36,7 +36,7 @@ public class BrowserLocalFileSystem { localFileSystem.open(), FilePath.of(file), Files.getLastModifiedTime(file).toInstant(), - Files.size(file), + "" + Files.size(file), null, Files.isDirectory(file) ? FileKind.DIRECTORY : FileKind.FILE); } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserStatusBarComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserStatusBarComp.java index 7b2cd2e6d..8db966180 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserStatusBarComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserStatusBarComp.java @@ -88,7 +88,7 @@ public class BrowserStatusBarComp extends SimpleComp { } else { var expected = p.expectedTimeRemaining(); var show = p.elapsedTime().compareTo(Duration.of(200, ChronoUnit.MILLIS)) > 0 - && (p.getTotal() > 50_000_000 || expected.toMillis() > 5000); + && (!p.hasKnownTotalSize() || p.getTotal() > 50_000_000 || expected.toMillis() > 5000); var time = show ? HumanReadableFormat.duration(p.expectedTimeRemaining()) : ""; return time; } @@ -106,6 +106,10 @@ public class BrowserStatusBarComp extends SimpleComp { return null; } else { var transferred = HumanReadableFormat.progressByteCount(p.getTransferred()); + if (!p.hasKnownTotalSize()) { + return transferred; + } + var all = HumanReadableFormat.byteCount(p.getTotal()); return transferred + " / " + all; } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java index 4dc1fc403..bd61017bb 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferComp.java @@ -65,6 +65,10 @@ public class BrowserTransferComp extends SimpleComp { return Bindings.createStringBinding( () -> { var p = sourceItem.get().getProgress().getValue(); + if (!p.hasKnownTotalSize()) { + return entry.getFileName(); + } + var hideProgress = sourceItem.get().downloadFinished().get(); var share = p != null ? (p.getTransferred() * 100 / p.getTotal()) : 0; diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferProgress.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferProgress.java index 99b7e291d..14004a674 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferProgress.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserTransferProgress.java @@ -22,6 +22,10 @@ public class BrowserTransferProgress { return transferred >= total; } + public boolean hasKnownTotalSize() { + return total > 0; + } + public Duration elapsedTime() { var now = Instant.now(); var elapsed = Duration.between(start, now); diff --git a/core/src/main/java/io/xpipe/core/store/FileEntry.java b/core/src/main/java/io/xpipe/core/store/FileEntry.java index 247ee06fb..e2169c45a 100644 --- a/core/src/main/java/io/xpipe/core/store/FileEntry.java +++ b/core/src/main/java/io/xpipe/core/store/FileEntry.java @@ -6,13 +6,14 @@ import lombok.Value; import lombok.experimental.NonFinal; import java.time.Instant; +import java.util.OptionalLong; @Value @NonFinal public class FileEntry { FileSystem fileSystem; Instant date; - long size; + String size; FileInfo info; @@ -28,7 +29,7 @@ public class FileEntry { FileSystem fileSystem, @NonNull FilePath path, Instant date, - long size, + String size, FileInfo info, @NonNull FileKind kind) { this.fileSystem = fileSystem; @@ -40,7 +41,20 @@ public class FileEntry { } public static FileEntry ofDirectory(FileSystem fileSystem, FilePath path) { - return new FileEntry(fileSystem, path, Instant.now(), 0, null, FileKind.DIRECTORY); + return new FileEntry(fileSystem, path, Instant.now(), null, null, FileKind.DIRECTORY); + } + + public OptionalLong getFileSizeLong() { + if (size == null) { + return OptionalLong.empty(); + } + + try { + var l = Long.parseLong(size); + return OptionalLong.of(l); + } catch (NumberFormatException e) { + return OptionalLong.empty(); + } } public FileEntry resolved() { diff --git a/core/src/main/java/io/xpipe/core/store/FileInfo.java b/core/src/main/java/io/xpipe/core/store/FileInfo.java index 3aa2408f8..fa899bf64 100644 --- a/core/src/main/java/io/xpipe/core/store/FileInfo.java +++ b/core/src/main/java/io/xpipe/core/store/FileInfo.java @@ -40,7 +40,7 @@ public sealed interface FileInfo permits FileInfo.Windows, FileInfo.Unix { @Override public boolean possiblyExecutable() { - return permissions.contains("x"); + return permissions == null || permissions.contains("x"); } } } diff --git a/core/src/main/java/io/xpipe/core/store/LinkFileEntry.java b/core/src/main/java/io/xpipe/core/store/LinkFileEntry.java index a1c48ae57..d22e75eaf 100644 --- a/core/src/main/java/io/xpipe/core/store/LinkFileEntry.java +++ b/core/src/main/java/io/xpipe/core/store/LinkFileEntry.java @@ -17,7 +17,7 @@ public class LinkFileEntry extends FileEntry { FileSystem fileSystem, @NonNull FilePath path, Instant date, - long size, + String size, @NonNull FileInfo info, @NonNull FileEntry target) { super(fileSystem, path, date, size, info, FileKind.LINK); diff --git a/dist/changelogs/16.0.md b/dist/changelogs/16.0.md index c18853e66..af842139e 100644 --- a/dist/changelogs/16.0.md +++ b/dist/changelogs/16.0.md @@ -31,6 +31,7 @@ The password manager integration has been improved and made more robust: - The SSH gateway implementation has been reworked so that you can now use local SSH keys and other identities for connections with gateways - Generated connection names, e.g. VM names, will now automatically update on refresh when they were changed +- You can now unlock the vault with your password manager - Various speed improvements for shell operations - Various startup speed improvements - The scripts context menu now shows the respective scripts icons instead of generic ones @@ -41,6 +42,7 @@ The password manager integration has been improved and made more robust: ## Fixes +- Fix various embedded and busybox systems failing to open in file browser when essential commands like stat were missing - Fix Windows msi updates failing when initial installation was installed per-user as an Administrator - Fix Windows msi updates launching XPipe as Administrator when restarting if it was a system-wide program files installation - Fix some dialog content shifting around on initial show