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,48 +102,62 @@ 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 ' ) {
120
+ if (ignoredActions . has ( undone .type ) ) {
96
121
// console.log('We did something useless!')
97
- do {
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
this .doneAction .forEach (action => {
114
- // console.log('In the loop', this.$store)
142
+ // console.log('In the loop', this.$store)
115
143
// this.$store.commit(`${mutation.type}`, mutation.payload);
116
144
this .$store .dispatch (action .type , cloneDeep (action .payload ))
117
145
this .doneAction .pop ()
118
146
})
119
147
this .isTimetraveling = false
120
148
},
149
+
121
150
redo : function () {
122
151
let action = this .undoneAction .pop ()
152
+
153
+ // we have to set timeTraveling to true to preserve the undoneAction array while we make changes
123
154
this .isTimetraveling = true
124
155
if (action) {
125
156
this .$store .dispatch (action .type , cloneDeep (action .payload ))
126
157
}
127
158
this .isTimetraveling = false
128
- if (action && (action .type === ' setActiveComponent ' )) {
129
- console .log (' WE GOTTA DO MORE' )
159
+ if (action && ignoredActions . has (action .type )) {
160
+ // console.log('WE GOTTA DO MORE')
130
161
this .redo ()
131
162
}
132
163
}
0 commit comments