summaryrefslogtreecommitdiff
path: root/Hutch/Views/Tickets
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-12 00:34:54 -0500
committerChristian Cleberg <[email protected]>2026-04-12 00:34:54 -0500
commit5f6d545eb3455a9e4da5a3cb4460811e3a48d939 (patch)
tree7b7591146da4e02bd617ddb9f26e47b1c4474ef6 /Hutch/Views/Tickets
parentcb1ea5ea4f163d87053285d3fb7999b12a3558b9 (diff)
downloadhutch-2.14.0.tar.gz
hutch-2.14.0.tar.bz2
hutch-2.14.0.zip
improve home attention flows and cross-linkingv2.14.0
Diffstat (limited to 'Hutch/Views/Tickets')
-rw-r--r--Hutch/Views/Tickets/TicketDetailView.swift35
1 files changed, 35 insertions, 0 deletions
diff --git a/Hutch/Views/Tickets/TicketDetailView.swift b/Hutch/Views/Tickets/TicketDetailView.swift
index 22ebaa9..4bea3ae 100644
--- a/Hutch/Views/Tickets/TicketDetailView.swift
+++ b/Hutch/Views/Tickets/TicketDetailView.swift
@@ -16,6 +16,7 @@ struct TicketDetailView: View {
@State private var showResolveSheet = false
@State private var showAssignSheet = false
@State private var showLabelsSheet = false
+ @State private var isOpeningTracker = false
// Comment composer mode
@State private var commentMode: CommentMode = .write
@@ -227,6 +228,26 @@ struct TicketDetailView: View {
}
.font(.caption)
+ Button {
+ openTracker()
+ } label: {
+ HStack(spacing: 6) {
+ Label("\(ownerUsername)/\(trackerName)", systemImage: "checklist")
+ .font(.caption.weight(.medium))
+ if isOpeningTracker {
+ ProgressView()
+ .controlSize(.small)
+ } else {
+ Image(systemName: "arrow.up.right")
+ .font(.caption2)
+ .foregroundStyle(.tertiary)
+ }
+ }
+ .foregroundStyle(.secondary)
+ }
+ .buttonStyle(.plain)
+ .disabled(isOpeningTracker)
+
if !ticket.assignees.isEmpty {
HStack(spacing: 4) {
Image(systemName: "person.fill")
@@ -346,6 +367,20 @@ struct TicketDetailView: View {
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.hasPrefix("~") ? String(trimmed.dropFirst()) : trimmed
}
+
+ private func openTracker() {
+ guard !isOpeningTracker else { return }
+ isOpeningTracker = true
+ Task {
+ defer { isOpeningTracker = false }
+ do {
+ let tracker = try await appState.resolveTracker(owner: ownerUsername, name: trackerName)
+ appState.navigateToTracker(tracker)
+ } catch {
+ appState.presentTicketDeepLinkError()
+ }
+ }
+ }
}
// MARK: - Self-Sizing Markdown Web View