bunch of ui adjustments

This commit is contained in:
talksik
2021-12-23 03:48:32 -08:00
parent f6a4d94de4
commit 8f4ecb0780
10 changed files with 402 additions and 264 deletions
+4 -4
View File
@@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
8904DEC8277055E90071E6CA /* OnboardingTrioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8904DEC7277055E90071E6CA /* OnboardingTrioView.swift */; };
8904DEC8277055E90071E6CA /* OnboardingOneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8904DEC7277055E90071E6CA /* OnboardingOneView.swift */; };
891060E4277359B900F14509 /* CloudStorageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891060E3277359B900F14509 /* CloudStorageService.swift */; };
891060E82774460500F14509 /* FirebaseInAppMessaging-Beta in Frameworks */ = {isa = PBXBuildFile; productRef = 891060E72774460500F14509 /* FirebaseInAppMessaging-Beta */; };
891060EA2774460500F14509 /* FirebaseInAppMessagingSwift-Beta in Frameworks */ = {isa = PBXBuildFile; productRef = 891060E92774460500F14509 /* FirebaseInAppMessagingSwift-Beta */; };
@@ -84,7 +84,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
8904DEC7277055E90071E6CA /* OnboardingTrioView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingTrioView.swift; sourceTree = "<group>"; };
8904DEC7277055E90071E6CA /* OnboardingOneView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingOneView.swift; sourceTree = "<group>"; };
891060E3277359B900F14509 /* CloudStorageService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudStorageService.swift; sourceTree = "<group>"; };
891060E527743FEB00F14509 /* nirvana-ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "nirvana-ios.entitlements"; sourceTree = "<group>"; };
89110713277166D6005797FA /* UserFriends.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFriends.swift; sourceTree = "<group>"; };
@@ -439,7 +439,7 @@
89F18AF2276ECD5D00115B1E /* OnBoarding */ = {
isa = PBXGroup;
children = (
8904DEC7277055E90071E6CA /* OnboardingTrioView.swift */,
8904DEC7277055E90071E6CA /* OnboardingOneView.swift */,
);
path = OnBoarding;
sourceTree = "<group>";
@@ -584,7 +584,7 @@
891A15E127653A7000B26659 /* nirvana_iosApp.swift in Sources */,
89BCABED276D2B05009E9B10 /* WavesGlassBackgroundView.swift in Sources */,
89F05BA6276ACD830002E9C7 /* ContactsPickerView.swift in Sources */,
8904DEC8277055E90071E6CA /* OnboardingTrioView.swift in Sources */,
8904DEC8277055E90071E6CA /* OnboardingOneView.swift in Sources */,
896CE7022770892F00DB474E /* CircleGridView.swift in Sources */,
89BDCDEA27697F9C00577829 /* UserMenu.swift in Sources */,
89BCABE7276B3D64009E9B10 /* InnerCircleViewModel.swift in Sources */,
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "undraw_explore_re_8l4v.svg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

@@ -9,6 +9,8 @@ import SwiftUI
import NavigationStack
struct AddBasicInfoView: View {
@Environment(\.dismiss) var dismiss
@EnvironmentObject var navigationStack : NavigationStack
@EnvironmentObject var authSessionStore: AuthSessionStore
@ObservedObject var addInfoViewModel: AddBasicInfoViewModel = AddBasicInfoViewModel()
@@ -22,120 +24,113 @@ struct AddBasicInfoView: View {
count: 5)
var body: some View {
ZStack {
// bg
WavesGlassBackgroundView()
// programmatic back button
ZStack(alignment: .topLeading) {
Color.clear
NavigationView {
ZStack {
// bg
WavesGlassBackgroundView()
Button {
self.navigationStack.pop()
} label: {
Label("back", systemImage:"chevron.left")
.labelStyle(.iconOnly)
.font(.title2)
}
.padding()
}
// main content
VStack {
// header logo area
LogoHeaderView()
// action text
VStack(alignment: .leading) {
Text("Let's Build A Profile")
.font(.title)
.fontWeight(.medium)
.foregroundColor(NirvanaColor.teal)
.multilineTextAlignment(.center)
Text("Select an avatar you like, then make a username! You can always change this later.")
.font(.subheadline)
.foregroundColor(Color.black.opacity(0.7))
}
.padding()
// Horizontal scroll view to allow user to select the avatar he or she wants
ScrollView([.horizontal, .vertical], showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(0..<Avatars.avatarSystemNames.count) { index in
Image(Avatars.avatarSystemNames[index])
.resizable()
.scaledToFit()
.frame(width: 50, height: 50, alignment: .center)
.blur(radius: self.selectedAvatarIndex == index ? 0 : 1)
.scaleEffect(self.selectedAvatarIndex == index ? 1.3 : 1)
.padding()
.background(self.selectedAvatarIndex == index ? Color.white.opacity(0.3) : Color.clear)
.clipShape(Circle())
.onTapGesture {
print("selected another avatar: \(index)")
self.selectedAvatarIndex = index
}
.animation(.spring())
}
}.padding(.top, 20)
}
// input nickname
// main content
VStack {
TextField("Nickname", text: self.$nickname)
.padding()
.background(.ultraThinMaterial)
.clipShape(Capsule())
.shadow(color: Color.black.opacity(0.3), radius: 20, x: 0, y: 20)
.font(.subheadline)
.multilineTextAlignment(.center)
// header logo area
LogoHeaderView()
// action text
VStack(alignment: .leading) {
Text("Let's Build A Profile")
.font(.title)
.fontWeight(.medium)
.foregroundColor(NirvanaColor.teal)
.multilineTextAlignment(.center)
Text("What do your friends call you?")
.font(.footnote)
.foregroundColor(Color.black.opacity(0.7))
}
.padding()
Spacer()
// button to save information
Button {
var updatedUser = self.authSessionStore.user
updatedUser?.avatar = Avatars.avatarSystemNames[self.selectedAvatarIndex]
updatedUser?.nickname = self.nickname
print("attempting to save information \(updatedUser)")
if updatedUser != nil {
self.addInfoViewModel.updateUser(currUser: updatedUser!) {
self.navigationStack.push(InnerCircleView())
}
Text("Select an avatar you like, then make a username! You can always change this later.")
.font(.subheadline)
.foregroundColor(Color.black.opacity(0.7))
}
} label: {
Text("Save")
.fontWeight(.heavy)
.foregroundColor(Color.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(self.nickname.count == 0 ? Color.white.opacity(0.3) : NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
// Horizontal scroll view to allow user to select the avatar he or she wants
ScrollView([.horizontal, .vertical], showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(0..<Avatars.avatarSystemNames.count) { index in
Image(Avatars.avatarSystemNames[index])
.resizable()
.scaledToFit()
.frame(width: 50, height: 50, alignment: .center)
.blur(radius: self.selectedAvatarIndex == index ? 0 : 0.2)
.scaleEffect(self.selectedAvatarIndex == index ? 1.5 : 1)
.padding()
.background(self.selectedAvatarIndex == index ? NirvanaColor.teal.opacity(0.5) : Color.clear)
.clipShape(Circle())
.onTapGesture {
print("selected another avatar: \(index)")
self.selectedAvatarIndex = index
}
.animation(.spring())
}
}.padding(.top, 20)
}
// input nickname
VStack {
TextField("nickname", text: self.$nickname)
.padding()
.background(.ultraThinMaterial)
.clipShape(Capsule())
.shadow(radius:10)
.font(.subheadline)
.multilineTextAlignment(.center)
Text("What do your friends call you?")
.font(.caption)
.foregroundColor(NirvanaColor.teal)
}
.padding()
Spacer()
// button to save information
Button {
var updatedUser = self.authSessionStore.user
updatedUser?.avatar = Avatars.avatarSystemNames[self.selectedAvatarIndex]
updatedUser?.nickname = self.nickname
print("attempting to save information \(updatedUser)")
if updatedUser != nil {
self.addInfoViewModel.updateUser(currUser: updatedUser!) {
self.navigationStack.push(InnerCircleView())
}
}
} label: {
Text("Save")
.fontWeight(.heavy)
.foregroundColor(self.nickname.count == 0 ? Color.white.opacity(0.2) : Color.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(self.nickname.count == 0 ? Color.white.opacity(0.3) : NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
}
.animation(.default)
.padding()
}
.animation(.default)
.padding()
.frame(maxWidth: UIScreen.main.bounds.width - 20, maxHeight: .infinity)
}
.frame(maxHeight: .infinity)
}
.onAppear {
// get current user nickname and avatar if they have one
self.nickname = self.authSessionStore.user?.nickname ?? ""
if self.authSessionStore.user?.avatar != nil { // if user has previously selected an avatar
self.selectedAvatarIndex = Avatars.avatarSystemNames.firstIndex(of: (self.authSessionStore.user?.avatar)!) ?? 0 // 0 in case the system names doesn't have it anymore
.onAppear {
// get current user nickname and avatar if they have one
self.nickname = self.authSessionStore.user?.nickname ?? ""
if self.authSessionStore.user?.avatar != nil { // if user has previously selected an avatar
self.selectedAvatarIndex = Avatars.avatarSystemNames.firstIndex(of: (self.authSessionStore.user?.avatar)!) ?? 0 // 0 in case the system names doesn't have it anymore
}
}
.navigationBarItems(trailing: Button(action: {
dismiss()
}, label: {
Text("Cancel")
}))
.navigationBarHidden(true)
}
//TODO: hook up the alert with the view model
// .alert(isPresented: Binding<Bool>(
@@ -42,7 +42,7 @@ struct CircleNavigationView: View {
}
Button {
self.navigationStack.push(OnboardingTrioView())
self.navigationStack.push(OnboardingOneView())
} label: {
Label("why?", systemImage: "leaf")
.foregroundColor(NirvanaColor.teal)
@@ -12,6 +12,7 @@ enum SheetView : Identifiable {
var id: Self { self }
case contacts
case inbox
case profile
}
struct InnerCircleView: View {
@@ -48,8 +49,10 @@ struct InnerCircleView: View {
switch page {
case SheetView.contacts:
FindFriendsView()
case SheetView.inbox:
InboxView()// test one for now
// case SheetView.inbox: // removing feature for now
// InboxView()
case SheetView.profile:
AddBasicInfoView()
default:
Text("asdf")
}
@@ -0,0 +1,186 @@
//
// OnboardingTrio.swift
// nirvana-ios
//
// Created by Arjun Patel on 12/14/21.
//
import SwiftUI
import NavigationStack
struct OnboardingOneView: View {
@EnvironmentObject var navigationStack: NavigationStack
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
var body: some View {
OnboardingTemplateView(imgName: "undraw_explore_re_8l4v-1", mainLeadingActText: "Be", mainHighlightedActText: "yourself", mainTrailingActText: "again.", subActText: "No more endless feeds, profiles, media, fomo, anxiety...focus on you and be more present.", bottomActArea: AnyView(
VStack {
// little bar to show progress out of three steps
HStack {
Capsule()
.frame(width: 20, height: 5)
.foregroundColor(NirvanaColor.teal)
Capsule()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
Circle()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
}
.padding()
HStack {
Button {
self.navigationStack.push(OnboardingTwo())
} label: {
Text("Next")
.fontWeight(.heavy)
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
}
// skip to hub
Button {
self.navigationStack.push(InnerCircleView())
} label: {
Text("Skip")
.font(.caption)
.foregroundColor(NirvanaColor.teal)
}
}
}
))
}
}
struct OnboardingTrioView_Previews: PreviewProvider {
static var previews: some View {
OnboardingOneView().environmentObject(AuthSessionStore())
}
}
struct OnboardingTwo: View {
@EnvironmentObject var navigationStack: NavigationStack
var body: some View {
OnboardingTemplateView(imgName: "undraw_connection_b-38-q", mainLeadingActText: "Be picky about your", mainHighlightedActText: "inner circle.", mainTrailingActText: "", subActText: "You are who you hang out with. We kept things minimal because less is more...and we care.", bottomActArea: AnyView(
VStack {
// little bar to show progress out of three steps
HStack {
Capsule()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
Capsule()
.frame(width: 20, height: 5)
.foregroundColor(NirvanaColor.teal)
Circle()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
}
.padding()
HStack {
Button {
self.navigationStack.pop()
} label: {
Label("back", systemImage:"chevron.left")
.labelStyle(.iconOnly)
.font(.title2)
.foregroundColor(NirvanaColor.teal)
.padding()
.background(.ultraThinMaterial)
.clipShape(Capsule())
.shadow(radius:10)
}
Button {
self.navigationStack.push(OnboardingTwo())
} label: {
Text("Next")
.fontWeight(.heavy)
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
}
// skip to hub
Button {
self.navigationStack.push(InnerCircleView())
} label: {
Text("Skip")
.font(.caption)
.foregroundColor(NirvanaColor.teal)
}
}
}
))
}
}
struct OnboardingThree: View {
@EnvironmentObject var navigationStack: NavigationStack
var body: some View {
OnboardingTemplateView(imgName: "undraw_voice_assistant_nrv7", mainLeadingActText: "Buttery smooth convos with your", mainHighlightedActText: "authentic voice.", mainTrailingActText: "", subActText: "Less screen time, no more meaningless texts. Start mindfully conversing without all of the noise.", bottomActArea: AnyView(
VStack {
// little bar to show progress out of three steps
HStack {
Capsule()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
Capsule()
.frame(width: 5, height: 5)
.foregroundColor(NirvanaColor.teal)
Circle()
.frame(width: 20, height: 5)
.foregroundColor(NirvanaColor.teal)
}
.padding()
HStack {
Button {
self.navigationStack.pop()
} label: {
Label("back", systemImage:"chevron.left")
.labelStyle(.iconOnly)
.font(.title2)
.foregroundColor(NirvanaColor.teal)
.padding()
.background(.ultraThinMaterial)
.clipShape(Capsule())
.shadow(radius:10)
}
Button {
self.navigationStack.push(OnboardingTwo())
} label: {
Text("Get Started")
.fontWeight(.heavy)
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
.background(NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
}
}
}
))
}
}
@@ -1,72 +0,0 @@
//
// OnboardingTrio.swift
// nirvana-ios
//
// Created by Arjun Patel on 12/14/21.
//
import SwiftUI
import NavigationStack
struct OnboardingTrioView: View {
@EnvironmentObject var navigationStack: NavigationStack
var body: some View {
ZStack(alignment: .topLeading) {
TabView {
OnboardingTemplateView(imgName: "undraw_through_the_park_lxnl", mainLeadingActText: "Be", mainHighlightedActText: "yourself", mainTrailingActText: "again.", subActText: "No more endless feeds, profiles, media, fomo, anxiety...focus on you and be more present.")
OnboardingTemplateView(imgName: "undraw_connection_b-38-q", mainLeadingActText: "Be picky about your", mainHighlightedActText: "inner circle.", mainTrailingActText: "", subActText: "You are who you hang out with. We kept things minimal because less is more...and we care.")
OnboardingTemplateView(imgName: "undraw_voice_assistant_nrv7", mainLeadingActText: "Buttery smooth convos with your", mainHighlightedActText: "authentic voice.", mainTrailingActText: "", subActText: "Less screen time, no more meaningless texts. Start mindfully conversing without all of the noise.", bottomActArea: AnyView(
VStack {
Button {
self.navigationStack.push(AddBasicInfoView())
} label: {
Text("Get Started")
.bold()
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding()
.background(NirvanaColor.teal)
.clipShape(Capsule())
.shadow(radius:10)
}
}.padding(.bottom, 30)
)
)
}
.navigationBarHidden(true)
.tabViewStyle(.page(indexDisplayMode: .automatic))
.ignoresSafeArea(.all)
HStack(alignment: .center) {
Button {
self.navigationStack.pop()
} label: {
Label("back", systemImage:"chevron.left")
.labelStyle(.iconOnly)
.font(.title2)
}
Spacer()
Button {
self.navigationStack.push(AddBasicInfoView())
} label: {
Text("Skip")
.foregroundColor(NirvanaColor.dimTeal)
}
}
.padding()
}
}
}
struct OnboardingTrioView_Previews: PreviewProvider {
static var previews: some View {
OnboardingTrioView().environmentObject(AuthSessionStore())
}
}
@@ -55,85 +55,10 @@ struct PhoneCodeVerificationView: View {
if self.verificationCode.count == 6 {
Button {
print("started verification process of code")
//disable focused textfield
self.focusedInputField = false
// show loading screen
self.isLoading.toggle()
// TODO: do all of this in view model authstore
// 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
)
// TODO: bug one: not navigating after creating user...two: creating user with a random Id
// firebase will now verify the credential
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil {
self.isLoading.toggle()
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")
// 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("firebase auth: user id that was authenticated is: \(userId)")
print("firebase auth: phone number that was authenticated is: \(userPhoneNumber)")
// if for some reason firebase couldn't get auth details
if userId == nil || userPhoneNumber == nil {
self.isLoading.toggle()
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
}
self.phoneverificationViewModel.createOrUpdateUser(userId: userId!, phoneNumber: userPhoneNumber!) {res in
switch res {
case .success(let msg):
// then sending to next page
self.navigationStack.push(OnboardingTrioView())
return
case .error(let error):
self.isLoading.toggle()
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
default: break
}
}
}
self.verify()
} label: {
Text("Verify")
.bold()
.fontWeight(.heavy)
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)
@@ -179,6 +104,85 @@ struct PhoneCodeVerificationView: View {
Text(self.toastSubMessage)
}
}
func verify() {
print("started verification process of code")
//disable focused textfield
self.focusedInputField = false
// show loading screen
self.isLoading.toggle()
// TODO: do all of this in view model authstore
// 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
)
// TODO: bug one: not navigating after creating user...two: creating user with a random Id
// firebase will now verify the credential
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil {
self.isLoading.toggle()
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")
// 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("firebase auth: user id that was authenticated is: \(userId)")
print("firebase auth: phone number that was authenticated is: \(userPhoneNumber)")
// if for some reason firebase couldn't get auth details
if userId == nil || userPhoneNumber == nil {
self.isLoading.toggle()
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
}
self.phoneverificationViewModel.createOrUpdateUser(userId: userId!, phoneNumber: userPhoneNumber!) {res in
switch res {
case .success(let msg):
// then sending to next page
self.navigationStack.push(OnboardingOneView())
return
case .error(let error):
self.isLoading.toggle()
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
default: break
}
}
}
}
}
struct PhoneCodeVerificationView_Previews: PreviewProvider {
@@ -123,7 +123,7 @@ struct OnboardingTemplateView_Previews: PreviewProvider {
VStack(alignment: .center) {
NavigationLink(destination: HomeView()) {
Text("Start Your Detox")
.bold()
.fontWeight(.heavy)
.foregroundColor(NirvanaColor.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 20)