From 89ffa4194ee2ae9c9c8f2b76b91eca9ccfcf6596 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Fri, 3 Jul 2020 15:22:20 -0300 Subject: [PATCH 01/16] :recycle: create option creators, improve header transparency --- client/components/mobile/Header.jsx | 4 +- client/modules/Mobile/MobilePreferences.jsx | 106 +++++--------------- client/theme.js | 3 + 3 files changed, 32 insertions(+), 81 deletions(-) diff --git a/client/components/mobile/Header.jsx b/client/components/mobile/Header.jsx index 1f7f7a29..e1057d0c 100644 --- a/client/components/mobile/Header.jsx +++ b/client/components/mobile/Header.jsx @@ -3,14 +3,14 @@ import styled from 'styled-components'; import PropTypes from 'prop-types'; import { prop, remSize } from '../../theme'; -const background = prop('MobilePanel.default.background'); +const background = transparent => prop(transparent ? 'backgroundColor' : 'MobilePanel.default.background'); const textColor = prop('primaryTextColor'); const HeaderDiv = styled.div` position: fixed; width: 100%; - background: ${props => (props.transparent ? 'transparent' : background)}; + background: ${props => background(props.transparent === true)}; color: ${textColor}; padding: ${remSize(12)}; padding-left: ${remSize(16)}; diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index a9dc9f34..9ebb219c 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -20,11 +20,6 @@ const Content = styled.div` margin-top: ${remSize(68)}; `; - -const SettingsHeader = styled(Header)` - background: transparent; -`; - const SectionHeader = styled.h2` color: ${prop('primaryTextColor')}; padding-top: ${remSize(32)}; @@ -34,6 +29,23 @@ const SectionSubeader = styled.h3` color: ${prop('primaryTextColor')}; `; +const optionsOnOff = (name, onLabel = 'On', offLabel = 'Off') => [ + { + value: true, label: onLabel, ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') + }, + { + value: false, label: offLabel, ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') + }, +]; + +const optionsPickOne = (name, ...options) => options.map(option => ({ + value: option, + label: option, + ariaLabel: `${option} ${name} on`, + name: `${option} ${name}`, + id: `${option}-${name}-on`.replace(' ', '-') +})); + const MobilePreferences = (props) => { const { @@ -47,49 +59,21 @@ const MobilePreferences = (props) => { { title: 'Theme', value: theme, - options: [ - { - value: 'light', label: 'light', ariaLabel: 'light theme on', name: 'light theme', id: 'light-theme-on' - }, - { - value: 'dark', label: 'dark', ariaLabel: 'dark theme on', name: 'dark theme', id: 'dark-theme-on' - }, - { - value: 'contrast', - label: 'contrast', - ariaLabel: 'contrast theme on', - name: 'contrast theme', - id: 'contrast-theme-on' - } - ], + options: optionsPickOne('theme', 'light', 'dark', 'contrast'), onSelect: x => setTheme(x) // setTheme }, { title: 'Autosave', value: autosave, - options: [ - { - value: true, label: 'On', ariaLabel: 'autosave on', name: 'autosave', id: 'autosave-on' - }, - { - value: false, label: 'Off', ariaLabel: 'autosave off', name: 'autosave', id: 'autosave-off' - }, - ], + options: optionsOnOff('autosave'), onSelect: x => setAutosave(x) // setAutosave }, { title: 'Word Wrap', value: linewrap, - options: [ - { - value: true, label: 'On', ariaLabel: 'linewrap on', name: 'linewrap', id: 'linewrap-on' - }, - { - value: false, label: 'Off', ariaLabel: 'linewrap off', name: 'linewrap', id: 'linewrap-off' - }, - ], + options: optionsOnOff('linewrap'), onSelect: x => setLinewrap(x) } ]; @@ -98,40 +82,19 @@ const MobilePreferences = (props) => { { title: 'Plain-text', value: textOutput, - options: [ - { - value: true, label: 'On', ariaLabel: 'text output on', name: 'text output', id: 'text-output-on' - }, - { - value: false, label: 'Off', ariaLabel: 'text output off', name: 'text output', id: 'text-output-off' - }, - ], + options: optionsOnOff('text output'), onSelect: x => setTextOutput(x) }, { title: 'Table-text', value: gridOutput, - options: [ - { - value: true, label: 'On', ariaLabel: 'table output on', name: 'table output', id: 'table-output-on' - }, - { - value: false, label: 'Off', ariaLabel: 'table output off', name: 'table output', id: 'table-output-off' - }, - ], + options: optionsOnOff('table output'), onSelect: x => setGridOutput(x) }, { title: 'Sound', value: soundOutput, - options: [ - { - value: true, label: 'On', ariaLabel: 'sound output on', name: 'sound output', id: 'sound-output-on' - }, - { - value: false, label: 'Off', ariaLabel: 'sound output off', name: 'sound output', id: 'sound-output-off' - }, - ], + options: optionsOnOff('sound output'), onSelect: x => setSoundOutput(x) }, ]; @@ -140,27 +103,13 @@ const MobilePreferences = (props) => { { title: 'Line Numbers', value: lineNumbers, - options: [ - { - value: true, label: 'On', ariaLabel: 'line numbers on', name: 'line numbers', id: 'line-numbers-on' - }, - { - value: false, label: 'Off', ariaLabel: 'line numbers off', name: 'line numbers', id: 'line-numbers-off' - }, - ], + options: optionsOnOff('line numbers'), onSelect: x => setLineNumbers(x) }, { title: 'Lint Warning Sound', value: lintWarning, - options: [ - { - value: true, label: 'On', ariaLabel: 'lint warning on', name: 'lint warning', id: 'lint-warning-on' - }, - { - value: false, label: 'Off', ariaLabel: 'lint warning off', name: 'lint warning', id: 'lint-warning-off' - }, - ], + options: optionsOnOff('lint warning'), onSelect: x => setLintWarning(x) }, ]; @@ -168,10 +117,9 @@ const MobilePreferences = (props) => { return (
- - +
- +
General Settings diff --git a/client/theme.js b/client/theme.js index 5dba9b88..4aee2a09 100644 --- a/client/theme.js +++ b/client/theme.js @@ -62,6 +62,7 @@ export default { colors, ...common, primaryTextColor: grays.dark, + backgroundColor: grays.lighter, Button: { default: { @@ -101,6 +102,7 @@ export default { colors, ...common, primaryTextColor: grays.lightest, + backgroundColor: grays.darker, Button: { default: { @@ -140,6 +142,7 @@ export default { colors, ...common, primaryTextColor: grays.lightest, + backgroundColor: grays.darker, Button: { default: { From 1c4b234f2f0f2fbafde5ce9cbcbaa669bbf94563 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Fri, 17 Jul 2020 15:36:38 -0300 Subject: [PATCH 02/16] :recycle: refactor --- client/modules/Mobile/MobileSketchView.jsx | 135 +++------------------ 1 file changed, 15 insertions(+), 120 deletions(-) diff --git a/client/modules/Mobile/MobileSketchView.jsx b/client/modules/Mobile/MobileSketchView.jsx index 64eabb5e..ad814e10 100644 --- a/client/modules/Mobile/MobileSketchView.jsx +++ b/client/modules/Mobile/MobileSketchView.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, useSelector, useDispatch } from 'react-redux'; import styled from 'styled-components'; import Header from '../../components/mobile/Header'; import IconButton from '../../components/mobile/IconButton'; @@ -15,43 +15,34 @@ import * as FilesActions from '../IDE/actions/files'; import { getHTMLFile } from '../IDE/reducers/files'; - import { ExitIcon } from '../../common/icons'; import { remSize } from '../../theme'; - const Content = styled.div` z-index: 0; margin-top: ${remSize(68)}; `; const MobileSketchView = (props) => { - // TODO: useSelector requires react-redux ^7.1.0 - // const htmlFile = useSelector(state => getHTMLFile(state.files)); - // const jsFiles = useSelector(state => getJSFiles(state.files)); - // const cssFiles = useSelector(state => getCSSFiles(state.files)); - // const files = useSelector(state => state.files); + const { files, ide, preferences } = useSelector(state => state); + + const htmlFile = useSelector(state => getHTMLFile(state.files)); + const projectName = useSelector(state => state.project.name); + const selectedFile = useSelector(state => state.files.find(file => file.isSelectedFile) || + state.files.find(file => file.name === 'sketch.js') || + state.files.find(file => file.name !== 'root')); const { - htmlFile, files, selectedFile, projectName - } = props; - - // Actions - const { - setTextOutput, setGridOutput, setSoundOutput, - endSketchRefresh, stopSketch, - dispatchConsoleEvent, expandConsole, clearConsole, - setBlobUrl, - } = props; - - const { preferences, ide } = props; + setTextOutput, setGridOutput, setSoundOutput, dispatchConsoleEvent, + endSketchRefresh, stopSketch, setBlobUrl, expandConsole, clearConsole + } = bindActionCreators({ + ...ProjectActions, ...IDEActions, ...PreferencesActions, ...ConsoleActions, ...FilesActions + }, useDispatch()); return (
- } + leftButton={} title={projectName} /> @@ -85,100 +76,4 @@ const MobileSketchView = (props) => { ); }; -MobileSketchView.propTypes = { - params: PropTypes.shape({ - project_id: PropTypes.string, - username: PropTypes.string - }).isRequired, - - htmlFile: PropTypes.shape({ - id: PropTypes.string.isRequired, - content: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - files: PropTypes.arrayOf(PropTypes.shape({ - id: PropTypes.string.isRequired, - content: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - })).isRequired, - - selectedFile: PropTypes.shape({ - id: PropTypes.string.isRequired, - content: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - - preferences: PropTypes.shape({ - fontSize: PropTypes.number.isRequired, - autosave: PropTypes.bool.isRequired, - linewrap: PropTypes.bool.isRequired, - lineNumbers: PropTypes.bool.isRequired, - lintWarning: PropTypes.bool.isRequired, - textOutput: PropTypes.bool.isRequired, - gridOutput: PropTypes.bool.isRequired, - soundOutput: PropTypes.bool.isRequired, - theme: PropTypes.string.isRequired, - autorefresh: PropTypes.bool.isRequired - }).isRequired, - - ide: PropTypes.shape({ - isPlaying: PropTypes.bool.isRequired, - isAccessibleOutputPlaying: PropTypes.bool.isRequired, - consoleEvent: PropTypes.array, - modalIsVisible: PropTypes.bool.isRequired, - sidebarIsExpanded: PropTypes.bool.isRequired, - consoleIsExpanded: PropTypes.bool.isRequired, - preferencesIsVisible: PropTypes.bool.isRequired, - projectOptionsVisible: PropTypes.bool.isRequired, - newFolderModalVisible: PropTypes.bool.isRequired, - shareModalVisible: PropTypes.bool.isRequired, - shareModalProjectId: PropTypes.string.isRequired, - shareModalProjectName: PropTypes.string.isRequired, - shareModalProjectUsername: PropTypes.string.isRequired, - editorOptionsVisible: PropTypes.bool.isRequired, - keyboardShortcutVisible: PropTypes.bool.isRequired, - unsavedChanges: PropTypes.bool.isRequired, - infiniteLoop: PropTypes.bool.isRequired, - previewIsRefreshing: PropTypes.bool.isRequired, - infiniteLoopMessage: PropTypes.string.isRequired, - projectSavedTime: PropTypes.string, - previousPath: PropTypes.string.isRequired, - justOpenedProject: PropTypes.bool.isRequired, - errorType: PropTypes.string, - runtimeErrorWarningVisible: PropTypes.bool.isRequired, - uploadFileModalVisible: PropTypes.bool.isRequired - }).isRequired, - - projectName: PropTypes.string.isRequired, - - setTextOutput: PropTypes.func.isRequired, - setGridOutput: PropTypes.func.isRequired, - setSoundOutput: PropTypes.func.isRequired, - dispatchConsoleEvent: PropTypes.func.isRequired, - endSketchRefresh: PropTypes.func.isRequired, - stopSketch: PropTypes.func.isRequired, - setBlobUrl: PropTypes.func.isRequired, - expandConsole: PropTypes.func.isRequired, - clearConsole: PropTypes.func.isRequired, -}; - -function mapStateToProps(state) { - return { - htmlFile: getHTMLFile(state.files), - projectName: state.project.name, - files: state.files, - ide: state.ide, - preferences: state.preferences, - selectedFile: state.files.find(file => file.isSelectedFile) || - state.files.find(file => file.name === 'sketch.js') || - state.files.find(file => file.name !== 'root'), - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators({ - ...ProjectActions, ...IDEActions, ...PreferencesActions, ...ConsoleActions, ...FilesActions - }, dispatch); -} - -export default connect(mapStateToProps, mapDispatchToProps)(MobileSketchView); +export default MobileSketchView; From 3a596ec371dcfc021c3e3f080cdb52e2b8208827 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Fri, 17 Jul 2020 16:01:12 -0300 Subject: [PATCH 03/16] :recycle: refactor , create PreferenceCreators --- client/common/helpers/PreferenceCreators.jsx | 26 ++++++++ client/modules/Mobile/MobilePreferences.jsx | 69 +++----------------- 2 files changed, 34 insertions(+), 61 deletions(-) create mode 100644 client/common/helpers/PreferenceCreators.jsx diff --git a/client/common/helpers/PreferenceCreators.jsx b/client/common/helpers/PreferenceCreators.jsx new file mode 100644 index 00000000..9b977e09 --- /dev/null +++ b/client/common/helpers/PreferenceCreators.jsx @@ -0,0 +1,26 @@ +export const optionsOnOff = (name, onLabel = 'On', offLabel = 'Off') => [ + { + value: true, label: onLabel, ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') + }, + { + value: false, label: offLabel, ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') + }, +]; + +export const optionsPickOne = (name, ...options) => options.map(option => ({ + value: option, + label: option, + ariaLabel: `${option} ${name} on`, + name: `${option} ${name}`, + id: `${option}-${name}-on`.replace(' ', '-') +})); + +const nameToValueName = x => (x && x.toLowerCase().replace(/#|_|-/g, ' ')); + +// preferenceOnOff: name, value and onSelect are mandatory. propname is optional +export const preferenceOnOff = (name, value, onSelect, propname) => ({ + title: name, + value, + options: optionsOnOff(propname || nameToValueName(name)), + onSelect +}); diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 9ebb219c..07a1337c 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -14,6 +14,7 @@ import Header from '../../components/mobile/Header'; import PreferencePicker from '../../components/mobile/PreferencePicker'; import { ExitIcon } from '../../common/icons'; import { remSize, prop } from '../../theme'; +import { optionsOnOff, optionsPickOne, preferenceOnOff } from '../../common/helpers/PreferenceCreators'; const Content = styled.div` z-index: 0; @@ -29,23 +30,6 @@ const SectionSubeader = styled.h3` color: ${prop('primaryTextColor')}; `; -const optionsOnOff = (name, onLabel = 'On', offLabel = 'Off') => [ - { - value: true, label: onLabel, ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') - }, - { - value: false, label: offLabel, ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') - }, -]; - -const optionsPickOne = (name, ...options) => options.map(option => ({ - value: option, - label: option, - ariaLabel: `${option} ${name} on`, - name: `${option} ${name}`, - id: `${option}-${name}-on`.replace(' ', '-') -})); - const MobilePreferences = (props) => { const { @@ -62,56 +46,19 @@ const MobilePreferences = (props) => { options: optionsPickOne('theme', 'light', 'dark', 'contrast'), onSelect: x => setTheme(x) // setTheme }, - - { - title: 'Autosave', - value: autosave, - options: optionsOnOff('autosave'), - onSelect: x => setAutosave(x) // setAutosave - }, - - { - title: 'Word Wrap', - value: linewrap, - options: optionsOnOff('linewrap'), - onSelect: x => setLinewrap(x) - } + preferenceOnOff('Autosave', autosave, setAutosave, 'autosave'), + preferenceOnOff('Word Wrap', linewrap, setLinewrap, 'linewrap') ]; const outputSettings = [ - { - title: 'Plain-text', - value: textOutput, - options: optionsOnOff('text output'), - onSelect: x => setTextOutput(x) - }, - { - title: 'Table-text', - value: gridOutput, - options: optionsOnOff('table output'), - onSelect: x => setGridOutput(x) - }, - { - title: 'Sound', - value: soundOutput, - options: optionsOnOff('sound output'), - onSelect: x => setSoundOutput(x) - }, + preferenceOnOff('Plain-text', textOutput, setTextOutput, 'text output'), + preferenceOnOff('Table-text', gridOutput, setGridOutput, 'table output'), + preferenceOnOff('Lint Warning Sound', soundOutput, setSoundOutput, 'sound output') ]; const accessibilitySettings = [ - { - title: 'Line Numbers', - value: lineNumbers, - options: optionsOnOff('line numbers'), - onSelect: x => setLineNumbers(x) - }, - { - title: 'Lint Warning Sound', - value: lintWarning, - options: optionsOnOff('lint warning'), - onSelect: x => setLintWarning(x) - }, + preferenceOnOff('Line Numbers', lineNumbers, setLineNumbers), + preferenceOnOff('Lint Warning Sound', lintWarning, setLintWarning) ]; return ( From b87a313e122f7d6088211580a216dccba4785e7c Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Fri, 17 Jul 2020 16:06:13 -0300 Subject: [PATCH 04/16] :recycle: refactor to use hooks --- client/modules/Mobile/MobilePreferences.jsx | 28 ++++++++------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 07a1337c..297d60a4 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { bindActionCreators } from 'redux'; -import { connect } from 'react-redux'; +import { connect, useSelector, useDispatch } from 'react-redux'; import { withRouter } from 'react-router'; import PropTypes from 'prop-types'; import styled from 'styled-components'; @@ -31,13 +31,17 @@ const SectionSubeader = styled.h3` `; -const MobilePreferences = (props) => { +const MobilePreferences = () => { + // Props const { - setTheme, setAutosave, setLinewrap, setTextOutput, setGridOutput, setSoundOutput, lineNumbers, lintWarning - } = props; + theme, autosave, linewrap, textOutput, gridOutput, soundOutput, lineNumbers, lintWarning + } = useSelector(state => state.preferences); + + // Actions const { - theme, autosave, linewrap, textOutput, gridOutput, soundOutput, setLineNumbers, setLintWarning - } = props; + setTheme, setAutosave, setLinewrap, setTextOutput, setGridOutput, setSoundOutput, setLineNumbers, setLintWarning, + } = bindActionCreators({ ...PreferencesActions, ...IdeActions }, useDispatch()); + const generalSettings = [ { @@ -108,14 +112,4 @@ MobilePreferences.propTypes = { setSoundOutput: PropTypes.func.isRequired, }; -const mapStateToProps = state => ({ - ...state.preferences, -}); - -const mapDispatchToProps = dispatch => bindActionCreators({ - ...PreferencesActions, - ...IdeActions -}, dispatch); - - -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MobilePreferences)); +export default withRouter(MobilePreferences); From 9447bb575479dd9020cb25efd649d9170b4eb6dc Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Fri, 17 Jul 2020 16:52:45 -0300 Subject: [PATCH 05/16] :recycle: remove getConsoleFeedStyle from Console --- client/modules/IDE/components/Console.jsx | 135 +++++++++++----------- 1 file changed, 65 insertions(+), 70 deletions(-) diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index cdc28cd3..14d32e0d 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useEffect, useRef } from 'react'; + import { bindActionCreators } from 'redux'; import { useSelector, useDispatch } from 'react-redux'; @@ -28,61 +29,64 @@ import DownArrowIcon from '../../../images/down-arrow.svg'; import * as IDEActions from '../../IDE/actions/ide'; import * as ConsoleActions from '../../IDE/actions/console'; +const useDidUpdate = (callback, deps) => { + const hasMount = useRef(false); + + useEffect(() => { + if (hasMount.current) { + callback(); + } else { + hasMount.current = true; + } + }, deps); +}; + +const getConsoleFeedStyle = (theme, times, fontSize) => { + const style = {}; + const CONSOLE_FEED_LIGHT_ICONS = { + LOG_WARN_ICON: `url(${warnLightUrl})`, + LOG_ERROR_ICON: `url(${errorLightUrl})`, + LOG_DEBUG_ICON: `url(${debugLightUrl})`, + LOG_INFO_ICON: `url(${infoLightUrl})` + }; + const CONSOLE_FEED_DARK_ICONS = { + LOG_WARN_ICON: `url(${warnDarkUrl})`, + LOG_ERROR_ICON: `url(${errorDarkUrl})`, + LOG_DEBUG_ICON: `url(${debugDarkUrl})`, + LOG_INFO_ICON: `url(${infoDarkUrl})` + }; + const CONSOLE_FEED_CONTRAST_ICONS = { + LOG_WARN_ICON: `url(${warnContrastUrl})`, + LOG_ERROR_ICON: `url(${errorContrastUrl})`, + LOG_DEBUG_ICON: `url(${debugContrastUrl})`, + LOG_INFO_ICON: `url(${infoContrastUrl})` + }; + const CONSOLE_FEED_SIZES = { + TREENODE_LINE_HEIGHT: 1.2, + BASE_FONT_SIZE: fontSize, + ARROW_FONT_SIZE: fontSize, + LOG_ICON_WIDTH: fontSize, + LOG_ICON_HEIGHT: 1.45 * fontSize, + }; + + if (times > 1) { + Object.assign(style, CONSOLE_FEED_WITHOUT_ICONS); + } + switch (theme) { + case 'light': + return Object.assign(CONSOLE_FEED_LIGHT_STYLES, CONSOLE_FEED_LIGHT_ICONS, CONSOLE_FEED_SIZES, style); + case 'dark': + return Object.assign(CONSOLE_FEED_DARK_STYLES, CONSOLE_FEED_DARK_ICONS, CONSOLE_FEED_SIZES, style); + case 'contrast': + return Object.assign(CONSOLE_FEED_CONTRAST_STYLES, CONSOLE_FEED_CONTRAST_ICONS, CONSOLE_FEED_SIZES, style); + default: + return ''; + } +}; + class ConsoleComponent extends React.Component { componentDidUpdate(prevProps) { this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; - if (this.props.theme !== prevProps.theme) { - this.props.clearConsole(); - this.props.dispatchConsoleEvent(this.props.consoleEvents); - } - - if (this.props.fontSize !== prevProps.fontSize) { - this.props.clearConsole(); - this.props.dispatchConsoleEvent(this.props.consoleEvents); - } - } - - getConsoleFeedStyle(theme, times) { - const style = {}; - const CONSOLE_FEED_LIGHT_ICONS = { - LOG_WARN_ICON: `url(${warnLightUrl})`, - LOG_ERROR_ICON: `url(${errorLightUrl})`, - LOG_DEBUG_ICON: `url(${debugLightUrl})`, - LOG_INFO_ICON: `url(${infoLightUrl})` - }; - const CONSOLE_FEED_DARK_ICONS = { - LOG_WARN_ICON: `url(${warnDarkUrl})`, - LOG_ERROR_ICON: `url(${errorDarkUrl})`, - LOG_DEBUG_ICON: `url(${debugDarkUrl})`, - LOG_INFO_ICON: `url(${infoDarkUrl})` - }; - const CONSOLE_FEED_CONTRAST_ICONS = { - LOG_WARN_ICON: `url(${warnContrastUrl})`, - LOG_ERROR_ICON: `url(${errorContrastUrl})`, - LOG_DEBUG_ICON: `url(${debugContrastUrl})`, - LOG_INFO_ICON: `url(${infoContrastUrl})` - }; - const CONSOLE_FEED_SIZES = { - TREENODE_LINE_HEIGHT: 1.2, - BASE_FONT_SIZE: this.props.fontSize, - ARROW_FONT_SIZE: this.props.fontSize, - LOG_ICON_WIDTH: this.props.fontSize, - LOG_ICON_HEIGHT: 1.45 * this.props.fontSize, - }; - - if (times > 1) { - Object.assign(style, CONSOLE_FEED_WITHOUT_ICONS); - } - switch (theme) { - case 'light': - return Object.assign(CONSOLE_FEED_LIGHT_STYLES, CONSOLE_FEED_LIGHT_ICONS, CONSOLE_FEED_SIZES, style); - case 'dark': - return Object.assign(CONSOLE_FEED_DARK_STYLES, CONSOLE_FEED_DARK_ICONS, CONSOLE_FEED_SIZES, style); - case 'contrast': - return Object.assign(CONSOLE_FEED_CONTRAST_STYLES, CONSOLE_FEED_CONTRAST_ICONS, CONSOLE_FEED_SIZES, style); - default: - return ''; - } } render() { @@ -91,6 +95,8 @@ class ConsoleComponent extends React.Component { 'preview-console--collapsed': !this.props.isExpanded }); + console.log(this.props.isExpanded); + return (
@@ -126,7 +132,7 @@ class ConsoleComponent extends React.Component { } @@ -147,7 +153,6 @@ ConsoleComponent.propTypes = { collapseConsole: PropTypes.func.isRequired, expandConsole: PropTypes.func.isRequired, clearConsole: PropTypes.func.isRequired, - dispatchConsoleEvent: PropTypes.func.isRequired, theme: PropTypes.string.isRequired, fontSize: PropTypes.number.isRequired }; @@ -165,6 +170,11 @@ const Console = () => { collapseConsole, expandConsole, clearConsole, dispatchConsoleEvent } = bindActionCreators({ ...IDEActions, ...ConsoleActions }, useDispatch()); + useDidUpdate(() => { + clearConsole(); + dispatchConsoleEvent(consoleEvents); + }, [theme, fontSize]); + return ( { ); }; -// 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; From 9e95517f704c4fc0e7ea44cf022d49e06d8f4a4c Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Mon, 20 Jul 2020 17:56:35 -0300 Subject: [PATCH 06/16] :construction: refactor to hooks --- client/modules/IDE/components/Console.jsx | 149 +++++++++------------- 1 file changed, 59 insertions(+), 90 deletions(-) diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index 14d32e0d..c1596c89 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; import React, { useEffect, useRef } from 'react'; import { bindActionCreators } from 'redux'; -import { useSelector, useDispatch } from 'react-redux'; +import { useSelector, useDispatch, useState } from 'react-redux'; import classNames from 'classnames'; import { Console as ConsoleFeed } from 'console-feed'; import { @@ -84,88 +83,17 @@ const getConsoleFeedStyle = (theme, times, fontSize) => { } }; -class ConsoleComponent extends React.Component { - componentDidUpdate(prevProps) { - this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; - } - - render() { - const consoleClass = classNames({ - 'preview-console': true, - 'preview-console--collapsed': !this.props.isExpanded - }); - - console.log(this.props.isExpanded); - - return ( -
-
-

Console

-
- - - -
-
-
{ this.consoleMessages = element; }} className="preview-console__messages"> - {this.props.consoleEvents.map((consoleEvent) => { - const { method, times } = consoleEvent; - const { theme } = this.props; - return ( -
- { times > 1 && -
- {times} -
- } - -
- ); - })} -
-
- ); - } -} - -ConsoleComponent.propTypes = { - consoleEvents: PropTypes.arrayOf(PropTypes.shape({ - method: PropTypes.string.isRequired, - args: PropTypes.arrayOf(PropTypes.string) - })), - isExpanded: PropTypes.bool.isRequired, - collapseConsole: PropTypes.func.isRequired, - expandConsole: PropTypes.func.isRequired, - clearConsole: PropTypes.func.isRequired, - theme: PropTypes.string.isRequired, - fontSize: PropTypes.number.isRequired -}; - -ConsoleComponent.defaultProps = { - consoleEvents: [] -}; - +// 1 . FIXME: Object is not a function 🤷🏻 const Console = () => { const consoleEvents = useSelector(state => state.console); - const { consoleIsExpanded } = useSelector(state => state.ide); + const isExpanded = useSelector(state => state.ide.consoleIsExpanded); const { theme, fontSize } = useSelector(state => state.preferences); + const [cm, setCm] = useState({}); + + // 2. FIXME: Console is not opening/closing, and I suspect it has to do with this + useDidUpdate(() => { if (cm) cm.scrollTop = cm.scrollHeight; }); + const { collapseConsole, expandConsole, clearConsole, dispatchConsoleEvent } = bindActionCreators({ ...IDEActions, ...ConsoleActions }, useDispatch()); @@ -175,18 +103,59 @@ const Console = () => { dispatchConsoleEvent(consoleEvents); }, [theme, fontSize]); + // const [consoleMessages, setConsoleMessages] = useState({}); + // this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; + + + const consoleClass = classNames({ + 'preview-console': true, + 'preview-console--collapsed': isExpanded + }); + return ( - +
+
+

Console

+
+ + + +
+
+
setCm(element)} className="preview-console__messages"> + {consoleEvents.map((consoleEvent) => { + const { method, times } = consoleEvent; + return ( +
+ { times > 1 && +
+ {times} +
+ } + +
+ ); + })} +
+
); }; + export default Console; From 234c4ffe14f4aa39bc0861b9dceb583582e6fbbb Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Mon, 20 Jul 2020 18:37:50 -0300 Subject: [PATCH 07/16] :bug: fix broken useState --- client/modules/IDE/components/Console.jsx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index c1596c89..258ae425 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -83,17 +83,11 @@ const getConsoleFeedStyle = (theme, times, fontSize) => { } }; -// 1 . FIXME: Object is not a function 🤷🏻 const Console = () => { const consoleEvents = useSelector(state => state.console); const isExpanded = useSelector(state => state.ide.consoleIsExpanded); const { theme, fontSize } = useSelector(state => state.preferences); - const [cm, setCm] = useState({}); - - // 2. FIXME: Console is not opening/closing, and I suspect it has to do with this - useDidUpdate(() => { if (cm) cm.scrollTop = cm.scrollHeight; }); - const { collapseConsole, expandConsole, clearConsole, dispatchConsoleEvent } = bindActionCreators({ ...IDEActions, ...ConsoleActions }, useDispatch()); @@ -101,11 +95,23 @@ const Console = () => { useDidUpdate(() => { clearConsole(); dispatchConsoleEvent(consoleEvents); - }, [theme, fontSize]); + }, [theme, fontSize]); // // const [consoleMessages, setConsoleMessages] = useState({}); // this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; + // const clearConsole = () => {}; + // const collapseConsole = () => {}; + // const expandConsole = () => {}; + + // const isExpanded = true; + // const fontSize = 16; + // const theme = {}; + + // // 2. FIXME: Console is not opening/closing, and I suspect it has to do with this + const cm = useRef({}); + useDidUpdate(() => { if (cm.current) cm.current.scrollTop = cm.current.scrollHeight; }); + const consoleClass = classNames({ 'preview-console': true, @@ -132,7 +138,7 @@ const Console = () => {
-
setCm(element)} className="preview-console__messages"> +
{consoleEvents.map((consoleEvent) => { const { method, times } = consoleEvent; return ( From 556c9d15fe88ae542e9de0294430d92f851399eb Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Mon, 20 Jul 2020 19:02:30 -0300 Subject: [PATCH 08/16] :bug: fix console not opening/closing --- client/modules/IDE/components/Console.jsx | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index 258ae425..263ef786 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -95,27 +95,16 @@ const Console = () => { useDidUpdate(() => { clearConsole(); dispatchConsoleEvent(consoleEvents); - }, [theme, fontSize]); // + }, [theme, fontSize]); - // const [consoleMessages, setConsoleMessages] = useState({}); - // this.consoleMessages.scrollTop = this.consoleMessages.scrollHeight; - - // const clearConsole = () => {}; - // const collapseConsole = () => {}; - // const expandConsole = () => {}; - - // const isExpanded = true; - // const fontSize = 16; - // const theme = {}; + const cm = useRef({}); // // 2. FIXME: Console is not opening/closing, and I suspect it has to do with this - const cm = useRef({}); - useDidUpdate(() => { if (cm.current) cm.current.scrollTop = cm.current.scrollHeight; }); - + useDidUpdate(() => { cm.current.scrollTop = cm.current.scrollHeight; }); const consoleClass = classNames({ 'preview-console': true, - 'preview-console--collapsed': isExpanded + 'preview-console--collapsed': !isExpanded }); return ( From 24a26c16c2d399696db293b0d14cebe3cbccdc2b Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Mon, 20 Jul 2020 19:08:03 -0300 Subject: [PATCH 09/16] :broom: remove needless imports --- client/modules/IDE/components/Console.jsx | 17 +++-------------- client/utils/custom-hooks.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 client/utils/custom-hooks.js diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index 263ef786..cb2500c1 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -1,8 +1,8 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useRef } from 'react'; import { bindActionCreators } from 'redux'; -import { useSelector, useDispatch, useState } from 'react-redux'; +import { useSelector, useDispatch } from 'react-redux'; import classNames from 'classnames'; import { Console as ConsoleFeed } from 'console-feed'; import { @@ -27,18 +27,7 @@ import DownArrowIcon from '../../../images/down-arrow.svg'; import * as IDEActions from '../../IDE/actions/ide'; import * as ConsoleActions from '../../IDE/actions/console'; - -const useDidUpdate = (callback, deps) => { - const hasMount = useRef(false); - - useEffect(() => { - if (hasMount.current) { - callback(); - } else { - hasMount.current = true; - } - }, deps); -}; +import { useDidUpdate } from '../../../utils/custom-hooks'; const getConsoleFeedStyle = (theme, times, fontSize) => { const style = {}; diff --git a/client/utils/custom-hooks.js b/client/utils/custom-hooks.js new file mode 100644 index 00000000..7e0a7b8f --- /dev/null +++ b/client/utils/custom-hooks.js @@ -0,0 +1,15 @@ +import React, { useEffect, useRef } from 'react'; + +export const noop = () => {}; + +export const useDidUpdate = (callback, deps) => { + const hasMount = useRef(false); + + useEffect(() => { + if (hasMount.current) { + callback(); + } else { + hasMount.current = true; + } + }, deps); +}; From 604add5b03a18c7731062745e63b71fd0a4c7311 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Mon, 20 Jul 2020 19:11:20 -0300 Subject: [PATCH 10/16] :broom: remove FIXME --- client/components/mobile/Header.jsx | 1 - client/modules/IDE/components/Console.jsx | 1 - 2 files changed, 2 deletions(-) diff --git a/client/components/mobile/Header.jsx b/client/components/mobile/Header.jsx index e1057d0c..cf727b7c 100644 --- a/client/components/mobile/Header.jsx +++ b/client/components/mobile/Header.jsx @@ -23,7 +23,6 @@ const HeaderDiv = styled.div` justify-content: flex-start; align-items: center; - // TODO: svg { max-height: ${remSize(32)}; padding: ${remSize(4)} diff --git a/client/modules/IDE/components/Console.jsx b/client/modules/IDE/components/Console.jsx index cb2500c1..ddb6d55e 100644 --- a/client/modules/IDE/components/Console.jsx +++ b/client/modules/IDE/components/Console.jsx @@ -88,7 +88,6 @@ const Console = () => { const cm = useRef({}); - // // 2. FIXME: Console is not opening/closing, and I suspect it has to do with this useDidUpdate(() => { cm.current.scrollTop = cm.current.scrollHeight; }); const consoleClass = classNames({ From 4ac8fa0f34ed2a79f0b5a17d3cb4622f79f63e39 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 12:14:58 -0300 Subject: [PATCH 11/16] :sparkles: make console-expanding button on bottom bar --- client/components/mobile/ActionStrip.jsx | 38 ++++++++++++++++++++++ client/components/mobile/Footer.jsx | 4 ++- client/modules/IDE/pages/MobileIDEView.jsx | 11 ++++--- client/theme.js | 9 +++-- 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 client/components/mobile/ActionStrip.jsx diff --git a/client/components/mobile/ActionStrip.jsx b/client/components/mobile/ActionStrip.jsx new file mode 100644 index 00000000..27097b64 --- /dev/null +++ b/client/components/mobile/ActionStrip.jsx @@ -0,0 +1,38 @@ +import React from 'react'; +import styled from 'styled-components'; +import { bindActionCreators } from 'redux'; +import { useDispatch } from 'react-redux'; +import { prop, remSize } from '../../theme'; +import IconButton from './IconButton'; +import { ExitIcon } from '../../common/icons'; +import * as IDEActions from '../../modules/IDE/actions/ide'; + +const background = prop('MobilePanel.default.background'); +const textColor = prop('primaryTextColor'); + +const BottomBarContent = styled.h2` + padding: ${remSize(12)}; + + svg { + max-height: ${remSize(32)}; + padding: ${remSize(4)} + } +`; + +export default () => { + const { expandConsole } = bindActionCreators(IDEActions, useDispatch()); + + const actions = [{ icon: ExitIcon, aria: 'Say Something', action: expandConsole }]; + + return ( + + {actions.map(({ icon, aria, action }) => + ( action()} + />))} + + ); +}; diff --git a/client/components/mobile/Footer.jsx b/client/components/mobile/Footer.jsx index 25f10c1d..ff19eee1 100644 --- a/client/components/mobile/Footer.jsx +++ b/client/components/mobile/Footer.jsx @@ -1,6 +1,6 @@ import React from 'react'; import styled from 'styled-components'; -import { prop } from '../../theme'; +import { prop, grays } from '../../theme'; const background = prop('MobilePanel.default.background'); @@ -12,4 +12,6 @@ export default styled.div` bottom: 0; background: ${background}; color: ${textColor}; + + & > * + * { border-top: dashed 1px ${prop('Separator')} } `; diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 943c980e..43851092 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -28,12 +28,13 @@ import Footer from '../../../components/mobile/Footer'; import IDEWrapper from '../../../components/mobile/IDEWrapper'; import Console from '../components/Console'; import { remSize } from '../../../theme'; +import ActionStrip from '../../../components/mobile/ActionStrip'; const isUserOwner = ({ project, user }) => (project.owner && project.owner.id === user.id); -const BottomBarContent = styled.h2` - padding: ${remSize(12)}; - padding-left: ${remSize(32)}; + +const Expander = styled.div` + height: ${props => (props.expanded ? remSize(160) : remSize(27))}; `; const MobileIDEView = (props) => { @@ -103,8 +104,8 @@ const MobileIDEView = (props) => { />
- - Bottom Bar + {ide.consoleIsExpanded && } +
); diff --git a/client/theme.js b/client/theme.js index 4aee2a09..45f2772e 100644 --- a/client/theme.js +++ b/client/theme.js @@ -96,7 +96,8 @@ export default { background: grays.light, border: grays.middleLight, }, - } + }, + Separator: grays.middleLight, }, [Theme.dark]: { colors, @@ -136,7 +137,8 @@ export default { background: grays.dark, border: grays.middleDark, }, - } + }, + Separator: grays.middleDark, }, [Theme.contrast]: { colors, @@ -176,6 +178,7 @@ export default { background: grays.dark, border: grays.middleDark, }, - } + }, + Separator: grays.middleDark, }, }; From db5d853ff1423f376adc58b8eaecac8aa550e8f5 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 12:21:46 -0300 Subject: [PATCH 12/16] :sparkles: add console-opening button on bottom bar --- client/common/icons.jsx | 3 +++ client/components/mobile/ActionStrip.jsx | 8 ++++---- client/images/code.svg | 13 +++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/common/icons.jsx b/client/common/icons.jsx index bbc2a662..2446312e 100644 --- a/client/common/icons.jsx +++ b/client/common/icons.jsx @@ -12,6 +12,8 @@ import Exit from '../images/exit.svg'; import DropdownArrow from '../images/down-filled-triangle.svg'; import Preferences from '../images/preferences.svg'; import Play from '../images/triangle-arrow-right.svg'; +import Code from '../images/code.svg'; + // HOC that adds the right web accessibility props // https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html @@ -74,3 +76,4 @@ export const ExitIcon = withLabel(Exit); export const DropdownArrowIcon = withLabel(DropdownArrow); export const PreferencesIcon = withLabel(Preferences); export const PlayIcon = withLabel(Play); +export const CodeIcon = withLabel(Code); diff --git a/client/components/mobile/ActionStrip.jsx b/client/components/mobile/ActionStrip.jsx index 27097b64..3dfee85d 100644 --- a/client/components/mobile/ActionStrip.jsx +++ b/client/components/mobile/ActionStrip.jsx @@ -4,25 +4,25 @@ import { bindActionCreators } from 'redux'; import { useDispatch } from 'react-redux'; import { prop, remSize } from '../../theme'; import IconButton from './IconButton'; -import { ExitIcon } from '../../common/icons'; +import { CodeIcon } from '../../common/icons'; import * as IDEActions from '../../modules/IDE/actions/ide'; const background = prop('MobilePanel.default.background'); const textColor = prop('primaryTextColor'); const BottomBarContent = styled.h2` - padding: ${remSize(12)}; + padding: ${remSize(8)}; svg { max-height: ${remSize(32)}; - padding: ${remSize(4)} + /* padding: ${remSize(4)} */ } `; export default () => { const { expandConsole } = bindActionCreators(IDEActions, useDispatch()); - const actions = [{ icon: ExitIcon, aria: 'Say Something', action: expandConsole }]; + const actions = [{ icon: CodeIcon, aria: 'Say Something', action: expandConsole }]; return ( diff --git a/client/images/code.svg b/client/images/code.svg index 55337424..57f1f52c 100644 --- a/client/images/code.svg +++ b/client/images/code.svg @@ -1,8 +1,5 @@ - - - - - - - - + + + + + From c9a4d6eccce48bb0a9cc2bc7a44a23cd3457c63d Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 12:25:22 -0300 Subject: [PATCH 13/16] :broom: remove needless imports --- client/components/mobile/ActionStrip.jsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/components/mobile/ActionStrip.jsx b/client/components/mobile/ActionStrip.jsx index 3dfee85d..51dfadc9 100644 --- a/client/components/mobile/ActionStrip.jsx +++ b/client/components/mobile/ActionStrip.jsx @@ -2,20 +2,16 @@ import React from 'react'; import styled from 'styled-components'; import { bindActionCreators } from 'redux'; import { useDispatch } from 'react-redux'; -import { prop, remSize } from '../../theme'; +import { remSize } from '../../theme'; import IconButton from './IconButton'; import { CodeIcon } from '../../common/icons'; import * as IDEActions from '../../modules/IDE/actions/ide'; -const background = prop('MobilePanel.default.background'); -const textColor = prop('primaryTextColor'); - const BottomBarContent = styled.h2` padding: ${remSize(8)}; svg { max-height: ${remSize(32)}; - /* padding: ${remSize(4)} */ } `; From 482b1d9be01a1313962734c87bc890c02d29f563 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 18:01:00 -0300 Subject: [PATCH 14/16] :ok_hand: restore original code icon --- client/common/icons.jsx | 3 ++- client/components/mobile/ActionStrip.jsx | 4 ++-- client/images/code.svg | 13 ++++++++----- client/images/terminal.svg | 5 +++++ 4 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 client/images/terminal.svg diff --git a/client/common/icons.jsx b/client/common/icons.jsx index 2446312e..624f9f31 100644 --- a/client/common/icons.jsx +++ b/client/common/icons.jsx @@ -13,6 +13,7 @@ import DropdownArrow from '../images/down-filled-triangle.svg'; import Preferences from '../images/preferences.svg'; import Play from '../images/triangle-arrow-right.svg'; import Code from '../images/code.svg'; +import Terminal from '../images/terminal.svg'; // HOC that adds the right web accessibility props @@ -76,4 +77,4 @@ export const ExitIcon = withLabel(Exit); export const DropdownArrowIcon = withLabel(DropdownArrow); export const PreferencesIcon = withLabel(Preferences); export const PlayIcon = withLabel(Play); -export const CodeIcon = withLabel(Code); +export const TerminalIcon = withLabel(Terminal); diff --git a/client/components/mobile/ActionStrip.jsx b/client/components/mobile/ActionStrip.jsx index 51dfadc9..ed3f53e0 100644 --- a/client/components/mobile/ActionStrip.jsx +++ b/client/components/mobile/ActionStrip.jsx @@ -4,7 +4,7 @@ import { bindActionCreators } from 'redux'; import { useDispatch } from 'react-redux'; import { remSize } from '../../theme'; import IconButton from './IconButton'; -import { CodeIcon } from '../../common/icons'; +import { TerminalIcon } from '../../common/icons'; import * as IDEActions from '../../modules/IDE/actions/ide'; const BottomBarContent = styled.h2` @@ -18,7 +18,7 @@ const BottomBarContent = styled.h2` export default () => { const { expandConsole } = bindActionCreators(IDEActions, useDispatch()); - const actions = [{ icon: CodeIcon, aria: 'Say Something', action: expandConsole }]; + const actions = [{ icon: TerminalIcon, aria: 'Say Something', action: expandConsole }]; return ( diff --git a/client/images/code.svg b/client/images/code.svg index 57f1f52c..55337424 100644 --- a/client/images/code.svg +++ b/client/images/code.svg @@ -1,5 +1,8 @@ - - - - - + + + + + + + + diff --git a/client/images/terminal.svg b/client/images/terminal.svg new file mode 100644 index 00000000..57f1f52c --- /dev/null +++ b/client/images/terminal.svg @@ -0,0 +1,5 @@ + + + + + From f3bedb0932aba6f178642f3a3d66ad6dfee72092 Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 18:09:48 -0300 Subject: [PATCH 15/16] :ok_hand: make console button toggle between collapse and expand --- client/components/mobile/ActionStrip.jsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/components/mobile/ActionStrip.jsx b/client/components/mobile/ActionStrip.jsx index ed3f53e0..0d75a579 100644 --- a/client/components/mobile/ActionStrip.jsx +++ b/client/components/mobile/ActionStrip.jsx @@ -1,7 +1,7 @@ import React from 'react'; import styled from 'styled-components'; import { bindActionCreators } from 'redux'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { remSize } from '../../theme'; import IconButton from './IconButton'; import { TerminalIcon } from '../../common/icons'; @@ -16,9 +16,10 @@ const BottomBarContent = styled.h2` `; export default () => { - const { expandConsole } = bindActionCreators(IDEActions, useDispatch()); + const { expandConsole, collapseConsole } = bindActionCreators(IDEActions, useDispatch()); + const { consoleIsExpanded } = useSelector(state => state.ide); - const actions = [{ icon: TerminalIcon, aria: 'Say Something', action: expandConsole }]; + const actions = [{ icon: TerminalIcon, aria: 'Say Something', action: consoleIsExpanded ? collapseConsole : expandConsole }]; return ( From ccbe96dfc2cdf3d0c304882e2d195178f181358b Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Tue, 21 Jul 2020 18:18:19 -0300 Subject: [PATCH 16/16] :truck: move preferences creators to components/Preferences --- .../IDE/components/Preferences}/PreferenceCreators.jsx | 0 .../components/{Preferences.jsx => Preferences/index.jsx} | 6 +++--- client/modules/IDE/pages/IDEView.jsx | 2 +- client/modules/Mobile/MobilePreferences.jsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename client/{common/helpers => modules/IDE/components/Preferences}/PreferenceCreators.jsx (100%) rename client/modules/IDE/components/{Preferences.jsx => Preferences/index.jsx} (98%) diff --git a/client/common/helpers/PreferenceCreators.jsx b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx similarity index 100% rename from client/common/helpers/PreferenceCreators.jsx rename to client/modules/IDE/components/Preferences/PreferenceCreators.jsx diff --git a/client/modules/IDE/components/Preferences.jsx b/client/modules/IDE/components/Preferences/index.jsx similarity index 98% rename from client/modules/IDE/components/Preferences.jsx rename to client/modules/IDE/components/Preferences/index.jsx index 1a658c3c..5fd5147d 100644 --- a/client/modules/IDE/components/Preferences.jsx +++ b/client/modules/IDE/components/Preferences/index.jsx @@ -7,9 +7,9 @@ import { withTranslation } from 'react-i18next'; // import { connect } from 'react-redux'; // import * as PreferencesActions from '../actions/preferences'; -import PlusIcon from '../../../images/plus.svg'; -import MinusIcon from '../../../images/minus.svg'; -import beepUrl from '../../../sounds/audioAlert.mp3'; +import PlusIcon from '../../../../images/plus.svg'; +import MinusIcon from '../../../../images/minus.svg'; +import beepUrl from '../../../../sounds/audioAlert.mp3'; class Preferences extends React.Component { constructor(props) { diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index fbcecf1b..b28e505f 100644 --- a/client/modules/IDE/pages/IDEView.jsx +++ b/client/modules/IDE/pages/IDEView.jsx @@ -10,7 +10,7 @@ import Editor from '../components/Editor'; import Sidebar from '../components/Sidebar'; import PreviewFrame from '../components/PreviewFrame'; import Toolbar from '../components/Toolbar'; -import Preferences from '../components/Preferences'; +import Preferences from '../components/Preferences/index'; import NewFileModal from '../components/NewFileModal'; import NewFolderModal from '../components/NewFolderModal'; import UploadFileModal from '../components/UploadFileModal'; diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 7625aacd..c7991c2f 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -14,7 +14,7 @@ import Header from '../../components/mobile/Header'; import PreferencePicker from '../../components/mobile/PreferencePicker'; import { ExitIcon } from '../../common/icons'; import { remSize, prop } from '../../theme'; -import { optionsOnOff, optionsPickOne, preferenceOnOff } from '../../common/helpers/PreferenceCreators'; +import { optionsOnOff, optionsPickOne, preferenceOnOff } from '../IDE/components/Preferences/PreferenceCreators'; const Content = styled.div` z-index: 0;