-
Notifications
You must be signed in to change notification settings - Fork 54
/
sagas.ts
100 lines (90 loc) 路 2.58 KB
/
sagas.ts
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
import { EventChannel, eventChannel } from 'redux-saga'
import { call, fork, put, select, take, takeEvery } from 'redux-saga/effects'
import { ErrorCode, MetaTransactionError } from 'decentraland-transactions'
import {
renderToast,
ShowToastAction,
SHOW_TOAST,
HIDE_TOAST,
HideToastAction,
showToast,
hideAllToasts
} from './actions'
import { getState } from './selectors'
import * as cache from './cache'
import {
TransactionEventData,
TransactionEventType,
transactionEvents
} from '../wallet/utils'
import { SWITCH_NETWORK_SUCCESS } from '../wallet/actions'
import {
getContractAccountErrorToast,
getInvalidAddressErrorToast,
getUnknownErrorToast
} from './toasts/meta-transactions'
export function* toastSaga() {
yield fork(watchMetaTransactionErrors)
yield takeEvery(SHOW_TOAST, handleShowToast)
yield takeEvery(HIDE_TOAST, handleHideToast)
yield takeEvery(SWITCH_NETWORK_SUCCESS, handleSwitchNetworkSuccess)
}
function* handleShowToast(action: ShowToastAction) {
const { toast } = action.payload
const ids: number[] = yield select(getState)
const lastId = Number(ids[ids.length - 1] || 0)
const id = lastId + 1
cache.set(id, toast)
yield put(renderToast(id))
}
function* handleHideToast(action: HideToastAction) {
const { id } = action.payload
cache.remove(id)
}
export function createMetaTransactionsErrorChannel() {
return eventChannel<ErrorCode>(emitter => {
function handleError(
data: TransactionEventData<TransactionEventType.ERROR>
) {
if (data.error instanceof MetaTransactionError) {
emitter(data.error.code)
}
}
transactionEvents.on(TransactionEventType.ERROR, handleError)
return () =>
transactionEvents.removeListener(TransactionEventType.ERROR, handleError)
})
}
export function* watchMetaTransactionErrors() {
const channel: EventChannel<ErrorCode> = yield call(
createMetaTransactionsErrorChannel
)
while (true) {
const code: ErrorCode = yield take(channel)
yield call(handleMetaTransactionError, code)
}
}
export function* handleMetaTransactionError(code: ErrorCode) {
switch (code) {
case ErrorCode.CONTRACT_ACCOUNT: {
yield put(showToast(getContractAccountErrorToast()))
break
}
case ErrorCode.INVALID_ADDRESS: {
yield put(showToast(getInvalidAddressErrorToast()))
break
}
case ErrorCode.USER_DENIED: {
// do nothing
break
}
case ErrorCode.UNKNOWN:
default: {
yield put(showToast(getUnknownErrorToast()))
break
}
}
}
function* handleSwitchNetworkSuccess() {
yield put(hideAllToasts())
}