浏览代码

Adds data saving / loading to local storage

main
Steve Ruiz 4 年前
父节点
当前提交
520553fb2f
共有 7 个文件被更改,包括 99 次插入6 次删除
  1. 2
    0
      components/editor.tsx
  2. 2
    0
      hooks/useCamera.ts
  3. 8
    0
      hooks/useLoadOnMount.ts
  4. 3
    1
      pages/index.tsx
  5. 61
    4
      state/history.ts
  6. 9
    0
      state/sessions/transform-session.ts
  7. 14
    1
      state/state.ts

+ 2
- 0
components/editor.tsx 查看文件

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

+ 2
- 0
hooks/useCamera.ts 查看文件

21
           "transform",
21
           "transform",
22
           `scale(${zoom}) translate(${point[0]} ${point[1]})`
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
       camera = data.camera
28
       camera = data.camera

+ 8
- 0
hooks/useLoadOnMount.ts 查看文件

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 查看文件

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
 export default function Home() {
5
 export default function Home() {
4
   return (
6
   return (

+ 61
- 4
state/history.ts 查看文件

1
 import { Data } from "types"
1
 import { Data } from "types"
2
 import { BaseCommand } from "./commands/command"
2
 import { BaseCommand } from "./commands/command"
3
+import state from "./state"
3
 
4
 
4
 // A singleton to manage history changes.
5
 // A singleton to manage history changes.
5
 
6
 
6
-class History<T> {
7
+class BaseHistory<T> {
7
   private stack: BaseCommand<T>[] = []
8
   private stack: BaseCommand<T>[] = []
8
   private pointer = -1
9
   private pointer = -1
9
   private maxLength = 100
10
   private maxLength = 100
42
     this.save(data)
43
     this.save(data)
43
   }
44
   }
44
 
45
 
45
-  save = (data: T) => {
46
+  load(data: T, id = "code_slate_0.0.1") {
46
     if (typeof window === "undefined") return
47
     if (typeof window === "undefined") return
47
     if (typeof localStorage === "undefined") return
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
   disable = () => {
64
   disable = () => {
57
     this._enabled = true
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
   get disabled() {
80
   get disabled() {
61
     return !this._enabled
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 查看文件

56
     } = this
56
     } = this
57
 
57
 
58
     // Edge Transform
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
     switch (transformType) {
69
     switch (transformType) {
61
       case TransformEdge.Top: {
70
       case TransformEdge.Top: {

+ 14
- 1
state/state.ts 查看文件

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

正在加载...
取消
保存