Преглед изворни кода

refactor: include Tag/Task/SubTask in model context, change relationship to cascade

Sam Jaffe пре 2 недеља
родитељ
комит
a53bd05ecb

+ 1 - 1
Todos/Model/Project.swift

@@ -13,7 +13,7 @@ final class Project : Codable {
   var timestamp: Date
   var category: String = ""
   var name: String = "New Project"
-  @Relationship(deleteRule: .nullify)
+  @Relationship(deleteRule: .cascade)
   var tasks: [Task] = []
   
   init(timestamp: Date) {

+ 20 - 5
Todos/Model/Task.swift

@@ -50,7 +50,7 @@ final class SubTask : Codable {
     }
     return rval
   }
-  
+
   enum CodingKeys : CodingKey { case name, notes, status }
 
   required init(from decoder: any Decoder) throws {
@@ -59,7 +59,7 @@ final class SubTask : Codable {
     notes = try container.decode(String.self, forKey: .notes)
     status = try container.decode(Status.self, forKey: .status)
   }
-  
+
   func encode(to encoder: any Encoder) throws {
     var container = encoder.container(keyedBy: CodingKeys.self)
     try container.encode(name, forKey: .name)
@@ -68,19 +68,34 @@ final class SubTask : Codable {
   }
 }
 
-struct Tag : Codable, Identifiable {
+@Model
+final class Tag : Codable {
   var id: String
-  
+
+  init(id: String) {
+    self.id = id
+  }
+
   func like(_ str: String) -> Bool {
     return id.caseInsensitiveCompare(str) == .orderedSame
   }
+
+  required init(from decoder: any Decoder) throws {
+    id = try decoder.singleValueContainer().decode(String.self)
+  }
+
+  func encode(to encoder: any Encoder) throws {
+    var single = encoder.singleValueContainer()
+    try single.encode(id)
+  }
 }
 
 @Model
 final class Task : Codable {
   var name: String
+  @Relationship(deleteRule: .cascade)
   var tags: [Tag] = []
-  @Relationship(deleteRule: .nullify)
+  @Relationship(deleteRule: .cascade)
   var subtasks: [SubTask] = []
   var notes: String = ""
   var status: Status = Status.Todo

+ 3 - 0
Todos/TodosApp.swift

@@ -20,6 +20,9 @@ struct TodosApp: App {
   var sharedModelContainer: ModelContainer = {
     let schema = Schema([
       Project.self,
+      Task.self,
+      SubTask.self,
+      Tag.self,
     ])
     let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
 

+ 2 - 0
Todos/View/ProjectPanelView.swift

@@ -9,6 +9,7 @@ import SwiftUI
 import SwiftData
 
 struct ProjectPanelView: View {
+  @Environment(\.modelContext) private var modelContext
   @AppStorage(UserDefaultsKeys.Category) var allGroups = CodableArray<Category>()
   @Bindable var item: Project
   @State private var empty = Category()
@@ -54,6 +55,7 @@ struct ProjectPanelView: View {
   private func addItem() {
     withAnimation {
       let newTask = Task(name: "New Task")
+      modelContext.insert(newTask)
       item.tasks.append(newTask)
     }
   }

+ 4 - 1
Todos/View/TagBarView.swift

@@ -9,6 +9,7 @@ import SwiftUI
 import SwiftData
 
 struct TagBarView: View {
+  @Environment(\.modelContext) private var modelContext
   @Binding var tags: [Tag]
   @AppStorage(UserDefaultsKeys.UrlHints) var allHints = CodableArray<URLHint>()
 
@@ -38,7 +39,9 @@ struct TagBarView: View {
       TextField("Tag", text: $active)
         .onSubmit {
           if !active.isEmpty && !tags.contains(where: { $0.like(active) }) {
-            tags.append(Tag(id: active))
+            let newTag = Tag(id: active)
+            modelContext.insert(newTag)
+            tags.append(newTag)
           }
           active = ""
         }

+ 5 - 2
Todos/View/TaskView.swift

@@ -9,11 +9,12 @@ import SwiftUI
 import SwiftData
 
 struct TaskView: View {
+  @Environment(\.modelContext) private var modelContext
   @Binding var task: Task
 
   @State private var hideTags: Bool = false
   @State private var hideNotes: Bool = false
-  
+
   @FocusState private var isFocused: Bool
 
   var body: some View {
@@ -39,7 +40,9 @@ struct TaskView: View {
         TextField("Task Name", text: $task.name)
           .focused($isFocused)
         Button() {
-          task.subtasks.append(SubTask(name: "Subtask"))
+          let newSubtask = SubTask(name: "Subtask")
+          modelContext.insert(newSubtask)
+          task.subtasks.append(newSubtask)
         } label: {
           Image(systemName: "plus")
             .help("Add a Subtask")