Skip to content

Commit 8cc879a

Browse files
committed
Переделываю экран черного списка
1 parent 760363f commit 8cc879a

File tree

4 files changed

+127
-16
lines changed

4 files changed

+127
-16
lines changed

SwiftUI-WorkoutApp.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
671B4AE92D4F623100286996 /* ModernPickedImagesGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671B4AE82D4F623100286996 /* ModernPickedImagesGrid.swift */; };
1717
671B4AEB2D4F683E00286996 /* ImagePickerViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671B4AEA2D4F683E00286996 /* ImagePickerViews.swift */; };
1818
671D7DEC28210D2F0068E728 /* EmptyContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 671D7DEB28210D2F0068E728 /* EmptyContentView.swift */; };
19+
674000402D55E97900E5CB06 /* BlackListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6740003F2D55E97900E5CB06 /* BlackListScreen.swift */; };
1920
67419ACF282E70B9004F5339 /* ParksListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67419ACE282E70B9004F5339 /* ParksListScreen.swift */; };
2021
6747575628113419002F0A24 /* ChangePasswordScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6747575528113419002F0A24 /* ChangePasswordScreen.swift */; };
2122
6747575928128603002F0A24 /* ParkDetailScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6747575828128603002F0A24 /* ParkDetailScreen.swift */; };
@@ -103,6 +104,7 @@
103104
671B4AE82D4F623100286996 /* ModernPickedImagesGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModernPickedImagesGrid.swift; sourceTree = "<group>"; };
104105
671B4AEA2D4F683E00286996 /* ImagePickerViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePickerViews.swift; sourceTree = "<group>"; };
105106
671D7DEB28210D2F0068E728 /* EmptyContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyContentView.swift; sourceTree = "<group>"; };
107+
6740003F2D55E97900E5CB06 /* BlackListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlackListScreen.swift; sourceTree = "<group>"; };
106108
67419ACE282E70B9004F5339 /* ParksListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParksListScreen.swift; sourceTree = "<group>"; };
107109
6747575528113419002F0A24 /* ChangePasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangePasswordScreen.swift; sourceTree = "<group>"; };
108110
6747575828128603002F0A24 /* ParkDetailScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParkDetailScreen.swift; sourceTree = "<group>"; };
@@ -408,6 +410,7 @@
408410
674D061A28280A63007E75C6 /* FriendRequestsView.swift */,
409411
674D0622282A9896007E75C6 /* SearchUsersScreen.swift */,
410412
6765B2572D4544C8006164AB /* MainUserProfileScreen.swift */,
413+
6740003F2D55E97900E5CB06 /* BlackListScreen.swift */,
411414
);
412415
path = Profile;
413416
sourceTree = "<group>";
@@ -624,6 +627,7 @@
624627
6798AA40280AEDC900DB76F1 /* RootScreen.swift in Sources */,
625628
671B4AE92D4F623100286996 /* ModernPickedImagesGrid.swift in Sources */,
626629
675EC64F2814126800C2E229 /* TextEntryScreen.swift in Sources */,
630+
674000402D55E97900E5CB06 /* BlackListScreen.swift in Sources */,
627631
674D0623282A9896007E75C6 /* SearchUsersScreen.swift in Sources */,
628632
67A4710D2AEED8F8004D341D /* PastEventStorage.swift in Sources */,
629633
675FB8DB2ADDB87200C9671F /* ParksMapScreen+LocationSettingReminderView.swift in Sources */,
@@ -856,7 +860,7 @@
856860
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
857861
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
858862
CODE_SIGN_STYLE = Automatic;
859-
CURRENT_PROJECT_VERSION = 11;
863+
CURRENT_PROJECT_VERSION = 12;
860864
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
861865
DEVELOPMENT_TEAM = CR68PP2Z3F;
862866
ENABLE_PREVIEWS = YES;
@@ -907,7 +911,7 @@
907911
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
908912
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
909913
CODE_SIGN_STYLE = Automatic;
910-
CURRENT_PROJECT_VERSION = 11;
914+
CURRENT_PROJECT_VERSION = 12;
911915
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
912916
DEVELOPMENT_TEAM = CR68PP2Z3F;
913917
ENABLE_PREVIEWS = YES;

SwiftUI-WorkoutApp/Screens/Common/UsersListScreen.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ extension UsersListScreen {
5757
case eventParticipants(list: [UserResponse])
5858
/// Тренирующиеся на площадке
5959
case parkParticipants(list: [UserResponse])
60-
/// Черный список основного пользователя
61-
case blacklist
6260
}
6361
}
6462

