From 7bab4d5ed8734b792f678238d10d458ba9c956c2 Mon Sep 17 00:00:00 2001 From: adroitwhiz Date: Tue, 14 Apr 2020 16:50:55 -0400 Subject: [PATCH] Abstract color reducer into reducer-generator --- src/lib/make-color-reducer.js | 62 +++++++++++++++++++++++++++++++++ src/reducers/fill-color.js | 64 ++++++----------------------------- 2 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 src/lib/make-color-reducer.js diff --git a/src/lib/make-color-reducer.js b/src/lib/make-color-reducer.js new file mode 100644 index 00000000..786f24ca --- /dev/null +++ b/src/lib/make-color-reducer.js @@ -0,0 +1,62 @@ +import log from '../log/log'; +import {CHANGE_SELECTED_ITEMS} from '../reducers/selected-items'; +import {CLEAR_GRADIENT} from '../reducers/selection-gradient-type'; +import {getColorsFromSelection, MIXED} from '../helper/style-path'; +import GradientTypes from './gradient-types'; + +// Matches hex colors +const hexRegex = /^#([0-9a-f]{3}){1,2}$/i; + +const isValidHexColor = color => { + if (!hexRegex.test(color) && color !== null && color !== MIXED) { + log.warn(`Invalid hex color code: ${color}`); + return false; + } + return true; +}; + +const makeColorReducer = ({ + changePrimaryColorAction, + changeSecondaryColorAction, + defaultColor, + selectionPrimaryColorKey, + selectionSecondaryColorKey, + selectionGradientTypeKey +}) => function colorReducer (state, action) { + if (typeof state === 'undefined') { + state = { + primary: defaultColor, + secondary: null + }; + } + switch (action.type) { + case changePrimaryColorAction: + if (!isValidHexColor(action.color)) return state; + return {...state, primary: action.color}; + case changeSecondaryColorAction: + if (!isValidHexColor(action.color)) return state; + return {...state, secondary: action.color}; + case CHANGE_SELECTED_ITEMS: { + // Don't change state if no selection + if (!action.selectedItems || !action.selectedItems.length) { + return state; + } + const colors = getColorsFromSelection(action.selectedItems, action.bitmapMode); + + const newState = {...state, primary: colors[selectionPrimaryColorKey]}; + + // Gradient type may be solid when multiple gradient types are selected. + // In this case, changing the first color should not change the second color. + if (colors[selectionGradientTypeKey] !== GradientTypes.SOLID || colors[selectionSecondaryColorKey] === MIXED) { + newState.secondary = colors[selectionSecondaryColorKey]; + } + return newState; + } + case CLEAR_GRADIENT: + return {...state, secondary: null}; + default: + return state; + } +}; + +export default makeColorReducer; diff --git a/src/reducers/fill-color.js b/src/reducers/fill-color.js index 795c87bb..4c234b66 100644 --- a/src/reducers/fill-color.js +++ b/src/reducers/fill-color.js @@ -1,72 +1,30 @@ -import log from '../log/log'; -import {CHANGE_SELECTED_ITEMS} from './selected-items'; -import {CLEAR_GRADIENT} from './selection-gradient-type'; -import {getColorsFromSelection, MIXED} from '../helper/style-path'; -import GradientTypes from '../lib/gradient-types'; +import makeColorReducer from '../lib/make-color-reducer'; const CHANGE_FILL_COLOR = 'scratch-paint/fill-color/CHANGE_FILL_COLOR'; const CHANGE_FILL_COLOR_2 = 'scratch-paint/fill-color/CHANGE_FILL_COLOR_2'; const DEFAULT_COLOR = '#9966FF'; -const initialState = { - primary: DEFAULT_COLOR, - secondary: null -}; -// Matches hex colors -const hexRegex = /^#([0-9a-f]{3}){1,2}$/i; - -const isValidHexColor = color => { - if (!hexRegex.test(color) && color !== null && color !== MIXED) { - log.warn(`Invalid hex color code: ${color}`); - return false; - } - return true; -}; - -const reducer = function (state, action) { - if (typeof state === 'undefined') state = initialState; - switch (action.type) { - case CHANGE_FILL_COLOR: - if (!isValidHexColor(action.fillColor)) return state; - return {...state, primary: action.fillColor}; - case CHANGE_FILL_COLOR_2: - if (!isValidHexColor(action.fillColor)) return state; - return {...state, secondary: action.fillColor}; - case CHANGE_SELECTED_ITEMS: { - // Don't change state if no selection - if (!action.selectedItems || !action.selectedItems.length) { - return state; - } - const colors = getColorsFromSelection(action.selectedItems, action.bitmapMode); - - const newState = {...state, primary: colors.fillColor}; - - // Gradient type may be solid when multiple gradient types are selected. - // In this case, changing the first color should not change the second color. - if (colors.gradientType !== GradientTypes.SOLID || colors.fillColor2 === MIXED) { - newState.secondary = colors.fillColor2; - } - return newState; - } - case CLEAR_GRADIENT: - return {...state, secondary: null}; - default: - return state; - } -}; +const reducer = makeColorReducer({ + changePrimaryColorAction: CHANGE_FILL_COLOR, + changeSecondaryColorAction: CHANGE_FILL_COLOR_2, + defaultColor: DEFAULT_COLOR, + selectionPrimaryColorKey: 'fillColor', + selectionSecondaryColorKey: 'fillColor2', + selectionGradientTypeKey: 'gradientType' +}); // Action creators ================================== const changeFillColor = function (fillColor) { return { type: CHANGE_FILL_COLOR, - fillColor + color: fillColor }; }; const changeFillColor2 = function (fillColor) { return { type: CHANGE_FILL_COLOR_2, - fillColor + color: fillColor }; };