NewScheduleItemEditor.swift 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //
  2. // NewScheduleItemEditor.swift
  3. // LoopKitUI
  4. //
  5. // Created by Michael Pangburn on 5/7/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. import LoopKit
  10. struct NewScheduleItemEditor<Value, ValuePicker: View>: View {
  11. enum SelectableTimes {
  12. case only(TimeInterval)
  13. case allExcept(Set<TimeInterval>)
  14. }
  15. @Binding var isPresented: Bool
  16. @State var item: RepeatingScheduleValue<Value>
  17. var initialItem: RepeatingScheduleValue<Value>
  18. var selectableTimes: SelectableTimes
  19. var valuePicker: (_ item: Binding<RepeatingScheduleValue<Value>>, _ availableWidth: CGFloat) -> ValuePicker
  20. var save: (RepeatingScheduleValue<Value>) -> Void
  21. init(
  22. isPresented: Binding<Bool>,
  23. initialItem: RepeatingScheduleValue<Value>,
  24. selectableTimes: SelectableTimes,
  25. @ViewBuilder valuePicker: @escaping (_ item: Binding<RepeatingScheduleValue<Value>>, _ availableWidth: CGFloat) -> ValuePicker,
  26. onSave save: @escaping (RepeatingScheduleValue<Value>) -> Void
  27. ) {
  28. self._isPresented = isPresented
  29. self._item = State(initialValue: initialItem)
  30. self.initialItem = initialItem
  31. self.selectableTimes = selectableTimes
  32. self.valuePicker = valuePicker
  33. self.save = save
  34. }
  35. var body: some View {
  36. VStack(spacing: 0) {
  37. ModalHeaderButtonBar(
  38. leading: { cancelButton },
  39. center: {
  40. Text(LocalizedString("New Entry", comment: "Title for mini-modal to add a new schedule entry"))
  41. .font(.headline)
  42. },
  43. trailing: { addButton }
  44. )
  45. ScheduleItemPicker(
  46. item: $item,
  47. isTimeSelectable: isTimeSelectable,
  48. valuePicker: { self.valuePicker(self.$item, $0) }
  49. )
  50. .padding(.horizontal)
  51. .background(
  52. RoundedCorners(radius: 10, corners: [.bottomLeft, .bottomRight])
  53. .fill(Color(.secondarySystemGroupedBackground))
  54. )
  55. }
  56. .padding(.horizontal)
  57. }
  58. func isTimeSelectable(_ time: TimeInterval) -> Bool {
  59. switch selectableTimes {
  60. case .only(let selectableTime):
  61. return time == selectableTime
  62. case .allExcept(let unavailableTimes):
  63. return !unavailableTimes.contains(time)
  64. }
  65. }
  66. var addButton: some View {
  67. Button(
  68. action: {
  69. withAnimation {
  70. self.save(self.item)
  71. self.isPresented = false
  72. }
  73. }, label: {
  74. Text(LocalizedString("Add", comment: "Button text to confirm adding a new schedule item"))
  75. }
  76. )
  77. }
  78. var cancelButton: some View {
  79. Button(
  80. action: {
  81. withAnimation {
  82. self.isPresented = false
  83. }
  84. }, label: {
  85. Text(LocalizedString("Cancel", comment: "Button text to cancel adding a new schedule item"))
  86. }
  87. )
  88. }
  89. }