♻️ refactor <Console /> to use hooks

This commit is contained in:
ghalestrilo 2020-07-17 16:33:15 -03:00
commit d3f7d3de39
7 changed files with 87 additions and 45 deletions

View file

@ -1,20 +1,42 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import PropTypes from 'prop-types';
import { prop, remSize } from '../../theme'; import { prop, remSize } from '../../theme';
const background = prop('MobilePanel.default.background'); const background = prop('MobilePanel.default.background');
const textColor = prop('primaryTextColor'); const textColor = prop('primaryTextColor');
const Footer = styled.div` const FooterWrapper = styled.div`
position: fixed; position: fixed;
width: 100%; width: 100%;
bottom: 0;
`;
const FooterContent = styled.div`
background: ${background}; background: ${background};
color: ${textColor}; color: ${textColor};
padding: ${remSize(12)}; padding: ${remSize(12)};
padding-left: ${remSize(32)}; padding-left: ${remSize(32)};
z-index: 1;
bottom: 0;
`; `;
const Footer = ({ before, children }) => (
<FooterWrapper>
{before}
<FooterContent>
{children}
</FooterContent>
</FooterWrapper>
);
Footer.propTypes = {
before: PropTypes.element,
children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]),
};
Footer.defaultProps = {
before: <></>,
children: <></>
};
export default Footer; export default Footer;

View file

