Pārlūkot izejas kodu

Adds data saving / loading to local storage

main
Steve Ruiz 4 gadus atpakaļ
vecāks
revīzija
520553fb2f

+ 2
- 0
components/editor.tsx Parādīt failu

@@ -1,4 +1,5 @@
1 1
 import useKeyboardEvents from "hooks/useKeyboardEvents"
2
+import useLoadOnMount from "hooks/useLoadOnMount"
2 3
 import Canvas from "./canvas/canvas"
3 4
 import StatusBar from "./status-bar"
4 5
 import Toolbar from "./toolbar"
@@ -6,6 +7,7 @@ import CodePanel from "./code-panel/code-panel"
6 7
 
7 8
 export default function Editor() {
8 9
   useKeyboardEvents()
10
+  useLoadOnMount()
9 11
 
10 12
   return (
11 13
     <>

+ 2
- 0
hooks/useCamera.ts Parādīt failu

@@ -21,6 +21,8 @@ export default function useCamera(ref: React.MutableRefObject<SVGGElement>) {
21 21
           "transform",
22 22
           `scale(${zoom}) translate(${point[0]} ${point[1]})`
23 23
         )
24
+
25
+        localStorage.setItem("code_slate_camera", JSON.stringify(data.camera))
24 26
       }
25 27
 
26 28
       camera = data.camera

+ 8
- 0
hooks/useLoadOnMount.ts Parādīt failu

@@ -0,0 +1,8 @@
1
+import { useEffect } from "react"
2
+import state from "state"
3
+
4
+export default function useLoadOnMount() {
5
+  useEffect(() => {
6
+    state.send("MOUNTED")
7
+  }, [])
8
+}

+ 3
- 1
pages/index.tsx Parādīt failu

@@ -1,4 +1,6 @@
1
-import Editor from "components/editor"
1
+// import Editor from "components/editor"
2
+import dynamic from "next/dynamic"
3
+const Editor = dynamic(() => import("components/editor"), { ssr: false })
2 4
 
3 5
 export default function Home() {
4 6
   return (

+ 61
- 4
state/history.ts Parādīt failu

@@ -1,9 +1,10 @@
1 1
 import { Data } from "types"
2 2
 import { BaseCommand } from "./commands/command"
3
+import state from "./state"
3 4
 
4 5
 // A singleton to manage history changes.
5 6
 
6
-class History<T> {
7
+class BaseHistory<T> {
7 8
   private stack: BaseCommand<T>[] = []
8 9
   private pointer = -1
9 10
   private maxLength = 100
@@ -42,11 +43,22 @@ class History<T> {
42 43
     this.save(data)
43 44
   }
44 45
 
45
-  save = (data: T) => {
46
+  load(data: T, id = "code_slate_0.0.1") {
46 47
     if (typeof window === "undefined") return
47 48
     if (typeof localStorage === "undefined") return
48 49
 
49
-    localStorage.setItem("code_slate_0.0.1", JSON.stringify(data))
50
+    const savedData = localStorage.getItem(id)
51
+
52
+    if (savedData !== null) {
53
+      Object.assign(data, this.restoreSavedData(JSON.parse(savedData)))
54
+    }
55
+  }
56
+
57
+  save = (data: T, id = "code_slate_0.0.1") => {
58
+    if (typeof window === "undefined") return
59
+    if (typeof localStorage === "undefined") return
60
+
61
+    localStorage.setItem(id, JSON.stringify(this.prepareDataForSave(data)))
50 62
   }
51 63
 
52 64
   disable = () => {
@@ -57,9 +69,54 @@ class History<T> {
57 69
     this._enabled = true
58 70
   }
59 71
 
72
+  prepareDataForSave(data: T): any {
73
+    return { ...data }
74
+  }
75
+
76
+  restoreSavedData(data: any): T {
77
+    return { ...data }
78
+  }
79
+
60 80
   get disabled() {
61 81
     return !this._enabled
62 82
   }
63 83
 }
64 84
 
65
-export default new History<Data>()
85
+// App-specific
86
+
87
+class History extends BaseHistory<Data> {
88
+  constructor() {
89
+    super()
90
+  }
91
+
92
+  prepareDataForSave(data: Data): any {
93
+    const dataToSave: any = { ...data }
94
+
95
+    dataToSave.selectedIds = Array.from(data.selectedIds.values())
96
+
97
+    return dataToSave
98
+  }
99
+
100
+  restoreSavedData(data: any): Data {
101
+    const restoredData = { ...data }
102
+
103
+    restoredData.selectedIds = new Set(restoredData.selectedIds)
104
+
105
+    // Also restore camera position, which is saved separately in this app
106
+    const cameraInfo = localStorage.getItem("code_slate_camera")
107
+
108
+    if (cameraInfo !== null) {
109
+      Object.assign(data.camera, JSON.parse(cameraInfo))
110
+
111
+      // And update the CSS property
112
+      document.documentElement.style.setProperty(
113
+        "--camera-zoom",
114
+        data.camera.zoom.toString()
115
+      )
116
+    }
117
+
118
+    return restoredData
119
+  }
120
+}
121
+
122
+export default new History()

+ 9
- 0
state/sessions/transform-session.ts Parādīt failu

@@ -56,6 +56,15 @@ export default class TransformSession extends BaseSession {
56 56
     } = this
57 57
 
58 58
     // Edge Transform
59
+    /*
60
+    Edge transform
61
+    
62
+    Corners a and b are the original top-left and bottom-right corners of the
63
+    bounding box. Depending on what the user is dragging, change one or both
64
+    points. To keep things smooth, calculate based by adding the delta (the 
65
+    vector between the current point and its original point) to the original
66
+    bounding box values.
67
+    */
59 68
 
60 69
     switch (transformType) {
61 70
       case TransformEdge.Top: {

+ 14
- 1
state/state.ts Parādīt failu

@@ -52,8 +52,16 @@ const state = createState({
52 52
     SELECTED_POLYLINE_TOOL: { unless: "isReadOnly", to: "polyline" },
53 53
     SELECTED_RECTANGLE_TOOL: { unless: "isReadOnly", to: "rectangle" },
54 54
   },
55
-  initial: "selecting",
55
+  initial: "loading",
56 56
   states: {
57
+    loading: {
58
+      on: {
59
+        MOUNTED: {
60
+          do: "restoreSavedData",
61
+          to: "selecting",
62
+        },
63
+      },
64
+    },
57 65
     selecting: {
58 66
       on: {
59 67
         UNDO: { do: "undo" },
@@ -492,6 +500,11 @@ const state = createState({
492 500
     decreaseCodeFontSize(data) {
493 501
       data.settings.fontSize--
494 502
     },
503
+
504
+    // Data
505
+    restoreSavedData(data) {
506
+      history.load(data)
507
+    },
495 508
   },
496 509
   values: {
497 510
     selectedIds(data) {

Notiek ielāde…
Atcelt
Saglabāt