Merge branch 'develop'
This commit is contained in:
@ -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
4
mopidy_iris/static/app.min.js
vendored
4
mopidy_iris/static/app.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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
|
||||
|
||||
@ -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>}
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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');
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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"> </button>
|
||||
<button className="placeholder"> </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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 = [];
|
||||
|
||||
@ -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 = [];
|
||||
|
||||
Reference in New Issue
Block a user