@@ -411,15 +411,13 @@ public struct AppsView: View {
411411 @State private var selectedApp : AltApp ? = nil
412412 @State private var sortOption : SortOption = . nameAZ
413413
414- /// Which repositories are expanded (by repository key string). Starts with all repos expanded when apps load.
414+ /// Which repositories are expanded (by repository key string).
415415 @State private var expandedRepos : Set < String > = [ ]
416416
417417 public init ( repoURLs: [ URL ] = [ URL ( string: " https://repository.apptesters.org/ " ) !] ) {
418418 _vm = StateObject ( wrappedValue: RepoViewModel ( sourceURLs: repoURLs) )
419419 }
420420
421- // MARK: - Smaller computed helpers to keep `body` tiny
422-
423421 private var sortedApps : [ AltApp ] {
424422 switch sortOption {
425423 case . nameAZ:
@@ -598,34 +596,45 @@ public struct AppsView: View {
598596 }
599597
600598 @ViewBuilder private func repoSection( _ repoKey: String ) -> some View {
599+ // NOTE: If collapsed, show header only (no app rows)
601600 Section {
602601 if expandedRepos. contains ( repoKey) {
603602 ForEach ( groupedApps [ repoKey] ?? [ ] ) { app in
604603 Button { selectedApp = app } label: { AppRowView ( app: app) }
605604 . buttonStyle ( . plain)
606605 }
607606 } else {
608- if let first = groupedApps [ repoKey] ? . first {
609- Button { selectedApp = first } label: { AppRowView ( app: first) . opacity ( 0.85 ) }
610- . buttonStyle ( . plain)
611- }
607+ // collapsed: intentionally show no rows
608+ EmptyView ( )
612609 }
613610 } header: {
614611 repoHeader ( repoKey)
615612 }
616613 }
617614
618615 @ViewBuilder private var listView : some View {
619- List {
620- ForEach ( orderedRepoKeys, id: \. self) { repoKey in
621- repoSection ( repoKey)
616+ if sortOption == . repoAZ {
617+ List {
618+ ForEach ( orderedRepoKeys, id: \. self) { repoKey in
619+ repoSection ( repoKey)
620+ }
622621 }
622+ . listStyle ( PlainListStyle ( ) )
623+ . refreshable { vm. refresh ( ) }
624+ } else {
625+ // flat list for all other sort modes
626+ List {
627+ ForEach ( filteredApps) { app in
628+ Button { selectedApp = app } label: { AppRowView ( app: app) }
629+ . buttonStyle ( . plain)
630+ }
631+ }
632+ . listStyle ( PlainListStyle ( ) )
633+ . refreshable { vm. refresh ( ) }
623634 }
624- . listStyle ( PlainListStyle ( ) )
625- . refreshable { vm. refresh ( ) }
626635 }
627636
628- // MARK: - Body stays small and easy to type-check
637+ // MARK: - Body
629638 public var body : some View {
630639 VStack ( spacing: 0 ) {
631640 searchAndSortBar
@@ -662,16 +671,26 @@ public struct AppsView: View {
662671 }
663672 }
664673 . onAppear {
665- expandedRepos = Set ( orderedRepoKeys)
674+ expandedRepos = ( sortOption == . repoAZ ) ? Set ( orderedRepoKeys) : [ ]
666675 }
667676 . onChange ( of: vm. apps) { _ in
668- expandedRepos = Set ( orderedRepoKeys)
677+ if sortOption == . repoAZ {
678+ expandedRepos = Set ( orderedRepoKeys)
679+ } else {
680+ expandedRepos. removeAll ( )
681+ }
669682 }
670683 . onChange ( of: searchText) { _ in
671- expandedRepos. formUnion ( orderedRepoKeys)
684+ if sortOption == . repoAZ {
685+ expandedRepos. formUnion ( orderedRepoKeys)
686+ }
672687 }
673- . onChange ( of: sortOption) { _ in
674- expandedRepos. formUnion ( orderedRepoKeys)
688+ . onChange ( of: sortOption) { newOption in
689+ if newOption == . repoAZ {
690+ expandedRepos. formUnion ( orderedRepoKeys)
691+ } else {
692+ expandedRepos. removeAll ( )
693+ }
675694 }
676695 }
677696}
0 commit comments