diff --git a/common/app/App.jsx b/common/app/App.jsx index fb5e239288..bb488ad925 100644 --- a/common/app/App.jsx +++ b/common/app/App.jsx @@ -6,7 +6,6 @@ import { createSelector } from 'reselect'; import ns from './ns.json'; import { fetchUser, - fetchYoutube, updateAppLang, trackEvent, loadCurrentChallenge, @@ -23,7 +22,6 @@ import { userSelector } from './redux/selectors'; const mapDispatchToProps = { closeDropdown, fetchUser, - fetchYoutube, loadCurrentChallenge, openDropdown, submitChallenge, @@ -37,13 +35,11 @@ const mapStateToProps = createSelector( state => state.app.isSignInAttempted, state => state.app.toast, state => state.challengesApp.toast, - state => state.entities.youtube, ( { user: { username, points, picture } }, isNavDropdownOpen, isSignInAttempted, toast, - youtube ) => ({ username, points, @@ -51,8 +47,7 @@ const mapStateToProps = createSelector( toast, isNavDropdownOpen, showLoading: !isSignInAttempted, - isSignedIn: !!username, - isYoutubeLoaded: Object.keys(youtube).length > 0 + isSignedIn: !!username }) ); @@ -60,10 +55,8 @@ const propTypes = { children: PropTypes.node, closeDropdown: PropTypes.func.isRequired, fetchUser: PropTypes.func, - fetchYoutube: PropTypes.func.isRequired, isNavDropdownOpen: PropTypes.bool, isSignedIn: PropTypes.bool, - isYoutubeLoaded: PropTypes.bool, loadCurrentChallenge: PropTypes.func.isRequired, openDropdown: PropTypes.func.isRequired, params: PropTypes.object, @@ -89,9 +82,6 @@ export class FreeCodeCamp extends React.Component { if (!this.props.isSignedIn) { this.props.fetchUser(); } - if (!this.props.isYoutubeLoaded) { - this.props.fetchYoutube(); - } } renderChallengeComplete() { diff --git a/common/app/redux/actions.js b/common/app/redux/actions.js index df30c432f9..6768f58627 100644 --- a/common/app/redux/actions.js +++ b/common/app/redux/actions.js @@ -145,9 +145,3 @@ export const addThemeToBody = createAction(types.addThemeToBody); export const openDropdown = createAction(types.openDropdown, noop); export const closeDropdown = createAction(types.closeDropdown, noop); - -export const fetchYoutube = createAction(types.fetchYoutube); -export const updateYoutube = createAction(types.updateYoutube); - -export const updateBlock = createAction(types.updateBlock); -export const updateSuperBlock = createAction(types.updateSuperBlock); diff --git a/common/app/redux/entities-reducer.js b/common/app/redux/entities-reducer.js index 8dcbb104c3..9e3df2c6c4 100644 --- a/common/app/redux/entities-reducer.js +++ b/common/app/redux/entities-reducer.js @@ -6,32 +6,9 @@ const initialState = { superBlock: {}, block: {}, challenge: {}, - user: {}, - youtube: {} + user: {} }; -const blocksReducer = handleActions( - { - [types.updateBlock]: (state, { payload }) => ({ - ...state, - block: payload - }), - [types.updateSuperBlock]: (state, { payload }) => ({ - ...state, - superBlock: payload - }) - }, initialState - ); - -const youtubeReducer = handleActions( - { - [types.updateYoutube]: (state, { payload }) => ({ - ...state, - ...payload - }) - }, initialState.youtube - ); - const userReducer = handleActions( { [types.updateUserPoints]: (state, { payload: { username, points } }) => ({ @@ -114,19 +91,8 @@ function metaReducer(state = initialState, action) { export default function entitiesReducer(state, action) { const newState = metaReducer(state, action); const user = userReducer(newState.user, action); - const youtube = youtubeReducer(newState.youtube, action); - const blocks = blocksReducer(newState, action); if (newState.user !== user) { return { ...newState, user }; } - if ( - newState.block !== blocks.block || - newState.superBlock !== blocks.superBlock - ) { - return { ...newState, ...blocks }; - } - if (newState.youtube !== youtube) { - return { ...newState, youtube }; - } return newState; } diff --git a/common/app/redux/fetch-youtube-saga.js b/common/app/redux/fetch-youtube-saga.js deleted file mode 100644 index 84bbce4cdd..0000000000 --- a/common/app/redux/fetch-youtube-saga.js +++ /dev/null @@ -1,83 +0,0 @@ -import { Observable } from 'rx'; - -import { get$ } from '../../utils/ajax-stream'; -import types from './types'; -import { - createErrorObservable, - updateBlock, - updateSuperBlock, - updateYoutube -} from './actions'; -import { - initMap, - updateSuperBlocks -} from '../routes/challenges/redux/actions'; -import { - createMapUi, - searchableChallengeTitles -} from '../routes/challenges/utils'; - -const { fetchYoutube } = types; -export default function fetchYoutubeSaga(action$, getState) { - return action$ - .filter(action => action.type === fetchYoutube) - .flatMap(() => { - const url = '/api/youtube'; - return get$(url) - // allow fetchChallenges to complete - .delay(1000) - .flatMap(result => { - const { youtube } = JSON.parse(result.response); - const store = getState(); - const { entities } = store; - const { block, superBlock } = entities; - const superBlockWithYoutube = { - ...superBlock, - youtube: { - blocks: Object.keys(youtube), - dashedName: 'youtube', - name: 'YouTube', - order: 9, - title: 'YouTube' - } - }; - const youtubeBlocks = Object.keys(youtube) - .map(playlist => youtube[playlist]) - .reduce((accu, current) => { - const videosForPlaylist = Object.keys(current.videos) - .map(video => current.videos[video].dashedName); - return { - ...accu, - [current.dashedName]: { - challenges: videosForPlaylist - } - }; - }, {}); - const blockWithYoutube = { - ...block, - ...youtubeBlocks - }; - const updatedEntities = { - ...entities, - block: blockWithYoutube, - superBlock: superBlockWithYoutube - }; - return Observable.of( - updateBlock(blockWithYoutube), - // update entities.superBlock - updateSuperBlock(superBlockWithYoutube), - // update challengesApp.superblocks - updateSuperBlocks(Object.keys(superBlockWithYoutube)), - updateYoutube(youtube), - initMap( - createMapUi( - updatedEntities, - Object.keys(superBlockWithYoutube), - searchableChallengeTitles(updatedEntities) - ) - ) - ); - }) - .catch(createErrorObservable); - }); -} diff --git a/common/app/redux/index.js b/common/app/redux/index.js index 4cf905e4d6..4f29ce7e0d 100644 --- a/common/app/redux/index.js +++ b/common/app/redux/index.js @@ -1,12 +1,10 @@ import fetchUserSaga from './fetch-user-saga'; import loadCurrentChallengeSaga from './load-current-challenge-saga'; -import fetchYoutubeSaga from './fetch-youtube-saga'; export { default as reducer } from './reducer'; export * as actions from './actions'; export { default as types } from './types'; export const sagas = [ fetchUserSaga, - loadCurrentChallengeSaga, - fetchYoutubeSaga + loadCurrentChallengeSaga ]; diff --git a/common/app/redux/types.js b/common/app/redux/types.js index aeef2b4738..766b695c85 100644 --- a/common/app/redux/types.js +++ b/common/app/redux/types.js @@ -17,12 +17,6 @@ export default createTypes([ 'loadCurrentChallenge', 'updateMyCurrentChallenge', - 'fetchYoutube', - 'updateYoutube', - - 'updateBlock', - 'updateSuperBlock', - 'handleError', // used to hit the server 'hardGoTo', diff --git a/common/app/routes/challenges/redux/actions.js b/common/app/routes/challenges/redux/actions.js index 8f1766dc70..ca411382b3 100644 --- a/common/app/routes/challenges/redux/actions.js +++ b/common/app/routes/challenges/redux/actions.js @@ -26,7 +26,6 @@ export const fetchChallengeCompleted = createAction( (_, challenge) => challenge, entities => ({ entities }) ); -export const updateSuperBlocks = createAction(types.updateSuperBlocks); export const closeChallengeModal = createAction(types.closeChallengeModal); export const resetUi = createAction(types.resetUi); export const updateHint = createAction(types.updateHint); diff --git a/common/app/routes/challenges/redux/reducer.js b/common/app/routes/challenges/redux/reducer.js index fc99eae324..cda99f4fb2 100644 --- a/common/app/routes/challenges/redux/reducer.js +++ b/common/app/routes/challenges/redux/reducer.js @@ -134,11 +134,7 @@ const mainReducer = handleActions( }), [types.fetchChallengesCompleted]: (state, { payload = [] }) => ({ ...state, - superBlocks: [ ...payload ] - }), - [types.updateSuperBlocks]: (state, { payload = [] }) => ({ - ...state, - superBlocks: [ ...payload ] + superBlocks: payload }), // step diff --git a/common/app/routes/challenges/redux/types.js b/common/app/routes/challenges/redux/types.js index 1c5ab7d2dd..d04cd0bb38 100644 --- a/common/app/routes/challenges/redux/types.js +++ b/common/app/routes/challenges/redux/types.js @@ -24,7 +24,6 @@ export default createTypes([ 'unlockUntrustedCode', 'closeChallengeModal', 'updateSuccessMessage', - 'updateSuperBlocks', // map 'updateFilter', diff --git a/common/app/routes/challenges/utils.js b/common/app/routes/challenges/utils.js index 68fb536668..c58dad00a0 100644 --- a/common/app/routes/challenges/utils.js +++ b/common/app/routes/challenges/utils.js @@ -506,7 +506,7 @@ export function applyFilterToMap(tree, filterRegex) { // if leaf (challenge) then test if regex is a match if (!Array.isArray(node.children)) { // does challenge name meet filter criteria? - if (filterRegex.test(node.title) || filterRegex.test(node.name)) { + if (filterRegex.test(node.title)) { // is challenge currently hidden? if (node.isHidden) { // unhide challenge, it matches diff --git a/common/app/routes/challenges/views/map/Header.jsx b/common/app/routes/challenges/views/map/Header.jsx index dde449eeb6..712189bdda 100644 --- a/common/app/routes/challenges/views/map/Header.jsx +++ b/common/app/routes/challenges/views/map/Header.jsx @@ -39,10 +39,6 @@ export class Header extends PureComponent { this.handleClearButton = this.handleClearButton.bind(this); } - componentWillUnmount() { - this.props.clearFilter(); - } - handleKeyDown(e) { if (e.keyCode === ESC) { e.preventDefault(); diff --git a/common/app/routes/challenges/views/map/Map.jsx b/common/app/routes/challenges/views/map/Map.jsx index e18eae07a7..e40701e45c 100644 --- a/common/app/routes/challenges/views/map/Map.jsx +++ b/common/app/routes/challenges/views/map/Map.jsx @@ -7,7 +7,6 @@ import { Col, Row } from 'react-bootstrap'; import MapHeader from './Header.jsx'; import SuperBlock from './Super-Block.jsx'; -import YoutubeSuperBlock from './youtube/YoutubeSuperBlock.jsx'; import { fetchChallenges } from '../../redux/actions'; import { updateTitle } from '../../../../redux/actions'; @@ -23,12 +22,12 @@ const fetchOptions = { }; const propTypes = { fetchChallenges: PropTypes.func.isRequired, - isYoutubeLoaded: PropTypes.bool, params: PropTypes.object, superBlocks: PropTypes.array, updateTitle: PropTypes.func.isRequired }; -class ShowMap extends PureComponent { + +export class ShowMap extends PureComponent { componentWillMount() { // if no params then map is open in drawer // do not update title @@ -44,23 +43,12 @@ class ShowMap extends PureComponent { if (!Array.isArray(superBlocks) || !superBlocks.length) { return
No videos found for this playlist
); - } - return videosArray - .map((video, i) => ( -- - - { title } - - -
- ); - } -} - -YoutubeVideo.displayName = 'YoutubeVideo'; -YoutubeVideo.propTypes = propTypes; - -export default connect( - mapStateToProps, - mapDispatchToProps -)(YoutubeVideo); diff --git a/common/app/routes/index.js b/common/app/routes/index.js index 80c31574d0..c006b3b21e 100644 --- a/common/app/routes/index.js +++ b/common/app/routes/index.js @@ -6,7 +6,6 @@ import { import NotFound from '../components/NotFound/index.jsx'; import { addLang } from '../utils/lang'; import settingsRoute from './settings'; -import youtubeRoute from './youtube'; export default function createChildRoute(deps) { return { @@ -23,7 +22,6 @@ export default function createChildRoute(deps) { modernChallengesRoute(deps), mapRoute(deps), settingsRoute(deps), - youtubeRoute(deps), { path: '*', component: NotFound diff --git a/common/app/routes/youtube/components/YoutubeVideo.jsx b/common/app/routes/youtube/components/YoutubeVideo.jsx deleted file mode 100644 index 93519abe72..0000000000 --- a/common/app/routes/youtube/components/YoutubeVideo.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { PropTypes } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import PureComponent from 'react-pure-render/component'; -import { Col } from 'react-bootstrap'; -import YouTube from 'react-youtube'; - -import { updateTitle } from '../../../redux/actions'; - -import * as styles from '../styles'; - -const mapActionsToDispatch = { - updateTitle -}; -const mapStateToProps = createSelector( - (_, props) => props.params.playlist, - (_, props) => props.params.video, - state => state.entities.youtube, - (selectedPlaylist, selectedVideo, youtube = {}) => { - const playlist = youtube[selectedPlaylist]; - return { - playlist, - video: playlist.videos[selectedVideo] - }; - } -); - -const propTypes = { - playlist: PropTypes.object, - updateTitle: PropTypes.func.isRequired, - video: PropTypes.object -}; - -class YoutubeVideo extends PureComponent { - componentWillMount() { - const { updateTitle, playlist, video } = this.props; - const title = playlist.title && video.title ? - `${playlist.title} - ${video.title}` : - 'freeCodeCamp on YouTube'; - updateTitle(title); - } - componentWillReceiveProps(nextProps) { - const { updateTitle, playlist, video } = nextProps; - if (this.props.video !== video) { - updateTitle(`${playlist.title} - ${video.title}`); - } - } - - render() { - const { - playlist: { title: playlistTitle }, - video: { - description, - title: videoTitle, - videoId - } - } = this.props; - const { - descriptionContainer, - descriptionText - } = styles; - const options = { - width: '100%', - playerVars: { autoplay: 1 } - }; - return ( -- { description } -
-