aboutsummaryrefslogtreecommitdiff
path: root/Map/Presentation/Windows/MapEditorWindow.swift
blob: 65316cc8686bc69e1d1a44483bcfa3739cfd2843 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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<Map>

  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)
  }
}