Skip to content

Commit

Permalink
feat(ios): separate list for leagues and events
Browse files Browse the repository at this point in the history
  • Loading branch information
autoreleasefool committed Aug 7, 2024
1 parent a9f10ec commit 6cf3b5c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 12 deletions.
61 changes: 51 additions & 10 deletions ios/Approach/Sources/LeaguesListFeature/LeaguesList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ extension League.Ordering: CustomStringConvertible {
@Reducer
// swiftlint:disable:next type_body_length
public struct LeaguesList: Reducer, Sendable {
public typealias SectionList = SectionResourceList<League.List, League.List.FetchRequest>

@ObservableState
public struct State: Equatable {
public let bowler: Bowler.Summary

public var list: ResourceList<League.List, League.List.FetchRequest>.State
public var list: SectionList.State
public var preferredGear: PreferredGear.State
public var widgets: StatisticsWidgetLayout.State

Expand All @@ -57,7 +59,7 @@ public struct LeaguesList: Reducer, Sendable {
self.filter = filter
self.widgets = .init(context: LeaguesList.widgetContext(forBowler: bowler.id), newWidgetSource: .bowler(bowler.id))
self.preferredGear = .init(bowler: bowler.id)
self.list = .init(
self.list = SectionList.State(
features: [
.add,
.swipeToEdit,
Expand Down Expand Up @@ -101,7 +103,7 @@ public struct LeaguesList: Reducer, Sendable {

case errors(Errors<ErrorID>.Action)
case preferredGear(PreferredGear.Action)
case list(ResourceList<League.List, League.List.FetchRequest>.Action)
case list(SectionList.Action)
case widgets(StatisticsWidgetLayout.Action)
case destination(PresentationAction<Destination.Action>)
}
Expand All @@ -120,6 +122,11 @@ public struct LeaguesList: Reducer, Sendable {
case sortOrder(SortOrder<League.Ordering>)
}

public enum SectionID: String {
case leagues
case events
}

public enum ErrorID: Hashable {
case leagueNotFound
case failedToArchiveLeague
Expand All @@ -143,12 +150,8 @@ public struct LeaguesList: Reducer, Sendable {
}

Scope(state: \.list, action: \.internal.list) {
ResourceList { request in
leagues.list(
bowledBy: request.filter.bowler,
withRecurrence: request.filter.recurrence,
ordering: request.ordering
)
SectionResourceList { @Sendable in
fetchResources(query: $0)
}
}

Expand Down Expand Up @@ -325,7 +328,7 @@ public struct LeaguesList: Reducer, Sendable {
.destination(.presented(.games(.view))),
.destination(.presented(.games(.delegate(.doNothing)))),
.preferredGear(.internal), .preferredGear(.view),
.list(.internal), .list(.view),
.list(.internal), .list(.view), .list(.binding),
.widgets(.internal), .widgets(.view),
.errors(.internal), .errors(.view):
return .none
Expand Down Expand Up @@ -367,6 +370,44 @@ public struct LeaguesList: Reducer, Sendable {
}
}
}

private func fetchResources(
query: League.List.FetchRequest
) -> AsyncThrowingStream<[SectionList.Section], Error> {
return AsyncThrowingStream { continuation in
let task = Task {
do {
for try await leagues in self.leagues.list(
bowledBy: query.filter.bowler,
withRecurrence: query.filter.recurrence,
ordering: query.ordering
) {
let repeating = IdentifiedArrayOf<League.List>(
uniqueElements: leagues.filter { $0.recurrence == .repeating }
)
let oneOffs = IdentifiedArrayOf<League.List>(
uniqueElements: leagues.filter { $0.recurrence == .once }
)

continuation.yield([
repeating.isEmpty ? nil : SectionList.Section(
id: SectionID.leagues.rawValue,
title: Strings.League.List.Repeating.title,
items: repeating
),
oneOffs.isEmpty ? nil : SectionList.Section(
id: SectionID.events.rawValue,
title: Strings.League.List.Once.title,
items: oneOffs
),
].compactMap { $0 })
}
}
}

continuation.onTermination = { _ in task.cancel() }
}
}
}

extension LeaguesList {
Expand Down
4 changes: 2 additions & 2 deletions ios/Approach/Sources/LeaguesListFeature/LeaguesListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public struct LeaguesListView: View {
}

public var body: some View {
ResourceListView(
SectionResourceListView(
store: store.scope(state: \.list, action: \.internal.list)
) { league in
) { _, league in
Button { send(.didTapLeague(id: league.id)) } label: {
LabeledContent(league.name, value: format(average: league.average))
}
Expand Down
1 change: 1 addition & 0 deletions ios/Approach/Sources/ModelsLibrary/League.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ extension League {
public struct List: Identifiable, Codable, Equatable {
public let id: League.ID
public let name: String
public let recurrence: Recurrence
public let average: Double?

public var summary: Summary {
Expand Down
8 changes: 8 additions & 0 deletions ios/Approach/Sources/StringsLibrary/Strings+Generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,14 @@ public enum Strings {
public static let add = Strings.tr("Localizable", "league.list.add", fallback: "Add League")
/// Leagues
public static let title = Strings.tr("Localizable", "league.list.title", fallback: "Leagues")
public enum Once {
/// Events
public static let title = Strings.tr("Localizable", "league.list.once.title", fallback: "Events")
}
public enum Repeating {
/// Leagues
public static let title = Strings.tr("Localizable", "league.list.repeating.title", fallback: "Leagues")
}
}
public enum Properties {
/// Additional Games
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@
"league.title" = "League";
"league.list.title" = "Leagues";
"league.list.add" = "Add League";
"league.list.repeating.title" = "Leagues";
"league.list.once.title" = "Events";
"league.filters.title" = "Filter Leagues";
"league.properties.alley" = "Bowling Alley";
"league.properties.recurrence" = "Repeat?";
Expand Down

0 comments on commit 6cf3b5c

Please sign in to comment.