@@ -14,14 +14,18 @@ struct LoginFeature {
1414 @ObservableState
1515 struct State : Equatable {
1616 @Presents var alert : AlertState < Never > ?
17- var isLoading = false
17+ var loading = LoadingFeature . State ( )
18+
19+ var isLoading : Bool {
20+ loading. isLoading
21+ }
1822 }
1923
2024 enum Action {
2125 case alert( PresentationAction < Never > )
2226 case tapSignInButton( AuthProvider )
2327 case signInFailed( AlertType )
24- case signInCancelled
28+ case loading ( LoadingFeature . Action )
2529 }
2630
2731 enum AlertType : Equatable {
@@ -32,28 +36,19 @@ struct LoginFeature {
3236 @Dependency ( \. signInUseCase) var signInUseCase
3337
3438 var body : some ReducerOf < Self > {
39+ Scope ( state: \. loading, action: \. loading) {
40+ LoadingFeature ( )
41+ }
3542 Reduce { state, action in
3643 switch action {
3744 case . alert:
3845 break
3946 case . tapSignInButton( let provider) :
40- state. isLoading = true
41- return . run { [ signInUseCase] send in
42- do {
43- try await signInUseCase. execute ( provider)
44- } catch {
45- if error. isSocialLoginCancelled {
46- await send ( . signInCancelled)
47- return
48- }
49- await send ( . signInFailed( alertType ( for: error) ) )
50- }
51- }
52- case . signInCancelled:
53- state. isLoading = false
47+ return signInEffect ( provider)
5448 case . signInFailed( let alertType) :
55- state. isLoading = false
5649 state. alert = alertState ( for: alertType)
50+ case . loading:
51+ break
5752 }
5853 return . none
5954 }
@@ -79,6 +74,19 @@ private enum SignInUseCaseKey: DependencyKey {
7974}
8075
8176private extension LoginFeature {
77+ func signInEffect( _ provider: AuthProvider ) -> Effect < Action > {
78+ . run { [ signInUseCase] send in
79+ await send ( . loading( . begin( target: . default, mode: . immediate) ) )
80+ do {
81+ try await signInUseCase. execute ( provider)
82+ } catch {
83+ await send ( . loading( . end( target: . default, mode: . immediate) ) )
84+ if error. isSocialLoginCancelled { return }
85+ await send ( . signInFailed( Self . alertType ( for: error) ) )
86+ }
87+ }
88+ }
89+
8290 func alertState( for alertType: AlertType ) -> AlertState < Never > {
8391 let title : String
8492 let message : String
@@ -103,7 +111,7 @@ private extension LoginFeature {
103111 }
104112 }
105113
106- func alertType( for error: Error ) -> AlertType {
114+ static func alertType( for error: Error ) -> AlertType {
107115 if case AuthError . emailNotFound = error {
108116 return . emailUnavailable
109117 }
0 commit comments