gitbay/Discovery/ProfileViewModel.swift
40 lines · 1163 bytes
1import Foundation
2import Observation
3
4/// `profile show <name>` plus the profile's reachable repositories via
5/// `repo search` filtered to the owner prefix.
6@Observable
7@MainActor
8final class ProfileViewModel {
9
10 nonisolated struct Profile: Decodable, Sendable, Hashable {
11 let name: String
12 let kind: String // user | org
13 let description: String?
14 let website: String?
15 }
16
17 private(set) var state: LoadState<Profile> = .loading
18 private(set) var repos: [RepoSummary] = []
19
20 private let client: GitbayClient
21 let name: String
22
23 init(client: GitbayClient, name: String) {
24 self.client = client
25 self.name = name
26 }
27
28 func load() async {
29 do {
30 state = .loaded(try await client.read(["profile", "show", name], as: Profile.self))
31 } catch {
32 state = .from(error)
33 return
34 }
35 // Search matches on path, so the owner name surfaces their repos;
36 // keep only true prefix matches.
37 repos = ((try? await client.readList(["repo", "search", name], of: RepoSummary.self)) ?? [])
38 .filter { $0.owner == name }
39 }
40}