import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import ReactDom from 'react-dom'; import { createSelector } from 'reselect'; import { connect } from 'react-redux'; import ns from './ns.json'; import BugModal from './Bug-Modal.jsx'; import ToolPanel from './Tool-Panel.jsx'; import ChallengeTitle from './Challenge-Title.jsx'; import ChallengeDescription from './Challenge-Description.jsx'; import TestSuite from './Test-Suite.jsx'; import Output from './Output.jsx'; import { openBugModal, updateHint, executeChallenge, unlockUntrustedCode, challengeMetaSelector, testsSelector, outputSelector, hintIndexSelector, codeLockedSelector, chatRoomSelector } from './redux'; import { descriptionRegex } from './utils'; import { challengeSelector } from '../../redux'; import { makeToast } from '../../Toasts/redux'; const mapDispatchToProps = { makeToast, executeChallenge, updateHint, openBugModal, unlockUntrustedCode }; const mapStateToProps = createSelector( challengeSelector, challengeMetaSelector, testsSelector, outputSelector, hintIndexSelector, codeLockedSelector, chatRoomSelector, ( { description }, { title }, tests, output, hintIndex, isCodeLocked, helpChatRoom ) => ({ title, description, tests, output, isCodeLocked, helpChatRoom }) ); const propTypes = { description: PropTypes.arrayOf(PropTypes.string), executeChallenge: PropTypes.func, helpChatRoom: PropTypes.string, hint: PropTypes.string, isCodeLocked: PropTypes.bool, makeToast: PropTypes.func, openBugModal: PropTypes.func, output: PropTypes.string, tests: PropTypes.arrayOf(PropTypes.object), title: PropTypes.string, unlockUntrustedCode: PropTypes.func, updateHint: PropTypes.func }; export class SidePanel extends PureComponent { constructor(props) { super(props); this.bindTopDiv = this.bindTopDiv.bind(this); } componentWillUpdate(nextProps) { const { title } = this.props; if (title !== nextProps.title) { const node = ReactDom.findDOMNode(this.descriptionTop); setTimeout(() => { node.scrollIntoView({ behavior: 'smooth'}); }, 0); } } bindTopDiv(node) { this.descriptionTop = node; } renderDescription(description = [ 'Happy Coding!' ]) { return description.map((line, index) => { if (descriptionRegex.test(line)) { return (
); } return (

); }); } render() { const { title, description, tests = [], output, hint, executeChallenge, updateHint, makeToast, helpChatRoom, openBugModal, isCodeLocked, unlockUntrustedCode } = this.props; return (

{ title } { this.renderDescription(description) }

); } } SidePanel.displayName = 'SidePanel'; SidePanel.propTypes = propTypes; export default connect( mapStateToProps, mapDispatchToProps )(SidePanel);