Abstract color reducer into reducer-generator

This commit is contained in:
adroitwhiz 2020-04-14 16:50:55 -04:00
parent 018958ce7b
commit 7bab4d5ed8
2 changed files with 73 additions and 53 deletions

View file

@ -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;

View file

@ -1,72 +1,30 @@
import log from '../log/log'; import makeColorReducer from '../lib/make-color-reducer';
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';
const CHANGE_FILL_COLOR = 'scratch-paint/fill-color/CHANGE_FILL_COLOR'; 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 CHANGE_FILL_COLOR_2 = 'scratch-paint/fill-color/CHANGE_FILL_COLOR_2';
const DEFAULT_COLOR = '#9966FF'; const DEFAULT_COLOR = '#9966FF';
const initialState = {
primary: DEFAULT_COLOR,
secondary: null
};
// Matches hex colors const reducer = makeColorReducer({
const hexRegex = /^#([0-9a-f]{3}){1,2}$/i; changePrimaryColorAction: CHANGE_FILL_COLOR,
changeSecondaryColorAction: CHANGE_FILL_COLOR_2,
const isValidHexColor = color => { defaultColor: DEFAULT_COLOR,
if (!hexRegex.test(color) && color !== null && color !== MIXED) { selectionPrimaryColorKey: 'fillColor',
log.warn(`Invalid hex color code: ${color}`); selectionSecondaryColorKey: 'fillColor2',
return false; selectionGradientTypeKey: 'gradientType'
} });
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;
}
};
// Action creators ================================== // Action creators ==================================
const changeFillColor = function (fillColor) { const changeFillColor = function (fillColor) {
return { return {
type: CHANGE_FILL_COLOR, type: CHANGE_FILL_COLOR,
fillColor color: fillColor
}; };
}; };
const changeFillColor2 = function (fillColor) { const changeFillColor2 = function (fillColor) {
return { return {
type: CHANGE_FILL_COLOR_2, type: CHANGE_FILL_COLOR_2,
fillColor color: fillColor
}; };
}; };