Files
freeCodeCamp/packages/learn/src/templates/Challenges/redux/index.js

246 lines
6.9 KiB
JavaScript
Raw Normal View History

2018-04-06 14:51:52 +01:00
import { createAction, handleActions } from 'redux-actions';
import { createTypes } from '../../../../utils/stateManagment';
import { createPoly } from '../utils/polyvinyl';
import challengeModalEpic from './challenge-modal-epic';
import completionEpic from './completion-epic';
import executeChallengeEpic from './execute-challenge-epic';
import codeLockEpic from './code-lock-epic';
import createQuestionEpic from './create-question-epic';
import codeStorageEpic from './code-storage-epic';
import currentChallengeEpic from './current-challenge-epic';
2018-04-06 14:51:52 +01:00
const ns = 'challenge';
export const backendNS = 'backendChallenge';
2018-04-06 14:51:52 +01:00
const initialState = {
challengeFiles: {},
challengeMeta: {
id: '',
nextChallengePath: '/'
},
challengeTests: [],
consoleOut: '',
isCodeLocked: false,
2018-04-06 14:51:52 +01:00
isJSEnabled: true,
modal: {
completion: false,
help: false,
reset: false
2018-04-06 14:51:52 +01:00
},
2018-05-24 19:45:38 +01:00
projectFormVaules: {},
2018-04-06 14:51:52 +01:00
successMessage: 'Happy Coding!'
};
export const epics = [
challengeModalEpic,
codeLockEpic,
completionEpic,
createQuestionEpic,
executeChallengeEpic,
codeStorageEpic,
currentChallengeEpic
];
2018-04-06 14:51:52 +01:00
export const types = createTypes(
[
'createFiles',
'createQuestion',
2018-04-06 14:51:52 +01:00
'initTests',
'initConsole',
'updateConsole',
'updateChallengeMeta',
'updateFile',
'updateJSEnabled',
2018-05-24 19:45:38 +01:00
'updateProjectFormValues',
2018-04-06 14:51:52 +01:00
'updateSuccessMessage',
'updateTests',
'lockCode',
'unlockCode',
2018-04-06 14:51:52 +01:00
'disableJSOnError',
'storedCodeFound',
'noStoredCodeFound',
2018-04-06 14:51:52 +01:00
'closeModal',
'openModal',
'challengeMounted',
2018-04-06 14:51:52 +01:00
'checkChallenge',
'executeChallenge',
'resetChallenge',
'submitChallenge',
'submitComplete'
2018-04-06 14:51:52 +01:00
],
ns
);
export const createFiles = createAction(types.createFiles, challengeFiles =>
Object.keys(challengeFiles)
.filter(key => challengeFiles[key])
.map(key => challengeFiles[key])
.reduce(
(challengeFiles, file) => ({
...challengeFiles,
[file.key]: {
...createPoly(file),
seed: file.contents.slice(0)
}
}),
{}
)
);
export const createQuestion = createAction(types.createQuestion);
2018-04-06 14:51:52 +01:00
export const initTests = createAction(types.initTests);
export const updateTests = createAction(types.updateTests);
export const initConsole = createAction(types.initConsole);
export const updateChallengeMeta = createAction(types.updateChallengeMeta);
export const updateFile = createAction(types.updateFile);
export const updateConsole = createAction(types.updateConsole);
export const updateJSEnabled = createAction(types.updateJSEnabled);
2018-05-24 19:45:38 +01:00
export const updateProjectFormValues = createAction(
types.updateProjectFormValues
);
2018-04-06 14:51:52 +01:00
export const updateSuccessMessage = createAction(types.updateSuccessMessage);
export const lockCode = createAction(types.lockCode);
export const unlockCode = createAction(types.unlockCode);
export const disableJSOnError = createAction(types.disableJSOnError);
export const storedCodeFound = createAction(types.storedCodeFound);
export const noStoredCodeFound = createAction(types.noStoredCodeFound);
2018-04-06 14:51:52 +01:00
export const closeModal = createAction(types.closeModal);
export const openModal = createAction(types.openModal);
export const challengeMounted = createAction(types.challengeMounted);
2018-04-06 14:51:52 +01:00
export const checkChallenge = createAction(types.checkChallenge);
export const executeChallenge = createAction(types.executeChallenge);
export const resetChallenge = createAction(types.resetChallenge);
2018-04-06 14:51:52 +01:00
export const submitChallenge = createAction(types.submitChallenge);
export const submitComplete = createAction(types.submitComplete);
2018-04-06 14:51:52 +01:00
export const challengeFilesSelector = state => state[ns].challengeFiles;
export const challengeMetaSelector = state => state[ns].challengeMeta;
export const challengeTestsSelector = state => state[ns].challengeTests;
export const consoleOutputSelector = state => state[ns].consoleOut;
export const isCodeLockedSelector = state => state[ns].isCodeLocked;
2018-04-06 14:51:52 +01:00
export const isCompletionModalOpenSelector = state =>
2018-04-11 14:51:47 +01:00
state[ns].modal.completion;
export const isHelpModalOpenSelector = state => state[ns].modal.help;
export const isResetModalOpenSelector = state => state[ns].modal.reset;
2018-04-11 14:43:23 +01:00
export const isJSEnabledSelector = state => state[ns].isJSEnabled;
2018-04-06 14:51:52 +01:00
export const successMessageSelector = state => state[ns].successMessage;
2018-05-24 19:45:38 +01:00
export const backendFormValuesSelector = state => state.form[backendNS];
export const projectFormVaulesSelector = state =>
state[ns].projectFormVaules || {};
2018-04-06 14:51:52 +01:00
export const reducer = handleActions(
{
[types.createFiles]: (state, { payload }) => ({
...state,
challengeFiles: payload
}),
[types.updateFile]: (state, { payload: { key, editorValue } }) => ({
...state,
challengeFiles: {
...state.challengeFiles,
[key]: {
...state.challengeFiles[key],
contents: editorValue
}
}
}),
[types.storedCodeFound]: (state, { payload }) => ({
...state,
challengeFiles: payload
}),
2018-04-06 14:51:52 +01:00
[types.initTests]: (state, { payload }) => ({
...state,
challengeTests: payload
}),
[types.updateTests]: (state, { payload }) => ({
...state,
challengeTests: payload
}),
2018-04-06 14:51:52 +01:00
[types.initConsole]: (state, { payload }) => ({
...state,
consoleOut: payload
}),
[types.updateConsole]: (state, { payload }) => ({
...state,
consoleOut: state.consoleOut + '\n' + payload
}),
[types.updateChallengeMeta]: (state, { payload }) => ({
...state,
challengeMeta: { ...payload }
}),
[types.resetChallenge]: state => ({
2018-04-06 14:51:52 +01:00
...state,
challengeFiles: {
...Object.keys(state.challengeFiles)
.map(key => state.challengeFiles[key])
.reduce(
(files, file) => ({
...files,
[file.key]: {
...file,
contents: file.seed.slice()
}
}),
{}
)
},
challengeTests: state.challengeTests.map(({ text, testString }) => ({
text,
testString
})),
consoleOut: ''
2018-04-06 14:51:52 +01:00
}),
2018-05-24 19:45:38 +01:00
[types.updateProjectFormValues]: (state, { payload }) => ({
...state,
projectFormVaules: payload
}),
[types.lockCode]: state => ({
...state,
isCodeLocked: true
}),
[types.unlockCode]: state => ({
...state,
isJSEnabled: true,
isCodeLocked: false
}),
[types.disableJSOnError]: (state, { payload }) => ({
2018-04-06 14:51:52 +01:00
...state,
consoleOut: state.consoleOut + '\n' + payload,
2018-04-06 14:51:52 +01:00
isJSEnabled: false
}),
2018-04-06 14:51:52 +01:00
[types.updateSuccessMessage]: (state, { payload }) => ({
...state,
successMessage: payload
}),
[types.closeModal]: (state, { payload }) => ({
...state,
modal: {
...state.modal,
[payload]: false
}
}),
[types.openModal]: (state, { payload }) => ({
...state,
modal: {
...state.modal,
[payload]: true
}
})
},
initialState
);