]> git.r.bdr.sh - rbdr/map/blob - Map/Presentation/Windows/MapEditorWindow.swift
65316cc8686bc69e1d1a44483bcfa3739cfd2843
[rbdr/map] / Map / Presentation / Windows / MapEditorWindow.swift
1 import CoreData
2 import SwiftUI
3
4 struct MapEditorWindow: View {
5 @Environment(\.managedObjectContext) private var viewContext
6
7 @EnvironmentObject var store: AppStore
8
9 @FetchRequest(
10 sortDescriptors: [NSSortDescriptor(keyPath: \Map.createdAt, ascending: true)],
11 animation: .default)
12 private var maps: FetchedResults<Map>
13
14 var body: some View {
15 NavigationView {
16 List {
17 if maps.count == 0 {
18 EmptyMapDetailScreen()
19 }
20 ForEach(maps) { map in
21 NavigationLink(
22 destination: MapDetailScreen(map: map, title: map.title ?? "", content: map.content ?? "")
23 ) {
24 HStack {
25 Text(map.title ?? "Untitled Map")
26 Spacer()
27 Text(mapFormatter.string(from: (map.createdAt ?? Date())))
28 .font(.caption)
29 .padding(.vertical, 2.0)
30 .padding(.horizontal, 4.0)
31 .background(Color.accentColor)
32 .foregroundColor(Color.black)
33 .cornerRadius(2.0)
34 }.padding(.leading, 8.0)
35 }.contextMenu {
36 Button(
37 action: { store.send(.deleteMap(map: map)) },
38 label: {
39 Image(systemName: "trash")
40 Text("Delete")
41 })
42 }
43 }
44 .onDelete(perform: deleteMaps)
45 }.frame(minWidth: 250.0, alignment: .leading)
46 .toolbar {
47 HStack {
48 Button(action: toggleSidebar) {
49 Label("Toggle Sidebar", systemImage: "sidebar.left")
50 }
51 Button(action: addMap) {
52 Label("Add Map", systemImage: "plus")
53 }
54 }
55 }
56 EmptyMapDetailScreen()
57 }
58 }
59
60 private func toggleSidebar() {
61 NSApp.keyWindow?.firstResponder?.tryToPerform(
62 #selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
63 }
64
65 private func addMap() {
66 withAnimation {
67 let newMap = Map(context: viewContext)
68 newMap.uuid = UUID()
69 newMap.createdAt = Date()
70 newMap.title = "Map \(newMap.createdAt!.format())"
71 newMap.content = ""
72
73 do {
74 try viewContext.save()
75 } catch {
76 let nsError = error as NSError
77 fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
78 }
79 }
80 }
81
82 private func deleteMaps(offsets: IndexSet) {
83
84 withAnimation {
85 offsets.map { maps[$0] }.forEach(viewContext.delete)
86
87 do {
88 try viewContext.save()
89 } catch {
90 let nsError = error as NSError
91 fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
92 }
93 }
94 }
95 }
96
97 private let mapFormatter: DateFormatter = {
98 let formatter = DateFormatter()
99 formatter.dateStyle = .short
100 formatter.timeStyle = .none
101 return formatter
102 }()
103
104 struct ContentView_Previews: PreviewProvider {
105 static var previews: some View {
106 MapEditorWindow().environment(
107 \.managedObjectContext, PersistenceController.preview.container.viewContext)
108 }
109 }