]> git.r.bdr.sh - rbdr/map/blobdiff - Map/Views/MapDetail.swift
Fix performance and undo
[rbdr/map] / Map / Views / MapDetail.swift
index a8ea3d17fa054611e46f4a5ae66c34299973e6f9..bebe3a12414a5e9be8f5a9ca46de107d4442c530 100644 (file)
@@ -5,9 +5,25 @@
 //  Created by Ruben Beltran del Rio on 2/1/21.
 //
 
+import Combine
 import CoreData
 import SwiftUI
 
+class SaveTimer {
+  let currentTimePublisher = Timer.TimerPublisher(interval: 1, runLoop: .main, mode: .default)
+  let cancellable: AnyCancellable?
+
+  init() {
+    self.cancellable = currentTimePublisher.connect() as? AnyCancellable
+  }
+
+  deinit {
+    self.cancellable?.cancel()
+  }
+}
+
+let timer = SaveTimer()
+
 struct MapDetailView: View {
   @Environment(\.managedObjectContext) private var viewContext
   @Environment(\.colorScheme) var colorScheme
@@ -20,25 +36,8 @@ struct MapDetailView: View {
     MapColor.colorForScheme(colorScheme)
   }
 
-  private var title: Binding<String> {
-    Binding(
-      get: { map.title ?? "" },
-      set: { title in
-        map.title = title
-      }
-    )
-  }
-
-  private var content: Binding<String> {
-    Binding(
-      get: { map.content ?? "" },
-      set: { content in
-        map.content = content
-      }
-    )
-  }
-
-  @State private var selectedEvolution = StageType.general
+  @State var title: String
+  @State var content: String
 
   var body: some View {
     if map.uuid != nil {
@@ -46,10 +45,7 @@ struct MapDetailView: View {
         VStack {
           HStack {
             TextField(
-              "Title", text: title,
-              onCommit: {
-                try? viewContext.save()
-              }
+              "Title", text: $title
             ).font(.title2).textFieldStyle(PlainTextFieldStyle()).padding(.vertical, 4.0).padding(
               .leading, 4.0)
             Button(action: saveText) {
@@ -59,43 +55,49 @@ struct MapDetailView: View {
               Image(systemName: "photo")
             }.padding(.vertical, 4.0).padding(.leading, 4.0).padding(.trailing, 8.0)
           }
-          Picker("Evolution", selection: $selectedEvolution) {
-            ForEach(StageType.allCases) { stage in
-              Text(Stage.title(stage)).tag(stage).padding(4.0)
-            }
-          }.padding(.horizontal, 8.0).padding(.vertical, 4.0)
+          EvolutionPicker()
 
           ZStack(alignment: .topLeading) {
-            MapTextEditor(text: content).onChange(of: map.content) { _ in
-              try? viewContext.save()
-            }
-            .background(mapColor.background)
-            .foregroundColor(mapColor.foreground)
-            .frame(minHeight: 96.0)
+            MapTextEditor(text: $content, colorScheme: colorScheme)
+              .background(mapColor.background)
+              .foregroundColor(mapColor.foreground)
+              .frame(minHeight: 96.0)
           }.padding(.top, 8.0).padding(.leading, 8.0).background(mapColor.background).cornerRadius(
             5.0)
         }.padding(.horizontal, 8.0)
         ScrollView([.horizontal, .vertical]) {
-          MapRenderView(map: map, evolution: Stage.stages(selectedEvolution))
+          SlowMapRender(
+            content: content, evolution: Stage.stages(store.state.selectedEvolution),
+            colorScheme: colorScheme)
         }.background(mapColor.background)
+      }.onReceive(timer.currentTimePublisher) { _ in
+        saveModel()
+      }.onDisappear {
+        saveModel()
       }
     } else {
       DefaultMapView()
     }
   }
 
+  private func saveModel() {
+    map.content = content
+    map.title = title
+    try? viewContext.save()
+  }
+
   private func saveText() {
     store.send(.exportMapAsText(map: map))
   }
 
   private func saveImage() {
-    store.send(.exportMapAsImage(map: map, evolution: selectedEvolution))
+    store.send(.exportMapAsImage(map: map))
   }
 }
 
 struct MapDetailView_Previews: PreviewProvider {
   static var previews: some View {
-    MapDetailView(map: Map()).environment(
+    MapDetailView(map: Map(), title: "", content: "").environment(
       \.managedObjectContext, PersistenceController.preview.container.viewContext)
   }
 }