Pretty URLs for albums URLs as well
This commit is contained in:
parent
e232ec8c16
commit
216f2e7348
@ -19,6 +19,7 @@ export default class Albums extends Component {
|
||||
}
|
||||
|
||||
// Set grid props
|
||||
const artists = this.props.artists;
|
||||
const grid = {
|
||||
isFetching: this.props.isFetching,
|
||||
items: this.props.albums,
|
||||
@ -26,6 +27,14 @@ export default class Albums extends Component {
|
||||
itemsLabel: "app.common.album",
|
||||
subItemsType: "tracks",
|
||||
subItemsLabel: "app.common.track",
|
||||
buildLinkTo: (itemType, item) => {
|
||||
let artist = encodeURIComponent(item.get("artist"));
|
||||
if (artists && artists.size > 0) {
|
||||
const id = item.get("artist");
|
||||
artist = encodeURIComponent(id + "-" + artists.getIn([id, "name"]));
|
||||
}
|
||||
return "/artist/" + artist + "/album/" + item.get("id") + "-" + encodeURIComponent(item.get("name"));
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
@ -40,5 +49,6 @@ Albums.propTypes = {
|
||||
error: PropTypes.string,
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
albums: PropTypes.instanceOf(Immutable.List).isRequired,
|
||||
artists: PropTypes.instanceOf(Immutable.Map),
|
||||
pagination: PropTypes.object.isRequired,
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ export default class Artists extends Component {
|
||||
subItemsType: "albums",
|
||||
subItemsLabel: "app.common.album",
|
||||
buildLinkTo: (itemType, item) => {
|
||||
return "/" + itemType + "/" + item.get("id") + "-" + encodeURIComponent(item.get("name"));
|
||||
return "/artist/" + item.get("id") + "-" + encodeURIComponent(item.get("name"));
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -91,7 +91,11 @@ function _uglyFixes(jsonData) {
|
||||
return songs.map(function (song) {
|
||||
// Fix for cdata left in artist and album
|
||||
song.artist.name = song.artist.cdata;
|
||||
delete(song.artist.cdata);
|
||||
delete(song.artist.toString);
|
||||
song.album.name = song.album.cdata;
|
||||
delete(song.album.cdata);
|
||||
delete(song.album.toString);
|
||||
return song;
|
||||
});
|
||||
};
|
||||
@ -105,6 +109,11 @@ function _uglyFixes(jsonData) {
|
||||
album.name = album.name + " [Disk " + album.disk + "]";
|
||||
}
|
||||
|
||||
// Fix for cdata left in artist
|
||||
album.artist.name = album.artist.cdata;
|
||||
delete(album.artist.cdata);
|
||||
delete(album.artist.toString);
|
||||
|
||||
// Move songs one node top
|
||||
if (album.tracks.song) {
|
||||
album.tracks = album.tracks.song;
|
||||
|
@ -10,7 +10,6 @@ import SimpleLayout from "./components/layouts/Simple";
|
||||
import SidebarLayout from "./components/layouts/Sidebar";
|
||||
import ArtistPage from "./views/ArtistPage";
|
||||
import ArtistsPage from "./views/ArtistsPage";
|
||||
import AlbumPage from "./views/AlbumPage";
|
||||
import AlbumsPage from "./views/AlbumsPage";
|
||||
import BrowsePage from "./views/BrowsePage";
|
||||
import DiscoverPage from "./views/DiscoverPage";
|
||||
@ -31,9 +30,9 @@ export default (
|
||||
<Route path="discover" component={DiscoverPage} />
|
||||
<Route path="browse" component={BrowsePage} />
|
||||
<Route path="artists" component={ArtistsPage} />
|
||||
<Route path="artist/:id" component={ArtistPage} />
|
||||
<Route path="artist/:artist" component={ArtistPage} />
|
||||
<Route path="albums" component={AlbumsPage} />
|
||||
<Route path="album/:id" component={AlbumPage} />
|
||||
<Route path="artist/:artist/album/:album" component={ArtistPage} />
|
||||
<Route path="songs" component={SongsPage} />
|
||||
<Route path="playlist" component={PlaylistPage} />
|
||||
<IndexRoute component={HomePage} />
|
||||
|
@ -1,63 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import { bindActionCreators } from "redux";
|
||||
import { connect } from "react-redux";
|
||||
import Immutable from "immutable";
|
||||
|
||||
import * as actionCreators from "../actions";
|
||||
|
||||
import Album from "../components/Album";
|
||||
|
||||
// TODO: AlbumPage should be scrolled ArtistPage
|
||||
|
||||
export class AlbumPage extends Component {
|
||||
componentWillMount() {
|
||||
// Load the data
|
||||
this.props.actions.loadAlbums({
|
||||
pageNumber: 1,
|
||||
filter: this.props.params.id,
|
||||
include: ["songs"],
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.album) {
|
||||
return (
|
||||
<Album album={this.props.album} songs={this.props.songs} />
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div></div>
|
||||
); // TODO: Loading + error
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const albums = state.api.entities.get("album");
|
||||
let album = undefined;
|
||||
let songs = new Immutable.List();
|
||||
if (albums) {
|
||||
// Get artist
|
||||
album = albums.find(
|
||||
item => item.get("id") == ownProps.params.id
|
||||
);
|
||||
// Get songs
|
||||
const tracks = album.get("tracks");
|
||||
if (Immutable.List.isList(tracks)) {
|
||||
songs = new Immutable.List(
|
||||
tracks.map(
|
||||
id => state.api.entities.getIn(["track", id])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
album: album,
|
||||
songs: songs,
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
actions: bindActionCreators(actionCreators, dispatch),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AlbumPage);
|
@ -56,7 +56,7 @@ class AlbumsPageIntl extends Component {
|
||||
const error = handleErrorI18nObject(this.props.error, formatMessage, albumsMessages);
|
||||
|
||||
return (
|
||||
<Albums isFetching={this.props.isFetching} error={error} albums={this.props.albumsList} pagination={pagination} />
|
||||
<Albums isFetching={this.props.isFetching} error={error} albums={this.props.albumsList} artists={this.props.artistsList} pagination={pagination} />
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -67,15 +67,21 @@ AlbumsPageIntl.propTypes = {
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
let albumsList = new Immutable.List();
|
||||
let artistsList = new Immutable.Map();
|
||||
if (state.paginated.type == "album" && state.paginated.result.size > 0) {
|
||||
albumsList = state.paginated.result.map(
|
||||
id => state.entities.getIn(["entities", "album", id])
|
||||
);
|
||||
albumsList.forEach(function (album) {
|
||||
const albumArtist = album.get("artist");
|
||||
artistsList = artistsList.set(albumArtist, state.entities.getIn(["entities", "artist", albumArtist]));
|
||||
});
|
||||
}
|
||||
return {
|
||||
isFetching: state.entities.isFetching,
|
||||
error: state.entities.error,
|
||||
albumsList: albumsList,
|
||||
artistsList: artistsList,
|
||||
currentPage: state.paginated.currentPage,
|
||||
nPages: state.paginated.nPages,
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ const artistMessages = defineMessages(messagesMap(Array.concat([], APIMessages))
|
||||
*/
|
||||
class ArtistPageIntl extends Component {
|
||||
componentWillMount() {
|
||||
const id = filterInt(this.props.params.id.split("-")[0]);
|
||||
const id = filterInt(this.props.params.artist.split("-")[0]);
|
||||
if (isNaN(id)) {
|
||||
// Redirect to homepage
|
||||
this.context.router.replace({
|
||||
@ -65,7 +65,7 @@ ArtistPageIntl.contextTypes = {
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const id = ownProps.params.id.split("-")[0];
|
||||
const id = ownProps.params.artist.split("-")[0];
|
||||
// Get artist
|
||||
let artist = state.entities.getIn(["entities", "artist", id]);
|
||||
let albums = new Immutable.List();
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(636);Object.keys(r).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},636:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
|
||||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="./",t(0)}({0:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(635);Object.keys(r).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})})},635:function(e,t){!function(t,n){function r(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function a(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,s(t)}function c(e){var t=E[e[v]];return t||(t={},y++,e[v]=y,E[y]=t),t}function i(e,t,r){if(t||(t=n),f)return t.createElement(e);r||(r=c(t));var a;return a=r.cache[e]?r.cache[e].cloneNode():g.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||p.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function l(e,t){if(e||(e=n),f)return e.createDocumentFragment();t=t||c(e);for(var r=t.frag.cloneNode(),o=0,i=a(),l=i.length;o<l;o++)r.createElement(i[o]);return r}function u(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+a().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function s(e){e||(e=n);var t=c(e);return!b.shivCSS||d||t.hasCSS||(t.hasCSS=!!r(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||u(e,t),e}var d,f,m="3.7.3-pre",h=t.html5||{},p=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,g=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",y=0,E={};!function(){try{var e=n.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,f=1==e.childNodes.length||function(){n.createElement("a");var e=n.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(t){d=!0,f=!0}}();var b={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:s,createElement:i,createDocumentFragment:l,addElements:o};t.html5=b,s(n),"object"==typeof e&&e.exports&&(e.exports=b)}("undefined"!=typeof window?window:this,document)}});
|
||||
//# sourceMappingURL=fix.ie9.js.map
|
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
Loading…
Reference in New Issue
Block a user