Add show search

This commit is contained in:
Grégoire Delattre 2017-01-06 22:01:33 +01:00
parent 74b2f351bd
commit df58a80125
7 changed files with 68 additions and 8 deletions

View File

@ -1,6 +1,7 @@
package shows
import (
"encoding/json"
"errors"
"net/http"
@ -27,15 +28,21 @@ func GetDetailsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) err
// SearchShow will search a show
func SearchShow(env *web.Env, w http.ResponseWriter, r *http.Request) error {
key := r.FormValue("key")
if key == "" {
var data struct {
Key string `json:"key"`
}
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
return err
}
if data.Key == "" {
return env.RenderError(w, errors.New("no given key"))
}
var shows []*polochon.Show
searchers := env.Config.ShowSearchers
for _, searcher := range searchers {
result, err := searcher.SearchShow(key, env.Log)
result, err := searcher.SearchShow(data.Key, env.Log)
if err != nil {
env.Log.Errorf("error while searching show : %s", err)
continue
@ -43,7 +50,7 @@ func SearchShow(env *web.Env, w http.ResponseWriter, r *http.Request) error {
shows = append(shows, result...)
}
env.Log.Debugf("got %d shows doing search %q", len(shows), key)
env.Log.Debugf("got %d shows doing search %q", len(shows), data.Key)
showList := []*Show{}
for _, s := range shows {
show := New(s.ImdbID)

View File

@ -86,7 +86,7 @@ func main() {
env.Handle("/shows/{id:tt[0-9]+}", shows.GetDetailsHandler)
env.Handle("/shows/refresh", extmedias.RefreshShows)
env.Handle("/shows/explore", extmedias.ExploreShows)
env.Handle("/shows/search", shows.SearchShow)
env.Handle("/shows/search", shows.SearchShow).Methods("POST")
n := negroni.Classic()
n.Use(authMiddleware)

View File

@ -112,6 +112,13 @@ export function fetchShows(url) {
)
}
export function searchShows(search) {
return request(
'SEARCH_SHOWS',
configureAxios().post('/shows/search', search)
)
}
export function fetchShowDetails(imdbId) {
return request(
'SHOW_FETCH_DETAILS',

View File

@ -90,10 +90,12 @@ const MovieListSearch = (props) => (
const ShowListPopular = (props) => (
<ShowList {...props} showsUrl='/shows/explore'/>
)
const ShowDetailsView = (props) => (
<ShowDetails {...props} />
)
const ShowListSearch = (props) => (
<ShowList {...props} />
)
ReactDOM.render((
<Provider store={store}>
@ -106,6 +108,7 @@ ReactDOM.render((
<Route path="/movies/search/:search" component={UserIsAuthenticated(MovieListSearch)} />
<Route path="/movies/popular" component={UserIsAuthenticated(MovieListPopular)} />
<Route path="/movies/polochon(/:page)" component={UserIsAuthenticated(MovieListPolochon)} />
<Route path="/shows/search/:search" component={UserIsAuthenticated(ShowListSearch)} />
<Route path="/shows/popular" component={UserIsAuthenticated(ShowListPopular)} />
<Route path="/shows/details/:imdbId" component={UserIsAuthenticated(ShowDetailsView)} />
</Route>

View File

@ -10,19 +10,28 @@ export default class NavBar extends React.Component {
constructor(props) {
super(props);
this.handleMovieSearch = this.handleMovieSearch.bind(this);
this.handleShowSearch = this.handleShowSearch.bind(this);
}
handleMovieSearch() {
this.props.router.push(`/movies/search/${encodeURI(this.props.movieStore.search)}`)
}
handleShowSearch() {
this.props.router.push(`/shows/search/${encodeURI(this.props.showStore.search)}`)
}
render() {
const username = this.props.userStore.username;
const isLoggedIn = username !== "" ? true : false;
const location = this.props.router.getCurrentLocation().pathname;
let displayMovieSearch = false;
let displayShowSearch = false;
if (isLoggedIn && location.indexOf("movies") > -1)
{
displayMovieSearch = true;
}
if (isLoggedIn && location.indexOf("shows") > -1)
{
displayShowSearch = true;
}
return (
<div>
<Navbar fluid fixedTop collapseOnSelect>
@ -72,7 +81,19 @@ export default class NavBar extends React.Component {
<Control.text
model="movieStore.search"
className="form-control"
placeholder="Search"
placeholder="Search movies"
updateOn="change"
/>
</Form>
</Navbar.Form>
}
{displayShowSearch &&
<Navbar.Form pullRight>
<Form model="showStore" className="input-group" onSubmit={() => this.handleShowSearch()}>
<Control.text
model="showStore.search"
className="form-control"
placeholder="Search shows"
updateOn="change"
/>
</Form>

View File

@ -20,7 +20,24 @@ function ShowButtons(props) {
export default class ShowList extends React.Component {
componentWillMount() {
if (this.props.showsUrl) {
this.props.fetchShows(this.props.showsUrl);
} else if (this.props.params && this.props.params.search != "") {
this.props.searchShows({
key: this.props.params.search
});
}
}
componentWillUpdate(nextProps, nextState) {
if (!nextProps.params || nextProps.params.search === "") {
return
}
if (this.props.params.search === nextProps.params.search) {
return
}
this.props.searchShows({
key: nextProps.params.search
});
}
render() {
const shows = this.props.showStore.shows;

View File

@ -6,6 +6,7 @@ const defaultState = {
show: {
seasons: [],
},
search: "",
};
export default function showStore(state = defaultState, action) {
@ -25,6 +26,10 @@ export default function showStore(state = defaultState, action) {
show: sortEpisodes(action.payload.data),
})
return state;
case 'SEARCH_SHOWS_FULFILLED':
return Object.assign({}, state, {
shows: action.payload.data,
})
case 'SELECT_SHOW':
// Don't select the show if we're fetching another show's details
if (state.fetchingDetails) {