Browse Source

feat: add popover to Task w/ Category picker and new Priority enum

Sam Jaffe 2 tuần trước cách đây
mục cha
commit
21abee85ca
3 tập tin đã thay đổi với 71 bổ sung9 xóa
  1. 33 0
      Todos/Model/Priority.swift
  2. 1 0
      Todos/Model/Task.swift
  3. 37 9
      Todos/View/TaskView.swift

+ 33 - 0
Todos/Model/Priority.swift

@@ -0,0 +1,33 @@
+//
+//  Priority.swift
+//  Todos
+//
+//  Created by Sam Jaffe on 3/7/26.
+//
+
+import Foundation
+import SwiftUI
+
+enum Priority : String, CaseIterable, Identifiable, Codable {
+  case low = "Low"
+  case medium = "Medium"
+  case high = "High"
+
+  var id: String { self.rawValue }
+  
+  var label: String {
+    switch self {
+    case .low: return "chevron.down"
+    case .medium: return "chevron.up"
+    case .high: return "chevron.up.2"
+    }
+  }
+  
+  var style: some ShapeStyle {
+    switch self {
+    case .low: return .green
+    case .medium: return .blue
+    case .high: return .red
+    }
+  }
+}

+ 1 - 0
Todos/Model/Task.swift

@@ -21,6 +21,7 @@ final class Task: Codable {
   var subtasks: [SubTask] = []
   var notes: String = ""
   var status: Status = Status.todo
+  var priority: Priority? = nil
 
   init(parent: Project? = nil) {
     self.project = parent

+ 37 - 9
Todos/View/TaskView.swift

@@ -13,15 +13,25 @@ struct TaskView: View {
   @AppStorage(UserDefaultsKeys.Category) var allGroups = CodableArray<Category>()
   @Binding var task: Task
 
+  @State private var showDialogue: Bool = false
   @State private var hideTags: Bool = false
   @State private var hideNotes: Bool = false
   @State private var empty = Category()
+  let unset: Priority? = nil
 
   @FocusState private var isFocused: Bool
 
   var body: some View {
     VStack {
       HStack {
+        if let priority = task.priority {
+          Image(systemName: priority.label)
+            .foregroundStyle(priority.style)
+            .bold()
+            .frame(width: 20)
+            .padding(.trailing, -10)
+        }
+
         StatusPicker(status: $task.status)
           .onChange(of: task.status) {
             if task.status.isStrong {
@@ -42,22 +52,40 @@ struct TaskView: View {
           Image(systemName: "plus")
             .help("Add a Subtask")
         }
-      }
-
-      if isFocused || !(hideTags || task.tags.isEmpty) {
-        HStack {
-          TagBarView(task: $task)
-            .font(.footnote)
-            .padding(.leading, 30)
-          if isFocused {
-            Picker("", selection: $task.category) {
+        Button {
+          showDialogue = !showDialogue
+        } label: {
+          Label("", systemImage: "ellipsis.circle")
+            .foregroundStyle(.gray)
+            .font(.title2)
+        }
+        .buttonStyle(.borderless)
+        .popover(isPresented: $showDialogue) {
+          List{
+            Picker("Task Category", selection: $task.category) {
               Text(empty.name).tag("")
               ForEach(allGroups) { group in
                 Text(group.name)
               }
             }
             .fixedSize(horizontal: true, vertical: false)
+
+            Picker("Priority", selection: $task.priority) {
+              Text("").tag(unset)
+              ForEach(Priority.allCases) { unit in
+                Text(unit.id).tag(unit)
+              }
+            }
           }
+        }
+        Text("")
+      }
+
+      if isFocused || !(hideTags || task.tags.isEmpty) {
+        HStack {
+          TagBarView(task: $task)
+            .font(.footnote)
+            .padding(.leading, 30)
           VisibilityTapper(hideToggle: $hideTags)
         }.focused($isFocused)
       }