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