Add more prettty and human readable artists URLs
This commit is contained in:
parent
85dcf6d271
commit
e232ec8c16
@ -46,3 +46,10 @@ homogeneous.
|
|||||||
## Hooks
|
## Hooks
|
||||||
|
|
||||||
Usefuls Git hooks are located in `hooks` folder.
|
Usefuls Git hooks are located in `hooks` folder.
|
||||||
|
|
||||||
|
|
||||||
|
## Notes on URLs
|
||||||
|
|
||||||
|
Text after any dash in a URL parameter is considered as a comment and
|
||||||
|
discarded. In `/artist/1-foobar`, the artist ID is `1` and the `foobar` text
|
||||||
|
is simply considered as a comment for human readable URLs.
|
||||||
|
@ -26,6 +26,9 @@ export default class Artists extends Component {
|
|||||||
itemsLabel: "app.common.artist",
|
itemsLabel: "app.common.artist",
|
||||||
subItemsType: "albums",
|
subItemsType: "albums",
|
||||||
subItemsLabel: "app.common.album",
|
subItemsLabel: "app.common.album",
|
||||||
|
buildLinkTo: (itemType, item) => {
|
||||||
|
return "/" + itemType + "/" + item.get("id") + "-" + encodeURIComponent(item.get("name"));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -64,7 +64,10 @@ class GridItemCSSIntl extends Component {
|
|||||||
{ itemCount: nSubItems }
|
{ itemCount: nSubItems }
|
||||||
);
|
);
|
||||||
|
|
||||||
const to = "/" + this.props.itemsType + "/" + this.props.item.get("id");
|
let to = "/" + this.props.itemsType + "/" + this.props.item.get("id");
|
||||||
|
if (this.props.buildLinkTo) {
|
||||||
|
to = this.props.buildLinkTo(this.props.itemsType, this.props.item);
|
||||||
|
}
|
||||||
const id = "grid-item-" + this.props.itemsType + "/" + this.props.item.get("id");
|
const id = "grid-item-" + this.props.itemsType + "/" + this.props.item.get("id");
|
||||||
const title = formatMessage(gridMessages["app.grid.goTo" + this.props.itemsType.capitalize() + "Page"]);
|
const title = formatMessage(gridMessages["app.grid.goTo" + this.props.itemsType.capitalize() + "Page"]);
|
||||||
|
|
||||||
@ -85,6 +88,7 @@ GridItemCSSIntl.propTypes = {
|
|||||||
itemsLabel: PropTypes.string.isRequired,
|
itemsLabel: PropTypes.string.isRequired,
|
||||||
subItemsType: PropTypes.string.isRequired,
|
subItemsType: PropTypes.string.isRequired,
|
||||||
subItemsLabel: PropTypes.string.isRequired,
|
subItemsLabel: PropTypes.string.isRequired,
|
||||||
|
buildLinkTo: PropTypes.func,
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
export let GridItem = injectIntl(CSSModules(GridItemCSSIntl, css));
|
export let GridItem = injectIntl(CSSModules(GridItemCSSIntl, css));
|
||||||
@ -237,9 +241,9 @@ export class Grid extends Component {
|
|||||||
|
|
||||||
// Build grid items
|
// Build grid items
|
||||||
let gridItems = [];
|
let gridItems = [];
|
||||||
const { itemsType, itemsLabel, subItemsType, subItemsLabel } = this.props;
|
const { itemsType, itemsLabel, subItemsType, subItemsLabel, buildLinkTo } = this.props;
|
||||||
this.props.items.forEach(function (item) {
|
this.props.items.forEach(function (item) {
|
||||||
gridItems.push(<GridItem item={item} itemsType={itemsType} itemsLabel={itemsLabel} subItemsType={subItemsType} subItemsLabel={subItemsLabel} key={item.get("id")} />);
|
gridItems.push(<GridItem item={item} itemsType={itemsType} itemsLabel={itemsLabel} subItemsType={subItemsType} subItemsLabel={subItemsLabel} buildLinkTo={buildLinkTo} key={item.get("id")} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -264,6 +268,7 @@ Grid.propTypes = {
|
|||||||
itemsLabel: PropTypes.string.isRequired,
|
itemsLabel: PropTypes.string.isRequired,
|
||||||
subItemsType: PropTypes.string.isRequired,
|
subItemsType: PropTypes.string.isRequired,
|
||||||
subItemsLabel: PropTypes.string.isRequired,
|
subItemsLabel: PropTypes.string.isRequired,
|
||||||
|
buildLinkTo: PropTypes.func,
|
||||||
filterText: PropTypes.string,
|
filterText: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// NPM imports
|
// NPM imports
|
||||||
import React, { Component } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
import { bindActionCreators } from "redux";
|
import { bindActionCreators } from "redux";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
import { defineMessages, injectIntl, intlShape } from "react-intl";
|
||||||
import Immutable from "immutable";
|
import Immutable from "immutable";
|
||||||
|
|
||||||
// Local imports
|
// Local imports
|
||||||
import { messagesMap, handleErrorI18nObject } from "../utils";
|
import { messagesMap, handleErrorI18nObject, filterInt } from "../utils";
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
import * as actionCreators from "../actions";
|
import * as actionCreators from "../actions";
|
||||||
@ -26,9 +26,16 @@ const artistMessages = defineMessages(messagesMap(Array.concat([], APIMessages))
|
|||||||
*/
|
*/
|
||||||
class ArtistPageIntl extends Component {
|
class ArtistPageIntl extends Component {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
const id = filterInt(this.props.params.id.split("-")[0]);
|
||||||
|
if (isNaN(id)) {
|
||||||
|
// Redirect to homepage
|
||||||
|
this.context.router.replace({
|
||||||
|
pathname: "/",
|
||||||
|
});
|
||||||
|
}
|
||||||
// Load the data
|
// Load the data
|
||||||
this.props.actions.loadArtist({
|
this.props.actions.loadArtist({
|
||||||
filter: this.props.params.id,
|
filter: id,
|
||||||
include: ["albums", "songs"],
|
include: ["albums", "songs"],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -53,10 +60,14 @@ class ArtistPageIntl extends Component {
|
|||||||
ArtistPageIntl.propTypes = {
|
ArtistPageIntl.propTypes = {
|
||||||
intl: intlShape.isRequired,
|
intl: intlShape.isRequired,
|
||||||
};
|
};
|
||||||
|
ArtistPageIntl.contextTypes = {
|
||||||
|
router: PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
|
const id = ownProps.params.id.split("-")[0];
|
||||||
// Get artist
|
// Get artist
|
||||||
let artist = state.entities.getIn(["entities", "artist", ownProps.params.id]);
|
let artist = state.entities.getIn(["entities", "artist", id]);
|
||||||
let albums = new Immutable.List();
|
let albums = new Immutable.List();
|
||||||
let songs = new Immutable.Map();
|
let songs = new Immutable.Map();
|
||||||
if (artist) {
|
if (artist) {
|
||||||
|
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