/
list.js
89 lines (67 loc) · 1.85 KB
/
list.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
const Type = require('union-type');
const T = require('ramda/src/T')
, adjust = require('ramda/src/adjust')
, append = require('ramda/src/append')
, curry = require('ramda/src/curry')
;
const h = require('snabbdom/h');
const upload = require('./upload');
const uploader = require('./uploader');
const noFx = (s) => [s, []];
// note: prefer to check if iterable,
// but FileList.prototype doesn't seem to have Symbol.iterator cross-browser?
const isFileList = (x) => x.length !== undefined
// action
const Action = Type({
Create: [Function, isFileList],
Result: [Number, uploader.Result]
});
const update = Action.caseOn({
Create: (up,files,model) => {
const idx = nextIndex(model);
const task = up(files);
const taskAction = Action.Result(idx);
const newState = append( upload.init(files), model);
return [newState, [task.map(taskAction)]];
},
Result: (i,result,model) => {
const finish = (type) => () => {
return adjust(upload.update(upload.Action[type]()), i, model);
};
return noFx(
uploader.Result.case({
OK: finish('Uploaded'),
NotFound: finish('Error'),
Error: finish('Error'),
Abort: finish('Abort'),
Progress: (abort,p) => {
return adjust(upload.update(upload.Action.Progress(abort,p)), i, model);
}
}, result)
);
}
});
// model
const init = () => []
const nextIndex = (model) => model.length;
// view
const view = (model) => {
return (
h('ul', {style: style.ul}, model.map( listItemView ) )
);
};
const listItemView = (item, i) => {
return (
h('li', {style: style.li}, [
upload.view(
{ progress: { height: 20, width: 200 } },
item
)
])
);
}
const style = {
ul: {'list-style': 'none'},
li: { }
}
module.exports = { init, update, Action, view }