import SwiftUI /// What this instance hosts. `repo search` needs a query; this is the /// listing you read when you do not know a name yet. struct ExploreView: View { @State private var list: PagedListModel init(client: GitbayClient) { _list = State(initialValue: PagedListModel( client: client, argv: ["explore"], emptyMessage: "This instance hosts no public repositories." )) } /// One Text, not two: the HStack spaces its children, and a gap /// between the owner and the name would read as part of the path. private func path(of repo: PublicRepo) -> AttributedString { var owner = AttributedString(repo.owner + "/") owner.foregroundColor = .secondary var name = AttributedString(repo.name) name.font = .gbSans(.subheadline).weight(.medium) return owner + name } var body: some View { List { ForEach(list.state.value ?? []) { repo in NavigationLink(value: RepoRoute.repo(repo.path)) { VStack(alignment: .leading, spacing: 4) { HStack(spacing: 6) { Text(path(of: repo)) if repo.isArchived { GBChip("archived", .secondary) } } .font(.gbSans(.subheadline)) .lineLimit(1) if let description = repo.description, !description.isEmpty { Text(description) .font(.gbSans(.caption)) .foregroundStyle(.secondary) .lineLimit(2) } if let topics = repo.topics, !topics.isEmpty { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 6) { ForEach(topics, id: \.self) { topic in GBChip(topic, .gbAccent) } } } } } .padding(.vertical, 2) } } PageFooter(list: list) } .overlay { LoadStateOverlay(state: list.state) } .navigationTitle("Explore") .task { if list.state.value == nil { await list.reload() } } .refreshable { await list.reload() } } }