From c919ce5dc8416e25413ebed363cd152c3c4ce190 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 15 Aug 2016 12:10:09 -0700 Subject: [PATCH] Feature(code-uri): Load and remove code uri on loadCode --- client/sagas/code-storage-saga.js | 21 +++++++++++++++++-- client/utils/code-uri.js | 17 ++++++++++++++- common/app/routes/challenges/redux/actions.js | 1 + common/app/routes/challenges/redux/reducer.js | 9 ++++++++ common/app/routes/challenges/redux/types.js | 1 + 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/client/sagas/code-storage-saga.js b/client/sagas/code-storage-saga.js index 440cf0a830..ce77025c28 100644 --- a/client/sagas/code-storage-saga.js +++ b/client/sagas/code-storage-saga.js @@ -1,6 +1,7 @@ import { Observable } from 'rx'; import store from 'store'; +import { removeCodeUri, getCodeUri } from '../utils/code-uri'; import { ofType } from '../../common/utils/get-actions-of-type'; import { updateContents } from '../../common/utils/polyvinyl'; import combineSagas from '../../common/utils/combine-sagas'; @@ -9,7 +10,8 @@ import { makeToast } from '../../common/app/toasts/redux/actions'; import types from '../../common/app/routes/challenges/redux/types'; import { savedCodeFound, - updateMain + updateMain, + lockUntrustedCode } from '../../common/app/routes/challenges/redux/actions'; const legacyPrefixes = [ @@ -58,7 +60,7 @@ export function saveCodeSaga(actions, getState) { }); } -export function loadCodeSaga(actions$, getState) { +export function loadCodeSaga(actions$, getState, { window, location }) { return actions$ ::ofType(types.loadCode) .flatMap(() => { @@ -71,6 +73,21 @@ export function loadCodeSaga(actions$, getState) { key } } = getState(); + const codeUriFound = getCodeUri( + location, + window.decodeURIComponent + ); + if (codeUriFound) { + finalFiles = legacyToFile(codeUriFound, files, key); + removeCodeUri(location, window.history); + return Observable.of( + lockUntrustedCode(), + makeToast({ + message: 'I found code in the URI. Loading now' + }), + savedCodeFound(finalFiles) + ); + } const codeFound = getCode(id); if (codeFound) { diff --git a/client/utils/code-uri.js b/client/utils/code-uri.js index 3622e5843c..715b034ba0 100644 --- a/client/utils/code-uri.js +++ b/client/utils/code-uri.js @@ -49,7 +49,7 @@ export function getLegacySolutionFromQuery(query = '', decode) { )(query, 'solution'); } -export function getCodeUri({ location, decodeURIComponent }) { +export function getCodeUri(location, decodeURIComponent) { let query; if ( location.search && @@ -62,3 +62,18 @@ export function getCodeUri({ location, decodeURIComponent }) { return getLegacySolutionFromQuery(query, decodeURIComponent); } + +export function removeCodeUri(location, history) { + if ( + typeof location.search.split !== 'function' || + typeof history.replaceState !== 'function' + ) { + return false; + } + history.replaceState( + history.state, + null, + location.search.split('?')[0] + ); + return true; +} diff --git a/common/app/routes/challenges/redux/actions.js b/common/app/routes/challenges/redux/actions.js index 05467fa999..0d8c291224 100644 --- a/common/app/routes/challenges/redux/actions.js +++ b/common/app/routes/challenges/redux/actions.js @@ -22,6 +22,7 @@ export const fetchChallengeCompleted = createAction( ); export const resetUi = createAction(types.resetUi); export const updateHint = createAction(types.updateHint); +export const lockUntrustedCode = createAction(types.lockUntrustedCode); export const fetchChallenges = createAction(types.fetchChallenges); export const fetchChallengesCompleted = createAction( diff --git a/common/app/routes/challenges/redux/reducer.js b/common/app/routes/challenges/redux/reducer.js index ed14c18c77..12248cc689 100644 --- a/common/app/routes/challenges/redux/reducer.js +++ b/common/app/routes/challenges/redux/reducer.js @@ -45,6 +45,7 @@ const initialUiState = { shouldShowQuestions: false }; const initialState = { + isCodeLocked: false, id: '', challenge: '', helpChatRoom: 'Help', @@ -88,6 +89,14 @@ const mainReducer = handleActions( 0 : state.hintIndex + 1 }), + [types.lockUntrustedCode]: state => ({ + ...state, + isCodeLocked: true + }), + [types.unlockCode]: state => ({ + ...state, + isCodeLocked: false + }), [types.executeChallenge]: state => ({ ...state, tests: state.tests.map(test => ({ ...test, err: false, pass: false })) diff --git a/common/app/routes/challenges/redux/types.js b/common/app/routes/challenges/redux/types.js index 5fdb679724..15e4675b99 100644 --- a/common/app/routes/challenges/redux/types.js +++ b/common/app/routes/challenges/redux/types.js @@ -17,6 +17,7 @@ export default createTypes([ 'replaceChallenge', 'resetUi', 'updateHint', + 'lockUntrustedCode', // map 'updateFilter',