summaryrefslogtreecommitdiff
path: root/Hutch/Views/Tickets
diff options
context:
space:
mode:
Diffstat (limited to 'Hutch/Views/Tickets')
-rw-r--r--Hutch/Views/Tickets/TicketDetailView.swift9
-rw-r--r--Hutch/Views/Tickets/TicketListView.swift64
2 files changed, 58 insertions, 15 deletions
diff --git a/Hutch/Views/Tickets/TicketDetailView.swift b/Hutch/Views/Tickets/TicketDetailView.swift
index f85a0c1..32ef89c 100644
--- a/Hutch/Views/Tickets/TicketDetailView.swift
+++ b/Hutch/Views/Tickets/TicketDetailView.swift
@@ -220,6 +220,15 @@ struct TicketDetailView: View {
commentInput(viewModel)
}
}
+ .task(id: ticket.id) {
+ RecentActivityStore.recordTicket(
+ ownerUsername: ownerUsername,
+ trackerName: trackerName,
+ ticketId: ticket.id,
+ title: ticket.title,
+ defaults: appState.accountDefaults
+ )
+ }
.srhtErrorBanner(error: $vm.error)
.refreshable {
await reloadDetail(viewModel)
diff --git a/Hutch/Views/Tickets/TicketListView.swift b/Hutch/Views/Tickets/TicketListView.swift
index f7529fb..8f7d348 100644
--- a/Hutch/Views/Tickets/TicketListView.swift
+++ b/Hutch/Views/Tickets/TicketListView.swift
@@ -23,12 +23,29 @@ struct TicketListView: View {
@State private var showBulkCloseSheet = false
@State private var showBulkAssignSheet = false
@State private var bulkActionResult: TicketBulkActionResult?
+ @State private var pinChangeCount = 0
private var isOwnedByCurrentUser: Bool {
guard let currentUser = appState.currentUser else { return false }
return normalizedUsername(currentUser.username) == normalizedUsername(tracker.owner.canonicalName)
}
+ private var currentUserKey: String? {
+ appState.currentUser?.canonicalName
+ }
+
+ private var isPinnedToHome: Bool {
+ _ = pinChangeCount
+ guard let currentUserKey else { return false }
+ return HomePinStore.isPinned(.tracker(tracker), for: currentUserKey, defaults: appState.accountDefaults)
+ }
+
+ private var navigationTitle: String {
+ guard let viewModel, viewModel.isSelectionMode else { return tracker.name }
+ let count = viewModel.selectedTicketCount
+ return count == 0 ? "Select Tickets" : "\(count) Selected"
+ }
+
init(
tracker: TrackerSummary,
onTrackerUpdated: @escaping (TrackerSummary) -> Void = { _ in /* no-op: default for callers that don't handle this event */ },
@@ -47,7 +64,7 @@ struct TicketListView: View {
SRHTLoadingStateView(message: "Loading tickets…")
}
}
- .navigationTitle(tracker.name)
+ .navigationTitle(navigationTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarLeading) {
@@ -66,16 +83,6 @@ struct TicketListView: View {
}
.disabled(viewModel.filteredTickets.isEmpty || viewModel.isPerformingAction)
} else {
- SRHTShareButton(
- url: SRHTWebURL.tracker(
- ownerUsername: String(tracker.owner.canonicalName.dropFirst()),
- trackerName: tracker.name
- ),
- target: .tracker
- ) {
- Image(systemName: "square.and.arrow.up")
- }
-
Button {
showCreateTicketSheet = true
} label: {
@@ -83,10 +90,6 @@ struct TicketListView: View {
}
.accessibilityLabel("Create ticket")
- Button("Select") {
- viewModel?.setSelectionMode(true)
- }
-
trackerActionsMenu
}
}
@@ -242,6 +245,12 @@ struct TicketListView: View {
}
}
+ private func togglePinnedState() {
+ guard let currentUserKey else { return }
+ HomePinStore.togglePin(.tracker(tracker), for: currentUserKey, defaults: appState.accountDefaults)
+ pinChangeCount += 1
+ }
+
@ViewBuilder
private func listContent(_ viewModel: TicketListViewModel) -> some View {
@Bindable var vm = viewModel
@@ -429,6 +438,31 @@ struct TicketListView: View {
private var trackerActionsMenu: some View {
Menu {
+ Button {
+ viewModel?.setSelectionMode(true)
+ } label: {
+ Label("Select", systemImage: "checkmark.circle")
+ }
+
+ if currentUserKey != nil {
+ Button {
+ togglePinnedState()
+ } label: {
+ Label(
+ isPinnedToHome ? "Unpin from Home" : "Pin to Home",
+ systemImage: isPinnedToHome ? "pin.slash" : "pin"
+ )
+ }
+ }
+
+ if let shareURL = SRHTWebURL.tracker(tracker) {
+ ShareLink(item: shareURL) {
+ Label("Share", systemImage: "square.and.arrow.up")
+ }
+ }
+
+ Divider()
+
if let trackerURL = SRHTWebURL.tracker(tracker) {
Button {
openURL(trackerURL)