Skip to content

Commit

Permalink
Added Top Tracks from lastfm in dashboard
Browse files Browse the repository at this point in the history
Todo : better presentation + clickable tracks / artists
  • Loading branch information
trekiteasy committed Jan 16, 2019
1 parent 2a3fc66 commit 4c0d984
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 64 deletions.
41 changes: 41 additions & 0 deletions app/actions/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getBestNewAlbums, getBestNewTracks } from 'pitchfork-bnm';

import globals from '../globals';
import { getNewsIndex, getNewsItem } from '../rest/Nuclear';
import { getTopTracks } from '../rest/LastFm';

const lastfm = new core.LastFmApi(
globals.lastfmApiKey,
Expand All @@ -26,6 +27,10 @@ export const LOAD_TOP_TAGS_START = 'LOAD_TOP_TAGS_START';
export const LOAD_TOP_TAGS_SUCCESS = 'LOAD_TOP_TAGS_SUCCESS';
export const LOAD_TOP_TAGS_ERROR = 'LOAD_TOP_TAGS_ERROR';

export const LOAD_TOP_TRACKS_START = 'LOAD_TOP_TRACKS_START';
export const LOAD_TOP_TRACKS_SUCCESS = 'LOAD_TOP_TRACKS_SUCCESS';
export const LOAD_TOP_TRACKS_ERROR = 'LOAD_TOP_TRACKS_ERROR';

export function loadTopTagsStart() {
return {
type: LOAD_TOP_TAGS_START,
Expand Down Expand Up @@ -165,3 +170,39 @@ export function loadNuclearNews() {
});
};
}

export function loadTopTracksStart() {
return {
type: LOAD_TOP_TRACKS_START,
};
}

export function loadTopTracksSuccess(tracks) {
return {
type: LOAD_TOP_TRACKS_SUCCESS,
payload: tracks,
};
}

export function loadTopTracksError() {
return {
type: LOAD_TOP_TRACKS_ERROR,
};
}

export function loadTopTracks() {
return dispatch => {
dispatch(loadTopTracksStart());
getTopTracks()
.then(tracks => tracks.json())
.then(tracksJson => {
//console.log('Top Trcks');
console.log(tracksJson);
dispatch(loadTopTracksSuccess(tracksJson.tracks.track));
})
.catch(error => {
dispatch(loadTopTracksError());
logger.error(error);
});
};
}
47 changes: 33 additions & 14 deletions app/components/Dashboard/ChartsTab/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
import React from 'react';
import {Tab} from 'semantic-ui-react';
import PropTypes from 'prop-types';
import { Tab } from 'semantic-ui-react';
import artPlaceholder from '../../../../resources/media/art_placeholder.png';
import numeral from 'numeral';

import styles from './styles.scss';

const ChartsTab = props => {
return (
<Tab.Pane attached={false}>
<div className={styles.charts_container}>
<h3>Charts in Nuclear are coming soon.</h3>
</div>
</Tab.Pane>
);
};
class ChartsTab extends React.Component {
constructor(props) {
super(props);
}

ChartsTab.propTypes = {

};
render() {
console.log(this.props);
return (
<Tab.Pane attached={false}>
<div className={styles.charts_container}>
<h3>Top Tracks from LastFm.</h3>
{this.props.topTracks.map((track, i) => {
return (
<div key={'toptrack-' + i} className={styles.track_row}>
<img src={track.image[0]['#text'] || artPlaceholder} />
<div className={styles.popular_track_name}>{track.name}</div>
<div className={styles.popular_track_artist}>
{track.artist.name}
</div>
<div className={styles.playcount}>
{numeral(track.playcount).format('0,0')} plays
</div>
</div>
);
})}
{console.log(this.props.topTracks)}
</div>
</Tab.Pane>
);
}
}

export default ChartsTab;
62 changes: 62 additions & 0 deletions app/components/Dashboard/ChartsTab/styles.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
@import '../../../vars';
.charts_container {
}

.popular_tracks_container {
display: flex;
flex: 1 1 auto;
flex-flow: column;

margin: 0 0.5rem;

.header {
margin-bottom: 1rem;

font-size: 16px;
font-variant: small-caps;
}

.track_row {
display: flex;
align-items: center;
flex-flow: row;

transition: 0.25s ease-in-out;

border-bottom: 1px solid rgba($background2, 0.2);

&:hover {
background: lighten($background, 10%);
}

img {
flex: 0 0 auto;

width: 3rem;
height: 3rem;
}

.popular_track_name {
flex: 1 1 auto;
margin: 0.25rem 0.5rem;
text-align: left;
}

.playcount {
flex: 1 1 auto;
margin: 0.25rem 0.5rem;
text-align: right;
text-transform: uppercase;
}
}

.expand_button {
display: flex;
justify-content: center;
padding: 0.5rem;
margin-top: 0.5rem;
transition: 0.25s;
cursor: pointer;

&:hover {
background: lighten($background, 5%);
}
}
}
40 changes: 24 additions & 16 deletions app/components/Dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,38 @@ class Dashboard extends React.Component {
return [
{
menuItem: 'Best new music',
render: () =>
<BestNewMusicTab
dashboardData={this.props.dashboardData}
artistInfoSearchByName={this.props.artistInfoSearchByName}
history={this.props.history}
/>
render: () => (
<BestNewMusicTab
dashboardData={this.props.dashboardData}
artistInfoSearchByName={this.props.artistInfoSearchByName}
history={this.props.history}
/>
),
},
{
menuItem: 'Charts',
render: () => <ChartsTab />
menuItem: 'Top Tracks',
render: () => (
<ChartsTab topTracks={this.props.dashboardData.topTracks} />
),
},
{
menuItem: 'Genres',
render: () =>
<GenresTab
genres={this.props.dashboardData.topTags}
history={this.props.history}
/>
render: () => (
<GenresTab
genres={this.props.dashboardData.topTags}
history={this.props.history}
/>
),
},
{
menuItem: 'Events',
render: () => { return null; }
render: () => {
return null;
},
},
{
menuItem: 'News',
render: () => <NewsTab news={this.props.dashboardData.news}/>
render: () => <NewsTab news={this.props.dashboardData.news} />,
},
];
}
Expand All @@ -46,12 +52,14 @@ class Dashboard extends React.Component {
this.props.loadBestNewAlbums();
this.props.loadNuclearNews();
this.props.loadTopTags();
this.props.loadTopTracks();
}

