Skip to content

Commit 5653461

Browse files
authored
Merge pull request #13 from LOLDragoon/undo
Undo
2 parents 4e4e400 + 823ed22 commit 5653461

File tree

11 files changed

+683
-100
lines changed

11 files changed

+683
-100
lines changed

package-lock.json

Lines changed: 125 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
"aws-amplify": "^1.1.30",
2222
"aws-amplify-vue": "^0.2.13",
2323
"aws-appsync": "^1.8.1",
24-
"lodash": ">=4.17.13",
2524
"fs-extra": "^8.1.0",
2625
"localforage": "^1.7.3",
26+
"lodash": ">=4.17.13",
27+
"lodash.isequal": "^4.5.0",
2728
"mousetrap": "^1.6.3",
2829
"prismjs": "^1.16.0",
2930
"quasar": "^1.0.0",

src/App.vue

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,127 @@
55
</template>
66

77
<script>
8+
import { SET_ACTIVE_COMPONENT } from './store/types'
9+
const deepEqual = require('lodash.isequal')
10+
const cloneDeep = require('lodash.clonedeep')
11+
import {defaultState} from './store/state/index.js'
12+
13+
let redoMixin = {
14+
data() {
15+
return {
16+
// banana:[],
17+
doneAction:[],
18+
undoneAction:[],
19+
isTimetraveling: false,
20+
initialState:{}
21+
}
22+
},
23+
24+
created(){
25+
26+
this.$store.subscribeAction((action,state)=>{
27+
// console.log("We are saving this action!", action)
28+
if (typeof action.payload === "object"){
29+
// console.log("We saved the world with a deepclone!", action.payload === cloneDeep)
30+
action.payload = cloneDeep(action.payload)
31+
}
32+
this.doneAction.push(action)
33+
// console.log('this is the action we are logging',action)
34+
// console.log('this is in our redo queue', this.undoneAction[this.undoneAction.length-1])
35+
// console.log("Are these equal to each other?", action == this.undoneAction[this.undoneAction.length-1])
36+
if(!this.isTimetraveling){
37+
if (this.undoneAction[this.undoneAction.length-1]){
38+
if(action.type == this.undoneAction[this.undoneAction.length-1].type &&
39+
deepEqual(action.payload,this.undoneAction[this.undoneAction.length-1].payload)){
40+
this.undoneAction.pop()
41+
}
42+
else{
43+
this.undoneAction = []
44+
}
45+
}
46+
}
47+
})
48+
// this.blankState = cloneDeep(this.$store)
49+
},
50+
51+
mounted(){
52+
window.addEventListener("keydown", event => {
53+
if (event.ctrlKey && event.key === "z") {
54+
event.preventDefault()
55+
this.undo()
56+
}
57+
});
58+
window.addEventListener("keydown", event => {
59+
if (event.ctrlKey && event.key === "y") {
60+
event.preventDefault()
61+
this.redo()
62+
}
63+
});
64+
//console.log("do we want this? or this.$store.state?", this.$store.state)
65+
this.initialState = defaultState(this.$store.state)
66+
67+
},
68+
69+
methods: {
70+
undo: function() {
71+
// do {
72+
// console.log("How far back?")
73+
74+
this.isTimetraveling = true;
75+
76+
let undone = this.doneAction.pop()
77+
78+
if(undone !== undefined){
79+
this.undoneAction.push(undone)
80+
if(undone.type==="setActiveComponent"){
81+
console.log("We did something useless!")
82+
do{
83+
this.undoneAction.push(this.doneAction.pop())
84+
}
85+
while (this.doneAction[this.doneAction.length-1] &&
86+
(this.doneAction[this.doneAction.length - 1].type === "setActiveComponent"))
87+
}
88+
}
89+
90+
// while (this.doneAction[this.doneAction.length-1] &&
91+
// (this.doneAction[this.doneAction.length - 1].type === "setActiveComponent" ||
92+
// this.doneAction[this.doneAction.length - 1].type === "updateComponentPosition" ))
93+
let payload = {
94+
initialState: this.initialState,
95+
store: this.$store
96+
}
97+
this.$store.commit("EMPTY_STATE",payload)
98+
console.log(this.$store)
99+
this.doneAction.forEach(action => {
100+
console.log("In the loop",this.$store)
101+
//this.$store.commit(`${mutation.type}`, mutation.payload);
102+
this.$store.dispatch(action.type, cloneDeep(action.payload));
103+
this.doneAction.pop();
104+
});
105+
this.isTimetraveling = false;
106+
107+
},
108+
redo: function() {
109+
110+
let action = this.undoneAction.pop()
111+
this.isTimetraveling = true;
112+
if(action){
113+
this.$store.dispatch(action.type, cloneDeep(action.payload))
114+
}
115+
this.isTimetraveling = false;
116+
if(action && (action.type === "setActiveComponent")){
117+
console.log("WE GOTTA DO MORE")
118+
this.redo();
119+
}
120+
}
121+
122+
}
123+
}
124+
125+
8126
export default {
9-
name: 'App'
127+
name: 'App',
128+
mixins:[redoMixin]
10129
}
11130
</script>
12131

