ContactImageRootView.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import Contacts
  2. import ContactsUI
  3. import SwiftUI
  4. import Swinject
  5. extension ContactImage {
  6. struct RootView: BaseView {
  7. let resolver: Resolver
  8. @State var state = StateModel()
  9. @State private var isAddSheetPresented: Bool = false
  10. @Environment(\.colorScheme) var colorScheme
  11. @Environment(AppState.self) var appState
  12. var body: some View {
  13. Form {
  14. contactItemsList
  15. }
  16. .onAppear(perform: configureView)
  17. .navigationTitle("Contacts Configuration")
  18. .navigationBarTitleDisplayMode(.large)
  19. .scrollContentBackground(.hidden)
  20. .background(appState.trioBackgroundColor(for: colorScheme))
  21. .toolbar {
  22. ToolbarItem(placement: .topBarTrailing) {
  23. Button(action: {
  24. isAddSheetPresented.toggle()
  25. }) {
  26. HStack {
  27. Text("Add Contact")
  28. Image(systemName: "plus")
  29. }
  30. }
  31. }
  32. }
  33. .sheet(isPresented: $isAddSheetPresented) {
  34. AddContactImageSheet(state: state)
  35. }
  36. }
  37. private var contactItemsList: some View {
  38. List {
  39. if state.contactImageEntries.isEmpty {
  40. Section(
  41. header: Text(""),
  42. content: {
  43. Text("No Contact Trick Entries.")
  44. }
  45. ).listRowBackground(Color.chart)
  46. } else {
  47. ForEach(state.contactImageEntries, id: \.id) { entry in
  48. NavigationLink(destination: ContactImageDetailView(entry: entry, state: state)) {
  49. HStack {
  50. ZStack {
  51. Circle()
  52. .fill(.black)
  53. .foregroundColor(.white)
  54. .frame(width: 40, height: 40)
  55. Image(uiImage: ContactPicture.getImage(contact: entry, state: state.state))
  56. .resizable()
  57. .frame(width: 40, height: 40)
  58. .clipShape(Circle())
  59. Circle()
  60. .stroke(lineWidth: 2)
  61. .foregroundColor(colorScheme == .dark ? .white : .black)
  62. .frame(width: 40, height: 40)
  63. }
  64. Text("\(entry.name)")
  65. }
  66. }
  67. }
  68. .onDelete(perform: onDelete)
  69. }
  70. Section {} header: {
  71. Text(
  72. "Add one or more contacts to your iOS Contacts to display real-time Trio metrics on your watch face. Be sure to grant Trio full access to your Contacts when prompted."
  73. )
  74. .textCase(nil)
  75. .foregroundStyle(.secondary)
  76. }
  77. }.listRowBackground(Color.chart)
  78. }
  79. private func onDelete(offsets: IndexSet) {
  80. Task {
  81. for offset in offsets {
  82. let entry = state.contactImageEntries[offset]
  83. await state.deleteContact(entry: entry)
  84. }
  85. }
  86. }
  87. }
  88. }