nice sheet for adding contacts

This commit is contained in:
talksik
2021-12-20 04:27:18 -08:00
parent a3374050ff
commit e2f8d9d1e2
6 changed files with 45 additions and 27 deletions
@@ -8,10 +8,11 @@
import SwiftUI import SwiftUI
import Contacts import Contacts
struct ContactPickerView: View { struct ContactsPickerView: View {
@Binding var showPicker: Bool @Environment(\.dismiss) var dismiss
// updates the parent view for it to do something with the new contact // updates the parent view for it to do something with the new contact
@Binding var selectedContact: CNContact? @State var selectedContact: CNContact?
var contacts: [String: [CNContact]] = loadContactsGrouped() var contacts: [String: [CNContact]] = loadContactsGrouped()
@@ -22,14 +23,17 @@ struct ContactPickerView: View {
ForEach(keys.sorted(), id: \.self) { key in ForEach(keys.sorted(), id: \.self) { key in
Section(header: Text(key)) { Section(header: Text(key)) {
ForEach(contacts[key] ?? [CNContact](), id: \.identifier) { contact in ForEach(contacts[key] ?? [CNContact](), id: \.identifier) { contact in
ContactRow(contact: contact, showPicker: self.$showPicker, selectedContact: self.$selectedContact) ContactRow(contact: contact, selectedContact: self.$selectedContact)
} }
} }
} }
} }
.listStyle(GroupedListStyle()) .listStyle(GroupedListStyle())
.navigationTitle("All Contacts".localized) .navigationTitle("All Contacts".localized)
.navigationBarItems(trailing: Button(action: {self.showPicker = false}, label: { .navigationBarItems(trailing: Button(action: {
dismiss()
}, label: {
Text("Cancel".localized) Text("Cancel".localized)
})) }))
} }
@@ -43,6 +47,8 @@ struct ContactPickerView: View {
return String(contact.familyName.first ?? "?") return String(contact.familyName.first ?? "?")
} }
print(group)
return group return group
} }
} }
@@ -50,7 +56,6 @@ struct ContactPickerView: View {
struct ContactRow: View { struct ContactRow: View {
var contact: CNContact var contact: CNContact
@Binding var showPicker: Bool
@Binding var selectedContact: CNContact? @Binding var selectedContact: CNContact?
var body: some View { var body: some View {
@@ -67,7 +72,6 @@ struct ContactRow: View {
func selectContact() { func selectContact() {
self.selectedContact = self.contact self.selectedContact = self.contact
self.showPicker = false
} }
} }
@@ -53,7 +53,7 @@ struct ContactsView: View {
Spacer() Spacer()
} }
.sheet(isPresented: self.$showPicker) { .sheet(isPresented: self.$showPicker) {
ContactPickerView(showPicker: self.$showPicker, selectedContact: self.$selectedContact) // ContactPickerView(showPicker: self.$showPicker, selectedContact: self.$selectedContact)
} }
.padding() .padding()
.background(NirvanaColor.bgLightGrey) .background(NirvanaColor.bgLightGrey)
@@ -12,17 +12,11 @@ import SwiftUI
class ContactsViewModel : ObservableObject { class ContactsViewModel : ObservableObject {
@Published var showPermissionAlert = false @Published var showPermissionAlert = false
let store: CNContactStore let store: CNContactStore = CNContactStore()
let keys: [CNKeyDescriptor] let keys: [CNKeyDescriptor] = [CNContactImageDataKey as CNKeyDescriptor,
CNContactPhoneNumbersKey as CNKeyDescriptor,
init() { CNContactEmailAddressesKey as CNKeyDescriptor,
store = CNContactStore() CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
keys = [CNContactImageDataKey as CNKeyDescriptor,
CNContactPhoneNumbersKey as CNKeyDescriptor,
CNContactEmailAddressesKey as CNKeyDescriptor,
CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]
}
func openSettings() { func openSettings() {
guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return } guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
@@ -30,19 +24,20 @@ class ContactsViewModel : ObservableObject {
} }
func requestAccess() { func requestAccess() {
store.requestAccess(for: .contacts) {
(granted, error) in store.requestAccess(for: .contacts) {(granted, error) in
// TODO: do something useful with completionHandler
return return
} }
// TODO do something useful with completionHandler
} }
func fetchContacts(sortOrder: CNContactSortOrder = .userDefault) -> [CNContact] { func fetchContacts(sortOrder: CNContactSortOrder = .userDefault) -> [CNContact] {
let authStatus = CNContactStore.authorizationStatus(for: .contacts) let authStatus = CNContactStore.authorizationStatus(for: .contacts)
if authStatus == .notDetermined { if authStatus == .notDetermined {
requestAccess() requestAccess()
} else if authStatus == .restricted { } else if authStatus == .restricted {
// TODO prompt user that app is useless without access to contacts // TODO: prompt user that app is useless without access to contacts
self.showPermissionAlert = true self.showPermissionAlert = true
} }
@@ -16,7 +16,7 @@ struct CircleGridView: View {
// magic variables for grid // magic variables for grid
// TODO: make the top left person or one horizontal person be in the center of screen...makes the top honeycomb pop // TODO: make the top left person or one horizontal person be in the center of screen...makes the top honeycomb pop
private static var numberOfItems: Int = 59 private static var numberOfItems: Int = 12
private static let size: CGFloat = UIScreen.main.bounds.height*0.15 // scaling with screen size private static let size: CGFloat = UIScreen.main.bounds.height*0.15 // scaling with screen size
private static let spacingBetweenColumns: CGFloat = 0 private static let spacingBetweenColumns: CGFloat = 0
private static let spacingBetweenRows: CGFloat = 0 private static let spacingBetweenRows: CGFloat = 0
@@ -12,6 +12,8 @@ struct CircleNavigationView: View {
@EnvironmentObject var navigationStack: NavigationStack @EnvironmentObject var navigationStack: NavigationStack
@EnvironmentObject var authSessionStore: AuthSessionStore @EnvironmentObject var authSessionStore: AuthSessionStore
@Binding var sheetView: SheetView?
var body: some View { var body: some View {
HStack(alignment: .center) { HStack(alignment: .center) {
Menu { Menu {
@@ -23,7 +25,8 @@ struct CircleNavigationView: View {
} }
Button { Button {
self.navigationStack.push(ContactsView()) print("going to show contacts now")
self.sheetView = .contacts
} label: { } label: {
Label("add peeps", systemImage: "person.2.wave.2") Label("add peeps", systemImage: "person.2.wave.2")
.foregroundColor(NirvanaColor.teal) .foregroundColor(NirvanaColor.teal)
@@ -141,6 +144,6 @@ struct CircleNavigationView: View {
struct CircleNavigationView_Previews: PreviewProvider { struct CircleNavigationView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
CircleNavigationView().environmentObject(AuthSessionStore(isPreview: true)) CircleNavigationView(sheetView: .constant(SheetView.contacts)).environmentObject(AuthSessionStore(isPreview: true))
} }
} }
@@ -8,10 +8,18 @@
import SwiftUI import SwiftUI
import NavigationStack import NavigationStack
enum SheetView : Identifiable {
var id: Self { self }
case contacts
case inbox
}
struct InnerCircleView: View { struct InnerCircleView: View {
@EnvironmentObject var authSessionStore: AuthSessionStore @EnvironmentObject var authSessionStore: AuthSessionStore
@EnvironmentObject var navigationStack: NavigationStack @EnvironmentObject var navigationStack: NavigationStack
@State var sheetView: SheetView? = nil
let universalSize = UIScreen.main.bounds let universalSize = UIScreen.main.bounds
var body: some View { var body: some View {
@@ -25,13 +33,21 @@ struct InnerCircleView: View {
// header // header
VStack(alignment: .leading) { VStack(alignment: .leading) {
CircleNavigationView() CircleNavigationView(sheetView: self.$sheetView)
Spacer() Spacer()
} }
CircleFooterView() CircleFooterView()
} }
.sheet(item: self.$sheetView) {page in
switch page {
case SheetView.contacts:
ContactsPickerView()
case SheetView.inbox:
OnboardingTrioView()// test one for now
}
}
.onAppear() { .onAppear() {
} }
} }