Recommendations in track index

This commit is contained in:
James Barnsley
2017-11-13 16:52:53 +13:00
parent da443805da
commit d5e2b56d95
5 changed files with 118 additions and 69 deletions

View File

@ -54,7 +54,7 @@ class LastfmAuthenticationFrame extends React.Component{
}
// Turn off our authorizing switch
this.setState({authorizing: false})
this.setState({authorizing: false});
}
startAuthorization(){

View File

@ -869,7 +869,7 @@ export function getFavorites(limit = 50, term = 'long_term'){
export function getRecommendations(uris = [], limit = 20){
return (dispatch, getState) => {
dispatch({type: 'SPOTIFY_RECOMMENDATIONS_LOADED', tracks: [], artists_uris: [], albums_uris: []})
dispatch({type: 'CLEAR_SPOTIFY_RECOMMENDATIONS'});
// build our starting point
var artists_ids = []
@ -909,15 +909,16 @@ export function getRecommendations(uris = [], limit = 20){
sendRequest(dispatch, getState, endpoint)
.then(
response => {
var tracks = Object.assign([], response.tracks);
// We only get simple artist objects, so we need to
// get the full object. We'll add URIs to our recommendations
// anyway so we can proceed in the meantime
var artists_uris = []
if (response.tracks.length > artists_ids.length && response.tracks.length > 10){
if (tracks.length > artists_ids.length && tracks.length > 10){
while (artists_uris.length < 5){
var random_index = Math.round(Math.random() * (response.tracks.length - 1))
var artist = response.tracks[random_index].artists[0]
var random_index = Math.round(Math.random() * (tracks.length - 1))
var artist = tracks[random_index].artists[0]
// Make sure this artist is not already in our sample, and
// is not one of the seeds
@ -931,10 +932,10 @@ export function getRecommendations(uris = [], limit = 20){
// Copy already loaded albums into array
var albums = []
var albums_uris = []
if (response.tracks.length > 10){
if (tracks.length > 10){
while (albums.length < 5){
var random_index = Math.round(Math.random() * (response.tracks.length - 1))
var album = response.tracks[random_index].album
var random_index = Math.round(Math.random() * (tracks.length - 1))
var album = tracks[random_index].album
// Make sure this album is not already in our sample
if (!albums_uris.includes(album.uri)){
@ -944,19 +945,23 @@ export function getRecommendations(uris = [], limit = 20){
}
}
// Officially add albums to index
dispatch({
type: 'ALBUMS_LOADED',
albums: albums
})
});
dispatch({
type: 'TRACKS_LOADED',
tracks: tracks
});
dispatch({
type: 'SPOTIFY_RECOMMENDATIONS_LOADED',
seeds_uris: uris,
tracks: response.tracks,
tracks_uris: helpers.arrayOf('uri',tracks),
artists_uris: artists_uris,
albums_uris: helpers.arrayOf('uri',albums)
})
});
},
error => {
dispatch(coreActions.handleException(

View File

@ -105,6 +105,9 @@ export default function reducer(spotify = {}, action){
}
);
case 'CLEAR_SPOTIFY_RECOMMENDATIONS':
return Object.assign({}, spotify, {recommendations: {artists_uris: [], albums_uris: [], tracks_uris: []}});
case 'SPOTIFY_RECOMMENDATIONS_LOADED':
return Object.assign(
{},
@ -113,9 +116,9 @@ export default function reducer(spotify = {}, action){
recommendations: {
artists_uris: action.artists_uris,
albums_uris: action.albums_uris,
tracks: helpers.formatTracks(action.tracks)
tracks_uris: action.tracks_uris
}
})
});
case 'SPOTIFY_FAVORITES_LOADED':
return Object.assign(

View File

@ -38,6 +38,12 @@ class Settings extends React.Component {
}
}
componentDidMount(){
if (this.props.lastfm.session && this.props.core.users["lastfm:user:"+this.props.lastfm.session.name] === undefined){
this.props.lastfmActions.getMe();
}
}
componentWillReceiveProps(newProps){
var changed = false
var state = this.state
@ -107,7 +113,7 @@ class Settings extends React.Component {
}
renderSpotifyUser(){
var user = this.props.spotify.me
var user = this.props.spotify.me;
if (user){
return (
@ -165,43 +171,59 @@ class Settings extends React.Component {
)
}
renderServiceStatus(service){
let colour = 'red'
let icon = 'close'
let name = service.charAt(0).toUpperCase() + service.slice(1).toLowerCase()
let text = 'Disconnected'
let tooltip = null
service = this.props[service]
renderServerStatus(){
var colour = 'grey';
var icon = 'question-circle';
var status = 'Unknown';
if (service.connecting){
icon = 'plug'
colour = 'grey'
text = 'Connecting'
} else if (name == 'Spotify' && (!this.props.mopidy.uri_schemes || !this.props.mopidy.uri_schemes.includes('spotify:'))){
icon = 'exclamation-triangle'
colour = 'red'
text = 'Not installed'
tooltip = 'Mopidy-Spotify is not installed or enabled'
} else if (service.connected){
icon = 'check'
colour = 'green'
text = 'Connected'
if (this.props.mopidy.connecting || this.props.pusher.connecting){
icon = 'plug';
status = 'Connecting...'
} else if (!this.props.mopidy.connected || !this.props.pusher.connected){
colour = 'red';
icon = 'close';
status = 'Disconnected';
} else if (this.props.mopidy.connected && this.props.pusher.connected){
colour = 'green';
icon = 'check';
status = 'Connected';
}
return (
<div className={"service"+(tooltip ? ' has-tooltip large-tooltip' : '')}>
<h4 className="title">
{name}
</h4>
<div className={colour+'-text icon'}>
<FontAwesome name={icon} />
</div>
<div className={"status "+colour+'-text'}>
{text}
</div>
{tooltip ? <span className="tooltip">{tooltip}</span> : null}
</div>
)
<span className={colour+'-text'}>
<FontAwesome name={icon} />&nbsp; {status}
</span>
);
}
renderSpotifyStatus(){
var colour = 'grey';
var icon = 'question-circle';
var status = 'Unknown';
if (this.props.spotify.connecting){
icon = 'plug';
status = 'Connecting...'
} else if (!this.props.spotify.connected){
colour = 'red';
icon = 'close';
status = 'Disconnected';
} else if (this.props.mopidy.connected){
colour = 'green';
icon = 'check';
status = 'Connected';
}
if (!this.props.mopidy.uri_schemes || !this.props.mopidy.uri_schemes.includes('spotify:')){
colour = 'orange';
status += ' (Mopidy-Spotify extension not installed/enabled!)';
}
return (
<span className={colour+'-text'}>
<FontAwesome name={icon} />&nbsp; {status}
</span>
);
}
render(){
@ -232,17 +254,17 @@ class Settings extends React.Component {
<section className="content-wrapper">
<h4 className="underline">Services</h4>
<h4 className="underline">Server</h4>
<div className="services">
{this.renderServiceStatus('mopidy')}
{this.renderServiceStatus('pusher')}
{this.renderServiceStatus('spotify')}
{this.renderServiceStatus('lastfm')}
<div className="field">
<div className="name">Status</div>
<div className="input">
<div className="text">
{this.renderServerStatus()}
</div>
</div>
</div>
<h4 className="underline">System</h4>
<div className="field">
<div className="name">Username</div>
<div className="input">
@ -317,6 +339,15 @@ class Settings extends React.Component {
<h4 className="underline">Spotify</h4>
<div className="field">
<div className="name">Status</div>
<div className="input">
<div className="text">
{this.renderSpotifyStatus()}
</div>
</div>
</div>
<div className="field current-user">
<div className="name">Current user</div>
<div className="input">

View File

@ -178,32 +178,42 @@ class Discover extends React.Component{
}
if (!this.props.recommendations || typeof(this.props.recommendations.albums_uris) === 'undefined' || typeof(this.props.recommendations.artists_uris) === 'undefined'){
return null
return null;
}
var albums = []
var albums = [];
if (this.props.recommendations.albums_uris && this.props.albums){
for (var i = 0; i < this.props.recommendations.albums_uris.length; i++){
var uri = this.props.recommendations.albums_uris[i]
var uri = this.props.recommendations.albums_uris[i];
if (this.props.albums.hasOwnProperty(uri)){
albums.push(this.props.albums[uri])
albums.push(this.props.albums[uri]);
}
}
}
var artists = []
var artists = [];
if (this.props.recommendations.artists_uris && this.props.artists){
for (var i = 0; i < this.props.recommendations.artists_uris.length; i++){
var uri = this.props.recommendations.artists_uris[i]
var uri = this.props.recommendations.artists_uris[i];
if (this.props.artists.hasOwnProperty(uri)){
artists.push(this.props.artists[uri])
artists.push(this.props.artists[uri]);
}
}
}
var uri = 'iris:discover'
var tracks = [];
if (this.props.recommendations.tracks_uris && this.props.tracks){
for (var i = 0; i < this.props.recommendations.tracks_uris.length; i++){
var uri = this.props.recommendations.tracks_uris[i];
if (this.props.tracks.hasOwnProperty(uri)){
tracks.push(this.props.tracks[uri]);
}
}
}
var uri = 'iris:discover';
if (this.props.params.seeds){
uri += ':'+this.props.params.seeds.split(':').join('_')
uri += ':'+this.props.params.seeds.split(':').join('_');
}
return (
@ -218,7 +228,7 @@ class Discover extends React.Component{
</section>
<section>
<h4>Tracks</h4>
{this.props.recommendations.tracks ? <TrackList className="discover-track-list" uri={uri} tracks={this.props.recommendations.tracks} /> : null}
<TrackList className="discover-track-list" uri={uri} tracks={tracks} />
</section>
</div>
)
@ -258,9 +268,9 @@ class Discover extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
albums: (state.core.albums ? state.core.albums : []),
artists: (state.core.artists ? state.core.artists : []),
tracks: (state.core.tracks ? state.core.tracks : []),
albums: state.core.albums,
artists: state.core.artists,
tracks: state.core.tracks,
genres: (state.core.genres ? state.core.genres : []),
authorized: state.spotify.authorization,
load_queue: state.ui.load_queue,