TaskView.swift 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // TaskView.swift
  3. // Todos
  4. //
  5. // Created by Sam Jaffe on 2/28/26.
  6. //
  7. import SwiftUI
  8. import SwiftData
  9. struct TaskView: View {
  10. @Environment(\.modelContext) private var modelContext
  11. @Binding var task: Task
  12. @State private var hideTags: Bool = false
  13. @State private var hideNotes: Bool = false
  14. @FocusState private var isFocused: Bool
  15. var body: some View {
  16. VStack {
  17. HStack {
  18. Image(systemName: task.status.label)
  19. .frame(width: 20)
  20. .padding(.trailing, -10)
  21. Picker("", selection: $task.status) {
  22. ForEach(Status.allCases) { unit in
  23. Text(String(describing: unit))
  24. }
  25. }
  26. .fixedSize(horizontal: true, vertical: false)
  27. .onChange(of: task.status) {
  28. if task.status.isStrong {
  29. task.subtasks
  30. .filter({ !$0.status.isStrong })
  31. .forEach({ subtask in subtask.status = task.status })
  32. }
  33. }
  34. TextField("Task Name", text: $task.name)
  35. .focused($isFocused)
  36. Button() {
  37. let newSubtask = SubTask(name: "Subtask")
  38. modelContext.insert(newSubtask)
  39. task.subtasks.append(newSubtask)
  40. } label: {
  41. Image(systemName: "plus")
  42. .help("Add a Subtask")
  43. }
  44. }
  45. if isFocused || !(hideTags || task.tags.isEmpty) {
  46. HStack {
  47. TagBarView(tags: $task.tags)
  48. .font(.footnote)
  49. .focused($isFocused)
  50. .padding(.leading, 30)
  51. VisibilityTapper(hideToggle: $hideTags)
  52. .focused($isFocused)
  53. }
  54. }
  55. if isFocused || !(hideNotes || task.notes.isEmpty) {
  56. HStack {
  57. TextField("Notes", text: $task.notes, axis: .vertical)
  58. .font(.footnote)
  59. .focused($isFocused)
  60. .padding(.leading, 30)
  61. VisibilityTapper(hideToggle: $hideNotes)
  62. .focused($isFocused)
  63. }
  64. }
  65. VStack {
  66. ForEach($task.subtasks) { subtask in
  67. SubTaskView(task: subtask)
  68. .padding(.leading, 5)
  69. .contextMenu {
  70. Button(action: { task.subtasks.removeAll(where: { $0.id == subtask.id }) }) {
  71. Label("Delete", systemImage: "trash")
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. #Preview {
  80. @Previewable @State var task = Task(name: "New Task")
  81. TaskView(task: $task)
  82. .frame(minHeight: 100) // Preview does not resize window properly
  83. }