Merge branch 'develop'

This commit is contained in:
James Barnsley
2018-04-10 21:03:03 +12:00
14 changed files with 174 additions and 162 deletions

View File

@ -368,7 +368,7 @@ var formatTracks = exports.formatTracks = function formatTracks(tracks) {
for (var i = 0; i < tracks.length; i++) {
// Nested track object (eg in spotify playlist)
if (tracks[i].track) {
if (tracks[i].track && isObject(tracks[i].track)) {
var track = Object.assign({}, tracks[i].track);
// Copy supporting values
@ -393,6 +393,8 @@ var formatTracks = exports.formatTracks = function formatTracks(tracks) {
if (track.track_no) {
track.track_number = track.track_no;
} else if (track.track_number) {
track.track_number = track.track_number;
}
if (track.disc_no) {
@ -788,11 +790,20 @@ var sortItems = exports.sortItems = function sortItems(array, property) {
/**
* Figure out if a value is a number
* @param data = mixed
* @param value = mixed
* @return boolean
**/
var isNumeric = exports.isNumeric = function isNumeric(data) {
return !isNaN(parseFloat(data)) && isFinite(data);
var isNumeric = exports.isNumeric = function isNumeric(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
};
/**
* Figure out if a value is an object
* @param value = mixed
* @return boolean
**/
var isObject = exports.isObject = function isObject(value) {
return value instanceof Object && value.constructor === Object;
};
/**
@ -50888,6 +50899,7 @@ var PusherMiddleware = function () {
// Broadcast of an error
if (message.error !== undefined) {
store.dispatch(coreActions.handleException('Pusher: ' + message.error.message, message));
} else {
@ -50922,6 +50934,9 @@ var PusherMiddleware = function () {
case 'radio_stopped':
store.dispatch(pusherActions.radioStopped());
break;
case 'restart':
window.location.reload(true);
break;
}
}
}
@ -64364,16 +64379,16 @@ var Album = function (_React$Component) {
value: function render() {
var _this2 = this;
if (helpers.isLoading(this.props.load_queue, ['spotify_albums/' + helpers.getFromUri('albumid', this.props.params.uri)])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
}
if (!this.props.album) {
return null;
if (helpers.isLoading(this.props.load_queue, ['spotify_albums/' + helpers.getFromUri('albumid', this.props.params.uri)])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
} else {
return null;
}
}
var artists = [];
@ -64480,12 +64495,6 @@ var Album = function (_React$Component) {
return Album;
}(_react2.default.Component);
/**
* Export our component
*
* We also integrate our global store, using connect()
**/
var mapStateToProps = function mapStateToProps(state, ownProps) {
var uri = ownProps.params.uri;
return {
@ -64747,14 +64756,6 @@ var Artist = function (_React$Component) {
value: function renderBody() {
var _this2 = this;
if (helpers.isLoading(this.props.load_queue, ['spotify_artists/' + helpers.getFromUri('artistid', this.props.params.uri), 'lastfm_method=artist.getInfo'])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
}
var scheme = helpers.uriSource(this.props.params.uri);
var related_artists = [];
@ -65414,20 +65415,25 @@ var Playlist = function (_React$Component) {
value: function render() {
var _this3 = this;
if (!this.props.playlist) return null;
var scheme = helpers.uriSource(this.props.params.uri);
var context = 'playlist';
if (this.props.playlist.can_edit) context = 'editable-playlist';
var user_id = helpers.getFromUri('userid', this.props.params.uri);
var playlist_id = helpers.getFromUri('playlistid', this.props.params.uri);
if (helpers.isLoading(this.props.load_queue, ['spotify_users/' + user_id + '/playlists/' + playlist_id + '?'])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
if (!this.props.playlist) {
if (helpers.isLoading(this.props.load_queue, ['spotify_users/' + user_id + '/playlists/' + playlist_id + '?'])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
} else {
return null;
}
}
var context = 'playlist';
if (this.props.playlist.can_edit) {
context = 'editable-playlist';
}
var tracks = [];
@ -65676,16 +65682,17 @@ var User = function (_React$Component) {
var _this2 = this;
var user_id = helpers.getFromUri('userid', this.props.params.uri);
if (helpers.isLoading(this.props.load_queue, ['spotify_users/' + user_id, 'spotify_users/' + user_id + '/playlists/?'])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
}
if (!this.props.user) {
return null;
if (helpers.isLoading(this.props.load_queue, ['spotify_users/' + user_id, 'spotify_users/' + user_id + '/playlists/?'])) {
return _react2.default.createElement(
'div',
{ className: 'body-loader loading' },
_react2.default.createElement('div', { className: 'loader' })
);
} else {
return null;
}
}
var playlists = [];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -73,7 +73,7 @@
// Release details
// These are automatically injected to built HTML
var build = "1522870566";
var build = "1523348344";
var version = "3.16.1";
// Construct the script tag

View File

@ -98,7 +98,7 @@ export default class GridItem extends React.Component{
}
return (
<div className="grid-item" onClick={e => this.handleClick(e)} onContextMenu={e => this.handleContextMenu(e)}>
<div className={"grid-item "+this.props.type+"-grid-item"} onClick={e => this.handleClick(e)} onContextMenu={e => this.handleContextMenu(e)}>
<Thumbnail size="medium" images={images} />
<div className="name">
{item.name ? item.name : <span className="dark-grey-text">{item.uri}</span>}

View File

@ -65,15 +65,21 @@ class Thumbnail extends React.Component{
}
render(){
var image = this.mapImageSizes()
var class_name = 'thumbnail '
if (this.props.size ) class_name += ' '+this.props.size
if (this.props.circle ) class_name += ' circle'
if (this.props.className ) class_name += ' '+this.props.className
var image = this.mapImageSizes();
var class_name = 'thumbnail ';
if (this.props.size){
class_name += ' '+this.props.size;
}
if (this.props.circle){
class_name += ' circle';
}
if (this.props.className){
class_name += ' '+this.props.className;
}
var zoom_icon = null
var zoom_icon = null;
if (this.props.canZoom){
zoom_icon = <span className="zoom" onClick={e => this.zoom(e,image)}><FontAwesome name="search" /></span>
zoom_icon = <span className="zoom" onClick={e => this.zoom(e,image)}><FontAwesome name="search" /></span>;
}
return (

View File

@ -284,7 +284,7 @@ export let formatTracks = function(tracks){
for (var i = 0; i < tracks.length; i++){
// Nested track object (eg in spotify playlist)
if (tracks[i].track){
if (tracks[i].track && isObject(tracks[i].track)){
var track = Object.assign({}, tracks[i].track);
// Copy supporting values
@ -310,6 +310,8 @@ export let formatTracks = function(tracks){
if (track.track_no){
track.track_number = track.track_no;
} else if (track.track_number){
track.track_number = track.track_number;
}
if (track.disc_no){
@ -711,11 +713,21 @@ export let sortItems = function (array, property, reverse = false, sort_map = nu
/**
* Figure out if a value is a number
* @param data = mixed
* @param value = mixed
* @return boolean
**/
export let isNumeric = function (data){
return !isNaN(parseFloat(data)) && isFinite(data)
export let isNumeric = function (value){
return !isNaN(parseFloat(value)) && isFinite(value)
}
/**
* Figure out if a value is an object
* @param value = mixed
* @return boolean
**/
export let isObject = function(value){
return value instanceof Object && value.constructor === Object;
}

View File

@ -296,6 +296,10 @@ const MopidyMiddleware = (function(){
));
break
case 'MOPIDY_PREVIOUS':
request(socket, store, 'playback.previous');
break
case 'MOPIDY_NEXT':
request(socket, store, 'playback.next');

View File

@ -53,10 +53,12 @@ const PusherMiddleware = (function(){
// Broadcast of an error
if (message.error !== undefined){
store.dispatch(coreActions.handleException(
'Pusher: '+message.error.message,
message
));
} else {
switch (message.method){
@ -90,6 +92,9 @@ const PusherMiddleware = (function(){
case 'radio_stopped':
store.dispatch(pusherActions.radioStopped());
break;
case 'restart':
window.location.reload(true);
break;
}
}
}

View File

@ -105,16 +105,16 @@ class Album extends React.Component{
}
render(){
if (helpers.isLoading(this.props.load_queue,['spotify_albums/'+helpers.getFromUri('albumid',this.props.params.uri)])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
}
if (!this.props.album){
return null
if (!this.props.album){
if (helpers.isLoading(this.props.load_queue,['spotify_albums/'+helpers.getFromUri('albumid',this.props.params.uri)])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
} else {
return null;
}
}
var artists = []
@ -173,13 +173,6 @@ class Album extends React.Component{
}
}
/**
* Export our component
*
* We also integrate our global store, using connect()
**/
const mapStateToProps = (state, ownProps) => {
var uri = ownProps.params.uri;
return {

View File

@ -115,15 +115,7 @@ class Artist extends React.Component{
)
}
renderBody(){
if (helpers.isLoading(this.props.load_queue,['spotify_artists/'+helpers.getFromUri('artistid',this.props.params.uri), 'lastfm_method=artist.getInfo'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
}
renderBody(){
var scheme = helpers.uriSource(this.props.params.uri);
var related_artists = []
@ -245,68 +237,55 @@ class Artist extends React.Component{
}
render(){
var scheme = helpers.uriSource(this.props.params.uri);
var scheme = helpers.uriSource(this.props.params.uri )
if (!this.props.artist){
if (helpers.isLoading(this.props.load_queue,['spotify_artists/'+helpers.getFromUri('artistid',this.props.params.uri), 'lastfm_method=artist.getInfo'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
} else {
return null;
}
}
if (this.props.artist && this.props.artist.images){
var image = helpers.sizedImages(this.props.artist.images ).huge
var image = helpers.sizedImages(this.props.artist.images).huge;
} else {
var image = null
var image = null;
}
if (this.props.artist){
var is_spotify = (scheme == 'spotify')
if (this.props.artist.tracks_uris && this.props.artist.tracks_uris.length > 0){
var uris_to_play = this.props.artist.tracks_uris
} else {
var uris_to_play = this.props.artist.albums_uris
}
return (
<div className="view artist-view">
<div className="intro">
<Parallax image={image} />
<div className="liner">
<h1>{this.props.artist ? this.props.artist.name : null}</h1>
<div className="actions">
<button className="primary" onClick={e => this.props.mopidyActions.playURIs(uris_to_play, this.props.artist.uri)}>Play</button>
{is_spotify ? <FollowButton className="white" uri={this.props.params.uri} removeText="Remove from library" addText="Add to library" is_following={this.inLibrary()} /> : null}
<ContextMenuTrigger className="white" onTrigger={e => this.handleContextMenu(e)} />
</div>
{ this.renderSubViewMenu() }
</div>
</div>
<div className="content-wrapper">
{this.renderBody()}
</div>
</div>
);
var is_spotify = (scheme == 'spotify')
if (this.props.artist.tracks_uris && this.props.artist.tracks_uris.length > 0){
var uris_to_play = this.props.artist.tracks_uris
} else {
return (
<div className="view artist-view">
<div className="intro">
<Parallax />
<div className="liner">
<h1>
<span className="placeholder"></span>
</h1>
<div className="actions">
<button className="placeholder">&nbsp;</button>
<button className="placeholder">&nbsp;</button>
</div>
{ this.renderSubViewMenu() }
var uris_to_play = this.props.artist.albums_uris
}
return (
<div className="view artist-view">
<div className="intro">
<Parallax image={image} />
<div className="liner">
<h1>{this.props.artist ? this.props.artist.name : null}</h1>
<div className="actions">
<button className="primary" onClick={e => this.props.mopidyActions.playURIs(uris_to_play, this.props.artist.uri)}>Play</button>
{is_spotify ? <FollowButton className="white" uri={this.props.params.uri} removeText="Remove from library" addText="Add to library" is_following={this.inLibrary()} /> : null}
<ContextMenuTrigger className="white" onTrigger={e => this.handleContextMenu(e)} />
</div>
</div>
<div className="content-wrapper">
{this.renderBody()}
{ this.renderSubViewMenu() }
</div>
</div>
);
}
<div className="content-wrapper">
{this.renderBody()}
</div>
</div>
);
}
}

View File

@ -159,20 +159,25 @@ class Playlist extends React.Component{
}
render(){
if (!this.props.playlist) return null
var scheme = helpers.uriSource(this.props.params.uri);
var user_id = helpers.getFromUri('userid',this.props.params.uri);
var playlist_id = helpers.getFromUri('playlistid',this.props.params.uri);
if (!this.props.playlist){
if (helpers.isLoading(this.props.load_queue,['spotify_users/'+user_id+'/playlists/'+playlist_id+'?'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
} else {
return null;
}
}
var scheme = helpers.uriSource(this.props.params.uri )
var context = 'playlist'
if (this.props.playlist.can_edit) context = 'editable-playlist'
var user_id = helpers.getFromUri('userid',this.props.params.uri)
var playlist_id = helpers.getFromUri('playlistid',this.props.params.uri)
if (helpers.isLoading(this.props.load_queue,['spotify_users/'+user_id+'/playlists/'+playlist_id+'?'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
var context = 'playlist';
if (this.props.playlist.can_edit){
context = 'editable-playlist';
}
var tracks = [];

View File

@ -56,16 +56,17 @@ class User extends React.Component{
render(){
var user_id = helpers.getFromUri('userid',this.props.params.uri);
if (helpers.isLoading(this.props.load_queue,['spotify_users/'+user_id,'spotify_users/'+user_id+'/playlists/?'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
}
if (!this.props.user){
return null;
if (!this.props.user){
if (helpers.isLoading(this.props.load_queue,['spotify_users/'+user_id,'spotify_users/'+user_id+'/playlists/?'])){
return (
<div className="body-loader loading">
<div className="loader"></div>
</div>
)
} else {
return null;
}
}
var playlists = [];