1
1
import React , { PropTypes , Component } from 'react' ;
2
- import { connectMonitor } from 'redux-devtools' ;
2
+ import { ActionCreators } from 'redux-devtools' ;
3
3
import LogMonitorEntry from './LogMonitorEntry' ;
4
4
import LogMonitorButton from './LogMonitorButton' ;
5
- import { toggleVisibility } from './actions ' ;
5
+ import { combineReducers , bindActionCreators } from 'redux ' ;
6
6
import * as themes from 'redux-devtools-themes' ;
7
+ import { connect } from 'react-redux' ;
7
8
8
9
const styles = {
9
10
container : {
@@ -34,36 +35,31 @@ const styles = {
34
35
}
35
36
} ;
36
37
37
- class LogMonitor extends Component {
38
- constructor ( props ) {
39
- super ( props ) ;
40
- if ( typeof window !== 'undefined' ) {
41
- window . addEventListener ( 'keydown' , ::this . handleKeyPress ) ;
42
- }
43
- }
44
-
38
+ export default class LogMonitor extends Component {
45
39
static propTypes = {
46
- // Provided by Redux DevTools
47
- computedStates : PropTypes . array . isRequired ,
48
- currentStateIndex : PropTypes . number . isRequired ,
49
- stagedActions : PropTypes . array . isRequired ,
50
- skippedActions : PropTypes . object . isRequired ,
51
- reset : PropTypes . func . isRequired ,
52
- commit : PropTypes . func . isRequired ,
53
- rollback : PropTypes . func . isRequired ,
54
- sweep : PropTypes . func . isRequired ,
55
- toggleAction : PropTypes . func . isRequired ,
56
- jumpToState : PropTypes . func . isRequired ,
57
-
58
- // Provided via built-in reducer and actions
59
40
monitorState : PropTypes . shape ( {
60
- isVisible : PropTypes . bool . isRequired
41
+ initialScrollTop : PropTypes . number . isRequired
61
42
} ) . isRequired ,
43
+
62
44
monitorActions : PropTypes . shape ( {
63
- toggleVisibility : PropTypes . func . isRequired
45
+ updateScrollTop : PropTypes . func . isRequired
46
+ } ) . isRequired ,
47
+
48
+ devToolsState : PropTypes . shape ( {
49
+ computedStates : PropTypes . array . isRequired ,
50
+ currentStateIndex : PropTypes . number . isRequired ,
51
+ stagedActions : PropTypes . array . isRequired ,
52
+ skippedActions : PropTypes . object . isRequired
53
+ } ) . isRequired ,
54
+
55
+ devToolsActions : PropTypes . shape ( {
56
+ reset : PropTypes . func . isRequired ,
57
+ commit : PropTypes . func . isRequired ,
58
+ rollback : PropTypes . func . isRequired ,
59
+ sweep : PropTypes . func . isRequired ,
60
+ toggleAction : PropTypes . func . isRequired
64
61
} ) . isRequired ,
65
62
66
- // Regular props
67
63
select : PropTypes . func . isRequired ,
68
64
theme : PropTypes . oneOfType ( [
69
65
PropTypes . object ,
@@ -76,12 +72,32 @@ class LogMonitor extends Component {
76
72
theme : 'nicinabox'
77
73
} ;
78
74
75
+ componentDidMount ( ) {
76
+ const node = this . refs . container ;
77
+ if ( ! node ) {
78
+ return ;
79
+ }
80
+
81
+ node . scrollTop = this . props . monitorState . initialScrollTop ;
82
+ this . interval = setInterval ( ::this . updateScrollTop , 1000 ) ;
83
+ }
84
+
85
+ componentWillUnmount ( ) {
86
+ clearInterval ( this . setInterval ) ;
87
+ }
88
+
89
+ updateScrollTop ( ) {
90
+ const node = this . refs . container ;
91
+ this . props . monitorActions . updateScrollTop ( node ? node . scrollTop : 0 ) ;
92
+ }
93
+
79
94
componentWillReceiveProps ( nextProps ) {
80
- const node = this . refs . elements ;
95
+ const node = this . refs . container ;
81
96
if ( ! node ) {
82
97
this . scrollDown = true ;
83
98
} else if (
84
- this . props . stagedActions . length < nextProps . stagedActions . length
99
+ this . props . devToolsState . stagedActions . length <
100
+ nextProps . devToolsState . stagedActions . length
85
101
) {
86
102
const { scrollTop, offsetHeight, scrollHeight } = node ;
87
103
@@ -94,7 +110,7 @@ class LogMonitor extends Component {
94
110
}
95
111
96
112
componentDidUpdate ( ) {
97
- const node = this . refs . elements ;
113
+ const node = this . refs . container ;
98
114
if ( ! node ) {
99
115
return ;
100
116
}
@@ -106,35 +122,30 @@ class LogMonitor extends Component {
106
122
}
107
123
108
124
handleRollback ( ) {
109
- this . props . rollback ( ) ;
125
+ this . props . devToolsActions . rollback ( ) ;
110
126
}
111
127
112
128
handleSweep ( ) {
113
- this . props . sweep ( ) ;
129
+ this . props . devToolsActions . sweep ( ) ;
114
130
}
115
131
116
132
handleCommit ( ) {
117
- this . props . commit ( ) ;
133
+ this . props . devToolsActions . commit ( ) ;
118
134
}
119
135
120
136
handleToggleAction ( index ) {
121
- this . props . toggleAction ( index ) ;
137
+ this . props . devToolsActions . toggleAction ( index ) ;
122
138
}
123
139
124
140
handleReset ( ) {
125
- this . props . reset ( ) ;
126
- }
127
-
128
- handleKeyPress ( event ) {
129
- if ( event . ctrlKey && event . keyCode === 72 ) { // Ctrl+H
130
- event . preventDefault ( ) ;
131
- this . props . monitorActions . toggleVisibility ( ) ;
132
- }
141
+ this . props . devToolsActions . reset ( ) ;
133
142
}
134
143
135
144
render ( ) {
136
145
const elements = [ ] ;
137
- const { monitorState, skippedActions, stagedActions, computedStates, select } = this . props ;
146
+ const { devToolsState, select } = this . props ;
147
+ // const { isVisible } = monitorState;
148
+ const { skippedActions, stagedActions, computedStates } = devToolsState ;
138
149
139
150
let theme ;
140
151
if ( typeof this . props . theme === 'string' ) {
@@ -148,10 +159,6 @@ class LogMonitor extends Component {
148
159
theme = this . props . theme ;
149
160
}
150
161
151
- if ( ! monitorState . isVisible ) {
152
- return null ;
153
- }
154
-
155
162
for ( let i = 0 ; i < stagedActions . length ; i ++ ) {
156
163
const action = stagedActions [ i ] ;
157
164
const { state, error } = computedStates [ i ] ;
@@ -181,12 +188,45 @@ class LogMonitor extends Component {
181
188
< LogMonitorButton theme = { theme } onClick = { ::this . handleSweep } enabled = { Object . keys ( skippedActions ) . some ( key => skippedActions [ key ] ) } > Sweep</ LogMonitorButton >
182
189
< LogMonitorButton theme = { theme } onClick = { ::this . handleCommit } enabled = { computedStates . length > 1 } > Commit</ LogMonitorButton >
183
190
</ div >
184
- < div style = { styles . elements } ref = "elements" >
191
+ < div style = { styles . elements } ref = 'container' >
185
192
{ elements }
186
193
</ div >
187
194
</ div >
188
195
) ;
189
196
}
190
197
}
191
198
192
- export default connectMonitor ( { toggleVisibility } ) ( LogMonitor ) ;
199
+ const UPDATE_SCROLL_TOP = '@@redux-devtools-log-monitor/UPDATE_SCROLL_TOP' ;
200
+ function updateScrollTop ( scrollTop ) {
201
+ return { type : UPDATE_SCROLL_TOP , scrollTop } ;
202
+ }
203
+
204
+ function createReducer ( { preserveScrollTop = true } ) {
205
+ function initialScrollTop ( state = 0 , action ) {
206
+ if ( ! preserveScrollTop ) {
207
+ return 0 ;
208
+ }
209
+
210
+ return action . type === UPDATE_SCROLL_TOP ?
211
+ action . scrollTop :
212
+ state ;
213
+ }
214
+
215
+ return combineReducers ( { initialScrollTop } ) ;
216
+ }
217
+
218
+ function mapStateToProps ( state ) {
219
+ return state ;
220
+ }
221
+
222
+ function mapDispatchToProps ( dispatch ) {
223
+ return {
224
+ monitorActions : bindActionCreators ( { updateScrollTop } , dispatch ) ,
225
+ devToolsActions : bindActionCreators ( ActionCreators , dispatch )
226
+ } ;
227
+ }
228
+
229
+ LogMonitor = connect ( mapStateToProps , mapDispatchToProps ) ( LogMonitor ) ;
230
+ LogMonitor . createReducer = createReducer ;
231
+
232
+ export default LogMonitor ;
0 commit comments