* fix(files): Decouple files from challenges * feat(server/react): Remove action logger use redux remote devtools instead! * feat(Challenges): Disable js on edit, enable on execute * feat(Challenge/Preview): Show message when js is disabled * refactor(frameEpic): Reduce code by using lodash * feat(frameEpic): Disable js in preview by state * feat(frameEpic): Colocate epic in Challenges/redux * refactor(ExecuteChallengeEpic): CoLocated with Challenges * refactor(executeChallengesEpic): Separate tests from main logic * feat(Challenge/Preview): Update main on edit * feat(frameEpuc): Replace frame on edit/execute This allows for sandbox to work properly * fix(Challenges/Utils): Require utisl * revert(frameEpic): Hoist function to mount code in frame * fix(frameEpic): Ensure new frame is given classname * feat(executeChallenge): Update main on code unlocked * fix(frameEpic): Filter out empty test message * fix(Challenge/Preview): Remove unnessary quote in classname * feat(codeStorageEpic): Separate localstorage from solutions loading * fix(fetchUser): Merge user actions into one prefer many effects from one action over one action to one effect * fix(themes): Centralize theme utils and defs * fix(entities.user): Fix user reducer namespacing * feat(frame): Refactor frameEpic to util * feat(Challenges.redux): Should not attempt to update main from storage * fix(loadPreviousChallengeEpic): Refactor for RFR * fix(Challenges.Modern): Show preview plane
54 lines
1.4 KiB
JavaScript
54 lines
1.4 KiB
JavaScript
import _ from 'lodash';
|
|
import {
|
|
addNS,
|
|
createTypes
|
|
} from 'berkeleys-redux-utils';
|
|
|
|
import { createPoly, setContent } from '../../utils/polyvinyl.js';
|
|
|
|
const ns = 'files';
|
|
|
|
export const types = createTypes([
|
|
'updateFile',
|
|
'createFiles'
|
|
], ns);
|
|
|
|
export const updateFileMetaCreator = (key, content)=> ({
|
|
file: { type: types.updateFile, payload: { key, content } }
|
|
});
|
|
export const createFilesMetaCreator = payload => ({
|
|
file: { type: types.createFiles, payload }
|
|
});
|
|
|
|
export const filesSelector = state => state[ns];
|
|
export const createFileSelector = keySelector => (state, props) => {
|
|
const files = filesSelector(state);
|
|
return files[keySelector(state, props)] || {};
|
|
};
|
|
|
|
const getFileAction = _.property('meta.file.type');
|
|
const getFilePayload = _.property('meta.file.payload');
|
|
|
|
export default addNS(
|
|
ns,
|
|
function reducer(state = {}, action) {
|
|
if (getFileAction(action)) {
|
|
if (getFileAction(action) === types.updateFile) {
|
|
const { key, content } = getFilePayload(action);
|
|
return {
|
|
...state,
|
|
[key]: setContent(content, state[key])
|
|
};
|
|
}
|
|
if (getFileAction(action) === types.createFiles) {
|
|
const files = getFilePayload(action);
|
|
return _.reduce(files, (files, file) => {
|
|
files[file.key] = createPoly(file);
|
|
return files;
|
|
}, { ...state });
|
|
}
|
|
}
|
|
return state;
|
|
}
|
|
);
|