summaryrefslogtreecommitdiff
path: root/Hutch/Views
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-01 23:37:12 -0500
committerChristian Cleberg <[email protected]>2026-04-01 23:37:12 -0500
commit0bef9acc515cfcb4ac6e2530cd34cbdbc47c2c1d (patch)
tree4457ca8d3fcc1f53383c9da46e19661a039834df /Hutch/Views
parenta83893afa086f0050c825144fa818024db4df056 (diff)
downloadhutch-0bef9acc515cfcb4ac6e2530cd34cbdbc47c2c1d.tar.gz
hutch-0bef9acc515cfcb4ac6e2530cd34cbdbc47c2c1d.tar.bz2
hutch-0bef9acc515cfcb4ac6e2530cd34cbdbc47c2c1d.zip
feat: show commit dates in Refs tabv2.8.1
Diffstat (limited to 'Hutch/Views')
-rw-r--r--Hutch/Views/Repositories/ReferencesListView.swift13
-rw-r--r--Hutch/Views/Repositories/RepositoryDetailViewModel.swift42
-rw-r--r--Hutch/Views/Repositories/RepositorySettingsView.swift2
-rw-r--r--Hutch/Views/Repositories/RepositorySettingsViewModel.swift4
4 files changed, 49 insertions, 12 deletions
diff --git a/Hutch/Views/Repositories/ReferencesListView.swift b/Hutch/Views/Repositories/ReferencesListView.swift
index 615ba25..6470a42 100644
--- a/Hutch/Views/Repositories/ReferencesListView.swift
+++ b/Hutch/Views/Repositories/ReferencesListView.swift
@@ -51,14 +51,21 @@ struct ReferencesListView: View {
}
private struct ReferenceRow: View {
- let reference: Reference
+ let reference: ReferenceDetail
let prefix: String
var body: some View {
HStack {
Label {
- Text(shortName)
- .font(.body.monospaced())
+ VStack(alignment: .leading, spacing: 2) {
+ Text(shortName)
+ .font(.body.monospaced())
+ if let date = reference.date {
+ Text(date.relativeDescription)
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ }
+ }
} icon: {
Image(systemName: icon)
.foregroundStyle(iconColor)
diff --git a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
index e2eaf4d..72c4d1f 100644
--- a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
+++ b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
@@ -24,10 +24,33 @@ private struct RefsRepository: Decodable, Sendable {
}
private struct RefsPage: Decodable, Sendable {
- let results: [Reference]
+ let results: [ReferencePayload]
let cursor: String?
}
+/// Decodes a single reference including the optional follow object for date extraction.
+private struct ReferencePayload: Decodable, Sendable {
+ let name: String
+ let target: String?
+ let follow: ReferenceFollow?
+
+ func toDetail() -> ReferenceDetail {
+ // Branches and lightweight tags follow to a Commit (author.time).
+ // Annotated tags follow to a Tag object (tagger.time).
+ let date = follow?.author?.time ?? follow?.tagger?.time
+ return ReferenceDetail(name: name, target: target, date: date)
+ }
+}
+
+private struct ReferenceFollow: Decodable, Sendable {
+ let author: ReferenceSignature?
+ let tagger: ReferenceSignature?
+}
+
+private struct ReferenceSignature: Decodable, Sendable {
+ let time: Date
+}
+
private struct ReadmeResponse: Decodable, Sendable {
let repository: ReadmeRepository?
}
@@ -98,8 +121,8 @@ final class RepositoryDetailViewModel {
// MARK: - References state
- private(set) var branches: [Reference] = []
- private(set) var tags: [Reference] = []
+ private(set) var branches: [ReferenceDetail] = []
+ private(set) var tags: [ReferenceDetail] = []
private(set) var isLoadingRefs = false
// MARK: - README state
@@ -220,7 +243,14 @@ final class RepositoryDetailViewModel {
query refs($rid: ID!) {
repository(rid: $rid) {
references {
- results { name target }
+ results {
+ name
+ target
+ follow {
+ ... on Commit { author { time } }
+ ... on Tag { tagger { time } }
+ }
+ }
cursor
}
}
@@ -240,8 +270,8 @@ final class RepositoryDetailViewModel {
responseType: RefsResponse.self
)
let allRefs = result.repository?.references.results ?? []
- branches = allRefs.filter { $0.name.hasPrefix("refs/heads/") }
- tags = allRefs.filter { $0.name.hasPrefix("refs/tags/") }
+ branches = allRefs.filter { $0.name.hasPrefix("refs/heads/") }.map { $0.toDetail() }
+ tags = allRefs.filter { $0.name.hasPrefix("refs/tags/") }.map { $0.toDetail() }
} catch {
self.error = error.userFacingMessage
}
diff --git a/Hutch/Views/Repositories/RepositorySettingsView.swift b/Hutch/Views/Repositories/RepositorySettingsView.swift
index aca2ff9..98d3d8a 100644
--- a/Hutch/Views/Repositories/RepositorySettingsView.swift
+++ b/Hutch/Views/Repositories/RepositorySettingsView.swift
@@ -2,7 +2,7 @@ import SwiftUI
struct RepositorySettingsView: View {
let repository: RepositorySummary
- let branches: [Reference]
+ let branches: [ReferenceDetail]
let client: SRHTClient
let onRenamed: (String) -> Void
let onDeleted: () -> Void
diff --git a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
index 2847cb7..571ae85 100644
--- a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
+++ b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
@@ -102,7 +102,7 @@ final class RepositorySettingsViewModel {
// MARK: - Branches (for HEAD picker)
- var branches: [Reference]
+ var branches: [ReferenceDetail]
// MARK: - Results
@@ -112,7 +112,7 @@ final class RepositorySettingsViewModel {
init(
repository: RepositorySummary,
- branches: [Reference],
+ branches: [ReferenceDetail],
client: SRHTClient
) {
self.repositoryId = repository.id