import CoreData import SwiftUI struct MapEditorWindow: View { @Environment(\.managedObjectContext) private var viewContext @EnvironmentObject var store: AppStore @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Map.createdAt, ascending: true)], animation: .default) private var maps: FetchedResults var body: some View { NavigationView { List { if maps.count == 0 { EmptyMapDetailScreen() } ForEach(maps) { map in NavigationLink( destination: MapDetailScreen(map: map, title: map.title ?? "", content: map.content ?? "") ) { HStack { Text(map.title ?? "Untitled Map") Spacer() Text(mapFormatter.string(from: (map.createdAt ?? Date()))) .font(.caption) .padding(.vertical, 2.0) .padding(.horizontal, 4.0) .background(Color.accentColor) .foregroundColor(Color.black) .cornerRadius(2.0) }.padding(.leading, 8.0) }.contextMenu { Button( action: { store.send(.deleteMap(map: map)) }, label: { Image(systemName: "trash") Text("Delete") }) } } .onDelete(perform: deleteMaps) }.frame(minWidth: 250.0, alignment: .leading) .toolbar { HStack { Button(action: toggleSidebar) { Label("Toggle Sidebar", systemImage: "sidebar.left") } Button(action: addMap) { Label("Add Map", systemImage: "plus") } } } EmptyMapDetailScreen() } } private func toggleSidebar() { NSApp.keyWindow?.firstResponder?.tryToPerform( #selector(NSSplitViewController.toggleSidebar(_:)), with: nil) } private func addMap() { withAnimation { let newMap = Map(context: viewContext) newMap.uuid = UUID() newMap.createdAt = Date() newMap.title = "Map \(newMap.createdAt!.format())" newMap.content = "" do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } private func deleteMaps(offsets: IndexSet) { withAnimation { offsets.map { maps[$0] }.forEach(viewContext.delete) do { try viewContext.save() } catch { let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } } } } private let mapFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .none return formatter }() struct ContentView_Previews: PreviewProvider { static var previews: some View { MapEditorWindow().environment( \.managedObjectContext, PersistenceController.preview.container.viewContext) } }