TeraCalendarComposerFields.swift (2433B)
1 import SwiftUI 2 3 struct TeraCalendarComposerFields: View { 4 @ObservedObject var store: TeraAddStore 5 6 var body: some View { 7 Picker("When", selection: binding(\.eventTiming)) { 8 ForEach(TeraEventTiming.allCases) { timing in 9 Text(timing.label).tag(Optional(timing)) 10 } 11 } 12 .accessibilityIdentifier("radroots.add.event_timing") 13 if store.form.eventTiming == .allDay { 14 TeraCivilDateField(label: "Starts", identifier: "radroots.add.event.start", raw: binding(\.eventStartDate)) 15 TeraCivilDateField(label: "Ends before (optional)", identifier: "radroots.add.event.end", raw: binding(\.eventEndDate)) 16 Text("The end date is not included. Leave it empty for a one-day event.") 17 .font(.caption).foregroundStyle(.secondary) 18 } else { 19 timedFields 20 } 21 } 22 23 @ViewBuilder 24 private var timedFields: some View { 25 TextField("Event time zone (optional)", text: Binding( 26 get: { store.form.eventTimezone ?? "" }, 27 set: { store.updateForm(\.eventTimezone, $0.isEmpty ? nil : String($0.prefix(255))) } 28 )) 29 .textInputAutocapitalization(.never).autocorrectionDisabled() 30 .accessibilityIdentifier("tera.add.event.timezone") 31 if let zone = selectedTimeZone { 32 Text(store.form.eventTimezone == nil ? "Device display time: \(zone.identifier)" : "Event time: \(zone.identifier)") 33 .font(.caption).foregroundStyle(.secondary) 34 TeraTimedCalendarField(label: "Starts", identifier: "radroots.add.event.start", timeZone: zone, 35 seconds: binding(\.eventStartUnixSeconds)) 36 TeraTimedCalendarField(label: "Ends", identifier: "radroots.add.event.end", timeZone: zone, 37 seconds: binding(\.eventEndUnixSeconds)) 38 if store.form.eventEndUnixSeconds != nil { 39 Button("Remove end time") { store.updateForm(\.eventEndUnixSeconds, nil) } 40 } 41 } else { 42 Text("Choose a supported time zone, such as America/Vancouver.").foregroundStyle(.secondary) 43 } 44 } 45 46 private var selectedTimeZone: TimeZone? { 47 guard let identifier = store.form.eventTimezone else { return .current } 48 guard identifier.utf8.count <= 255 else { return nil } 49 return TimeZone(identifier: identifier) 50 } 51 52 private func binding<Value>(_ keyPath: WritableKeyPath<TeraAddForm, Value>) -> Binding<Value> { 53 Binding(get: { store.form[keyPath: keyPath] }, set: { store.updateForm(keyPath, $0) }) 54 } 55 }