From 61164b6dd8343c8699d091dd5fccc55beb0b90b9 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Sat, 11 Apr 2026 19:47:40 -0500 Subject: feat: add contribution calendar to user profiles Add a trailing 365-day contribution heatmap to user profile views, backed by HutchStatsService. Includes calendar model, view model, SwiftUI calendar view, app configuration, and unit tests. --- Hutch/App/AppState.swift | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Hutch/App/AppState.swift') diff --git a/Hutch/App/AppState.swift b/Hutch/App/AppState.swift index 8613dc8..c519adc 100644 --- a/Hutch/App/AppState.swift +++ b/Hutch/App/AppState.swift @@ -56,6 +56,7 @@ final class AppState { // MARK: - Networking let client: SRHTClient + let configuration: AppConfiguration // MARK: - Deep link pending navigation @@ -67,6 +68,7 @@ final class AppState { // MARK: - Init init() { + self.configuration = AppConfiguration() let token = KeychainHelper.loadToken() self.client = SRHTClient(token: token) } @@ -107,11 +109,13 @@ final class AppState { accounts = storedAccounts activeAccountID = target.id currentUser = user + ContributionWidgetContextStore.saveActor(user.canonicalName) authPhase = .authenticated await refreshNeedsAttentionSnapshot() } catch { client.setToken(nil) currentUser = nil + ContributionWidgetContextStore.clear() authPhase = .unauthenticated NeedsAttentionSnapshotStore.clear() } @@ -131,6 +135,7 @@ final class AppState { UserDefaults.standard.set(entry.id, forKey: AppStorageKeys.activeAccountID) try KeychainHelper.saveAccounts(accounts) currentUser = user + ContributionWidgetContextStore.saveActor(user.canonicalName) authPhase = .authenticated await refreshNeedsAttentionSnapshot() } catch { @@ -168,6 +173,7 @@ final class AppState { let user = try await fetchMe() currentUser = user + ContributionWidgetContextStore.saveActor(user.canonicalName) authPhase = .authenticated await refreshNeedsAttentionSnapshot() } @@ -355,6 +361,7 @@ final class AppState { activeAccountID = "" UserDefaults.standard.removeObject(forKey: AppStorageKeys.activeAccountID) currentUser = nil + ContributionWidgetContextStore.clear() pendingDeepLink = nil pendingTabNavigation = nil deepLinkError = nil -- cgit v1.2.3