@@ -71,8 +69,6 @@ private extension UsersListScreen.Mode {
7169
"Участники мероприятия"
7270
case .parkParticipants:
7371
"Здесь тренируются"
74-
case .blacklist:
75-
"Черный список"
7672
}
7773
}
7874
}
@@ -119,7 +115,7 @@ private extension UsersListScreen {
119115
} label: {
120116
userRowView(with: model)
121117
}
122-
case .friends, .eventParticipants, .parkParticipants, .blacklist:
118+
case .friends, .eventParticipants, .parkParticipants:
123119
NavigationLink {
124120
UserDetailsScreen(for: model)
125121
.navigationBarTitleDisplayMode(.inline)
@@ -185,14 +181,6 @@ private extension UsersListScreen {
185181
}
186182
case let .eventParticipants(list), let .parkParticipants(list):
187183
users = list
188-
case .blacklist:
189-
if !users.isEmpty, !refresh { return }
190-
if !refresh { isLoading = true }
191-
users = try await client.getBlacklist()
192-
try? defaults.saveBlacklist(users)
193-
if users.isEmpty {
194-
dismiss()
195-
}
196184
}
197185
} catch {
198186
SWAlert.shared.presentDefaultUIKit(error)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import SWDesignSystem
2+
import SwiftUI
3+
import SWModels
4+
import SWNetworkClient
5+
import SWUtils
6+
7+
/// Экран для списка заблокированных пользователей
8+
struct BlackListScreen: View {
9+
@Environment(\.dismiss) private var dismiss
10+
@Environment(\.isNetworkConnected) private var isNetworkConnected
11+
@EnvironmentObject private var defaults: DefaultsService
12+
@State private var users = [UserResponse]()
13+
@State private var userToDelete: UserResponse?
14+
@State private var isLoading = false
15+
private var client: SWClient { SWClient(with: defaults) }
16+
17+
var body: some View {
18+
ScrollView {
19+
LazyVStack(spacing: 12) {
20+
ForEach(users) { user in
21+
Button {
22+
userToDelete = user
23+
} label: {
24+
makeLabelFor(user)
25+
}
26+
.opacity(userToDelete == user ? 0.5 : 1)
27+
.scaleEffect(userToDelete == user ? 0.95 : 1)
28+
.offset(x: userToDelete == user ? -32 : 0)
29+
.animation(.easeInOut(duration: 0.2), value: userToDelete)
30+
}
31+
}
32+
.padding([.horizontal, .top])
33+
.frame(maxWidth: .infinity)
34+
.confirmationDialog(
35+
.init(BlacklistOption.remove.dialogTitle),
36+
isPresented: .init(
37+
get: { userToDelete != nil },
38+
set: { if !$0 { userToDelete = nil } }
39+
),
40+
titleVisibility: .visible
41+
) {
42+
Button(
43+
.init(BlacklistOption.remove.rawValue),
44+
role: .destructive,
45+
action: unblock
46+
)
47+
} message: {
48+
Text(.init(BlacklistOption.remove.dialogMessage))
49+
}
50+
}
51+
.loadingOverlay(if: isLoading)
52+
.background(Color.swBackground)
53+
.task { await askForUsers() }
54+
.refreshable { await askForUsers(refresh: true) }
55+
.navigationTitle("Черный список")
56+
.navigationBarTitleDisplayMode(.inline)
57+
}
58+
}
59+
60+
private extension BlackListScreen {
61+
func makeLabelFor(_ user: UserResponse) -> some View {
62+
UserRowView(
63+
mode: .regular(
64+
.init(
65+
imageURL: user.avatarURL,
66+
name: user.userName ?? "",
67+
address: SWAddress(user.countryID, user.cityID)?.address ?? ""
68+
)
69+
)
70+
)
71+
}
72+
73+
func askForUsers(refresh: Bool = false) async {
74+
guard !isLoading else { return }
75+
do {
76+
if !users.isEmpty, !refresh { return }
77+
if !refresh { isLoading = true }
78+
users = try await client.getBlacklist()
79+
try? defaults.saveBlacklist(users)
80+
dismissIfEmpty()
81+
} catch {
82+
SWAlert.shared.presentDefaultUIKit(error)
83+
}
84+
isLoading = false
85+
}
86+
87+
func unblock() {
88+
guard let user = userToDelete else { return }
89+
isLoading = true
90+
Task {
91+
do {
92+
let isSuccess = try await SWClient(with: defaults).blacklistAction(
93+
user: user, option: .remove
94+
)
95+
if isSuccess {
96+
defaults.updateBlacklist(option: .remove, user: user)
97+
users.removeAll(where: { $0.id == user.id })
98+
}
99+
dismissIfEmpty()
100+
} catch {
101+
SWAlert.shared.presentDefaultUIKit(error)
102+
}
103+
isLoading = false
104+
}
105+
}
106+
107+
func dismissIfEmpty() {
108+
if users.isEmpty { dismiss() }
109+
}
110+
}
111+
112+
#if DEBUG
113+
#Preview {
114+
NavigationView {
115+
BlackListScreen()
116+
.environmentObject(DefaultsService())
117+
}
118+
}
119+
#endif

SwiftUI-WorkoutApp/Screens/Profile/MainUserProfileScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private extension MainUserProfileScreen {
115115
var blacklistButtonIfNeeded: some View {
116116
ZStack {
117117
if !defaults.blacklistedUsers.isEmpty {
118-
NavigationLink(destination: UsersListScreen(mode: .blacklist)) {
118+
NavigationLink(destination: BlackListScreen()) {
119119
FormRowView(
120120
title: "Черный список",
121121
trailingContent: .textWithChevron(defaults.blacklistedUsersCountString)

0 commit comments

Comments
 (0)