-
Notifications
You must be signed in to change notification settings - Fork 641
/
domain-state.js
106 lines (98 loc) · 2.99 KB
/
domain-state.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {observable, transaction, action, autorun, spy} from 'mobx';
import {createFactory, arrayOf, mapOf, getSnapshot, applySnapshot, getParent, hasParent, referenceTo, onPatch} from 'mobx-state-tree';
import {randomUuid} from '../utils';
const Arrow = createFactory({
id: '',
fromId: '',
toId: '',
get from() {
if (!hasParent(this))
return null
return getParent(this).boxes.get(this.fromId)
},
get to() {
if (!hasParent(this))
return null
return getParent(this).boxes.get(this.toId)
}
})
const Box = createFactory({
id: '',
name: '',
x: 0,
y: 0,
get width() {
return this.name.length * 15;
},
get isSelected() {
if (!hasParent(this))
return false
return getParent(this).selection === this
},
move: action(function(dx, dy) {
this.x += dx
this.y += dy
}),
setName: action(function(newName) {
this.name = newName
})
})
const Store = createFactory({
boxes: mapOf(Box),
arrows: arrayOf(Arrow),
selection: referenceTo("/boxes/id"),
addBox: action(function(name, x, y) {
const id = randomUuid()
this.boxes.set(id, Box({ name, x, y, id }))
}),
addArrow: action(function(fromId, toId) {
this.arrows.push(Arrow({ id: randomUuid(), fromId, toId }))
}),
setSelection: action(function(selection) {
this.selection = selection // TODO: remove action by emitting in reference
}),
createBox: action(function(name, x, y) {
this.addBox(name, x, y)
// TODO: set selection
})
})
/*
The store that holds our domain: boxes and arrows
*/
const store = Store({
"boxes":{
"ce9131ee-f528-4952-a012-543780c5e66d": {"id":"ce9131ee-f528-4952-a012-543780c5e66d","name":"Amsterdam","x":100,"y":100},
"14194d76-aa31-45c5-a00c-104cc550430f": {"id":"14194d76-aa31-45c5-a00c-104cc550430f","name":"Vienna","x":650,"y":300}
},
"arrows":[
{"id":"7b5d33c1-5e12-4278-b1c5-e4ae05c036bd","fromId":"ce9131ee-f528-4952-a012-543780c5e66d","toId":"14194d76-aa31-45c5-a00c-104cc550430f"}
],
"selection_id":""
})
export default store;
window.store = store; // for demo
/**
Generate 'amount' new random arrows and boxes
*/
export function generateStuff(amount) {
transaction(() => {
for(var i = 0; i < amount; i++) {
store.addBox('#' + i, Math.random() * window.innerWidth * 0.5, Math.random() * window.innerHeight);
store.addArrow(
store.boxes[Math.floor(Math.random() * store.boxes.length)].id,
store.boxes[Math.floor(Math.random() * store.boxes.length)].id
);
}
});
}
/**
Save / Restore the state of the store while this module is hot reloaded
*/
if (module.hot) {
if (module.hot.data && module.hot.data.store) {
applySnapshot(store, module.hot.data.store);
}
module.hot.dispose((data) => {
data.store = getSnapshot(store);
});
}