render() {
console.log(this.props);
return (
<div>
<Tab menu={{secondary: true, pointing: true}} panes={this.panes()} />
<Tab menu={{ secondary: true, pointing: true }} panes={this.panes()} />
</div>
);
}
Expand Down
21 changes: 12 additions & 9 deletions app/containers/DashboardContainer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import Dashboard from '../../components/Dashboard';

class DashboardContainer extends React.Component {
render() {
let {
actions,
dashboard,
history
} = this.props;
let { actions, dashboard, history } = this.props;
return (
<Dashboard
albumInfoSearch={actions.albumInfoSearch}
Expand All @@ -21,6 +17,7 @@ class DashboardContainer extends React.Component {
loadBestNewTracks={actions.loadBestNewTracks}
loadNuclearNews={actions.loadNuclearNews}
loadTopTags={actions.loadTopTags}
loadTopTracks={actions.loadTopTracks}
dashboardData={dashboard}
history={history}
/>
Expand All @@ -30,14 +27,20 @@ class DashboardContainer extends React.Component {

function mapStateToProps(state) {
return {
dashboard: state.dashboard
}
dashboard: state.dashboard,
};
}

function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(Object.assign({}, Actions, DashboardActions), dispatch)
actions: bindActionCreators(
Object.assign({}, Actions, DashboardActions),
dispatch
),
};
}

export default connect(mapStateToProps, mapDispatchToProps)(DashboardContainer);
export default connect(
mapStateToProps,
mapDispatchToProps
)(DashboardContainer);
55 changes: 30 additions & 25 deletions app/reducers/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,49 @@ import {
LOAD_BEST_NEW_ALBUMS_START,
LOAD_BEST_NEW_ALBUMS_SUCCESS,
LOAD_BEST_NEW_ALBUMS_ERROR,

LOAD_BEST_NEW_TRACKS_START,
LOAD_BEST_NEW_TRACKS_SUCCESS,
LOAD_BEST_NEW_TRACKS_ERROR,

LOAD_NUCLEAR_NEWS_START,
LOAD_NUCLEAR_NEWS_SUCCESS,
LOAD_NUCLEAR_NEWS_ERROR,

LOAD_TOP_TAGS_START,
LOAD_TOP_TAGS_SUCCESS,
LOAD_TOP_TAGS_ERROR
LOAD_TOP_TAGS_ERROR,
LOAD_TOP_TRACKS_START,
LOAD_TOP_TRACKS_SUCCESS,
LOAD_TOP_TRACKS_ERROR,
} from '../actions/dashboard';

const initialState = {
bestNewAlbums: [],
bestNewTracks: []
bestNewTracks: [],
topTracks: [],
};

export default function DashboardReducer(state=initialState, action) {
switch(action.type) {
case LOAD_BEST_NEW_ALBUMS_SUCCESS:
return Object.assign({}, state, {
bestNewAlbums: action.payload
});
case LOAD_BEST_NEW_TRACKS_SUCCESS:
return Object.assign({}, state, {
bestNewTracks: action.payload
});
case LOAD_NUCLEAR_NEWS_SUCCESS:
return Object.assign({}, state, {
news: action.payload
});
case LOAD_TOP_TAGS_SUCCESS:
return Object.assign({}, state, {
topTags: action.payload
});
default:
return state;
export default function DashboardReducer(state = initialState, action) {
switch (action.type) {
case LOAD_BEST_NEW_ALBUMS_SUCCESS:
return Object.assign({}, state, {
bestNewAlbums: action.payload,
});
case LOAD_BEST_NEW_TRACKS_SUCCESS:
return Object.assign({}, state, {
bestNewTracks: action.payload,
});
case LOAD_NUCLEAR_NEWS_SUCCESS:
return Object.assign({}, state, {
news: action.payload,
});
case LOAD_TOP_TAGS_SUCCESS:
return Object.assign({}, state, {
topTags: action.payload,
});
case LOAD_TOP_TRACKS_SUCCESS:
return Object.assign({}, state, {
topTracks: action.payload,
});
default:
return state;
}
}
6 changes: 6 additions & 0 deletions app/rest/LastFm.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ function searchTracks(terms) {
return makeLastfmRequest(parameters);
}

function getTopTracks() {
let parameters = 'chart.gettoptracks';
return makeLastfmRequest(parameters);
}

function makeLastfmRequest(parameters) {
return fetch(
apiUrl + parameters + '&api_key=' + lastfmApiKey + '&format=json'
Expand All @@ -18,4 +23,5 @@ function makeLastfmRequest(parameters) {

module.exports = {
searchTracks,
getTopTracks,
};

0 comments on commit 4c0d984

Please sign in to comment.