From 2c4dd762d872f58484738c60214d83b58b4e3254 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 11:38:39 +0100 Subject: [PATCH 01/12] ui: wrap in ScollView + dividers on AuthPickerView --- .../Sources/Views/AuthPickerView.swift | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index 5380ce43ea..eca0c7d2e5 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -17,45 +17,49 @@ public struct AuthPickerView { extension AuthPickerView: View { public var body: some View { - VStack { - Text(authService.string.authPickerTitle) - .font(.largeTitle) - .fontWeight(.bold) - .padding() - if authService.authenticationState == .authenticated { - SignedInView() - } else if authService.authView == .passwordRecovery { - PasswordRecoveryView() - } else if authService.authView == .emailLink { - EmailLinkView() - } else { - Text(authService.authenticationFlow == .login ? authService.string - .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) - VStack { Divider() } + ScrollView { + VStack { + Text(authService.string.authPickerTitle) + .font(.largeTitle) + .fontWeight(.bold) + .padding() + if authService.authenticationState == .authenticated { + SignedInView() + } else if authService.authView == .passwordRecovery { + PasswordRecoveryView() + } else if authService.authView == .emailLink { + Divider() + EmailLinkView() + } else { + Divider() + Text(authService.authenticationFlow == .login ? authService.string + .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) + VStack { Divider() } - EmailAuthView() - VStack { - authService.renderButtons() - }.padding(.horizontal) + EmailAuthView() + VStack { + authService.renderButtons() + }.padding(.horizontal) - VStack { Divider() } - HStack { - Text(authService - .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : - authService.string.alreadyHaveAnAccountLabel) - Button(action: { - withAnimation { - switchFlow() + VStack { Divider() } + HStack { + Text(authService + .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : + authService.string.alreadyHaveAnAccountLabel) + Button(action: { + withAnimation { + switchFlow() + } + }) { + Text(authService.authenticationFlow == .signUp ? authService.string + .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) + .fontWeight(.semibold) + .foregroundColor(.blue) } - }) { - Text(authService.authenticationFlow == .signUp ? authService.string - .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) - .fontWeight(.semibold) - .foregroundColor(.blue) } + PrivacyTOCsView(displayMode: .footer) + Text(authService.errorMessage).foregroundColor(.red) } - PrivacyTOCsView(displayMode: .footer) - Text(authService.errorMessage).foregroundColor(.red) } } } From af59d88e8e8c1168a394c23717549b599f000c3c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 12:27:07 +0100 Subject: [PATCH 02/12] refactor: phone auth into button --- .../Sources/Services/AuthService.swift | 1 + .../Sources/Views/AuthPickerView.swift | 2 + .../Sources/Views/PhoneAuthButtonView.swift | 86 ++------------ .../Sources/Views/PhoneAuthView.swift | 106 ++++++++++++++++++ 4 files changed, 118 insertions(+), 77 deletions(-) create mode 100644 FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index c26fed3635..e065451e78 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -33,6 +33,7 @@ public enum AuthView { case authPicker case passwordRecovery case emailLink + case phoneAuth case updatePassword } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index eca0c7d2e5..3eb202e1b3 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -30,6 +30,8 @@ extension AuthPickerView: View { } else if authService.authView == .emailLink { Divider() EmailLinkView() + } else if authService.authView == .phoneAuth { + // TODO: - how are we rendering the phone auth View?? } else { Divider() Text(authService.authenticationFlow == .login ? authService.string diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift index 5b71b156bc..36efb564b5 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift @@ -5,90 +5,22 @@ import SwiftUI @MainActor public struct PhoneAuthButtonView { @Environment(AuthService.self) private var authService - @State private var errorMessage = "" - @State private var phoneNumber = "" - @State private var showVerificationCodeInput = false - @State private var verificationCode = "" - @State private var verificationID = "" public init() {} } extension PhoneAuthButtonView: View { public var body: some View { - if authService.authenticationState != .authenticating { - VStack { - LabeledContent { - TextField(authService.string.enterPhoneNumberLabel, text: $phoneNumber) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .submitLabel(.next) - } label: { - Image(systemName: "at") - }.padding(.vertical, 6) - .background(Divider(), alignment: .bottom) - .padding(.bottom, 4) - Button(action: { - Task { - do { - let id = try await authService.verifyPhoneNumber(phoneNumber: phoneNumber) - verificationID = id - showVerificationCodeInput = true - } catch { - errorMessage = authService.string.localizedErrorMessage( - for: error - ) - } - } - }) { - Text(authService.string.smsCodeSentLabel) - .padding(.vertical, 8) - .frame(maxWidth: .infinity) - } - .disabled(!PhoneUtils.isValidPhoneNumber(phoneNumber)) - .padding([.top, .bottom], 8) - .frame(maxWidth: .infinity) - .buttonStyle(.borderedProminent) - Text(errorMessage).foregroundColor(.red) - }.sheet(isPresented: $showVerificationCodeInput) { - TextField(authService.string.phoneNumberVerificationCodeLabel, text: $verificationCode) - .keyboardType(.numberPad) - .padding() - .background(Color(.systemGray6)) - .cornerRadius(8) - .padding(.horizontal) - - Button(action: { - Task { - do { - try await authService.signInWithPhoneNumber( - verificationID: verificationID, - verificationCode: verificationCode - ) - } catch { - errorMessage = authService.string.localizedErrorMessage(for: error) - } - showVerificationCodeInput = false - } - }) { - Text(authService.string.verifyPhoneNumberAndSignInLabel) - .foregroundColor(.white) - .padding() - .frame(maxWidth: .infinity) - .background(Color.green) - .cornerRadius(8) - .padding(.horizontal) - } - }.onOpenURL { url in - authService.auth.canHandle(url) - } - } else { - ProgressView() - .progressViewStyle(CircularProgressViewStyle(tint: .white)) - .padding(.vertical, 8) - .frame(maxWidth: .infinity) + Button(action: { + authService.authView = .phoneAuth + }) { + Label("Sign in with Phone", systemImage: "phone.fill") + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.green.opacity(0.8)) // Light green + .cornerRadius(8) } - Text(errorMessage).foregroundColor(.red) } } diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift new file mode 100644 index 0000000000..3e07041d9f --- /dev/null +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift @@ -0,0 +1,106 @@ +// +// PhoneAuthView.swift +// FirebaseUI +// +// Created by Russell Wheatley on 14/05/2025. +// + +import FirebaseAuthSwiftUI +import FirebaseCore +import SwiftUI + +@MainActor +public struct PhoneAuthView { + @Environment(AuthService.self) private var authService + @State private var errorMessage = "" + @State private var phoneNumber = "" + @State private var showVerificationCodeInput = false + @State private var verificationCode = "" + @State private var verificationID = "" + + public init() {} +} + +extension PhoneAuthView: View { + public var body: some View { + if authService.authenticationState != .authenticating { + VStack { + LabeledContent { + TextField(authService.string.enterPhoneNumberLabel, text: $phoneNumber) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .submitLabel(.next) + } label: { + Image(systemName: "at") + }.padding(.vertical, 6) + .background(Divider(), alignment: .bottom) + .padding(.bottom, 4) + Button(action: { + Task { + do { + let id = try await authService.verifyPhoneNumber(phoneNumber: phoneNumber) + verificationID = id + showVerificationCodeInput = true + } catch { + errorMessage = authService.string.localizedErrorMessage( + for: error + ) + } + } + }) { + Text(authService.string.smsCodeSentLabel) + .padding(.vertical, 8) + .frame(maxWidth: .infinity) + } + .disabled(!PhoneUtils.isValidPhoneNumber(phoneNumber)) + .padding([.top, .bottom], 8) + .frame(maxWidth: .infinity) + .buttonStyle(.borderedProminent) + Text(errorMessage).foregroundColor(.red) + }.sheet(isPresented: $showVerificationCodeInput) { + TextField(authService.string.phoneNumberVerificationCodeLabel, text: $verificationCode) + .keyboardType(.numberPad) + .padding() + .background(Color(.systemGray6)) + .cornerRadius(8) + .padding(.horizontal) + + Button(action: { + Task { + do { + try await authService.signInWithPhoneNumber( + verificationID: verificationID, + verificationCode: verificationCode + ) + } catch { + errorMessage = authService.string.localizedErrorMessage(for: error) + } + showVerificationCodeInput = false + } + }) { + Text(authService.string.verifyPhoneNumberAndSignInLabel) + .foregroundColor(.white) + .padding() + .frame(maxWidth: .infinity) + .background(Color.green) + .cornerRadius(8) + .padding(.horizontal) + } + }.onOpenURL { url in + authService.auth.canHandle(url) + } + } else { + ProgressView() + .progressViewStyle(CircularProgressViewStyle(tint: .white)) + .padding(.vertical, 8) + .frame(maxWidth: .infinity) + } + Text(errorMessage).foregroundColor(.red) + } +} + +#Preview { + FirebaseOptions.dummyConfigurationForPreview() + return PhoneAuthView() + .environment(AuthService()) +} From bf20f0c72e348856ebe29a4412f9dbc57d69f844 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 12:27:31 +0100 Subject: [PATCH 03/12] chore: rename to "Sign with Facebook" for consistency --- .../FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index 1dbdc49a48..6258907c56 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -271,7 +271,7 @@ public class StringUtils { /// found in: /// - SignInWithFacebookButton public var facebookLoginButtonLabel: String { - return localizedString(for: "Continue with Facebook") + return localizedString(for: "Sign in with Facebook") } /// Facebook provider From 0702988a29d36ebb94f9e19b9fc901d51e214575 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 12:41:21 +0100 Subject: [PATCH 04/12] chore: change order of buttons --- .../FirebaseSwiftUIExample/ContentView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift index b85492a77b..a267b77a4f 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift @@ -34,8 +34,9 @@ struct ContentView: View { configuration: configuration ) .withGoogleSignIn() - .withFacebookSignIn() .withPhoneSignIn() + .withFacebookSignIn() + } var body: some View { From dea04f66ff22e93cc3053363a22ad9a1bff879ef Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:29:23 +0100 Subject: [PATCH 05/12] refactor: make phone auth a sheet that presents over AuthPickerView --- .../Sources/Services/AuthService.swift | 41 ++++++++++++++++++- .../Sources/Views/AuthPickerView.swift | 36 +++++++++++++++- .../Sources/Views/PasswordRecoveryView.swift | 2 +- .../Sources/Views/PhoneAuthButtonView.swift | 5 ++- .../Sources/Views/PhoneAuthView.swift | 1 - 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index dc2ed08abc..791587a0fc 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -34,7 +34,6 @@ public enum AuthView { case authPicker case passwordRecovery case emailLink - case phoneAuth case updatePassword } @@ -84,6 +83,44 @@ public final class AuthService { public var authenticationFlow: AuthenticationFlow = .login public var errorMessage = "" public let passwordPrompt: PasswordPromptCoordinator = .init() + + // MARK: - AuthPickerView Modal APIs + + public var isShowingAuthModal = false + + public enum AuthModalContentType { + case phoneAuth + } + + public var currentModal: AuthModalContentType? + + public var authModalViewBuilderRegistry: [AuthModalContentType: () -> AnyView] = [:] + + public func registerModalView(for type: AuthModalContentType, builder: @escaping () -> AnyView) { + authModalViewBuilderRegistry[type] = builder + } + + public func viewForCurrentModal() -> AnyView? { + guard let type = currentModal, + let builder = authModalViewBuilderRegistry[type] else { + return nil + } + return builder() + } + + public func presentModal(for type: AuthModalContentType) { + currentModal = type + isShowingAuthModal = true + } + + public func dismissModal() { + isShowingAuthModal = false + } + + // MARK: - End AuthPickerView Modal APIs + + // MARK: - Provider APIs + private var unsafeGoogleProvider: (any GoogleProviderAuthUIProtocol)? private var unsafeFacebookProvider: (any FacebookProviderAuthUIProtocol)? private var unsafePhoneAuthProvider: (any PhoneAuthProviderAuthUIProtocol)? @@ -147,6 +184,8 @@ public final class AuthService { } } + // MARK: - End Provider APIs + private func safeActionCodeSettings() throws -> ActionCodeSettings { // email sign-in requires action code settings guard let actionCodeSettings = configuration diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index 27cf9fdadc..c97de1dd83 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -11,6 +11,13 @@ public struct AuthPickerView { authService.authenticationFlow = authService .authenticationFlow == .login ? .signUp : .login } + + private var isAuthModalPresented: Binding { + Binding( + get: { authService.isShowingAuthModal }, + set: { authService.isShowingAuthModal = $0 } + ) + } } extension AuthPickerView: View { @@ -28,8 +35,6 @@ extension AuthPickerView: View { } else if authService.authView == .emailLink { Divider() EmailLinkView() - } else if authService.authView == .phoneAuth { - // TODO: - how are we rendering the phone auth View?? } else { Divider() if authService.emailSignInEnabled { @@ -64,6 +69,33 @@ extension AuthPickerView: View { PrivacyTOCsView(displayMode: .footer) Text(authService.errorMessage).foregroundColor(.red) } + }.sheet(isPresented: isAuthModalPresented) { + VStack(spacing: 0) { + HStack { + Button(action: { + authService.dismissModal() + }) { + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 17, weight: .medium)) + Text(authService.string.backButtonLabel) + .font(.system(size: 17)) + } + .foregroundColor(.blue) + } + Spacer() + } + .padding() + .background(Color(.systemBackground)) + + Divider() + + if let view = authService.viewForCurrentModal() { + view + .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding() + } + } } } } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift index c29e157ee6..de3bf94278 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift @@ -69,7 +69,7 @@ extension PasswordRecoveryView: View { } .padding() }.onOpenURL { _ in - // move the user to email/password View + // TODO: - move the user to email/password View } .navigationBarItems(leading: Button(action: { authService.authView = .authPicker diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift index 36efb564b5..f97a21d1d7 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift @@ -12,7 +12,10 @@ public struct PhoneAuthButtonView { extension PhoneAuthButtonView: View { public var body: some View { Button(action: { - authService.authView = .phoneAuth + authService.registerModalView(for: .phoneAuth) { + AnyView(PhoneAuthView().environment(authService)) + } + authService.presentModal(for: .phoneAuth) }) { Label("Sign in with Phone", systemImage: "phone.fill") .foregroundColor(.white) diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift index 3e07041d9f..386be1d28f 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift @@ -95,7 +95,6 @@ extension PhoneAuthView: View { .padding(.vertical, 8) .frame(maxWidth: .infinity) } - Text(errorMessage).foregroundColor(.red) } } From e09201489670a9851c7fceb6e359ae3e50e4e019 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:32:00 +0100 Subject: [PATCH 06/12] chore: email button same horizontal padding as other auth buttons --- .../FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift index de26519813..7e7c1719f3 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift @@ -123,7 +123,7 @@ extension EmailAuthView: View { } } .disabled(!isValid) - .padding([.top, .bottom], 8) + .padding([.top, .bottom, .horizontal], 8) .frame(maxWidth: .infinity) .buttonStyle(.borderedProminent) Button(action: { From 4854c78195425ed4d2e21a8d109396ee0908f1c2 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:37:47 +0100 Subject: [PATCH 07/12] chore: update string label --- .../FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift | 7 +++---- .../Sources/Views/PhoneAuthView.swift | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index 6258907c56..b091d5137c 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -315,14 +315,13 @@ public class StringUtils { public var phoneNumberVerificationCodeLabel: String { return localizedString(for: "Enter verification code") } - + /// Phone provider /// found in: /// - PhoneAuthButtonView - public var smsCodeSentLabel: String { - return localizedString(for: "SMS code sent") + public var smsCodeSendButtonLabel: String { + return localizedString(for: "Send SMS code") } - /// Phone provider /// found in: /// - PhoneAuthButtonView diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift index 386be1d28f..d3d71c456e 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift @@ -48,7 +48,7 @@ extension PhoneAuthView: View { } } }) { - Text(authService.string.smsCodeSentLabel) + Text(authService.string.smsCodeSendButtonLabel) .padding(.vertical, 8) .frame(maxWidth: .infinity) } From 4e1cec02b694b97cda195df30db5481bd5c37470 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:37:59 +0100 Subject: [PATCH 08/12] format --- .../FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index b091d5137c..1f3ba0f34b 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -315,13 +315,14 @@ public class StringUtils { public var phoneNumberVerificationCodeLabel: String { return localizedString(for: "Enter verification code") } - + /// Phone provider /// found in: /// - PhoneAuthButtonView public var smsCodeSendButtonLabel: String { return localizedString(for: "Send SMS code") } + /// Phone provider /// found in: /// - PhoneAuthButtonView From 69a9c61bc0a0b5ee2da77ea0d2909aaa2909aca9 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:47:57 +0100 Subject: [PATCH 09/12] chore: dismiss modal after sign-in/failure --- .../FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift index d3d71c456e..afec742650 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthView.swift @@ -76,6 +76,7 @@ extension PhoneAuthView: View { errorMessage = authService.string.localizedErrorMessage(for: error) } showVerificationCodeInput = false + authService.dismissModal() } }) { Text(authService.string.verifyPhoneNumberAndSignInLabel) From afd1ee6da55824b8ac663b1c16d4bb7c9005a8ba Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 21 May 2025 14:49:49 +0100 Subject: [PATCH 10/12] chore: horizontal padding to email verification button --- .../FirebaseAuthSwiftUI/Sources/Views/VerifyEmailView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/VerifyEmailView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/VerifyEmailView.swift index ca95ee1387..fd4b0e1deb 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/VerifyEmailView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/VerifyEmailView.swift @@ -25,7 +25,7 @@ extension VerifyEmailView: View { .padding(.vertical, 8) .frame(maxWidth: .infinity) } - .padding([.top, .bottom], 8) + .padding([.top, .bottom, .horizontal], 8) .frame(maxWidth: .infinity) .buttonStyle(.borderedProminent) }.sheet(isPresented: $showModal) { From 7866bf83dcd5e2a4ce34bfc221594b946b1fa2b8 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 27 May 2025 08:37:44 +0100 Subject: [PATCH 11/12] chore: annotate function as view builder --- .../FirebaseAuthSwiftUI/Sources/Services/AuthService.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index 791587a0fc..f544d57724 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -1,5 +1,6 @@ @preconcurrency import FirebaseAuth import SwiftUI +import SwiftUICore public protocol ExternalAuthProvider { var id: String { get } @@ -96,7 +97,8 @@ public final class AuthService { public var authModalViewBuilderRegistry: [AuthModalContentType: () -> AnyView] = [:] - public func registerModalView(for type: AuthModalContentType, builder: @escaping () -> AnyView) { + public func registerModalView(for type: AuthModalContentType, + @ViewBuilder builder: @escaping () -> AnyView) { authModalViewBuilderRegistry[type] = builder } From 47dbf7fa5e77ff120f9d4a885da016d1e629e064 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 27 May 2025 08:40:24 +0100 Subject: [PATCH 12/12] chore: rm unneeded swiftui core import --- .../FirebaseAuthSwiftUI/Sources/Services/AuthService.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index f544d57724..ae3ad3b173 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -1,6 +1,5 @@ @preconcurrency import FirebaseAuth import SwiftUI -import SwiftUICore public protocol ExternalAuthProvider { var id: String { get }