1
- import PropTypes from 'prop-types' ;
2
- import React from 'react' ;
3
- import { useSelector , useDispatch , connect } from 'react-redux' ;
1
+ import React , { useRef } from 'react' ;
2
+
3
+ import { bindActionCreators } from 'redux' ;
4
+
5
+ import { useSelector , useDispatch } from 'react-redux' ;
4
6
import classNames from 'classnames' ;
5
7
import { Console as ConsoleFeed } from 'console-feed' ;
6
8
import {
@@ -25,172 +27,118 @@ import DownArrowIcon from '../../../images/down-arrow.svg';
25
27
26
28
import * as IDEActions from '../../IDE/actions/ide' ;
27
29
import * as ConsoleActions from '../../IDE/actions/console' ;
30
+ import { useDidUpdate } from '../../../utils/custom-hooks' ;
28
31
29
- class ConsoleComponent extends React . Component {
30
- componentDidUpdate ( prevProps ) {
31
- this . consoleMessages . scrollTop = this . consoleMessages . scrollHeight ;
32
- if ( this . props . theme !== prevProps . theme ) {
33
- this . props . clearConsole ( ) ;
34
- this . props . dispatchConsoleEvent ( this . props . consoleEvents ) ;
35
- }
36
-
37
- if ( this . props . fontSize !== prevProps . fontSize ) {
38
- this . props . clearConsole ( ) ;
39
- this . props . dispatchConsoleEvent ( this . props . consoleEvents ) ;
40
- }
41
- }
42
-
43
- getConsoleFeedStyle ( theme , times ) {
44
- const style = { } ;
45
- const CONSOLE_FEED_LIGHT_ICONS = {
46
- LOG_WARN_ICON : `url(${ warnLightUrl } )` ,
47
- LOG_ERROR_ICON : `url(${ errorLightUrl } )` ,
48
- LOG_DEBUG_ICON : `url(${ debugLightUrl } )` ,
49
- LOG_INFO_ICON : `url(${ infoLightUrl } )`
50
- } ;
51
- const CONSOLE_FEED_DARK_ICONS = {
52
- LOG_WARN_ICON : `url(${ warnDarkUrl } )` ,
53
- LOG_ERROR_ICON : `url(${ errorDarkUrl } )` ,
54
- LOG_DEBUG_ICON : `url(${ debugDarkUrl } )` ,
55
- LOG_INFO_ICON : `url(${ infoDarkUrl } )`
56
- } ;
57
- const CONSOLE_FEED_CONTRAST_ICONS = {
58
- LOG_WARN_ICON : `url(${ warnContrastUrl } )` ,
59
- LOG_ERROR_ICON : `url(${ errorContrastUrl } )` ,
60
- LOG_DEBUG_ICON : `url(${ debugContrastUrl } )` ,
61
- LOG_INFO_ICON : `url(${ infoContrastUrl } )`
62
- } ;
63
- const CONSOLE_FEED_SIZES = {
64
- TREENODE_LINE_HEIGHT : 1.2 ,
65
- BASE_FONT_SIZE : this . props . fontSize ,
66
- ARROW_FONT_SIZE : this . props . fontSize ,
67
- LOG_ICON_WIDTH : this . props . fontSize ,
68
- LOG_ICON_HEIGHT : 1.45 * this . props . fontSize ,
69
- } ;
32
+ const getConsoleFeedStyle = ( theme , times , fontSize ) => {
33
+ const style = { } ;
34
+ const CONSOLE_FEED_LIGHT_ICONS = {
35
+ LOG_WARN_ICON : `url(${ warnLightUrl } )` ,
36
+ LOG_ERROR_ICON : `url(${ errorLightUrl } )` ,
37
+ LOG_DEBUG_ICON : `url(${ debugLightUrl } )` ,
38
+ LOG_INFO_ICON : `url(${ infoLightUrl } )`
39
+ } ;
40
+ const CONSOLE_FEED_DARK_ICONS = {
41
+ LOG_WARN_ICON : `url(${ warnDarkUrl } )` ,
42
+ LOG_ERROR_ICON : `url(${ errorDarkUrl } )` ,
43
+ LOG_DEBUG_ICON : `url(${ debugDarkUrl } )` ,
44
+ LOG_INFO_ICON : `url(${ infoDarkUrl } )`
45
+ } ;
46
+ const CONSOLE_FEED_CONTRAST_ICONS = {
47
+ LOG_WARN_ICON : `url(${ warnContrastUrl } )` ,
48
+ LOG_ERROR_ICON : `url(${ errorContrastUrl } )` ,
49
+ LOG_DEBUG_ICON : `url(${ debugContrastUrl } )` ,
50
+ LOG_INFO_ICON : `url(${ infoContrastUrl } )`
51
+ } ;
52
+ const CONSOLE_FEED_SIZES = {
53
+ TREENODE_LINE_HEIGHT : 1.2 ,
54
+ BASE_FONT_SIZE : fontSize ,
55
+ ARROW_FONT_SIZE : fontSize ,
56
+ LOG_ICON_WIDTH : fontSize ,
57
+ LOG_ICON_HEIGHT : 1.45 * fontSize ,
58
+ } ;
70
59
71
- if ( times > 1 ) {
72
- Object . assign ( style , CONSOLE_FEED_WITHOUT_ICONS ) ;
73
- }
74
- switch ( theme ) {
75
- case 'light' :
76
- return Object . assign ( CONSOLE_FEED_LIGHT_STYLES , CONSOLE_FEED_LIGHT_ICONS , CONSOLE_FEED_SIZES , style ) ;
77
- case 'dark' :
78
- return Object . assign ( CONSOLE_FEED_DARK_STYLES , CONSOLE_FEED_DARK_ICONS , CONSOLE_FEED_SIZES , style ) ;
79
- case 'contrast' :
80
- return Object . assign ( CONSOLE_FEED_CONTRAST_STYLES , CONSOLE_FEED_CONTRAST_ICONS , CONSOLE_FEED_SIZES , style ) ;
81
- default :
82
- return '' ;
83
- }
60
+ if ( times > 1 ) {
61
+ Object . assign ( style , CONSOLE_FEED_WITHOUT_ICONS ) ;
84
62
}
85
-
86
- render ( ) {
87
- const consoleClass = classNames ( {
88
- 'preview-console' : true ,
89
- 'preview-console--collapsed' : ! this . props . isExpanded
90
- } ) ;
91
-
92
- return (
93
- < section className = { consoleClass } >
94
- < header className = "preview-console__header" >
95
- < h2 className = "preview-console__header-title" > Console</ h2 >
96
- < div className = "preview-console__header-buttons" >
97
- < button className = "preview-console__clear" onClick = { this . props . clearConsole } aria-label = "Clear console" >
98
- Clear
99
- </ button >
100
- < button
101
- className = "preview-console__collapse"
102
- onClick = { this . props . collapseConsole }
103
- aria-label = "Close console"
104
- >
105
- < DownArrowIcon focusable = "false" aria-hidden = "true" />
106
- </ button >
107
- < button className = "preview-console__expand" onClick = { this . props . expandConsole } aria-label = "Open console" >
108
- < UpArrowIcon focusable = "false" aria-hidden = "true" />
109
- </ button >
110
- </ div >
111
- </ header >
112
- < div ref = { ( element ) => { this . consoleMessages = element ; } } className = "preview-console__messages" >
113
- { this . props . consoleEvents . map ( ( consoleEvent ) => {
114
- const { method, times } = consoleEvent ;
115
- const { theme } = this . props ;
116
- return (
117
- < div key = { consoleEvent . id } className = { `preview-console__message preview-console__message--${ method } ` } >
118
- { times > 1 &&
119
- < div
120
- className = "preview-console__logged-times"
121
- style = { { fontSize : this . props . fontSize , borderRadius : this . props . fontSize / 2 } }
122
- >
123
- { times }
124
- </ div >
125
- }
126
- < ConsoleFeed
127
- styles = { this . getConsoleFeedStyle ( theme , times ) }
128
- logs = { [ consoleEvent ] }
129
- />
130
- </ div >
131
- ) ;
132
- } ) }
133
- </ div >
134
- </ section >
135
- ) ;
63
+ switch ( theme ) {
64
+ case 'light' :
65
+ return Object . assign ( CONSOLE_FEED_LIGHT_STYLES , CONSOLE_FEED_LIGHT_ICONS , CONSOLE_FEED_SIZES , style ) ;
66
+ case 'dark' :
67
+ return Object . assign ( CONSOLE_FEED_DARK_STYLES , CONSOLE_FEED_DARK_ICONS , CONSOLE_FEED_SIZES , style ) ;
68
+ case 'contrast' :
69
+ return Object . assign ( CONSOLE_FEED_CONTRAST_STYLES , CONSOLE_FEED_CONTRAST_ICONS , CONSOLE_FEED_SIZES , style ) ;
70
+ default :
71
+ return '' ;
136
72
}
137
- }
138
-
139
- ConsoleComponent . propTypes = {
140
- consoleEvents : PropTypes . arrayOf ( PropTypes . shape ( {
141
- method : PropTypes . string . isRequired ,
142
- args : PropTypes . arrayOf ( PropTypes . string )
143
- } ) ) ,
144
- isExpanded : PropTypes . bool . isRequired ,
145
- collapseConsole : PropTypes . func . isRequired ,
146
- expandConsole : PropTypes . func . isRequired ,
147
- clearConsole : PropTypes . func . isRequired ,
148
- dispatchConsoleEvent : PropTypes . func . isRequired ,
149
- theme : PropTypes . string . isRequired ,
150
- fontSize : PropTypes . number . isRequired
151
- } ;
152
-
153
- ConsoleComponent . defaultProps = {
154
- consoleEvents : [ ]
155
73
} ;
156
74
157
- // TODO: Use Hooks implementation. Requires react-redux 7.1.0
158
- /*
159
75
const Console = ( ) => {
160
76
const consoleEvents = useSelector ( state => state . console ) ;
161
- const { consoleIsExpanded } = useSelector(state => state.ide);
77
+ const isExpanded = useSelector ( state => state . ide . consoleIsExpanded ) ;
162
78
const { theme, fontSize } = useSelector ( state => state . preferences ) ;
163
79
164
- const dispatch = useDispatch();
80
+ const {
81
+ collapseConsole, expandConsole, clearConsole, dispatchConsoleEvent
82
+ } = bindActionCreators ( { ...IDEActions , ...ConsoleActions } , useDispatch ( ) ) ;
83
+
84
+ useDidUpdate ( ( ) => {
85
+ clearConsole ( ) ;
86
+ dispatchConsoleEvent ( consoleEvents ) ;
87
+ } , [ theme , fontSize ] ) ;
88
+
89
+ const cm = useRef ( { } ) ;
90
+
91
+ useDidUpdate ( ( ) => { cm . current . scrollTop = cm . current . scrollHeight ; } ) ;
92
+
93
+ const consoleClass = classNames ( {
94
+ 'preview-console' : true ,
95
+ 'preview-console--collapsed' : ! isExpanded
96
+ } ) ;
165
97
166
98
return (
167
- <ConsoleComponent
168
- consoleEvents={consoleEvents}
169
- isExpanded={consoleIsExpanded}
170
- theme={theme}
171
- fontSize={fontSize}
172
- collapseConsole={() => dispatch({})}
173
- expandConsole={() => dispatch({})}
174
- clearConsole={() => dispatch({})}
175
- dispatchConsoleEvent={() => dispatch({})}
176
- />
99
+ < section className = { consoleClass } >
100
+ < header className = "preview-console__header" >
101
+ < h2 className = "preview-console__header-title" > Console</ h2 >
102
+ < div className = "preview-console__header-buttons" >
103
+ < button className = "preview-console__clear" onClick = { clearConsole } aria-label = "Clear console" >
104
+ Clear
105
+ </ button >
106
+ < button
107
+ className = "preview-console__collapse"
108
+ onClick = { collapseConsole }
109
+ aria-label = "Close console"
110
+ >
111
+ < DownArrowIcon focusable = "false" aria-hidden = "true" />
112
+ </ button >
113
+ < button className = "preview-console__expand" onClick = { expandConsole } aria-label = "Open console" >
114
+ < UpArrowIcon focusable = "false" aria-hidden = "true" />
115
+ </ button >
116
+ </ div >
117
+ </ header >
118
+ < div ref = { cm } className = "preview-console__messages" >
119
+ { consoleEvents . map ( ( consoleEvent ) => {
120
+ const { method, times } = consoleEvent ;
121
+ return (
122
+ < div key = { consoleEvent . id } className = { `preview-console__message preview-console__message--${ method } ` } >
123
+ { times > 1 &&
124
+ < div
125
+ className = "preview-console__logged-times"
126
+ style = { { fontSize, borderRadius : fontSize / 2 } }
127
+ >
128
+ { times }
129
+ </ div >
130
+ }
131
+ < ConsoleFeed
132
+ styles = { getConsoleFeedStyle ( theme , times , fontSize ) }
133
+ logs = { [ consoleEvent ] }
134
+ />
135
+ </ div >
136
+ ) ;
137
+ } ) }
138
+ </ div >
139
+ </ section >
177
140
) ;
178
141
} ;
179
- */
180
142
181
- const Console = connect (
182
- state => ( {
183
- consoleEvents : state . console ,
184
- isExpanded : state . ide . consoleIsExpanded ,
185
- theme : state . preferences . theme ,
186
- fontSize : state . preferences . fontSize
187
- } ) ,
188
- dispatch => ( {
189
- collapseConsole : ( ) => dispatch ( IDEActions . collapseConsole ( ) ) ,
190
- expandConsole : ( ) => dispatch ( IDEActions . expandConsole ( ) ) ,
191
- clearConsole : ( ) => dispatch ( ConsoleActions . clearConsole ( ) ) ,
192
- dispatchConsoleEvent : msgs => dispatch ( ConsoleActions . dispatchConsoleEvent ( msgs ) ) ,
193
- } )
194
- ) ( ConsoleComponent ) ;
195
143
196
144
export default Console ;
0 commit comments