]> git.r.bdr.sh - rbdr/map/blame - Map/Views/ContentView.swift
Fix performance and undo
[rbdr/map] / Map / Views / ContentView.swift
CommitLineData
5e8ff485
RBR
1//
2// ContentView.swift
3// Map
4//
5// Created by Ruben Beltran del Rio on 2/1/21.
6//
7
8import CoreData
9import SwiftUI
10
11struct 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
75a0e450
RBR
28 NavigationLink(
29 destination: MapDetailView(map: map, title: map.title ?? "", content: map.content ?? "")
30 ) {
5e8ff485
RBR
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)
91fd8618 42 }.contextMenu {
75a0e450
RBR
43 Button(
44 action: { store.send(.deleteMap(map: map)) },
45 label: {
46 Image(systemName: "trash")
47 Text("Delete")
48 })
5e8ff485
RBR
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 }
75a0e450 63 DefaultMapView()
5e8ff485
RBR
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
104private let mapFormatter: DateFormatter = {
105 let formatter = DateFormatter()
106 formatter.dateStyle = .short
107 formatter.timeStyle = .none
108 return formatter
109}()
110
111struct ContentView_Previews: PreviewProvider {
112 static var previews: some View {
113 ContentView().environment(
114 \.managedObjectContext, PersistenceController.preview.container.viewContext)
115 }
116}