listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

ItemListView.swift (2715B)


      1 import CoreData
      2 import SwiftUI
      3 
      4 struct ItemListView: View {
      5     let store: ItemStore
      6     let syncMonitor: CloudKitSyncMonitor
      7 
      8     @AppStorage("listName") private var listName = "Items"
      9     @AppStorage("colorTheme") private var colorThemeRaw = 0
     10     private var colorTheme: ColorTheme { ColorTheme(rawValue: colorThemeRaw) ?? .pilbara }
     11 
     12     @FetchRequest(
     13         sortDescriptors: [
     14             SortDescriptor(\ItemEntity.sortOrder, order: .forward),
     15         ],
     16         animation: .default
     17     )
     18     private var items: FetchedResults<ItemEntity>
     19 
     20     var body: some View {
     21         let activeItems = items.filter { !$0.isCompleted }.map(ItemValue.init)
     22         let completedItems = items.filter { $0.isCompleted }
     23             .sorted { $0.completedOrder > $1.completedOrder }
     24             .map(ItemValue.init)
     25 
     26         NavigationStack {
     27             Group {
     28                 if items.isEmpty {
     29                     ContentUnavailableView(
     30                         "No Items",
     31                         systemImage: "checklist",
     32                         description: Text("Add items on your iPhone or Mac.")
     33                     )
     34                 } else {
     35                     List {
     36                         ForEach(Array(activeItems.enumerated()), id: \.element.id) { index, item in
     37                             ItemRowView(
     38                                 item: item,
     39                                 index: index,
     40                                 totalActive: activeItems.count,
     41                                 colorTheme: colorTheme,
     42                                 onToggle: { toggleItem($0) }
     43                             )
     44                         }
     45 
     46                         if !completedItems.isEmpty {
     47                             Section("Completed") {
     48                                 ForEach(completedItems) { item in
     49                                     ItemRowView(
     50                                         item: item,
     51                                         index: 0,
     52                                         totalActive: 0,
     53                                         colorTheme: colorTheme,
     54                                         onToggle: { toggleItem($0) }
     55                                     )
     56                                 }
     57                             }
     58                         }
     59                     }
     60                 }
     61             }
     62             .navigationTitle(listName)
     63         }
     64     }
     65 
     66     private func toggleItem(_ item: ItemValue) {
     67         do {
     68             if item.isCompleted {
     69                 try store.uncomplete(itemID: item.id)
     70             } else {
     71                 try store.complete(itemID: item.id)
     72             }
     73         } catch {
     74             // Sync monitor handles error reporting
     75         }
     76     }
     77 }