66//
77
88import Foundation
9+ import Combine
910
1011@Observable
1112final class ProfileViewModel : Store {
1213 struct State : Equatable {
1314 var name : String = " "
1415 var email : String = " "
16+ var isNetworkConnected : Bool = true
1517 var statusMessage : String = " "
1618 var avatarURL : URL ?
1719 var earliestQuarterStart : Date ?
@@ -31,6 +33,7 @@ final class ProfileViewModel: Store {
3133
3234 enum Action {
3335 case onAppear
36+ case networkStatusChanged( Bool )
3437 case setAlert( Bool )
3538 case tapResetStatusMessageButton
3639 case willUpdateStatusMessage
@@ -66,22 +69,27 @@ final class ProfileViewModel: Store {
6669 private let fetchUserDataUseCase : FetchUserDataUseCase
6770 private let fetchTodosUseCase : FetchTodosUseCase
6871 private let upsertStatusMessageUseCase : UpsertStatusMessageUseCase
72+ private let networkConnectivityUseCase : ObserveNetworkConnectivityUseCase
6973 private let fetchHeatmapActivityTypesUseCase : FetchProfileHeatmapActivityTypesUseCase
7074 private let updateHeatmapActivityTypesUseCase : UpdateProfileHeatmapActivityTypesUseCase
7175 private let calendar = Calendar . current
76+ private var cancellables = Set < AnyCancellable > ( )
7277
7378 init (
7479 fetchUserDataUseCase: FetchUserDataUseCase ,
7580 fetchTodosUseCase: FetchTodosUseCase ,
7681 upsertStatusMessageUseCase: UpsertStatusMessageUseCase ,
82+ networkConnectivityUseCase: ObserveNetworkConnectivityUseCase ,
7783 fetchHeatmapActivityTypesUseCase: FetchProfileHeatmapActivityTypesUseCase ,
7884 updateHeatmapActivityTypesUseCase: UpdateProfileHeatmapActivityTypesUseCase
7985 ) {
8086 self . fetchUserDataUseCase = fetchUserDataUseCase
8187 self . fetchTodosUseCase = fetchTodosUseCase
8288 self . upsertStatusMessageUseCase = upsertStatusMessageUseCase
89+ self . networkConnectivityUseCase = networkConnectivityUseCase
8390 self . fetchHeatmapActivityTypesUseCase = fetchHeatmapActivityTypesUseCase
8491 self . updateHeatmapActivityTypesUseCase = updateHeatmapActivityTypesUseCase
92+ setupNetworkObserving ( )
8593 }
8694
8795 // swiftlint:disable cyclomatic_complexity
@@ -107,6 +115,8 @@ final class ProfileViewModel: Store {
107115 if let selectedQuarterStart = state. selectedQuarterStart {
108116 effects. append ( . fetchCompletionQuarter( selectedQuarterStart) )
109117 }
118+ case . networkStatusChanged( let isConnected) :
119+ state. isNetworkConnected = isConnected
110120 case . setAlert( let isPresented) :
111121 setAlert ( & state, isPresented: isPresented)
112122 case . tapResetStatusMessageButton:
@@ -169,6 +179,7 @@ final class ProfileViewModel: Store {
169179 }
170180 effects = [ . updateHeatmapActivityTypes( state. selectedActivityTypes) ]
171181 case . willUpdateStatusMessage:
182+ if !state. isNetworkConnected { break }
172183 let message = self . state. statusMessage
173184 effects = [ . updateStatusMessage( message) ]
174185 case . updateStatusMessage( let message) :
@@ -237,6 +248,16 @@ final class ProfileViewModel: Store {
237248}
238249
239250extension ProfileViewModel {
251+ private func setupNetworkObserving( ) {
252+ networkConnectivityUseCase. observe ( )
253+ . removeDuplicates ( )
254+ . receive ( on: DispatchQueue . main)
255+ . sink { [ weak self] isConnected in
256+ self ? . send ( . networkStatusChanged( isConnected) )
257+ }
258+ . store ( in: & cancellables)
259+ }
260+
240261 var quarterTitle : String {
241262 guard let start = state. selectedQuarterStart else { return " " }
242263 let year = calendar. component ( . year, from: start)
0 commit comments