Add todo CRUD tab in companion app
This commit is contained in:
73
IrisCompanion/iris/ViewModels/TodosViewModel.swift
Normal file
73
IrisCompanion/iris/ViewModels/TodosViewModel.swift
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// TodosViewModel.swift
|
||||
// iris
|
||||
//
|
||||
// Created by Codex.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@MainActor
|
||||
final class TodosViewModel: ObservableObject {
|
||||
@Published private(set) var todos: [TodoItem] = []
|
||||
@Published var newTitle: String = ""
|
||||
|
||||
private let store: TodoStore
|
||||
|
||||
init(store: TodoStore = TodoStore()) {
|
||||
self.store = store
|
||||
refresh()
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
todos = sortedItems(store.snapshot())
|
||||
}
|
||||
|
||||
func addTodo() {
|
||||
let trimmed = normalizedTitle(newTitle)
|
||||
guard !trimmed.isEmpty else { return }
|
||||
store.add(title: trimmed)
|
||||
newTitle = ""
|
||||
refresh()
|
||||
}
|
||||
|
||||
func deleteTodo(id: UUID) {
|
||||
store.delete(id: id)
|
||||
refresh()
|
||||
}
|
||||
|
||||
func toggleCompleted(id: UUID) {
|
||||
guard let current = todos.first(where: { $0.id == id }) else { return }
|
||||
store.setCompleted(id: id, completed: !current.isCompleted)
|
||||
refresh()
|
||||
}
|
||||
|
||||
func updateTitle(id: UUID, title: String) {
|
||||
let trimmed = normalizedTitle(title)
|
||||
guard !trimmed.isEmpty else { return }
|
||||
store.updateTitle(id: id, title: trimmed)
|
||||
refresh()
|
||||
}
|
||||
|
||||
private func normalizedTitle(_ raw: String) -> String {
|
||||
raw.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
private func sortedItems(_ items: [TodoItem]) -> [TodoItem] {
|
||||
items.sorted { lhs, rhs in
|
||||
if lhs.isCompleted != rhs.isCompleted {
|
||||
return !lhs.isCompleted
|
||||
}
|
||||
if lhs.isCompleted {
|
||||
let lhsDate = lhs.completedAt ?? lhs.updatedAt
|
||||
let rhsDate = rhs.completedAt ?? rhs.updatedAt
|
||||
if lhsDate != rhsDate {
|
||||
return lhsDate > rhsDate
|
||||
}
|
||||
} else if lhs.createdAt != rhs.createdAt {
|
||||
return lhs.createdAt > rhs.createdAt
|
||||
}
|
||||
return lhs.id.uuidString < rhs.id.uuidString
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user