Skip to content

Commit b27ebad

Browse files
authored
Обновил состояние экрана со списком площадок для пользователя (#319)
* Доработал экран с добавленными площадками По аналогии с другими экранами, где есть разные варианты состояний - в случае ошибки показываем вьюху с текстом ошибки, а не алерт * Убрал лишний текст "Загрузка..."
1 parent c4348b7 commit b27ebad

File tree

8 files changed

+105
-87
lines changed

8 files changed

+105
-87
lines changed

SwiftUI-WorkoutApp/Resources/Localizable.xcstrings

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,16 +1641,6 @@
16411641
}
16421642
}
16431643
},
1644-
"Загрузка..." : {
1645-
"localizations" : {
1646-
"en" : {
1647-
"stringUnit" : {
1648-
"state" : "translated",
1649-
"value" : "Loading..."
1650-
}
1651-
}
1652-
}
1653-
},
16541644
"Закрыть" : {
16551645
"localizations" : {
16561646
"en" : {

SwiftUI-WorkoutApp/Screens/Common/FriendsListScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ private extension FriendsListScreen {
9191
case let .error(errorKind):
9292
CommonErrorView(errorKind: errorKind)
9393
case .initial, .loading:
94-
ContainerRelativeView {
95-
Text("Загрузка...")
96-
}
94+
EmptyView()
9795
}
9896
}
9997

SwiftUI-WorkoutApp/Screens/Messages/DialogsListScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ private extension DialogsListScreen {
9494
case let .error(errorKind):
9595
CommonErrorView(errorKind: errorKind)
9696
case .initial, .loading:
97-
ContainerRelativeView {
98-
Text("Загрузка...")
99-
}
97+
EmptyView()
10098
}
10199
}
102100

SwiftUI-WorkoutApp/Screens/Parks/ParksListScreen.swift

Lines changed: 99 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,36 @@ import SWUtils
77
/// Экран со списком площадок
88
struct ParksListScreen: View {
99
@Environment(\.dismiss) private var dismiss
10+
@Environment(\.isNetworkConnected) private var isNetworkConnected
1011
@EnvironmentObject private var defaults: DefaultsService
1112
@EnvironmentObject private var parksManager: ParksManager
12-
@State private var parks = [Park]()
13-
@State private var isLoading = false
13+
@State private var currentState = CurrentState.initial
1414
/// Площадка для открытия детального экрана
1515
@State private var selectedPark: Park?
16+
private var client: SWClient { SWClient(with: defaults) }
1617
let mode: Mode
1718

1819
var body: some View {
1920
ScrollView {
20-
LazyVStack(spacing: 12) {
21-
ForEach(parks) { park in
22-
Button {
23-
switch mode {
24-
case let .event(_, callBack):
25-
callBack(park.id, park.name ?? park.longTitle)
26-
dismiss()
27-
case .usedBy, .added:
28-
selectedPark = park
29-
}
30-
} label: {
31-
ParkRowView(
32-
imageURL: park.previewImageURL,
33-
title: park.longTitle,
34-
address: park.address,
35-
usersTrainHereText: park.usersTrainHereText
36-
)
37-
}
38-
.accessibilityIdentifier("ParkViewCell")
39-
}
40-
}
41-
.padding([.top, .horizontal])
21+
contentView
22+
.animation(.default, value: currentState)
23+
.frame(maxWidth: .infinity)
4224
}
43-
.loadingOverlay(if: isLoading)
25+
.loadingOverlay(if: currentState.isLoading)
4426
.background(Color.swBackground)
4527
.sheet(item: $selectedPark) { park in
4628
NavigationView {
4729
ParkDetailScreen(park: park) { deletePark(id: $0) }
4830
}
4931
.navigationViewStyle(.stack)
5032
}
51-
.onChange(of: parks) { list in
52-
if list.isEmpty {
53-
defaults.setUserNeedUpdate(true)
33+
.onChange(of: currentState) { newState in
34+
if newState.isReadyAndEmpty {
5435
dismiss()
5536
}
5637
}
5738
.task { await askForParks() }
5839
.refreshable {
59-
guard mode.canRefreshList else { return }
6040
await askForParks(refresh: true)
6141
}
6242
.toolbar {
@@ -71,16 +51,45 @@ struct ParksListScreen: View {
7151

7252
extension ParksListScreen {
7353
enum Mode {
54+
/// Площадки, где тренируется пользователь
7455
case usedBy(userID: Int)
56+
/// Площадки, где тренируется пользователь, для создания мероприятия
7557
case event(userID: Int, didSelectPark: (_ id: Int, _ name: String) -> Void)
58+
/// Площадки, добавленные пользователем
7659
case added(list: [Park])
60+
}
61+
}
62+
63+
extension ParksListScreen {
64+
enum CurrentState: Equatable {
65+
case initial
66+
case loading
67+
case ready([Park])
68+
case error(ErrorKind)
69+
70+
var isLoading: Bool {
71+
if case .loading = self { true } else { false }
72+
}
73+
74+
/// Нужно ли загружать данные, когда их нет (или для рефреша)
75+
var shouldLoad: Bool {
76+
switch self {
77+
case .initial, .error: true
78+
case let .ready(parks): parks.isEmpty
79+
case .loading: false
80+
}
81+
}
7782

78-
var canRefreshList: Bool {
83+
var isReadyAndNotEmpty: Bool {
7984
switch self {
80-
case .added: false
81-
case .usedBy, .event: true
85+
case let .ready(parks): !parks.isEmpty
86+
default: false
8287
}
8388
}
89+
90+
var isReadyAndEmpty: Bool {
91+
if case let .ready(parks) = self { parks.isEmpty } else { false }
92+
}
8493
}
8594
}
8695

@@ -95,6 +104,39 @@ private extension ParksListScreen.Mode {
95104
}
96105

97106
private extension ParksListScreen {
107+
@ViewBuilder
108+
var contentView: some View {
109+
switch currentState {
110+
case let .ready(parks):
111+
LazyVStack(spacing: 12) {
112+
ForEach(parks) { park in
113+
Button {
114+
switch mode {
115+
case let .event(_, callBack):
116+
callBack(park.id, park.name ?? park.longTitle)
117+
dismiss()
118+
case .usedBy, .added:
119+
selectedPark = park
120+
}
121+
} label: {
122+
ParkRowView(
123+
imageURL: park.previewImageURL,
124+
title: park.longTitle,
125+
address: park.address,
126+
usersTrainHereText: park.usersTrainHereText
127+
)
128+
}
129+
.accessibilityIdentifier("ParkViewCell")
130+
}
131+
}
132+
.padding([.top, .horizontal])
133+
case let .error(errorKind):
134+
CommonErrorView(errorKind: errorKind)
135+
case .initial, .loading:
136+
EmptyView()
137+
}
138+
}
139+
98140
@ViewBuilder
99141
var refreshButtonIfNeeded: some View {
100142
if !DeviceOSVersionChecker.iOS16Available {
@@ -103,47 +145,45 @@ private extension ParksListScreen {
103145
} label: {
104146
Icons.Regular.refresh.view
105147
}
106-
.disabled(isLoading)
148+
.disabled(currentState.isLoading)
107149
}
108150
}
109151

110152
func askForParks(refresh: Bool = false) async {
111-
if isLoading { return }
112-
do {
113-
switch mode {
114-
case let .usedBy(userID), let .event(userID, _):
115-
let isMainUser = userID == defaults.mainUserInfo?.id
116-
let needUpdate = parks.isEmpty || refresh
117-
if isMainUser {
118-
if !needUpdate, !defaults.needUpdateUser { return }
119-
try await makeList(for: userID, isMainUser, refresh)
153+
switch mode {
154+
case let .usedBy(userID), let .event(userID, _):
155+
guard currentState.shouldLoad || refresh else { return }
156+
guard isNetworkConnected else {
157+
if currentState.isReadyAndNotEmpty {
158+
SWAlert.shared.presentNoConnection(false)
120159
} else {
121-
if !needUpdate { return }
122-
try await makeList(for: userID, isMainUser, refresh)
160+
currentState = .error(.notConnected)
123161
}
124-
case let .added(list):
125-
parks = list
162+
return
126163
}
127-
} catch {
128-
SWAlert.shared.presentDefaultUIKit(error)
164+
if !refresh {
165+
currentState = .loading
166+
}
167+
do {
168+
let parks = try await SWClient(with: defaults).getParksForUser(userID)
169+
let isMainUser = userID == defaults.mainUserInfo?.id
170+
if isMainUser { defaults.setUserNeedUpdate(false) }
171+
currentState = .ready(parks)
172+
} catch {
173+
currentState = .error(.common(message: error.localizedDescription))
174+
}
175+
case let .added(list):
176+
currentState = .ready(list)
129177
}
130-
isLoading = false
131-
}
132-
133-
func makeList(for userID: Int, _ isMainUser: Bool, _ isRefreshing: Bool) async throws {
134-
if !isRefreshing { isLoading = true }
135-
if isMainUser { defaults.setUserNeedUpdate(false) }
136-
parks = try await SWClient(with: defaults).getParksForUser(userID)
137178
}
138179

139180
func deletePark(id: Int) {
140181
selectedPark = nil
141-
parks.removeAll(where: { $0.id == id })
182+
guard case let .ready(parks) = currentState else { return }
142183
do {
143184
try parksManager.deletePark(with: id)
144-
if !mode.canRefreshList {
145-
dismiss()
146-
}
185+
let updatedParks = parks.filter { $0.id != id }
186+
currentState = .ready(updatedParks)
147187
} catch {
148188
SWAlert.shared.presentDefaultUIKit(error)
149189
}

SwiftUI-WorkoutApp/Screens/Profile/BlackListScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,7 @@ private extension BlackListScreen {
101101
case let .error(errorKind):
102102
CommonErrorView(errorKind: errorKind)
103103
case .initial, .loading:
104-
ContainerRelativeView {
105-
Text("Загрузка...")
106-
}
104+
EmptyView()
107105
}
108106
}
109107

SwiftUI-WorkoutApp/Screens/Profile/Journals/JournalEntriesScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ private extension JournalEntriesScreen {
125125
case let .error(errorKind):
126126
CommonErrorView(errorKind: errorKind)
127127
case .initial, .loading:
128-
ContainerRelativeView {
129-
Text("Загрузка...")
130-
}
128+
EmptyView()
131129
}
132130
}
133131

SwiftUI-WorkoutApp/Screens/Profile/Journals/JournalsListScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,7 @@ private extension JournalsListScreen {
146146
case let .error(errorKind):
147147
CommonErrorView(errorKind: errorKind)
148148
case .initial, .loading:
149-
ContainerRelativeView {
150-
Text("Загрузка...")
151-
}
149+
EmptyView()
152150
}
153151
}
154152

SwiftUI-WorkoutApp/Screens/Profile/MainUserFriendsListScreen.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,7 @@ private extension MainUserFriendsListScreen {
9797
case let .error(errorKind):
9898
CommonErrorView(errorKind: errorKind)
9999
case .initial, .loading:
100-
ContainerRelativeView {
101-
Text("Загрузка...")
102-
}
100+
EmptyView()
103101
}
104102
}
105103

0 commit comments

Comments
 (0)