@@ -8,9 +8,8 @@ import SWUtils
88struct DialogsListScreen : View {
99 @Environment ( \. isNetworkConnected) private var isNetworkConnected
1010 @EnvironmentObject private var defaults : DefaultsService
11- @State private var dialogs = [ DialogResponse ] ( )
11+ @EnvironmentObject private var viewModel : DialogsViewModel
1212 @State private var selectedDialog : DialogResponse ?
13- @State private var isLoading = false
1413 @State private var indexToDelete : Int ?
1514 @State private var openFriendList = false
1615 @State private var showDeleteConfirmation = false
@@ -34,22 +33,22 @@ struct DialogsListScreen: View {
3433 . navigationTitle ( " Сообщения " )
3534 }
3635 . navigationViewStyle ( . stack)
37- . task { await askForDialogs ( ) }
36+ . onChange ( of: defaults. isAuthorized, perform: viewModel. clearDialogsOnLogout)
37+ . task ( id: defaults. isAuthorized) { await askForDialogs ( ) }
3838 }
3939}
4040
4141private extension DialogsListScreen {
4242 var authorizedContentView : some View {
4343 dialogList
4444 . overlay { emptyContentView }
45- . loadingOverlay ( if: isLoading)
45+ . loadingOverlay ( if: viewModel . isLoading)
4646 . background ( Color . swBackground)
4747 . confirmationDialog (
4848 . init( Constants . Alert. deleteDialog) ,
4949 isPresented: $showDeleteConfirmation,
5050 titleVisibility: . visible
5151 ) { deleteDialogButton }
52- . refreshable { await askForDialogs ( refresh: true ) }
5352 . toolbar {
5453 ToolbarItem ( placement: . topBarLeading) {
5554 refreshButton
@@ -58,9 +57,6 @@ private extension DialogsListScreen {
5857 friendListButton
5958 }
6059 }
61- . onDisappear {
62- [ refreshTask, deleteDialogTask] . forEach { $0? . cancel ( ) }
63- }
6460 }
6561
6662 var refreshButton : some View {
@@ -71,8 +67,8 @@ private extension DialogsListScreen {
7167 } label: {
7268 Icons . Regular. refresh. view
7369 }
74- . opacity ( showEmptyView || !DeviceOSVersionChecker . iOS16Available ? 1 : 0 )
75- . disabled ( isLoading)
70+ . opacity ( viewModel . showEmptyView ? 1 : 0 )
71+ . disabled ( viewModel . isLoading || !isNetworkConnected )
7672 }
7773
7874 var friendListButton : some View {
@@ -86,28 +82,24 @@ private extension DialogsListScreen {
8682 Icons . Regular. plus. view
8783 . symbolVariant ( . circle)
8884 }
89- . opacity ( hasFriends || !dialogs . isEmpty ? 1 : 0 )
85+ . opacity ( hasFriends || viewModel . hasDialogs ? 1 : 0 )
9086 . disabled ( !isNetworkConnected)
9187 }
9288
9389 var emptyContentView : some View {
9490 EmptyContentView (
9591 mode: . dialogs,
96- action: emptyViewAction
92+ action: { openFriendList . toggle ( ) }
9793 )
98- . opacity ( showEmptyView ? 1 : 0 )
99- }
100-
101- var showEmptyView : Bool {
102- dialogs. isEmpty && !isLoading
94+ . opacity ( viewModel. showEmptyView ? 1 : 0 )
10395 }
10496
10597 @ViewBuilder
10698 var dialogList : some View {
10799 ZStack {
108100 Color . swBackground
109101 List {
110- ForEach ( dialogs) { model in
102+ ForEach ( viewModel . dialogs) { model in
111103 dialogListItem ( model)
112104 . listRowInsets ( . init( top: 12 , leading: 16 , bottom: 12 , trailing: 16 ) )
113105 . listRowBackground ( Color . swBackground)
@@ -116,9 +108,10 @@ private extension DialogsListScreen {
116108 . onDelete { initiateDeletion ( at: $0) }
117109 }
118110 . listStyle ( . plain)
119- . opacity ( dialogs. isEmpty ? 0 : 1 )
111+ . opacity ( viewModel. hasDialogs ? 1 : 0 )
112+ . refreshable { await askForDialogs ( refresh: true ) }
120113 }
121- . animation ( . default, value: dialogs. count)
114+ . animation ( . default, value: viewModel . dialogs. count)
122115 . background (
123116 NavigationLink (
124117 destination: lazyDestination,
@@ -130,7 +123,12 @@ private extension DialogsListScreen {
130123 @ViewBuilder
131124 var lazyDestination : some View {
132125 if let selectedDialog {
133- DialogScreen ( dialog: selectedDialog) { markAsRead ( $0) }
126+ DialogScreen (
127+ dialog: selectedDialog,
128+ markedAsReadClbk: { dialog in
129+ viewModel. markAsRead ( dialog, defaults: defaults)
130+ }
131+ )
134132 }
135133 }
136134
@@ -162,39 +160,12 @@ private extension DialogsListScreen {
162160 defaults. hasFriends
163161 }
164162
165- func emptyViewAction( ) {
166- openFriendList. toggle ( )
167- }
168-
169- func markAsRead( _ dialog: DialogResponse ) {
170- dialogs = dialogs. map { item in
171- if item. id == dialog. id {
172- var updatedDialog = dialog
173- updatedDialog. unreadMessagesCount = 0
174- return updatedDialog
175- } else {
176- return item
177- }
178- }
179- guard dialog. unreadMessagesCount > 0 ,
180- defaults. unreadMessagesCount >= dialog. unreadMessagesCount
181- else { return }
182- let newValue = defaults. unreadMessagesCount - dialog. unreadMessagesCount
183- defaults. saveUnreadMessagesCount ( newValue)
184- }
185-
186163 func askForDialogs( refresh: Bool = false ) async {
187- guard defaults. isAuthorized else { return }
188- if isLoading || ( !dialogs. isEmpty && !refresh) { return }
189- if !refresh { isLoading = true }
190164 do {
191- dialogs = try await client. getDialogs ( )
192- let unreadMessagesCount = dialogs. map ( \. unreadMessagesCount) . reduce ( 0 , + )
193- defaults. saveUnreadMessagesCount ( unreadMessagesCount)
165+ try await viewModel. askForDialogs ( refresh: refresh, defaults: defaults)
194166 } catch {
195167 SWAlert . shared. presentDefaultUIKit ( message: error. localizedDescription)
196168 }
197- isLoading = false
198169 }
199170
200171 func initiateDeletion( at indexSet: IndexSet ) {
@@ -204,17 +175,11 @@ private extension DialogsListScreen {
204175
205176 func deleteAction( at index: Int ? ) {
206177 deleteDialogTask = Task {
207- guard let index, !isLoading else { return }
208- isLoading = true
209178 do {
210- let dialogID = dialogs [ index] . id
211- if try await client. deleteDialog ( dialogID) {
212- dialogs. remove ( at: index)
213- }
179+ try await viewModel. deleteDialog ( at: index, defaults: defaults)
214180 } catch {
215181 SWAlert . shared. presentDefaultUIKit ( message: error. localizedDescription)
216182 }
217- isLoading = false
218183 }
219184 }
220185}
0 commit comments