8
8
import { SET_ACTIVE_COMPONENT } from ' ./store/types'
9
9
const deepEqual = require (' lodash.isequal' )
10
10
const cloneDeep = require (' lodash.clonedeep' )
11
+ const throttle = require (' lodash.throttle' )
11
12
import { defaultState } from ' ./store/state/index.js'
12
13
14
+
15
+ // use this to make sure these actions don't count as things you "undo"
16
+ const ignoredActions = new Set ([
17
+ " setActiveComponent" ,
18
+ " setActiveLayer" ,
19
+ " upOneLayer" ,
20
+ " setActiveHTML"
21
+ ])
22
+
23
+
13
24
let redoMixin = {
14
25
data () {
15
26
return {
@@ -47,19 +58,24 @@ let redoMixin = {
47
58
},
48
59
49
60
mounted () {
61
+
62
+ const throttledUndo = throttle (this .undo ,300 )
63
+ const throttledRedo = throttle (this .redo ,300 )
64
+
50
65
window .addEventListener (' keydown' , event => {
51
66
if (event .ctrlKey && event .key === ' z' ) {
52
67
event .preventDefault ()
53
- this . undo ()
68
+ throttledUndo ()
54
69
}
55
70
})
56
71
window .addEventListener (' keydown' , event => {
57
72
if (event .ctrlKey && event .key === ' y' ) {
58
73
event .preventDefault ()
59
- this . redo ()
74
+ throttledRedo ()
60
75
}
61
76
})
62
77
78
+ // commented code for hotkeys for debuging///////////////////////
63
79
// window.addEventListener('keydown', event => {
64
80
// if (event.ctrlKey && event.key === 'a') {
65
81
// event.preventDefault()
@@ -76,6 +92,7 @@ let redoMixin = {
76
92
// }
77
93
// }
78
94
// });
95
+ // ////////////////////////////////////////////////////////////////////
79
96
80
97
// console.log("do we want this? or this.$store.state?", this.$store.state)
81
98
this .initialState = defaultState (this .$store .state )
@@ -85,49 +102,63 @@ let redoMixin = {
85
102
undo : function () {
86
103
// do {
87
104
// console.log("How far back?")
105
+ if (this .doneAction .length === 0 ){
106
+ return
107
+ }
88
108
89
109
this .isTimetraveling = true
90
110
91
111
let undone = this .doneAction .pop ()
92
112
113
+ // assuming we have have something to undo, we check if we are undoing an action that has no feedback
114
+ // like say changing active elements or active components or going up and down a layer since these can be obscured from immediate feedback
115
+ // will just feel bad to undo (Imagine someone just clicking around out of boredom and then deciding to undo
116
+ // will force them to have to undo the 30 highlights they just did instead of the last "Real" action)
117
+ // if this happens we keep popping the doneAction queue and building up the redo queue.
93
118
if (undone !== undefined ) {
94
119
this .undoneAction .push (undone)
95
- if (undone .type === ' setActiveComponent' ) {
96
- console .log (' We did something useless!' )
97
- do {
120
+ if (ignoredActions .has (undone .type )) {
121
+ // console.log('We did something useless!')
122
+ while (this .doneAction [this .doneAction .length - 1 ] &&
123
+ ignoredActions .has (this .doneAction [this .doneAction .length - 1 ].type )){
98
124
this .undoneAction .push (this .doneAction .pop ())
99
125
}
100
- while (this .doneAction [this .doneAction .length - 1 ] &&
101
- (this .doneAction [this .doneAction .length - 1 ].type === ' setActiveComponent' ))
126
+ let finalPop = this .doneAction .pop ()
127
+ if (finalPop !== undefined ){
128
+ this .undoneAction .push (finalPop)
129
+ }
102
130
}
131
+ // if we get here, that means we have undone all "useless" actions
132
+ // so we have to do one more final pop and push, have to make sure it isn't null though
133
+
103
134
}
104
135
105
- // while (this.doneAction[this.doneAction.length-1] &&
106
- // (this.doneAction[this.doneAction.length - 1].type === "setActiveComponent" ||
107
- // this.doneAction[this.doneAction.length - 1].type === "updateComponentPosition" ))
108
136
let payload = {
109
137
initialState: this .initialState ,
110
138
store: this .$store
111
139
}
112
140
this .$store .commit (' EMPTY_STATE' , payload)
113
141
console .log (this .$store )
114
142
this .doneAction .forEach (action => {
115
- console .log (' In the loop' , this .$store )
143
+ // console.log('In the loop', this.$store)
116
144
// this.$store.commit(`${mutation.type}`, mutation.payload);
117
145
this .$store .dispatch (action .type , cloneDeep (action .payload ))
118
146
this .doneAction .pop ()
119
147
})
120
148
this .isTimetraveling = false
121
149
},
150
+
122
151
redo : function () {
123
152
let action = this .undoneAction .pop ()
153
+
154
+ // we have to set timeTraveling to true to preserve the undoneAction array while we make changes
124
155
this .isTimetraveling = true
125
156
if (action) {
126
157
this .$store .dispatch (action .type , cloneDeep (action .payload ))
127
158
}
128
159
this .isTimetraveling = false
129
- if (action && (action .type === ' setActiveComponent ' )) {
130
- console .log (' WE GOTTA DO MORE' )
160
+ if (action && ignoredActions . has (action .type )) {
161
+ // console.log('WE GOTTA DO MORE')
131
162
this .redo ()
132
163
}
133
164
}
0 commit comments