Skip to content

Commit 54e68f5

Browse files
authored
Доработки (#278)
* Доработки в списке пользователей - Анимируем принятие заявки в друзья - После принятия заявки в друзья обновляем список друзей и отображаем нового друга - После ответа на заявку в друзья убираем эту заявку из списка на экране - При рефреше на экране с черным списком закрываем экран, если сервер прислал пустой черный список * Фильтруем ошибку CancellationError Похоже, есть баг в SUI, из-за которого лишний раз вызываются запросы внутри модификатора task при исчезновении вьюхи в определенной ситуации, нужно разбираться дальше * Нашел место, откуда вылезает ошибка -999 В статье № 106 будет подробный пример * Правка видимости профиля другого пользователя У некоторых пользователей не хватает данных, которые я считаю обязательными для отображения профиля, например, возраст, имя или город - раньше их не показывали и был пустой экран, а теперь показываем все, что есть
1 parent f786088 commit 54e68f5

22 files changed

+108
-79
lines changed

SwiftUI-WorkoutApp.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@
856856
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
857857
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
858858
CODE_SIGN_STYLE = Automatic;
859-
CURRENT_PROJECT_VERSION = 9;
859+
CURRENT_PROJECT_VERSION = 10;
860860
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
861861
DEVELOPMENT_TEAM = CR68PP2Z3F;
862862
ENABLE_PREVIEWS = YES;
@@ -907,7 +907,7 @@
907907
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
908908
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
909909
CODE_SIGN_STYLE = Automatic;
910-
CURRENT_PROJECT_VERSION = 9;
910+
CURRENT_PROJECT_VERSION = 10;
911911
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
912912
DEVELOPMENT_TEAM = CR68PP2Z3F;
913913
ENABLE_PREVIEWS = YES;

SwiftUI-WorkoutApp/Libraries/SWNetwork/Sources/SWNetwork/SWNetwork.swift

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,20 @@ private extension SWNetworkService {
163163
/// - Returns: Новая ошибка
164164
@discardableResult
165165
func handleUrlSession(_ error: Error, _ request: URLRequest) -> Error {
166-
if (error as NSError).code == -999 {
167-
assertionFailure("Запрос отменён! Код ошибки: -999")
166+
let errorCode = (error as NSError).code
167+
if errorCode == -999 {
168+
let message = "Запрос отменён! Код ошибки: -999. URL запроса: \(request.urlString)"
169+
logger.error("\(message)")
170+
} else {
171+
logger.error(
172+
"""
173+
Ошибка!
174+
\(error.localizedDescription, privacy: .public)
175+
Код ошибки: \(errorCode, privacy: .public)
176+
\nURL запроса: \(request.urlString, privacy: .public)
177+
"""
178+
)
168179
}
169-
logger.error(
170-
"""
171-
\(error.localizedDescription, privacy: .public)
172-
\nURL запроса: \(request.urlString, privacy: .public)
173-
"""
174-
)
175180
guard let urlError = error as? URLError else {
176181
return error
177182
}

SwiftUI-WorkoutApp/Libraries/SWUtils/Sources/SWUtils/SWAlert.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ public final class SWAlert {
3434
topMostViewController.present(alert, animated: true)
3535
}
3636

37+
/// Показывает стандартный алерт с сообщение об ошибке
38+
///
39+
/// Игнорирует `CancellationError`
40+
public func presentDefaultUIKit(_ error: Error) {
41+
guard (error as NSError).code != -999 else { return }
42+
presentDefaultUIKit(message: error.localizedDescription)
43+
}
44+
3745
private func dismiss() {
3846
currentAlert?.dismiss(animated: true)
3947
currentAlert = nil

SwiftUI-WorkoutApp/Screens/Common/ImagePicker/ModernPickedImagesGrid.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct ModernPickedImagesGrid: View {
6666
let newImages = try await loadImages(from: selectedItems)
6767
images.append(contentsOf: newImages)
6868
} catch {
69-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
69+
SWAlert.shared.presentDefaultUIKit(error)
7070
}
7171
selectedItems.removeAll()
7272
isLoading.toggle()

SwiftUI-WorkoutApp/Screens/Common/TextEntryScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private extension TextEntryScreen {
124124
}
125125
if isSuccess { refreshClbk() }
126126
} catch {
127-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
127+
SWAlert.shared.presentDefaultUIKit(error)
128128
}
129129
isLoading = false
130130
}

SwiftUI-WorkoutApp/Screens/Common/UsersListScreen.swift

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import SWUtils
66

77
/// Экран со списком пользователей
88
struct UsersListScreen: View {
9+
@Environment(\.dismiss) private var dismiss
910
@Environment(\.isNetworkConnected) private var isNetworkConnected
1011
@EnvironmentObject private var defaults: DefaultsService
1112
@State private var users = [UserResponse]()
@@ -21,20 +22,10 @@ struct UsersListScreen: View {
2122
ScrollView {
2223
VStack(spacing: 0) {
2324
friendRequestsSectionIfNeeded
24-
SectionView(
25-
header: friendRequests.isEmpty ? nil : "Друзья",
26-
mode: .regular
27-
) {
28-
LazyVStack(spacing: 12) {
29-
ForEach(users) { item in
30-
listItem(for: item)
31-
.disabled(item.id == defaults.mainUserInfo?.id)
32-
}
33-
}
34-
}
35-
.padding(.top)
25+
friendsSectionIfNeeded
3626
}
3727
.padding(.horizontal)
28+
.frame(maxWidth: .infinity)
3829
}
3930
.sheet(
4031
item: $messagingModel.recipient,
@@ -98,6 +89,27 @@ private extension UsersListScreen {
9889
}
9990
}
10091

92+
@ViewBuilder
93+
var friendsSectionIfNeeded: some View {
94+
ZStack {
95+
if !users.isEmpty {
96+
SectionView(
97+
header: friendRequests.isEmpty ? nil : "Друзья",
98+
mode: .regular
99+
) {
100+
LazyVStack(spacing: 12) {
101+
ForEach(users) { item in
102+
listItem(for: item)
103+
.disabled(item.id == defaults.mainUserInfo?.id)
104+
}
105+
}
106+
}
107+
}
108+
}
109+
.animation(.default, value: users)
110+
.padding(.top)
111+
}
112+
101113
@ViewBuilder
102114
func listItem(for model: UserResponse) -> some View {
103115
switch mode {
@@ -146,7 +158,7 @@ private extension UsersListScreen {
146158
let isSuccess = try await client.sendMessage(messagingModel.message, to: userID)
147159
endMessaging(isSuccess: isSuccess)
148160
} catch {
149-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
161+
SWAlert.shared.presentDefaultUIKit(error)
150162
}
151163
messagingModel.isLoading = false
152164
}
@@ -166,32 +178,24 @@ private extension UsersListScreen {
166178
case let .friends(userID), let .friendsForChat(userID):
167179
if !users.isEmpty, !refresh { return }
168180
if !refresh { isLoading = true }
169-
let isMainUser = userID == defaults.mainUserInfo?.id
170-
let response = try await client.getFriendsForUser(id: userID)
171-
if isMainUser {
172-
try? defaults.saveFriendsIds(response.map(\.id))
173-
if defaults.friendRequestsList.isEmpty || refresh {
174-
friendRequests = try await client.getFriendRequests()
175-
try? defaults.saveFriendRequests(friendRequests)
176-
} else {
177-
friendRequests = defaults.friendRequestsList
178-
}
181+
if userID == defaults.mainUserInfo?.id {
182+
try await makeListForMainUser(userID)
183+
} else {
184+
users = try await client.getFriendsForUser(id: userID)
179185
}
180-
users = response
181186
case let .eventParticipants(list), let .parkParticipants(list):
182187
users = list
183188
case .blacklist:
184189
if !users.isEmpty, !refresh { return }
185190
if !refresh { isLoading = true }
186-
if defaults.blacklistedUsers.isEmpty || refresh {
187-
users = try await client.getBlacklist()
188-
try? defaults.saveBlacklist(users)
189-
} else {
190-
users = defaults.blacklistedUsers
191+
users = try await client.getBlacklist()
192+
try? defaults.saveBlacklist(users)
193+
if users.isEmpty {
194+
dismiss()
191195
}
192196
}
193197
} catch {
194-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
198+
SWAlert.shared.presentDefaultUIKit(error)
195199
}
196200
isLoading = false
197201
}
@@ -202,14 +206,26 @@ private extension UsersListScreen {
202206
do {
203207
let isSuccess = try await client.respondToFriendRequest(from: userID, accept: accept)
204208
if isSuccess {
205-
await askForUsers(refresh: true)
209+
friendRequests.removeAll(where: { $0.id == userID })
210+
try await makeListForMainUser(defaults.mainUserInfo?.id)
206211
}
207212
} catch {
208-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
213+
SWAlert.shared.presentDefaultUIKit(error)
209214
}
210215
isLoading = false
211216
}
212217
}
218+
219+
func makeListForMainUser(_ id: Int?) async throws {
220+
guard let id else { return }
221+
async let friendsTask = client.getFriendsForUser(id: id)
222+
async let requestsTask = client.getFriendRequests()
223+
let (friends, requests) = try await (friendsTask, requestsTask)
224+
try? defaults.saveFriendsIds(friends.map(\.id))
225+
try? defaults.saveFriendRequests(requests)
226+
users = friends
227+
friendRequests = requests
228+
}
213229
}
214230

215231
#if DEBUG

SwiftUI-WorkoutApp/Screens/Events/EventDetailsScreen.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private extension EventDetailsScreen {
117117
onDeletion(event.id)
118118
}
119119
} catch {
120-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
120+
SWAlert.shared.presentDefaultUIKit(error)
121121
}
122122
isLoading = false
123123
}
@@ -228,7 +228,7 @@ private extension EventDetailsScreen {
228228
event.trainHere = oldValue
229229
}
230230
} catch {
231-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
231+
SWAlert.shared.presentDefaultUIKit(error)
232232
event.trainHere = oldValue
233233
}
234234
isLoading = false
@@ -343,7 +343,7 @@ private extension EventDetailsScreen {
343343
do {
344344
event = try await SWClient(with: defaults).getEvent(by: event.id)
345345
} catch {
346-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
346+
SWAlert.shared.presentDefaultUIKit(error)
347347
}
348348
isLoading = false
349349
}
@@ -356,7 +356,7 @@ private extension EventDetailsScreen {
356356
event.comments.removeAll(where: { $0.id == id })
357357
}
358358
} catch {
359-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
359+
SWAlert.shared.presentDefaultUIKit(error)
360360
}
361361
isLoading = false
362362
}
@@ -372,7 +372,7 @@ private extension EventDetailsScreen {
372372
event.photos = event.removePhotoById(id)
373373
}
374374
} catch {
375-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
375+
SWAlert.shared.presentDefaultUIKit(error)
376376
}
377377
isLoading = false
378378
}

