-
Notifications
You must be signed in to change notification settings - Fork 6
/
actions.js
104 lines (94 loc) · 2.76 KB
/
actions.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
import crawl from 'tree-crawl';
const actions = ({ setState }) => ({
/**
* Loads the latest meta from server; update client state if it isn't up to date
*/
getLatestMeta: state => {
const src = state.activeVideo.src;
const clientMeta = state.activeVideo.meta;
fetch(src.replace('video.mp4', 'meta.json'), { cache: 'no-cache' })
.then(response => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
})
.then(serverMeta => {
const isEqual =
JSON.stringify({
title: clientMeta.title,
description: clientMeta.description,
tags: clientMeta.tags,
people: clientMeta.people
}) ===
JSON.stringify({
title: serverMeta.title,
description: serverMeta.description,
tags: serverMeta.tags,
people: serverMeta.people
});
if (!isEqual) {
// something was changed, so update client state to match server
setState({
data: setNewMetaInTree(
JSON.parse(JSON.stringify(state.data)),
serverMeta
)
});
alert(
'Someone edited this video as well. We just synced the data, please continue editing.'
);
}
})
.catch(e => console.log(e));
},
handleSave: (state, newMeta, src) => {
// keep old meta for the case we need to revert
const oldMeta = JSON.stringify(state.activeVideo.meta);
// we're optimistic, so update client state immediately
setState({
data: setNewMetaInTree(JSON.parse(JSON.stringify(state.data)), newMeta)
});
// send POST request to server
fetch(src.replace('video.mp4', 'meta.json'), {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
method: 'POST',
body: JSON.stringify(newMeta)
})
.then(response => {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
})
.catch(error => {
alert(`Error while saving: ${error.message}`);
// revert client state to old meta
setState({
data: setNewMetaInTree(
JSON.parse(JSON.stringify(state.data)),
JSON.parse(oldMeta)
)
});
});
}
});
const setNewMetaInTree = (tree, newMeta) => {
crawl(
tree,
(node, context) => {
if (node.meta && node.meta.id === newMeta.id) {
const newNode = node;
newNode.meta = newMeta;
context.parent.items[context.index] = newNode;
context.replace(newNode);
}
},
{ getChildren: node => node.items }
);
return tree;
};
export default actions;