diff --git a/nirvana-ios.xcodeproj/project.pbxproj b/nirvana-ios.xcodeproj/project.pbxproj index 126c874..526c136 100644 --- a/nirvana-ios.xcodeproj/project.pbxproj +++ b/nirvana-ios.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 89288EC7276756DF00E962C4 /* FirebaseDatabase in Frameworks */ = {isa = PBXBuildFile; productRef = 89288EC6276756DF00E962C4 /* FirebaseDatabase */; }; 89288EC9276756DF00E962C4 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 89288EC8276756DF00E962C4 /* FirebaseStorage */; }; 89288ECB27675B9F00E962C4 /* OnboardingTemplateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89288ECA27675B9F00E962C4 /* OnboardingTemplateView.swift */; }; + 89AD5573276DD790001658E0 /* SplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89AD5572276DD790001658E0 /* SplashView.swift */; }; 89B46E71276893E200B74255 /* AuthSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89B46E70276893E200B74255 /* AuthSessionStore.swift */; }; 89BCABE2276B3CB0009E9B10 /* NavigationStack in Frameworks */ = {isa = PBXBuildFile; productRef = 89BCABE1276B3CB0009E9B10 /* NavigationStack */; }; 89BCABE5276B3D58009E9B10 /* InnerCircleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89BCABE4276B3D58009E9B10 /* InnerCircleView.swift */; }; @@ -71,6 +72,7 @@ 892179E52765FECD001E6C60 /* FooterControlsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterControlsViewModel.swift; sourceTree = ""; }; 89288EBF276755DF00E962C4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 89288ECA27675B9F00E962C4 /* OnboardingTemplateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTemplateView.swift; sourceTree = ""; }; + 89AD5572276DD790001658E0 /* SplashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashView.swift; sourceTree = ""; }; 89B46E70276893E200B74255 /* AuthSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthSessionStore.swift; sourceTree = ""; }; 89BCABE4276B3D58009E9B10 /* InnerCircleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InnerCircleView.swift; sourceTree = ""; }; 89BCABE6276B3D64009E9B10 /* InnerCircleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InnerCircleViewModel.swift; sourceTree = ""; }; @@ -160,6 +162,7 @@ 891A15F62765639B00B26659 /* Views */ = { isa = PBXGroup; children = ( + 89AD5571276DD77D001658E0 /* SplashView */, 89AD5570276DBBD4001658E0 /* New Group */, 89BCABEE276D2DD6009E9B10 /* PhoneVerification */, 89BDCDED2769B3EB00577829 /* Contacts */, @@ -249,6 +252,14 @@ path = "New Group"; sourceTree = ""; }; + 89AD5571276DD77D001658E0 /* SplashView */ = { + isa = PBXGroup; + children = ( + 89AD5572276DD790001658E0 /* SplashView.swift */, + ); + path = SplashView; + sourceTree = ""; + }; 89BCABDF276B3588009E9B10 /* InnerCircle */ = { isa = PBXGroup; children = ( @@ -404,6 +415,7 @@ 89BDCDE527695DB900577829 /* NirvanaImage.swift in Sources */, 891A16132765A44300B26659 /* ChatsCarouselViewModel.swift in Sources */, 89F05B9B276A87920002E9C7 /* ContactsViewModel.swift in Sources */, + 89AD5573276DD790001658E0 /* SplashView.swift in Sources */, 891A15E127653A7000B26659 /* nirvana_iosApp.swift in Sources */, 89BCABED276D2B05009E9B10 /* WavesGlassBackgroundView.swift in Sources */, 89F05BA6276ACD830002E9C7 /* ContactsPickerView.swift in Sources */, diff --git a/nirvana-ios/Views/PhoneVerification/PhoneVerificationView.swift b/nirvana-ios/Views/PhoneVerification/PhoneVerificationView.swift index 25ab97e..f1d5448 100644 --- a/nirvana-ios/Views/PhoneVerification/PhoneVerificationView.swift +++ b/nirvana-ios/Views/PhoneVerification/PhoneVerificationView.swift @@ -22,6 +22,8 @@ struct PhoneVerificationView: View { @State var toastText = "" @State var toastSubMessage = "" + @State var isLoading = false + // TODO: format the input so that it shows the parentheses and stuff (949)923-0445 var body: some View { ZStack(alignment: .topLeading) { @@ -62,50 +64,71 @@ struct PhoneVerificationView: View { } .padding(.vertical, 20) - Button { - let concatPhoneNumber = "+"+self.ccode+self.phoneNumber - - // do auth stuff from firebase - PhoneAuthProvider.provider() - .verifyPhoneNumber(concatPhoneNumber, uiDelegate: nil) { verificationID, error in - // problem verifying number showing alert...maybe fake number or something from user - if error != nil { - self.toastText = "⚠️ Please try again." - self.toastSubMessage = "There was an issue validating your phone number" - self.showToast.toggle() - - print((error?.localizedDescription)!) - - return - } - - print("sending sms") - - // TODO: Sign in using the verificationID and the code sent to the user - // if there is no user with the phone number, then create one - - UserDefaults.standard.set(verificationID, forKey: "authVerificationID") - - // then async send to next page - // TODO: coming back after function end and then having 1 second before hitting this...need to use async and combine and all of that to make sure that the main thread is not affected and it's all smooth - self.navigationStack.push(PhoneVerificationCodeView()) // verify code page - } - } label: { - VStack { - Text("Send Verification") - .fontWeight(.heavy) - .foregroundColor(NirvanaColor.white) - .frame(maxWidth: .infinity) - .padding(.vertical, 20) - .background(self.phoneNumber.count == 10 ? NirvanaColor.teal : Color.white.opacity(0.2)) // show dull button if didn't enter full phone number - .clipShape(Capsule()) - .shadow(radius:10) - .animation(.default) + // did they input a 10 digit number? + if self.phoneNumber.count == 10 { + Button { + let concatPhoneNumber = "+"+self.ccode+self.phoneNumber - Text("You might receive an SMS message for verification and standard rates apply.") - .font(.footnote) - .foregroundColor(Color.gray) + //show loading screen + self.isLoading.toggle() + + DispatchQueue.main.async { + print("sending sms and/or redirecting") + + // do auth stuff from firebase + PhoneAuthProvider.provider() + .verifyPhoneNumber(concatPhoneNumber, uiDelegate: nil) { verificationID, error in + // got a response...done loading... either error to show or next page + self.isLoading.toggle() + + // problem verifying number showing alert...maybe fake number or something from user + if error != nil { + self.toastText = "⚠️ Please try again." + self.toastSubMessage = "There was an issue validating your phone number" + self.showToast.toggle() + + print((error?.localizedDescription)!) + + return + } + + // TODO: Sign in using the verificationID and the code sent to the user + // if there is no user with the phone number, then create one + + UserDefaults.standard.set(verificationID, forKey: "authVerificationID") + + // then async send to next page + // TODO: coming back after function end and then having 1 second before hitting this...need to use async and combine and all of that to make sure that the main thread is not affected and it's all smooth + self.navigationStack.push(PhoneVerificationCodeView()) // verify code page + } + } + + } label: { + VStack { + Text("Send Verification") + .fontWeight(.heavy) + .foregroundColor(Color.white) + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(NirvanaColor.teal) // show dull button if didn't enter full phone number + .clipShape(Capsule()) + .shadow(radius:10) + .animation(.default) + + Text("You might receive an SMS message for verification and standard rates apply.") + .font(.footnote) + .foregroundColor(Color.black.opacity(0.5)) + } } + } else { + Text("Send Verification") + .foregroundColor(Color.white.opacity(0.2)) + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(Color.white.opacity(0.2)) // show dull button if didn't enter full phone number + .clipShape(Capsule()) + .shadow(radius:10) + .animation(.default) } } )) @@ -121,11 +144,16 @@ struct PhoneVerificationView: View { .foregroundColor(NirvanaColor.teal) .padding() } + + + if self.isLoading { + SplashView() + } + + SplashView() } .alert(self.toastText, isPresented: self.$showToast) { - Button("OK", role: ButtonRole.cancel) { } - } message: { Text(self.toastSubMessage) } @@ -149,6 +177,8 @@ struct PhoneVerificationCodeView: View { @State var toastText = "" @State var toastSubMessage = "" + @State var isLoading = false + var body: some View { ZStack(alignment: .topLeading) { Color.clear @@ -161,7 +191,7 @@ struct PhoneVerificationCodeView: View { .clipShape(Capsule()) .keyboardType(.decimalPad) .shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 20) - .font(.subheadline) + .font(.largeTitle) .multilineTextAlignment(.center) .padding(.vertical) // .onReceive(Just(self.$verificationCode)) { newValue in @@ -172,60 +202,80 @@ struct PhoneVerificationCodeView: View { // } // } - Button { - print("verify code") - - // do auth stuff - - // get it from the previous screen but from storage - let verificationID = UserDefaults.standard.string(forKey: "authVerificationID") - - if verificationID == nil { - self.toastText = "There was an error validating your code." - self.showToast.toggle() - } - // if we got a value, then continue with verifying their code - let credential = PhoneAuthProvider.provider().credential( - withVerificationID: verificationID!, - verificationCode: self.verificationCode - ) - - // firebase will now verify the credential - Auth.auth().signIn(with: credential) { (res, err) in - if err != nil { - self.toastText = "⚠️ Error with Verification" - self.toastSubMessage = "Code is invalid. Please try again or re-enter your phone number in the previous page." + if self.verificationCode.count == 6 { + Button { + print("started verification process of code") + // show loading screen + self.isLoading.toggle() + + + // get it from the previous screen but from storage + let verificationID = UserDefaults.standard.string(forKey: "authVerificationID") + + if verificationID == nil { + self.toastText = "There was an error validating your code." self.showToast.toggle() - - print((err?.localizedDescription)!) - return } - //setting in key storage - UserDefaults.standard.set(true, forKey: "authVerificationID") - - //TODO: is the auth listener going to find that this person signed in? idk test it - - // firebase either created a new user or is giving back an existing user's id - let userId = res?.user.uid - let userPhoneNumber = res?.user.phoneNumber - print("user id that was authenticated is: \(userId)") - print("user id that was authenticated is: \(userPhoneNumber)") - - - // then sending to next page - self.navigationStack.push(PhoneVerificationCodeView()) // verify code page + // TESTING: let it do it's thing but don't ruin the ui main thread + DispatchQueue.main.async { + // if we got a value, then continue with verifying their code + let credential = PhoneAuthProvider.provider().credential( + withVerificationID: verificationID!, + verificationCode: self.verificationCode + ) + + // firebase will now verify the credential + Auth.auth().signIn(with: credential) { (res, err) in + // done with the response here, turn off loading screen + self.isLoading.toggle() + + if err != nil { + self.toastText = "⚠️ Error with Verification" + self.toastSubMessage = "Code is invalid. Please try again or re-enter your phone number in the previous page." + self.showToast.toggle() + + print((err?.localizedDescription)!) + return + } + + //setting in key storage + UserDefaults.standard.set(true, forKey: "authVerificationID") + + //TODO: is the auth listener going to find that this person signed in? idk test it + + // firebase either created a new user or is giving back an existing user's id + let userId = res?.user.uid + let userPhoneNumber = res?.user.phoneNumber + print("user id that was authenticated is: \(userId)") + print("user id that was authenticated is: \(userPhoneNumber)") + + + // then sending to next page + self.navigationStack.push(PhoneVerificationCodeView()) // verify code page + } + } + } label: { + Text("Verify") + .bold() + .foregroundColor(NirvanaColor.white) + .frame(maxWidth: .infinity) + .padding(.vertical, 20) + .background(NirvanaColor.teal) + .clipShape(Capsule()) + .shadow(radius:10) } - } label: { - Text("Send Verification") - .bold() - .foregroundColor(NirvanaColor.white) + } else { + Text("Verify") + .foregroundColor(Color.white.opacity(0.2)) .frame(maxWidth: .infinity) .padding(.vertical, 20) - .background(NirvanaColor.teal) + .background(Color.white.opacity(0.2)) // show dull button if didn't enter full phone number .clipShape(Capsule()) .shadow(radius:10) + .animation(.default) } + } )) @@ -240,6 +290,10 @@ struct PhoneVerificationCodeView: View { .foregroundColor(NirvanaColor.teal) .padding() } + + if self.isLoading { + SplashView() + } } .alert(self.toastText, isPresented: self.$showToast) { diff --git a/nirvana-ios/Views/SplashView/SplashView.swift b/nirvana-ios/Views/SplashView/SplashView.swift new file mode 100644 index 0000000..f6a6d77 --- /dev/null +++ b/nirvana-ios/Views/SplashView/SplashView.swift @@ -0,0 +1,37 @@ +// +// SplashView.swift +// nirvana-ios +// +// Created by Arjun Patel on 12/18/21. +// + +import SwiftUI + +struct SplashView: View { + @State var scale = 1.0 + + var body: some View { + ZStack { + HStack { + Image("undraw_handcrafts_leaf") + .resizable() + .frame(width: 50, height: 75) + .foregroundColor(Color.white) + .scaleEffect(self.scale) + .animation(.easeIn(duration: 2).repeatForever(autoreverses: true)) + } + } + .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + .background(NirvanaColor.teal) + .onAppear { + self.scale = 1.3 + } + .ignoresSafeArea(.all) + } +} + +struct SplashView_Previews: PreviewProvider { + static var previews: some View { + SplashView() + } +}