SwiftUI-WorkoutApp/Screens/Events/EventFormScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private extension EventFormScreen {
189189
dismiss()
190190
}
191191
} catch {
192-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
192+
SWAlert.shared.presentDefaultUIKit(error)
193193
}
194194
isLoading = false
195195
}

SwiftUI-WorkoutApp/Screens/Events/EventsListScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private extension EventsListScreen {
188188
if selectedEventType == .past {
189189
pastEventStorage.loadIfNeeded(&pastEvents)
190190
}
191-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
191+
SWAlert.shared.presentDefaultUIKit(error)
192192
}
193193
isLoading = false
194194
}

SwiftUI-WorkoutApp/Screens/Messages/DialogScreen.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ private extension DialogScreen {
162162
markedAsReadClbk(dialog)
163163
}
164164
} catch {
165-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
165+
SWAlert.shared.presentDefaultUIKit(error)
166166
}
167167
}
168168

@@ -172,7 +172,7 @@ private extension DialogScreen {
172172
do {
173173
messages = try await SWClient(with: defaults).getMessages(for: dialog.id).reversed()
174174
} catch {
175-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
175+
SWAlert.shared.presentDefaultUIKit(error)
176176
}
177177
isLoading = false
178178
}
@@ -188,7 +188,7 @@ private extension DialogScreen {
188188
await askForMessages(refresh: true)
189189
}
190190
} catch {
191-
SWAlert.shared.presentDefaultUIKit(message: error.localizedDescription)
191+
SWAlert.shared.presentDefaultUIKit(error)
192192
}
193193
isLoading = false
194194
}

0 commit comments

Comments
 (0)