SilencePodSelectionView.swift 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // SilencePodSelectionView.swift
  3. // OmniKit
  4. //
  5. // Created by Joe Moran 8/30/23.
  6. // Copyright © 2023 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. import LoopKit
  10. import LoopKitUI
  11. import OmniKit
  12. struct SilencePodSelectionView: View {
  13. @Environment(\.horizontalSizeClass) var horizontalSizeClass
  14. @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
  15. private var initialValue: SilencePodPreference
  16. @State private var preference: SilencePodPreference
  17. private var onSave: ((_ selectedValue: SilencePodPreference, _ completion: @escaping (_ error: LocalizedError?) -> Void) -> Void)?
  18. @State private var alertIsPresented: Bool = false
  19. @State private var error: LocalizedError?
  20. @State private var saving: Bool = false
  21. init(initialValue: SilencePodPreference, onSave: @escaping (_ selectedValue: SilencePodPreference, _ completion: @escaping (_ error: LocalizedError?) -> Void) -> Void) {
  22. self.initialValue = initialValue
  23. self._preference = State(initialValue: initialValue)
  24. self.onSave = onSave
  25. }
  26. var body: some View {
  27. contentWithCancel
  28. }
  29. var content: some View {
  30. VStack {
  31. List {
  32. Section {
  33. Text(LocalizedString("Silence Pod mode suppresses all Pod alert and confirmation reminder beeping.", comment: "Help text for Silence Pod view")).fixedSize(horizontal: false, vertical: true)
  34. .padding(.vertical, 10)
  35. }
  36. Section {
  37. ForEach(SilencePodPreference.allCases, id: \.self) { preference in
  38. HStack {
  39. CheckmarkListItem(
  40. title: Text(preference.title),
  41. description: Text(preference.description),
  42. isSelected: Binding(
  43. get: { self.preference == preference },
  44. set: { isSelected in
  45. if isSelected {
  46. self.preference = preference
  47. }
  48. }
  49. )
  50. )
  51. }
  52. .padding(.vertical, 10)
  53. }
  54. }
  55. .buttonStyle(PlainButtonStyle()) // Disable row highlighting on selection
  56. }
  57. VStack {
  58. Button(action: {
  59. saving = true
  60. onSave?(preference) { (error) in
  61. saving = false
  62. if let error = error {
  63. self.error = error
  64. self.alertIsPresented = true
  65. } else {
  66. self.presentationMode.wrappedValue.dismiss()
  67. }
  68. }
  69. }) {
  70. Text(saveButtonText)
  71. .actionButtonStyle(.primary)
  72. }
  73. .padding()
  74. .disabled(saving || !valueChanged)
  75. }
  76. .padding(self.horizontalSizeClass == .regular ? .bottom : [])
  77. .background(Color(UIColor.secondarySystemGroupedBackground).shadow(radius: 5))
  78. }
  79. .insetGroupedListStyle()
  80. .navigationTitle(LocalizedString("Silence Pod", comment: "navigation title for Silnce Pod"))
  81. .navigationBarTitleDisplayMode(.automatic)
  82. .alert(isPresented: $alertIsPresented, content: { alert(error: error) })
  83. }
  84. private var contentWithCancel: some View {
  85. if saving {
  86. return AnyView(content
  87. .navigationBarBackButtonHidden(true)
  88. )
  89. } else if valueChanged {
  90. return AnyView(content
  91. .navigationBarBackButtonHidden(true)
  92. .navigationBarItems(leading: cancelButton)
  93. )
  94. } else {
  95. return AnyView(content)
  96. }
  97. }
  98. private var cancelButton: some View {
  99. Button(action: { self.presentationMode.wrappedValue.dismiss() } ) {
  100. Text(LocalizedString("Cancel", comment: "Button title for cancelling silence pod edit"))
  101. }
  102. }
  103. var saveButtonText: String {
  104. if saving {
  105. return LocalizedString("Saving...", comment: "button title for saving silence pod preference while saving")
  106. } else {
  107. return LocalizedString("Save", comment: "button title for saving silence pod preference")
  108. }
  109. }
  110. private var valueChanged: Bool {
  111. return preference != initialValue
  112. }
  113. private func alert(error: Error?) -> SwiftUI.Alert {
  114. return SwiftUI.Alert(
  115. title: Text(LocalizedString("Failed to update silence pod preference.", comment: "Alert title for error when updating silence pod preference")),
  116. message: Text(error?.localizedDescription ?? "No Error")
  117. )
  118. }
  119. }
  120. struct SilencePodSelectionView_Previews: PreviewProvider {
  121. static var previews: some View {
  122. NavigationView {
  123. SilencePodSelectionView(initialValue: .disabled) { selectedValue, completion in
  124. print("Selected: \(selectedValue)")
  125. completion(nil)
  126. }
  127. }
  128. }
  129. }