diff options
| author | Christian Cleberg <[email protected]> | 2026-04-12 11:49:45 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-12 11:49:45 -0500 |
| commit | 9e48e4681487b1c69577c0e9e5f83d8d8225e494 (patch) | |
| tree | 825ce946dac13ad24a123b647722a6cab6c51599 | |
| parent | c0744a35891f89e50ab407a0b8557ce9d5c5e6cc (diff) | |
| download | hutch-9e48e4681487b1c69577c0e9e5f83d8d8225e494.tar.gz hutch-9e48e4681487b1c69577c0e9e5f83d8d8225e494.tar.bz2 hutch-9e48e4681487b1c69577c0e9e5f83d8d8225e494.zip | |
feat: add prioritization of polling hutch-stats for logged in user
| -rw-r--r-- | Hutch.xcodeproj/project.pbxproj | 12 | ||||
| -rw-r--r-- | Hutch/Networking/HutchStatsService.swift | 19 | ||||
| -rw-r--r-- | Hutch/Views/Lookup/UserProfileView.swift | 5 | ||||
| -rw-r--r-- | Hutch/Views/More/ProfileView.swift | 5 | ||||
| -rw-r--r-- | HutchTests/ContributionCalendarTests.swift | 24 |
5 files changed, 52 insertions, 13 deletions
diff --git a/Hutch.xcodeproj/project.pbxproj b/Hutch.xcodeproj/project.pbxproj index 1fe01ce..7e0ee15 100644 --- a/Hutch.xcodeproj/project.pbxproj +++ b/Hutch.xcodeproj/project.pbxproj @@ -532,7 +532,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.15.1; + MARKETING_VERSION = 2.15.2; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -569,7 +569,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.15.1; + MARKETING_VERSION = 2.15.2; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -632,7 +632,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchWidgetExtension/Info.plist; @@ -642,7 +642,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.15.1; + MARKETING_VERSION = 2.15.2; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -661,7 +661,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = ZCNAX3VL9D; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HutchWidgetExtension/Info.plist; @@ -671,7 +671,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.15.1; + MARKETING_VERSION = 2.15.2; PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; diff --git a/Hutch/Networking/HutchStatsService.swift b/Hutch/Networking/HutchStatsService.swift index 69a2a20..52d86b9 100644 --- a/Hutch/Networking/HutchStatsService.swift +++ b/Hutch/Networking/HutchStatsService.swift @@ -9,20 +9,23 @@ struct HutchStatsService: ContributionCalendarServing { private let session: URLSession private let decoder: JSONDecoder private let baseURL: URL + private let currentActor: String? init( session: URLSession = .shared, - configuration: AppConfiguration + configuration: AppConfiguration, + currentActor: String? = nil ) { self.session = session self.baseURL = configuration.hutchStatsBaseURL self.decoder = JSONDecoder() + self.currentActor = currentActor } func fetchContributionCalendar(actor: String, endingOn endDate: Date) async throws -> ContributionCalendarResponse { return try await fetch( path: "api/contributions/\(actor)", - queryItems: trailingYearQueryItems(endingOn: endDate), + queryItems: contributionQueryItems(actor: actor, endingOn: endDate), responseType: ContributionCalendarResponse.self ) } @@ -30,7 +33,7 @@ struct HutchStatsService: ContributionCalendarServing { func fetchContributionStats(actor: String, endingOn endDate: Date) async throws -> ContributionStatsResponse { return try await fetch( path: "api/contributions/\(actor)/stats", - queryItems: trailingYearQueryItems(endingOn: endDate), + queryItems: contributionQueryItems(actor: actor, endingOn: endDate), responseType: ContributionStatsResponse.self ) } @@ -86,15 +89,21 @@ struct HutchStatsService: ContributionCalendarServing { return normalizedStartDate...normalizedEndDate } - private func trailingYearQueryItems(endingOn endDate: Date) -> [URLQueryItem] { + func contributionQueryItems(actor: String, endingOn endDate: Date) -> [URLQueryItem] { let range = trailingRange(endingOn: endDate) let start = Self.rangeFormatter.string(from: range.lowerBound) let end = Self.rangeFormatter.string(from: range.upperBound) - return [ + var queryItems = [ URLQueryItem(name: "from", value: start), URLQueryItem(name: "to", value: end) ] + + if actor == currentActor { + queryItems.append(URLQueryItem(name: "prioritize", value: "self")) + } + + return queryItems } private static let rangeFormatter: DateFormatter = { diff --git a/Hutch/Views/Lookup/UserProfileView.swift b/Hutch/Views/Lookup/UserProfileView.swift index bc04b08..b467c63 100644 --- a/Hutch/Views/Lookup/UserProfileView.swift +++ b/Hutch/Views/Lookup/UserProfileView.swift @@ -175,7 +175,10 @@ struct UserProfileView: View { ownerUsername: owner, actor: actor, client: appState.client, - statsService: HutchStatsService(configuration: appState.configuration) + statsService: HutchStatsService( + configuration: appState.configuration, + currentActor: appState.currentUser?.canonicalName + ) ) profileViewModel = newViewModel vm = newViewModel diff --git a/Hutch/Views/More/ProfileView.swift b/Hutch/Views/More/ProfileView.swift index a7172e4..53c5ce3 100644 --- a/Hutch/Views/More/ProfileView.swift +++ b/Hutch/Views/More/ProfileView.swift @@ -46,7 +46,10 @@ struct ProfileView: View { ownerUsername: owner, actor: actor, client: appState.client, - statsService: HutchStatsService(configuration: appState.configuration) + statsService: HutchStatsService( + configuration: appState.configuration, + currentActor: appState.currentUser?.canonicalName + ) ) contributionViewModel = newViewModel vm = newViewModel diff --git a/HutchTests/ContributionCalendarTests.swift b/HutchTests/ContributionCalendarTests.swift index 4ce2f1f..9e76e42 100644 --- a/HutchTests/ContributionCalendarTests.swift +++ b/HutchTests/ContributionCalendarTests.swift @@ -94,6 +94,30 @@ struct ContributionCalendarTests { } @Test + func selfContributionRequestsIncludeExplicitPrioritySignal() { + let service = HutchStatsService( + configuration: AppConfiguration(), + currentActor: "~alice" + ) + let endDate = ContributionDateParser.parse("2026-04-11")! + let queryItems = service.contributionQueryItems(actor: "~alice", endingOn: endDate) + + #expect(queryItems.contains(URLQueryItem(name: "prioritize", value: "self"))) + } + + @Test + func otherContributionRequestsDoNotIncludePrioritySignal() { + let service = HutchStatsService( + configuration: AppConfiguration(), + currentActor: "~alice" + ) + let endDate = ContributionDateParser.parse("2026-04-11")! + let queryItems = service.contributionQueryItems(actor: "~bob", endingOn: endDate) + + #expect(queryItems.contains(URLQueryItem(name: "prioritize", value: "self")) == false) + } + + @Test func contributionIntensityBucketsMatchProductRules() { #expect(ContributionIntensity(count: 0) == .empty) #expect(ContributionIntensity(count: 1) == .level1) |
