feat: add macOS task board widget app

This commit is contained in:
loveuer
2026-09-02 00:27:33 -07:00
commit 9dafdce855
13 changed files with 485 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
import Foundation
enum TaskList: String, CaseIterable, Codable, Identifiable {
case todo
case doing
case done
var id: String { rawValue }
var title: String {
switch self {
case .todo: "To do"
case .doing: "Doing"
case .done: "Done"
}
}
}
struct TaskItem: Identifiable, Codable, Equatable {
let id: UUID
var title: String
var list: TaskList
let createdAt: Date
init(id: UUID = UUID(), title: String, list: TaskList = .todo, createdAt: Date = .now) {
self.id = id
self.title = title
self.list = list
self.createdAt = createdAt
}
}
+53
View File
@@ -0,0 +1,53 @@
import Foundation
import Combine
#if canImport(WidgetKit)
import WidgetKit
#endif
final class TaskStore: ObservableObject {
static let groupIdentifier = "group.com.example.utrello"
private static let tasksKey = "tasks"
@Published private(set) var tasks: [TaskItem] {
didSet { save() }
}
init() {
tasks = Self.loadTasks()
}
func add(title: String, to list: TaskList = .todo) {
let title = title.trimmingCharacters(in: .whitespacesAndNewlines)
guard !title.isEmpty else { return }
tasks.insert(TaskItem(title: title, list: list), at: 0)
}
func move(_ task: TaskItem, to list: TaskList) {
guard let index = tasks.firstIndex(of: task) else { return }
tasks[index].list = list
}
func delete(_ task: TaskItem) {
tasks.removeAll { $0.id == task.id }
}
private func save() {
guard let data = try? JSONEncoder().encode(tasks) else { return }
Self.defaults.set(data, forKey: Self.tasksKey)
#if canImport(WidgetKit)
WidgetCenter.shared.reloadTimelines(ofKind: "UTrelloTasksWidget")
#endif
}
static func loadTasks() -> [TaskItem] {
guard
let data = defaults.data(forKey: tasksKey),
let tasks = try? JSONDecoder().decode([TaskItem].self, from: data)
else { return [] }
return tasks
}
private static var defaults: UserDefaults {
UserDefaults(suiteName: groupIdentifier) ?? .standard
}
}