diff options
Diffstat (limited to 'Hutch/Views/Repositories/FileTreeViewModel.swift')
| -rw-r--r-- | Hutch/Views/Repositories/FileTreeViewModel.swift | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/Hutch/Views/Repositories/FileTreeViewModel.swift b/Hutch/Views/Repositories/FileTreeViewModel.swift index 7330cd8..9ccd74b 100644 --- a/Hutch/Views/Repositories/FileTreeViewModel.swift +++ b/Hutch/Views/Repositories/FileTreeViewModel.swift @@ -1,7 +1,25 @@ import Foundation +// MARK: - Linked file + +/// Identifies a repository file to fetch and display in a sheet. +struct LinkedFileRequest: Identifiable, Sendable { + var id: String { "\(revspec):\(path)" } + let path: String + let revspec: String + let fileName: String +} + // MARK: - Response types (file-private to avoid @MainActor Decodable issues) +private struct LinkedFileResponse: Decodable, Sendable { + let repository: LinkedFileRepository? +} + +private struct LinkedFileRepository: Decodable, Sendable { + let path: TreeEntry? +} + private struct RevparseResponse: Decodable, Sendable { let repository: RevparseRepository? } @@ -471,6 +489,43 @@ final class FileTreeViewModel { return result.repository?.object?.entries ?? GitTreeEntryPage(results: [], cursor: nil) } + // MARK: - Linked File (used by README link interception) + + private static let linkedFileQuery = """ + query linkedFile($rid: ID!, $revspec: String, $path: String!) { + repository(rid: $rid) { + path(revspec: $revspec, path: $path) { + id + name + mode + object { + __typename + ... on TextBlob { text size } + ... on BinaryBlob { size } + } + } + } + } + """ + + /// Fetch a single file by path using the `repository.path()` field. + /// Returns a `TreeEntry` on success, or throws on API/network error. + /// Returns `nil` if the path resolves to nothing (file not found). + func fetchLinkedFile(path: String, revspec: String) async throws -> TreeEntry? { + let variables: [String: any Sendable] = [ + "rid": repositoryRid, + "revspec": revspec, + "path": path + ] + let result = try await client.execute( + service: service, + query: Self.linkedFileQuery, + variables: variables, + responseType: LinkedFileResponse.self + ) + return result.repository?.path + } + /// Dismiss the file view and go back to the directory listing. func dismissFileView() { viewingEntry = nil |
