// // EditFilterView.swift // Tusker // // Created by Shadowfacts on 12/2/22. // Copyright © 2022 Shadowfacts. All rights reserved. // import SwiftUI import Pachyderm struct EditFilterView: View { private static let expiresInOptions: [MenuPicker.Option] = { let f = DateComponentsFormatter() f.maximumUnitCount = 1 f.unitsStyle = .full f.allowedUnits = [.weekOfMonth, .day, .hour, .minute] let durations: [TimeInterval] = [ 30 * 60, 60 * 60, 6 * 60 * 60, 24 * 60 * 60, 3 * 24 * 60 * 60, 7 * 24 * 60 * 60, ] return durations.map { .init(value: $0, title: f.string(from: $0)!) } }() @ObservedObject var filter: FilterMO let updateFilter: () -> Void @EnvironmentObject private var mastodonController: MastodonController @State private var edited = false init(filter: FilterMO, updateFilter: @escaping () -> Void) { self.filter = filter self.updateFilter = updateFilter if let expiresAt = filter.expiresAt { let dist = expiresAt.timeIntervalSinceNow self.expiresIn = Self.expiresInOptions.min(by: { a, b in let aDist = abs(a.value - dist) let bDist = abs(b.value - dist) return aDist < bDist })!.value } else { self.expiresIn = 24 * 60 * 60 } } @State private var expiresIn: TimeInterval { didSet { if filter.expiresAt != nil { filter.expiresAt = Date(timeIntervalSinceNow: expiresIn) } } } private var expires: Binding { Binding { filter.expiresAt != nil } set: { newValue in if newValue { filter.expiresAt = Date(timeIntervalSinceNow: expiresIn) } else { filter.expiresAt = nil } } } var body: some View { Form { Section { TextField("Phrase", text: $filter.phrase) Toggle("Whole Word", isOn: $filter.wholeWord) } Section { Toggle("Expires", isOn: expires) if expires.wrappedValue { Picker(selection: $expiresIn) { ForEach(Self.expiresInOptions, id: \.value) { option in Text(option.title).tag(option.value) } } label: { Text("Duration") } } } Section { ForEach(Filter.Context.allCases, id: \.rawValue) { context in Toggle(isOn: Binding(get: { filter.contexts.contains(context) }, set: { newValue in if newValue { if !filter.contexts.contains(context) { filter.contexts.append(context) } } else if filter.contexts.count > 1 { filter.contexts.removeAll(where: { $0 == context }) } })) { Text(context.displayName) } .toggleStyle(FilterContextToggleStyle()) } } header: { Text("Contexts") } } .navigationTitle("Edit Filter") .navigationBarTitleDisplayMode(.inline) .onReceive(filter.objectWillChange, perform: { _ in edited = true }) .onDisappear { if edited { updateFilter() } } } } private struct FilterContextToggleStyle: ToggleStyle { func makeBody(configuration: Configuration) -> some View { Button { configuration.isOn.toggle() } label: { HStack { configuration.label .foregroundColor(.primary) Spacer() if configuration.isOn { Image(systemName: "checkmark") } } } } } //struct EditFilterView_Previews: PreviewProvider { // static var previews: some View { // EditFilterView() // } //}