implement the random location
This commit is contained in:
parent
6e6af71ad1
commit
aa65fa4b11
|
@ -3,6 +3,13 @@ export const START_LOADING_ALL_TOPICS = 'START_LOADING_ALL_TOPICS';
|
||||||
export const LOADED_ALL_TOPICS = 'LOADED_ALL_TOPICS';
|
export const LOADED_ALL_TOPICS = 'LOADED_ALL_TOPICS';
|
||||||
export const START_LOADING_RANDOM_TOPIC = 'START_LOADING_RANDOM_TOPIC';
|
export const START_LOADING_RANDOM_TOPIC = 'START_LOADING_RANDOM_TOPIC';
|
||||||
export const LOADED_RANDOM_TOPIC = 'LOADED_RANDOM_TOPIC';
|
export const LOADED_RANDOM_TOPIC = 'LOADED_RANDOM_TOPIC';
|
||||||
|
// Locations/Places
|
||||||
|
|
||||||
|
// Places Action Types
|
||||||
|
export const START_LOADING_ALL_PLACES = 'START_LOADING_ALL_PLACES';
|
||||||
|
export const LOADED_ALL_PLACES = 'LOADED_ALL_PLACES';
|
||||||
|
export const START_LOADING_RANDOM_PLACE = 'START_LOADING_RANDOM_PLACE';
|
||||||
|
export const LOADED_RANDOM_PLACE = 'LOADED_RANDOM_PLACE';
|
||||||
|
|
||||||
// Videos Action Types
|
// Videos Action Types
|
||||||
export const ADD_VIDEOS_TO_STATE = 'ADD_VIDEOS_TO_STATE';
|
export const ADD_VIDEOS_TO_STATE = 'ADD_VIDEOS_TO_STATE';
|
||||||
|
|
70
src/actions/places.js
Normal file
70
src/actions/places.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import { fetchPlaces, fetchVideosByPlace } from '../utils/api';
|
||||||
|
import { APIError } from './errors';
|
||||||
|
import { getItem, setItem } from '../utils/safe-storage';
|
||||||
|
import getRandomTopic from '../utils/get-random-place';
|
||||||
|
import { addVideosToState } from './videos';
|
||||||
|
import {
|
||||||
|
START_LOADING_ALL_PLACES,
|
||||||
|
LOADED_ALL_PLACES,
|
||||||
|
START_LOADING_RANDOM_PLACE,
|
||||||
|
LOADED_RANDOM_PLACE
|
||||||
|
} from './action_types';
|
||||||
|
|
||||||
|
export function getAllPlaces() {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(startLoadingAllPlaces());
|
||||||
|
// this calls the API
|
||||||
|
fetchPlaces()
|
||||||
|
.then(places => {
|
||||||
|
dispatch(loadedPlaces(places));
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch(APIError(error));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function startLoadingAllPlaces() {
|
||||||
|
return {
|
||||||
|
type: START_LOADING_ALL_PLACES
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadedPlaces(places) {
|
||||||
|
// cache
|
||||||
|
setItem('allPlaces', JSON.stringify(places));
|
||||||
|
setItem('placesUpdatedAt', new Date());
|
||||||
|
return {
|
||||||
|
type: LOADED_ALL_PLACES,
|
||||||
|
payload: places
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// actions :
|
||||||
|
// - async actions
|
||||||
|
// - simple: return action type and payload.
|
||||||
|
export function getRandomPlaceVideos(allPlaces, numVideos=3) {
|
||||||
|
return dispatch => {
|
||||||
|
const randomTopic = getRandomTopic(allPlaces);
|
||||||
|
dispatch(loadingRandomTopicVideos());
|
||||||
|
fetchVideosByPlace(randomTopic.name, 0, numVideos)
|
||||||
|
.then(videos => {
|
||||||
|
dispatch(addVideosToState(videos));
|
||||||
|
dispatch(loadedRandomTopicVideos(randomTopic, videos));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadedRandomTopicVideos(place, videos) {
|
||||||
|
return {
|
||||||
|
type: LOADED_RANDOM_PLACE,
|
||||||
|
payload: {
|
||||||
|
place: place,
|
||||||
|
videos: videos
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadingRandomTopicVideos() {
|
||||||
|
return {
|
||||||
|
type: START_LOADING_RANDOM_PLACE
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,24 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import VideoItem from "./VideoItem";
|
|
||||||
import Grid from 'react-css-grid'
|
|
||||||
import SectionHeading from "./SectionHeading";
|
|
||||||
|
|
||||||
class RandomLocation extends React.Component {
|
|
||||||
render() {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<SectionHeading title="Random Location"/>
|
|
||||||
<Grid
|
|
||||||
width={225}
|
|
||||||
gap={24}>
|
|
||||||
<VideoItem/>
|
|
||||||
<VideoItem/>
|
|
||||||
<VideoItem/>
|
|
||||||
</Grid>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (RandomLocation);
|
|
62
src/components/RandomPlace.js
Normal file
62
src/components/RandomPlace.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import Grid from 'react-css-grid'
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import VideoItem from "./VideoItem";
|
||||||
|
import RandomItemTitle from "./SectionHeading";
|
||||||
|
import {Link} from 'react-router-dom';
|
||||||
|
|
||||||
|
class RandomPlace extends React.Component {
|
||||||
|
|
||||||
|
shufflePlace() {
|
||||||
|
this.props.getRandomPlaceVideos(this.props.allPlaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<h2 className="section-heading">from the Archive Places - من مواضيع الارشيف</h2>
|
||||||
|
<RandomItemTitle title={this.props.placeName}
|
||||||
|
count={this.props.placeCount}
|
||||||
|
src={'/results/place/' + this.props.placeName}
|
||||||
|
/>
|
||||||
|
<Grid
|
||||||
|
width={450}
|
||||||
|
>
|
||||||
|
{/* View all places button*/}
|
||||||
|
<Link to="/places">
|
||||||
|
<button className="view-all-places">
|
||||||
|
<span className="english-text">All Places - </span>
|
||||||
|
<span className="arabic-text"> جميع الأماكن </span>
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
{/* Shuffle button */}
|
||||||
|
<button className="shuffle-button" onClick={this.shufflePlace.bind(this)}>
|
||||||
|
<span className="english-text">Shuffle Places - </span>
|
||||||
|
<span className="arabic-text"> موضوع عشوائي </span>
|
||||||
|
<i className="fa fa-random"></i>
|
||||||
|
</button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid className="random-places"
|
||||||
|
width={220}
|
||||||
|
gap={12}>
|
||||||
|
{this.props.videos.map(video =>
|
||||||
|
<VideoItem id={video.id} key={video.id} title={video.title}/>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomPlace.propTypes = {
|
||||||
|
placeName: PropTypes.string,
|
||||||
|
allPlaces: PropTypes.array,
|
||||||
|
videos: PropTypes.array,
|
||||||
|
loading: PropTypes.bool,
|
||||||
|
placeCount: PropTypes.number,
|
||||||
|
getRandomPlaceVideos: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (RandomPlace);
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { getAllTopics, getRandomTopicVideos } from '../actions/topics';
|
import {getAllTopics, getRandomTopicVideos} from '../actions/topics';
|
||||||
import RandomLocation from "../components/RandomLocation";
|
import {getAllPlaces, getRandomPlaceVideos} from '../actions/places';
|
||||||
|
import RandomPlace from "../components/RandomPlace";
|
||||||
import RandomDate from "../components/RandomDate";
|
import RandomDate from "../components/RandomDate";
|
||||||
import RandomTopic from "../components/RandomTopic";
|
import RandomTopic from "../components/RandomTopic";
|
||||||
|
|
||||||
|
@ -12,6 +13,12 @@ class Home extends React.Component {
|
||||||
} else {
|
} else {
|
||||||
this.props.getAllTopics();
|
this.props.getAllTopics();
|
||||||
}
|
}
|
||||||
|
// places
|
||||||
|
if (this.props.allPlaces && this.props.allPlaces.length > 0 && !this.props.randomPlace) {
|
||||||
|
this.props.getRandomPlaceVideos()(this.props.allPlaces);
|
||||||
|
} else {
|
||||||
|
this.props.getAllPlaces();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
@ -20,20 +27,31 @@ class Home extends React.Component {
|
||||||
if ((this.props.allTopics || nextProps.allTopics) && !this.props.loadingRandomTopic && !nextProps.loadingRandomTopic && !this.props.randomTopic) {
|
if ((this.props.allTopics || nextProps.allTopics) && !this.props.loadingRandomTopic && !nextProps.loadingRandomTopic && !this.props.randomTopic) {
|
||||||
this.props.getRandomTopicVideos(nextProps.allTopics);
|
this.props.getRandomTopicVideos(nextProps.allTopics);
|
||||||
}
|
}
|
||||||
|
// places
|
||||||
|
if ((this.props.allPlaces || nextProps.allPlaces) && !this.props.loadingRandomPlace && !nextProps.loadingRandomPlace && !this.props.randomPlace) {
|
||||||
|
this.props.getRandomPlaceVideos()(nextProps.allPlaces);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<RandomTopic
|
<RandomTopic
|
||||||
topicName={ this.props.randomTopic || ''}
|
topicName={this.props.randomTopic || ''}
|
||||||
allTopics={ this.props.allTopics || [] }
|
allTopics={this.props.allTopics || []}
|
||||||
topicCount={ this.props.randomTopicCount }
|
topicCount={this.props.randomTopicCount}
|
||||||
videos = { this.props.randomTopicVideos || [] }
|
videos={this.props.randomTopicVideos || []}
|
||||||
loading = { this.props.loadingAllTopics || this.props.loadingRandomTopic }
|
loading={this.props.loadingAllTopics || this.props.loadingRandomTopic}
|
||||||
getRandomTopicVideos={ this.props.getRandomTopicVideos }
|
getRandomTopicVideos={this.props.getRandomTopicVideos}
|
||||||
|
/>
|
||||||
|
<RandomPlace
|
||||||
|
placeName={this.props.randomPlace || ''}
|
||||||
|
allPlaces={this.props.allPlaces || []}
|
||||||
|
placeCount={this.props.randomPlaceCount}
|
||||||
|
videos={this.props.randomPlaceVideos || []}
|
||||||
|
loading={this.props.loadingAllPlaces || this.props.loadingRandomPlace}
|
||||||
|
getRandomPlaceVideos={this.props.getRandomPlaceVideos}
|
||||||
/>
|
/>
|
||||||
<RandomLocation/>
|
|
||||||
<RandomDate/>
|
<RandomDate/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -46,12 +64,23 @@ const mapStateToProps = state => ({
|
||||||
randomTopic: state.topics.randomTopic,
|
randomTopic: state.topics.randomTopic,
|
||||||
randomTopicCount: state.topics.randomTopicCount,
|
randomTopicCount: state.topics.randomTopicCount,
|
||||||
loadingRandomTopic: state.topics.loadingRandomTopic,
|
loadingRandomTopic: state.topics.loadingRandomTopic,
|
||||||
randomTopicVideos: state.topics.randomTopicVideos
|
randomTopicVideos: state.topics.randomTopicVideos,
|
||||||
|
// places
|
||||||
|
allPlaces: state.topics.allPlaces,
|
||||||
|
loadingAllPlaces: state.topics.loadingAllPlaces,
|
||||||
|
randomPlace: state.topics.randomPlace,
|
||||||
|
randomPlaceCount: state.topics.randomPlaceCount,
|
||||||
|
loadingRandomPlace: state.topics.loadingRandomPlace,
|
||||||
|
randomPlaceVideos: state.topics.randomPlaceVideos,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
getAllTopics: () => dispatch(getAllTopics()),
|
getAllTopics: () => dispatch(getAllTopics()),
|
||||||
getRandomTopicVideos: allTopics => dispatch(getRandomTopicVideos(allTopics))
|
getRandomTopicVideos: allTopics => dispatch(getRandomTopicVideos(allTopics)),
|
||||||
|
// places
|
||||||
|
getAllPlaces: () => dispatch(getAllPlaces()),
|
||||||
|
getRandomPlaceVideos: allTopics => dispatch(getRandomPlaceVideos(allTopics)),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Home);
|
export default connect(mapStateToProps, mapDispatchToProps)(Home);
|
5
src/utils/get-random-place.js
Normal file
5
src/utils/get-random-place.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
export default function getRandomPlace(allPlaces, minVideos=3) {
|
||||||
|
const validPlaces = allPlaces.filter(place => place.items >= minVideos);
|
||||||
|
return validPlaces[Math.floor(Math.random() * validPlaces.length)];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user