txtodo

[DORMANT] a minimalist todo list app inspired by jeff huang
git clone git://git.figbert.com/txtodo.git
Log | Files | Refs | README

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 }