diff --git a/src/public/js/app.js b/src/public/js/app.js index c9e5b37..bec00f3 100644 --- a/src/public/js/app.js +++ b/src/public/js/app.js @@ -27,9 +27,6 @@ import { Provider, connect } from 'react-redux' import { Router } from 'react-router' import { routerActions } from 'react-router-redux' -// Root reducer -import rootReducer from './reducers/index' - // Action creators import * as actionCreators from './actions/actionCreators' @@ -39,13 +36,23 @@ import store, { history } from './store' // Components import NavBar from './components/navbar' import Alert from './components/alerts/alert' -import MovieList from './components/movies/list' -import ShowList from './components/shows/list' -import ShowDetails from './components/shows/details' -import UserLoginForm from './components/users/login' -import UserEdit from './components/users/edit' -import UserSignUp from './components/users/signup' -import TorrentList from './components/torrents/list' + +// Routes +import getRoutes from './routes' + +function mapStateToProps(state) { + return { + movieStore: state.movieStore, + showStore: state.showStore, + userStore: state.userStore, + torrentStore: state.torrentStore, + alerts: state.alerts, + } +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators(actionCreators, dispatch); +} function Main(props) { return ( @@ -65,225 +72,10 @@ function Main(props) { ); } - -function mapStateToProps(state) { - return { - movieStore: state.movieStore, - showStore: state.showStore, - userStore: state.userStore, - torrentStore: state.torrentStore, - alerts: state.alerts, - } -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators(actionCreators, dispatch); -} - -const App = connect(mapStateToProps, mapDispatchToProps)(Main); -export function startPollingTorrents() { - return request( - 'TORRENTS_FETCH', - configureAxios().get('/torrents') - ) -} - -// This function returns true if the user is logged in, false otherwise -function isLoggedIn() { - const state = store.getState(); - const isLogged = state.userStore.isLogged; - let token = localStorage.getItem('token'); - - // Let's check if the user has a token, if he does let's assume he's logged - // in. If that's not the case he will be logged out on the fisrt query - if (token && token !== "") { - store.dispatch({ - type: 'USER_SET_TOKEN', - payload: { - token: token, - }, - }); - } - - if (isLogged || (token && token !== "")) { - return true - } - - return false -} - -var pollingTorrentsId; -const loginCheck = function(nextState, replace, next, f = null) { - const loggedIn = isLoggedIn(); - if (!loggedIn) { - replace('/users/login'); - } else { - if (f) { - f(); - } - - // Poll torrents once logged - if (!pollingTorrentsId) { - // Fetch the torrents every 10s - pollingTorrentsId = setInterval(function() { - store.dispatch(actionCreators.fetchTorrents()); - }, 10000); - } - } - - next(); -} - -const defaultRoute = '/movies/explore/yts/seeds'; -const routes = { - path: '/', - component: App, - indexRoute: {onEnter: ({params}, replace) => replace(defaultRoute)}, - childRoutes: [ - { - path: '/users/signup', - component: UserSignUp - }, - { - path: '/users/login', - component: UserLoginForm, - onEnter: function(nextState, replace, next) { - if (isLoggedIn()) { - // User is already logged in, redirect him to the default route - replace(defaultRoute); - } - next(); - }, - }, - { - path: '/users/edit', - component: UserEdit, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next); - }, - }, - { - path: '/users/logout', - onEnter: function(nextState, replace, next) { - // Stop polling - if (pollingTorrentsId !== null) { - clearInterval(pollingTorrentsId); - pollingTorrentsId = null; - } - store.dispatch(actionCreators.userLogout()); - replace('/users/login'); - next(); - }, - }, - { - path: '/movies/search/:search', - component: MovieList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchMovies(`/movies/search/${nextState.params.search}`)); - }); - }, - }, - { - path: '/movies/polochon', - component: MovieList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchMovies('/movies/polochon')); - }); - }, - }, - { - path: '/movies/explore/:source/:category', - component: MovieList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - var state = store.getState(); - // Fetch the explore options - if (Object.keys(state.movieStore.exploreOptions).length === 0) { - store.dispatch(actionCreators.getMovieExploreOptions()); - } - store.dispatch(actionCreators.fetchMovies( - `/movies/explore?source=${encodeURI(nextState.params.source)}&category=${encodeURI(nextState.params.category)}` - )); - }); - }, - }, - { - path: '/movies/wishlist', - component: MovieList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchMovies('/wishlist/movies')); - }); - }, - }, - { - path: '/shows/search/:search', - component: ShowList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchShows(`/shows/search/${nextState.params.search}`)); - }); - }, - }, - { - path: '/shows/polochon', - component: ShowList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchShows('/shows/polochon')); - }); - }, - }, - { - path: '/shows/wishlist', - component: ShowList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchShows('/wishlist/shows')); - }); - }, - }, - { - path: '/shows/details/:imdbId', - component: ShowDetails, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchShows(`/shows/search/${nextState.params.imdbId}`)); - }); - }, - }, - { - path: '/shows/explore/:source/:category', - component: ShowList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - var state = store.getState(); - // Fetch the explore options - if (Object.keys(state.showStore.exploreOptions).length === 0) { - store.dispatch(actionCreators.getShowExploreOptions()); - } - store.dispatch(actionCreators.fetchShows( - `/shows/explore?source=${encodeURI(nextState.params.source)}&category=${encodeURI(nextState.params.category)}` - )); - }); - }, - }, - { - path: '/torrents', - component: TorrentList, - onEnter: function(nextState, replace, next) { - loginCheck(nextState, replace, next, function() { - store.dispatch(actionCreators.fetchTorrents()); - }); - }, - }, - ], -} +export const App = connect(mapStateToProps, mapDispatchToProps)(Main); ReactDOM.render(( - + ),document.getElementById('app')); diff --git a/src/public/js/routes.js b/src/public/js/routes.js new file mode 100644 index 0000000..7e329dd --- /dev/null +++ b/src/public/js/routes.js @@ -0,0 +1,215 @@ +import React from 'react' + +import MovieList from './components/movies/list' +import ShowList from './components/shows/list' +import ShowDetails from './components/shows/details' +import UserLoginForm from './components/users/login' +import UserEdit from './components/users/edit' +import UserSignUp from './components/users/signup' +import TorrentList from './components/torrents/list' + +import * as actionCreators from './actions/actionCreators' +import store from './store' + +function startPollingTorrents() { + return request( + 'TORRENTS_FETCH', + configureAxios().get('/torrents') + ) +} + +// This function returns true if the user is logged in, false otherwise +function isLoggedIn() { + const state = store.getState(); + const isLogged = state.userStore.isLogged; + let token = localStorage.getItem('token'); + + // Let's check if the user has a token, if he does let's assume he's logged + // in. If that's not the case he will be logged out on the fisrt query + if (token && token !== "") { + store.dispatch({ + type: 'USER_SET_TOKEN', + payload: { + token: token, + }, + }); + } + + if (isLogged || (token && token !== "")) { + return true + } + + return false +} + +var pollingTorrentsId; +const loginCheck = function(nextState, replace, next, f = null) { + const loggedIn = isLoggedIn(); + if (!loggedIn) { + replace('/users/login'); + } else { + if (f) { + f(); + } + + // Poll torrents once logged + if (!pollingTorrentsId) { + // Fetch the torrents every 10s + pollingTorrentsId = setInterval(function() { + store.dispatch(actionCreators.fetchTorrents()); + }, 10000); + } + } + + next(); +} + +const defaultRoute = '/movies/explore/yts/seeds'; +export default function getRoutes(App) { + return { + path: '/', + component: App, + indexRoute: {onEnter: ({params}, replace) => replace(defaultRoute)}, + childRoutes: [ + { + path: '/users/signup', + component: UserSignUp + }, + { + path: '/users/login', + component: UserLoginForm, + onEnter: function(nextState, replace, next) { + if (isLoggedIn()) { + // User is already logged in, redirect him to the default route + replace(defaultRoute); + } + next(); + }, + }, + { + path: '/users/edit', + component: UserEdit, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next); + }, + }, + { + path: '/users/logout', + onEnter: function(nextState, replace, next) { + // Stop polling + if (pollingTorrentsId !== null) { + clearInterval(pollingTorrentsId); + pollingTorrentsId = null; + } + store.dispatch(actionCreators.userLogout()); + replace('/users/login'); + next(); + }, + }, + { + path: '/movies/search/:search', + component: MovieList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchMovies(`/movies/search/${nextState.params.search}`)); + }); + }, + }, + { + path: '/movies/polochon', + component: MovieList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchMovies('/movies/polochon')); + }); + }, + }, + { + path: '/movies/explore/:source/:category', + component: MovieList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + var state = store.getState(); + // Fetch the explore options + if (Object.keys(state.movieStore.exploreOptions).length === 0) { + store.dispatch(actionCreators.getMovieExploreOptions()); + } + store.dispatch(actionCreators.fetchMovies( + `/movies/explore?source=${encodeURI(nextState.params.source)}&category=${encodeURI(nextState.params.category)}` + )); + }); + }, + }, + { + path: '/movies/wishlist', + component: MovieList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchMovies('/wishlist/movies')); + }); + }, + }, + { + path: '/shows/search/:search', + component: ShowList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchShows(`/shows/search/${nextState.params.search}`)); + }); + }, + }, + { + path: '/shows/polochon', + component: ShowList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchShows('/shows/polochon')); + }); + }, + }, + { + path: '/shows/wishlist', + component: ShowList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchShows('/wishlist/shows')); + }); + }, + }, + { + path: '/shows/details/:imdbId', + component: ShowDetails, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchShows(`/shows/search/${nextState.params.imdbId}`)); + }); + }, + }, + { + path: '/shows/explore/:source/:category', + component: ShowList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + var state = store.getState(); + // Fetch the explore options + if (Object.keys(state.showStore.exploreOptions).length === 0) { + store.dispatch(actionCreators.getShowExploreOptions()); + } + store.dispatch(actionCreators.fetchShows( + `/shows/explore?source=${encodeURI(nextState.params.source)}&category=${encodeURI(nextState.params.category)}` + )); + }); + }, + }, + { + path: '/torrents', + component: TorrentList, + onEnter: function(nextState, replace, next) { + loginCheck(nextState, replace, next, function() { + store.dispatch(actionCreators.fetchTorrents()); + }); + }, + }, + ], + }; +};