mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-04-05 04:59:05 +08:00
allow opening symlinks pointing to folders in file manager (#156)
This commit is contained in:
@@ -28,21 +28,30 @@ NSDictionary *vp_handle_file_command(int fd, NSDictionary *msg) {
|
||||
NSMutableArray *entries = [NSMutableArray arrayWithCapacity:contents.count];
|
||||
for (NSString *name in contents) {
|
||||
NSString *full = [path stringByAppendingPathComponent:name];
|
||||
NSDictionary *attrs = [fm attributesOfItemAtPath:full error:nil];
|
||||
if (!attrs) continue;
|
||||
|
||||
NSString *fileType = attrs[NSFileType];
|
||||
struct stat st;
|
||||
if (lstat([full fileSystemRepresentation], &st) != 0) continue;
|
||||
|
||||
NSString *typeStr = @"file";
|
||||
if ([fileType isEqualToString:NSFileTypeDirectory]) typeStr = @"dir";
|
||||
else if ([fileType isEqualToString:NSFileTypeSymbolicLink]) typeStr = @"link";
|
||||
if (S_ISDIR(st.st_mode)) typeStr = @"dir";
|
||||
else if (S_ISLNK(st.st_mode)) typeStr = @"link";
|
||||
|
||||
NSNumber *size = attrs[NSFileSize] ?: @0;
|
||||
NSDate *mtime = attrs[NSFileModificationDate];
|
||||
NSNumber *posixPerms = attrs[NSFilePosixPermissions];
|
||||
BOOL linkTargetsDirectory = NO;
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
struct stat resolved;
|
||||
if (stat([full fileSystemRepresentation], &resolved) == 0) {
|
||||
linkTargetsDirectory = S_ISDIR(resolved.st_mode);
|
||||
}
|
||||
}
|
||||
|
||||
NSNumber *size = @(st.st_size);
|
||||
NSDate *mtime = [NSDate dateWithTimeIntervalSince1970:st.st_mtimespec.tv_sec];
|
||||
NSNumber *posixPerms = @((unsigned long)st.st_mode & 0777);
|
||||
|
||||
[entries addObject:@{
|
||||
@"name": name,
|
||||
@"type": typeStr,
|
||||
@"link_target_dir": @(linkTargetsDirectory),
|
||||
@"size": size,
|
||||
@"perm": [NSString stringWithFormat:@"%lo", [posixPerms unsignedLongValue]],
|
||||
@"mtime": @(mtime ? [mtime timeIntervalSince1970] : 0),
|
||||
|
||||
@@ -91,7 +91,7 @@ class VPhoneFileBrowserModel {
|
||||
}
|
||||
|
||||
func openItem(_ file: VPhoneRemoteFile) {
|
||||
if file.isDirectory {
|
||||
if file.isDirectoryLike {
|
||||
navigate(to: file.path)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ struct VPhoneFileBrowserView: View {
|
||||
Table(of: VPhoneRemoteFile.self, selection: $model.selection, sortOrder: $model.sortOrder) {
|
||||
TableColumn("", value: \.name) { file in
|
||||
Image(systemName: file.icon)
|
||||
.foregroundStyle(file.isDirectory ? .blue : .secondary)
|
||||
.foregroundStyle(file.isDirectoryLike ? .blue : .secondary)
|
||||
.frame(width: 20)
|
||||
}
|
||||
.width(28)
|
||||
@@ -72,7 +72,7 @@ struct VPhoneFileBrowserView: View {
|
||||
TableColumn("Size", value: \.size) { file in
|
||||
Text(file.displaySize)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
.foregroundStyle(file.isDirectory ? .secondary : .primary)
|
||||
.foregroundStyle(file.isDirectoryLike ? .secondary : .primary)
|
||||
}
|
||||
.width(min: 50, ideal: 80, max: .infinity)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ struct VPhoneRemoteFile: Identifiable, Hashable {
|
||||
let size: UInt64
|
||||
let permissions: String
|
||||
let modified: Date
|
||||
let symlinkTargetsDirectory: Bool
|
||||
|
||||
var id: String {
|
||||
path
|
||||
@@ -24,6 +25,10 @@ struct VPhoneRemoteFile: Identifiable, Hashable {
|
||||
type == .symbolicLink
|
||||
}
|
||||
|
||||
var isDirectoryLike: Bool {
|
||||
isDirectory || symlinkTargetsDirectory
|
||||
}
|
||||
|
||||
var displaySize: String {
|
||||
if isDirectory || isSymbolicLink { return "—" }
|
||||
return ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .file)
|
||||
@@ -86,6 +91,7 @@ extension VPhoneRemoteFile {
|
||||
self.dir = dir
|
||||
self.name = name
|
||||
self.type = type
|
||||
symlinkTargetsDirectory = entry["link_target_dir"] as? Bool ?? false
|
||||
size = (entry["size"] as? NSNumber)?.uint64Value ?? 0
|
||||
permissions = entry["perm"] as? String ?? "---"
|
||||
modified = Date(timeIntervalSince1970: (entry["mtime"] as? Double) ?? 0)
|
||||
|
||||
Reference in New Issue
Block a user