Skip to content

Commit 2e963ea

Browse files
committed
Рефактор
- Загружаем данные пользователя при смене фазы на конкретных экранах, не в одном месте - При авторизации загружаем все соц. данные, включая списки друзей, черный список и заявки в друзья
1 parent f26f3db commit 2e963ea

File tree

8 files changed

+50
-65
lines changed

8 files changed

+50
-65
lines changed

SwiftUI-WorkoutApp.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@
256256
children = (
257257
674E704D2B24D382008AE9D0 /* LoggerScreen.swift */,
258258
670CA19D280E8F09003914A3 /* SettingsScreen.swift */,
259-
6798AA72280B43FE00DB76F1 /* LoginScreen.swift */,
260259
);
261260
path = Settings;
262261
sourceTree = "<group>";
@@ -424,6 +423,7 @@
424423
isa = PBXGroup;
425424
children = (
426425
67BAF3F72836245100DB40D9 /* CommentsView.swift */,
426+
6798AA72280B43FE00DB76F1 /* LoginScreen.swift */,
427427
671D7DEB28210D2F0068E728 /* EmptyContentView.swift */,
428428
67515697283FEC0B00501346 /* ImagePicker */,
429429
6798AA65280B232F00DB76F1 /* IncognitoProfileView.swift */,
@@ -868,7 +868,7 @@
868868
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
869869
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
870870
CODE_SIGN_STYLE = Automatic;
871-
CURRENT_PROJECT_VERSION = 13;
871+
CURRENT_PROJECT_VERSION = 14;
872872
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
873873
DEVELOPMENT_TEAM = CR68PP2Z3F;
874874
ENABLE_PREVIEWS = YES;
@@ -919,7 +919,7 @@
919919
CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES;
920920
CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
921921
CODE_SIGN_STYLE = Automatic;
922-
CURRENT_PROJECT_VERSION = 13;
922+
CURRENT_PROJECT_VERSION = 14;
923923
DEVELOPMENT_ASSET_PATHS = "SwiftUI-WorkoutApp/Preview\\ Content/PreviewContent.swift SwiftUI-WorkoutApp/Preview\\ Content";
924924
DEVELOPMENT_TEAM = CR68PP2Z3F;
925925
ENABLE_PREVIEWS = YES;

SwiftUI-WorkoutApp/Libraries/SWNetworkClient/Sources/SWNetworkClient/SWClient.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,23 @@ public struct SWClient: Sendable {
3939
return result.userID
4040
}
4141

42-
/// Запрашивает обновления списка друзей, заявок в друзья, черного списка
42+
/// Запрашивает обновления для пользователя и его списков: друзья, заявки, черный список
4343
///
4444
/// - Вызывается при авторизации и при `scenePhase = active`
45-
/// - Список чатов не обновляет
45+
/// - Список чатов не обновляет (для этого `DialogsViewModel`)
4646
/// - Parameter userID: Идентификатор основного пользователя
4747
/// - Returns: Список друзей, заявок в друзья и черный список
48-
public func getSocialUpdates(userID: Int) async -> (
48+
public func getSocialUpdates(userID: Int) async throws -> (
49+
user: UserResponse,
4950
friends: [UserResponse],
5051
friendRequests: [UserResponse],
5152
blacklist: [UserResponse]
52-
)? {
53+
) {
54+
async let user = getUserByID(userID)
5355
async let friendsForUser = getFriendsForUser(id: userID)
5456
async let friendRequests = getFriendRequests()
5557
async let blacklist = getBlacklist()
56-
return try? await (friendsForUser, friendRequests, blacklist)
58+
return try await (user, friendsForUser, friendRequests, blacklist)
5759
}
5860

5961
/// Запрашивает данные пользователя по `id`

SwiftUI-WorkoutApp/Screens/Settings/LoginScreen.swift renamed to SwiftUI-WorkoutApp/Screens/Common/LoginScreen.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import SWUtils
77
/// Экран для авторизации / восстановления пароля
88
struct LoginScreen: View {
99
@EnvironmentObject private var defaults: DefaultsService
10+
@Environment(\.dismiss) private var dismiss
1011
@Environment(\.isNetworkConnected) private var isNetworkConnected
1112
@State private var isLoading = false
1213
@State private var credentials = LoginCredentials()
@@ -100,18 +101,21 @@ private extension LoginScreen {
100101
func loginAction() {
101102
guard !isLoading else { return }
102103
focus = nil
103-
isLoading.toggle()
104+
isLoading = true
104105
loginTask = Task {
105106
do {
106107
let token = AuthData(login: credentials.login, password: credentials.password).token
107108
let userId = try await client.logIn(with: token)
108109
try defaults.saveAuthData(login: credentials.login, password: credentials.password)
109-
let userInfo = try await client.getUserByID(userId)
110-
try defaults.saveUserInfo(userInfo)
110+
let result = try await client.getSocialUpdates(userID: userId)
111+
try defaults.saveFriendsIds(result.friends.map(\.id))
112+
try defaults.saveFriendRequests(result.friendRequests)
113+
try defaults.saveBlacklist(result.blacklist)
114+
try defaults.saveUserInfo(result.user)
111115
} catch {
112116
loginErrorMessage = error.localizedDescription
113117
}
114-
isLoading.toggle()
118+
isLoading = false
115119
}
116120
}
117121

SwiftUI-WorkoutApp/Screens/Messages/DialogsListScreen.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import SWUtils
66

77
/// Экран со списком диалогов
88
struct DialogsListScreen: View {
9+
@Environment(\.scenePhase) private var scenePhase
910
@Environment(\.isNetworkConnected) private var isNetworkConnected
1011
@EnvironmentObject private var defaults: DefaultsService
11-
@EnvironmentObject private var viewModel: DialogsViewModel
12+
@StateObject private var viewModel = DialogsViewModel()
1213
@State private var selectedDialog: DialogResponse?
1314
@State private var indexToDelete: Int?
1415
@State private var openFriendList = false
15-
@State private var showDeleteConfirmation = false
1616
@State private var refreshTask: Task<Void, Never>?
1717
@State private var deleteDialogTask: Task<Void, Never>?
1818
private var client: SWClient { SWClient(with: defaults) }
@@ -34,6 +34,11 @@ struct DialogsListScreen: View {
3434
}
3535
.navigationViewStyle(.stack)
3636
.onChange(of: defaults.isAuthorized, perform: viewModel.clearDialogsOnLogout)
37+
.onChange(of: scenePhase) { phase in
38+
if case .active = phase {
39+
refreshTask = Task { await askForDialogs() }
40+
}
41+
}
3742
.task(id: defaults.isAuthorized) { await askForDialogs() }
3843
}
3944
}
@@ -46,7 +51,7 @@ private extension DialogsListScreen {
4651
.background(Color.swBackground)
4752
.confirmationDialog(
4853
.init(Constants.Alert.deleteDialog),
49-
isPresented: $showDeleteConfirmation,
54+
isPresented: $indexToDelete.mappedToBool(),
5055
titleVisibility: .visible
5156
) { deleteDialogButton }
5257
.toolbar {
@@ -105,7 +110,7 @@ private extension DialogsListScreen {
105110
.listRowBackground(Color.swBackground)
106111
.listRowSeparator(.hidden)
107112
}
108-
.onDelete { initiateDeletion(at: $0) }
113+
.onDelete { indexToDelete = $0.first }
109114
}
110115
.listStyle(.plain)
111116
.opacity(viewModel.hasDialogs ? 1 : 0)
@@ -168,11 +173,6 @@ private extension DialogsListScreen {
168173
}
169174
}
170175

171-
func initiateDeletion(at indexSet: IndexSet) {
172-
indexToDelete = indexSet.first
173-
showDeleteConfirmation.toggle()
174-
}
175-
176176
func deleteAction(at index: Int?) {
177177
deleteDialogTask = Task {
178178
do {

SwiftUI-WorkoutApp/Screens/Messages/DialogsViewModel.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ final class DialogsViewModel: ObservableObject {
1515
defaults: DefaultsService
1616
) async throws {
1717
guard defaults.isAuthorized else { return }
18-
if isLoading || (!dialogs.isEmpty && !refresh) { return }
18+
guard !isLoading else { return }
19+
guard dialogs.isEmpty || refresh else { return }
1920
if !refresh || dialogs.isEmpty { isLoading = true }
2021
dialogs = try await SWClient(with: defaults).getDialogs()
2122
let unreadMessagesCount = dialogs.map(\.unreadMessagesCount).reduce(0, +)

SwiftUI-WorkoutApp/Screens/Profile/BlackListScreen.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ struct BlackListScreen: View {
3333
.frame(maxWidth: .infinity)
3434
.confirmationDialog(
3535
.init(BlacklistOption.remove.dialogTitle),
36-
isPresented: .init(
37-
get: { userToDelete != nil },
38-
set: { if !$0 { userToDelete = nil } }
39-
),
36+
isPresented: $userToDelete.mappedToBool(),
4037
titleVisibility: .visible
4138
) {
4239
Button(

SwiftUI-WorkoutApp/Screens/Profile/MainUserProfileScreen.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import SWUtils
66

77
/// Экран с профилем главного пользователя
88
struct MainUserProfileScreen: View {
9+
@Environment(\.scenePhase) private var scenePhase
910
@Environment(\.isNetworkConnected) private var isNetworkConnected
1011
@EnvironmentObject private var defaults: DefaultsService
12+
@State private var refreshTask: Task<Void, Never>?
1113
@State private var isLoading = false
1214
@State private var showLogoutDialog = false
1315
@State private var showSearchUsersScreen = false
@@ -30,6 +32,13 @@ struct MainUserProfileScreen: View {
3032
}
3133
.navigationViewStyle(.stack)
3234
.task { await askForUserInfo() }
35+
.onChange(of: scenePhase) { phase in
36+
if case .active = phase {
37+
refreshTask = Task {
38+
await askForUserInfo(refresh: true)
39+
}
40+
}
41+
}
3342
}
3443
}
3544

@@ -144,30 +153,22 @@ private extension MainUserProfileScreen {
144153
}
145154

146155
func askForUserInfo(refresh: Bool = false) async {
147-
guard defaults.isAuthorized else { return }
156+
guard let userId = defaults.mainUserInfo?.id else { return }
148157
guard !isLoading else { return }
149158
if !refresh { isLoading = true }
150159
if refresh || defaults.needUpdateUser {
151-
await makeUserInfo()
160+
do {
161+
let result = try await client.getSocialUpdates(userID: userId)
162+
try defaults.saveFriendsIds(result.friends.map(\.id))
163+
try defaults.saveFriendRequests(result.friendRequests)
164+
try defaults.saveBlacklist(result.blacklist)
165+
try defaults.saveUserInfo(result.user)
166+
} catch {
167+
SWAlert.shared.presentDefaultUIKit(error)
168+
}
152169
}
153170
isLoading = false
154171
}
155-
156-
func makeUserInfo() async {
157-
guard let mainUserId = defaults.mainUserInfo?.id else { return }
158-
do {
159-
// TODO: вынести обновление заявок/черного списка в отдельную логику
160-
async let getUserInfo = client.getUserByID(mainUserId)
161-
async let getFriendRequests = client.getFriendRequests()
162-
async let getBlacklist = client.getBlacklist()
163-
let (userInfo, friendRequests, blacklist) = try await (getUserInfo, getFriendRequests, getBlacklist)
164-
try defaults.saveUserInfo(userInfo)
165-
try defaults.saveFriendRequests(friendRequests)
166-
try defaults.saveBlacklist(blacklist)
167-
} catch {
168-
SWAlert.shared.presentDefaultUIKit(error)
169-
}
170-
}
171172
}
172173

173174
#if DEBUG

SwiftUI-WorkoutApp/SwiftUI_WorkoutAppApp.swift

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ struct SwiftUI_WorkoutAppApp: App {
1111
@StateObject private var defaults = DefaultsService()
1212
@StateObject private var network = NetworkStatus()
1313
@StateObject private var parksManager = ParksManager()
14-
@StateObject private var dialogsViewModel = DialogsViewModel()
1514
@State private var countriesUpdateTask: Task<Void, Never>?
16-
@State private var socialUpdateTask: Task<Void, Never>?
17-
@State private var dialogsUpdateTask: Task<Void, Never>?
1815
private let countriesStorage = SWAddress()
1916
private var client: SWClient { SWClient(with: defaults) }
2017
private var colorScheme: ColorScheme? {
@@ -39,7 +36,6 @@ struct SwiftUI_WorkoutAppApp: App {
3936
.environmentObject(tabViewModel)
4037
.environmentObject(defaults)
4138
.environmentObject(parksManager)
42-
.environmentObject(dialogsViewModel)
4339
.preferredColorScheme(colorScheme)
4440
.environment(\.isNetworkConnected, network.isConnected)
4541
.environment(\.userFlags, defaults.userFlags)
@@ -48,9 +44,8 @@ struct SwiftUI_WorkoutAppApp: App {
4844
switch phase {
4945
case .active:
5046
updateCountriesIfNeeded()
51-
updateSocialInfoIfNeeded()
5247
default:
53-
[socialUpdateTask, countriesUpdateTask].forEach { $0?.cancel() }
48+
countriesUpdateTask?.cancel()
5449
defaults.setUserNeedUpdate(true)
5550
}
5651
}
@@ -65,21 +60,6 @@ struct SwiftUI_WorkoutAppApp: App {
6560
}
6661
}
6762
}
68-
69-
private func updateSocialInfoIfNeeded() {
70-
guard let mainUserId = defaults.mainUserInfo?.id else { return }
71-
socialUpdateTask = Task {
72-
if let result = await client.getSocialUpdates(userID: mainUserId) {
73-
try? defaults.saveFriendsIds(result.friends.map(\.id))
74-
try? defaults.saveFriendRequests(result.friendRequests)
75-
try? defaults.saveBlacklist(result.blacklist)
76-
defaults.setUserNeedUpdate(false)
77-
}
78-
}
79-
dialogsUpdateTask = Task {
80-
try? await dialogsViewModel.askForDialogs(refresh: true, defaults: defaults)
81-
}
82-
}
8363
}
8464

8565
private extension SwiftUI_WorkoutAppApp {

0 commit comments

Comments
 (0)