diff options
| author | Christian Cleberg <[email protected]> | 2026-03-18 19:28:42 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-18 19:28:42 -0500 |
| commit | bb8fae4d1145266de4f5117a3b8c48f2ccacb0be (patch) | |
| tree | 2b4ce5b2a114c5df60aa20db07ad1d38f426e59d /Hutch | |
| parent | e07b4a28d6ac6086e5b652f72b9089e4d06f7e80 (diff) | |
| download | hutch-bb8fae4d1145266de4f5117a3b8c48f2ccacb0be.tar.gz hutch-bb8fae4d1145266de4f5117a3b8c48f2ccacb0be.tar.bz2 hutch-bb8fae4d1145266de4f5117a3b8c48f2ccacb0be.zip | |
lazily load file blobs from repository tree views
Diffstat (limited to 'Hutch')
| -rw-r--r-- | Hutch/Models/Git.swift | 19 | ||||
| -rw-r--r-- | Hutch/Views/Repositories/FileTreeView.swift | 2 | ||||
| -rw-r--r-- | Hutch/Views/Repositories/FileTreeViewModel.swift | 24 |
3 files changed, 26 insertions, 19 deletions
diff --git a/Hutch/Models/Git.swift b/Hutch/Models/Git.swift index 19ec31b..905822e 100644 --- a/Hutch/Models/Git.swift +++ b/Hutch/Models/Git.swift @@ -113,7 +113,7 @@ struct GitTree: Codable, Sendable { struct GitTextBlob: Codable, Sendable { let id: String? let shortId: String? - let text: String + let text: String? let size: Int? } @@ -134,14 +134,16 @@ struct GitTreeEntryPage: Codable, Sendable { extension GitObject: Codable { private enum CodingKeys: String, CodingKey { case type, id, shortId, entries, text, size, content + case typename = "__typename" } init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let type = try container.decodeIfPresent(String.self, forKey: .type) + let typename = try container.decodeIfPresent(String.self, forKey: .typename) - switch type { - case "TREE": + switch type ?? typename { + case "TREE", "Tree": let tree = GitTree( id: try container.decodeIfPresent(String.self, forKey: .id), shortId: try container.decodeIfPresent(String.self, forKey: .shortId), @@ -149,13 +151,12 @@ extension GitObject: Codable { ) self = .tree(tree) - case "BLOB": - // TextBlob has a "text" key; BinaryBlob does not - if container.contains(.text) { + case "BLOB", "TextBlob", "BinaryBlob": + if typename == "TextBlob" || container.contains(.text) { let blob = GitTextBlob( id: try container.decodeIfPresent(String.self, forKey: .id), shortId: try container.decodeIfPresent(String.self, forKey: .shortId), - text: try container.decode(String.self, forKey: .text), + text: try container.decodeIfPresent(String.self, forKey: .text), size: try container.decodeIfPresent(Int.self, forKey: .size) ) self = .textBlob(blob) @@ -184,12 +185,14 @@ extension GitObject: Codable { try container.encodeIfPresent(tree.entries, forKey: .entries) case .textBlob(let blob): try container.encode("BLOB", forKey: .type) + try container.encode("TextBlob", forKey: .typename) try container.encodeIfPresent(blob.id, forKey: .id) try container.encodeIfPresent(blob.shortId, forKey: .shortId) - try container.encode(blob.text, forKey: .text) + try container.encodeIfPresent(blob.text, forKey: .text) try container.encodeIfPresent(blob.size, forKey: .size) case .binaryBlob(let blob): try container.encode("BLOB", forKey: .type) + try container.encode("BinaryBlob", forKey: .typename) try container.encodeIfPresent(blob.id, forKey: .id) try container.encodeIfPresent(blob.shortId, forKey: .shortId) try container.encodeIfPresent(blob.size, forKey: .size) diff --git a/Hutch/Views/Repositories/FileTreeView.swift b/Hutch/Views/Repositories/FileTreeView.swift index 3750adb..45fe5b6 100644 --- a/Hutch/Views/Repositories/FileTreeView.swift +++ b/Hutch/Views/Repositories/FileTreeView.swift @@ -235,7 +235,7 @@ private struct FileTreeContentView: View { GeometryReader { geometry in ScrollView([.vertical, .horizontal]) { - Text(blob.text) + Text(blob.text ?? "") .font(.system(.body, design: .monospaced)) .multilineTextAlignment(.leading) .fixedSize(horizontal: true, vertical: false) diff --git a/Hutch/Views/Repositories/FileTreeViewModel.swift b/Hutch/Views/Repositories/FileTreeViewModel.swift index f270779..a9c86b4 100644 --- a/Hutch/Views/Repositories/FileTreeViewModel.swift +++ b/Hutch/Views/Repositories/FileTreeViewModel.swift @@ -96,6 +96,7 @@ final class FileTreeViewModel { mode object { type + __typename id shortId ... on Tree { @@ -110,12 +111,10 @@ final class FileTreeViewModel { } } ... on TextBlob { - text size } ... on BinaryBlob { size - content } } } @@ -142,6 +141,7 @@ final class FileTreeViewModel { mode object { type + __typename id shortId ... on Tree { @@ -156,12 +156,10 @@ final class FileTreeViewModel { } } ... on TextBlob { - text size } ... on BinaryBlob { size - content } } } @@ -187,6 +185,7 @@ final class FileTreeViewModel { mode object { type + __typename id shortId ... on Tree { @@ -201,12 +200,10 @@ final class FileTreeViewModel { } } ... on TextBlob { - text size } ... on BinaryBlob { size - content } } } @@ -321,16 +318,23 @@ final class FileTreeViewModel { // Otherwise fetch the subtree (handles pagination) await loadSubtree(name: entry.name, treeId: objectSHA) - case .textBlob: - viewingEntry = entry - viewingObject = object + case .textBlob(let blob): + if blob.text != nil { + viewingEntry = entry + viewingObject = object + } else if let blobId = blob.id { + await loadBlob(entry: entry, blobId: blobId) + } case .binaryBlob(let blob): - if blob.content != nil || blob.size != nil { + if blob.content != nil { viewingEntry = entry viewingObject = object } else if let blobId = blob.id { await loadBlob(entry: entry, blobId: blobId) + } else { + viewingEntry = entry + viewingObject = object } case .unknown: |
