Recommendations in track index
This commit is contained in:
@ -54,7 +54,7 @@ class LastfmAuthenticationFrame extends React.Component{
|
||||
}
|
||||
|
||||
// Turn off our authorizing switch
|
||||
this.setState({authorizing: false})
|
||||
this.setState({authorizing: false});
|
||||
}
|
||||
|
||||
startAuthorization(){
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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} /> {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} /> {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">
|
||||
|
||||
@ -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,
|
||||
|
||||
Reference in New Issue
Block a user