src/components/ComponentDisplay.vue

Lines changed: 131 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
:key="componentData.componentName"
99
:id ="componentData.componentName"
1010
:x="componentData.x"
11-
:y="componentData.y + 20"
11+
:y="componentData.y"
1212
:z="componentData.z"
1313
:w="componentData.w"
1414
:h="componentData.h"
@@ -19,7 +19,13 @@
1919
@dragging="onDrag"
2020
@resizing="onResize"
2121
@dblclick.native="onDoubleClick(componentData)"
22+
@dragstop="finishedDrag"
23+
@resizestop="finishedResize"
24+
:onDragStart="recordInitialPosition"
25+
:onResizeStart="recordInitialSize"
2226
>
27+
<!-- :onDragStart="recordInitialPosition"
28+
:onResizeStart="recordInitialSize" -->
2329
<div class="component-title">
2430
<p>{{ componentData.componentName }}</p>
2531
</div>
@@ -85,7 +91,9 @@ export default {
8591
testOptions: ["parent", "child", "grandchild"],
8692
testModel: [],
8793
mockImg: false,
88-
counter: 0
94+
counter: 0,
95+
initialPosition:{x:0, y:0,},
96+
initialSize:{w:0,h:0,},
8997
};
9098
},
9199
mounted() {
@@ -176,33 +184,40 @@ export default {
176184
},
177185
178186
updated() {
179-
console.log("updated")
187+
//console.log("updated")
180188
if(this.activeComponent === '')
181189
{
190+
if(this.$refs.boxes){
182191
this.$refs.boxes.forEach((element)=> {
183192
element.enabled = false;
184193
element.$emit('deactivated')
185194
element.$emit('update:active', false)
186195
187-
})
196+
})}
188197
}
189198
else{
190-
this.$refs.boxes.forEach((element)=>{
191-
if(this.activeComponent === element.$attrs.id)
192-
{
193-
element.enabled = true
194-
element.$emit('activated')
195-
element.$emit('update:active', true)
196-
}
197-
})
198-
}
199-
},
199+
this.$refs.boxes.forEach((element)=>{
200+
// added "element.enabled === false to stop it from emitting a change every frame the box moves
201+
//may need to re-enable to track box movement and resizing since that stuff isn't part of a single source of truth.
202+
if(this.activeComponent === element.$attrs.id && element.enabled === false)
203+
{
204+
element.enabled = true
205+
element.$emit('activated')
206+
element.$emit('update:active', true)
207+
}
208+
})
209+
}
210+
},
200211
201212
methods: {
202213
...mapActions([
203214
"setActiveComponent",
204215
"updateComponentChildrenMultiselectValue",
205-
"updateActiveComponentChildrenValue"
216+
"updateActiveComponentChildrenValue",
217+
"updateComponentPosition",
218+
"updateStartingPosition",
219+
"updateStartingSize",
220+
"updateComponentSize",
206221
]),
207222
onResize: function(x, y, width, height) {
208223
this.activeComponentData.x = x;
@@ -215,6 +230,71 @@ export default {
215230
this.componentMap[this.activeComponent].w = width;
216231
this.componentMap[this.activeComponent].h = height;
217232
},
233+
234+
recordInitialPosition: function(e) {
235+
console.log("we started a drag")
236+
console.log("this.intialPosition",this.initialPosition)
237+
console.log("WHAT IS THIS", this)
238+
if(this.activeComponent !== e.target.id){
239+
this.setActiveComponent(e.target.id)
240+
}
241+
this.initialPosition.x = this.activeComponentData.x
242+
this.initialPosition.y = this.activeComponentData.y
243+
// console.log(this.activeComponentData)
244+
// console.log(this.activeComponentData.x)
245+
// console.log(this.initialPosition.x)
246+
// console.log(this.initialPosition.y)
247+
248+
let payload = {
249+
x: this.initialPosition.x,
250+
y: this.initialPosition.y,
251+
activeComponent: this.activeComponent,
252+
routeArray: this.routes[this.activeRoute],
253+
activeComponentData: this.activeComponentData
254+
}
255+
console.log("x: ",payload.x,"y: ",payload.y)
256+
//this.updateStartingPosition(payload);
257+
},
258+
259+
recordInitialSize: function(e){
260+
console.log("MAKE MY MONSTER GROW!")
261+
262+
this.initialSize.h = this.activeComponentData.h
263+
this.initialSize.w = this.activeComponentData.w
264+
this.initialPosition.x = this.activeComponentData.x
265+
this.initialPosition.y = this.activeComponentData.y
266+
267+
let payload = {
268+
h: this.initialSize.h,
269+
w: this.initialSize.w,
270+
x: this.activeComponentData.x,
271+
y: this.activeComponentData.y,
272+
activeComponent: this.activeComponent,
273+
routeArray: this.routes[this.activeRoute],
274+
activeComponentData: this.activeComponentData
275+
}
276+
277+
//this.updateStartingSize(payload);
278+
279+
},
280+
281+
finishedResize: function(x,y,w,h){
282+
console.log("FINISHED RESIZING")
283+
let payload = {
284+
x: x,
285+
y: y,
286+
w: w,
287+
h: h,
288+
activeComponent: this.activeComponent,
289+
routeArray: this.routes[this.activeRoute],
290+
activeComponentData: this.activeComponentData
291+
}
292+
if(payload.x !== this.initialPosition.x || payload.y !== this.initialPosition.y ||
293+
payload.w !== this.initialSize.w || payload.h !==this.initialSize.h){
294+
this.updateComponentSize(payload)
295+
}
296+
},
297+
218298
onDrag: function(x, y) {
219299
this.activeComponentData.x = x;
220300
this.activeComponentData.y = y;
@@ -223,19 +303,45 @@ export default {
223303
this.componentMap[this.activeComponent].y = y;
224304
this.userImage;
225305
},
226-
onLayer: function(z) {
227-
this.activeComponentData.z = z;
306+
// onLayer: function(z) {
307+
// this.activeComponentData.z = z;
308+
// // Want to change the "Z" of the component found in Routes[activeRoute][whatever the component is]
309+
// //have to do this via an action or it won't be preserved in our undo/redo
310+
// },
311+
312+
finishedDrag: function(x,y){
313+
console.log("FINISHED DRAGGING")
314+
let payload = {
315+
x: x,
316+
y: y,
317+
activeComponent: this.activeComponent,
318+
routeArray: this.routes[this.activeRoute],
319+
activeComponentData: this.activeComponentData
320+
}
321+
// console.log("Payload.x = ", payload.x, "this.initialPosition.x", this.initialPosition.x)
322+
// console.log("Payload.y = ", payload.y, "this.initialPosition.y", this.initialPosition.y)
323+
if(payload.x !== this.initialPosition.x || payload.y !== this.initialPosition.y){
324+
this.updateComponentPosition(payload);
325+
}
228326
},
327+
229328
onActivated(componentData) {
329+
//console.log("I RAN!")
230330
this.$refs.boxes.forEach((element)=> {
231331
if (element.$attrs.id !== componentData.componentName){
232332
element.enabled = false;
233333
element.$emit('deactivated')
234334
element.$emit('update:active', false)
235335
}
236336
})
237-
this.setActiveComponent(componentData.componentName);
337+
// console.log("this is what is currently active",this.activeComponent)
338+
// console.log("this is this", this)
339+
// console.log('!(componentData.componentName === this.activeComponent)?',!(componentData.componentName === this.activeComponent))
340+
if(!(componentData.componentName === this.activeComponent)){
341+
this.setActiveComponent(componentData.componentName);
342+
}
238343
this.activeComponentData.isActive = true;
344+
239345
240346
},
241347
@@ -253,7 +359,9 @@ export default {
253359
// }
254360
},
255361
onDoubleClick(compData) {
256-
this.setActiveComponent(compData.componentName);
362+
if(!(componentData.componentName === this.activeComponent)){
363+
this.setActiveComponent(componentData.componentName);
364+
}
257365
this.activeComponentData.isActive = true;
258366
},
259367
handleAddChild() {
@@ -291,7 +399,9 @@ export default {
291399
handleClick(event){
292400
if(event.target.className === "component-display grid-bg")
293401
{
294-
this.setActiveComponent('')
402+
if(!('' === this.activeComponent)){
403+
this.setActiveComponent('');
404+
}
295405
}
296406
}
297407
}
@@ -310,7 +420,7 @@ export default {
310420
/* width: 1rem; */
311421
line-height: 1.2;
312422
/* margin: 10px; */
313-
z-index: 0;
423+
z-index: -1;
314424
}
315425
.component-children {
316426
position: absolute;

src/components/CreateComponent.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default {
7070
const component = {
7171
componentName: this.componentNameInputValue,
7272
x: 0,
73-
y: 0,
73+
y: 20,
7474
z: 0,
7575
w: 200,
7676
h: 200,
@@ -84,7 +84,9 @@ export default {
8484
8585
},
8686
resetActiveComponent () {
87+
if(!this.activeComponent === ''){
8788
this.setActiveComponent('')
89+
}
8890
8991
},
9092
handleIconClick () {

0 commit comments

Comments
 (0)