]>
Commit | Line | Data |
---|---|---|
5e8ff485 RBR |
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 | ||
77d0155b RBR |
14 | @EnvironmentObject var store: AppStore |
15 | ||
5e8ff485 RBR |
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(destination: MapDetailView(map: map)) { | |
29 | HStack { | |
30 | Text(map.title ?? "Untitled Map") | |
31 | Spacer() | |
32 | Text(mapFormatter.string(from: (map.createdAt ?? Date()))) | |
33 | .font(.caption) | |
34 | .padding(.vertical, 2.0) | |
35 | .padding(.horizontal, 4.0) | |
36 | .background(Color.accentColor) | |
37 | .foregroundColor(Color.black) | |
38 | .cornerRadius(2.0) | |
39 | }.padding(.leading, 8.0) | |
91fd8618 RBR |
40 | }.contextMenu { |
41 | Button(action: { store.send(.deleteMap(map: map))}) { | |
42 | Image(systemName: "trash") | |
43 | Text("Delete") | |
44 | } | |
5e8ff485 RBR |
45 | } |
46 | } | |
47 | .onDelete(perform: deleteMaps) | |
48 | }.frame(minWidth: 250.0, alignment: .leading) | |
49 | .toolbar { | |
50 | HStack { | |
51 | Button(action: toggleSidebar) { | |
52 | Label("Toggle Sidebar", systemImage: "sidebar.left") | |
53 | } | |
54 | Button(action: addMap) { | |
55 | Label("Add Map", systemImage: "plus") | |
56 | } | |
57 | } | |
58 | } | |
91fd8618 | 59 | DefaultMapView() |
5e8ff485 RBR |
60 | } |
61 | } | |
62 | ||
63 | private func toggleSidebar() { | |
64 | NSApp.keyWindow?.firstResponder?.tryToPerform( | |
65 | #selector(NSSplitViewController.toggleSidebar(_:)), with: nil) | |
66 | } | |
67 | ||
68 | private func addMap() { | |
69 | withAnimation { | |
70 | let newMap = Map(context: viewContext) | |
71 | newMap.uuid = UUID() | |
72 | newMap.createdAt = Date() | |
73 | newMap.title = "Map \(newMap.createdAt!.format())" | |
74 | newMap.content = "" | |
75 | ||
76 | do { | |
77 | try viewContext.save() | |
78 | } catch { | |
79 | let nsError = error as NSError | |
80 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | private func deleteMaps(offsets: IndexSet) { | |
86 | ||
87 | withAnimation { | |
88 | offsets.map { maps[$0] }.forEach(viewContext.delete) | |
89 | ||
90 | do { | |
91 | try viewContext.save() | |
92 | } catch { | |
93 | let nsError = error as NSError | |
94 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") | |
95 | } | |
96 | } | |
97 | } | |
98 | } | |
99 | ||
100 | private let mapFormatter: DateFormatter = { | |
101 | let formatter = DateFormatter() | |
102 | formatter.dateStyle = .short | |
103 | formatter.timeStyle = .none | |
104 | return formatter | |
105 | }() | |
106 | ||
107 | struct ContentView_Previews: PreviewProvider { | |
108 | static var previews: some View { | |
109 | ContentView().environment( | |
110 | \.managedObjectContext, PersistenceController.preview.container.viewContext) | |
111 | } | |
112 | } |