summaryrefslogtreecommitdiff
path: root/Hutch
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-16 11:50:53 -0500
committerGitHub <[email protected]>2026-07-16 11:50:53 -0500
commit0b6819d2d08b552e62fd236614d4c3c86a13394b (patch)
treeefb71f83c6dc62778ab01de9951cd229b50f348c /Hutch
parent2b913e1b727429a3a6bc7eb023003ef2815919ae (diff)
parentf3c70e04148c57dcafead89b4e02b83e5f5635f8 (diff)
downloadhutch-0b6819d2d08b552e62fd236614d4c3c86a13394b.tar.gz
hutch-0b6819d2d08b552e62fd236614d4c3c86a13394b.tar.bz2
hutch-0b6819d2d08b552e62fd236614d4c3c86a13394b.zip
Merge pull request #8 from zerolabsco/phase-3-sonarcloud-housekeepingv3.8.1
v3.8.1: SonarCloud triage, forceRefresh fix, housekeeping
Diffstat (limited to 'Hutch')
-rw-r--r--Hutch/App/AccountSession.swift (renamed from Hutch/Hutch/App/AccountSession.swift)0
-rw-r--r--Hutch/App/HutchIntents.swift6
-rw-r--r--Hutch/App/RootView.swift8
-rw-r--r--Hutch/Networking/ProjectService.swift8
-rw-r--r--Hutch/Views/Home/HomeViewModel.swift4
-rw-r--r--Hutch/Views/Patchsets/PatchsetDetailView.swift2
-rw-r--r--Hutch/Views/Projects/ProjectsListView.swift6
-rw-r--r--Hutch/Views/Repositories/RepositoryDetailViewModel.swift2
-rw-r--r--Hutch/Views/Tickets/TicketDetailView.swift2
9 files changed, 19 insertions, 19 deletions
diff --git a/Hutch/Hutch/App/AccountSession.swift b/Hutch/App/AccountSession.swift
index 1918b0a..1918b0a 100644
--- a/Hutch/Hutch/App/AccountSession.swift
+++ b/Hutch/App/AccountSession.swift
diff --git a/Hutch/App/HutchIntents.swift b/Hutch/App/HutchIntents.swift
index c2f144a..947ec04 100644
--- a/Hutch/App/HutchIntents.swift
+++ b/Hutch/App/HutchIntents.swift
@@ -134,7 +134,8 @@ struct SearchHutchIntent: AppIntent {
var route: HutchRoute {
let normalized = query.trimmingCharacters(in: .whitespacesAndNewlines)
- // TODO: Route to global local search once Hutch has one.
+ // Routes to Lookup for now; repoint at a global content search when Hutch
+ // gains one — tracked in ROADMAP.md § "App Intent gaps".
return normalized.isEmpty ? .lookup : .search(query: normalized)
}
@@ -145,7 +146,8 @@ struct SearchHutchIntent: AppIntent {
}
}
-// TODO: Add OpenSavedSearchIntent when Hutch has global saved-search persistence.
+// An OpenSavedSearchIntent belongs here once Hutch has global saved-search
+// persistence — tracked in ROADMAP.md § "App Intent gaps".
// MARK: - App Entities
diff --git a/Hutch/App/RootView.swift b/Hutch/App/RootView.swift
index 10720ad..2e16718 100644
--- a/Hutch/App/RootView.swift
+++ b/Hutch/App/RootView.swift
@@ -198,11 +198,9 @@ struct RootView: View {
}
switch link {
- case .home:
- homePath = NavigationPath()
- appState.selectedTab = .home
-
- case .recentActivity:
+ // Recent activity is a section of the Home tab, not a screen of its
+ // own, so its intent/widget deep link lands on Home like .home does.
+ case .home, .recentActivity:
homePath = NavigationPath()
appState.selectedTab = .home
diff --git a/Hutch/Networking/ProjectService.swift b/Hutch/Networking/ProjectService.swift
index 44320ca..91dc339 100644
--- a/Hutch/Networking/ProjectService.swift
+++ b/Hutch/Networking/ProjectService.swift
@@ -269,15 +269,15 @@ struct ProjectService: Sendable {
self.client = client
}
- func fetchProjects() async throws -> [Project] {
- try await fetchProjectSummaries().map(Self.makeSummaryProject)
+ func fetchProjects(forceRefresh: Bool = false) async throws -> [Project] {
+ try await fetchProjectSummaries(forceRefresh: forceRefresh).map(Self.makeSummaryProject)
}
func fetchProjectDetail(rid: String) async throws -> Project {
try await fetchProjectDetailPayload(rid: rid)
}
- private func fetchProjectSummaries() async throws -> [ProjectSummaryPayload] {
+ private func fetchProjectSummaries(forceRefresh: Bool) async throws -> [ProjectSummaryPayload] {
var results: [ProjectSummaryPayload] = []
var cursor: String?
@@ -295,7 +295,7 @@ struct ProjectService: Sendable {
cacheKey: APICacheKeys.projects(cursor: cursor),
resourceType: .userProfile,
ttl: APICacheTTLs.projectList,
- policy: .cacheFirstThenRefresh
+ policy: forceRefresh ? .refreshIgnoringCache : .cacheFirstThenRefresh
)
let response = cached.value
diff --git a/Hutch/Views/Home/HomeViewModel.swift b/Hutch/Views/Home/HomeViewModel.swift
index a3aed30..3789c11 100644
--- a/Hutch/Views/Home/HomeViewModel.swift
+++ b/Hutch/Views/Home/HomeViewModel.swift
@@ -683,7 +683,7 @@ final class HomeViewModel {
private func loadProjects(forceRefresh: Bool) async -> Result<[Project], Error> {
do {
- return .success(try await projectService.fetchProjects())
+ return .success(try await projectService.fetchProjects(forceRefresh: forceRefresh))
} catch {
return .failure(error)
}
@@ -716,7 +716,7 @@ final class HomeViewModel {
private func loadSystemStatusSnapshot(forceRefresh: Bool) async -> Result<CachedSystemStatusValue<SystemStatusSnapshot>, Error> {
do {
- return .success(try await systemStatusRepository.snapshotResult())
+ return .success(try await systemStatusRepository.snapshotResult(forceRefresh: forceRefresh))
} catch {
return .failure(error)
}
diff --git a/Hutch/Views/Patchsets/PatchsetDetailView.swift b/Hutch/Views/Patchsets/PatchsetDetailView.swift
index f560326..3ef5ff4 100644
--- a/Hutch/Views/Patchsets/PatchsetDetailView.swift
+++ b/Hutch/Views/Patchsets/PatchsetDetailView.swift
@@ -71,7 +71,7 @@ struct PatchsetDetailView: View {
Task { await viewModel.updateStatus(to: status) }
}
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* dismisses the dialog; no action needed */ }
}
.alert(
"Couldn't Update Patchset",
diff --git a/Hutch/Views/Projects/ProjectsListView.swift b/Hutch/Views/Projects/ProjectsListView.swift
index f6d5766..783417c 100644
--- a/Hutch/Views/Projects/ProjectsListView.swift
+++ b/Hutch/Views/Projects/ProjectsListView.swift
@@ -25,14 +25,14 @@ final class ProjectsListViewModel {
}
}
- func loadProjects() async {
+ func loadProjects(forceRefresh: Bool = false) async {
guard !isLoading else { return }
isLoading = true
error = nil
defer { isLoading = false }
do {
- projects = try await service.fetchProjects()
+ projects = try await service.fetchProjects(forceRefresh: forceRefresh)
} catch {
if projects.isEmpty {
self.error = error.userFacingMessage
@@ -115,7 +115,7 @@ struct ProjectsListView: View {
)
)
.refreshable {
- await viewModel.loadProjects()
+ await viewModel.loadProjects(forceRefresh: true)
}
.connectivityOverlay(hasContent: !viewModel.projects.isEmpty) {
await viewModel.loadProjects()
diff --git a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
index 9b6b942..82e1592 100644
--- a/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
+++ b/Hutch/Views/Repositories/RepositoryDetailViewModel.swift
@@ -627,7 +627,7 @@ final class RepositoryDetailViewModel {
/// Artifacts are release tarballs and signatures rather than media, so a
/// generic binary type is honest more often than guessing from the extension.
- private nonisolated static func mimeType(for url: URL) -> String {
+ private nonisolated static func mimeType(for _: URL) -> String {
"application/octet-stream"
}
diff --git a/Hutch/Views/Tickets/TicketDetailView.swift b/Hutch/Views/Tickets/TicketDetailView.swift
index b114fa6..6339776 100644
--- a/Hutch/Views/Tickets/TicketDetailView.swift
+++ b/Hutch/Views/Tickets/TicketDetailView.swift
@@ -204,7 +204,7 @@ struct TicketDetailView: View {
}
}
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* dismisses the dialog; no action needed */ }
} message: {
Text("This permanently deletes the ticket and its comments. This cannot be undone.")
}