Feat(Challenges): no js preview (#16149)
* 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
This commit is contained in:
committed by
Quincy Larson
parent
9051faee79
commit
2e410330f1
@@ -1,3 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
composeReducers,
|
||||
createAction,
|
||||
@@ -5,12 +6,14 @@ import {
|
||||
handleActions
|
||||
} from 'berkeleys-redux-utils';
|
||||
|
||||
import { types as app } from '../routes/Challenges/redux';
|
||||
import { themes } from '../../utils/themes';
|
||||
import { types as challenges } from '../routes/Challenges/redux';
|
||||
|
||||
export const ns = 'entities';
|
||||
export const getNS = state => state[ns];
|
||||
export const entitiesSelector = getNS;
|
||||
export const types = createTypes([
|
||||
'updateTheme',
|
||||
'updateUserFlag',
|
||||
'updateUserEmail',
|
||||
'updateUserLang',
|
||||
@@ -37,6 +40,17 @@ export const updateUserCurrentChallenge = createAction(
|
||||
types.updateUserCurrentChallenge
|
||||
);
|
||||
|
||||
// entity meta creators
|
||||
const getEntityAction = _.property('meta.entitiesAction');
|
||||
export const updateThemeMetacreator = (username, theme) => ({
|
||||
entitiesAction: {
|
||||
type: types.updateTheme,
|
||||
payload: {
|
||||
username,
|
||||
theme: !theme || theme === themes.default ? themes.default : themes.night
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const defaultState = {
|
||||
superBlock: {},
|
||||
@@ -73,33 +87,58 @@ export default composeReducers(
|
||||
}
|
||||
return state;
|
||||
},
|
||||
function(state = defaultState, action) {
|
||||
if (getEntityAction(action)) {
|
||||
const { payload: { username, theme } } = getEntityAction(action);
|
||||
return {
|
||||
...state,
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
theme
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return state;
|
||||
},
|
||||
handleActions(
|
||||
() => ({
|
||||
[
|
||||
app.submitChallenge.complete
|
||||
challenges.submitChallenge.complete
|
||||
]: (state, { payload: { username, points, challengeInfo } }) => ({
|
||||
...state,
|
||||
[username]: {
|
||||
...state[username],
|
||||
points,
|
||||
challengeMap: {
|
||||
...state[username].challengeMap,
|
||||
[challengeInfo.id]: challengeInfo
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
points,
|
||||
challengeMap: {
|
||||
...state.user[username].challengeMap,
|
||||
[challengeInfo.id]: challengeInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
[types.updateUserFlag]: (state, { payload: { username, flag } }) => ({
|
||||
...state,
|
||||
[username]: {
|
||||
...state[username],
|
||||
[flag]: !state[username][flag]
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
[flag]: !state.user[username][flag]
|
||||
}
|
||||
}
|
||||
}),
|
||||
[types.updateUserEmail]: (state, { payload: { username, email } }) => ({
|
||||
...state,
|
||||
[username]: {
|
||||
...state[username],
|
||||
email
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
email
|
||||
}
|
||||
}
|
||||
}),
|
||||
[types.updateUserLang]:
|
||||
@@ -110,9 +149,12 @@ export default composeReducers(
|
||||
}
|
||||
) => ({
|
||||
...state,
|
||||
[username]: {
|
||||
...state[username],
|
||||
languageTag
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
languageTag
|
||||
}
|
||||
}
|
||||
}),
|
||||
[types.updateUserCurrentChallenge]:
|
||||
@@ -123,9 +165,12 @@ export default composeReducers(
|
||||
}
|
||||
) => ({
|
||||
...state,
|
||||
[username]: {
|
||||
...state[username],
|
||||
currentChallengeId
|
||||
user: {
|
||||
...state.user,
|
||||
[username]: {
|
||||
...state.user[username],
|
||||
currentChallengeId
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
|
Reference in New Issue
Block a user