TaskView.swift (5481B)
1 // 2 // TaskView.swift 3 // txtodo 4 // 5 // Created by FIGBERT on 7/27/20. 6 // 7 8 import SwiftUI 9 10 struct TaskView: View { 11 @Environment(\.managedObjectContext) var managedObjectContext 12 @Environment(\.layoutDirection) var direction 13 @ObservedObject var task: Task 14 @State var priority: Int 15 @State private var config = TaskViewConfig() 16 17 var body: some View { 18 let priorityIntermediary = Binding<Int>( 19 get: { self.priority }, 20 set: { value in 21 self.priority = value 22 self.managedObjectContext.performAndWait { 23 self.task.priority = Int16(value) 24 try? self.managedObjectContext.save() 25 } 26 self.config.editingPriority = false 27 } 28 ) 29 return HStack { 30 if task.daily && !task.hasBeenDelayed && !task.completed && config.showingDelay { 31 Image(systemName: "calendar.circle.fill") 32 .font(.system(size: 25)) 33 .foregroundColor(.blue) 34 .onTapGesture { 35 self.managedObjectContext.performAndWait { 36 self.task.date = Calendar.current.date(byAdding: .day, value: 1, to: task.date) ?? Date() 37 self.task.hasBeenDelayed = true 38 try? self.managedObjectContext.save() 39 } 40 config.showingDelay = false 41 } 42 } 43 Image(systemName: task.completed ? "checkmark.square" : "square") 44 .onTapGesture { 45 let generator = UIImpactFeedbackGenerator(style: .medium) 46 generator.prepare() 47 self.managedObjectContext.performAndWait { 48 self.task.completed.toggle() 49 if !self.task.daily { 50 self.task.date = Date.init() 51 } 52 try? self.managedObjectContext.save() 53 } 54 generator.impactOccurred() 55 } 56 Spacer() 57 if !config.editingText { 58 Text(task.name) 59 .strikethrough(task.completed) 60 .onTapGesture(count: 2) { 61 if !self.task.completed { 62 self.config.editingText = true 63 } 64 } 65 .onTapGesture { 66 self.config.showingNotes = true 67 } 68 } else { 69 TextField("edit task", text: $task.name, onCommit: { 70 self.config.editingText = false 71 self.managedObjectContext.performAndWait { 72 try? self.managedObjectContext.save() 73 } 74 }) 75 } 76 Spacer() 77 if !config.editingPriority { 78 HStack(alignment: .center, spacing: 2) { 79 ForEach(1 ..< Int(task.priority + 1), id: \.self) {_ in 80 Text("!") 81 } 82 } 83 .font(.system(size: 10, weight: .light)) 84 .onTapGesture(count: 2) { 85 if !self.task.completed { 86 self.config.editingPriority = true 87 } 88 } 89 } else { 90 Picker( 91 selection: priorityIntermediary, 92 label: Text("task priority"), 93 content: { 94 Text("!").tag(1) 95 Text("!!").tag(2) 96 Text("!!!").tag(3) 97 }) 98 .pickerStyle(SegmentedPickerStyle()) 99 .labelsHidden() 100 } 101 if config.showingDelete { 102 Image(systemName: "trash.circle.fill") 103 .font(.system(size: 25)) 104 .foregroundColor(.red) 105 .onTapGesture { 106 self.managedObjectContext.performAndWait { 107 self.managedObjectContext.delete(self.task) 108 try? self.managedObjectContext.save() 109 } 110 } 111 } 112 } 113 .font(.system(size: 18, weight: .light)) 114 .foregroundColor(task.completed ? .secondary : .primary) 115 .multilineTextAlignment(.center) 116 .offset(x: config.offset) 117 .gesture( 118 DragGesture() 119 .onChanged({ value in 120 config.offset = direction == .leftToRight ? value.translation.width : -value.translation.width 121 }) 122 .onEnded({ value in 123 if task.daily && config.offset > 15 { 124 config.showingDelay.toggle() 125 } else if -config.offset > 15 { 126 config.showingDelete.toggle() 127 } 128 config.offset = 0 129 }) 130 ) 131 .sheet(isPresented: $config.showingNotes, content: { 132 NoteSheet(task: self.task) 133 }) 134 } 135 } 136 137 struct TaskViewConfig { 138 var editingText: Bool = false 139 var editingPriority: Bool = false 140 var showingNotes: Bool = false 141 var showingDelete: Bool = false 142 var showingDelay: Bool = false 143 var offset: CGFloat = 0 144 }