From 74ff77a38d8e06f916a83eab2a102ac278399f15 Mon Sep 17 00:00:00 2001 From: DD Date: Thu, 7 Sep 2017 17:59:14 -0400 Subject: [PATCH] add stroke color to state --- src/components/paint-editor.jsx | 25 ++---------- src/components/stroke-color-indicator.jsx | 38 ++++++++++++++++++ src/containers/stroke-color-indicator.jsx | 31 +++++++++++++++ src/reducers/color.js | 8 ++++ src/reducers/stroke-color.js | 33 ++++++++++++++++ test/unit/stroke-color-reducer.test.js | 48 +++++++++++++++++++++++ 6 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 src/components/stroke-color-indicator.jsx create mode 100644 src/containers/stroke-color-indicator.jsx create mode 100644 src/reducers/color.js create mode 100644 src/reducers/stroke-color.js create mode 100644 test/unit/stroke-color-reducer.test.js diff --git a/src/components/paint-editor.jsx b/src/components/paint-editor.jsx index 8558a140..31dfab59 100644 --- a/src/components/paint-editor.jsx +++ b/src/components/paint-editor.jsx @@ -6,6 +6,7 @@ import EraserMode from '../containers/eraser-mode.jsx'; import PropTypes from 'prop-types'; import LineMode from '../containers/line-mode.jsx'; import FillColorIndicatorComponent from '../containers/fill-color-indicator.jsx'; +import StrokeColorIndicatorComponent from '../containers/stroke-color-indicator.jsx'; import {defineMessages, injectIntl, intlShape} from 'react-intl'; import BufferedInputHOC from './forms/buffered-input-hoc.jsx'; @@ -20,16 +21,6 @@ const messages = defineMessages({ id: 'paint.paintEditor.costume', description: 'Label for the name of a sound', defaultMessage: 'Costume' - }, - fill: { - id: 'paint.paintEditor.fill', - description: 'Label for the color picker for the fill color', - defaultMessage: 'Fill' - }, - outline: { - id: 'paint.paintEditor.outline', - description: 'Label for the color picker for the outline color', - defaultMessage: 'Outline' } }); @@ -107,18 +98,10 @@ class PaintEditorComponent extends React.Component { {/* Second Row */}
- {/* To be fill */} + {/* fill */} - {/* To be stroke */} -
- -
+ {/* stroke */} +
Mode tools diff --git a/src/components/stroke-color-indicator.jsx b/src/components/stroke-color-indicator.jsx new file mode 100644 index 00000000..91478c43 --- /dev/null +++ b/src/components/stroke-color-indicator.jsx @@ -0,0 +1,38 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import {defineMessages, injectIntl, intlShape} from 'react-intl'; +import BufferedInputHOC from './forms/buffered-input-hoc.jsx'; +import Label from './forms/label.jsx'; +import Input from './forms/input.jsx'; + +import styles from './paint-editor.css'; + +const BufferedInput = BufferedInputHOC(Input); +const messages = defineMessages({ + stroke: { + id: 'paint.paintEditor.stroke', + description: 'Label for the color picker for the outline color', + defaultMessage: 'Outline' + } +}); +const StrokeColorIndicatorComponent = props => ( +
+ +
+); + +StrokeColorIndicatorComponent.propTypes = { + intl: intlShape, + onChangeStrokeColor: PropTypes.func.isRequired, + strokeColor: PropTypes.string.isRequired +}; + +export default injectIntl(StrokeColorIndicatorComponent); diff --git a/src/containers/stroke-color-indicator.jsx b/src/containers/stroke-color-indicator.jsx new file mode 100644 index 00000000..7e4baf67 --- /dev/null +++ b/src/containers/stroke-color-indicator.jsx @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {connect} from 'react-redux'; +import {changeStrokeColor} from '../reducers/stroke-color'; +import StrokeColorIndicatorComponent from '../components/stroke-color-indicator.jsx'; + +const StrokeColorIndicator = props => ( + +); + +StrokeColorIndicator.propTypes = { + handleChangeStrokeColor: PropTypes.func.isRequired, + strokeColor: PropTypes.string.isRequired +}; + +const mapStateToProps = state => ({ + strokeColor: state.scratchPaint.color.strokeColor +}); +const mapDispatchToProps = dispatch => ({ + handleChangeStrokeColor: strokeColor => { + dispatch(changeStrokeColor(strokeColor)); + } +}); + +export default connect( + mapStateToProps, + mapDispatchToProps +)(StrokeColorIndicator); diff --git a/src/reducers/color.js b/src/reducers/color.js new file mode 100644 index 00000000..62bba3a1 --- /dev/null +++ b/src/reducers/color.js @@ -0,0 +1,8 @@ +import {combineReducers} from 'redux'; +import fillColorReducer from './fill-color'; +import strokeColorReducer from './stroke-color'; + +export default combineReducers({ + fillColor: fillColorReducer, + strokeColor: strokeColorReducer +}); diff --git a/src/reducers/stroke-color.js b/src/reducers/stroke-color.js new file mode 100644 index 00000000..15efc21e --- /dev/null +++ b/src/reducers/stroke-color.js @@ -0,0 +1,33 @@ +import log from '../log/log'; + +const CHANGE_STROKE_COLOR = 'scratch-paint/stroke-color/CHANGE_STROKE_COLOR'; +const initialState = '#000'; +// Matches hex colors +const regExp = /^#([0-9a-f]{3}){1,2}$/i; + +const reducer = function (state, action) { + if (typeof state === 'undefined') state = initialState; + switch (action.type) { + case CHANGE_STROKE_COLOR: + if (!regExp.test(action.strokeColor)) { + log.warn(`Invalid hex color code: ${action.fillColor}`); + return state; + } + return action.strokeColor; + default: + return state; + } +}; + +// Action creators ================================== +const changeStrokeColor = function (strokeColor) { + return { + type: CHANGE_STROKE_COLOR, + strokeColor: strokeColor + }; +}; + +export { + reducer as default, + changeStrokeColor +}; diff --git a/test/unit/stroke-color-reducer.test.js b/test/unit/stroke-color-reducer.test.js new file mode 100644 index 00000000..7f812299 --- /dev/null +++ b/test/unit/stroke-color-reducer.test.js @@ -0,0 +1,48 @@ +/* eslint-env jest */ +import strokeColorReducer from '../../src/reducers/stroke-color'; +import {changeStrokeColor} from '../../src/reducers/stroke-color'; + +test('initialState', () => { + let defaultState; + + expect(strokeColorReducer(defaultState /* state */, {type: 'anything'} /* action */)).toBeDefined(); +}); + +test('changeStrokeColor', () => { + let defaultState; + + // 3 value hex code + let newStrokeColor = '#fff'; + expect(strokeColorReducer(defaultState /* state */, changeStrokeColor(newStrokeColor) /* action */)) + .toEqual(newStrokeColor); + expect(strokeColorReducer('#010' /* state */, changeStrokeColor(newStrokeColor) /* action */)) + .toEqual(newStrokeColor); + + // 6 value hex code + newStrokeColor = '#facade'; + expect(strokeColorReducer(defaultState /* state */, changeStrokeColor(newStrokeColor) /* action */)) + .toEqual(newStrokeColor); + expect(strokeColorReducer('#010' /* state */, changeStrokeColor(newStrokeColor) /* action */)) + .toEqual(newStrokeColor); +}); + +test('invalidChangeStrokeColor', () => { + const origState = '#fff'; + + expect(strokeColorReducer(origState /* state */, changeStrokeColor() /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#1') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#12') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#1234') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#12345') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('#1234567') /* action */)) + .toBe(origState); + expect(strokeColorReducer(origState /* state */, changeStrokeColor('invalid argument') /* action */)) + .toBe(origState); +});