| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- //
- // ContentView.swift
- // Todos
- //
- // Created by Sam Jaffe on 2/28/26.
- //
- import SwiftUI
- import SwiftData
- struct ContentView: View {
- @Environment(\.modelContext) private var modelContext
- @AppStorage(UserDefaultsKeys.WeekStart) private var weekStart = Date()
- let inPreview = ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
-
- @Binding var isMoveMode: Bool
- @Query private var items: [Project]
- @State private var selection: Project?
- var body: some View {
- NavigationSplitView {
- List(selection: $selection) {
- ForEach(items, id: \.self) { item in
- NavigationLink(value: item) {
- Text(item.name)
- } .contextMenu {
- Button(action: { deleteItem(item: item) }) {
- Label("Delete", systemImage: "trash")
- }
- }
- }
- .onDelete(perform: deleteItems)
- }
- .navigationSplitViewColumnWidth(min: 180, ideal: 200)
- .toolbar {
- ToolbarItem {
- Button(action: addItem) {
- Label("New Project", systemImage: "plus")
- }
- }
- }
- } detail: {
- if let selection = selection {
- ProjectPanelView(item: selection, isMoveMode: $isMoveMode)
- } else {
- let header = items.isEmpty ? "Create a New Project" : "Select a project from the sidebar"
- ContentUnavailableView(header, systemImage: "doc.text.image.fill")
- }
- }
- .onAppear(perform: autosave)
- }
- private func addItem() {
- withAnimation {
- let newItem = Project(timestamp: Date())
- modelContext.insert(newItem)
- }
- }
-
- private func autosave() {
- if inPreview {
- // This isn't great, but we shouldn't be running this in a preview
- // environment in the first place, so w/e.
- return
- }
-
- let now = Date()
- let sunday = Calendar.current.nextDate(after: weekStart,
- matching: DateComponents(weekday: 1),
- matchingPolicy: .nextTime)
- if now <= sunday! {
- return
- }
-
- let ymd = weekStart.formatted(.iso8601.year().month().day())
- SaveController.save(items, to: SaveController.filename(date: ymd))
- weekStart = now
- cleanup()
- }
-
- private func cleanup() {
- for item in items {
- item.tasks.removeAll(where: { $0.status == .Complete })
- for task in item.tasks {
- if task.status == .InProgress {
- task.status = .Todo
- }
- task.subtasks.removeAll(where: { $0.status == .Complete })
- for subtask in task.subtasks {
- if subtask.status == .InProgress {
- subtask.status = .Todo
- }
- }
- }
- }
- }
-
- private func deleteItem(item: Project) {
- if let selection = selection, selection == item {
- self.selection = nil
- }
- withAnimation {
- modelContext.delete(item)
- }
- }
- private func deleteItems(offsets: IndexSet) {
- if let selection = selection, offsets.contains(where: { items[$0] == selection }) {
- self.selection = nil
- }
- withAnimation {
- for index in offsets {
- modelContext.delete(items[index])
- }
- }
- }
- }
- #Preview {
- @Previewable @State var isMoveMode = false
- ContentView(isMoveMode: $isMoveMode)
- .modelContainer(for: Project.self, inMemory: true)
- }
|