-
Notifications
You must be signed in to change notification settings - Fork 643
/
notice.tsx
118 lines (99 loc) · 2.83 KB
/
notice.tsx
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
107
108
109
110
111
112
113
114
115
116
117
118
import React, { ReactNode } from 'react'
import { connect } from 'react-redux'
import { MessageBox } from '@admin-bro/design-system'
import { NoticeMessageInState, ReduxState } from '../../store/store'
import { dropNotice } from '../../store/actions/drop-notice'
import { setNoticeProgress } from '../../store/actions/set-Notice-progress'
const TIME_TO_DISAPPEAR = 3
type NotifyProgress = (options: {
noticeId: string; progress: number;
}) => void
type NoticeElementProps = {
notice: NoticeMessageInState;
drop: () => any;
notifyProgress: NotifyProgress;
}
type NoticeElementState = {
progress: number;
}
class NoticeElement extends React.Component<NoticeElementProps, NoticeElementState> {
private timer: NodeJS.Timeout | null
constructor(props) {
super(props)
const { notice } = props
this.timer = null
this.state = {
progress: notice.progress || 0,
}
}
componentDidMount(): void {
const { drop, notice, notifyProgress } = this.props
this.timer = setInterval(() => {
this.setState((state) => {
const progress = state.progress + 100 / TIME_TO_DISAPPEAR
notifyProgress({ noticeId: notice.id, progress })
return { progress }
})
}, 1000)
setTimeout(() => {
if (this.timer) {
clearInterval(this.timer)
}
drop()
}, 1000 * (TIME_TO_DISAPPEAR + 1))
}
componentWillUnmount(): void {
if (this.timer) {
clearInterval(this.timer)
}
}
render(): ReactNode {
const { notice, drop } = this.props
return (
<MessageBox
style={{ minWidth: '480px' }}
message={notice.message}
variant={notice.type === 'success' ? 'success' : 'danger'}
onCloseClick={drop}
/>
)
}
}
type NoticeBoxPropsFromState = {
notices: Array<NoticeMessageInState>;
}
type NoticeBoxDispatchFromState = {
drop: (noticeId: string) => void;
notifyProgress: NotifyProgress;
}
const NoticeBox: React.FC<NoticeBoxPropsFromState & NoticeBoxDispatchFromState> = (props) => {
const { drop, notices, notifyProgress } = props
const notice = notices.length ? notices[notices.length - 1] : null
if (notice) {
return (
<div data-testid="notice-wrapper">
<NoticeElement
key={notice.id}
notice={notice}
drop={(): void => drop(notice.id)}
notifyProgress={notifyProgress}
/>
</div>
)
}
return (
<div />
)
}
const mapStateToProps = (state: ReduxState): NoticeBoxPropsFromState => ({
notices: state.notices,
})
const mapDispatchToProps = (dispatch): NoticeBoxDispatchFromState => ({
drop: (noticeId: string): void => dispatch(dropNotice(noticeId)),
notifyProgress: ({
noticeId, progress,
}): void => dispatch(setNoticeProgress({ noticeId, progress })),
})
export default connect(
mapStateToProps, mapDispatchToProps,
)(NoticeBox)