mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-23 14:02:50 -05:00
Abstract color reducer into reducer-generator
This commit is contained in:
parent
018958ce7b
commit
7bab4d5ed8
2 changed files with 73 additions and 53 deletions
62
src/lib/make-color-reducer.js
Normal file
62
src/lib/make-color-reducer.js
Normal 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;
|
|
@ -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
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue