This repository has been archived by the owner on Feb 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
withdraw-saga.js
88 lines (77 loc) · 1.97 KB
/
withdraw-saga.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
import React from 'react'
import { Rx } from 'tom'
const VALID_PIN = '123'
const PIN_VALIDATED = { type: 'PIN_VALIDATED' }
const INVALID_PIN = { type: 'INVALID_PIN' }
const PIN_REJECTED = { type: 'PIN_REJECTED' }
class ATM extends React.Component {
onEnter = () => {
this.props.onEnter(this.refs.pin.value)
}
render() {
const { model } = this.props
const canIEnterPin = !model.authFailure && !model.authorized
return (
<div>
{canIEnterPin &&
<div>
<input ref="pin" />
<button disabled={model.isValidating} onClick={this.onEnter}>pin</button>
</div>
}
<p>{model.error && 'Invalid pin'}</p>
<p>{model.authorized && 'Authorized :)'}</p>
<p>{model.authFailure && 'Unauthorized :('}</p>
</div>
)
}
}
export default {
init() {
return {
model: {}
}
},
update(model, event) {
switch (event.type) {
case 'PIN_ENTERED' :
return {
model: { isValidating: true },
effect: { type: 'VALIDATE_PIN', pin: event.pin }
}
case PIN_VALIDATED.type :
return {
model: { authorized: true }
}
case INVALID_PIN.type :
return {
model: { error: true }
}
case PIN_REJECTED.type :
return {
model: { authFailure: true }
}
default :
return { model }
}
},
view(model, dispatch) {
const onEnter = pin => dispatch({ type: 'PIN_ENTERED', pin })
return <ATM model={model} onEnter={onEnter} />
},
run(effect, event$) {
switch (effect.type) {
case 'VALIDATE_PIN' :
const nextEvent$ = Rx.Observable
.just(effect.pin === VALID_PIN ? PIN_VALIDATED : INVALID_PIN)
.delay(500) // fake validation delay
const rejectPin$ = event$
.concat(nextEvent$)
.filter(e => e.type === INVALID_PIN.type)
.bufferWithCount(3)
.map(() => PIN_REJECTED)
.take(1)
return nextEvent$.merge(rejectPin$)
}
}
}