@ -1,5 +1,8 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { bindActionCreators } from 'redux';
import { useSelector, useDispatch } from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import { Console as ConsoleFeed } from 'console-feed'; import { Console as ConsoleFeed } from 'console-feed';
import { import {
@ -22,7 +25,10 @@ import infoContrastUrl from '../../../images/console-info-contrast.svg?byUrl';
import UpArrowIcon from '../../../images/up-arrow.svg'; import UpArrowIcon from '../../../images/up-arrow.svg';
import DownArrowIcon from '../../../images/down-arrow.svg'; import DownArrowIcon from '../../../images/down-arrow.svg';
class Console extends React.Component { import * as IDEActions from '../../IDE/actions/ide';
import * as ConsoleActions from '../../IDE/actions/console';
class ConsoleComponent extends React.Component {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight;
if (this.props.theme !== prevProps.theme) { if (this.props.theme !== prevProps.theme) {
@ -132,7 +138,7 @@ class Console extends React.Component {
} }
} }
Console.propTypes = { ConsoleComponent.propTypes = {
consoleEvents: PropTypes.arrayOf(PropTypes.shape({ consoleEvents: PropTypes.arrayOf(PropTypes.shape({
method: PropTypes.string.isRequired, method: PropTypes.string.isRequired,
args: PropTypes.arrayOf(PropTypes.string) args: PropTypes.arrayOf(PropTypes.string)
@ -146,8 +152,46 @@ Console.propTypes = {
fontSize: PropTypes.number.isRequired fontSize: PropTypes.number.isRequired
}; };
Console.defaultProps = { ConsoleComponent.defaultProps = {
consoleEvents: [] consoleEvents: []
}; };
const Console = () => {
const consoleEvents = useSelector(state => state.console);
const { consoleIsExpanded } = useSelector(state => state.ide);
const { theme, fontSize } = useSelector(state => state.preferences);
const {
collapseConsole, expandConsole, clearConsole, dispatchConsoleEvent
} = bindActionCreators({ ...IDEActions, ...ConsoleActions }, useDispatch());
return (
<ConsoleComponent
consoleEvents={consoleEvents}
isExpanded={consoleIsExpanded}
theme={theme}
fontSize={fontSize}
collapseConsole={collapseConsole}
expandConsole={expandConsole}
clearConsole={clearConsole}
dispatchConsoleEvent={dispatchConsoleEvent}
/>
);
};
// const Console = connect(
// state => ({
// consoleEvents: state.console,
// isExpanded: state.ide.consoleIsExpanded,
// theme: state.preferences.theme,
// fontSize: state.preferences.fontSize
// }),
// dispatch => ({
// collapseConsole: () => dispatch(IDEActions.collapseConsole()),
// expandConsole: () => dispatch(IDEActions.expandConsole()),
// clearConsole: () => dispatch(ConsoleActions.clearConsole()),
// dispatchConsoleEvent: msgs => dispatch(ConsoleActions.dispatchConsoleEvent(msgs)),
// })
// )(ConsoleComponent);
export default Console; export default Console;

View file

@ -324,16 +324,7 @@ class IDEView extends React.Component {
runtimeErrorWarningVisible={this.props.ide.runtimeErrorWarningVisible} runtimeErrorWarningVisible={this.props.ide.runtimeErrorWarningVisible}
provideController={(ctl) => { this.cmController = ctl; }} provideController={(ctl) => { this.cmController = ctl; }}
/> />
<Console <Console />
fontSize={this.props.preferences.fontSize}
consoleEvents={this.props.console}
isExpanded={this.props.ide.consoleIsExpanded}
expandConsole={this.props.expandConsole}
collapseConsole={this.props.collapseConsole}
clearConsole={this.props.clearConsole}
dispatchConsoleEvent={this.props.dispatchConsoleEvent}
theme={this.props.preferences.theme}
/>
</SplitPane> </SplitPane>
<section className="preview-frame-holder"> <section className="preview-frame-holder">
<header className="preview-frame__header"> <header className="preview-frame__header">
@ -649,6 +640,4 @@ function mapDispatchToProps(dispatch) {
); );
} }
export default withTranslation('WebEditor')(withRouter(connect(mapStateToProps, mapDispatchToProps)(IDEView))); export default withTranslation('WebEditor')(withRouter(connect(mapStateToProps, mapDispatchToProps)(IDEView)));

View file

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { useState } from 'react'; import { useState } from 'react';
import styled from 'styled-components';
// Imports to be Refactored // Imports to be Refactored
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -25,6 +26,8 @@ import Header from '../../../components/mobile/Header';
import Screen from '../../../components/mobile/MobileScreen'; import Screen from '../../../components/mobile/MobileScreen';
import Footer from '../../../components/mobile/Footer'; import Footer from '../../../components/mobile/Footer';
import IDEWrapper from '../../../components/mobile/IDEWrapper'; import IDEWrapper from '../../../components/mobile/IDEWrapper';
import Console from '../components/Console';
import { remSize } from '../../../theme';
const isUserOwner = ({ project, user }) => (project.owner && project.owner.id === user.id); const isUserOwner = ({ project, user }) => (project.owner && project.owner.id === user.id);
@ -94,7 +97,9 @@ const MobileIDEView = (props) => {
provideController={setTmController} provideController={setTmController}
/> />
</IDEWrapper> </IDEWrapper>
<Footer><h2>Bottom Bar</h2></Footer> <Footer before={<Console />} >
<h2>Bottom Bar</h2>
</Footer>
</Screen> </Screen>
); );
}; };

View file

@ -89,27 +89,4 @@ const MobilePreferences = () => {
</Screen>); </Screen>);
}; };
MobilePreferences.propTypes = {
fontSize: PropTypes.number.isRequired,
lineNumbers: PropTypes.bool.isRequired,
autosave: PropTypes.bool.isRequired,
linewrap: PropTypes.bool.isRequired,
textOutput: PropTypes.bool.isRequired,
gridOutput: PropTypes.bool.isRequired,
soundOutput: PropTypes.bool.isRequired,
lintWarning: PropTypes.bool.isRequired,
theme: PropTypes.string.isRequired,
setLinewrap: PropTypes.func.isRequired,
setLintWarning: PropTypes.func.isRequired,
setTheme: PropTypes.func.isRequired,
setFontSize: PropTypes.func.isRequired,
setLineNumbers: PropTypes.func.isRequired,
setAutosave: PropTypes.func.isRequired,
setTextOutput: PropTypes.func.isRequired,
setGridOutput: PropTypes.func.isRequired,
setSoundOutput: PropTypes.func.isRequired,
};
export default withRouter(MobilePreferences); export default withRouter(MobilePreferences);

View file

@ -7,6 +7,7 @@ import Header from '../../components/mobile/Header';
import IconButton from '../../components/mobile/IconButton'; import IconButton from '../../components/mobile/IconButton';
import PreviewFrame from '../IDE/components/PreviewFrame'; import PreviewFrame from '../IDE/components/PreviewFrame';
import Screen from '../../components/mobile/MobileScreen'; import Screen from '../../components/mobile/MobileScreen';
import Console from '../IDE/components/Console';
import * as ProjectActions from '../IDE/actions/project'; import * as ProjectActions from '../IDE/actions/project';
import * as IDEActions from '../IDE/actions/ide'; import * as IDEActions from '../IDE/actions/ide';
import * as PreferencesActions from '../IDE/actions/preferences'; import * as PreferencesActions from '../IDE/actions/preferences';
@ -17,6 +18,7 @@ import { getHTMLFile } from '../IDE/reducers/files';
import { ExitIcon } from '../../common/icons'; import { ExitIcon } from '../../common/icons';
import { remSize } from '../../theme'; import { remSize } from '../../theme';
import Footer from '../../components/mobile/Footer';
const Content = styled.div` const Content = styled.div`
z-index: 0; z-index: 0;
@ -73,6 +75,7 @@ const MobileSketchView = (props) => {
clearConsole={clearConsole} clearConsole={clearConsole}
/> />
</Content> </Content>
<Footer before={<Console />} />
</Screen>); </Screen>);
}; };

6
package-lock.json generated
View file

@ -11017,7 +11017,8 @@
}, },
"kind-of": { "kind-of": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "" "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
} }
} }
}, },
@ -34869,7 +34870,8 @@
}, },
"kind-of": { "kind-of": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "" "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
} }
} }
}, },