AutosaveMenu.swift 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // SaveAndRefreshMenu.swift
  3. // Todos
  4. //
  5. // Created by Sam Jaffe on 3/9/26.
  6. //
  7. import SwiftUI
  8. import SwiftData
  9. internal import Combine
  10. struct AutosaveMenu: View {
  11. @Environment(\.modelContext) private var modelContext
  12. @AppStorage(UserDefaultsKeys.WeekStart) private var weekStart = Date()
  13. let inPreview = ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
  14. @Query private var items: [Project]
  15. @Binding var hasAutosave: Bool
  16. var body: some View {
  17. Button("Save and Cleanup") {
  18. tryAutosave()
  19. }
  20. .keyboardShortcut("R", modifiers: [.command, .shift])
  21. // .disabled(!shouldAutosave)
  22. Text(" Next Autosave: after \(ymd(nextSunday(weekStart)))")
  23. .onAppear(perform: tryAutosave)
  24. }
  25. func tryAutosave() {
  26. if shouldAutosave && !inPreview {
  27. saveAndCleanup(weekStart)
  28. weekStart = Date()
  29. hasAutosave = true
  30. }
  31. }
  32. func nextSunday(_ date: Date) -> Date {
  33. Calendar.current.nextDate(after: date,
  34. matching: DateComponents(weekday: 1),
  35. matchingPolicy: .nextTime)!
  36. }
  37. func ymd(_ date: Date) -> String {
  38. date.formatted(.iso8601.year().month().day())
  39. }
  40. var shouldAutosave: Bool {
  41. ymd(Date()) > ymd(nextSunday(weekStart))
  42. }
  43. func saveAndCleanup(_ date: Date) {
  44. SaveController.save(items, toUrl: SaveController.filename(date: ymd(date)))
  45. for item in items {
  46. item.tasks.removeAll(where: { $0.status == .complete })
  47. for task in item.tasks {
  48. if task.status == .inProgress {
  49. task.status = .todo
  50. }
  51. task.subtasks.removeAll(where: { $0.status == .complete })
  52. for subtask in task.subtasks where subtask.status == .inProgress {
  53. subtask.status = .todo
  54. }
  55. }
  56. }
  57. }
  58. }
  59. #Preview {
  60. @Previewable @State var hasAutosave = true
  61. AutosaveMenu(hasAutosave: $hasAutosave)
  62. }