krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

ad108c76d062099af9e698e1f0ba0d8cecfeab1f

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-07-16T06:16:39Z

fix: deleted repositories linger until the cache expires

Deleting a repository left it on the list, and pulling to refresh did not shift
it. Two independent reasons, both cache-related.

deleteRepository never invalidated anything. Creation invalidates the
repositories and home prefixes; deletion was written without it, so the list and
Home kept serving a repository that no longer exists.

And forceRefresh only ever reached the build statuses — its own doc comment says
so — while the repository list itself was pinned to useCache: true. So a pull to
refresh re-served the same cache it already had. fetchPage already takes
useCache and falls through to an uncached fetch; it was simply never told.
 Hutch/Views/Repositories/RepositoryListViewModel.swift     | 5 ++++-
 Hutch/Views/Repositories/RepositorySettingsViewModel.swift | 5 +++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/Hutch/Views/Repositories/RepositoryListViewModel.swift b/Hutch/Views/Repositories/RepositoryListViewModel.swift
index 695abf8..b3669e6 100644
--- a/Hutch/Views/Repositories/RepositoryListViewModel.swift
+++ b/Hutch/Views/Repositories/RepositoryListViewModel.swift
@@ -189,7 +189,10 @@ final class RepositoryListViewModel {
                     filteredResults = []
                 }
             } else {
-                let repositories = try await fetchAllRepositories(useCache: true)
+                // forceRefresh used to reach only the build statuses, so a pull to
+                // refresh re-served the cached list and a deleted repository stayed
+                // on screen.
+                let repositories = try await fetchAllRepositories(useCache: !forceRefresh)
                 updateSearchIndex(with: repositories)
                 filteredResults = repositories
             }
diff --git a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
index dd8d7a1..0b31125 100644
--- a/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
+++ b/Hutch/Views/Repositories/RepositorySettingsViewModel.swift
@@ -231,6 +231,11 @@ final class RepositorySettingsViewModel {
                 variables: ["id": repositoryId],
                 responseType: DeleteRepositoryResponse.self
             )
+            // The list and Home are both served from cache, so without this the
+            // repository lingers on screen after it no longer exists. Creation
+            // already does this; deletion never did.
+            await client.invalidateCache(prefix: APICacheKeys.prefix(service.rawValue, "repositories"))
+            await client.invalidateCache(prefix: APICacheKeys.prefix("home"))
             didDelete = true
         } catch {
             self.error = error.userFacingMessage