Fix some aria warnings and use immutable everywhere
This commit is contained in:
parent
34713cdcde
commit
9d1ef1b0bf
@ -2,6 +2,7 @@ import React, { Component, PropTypes } from "react";
|
|||||||
import CSSModules from "react-css-modules";
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, FormattedMessage } from "react-intl";
|
import { defineMessages, FormattedMessage } from "react-intl";
|
||||||
import FontAwesome from "react-fontawesome";
|
import FontAwesome from "react-fontawesome";
|
||||||
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import { formatLength, messagesMap } from "../utils";
|
import { formatLength, messagesMap } from "../utils";
|
||||||
|
|
||||||
@ -32,9 +33,8 @@ class AlbumTrackRowCSS extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not object
|
|
||||||
AlbumTrackRowCSS.propTypes = {
|
AlbumTrackRowCSS.propTypes = {
|
||||||
track: PropTypes.object.isRequired
|
track: PropTypes.instanceOf(Immutable.Map).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let AlbumTrackRow = CSSModules(AlbumTrackRowCSS, css);
|
export let AlbumTrackRow = CSSModules(AlbumTrackRowCSS, css);
|
||||||
@ -56,9 +56,8 @@ class AlbumTracksTableCSS extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not object
|
|
||||||
AlbumTracksTableCSS.propTypes = {
|
AlbumTracksTableCSS.propTypes = {
|
||||||
tracks: PropTypes.object.isRequired
|
tracks: PropTypes.instanceOf(Immutable.List).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let AlbumTracksTable = CSSModules(AlbumTracksTableCSS, css);
|
export let AlbumTracksTable = CSSModules(AlbumTracksTableCSS, css);
|
||||||
@ -85,10 +84,9 @@ class AlbumRowCSS extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not object
|
|
||||||
AlbumRowCSS.propTypes = {
|
AlbumRowCSS.propTypes = {
|
||||||
album: PropTypes.object.isRequired,
|
album: PropTypes.instanceOf(Immutable.Map).isRequired,
|
||||||
songs: PropTypes.object.isRequired
|
songs: PropTypes.instanceOf(Immutable.List).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let AlbumRow = CSSModules(AlbumRowCSS, css);
|
export let AlbumRow = CSSModules(AlbumRowCSS, css);
|
||||||
@ -101,8 +99,7 @@ export default class Album extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not object
|
|
||||||
Album.propTypes = {
|
Album.propTypes = {
|
||||||
album: PropTypes.object.isRequired,
|
album: PropTypes.instanceOf(Immutable.Map).isRequired,
|
||||||
songs: PropTypes.object.isRequired
|
songs: PropTypes.instanceOf(Immutable.List).isRequired
|
||||||
};
|
};
|
||||||
|
@ -1,24 +1,51 @@
|
|||||||
import React, { Component, PropTypes } from "react";
|
import React, { Component, PropTypes } from "react";
|
||||||
import CSSModules from "react-css-modules";
|
import CSSModules from "react-css-modules";
|
||||||
|
import { defineMessages, FormattedMessage } from "react-intl";
|
||||||
|
import FontAwesome from "react-fontawesome";
|
||||||
|
import Immutable from "immutable";
|
||||||
|
|
||||||
|
import { messagesMap } from "../utils/";
|
||||||
|
|
||||||
import { AlbumRow } from "./Album";
|
import { AlbumRow } from "./Album";
|
||||||
|
|
||||||
|
import commonMessages from "../locales/messagesDescriptors/common";
|
||||||
|
|
||||||
import css from "../styles/Artist.scss";
|
import css from "../styles/Artist.scss";
|
||||||
|
|
||||||
|
const artistMessages = defineMessages(messagesMap(Array.concat([], commonMessages)));
|
||||||
|
|
||||||
class ArtistCSS extends Component {
|
class ArtistCSS extends Component {
|
||||||
render () {
|
render () {
|
||||||
let albumsRows = [];
|
const loading = (
|
||||||
if (this.props.artist.get("albums").size > 0) {
|
<div className="row text-center">
|
||||||
const artistAlbums = this.props.albums;
|
<p>
|
||||||
const artistSongs = this.props.songs;
|
<FontAwesome name="spinner" className="fa-pulse fa-3x fa-fw" aria-hidden="true" />
|
||||||
this.props.artist.get("albums").forEach(function (album) {
|
<span className="sr-only"><FormattedMessage {...artistMessages["app.common.loading"]} /></span>
|
||||||
album = artistAlbums.get(album);
|
</p>
|
||||||
const songs = album.get("tracks").map(
|
</div>
|
||||||
id => artistSongs.get(id)
|
|
||||||
);
|
);
|
||||||
albumsRows.push(<AlbumRow album={album} songs={songs} key={album.get("id")} />);
|
|
||||||
|
if (!this.props.artist) {
|
||||||
|
// Loading
|
||||||
|
return loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
let albumsRows = [];
|
||||||
|
const { albums, songs } = this.props;
|
||||||
|
const artistAlbums = this.props.artist.get("albums");
|
||||||
|
if (albums && songs && artistAlbums && artistAlbums.size > 0) {
|
||||||
|
this.props.artist.get("albums").forEach(function (album) {
|
||||||
|
album = albums.get(album);
|
||||||
|
const albumSongs = album.get("tracks").map(
|
||||||
|
id => songs.get(id)
|
||||||
|
);
|
||||||
|
albumsRows.push(<AlbumRow album={album} songs={albumSongs} key={album.get("id")} />);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Loading
|
||||||
|
albumsRows = loading;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="row" styleName="name">
|
<div className="row" styleName="name">
|
||||||
@ -41,11 +68,11 @@ class ArtistCSS extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Not object
|
|
||||||
ArtistCSS.propTypes = {
|
ArtistCSS.propTypes = {
|
||||||
artist: PropTypes.object.isRequired,
|
isFetching: PropTypes.bool.isRequired,
|
||||||
albums: PropTypes.object.isRequired,
|
artist: PropTypes.instanceOf(Immutable.Map),
|
||||||
songs: PropTypes.object.isRequired
|
albums: PropTypes.instanceOf(Immutable.Map),
|
||||||
|
songs: PropTypes.instanceOf(Immutable.Map)
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CSSModules(ArtistCSS, css);
|
export default CSSModules(ArtistCSS, css);
|
||||||
|
@ -43,7 +43,7 @@ class SongsTableRowCSS extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SongsTableRowCSS.propTypes = {
|
SongsTableRowCSS.propTypes = {
|
||||||
song: PropTypes.object.isRequired
|
song: PropTypes.instanceOf(Immutable.Map).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export let SongsTableRow = CSSModules(SongsTableRowCSS, css);
|
export let SongsTableRow = CSSModules(SongsTableRowCSS, css);
|
||||||
|
@ -25,8 +25,8 @@ class GridItemCSSIntl extends Component {
|
|||||||
const {formatMessage} = this.props.intl;
|
const {formatMessage} = this.props.intl;
|
||||||
|
|
||||||
let nSubItems = this.props.item.get(this.props.subItemsType);
|
let nSubItems = this.props.item.get(this.props.subItemsType);
|
||||||
if (Array.isArray(nSubItems)) {
|
if (Immutable.List.isList(nSubItems)) {
|
||||||
nSubItems = nSubItems.length;
|
nSubItems = nSubItems.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
let subItemsLabel = formatMessage(gridMessages[this.props.subItemsLabel], { itemCount: nSubItems });
|
let subItemsLabel = formatMessage(gridMessages[this.props.subItemsLabel], { itemCount: nSubItems });
|
||||||
@ -48,7 +48,7 @@ class GridItemCSSIntl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridItemCSSIntl.propTypes = {
|
GridItemCSSIntl.propTypes = {
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.instanceOf(Immutable.Map).isRequired,
|
||||||
itemsType: PropTypes.string.isRequired,
|
itemsType: PropTypes.string.isRequired,
|
||||||
itemsLabel: PropTypes.string.isRequired,
|
itemsLabel: PropTypes.string.isRequired,
|
||||||
subItemsType: PropTypes.string.isRequired,
|
subItemsType: PropTypes.string.isRequired,
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component, PropTypes } from "react";
|
|||||||
import CSSModules from "react-css-modules";
|
import CSSModules from "react-css-modules";
|
||||||
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
|
||||||
import FontAwesome from "react-fontawesome";
|
import FontAwesome from "react-fontawesome";
|
||||||
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import { messagesMap } from "../../utils";
|
import { messagesMap } from "../../utils";
|
||||||
|
|
||||||
@ -45,12 +46,12 @@ class WebPlayerCSSIntl extends Component {
|
|||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<div className="row" styleName="artRow" onMouseOver={this.artOpacityHandler} onMouseOut={this.artOpacityHandler}>
|
<div className="row" styleName="artRow" onMouseOver={this.artOpacityHandler} onMouseOut={this.artOpacityHandler}>
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<img src={this.props.song.art} width="200" height="200" ref="art" styleName="art" />
|
<img src={this.props.song.get("art")} width="200" height="200" alt={formatMessage(webplayerMessages["app.common.art"])} ref="art" styleName="art" />
|
||||||
<h2>{this.props.song.title}</h2>
|
<h2>{this.props.song.get("title")}</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<span className="text-capitalize">
|
<span className="text-capitalize">
|
||||||
<FormattedMessage {...webplayerMessages["app.webplayer.by"]} />
|
<FormattedMessage {...webplayerMessages["app.webplayer.by"]} />
|
||||||
</span> {this.props.song.artist}
|
</span> {this.props.song.get("artist")}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -89,7 +90,7 @@ class WebPlayerCSSIntl extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WebPlayerCSSIntl.propTypes = {
|
WebPlayerCSSIntl.propTypes = {
|
||||||
song: PropTypes.object.isRequired,
|
song: PropTypes.instanceOf(Immutable.Map).isRequired,
|
||||||
isPlaying: PropTypes.bool.isRequired,
|
isPlaying: PropTypes.bool.isRequired,
|
||||||
isRandom: PropTypes.bool.isRequired,
|
isRandom: PropTypes.bool.isRequired,
|
||||||
isRepeat: PropTypes.bool.isRequired,
|
isRepeat: PropTypes.bool.isRequired,
|
||||||
|
@ -7,7 +7,7 @@ import { messagesMap } from "../../utils";
|
|||||||
import commonMessages from "../../locales/messagesDescriptors/common";
|
import commonMessages from "../../locales/messagesDescriptors/common";
|
||||||
import messages from "../../locales/messagesDescriptors/layouts/Sidebar";
|
import messages from "../../locales/messagesDescriptors/layouts/Sidebar";
|
||||||
|
|
||||||
import WebPlayer from "../../containers/WebPlayer";
|
import WebPlayer from "../../views/WebPlayer";
|
||||||
|
|
||||||
import css from "../../styles/layouts/Sidebar.scss";
|
import css from "../../styles/layouts/Sidebar.scss";
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ module.exports = {
|
|||||||
"app.api.emptyResponse": "Empty response text.", // Empty response from the API
|
"app.api.emptyResponse": "Empty response text.", // Empty response from the API
|
||||||
"app.api.error": "Unknown API error.", // An unknown error occurred from the API
|
"app.api.error": "Unknown API error.", // An unknown error occurred from the API
|
||||||
"app.common.album": "{itemCount, plural, one {album} other {albums}}", // Album
|
"app.common.album": "{itemCount, plural, one {album} other {albums}}", // Album
|
||||||
|
"app.common.art": "Art", // Art
|
||||||
"app.common.artist": "{itemCount, plural, one {artist} other {artists}}", // Artist
|
"app.common.artist": "{itemCount, plural, one {artist} other {artists}}", // Artist
|
||||||
"app.common.cancel": "Cancel", // Cancel
|
"app.common.cancel": "Cancel", // Cancel
|
||||||
"app.common.close": "Close", // Close
|
"app.common.close": "Close", // Close
|
||||||
|
@ -3,6 +3,7 @@ module.exports = {
|
|||||||
"app.api.emptyResponse": "Réponse vide reçue.", // Empty response from the API
|
"app.api.emptyResponse": "Réponse vide reçue.", // Empty response from the API
|
||||||
"app.api.error": "Erreur inconnue.", // An unknown error occurred from the API
|
"app.api.error": "Erreur inconnue.", // An unknown error occurred from the API
|
||||||
"app.common.album": "{itemCount, plural, one {album} other {albums}}", // Albums
|
"app.common.album": "{itemCount, plural, one {album} other {albums}}", // Albums
|
||||||
|
"app.common.art": "Pochette", // Art
|
||||||
"app.common.artist": "{itemCount, plural, one {artiste} other {artistes}}", // Artists
|
"app.common.artist": "{itemCount, plural, one {artiste} other {artistes}}", // Artists
|
||||||
"app.common.cancel": "Annuler", // Cancel
|
"app.common.cancel": "Annuler", // Cancel
|
||||||
"app.common.close": "Fermer", // Close
|
"app.common.close": "Fermer", // Close
|
||||||
|
@ -14,6 +14,11 @@ const messages = [
|
|||||||
description: "Go",
|
description: "Go",
|
||||||
defaultMessage: "Go"
|
defaultMessage: "Go"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "app.common.art",
|
||||||
|
description: "Art",
|
||||||
|
defaultMessage: "Art"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "app.common.artist",
|
id: "app.common.artist",
|
||||||
description: "Artist",
|
description: "Artist",
|
||||||
|
@ -99,7 +99,7 @@ button.toggle {
|
|||||||
*/
|
*/
|
||||||
.main-panel {
|
.main-panel {
|
||||||
padding: $mainPadding;
|
padding: $mainPadding;
|
||||||
z-index: -10; /** TODO: z-index issue */
|
z-index: -10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,9 +43,9 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
// Get songs
|
// Get songs
|
||||||
const tracks = album.get("tracks");
|
const tracks = album.get("tracks");
|
||||||
if (Immutable.List.isList(tracks)) {
|
if (Immutable.List.isList(tracks)) {
|
||||||
songs = new Immutable.Map(
|
songs = new Immutable.List(
|
||||||
tracks.map(
|
tracks.map(
|
||||||
id => [id, state.api.entities.getIn(["track", id])]
|
id => state.api.entities.getIn(["track", id])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -18,22 +18,17 @@ export class ArtistPage extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
if (this.props.artist) {
|
|
||||||
return (
|
return (
|
||||||
<Artist artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
|
<Artist isFetching={this.props.isFetching} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<div></div>
|
|
||||||
); // TODO: Loading
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const artists = state.api.entities.get("artist");
|
const artists = state.api.entities.get("artist");
|
||||||
let artist = undefined;
|
let artist = undefined;
|
||||||
let albums = new Immutable.List();
|
let albums = new Immutable.Map();
|
||||||
let songs = new Immutable.List();
|
let songs = new Immutable.Map();
|
||||||
if (artists) {
|
if (artists) {
|
||||||
// Get artist
|
// Get artist
|
||||||
artist = artists.find(
|
artist = artists.find(
|
||||||
@ -59,6 +54,7 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
isFetching: state.api.isFetching,
|
||||||
artist: artist,
|
artist: artist,
|
||||||
albums: albums,
|
albums: albums,
|
||||||
songs: songs
|
songs: songs
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
import Immutable from "immutable";
|
||||||
|
|
||||||
import WebPlayerComponent from "../components/elements/WebPlayer";
|
import WebPlayerComponent from "../components/elements/WebPlayer";
|
||||||
|
|
||||||
|
|
||||||
export default class WebPlayer extends Component {
|
export default class WebPlayer extends Component {
|
||||||
render () {
|
render () {
|
||||||
const webplayerProps = {
|
const webplayerProps = {
|
||||||
song: {
|
song: new Immutable.Map({
|
||||||
art: "http://albumartcollection.com/wp-content/uploads/2011/07/summer-album-art.jpg",
|
art: "http://albumartcollection.com/wp-content/uploads/2011/07/summer-album-art.jpg",
|
||||||
title: "Tel-ho",
|
title: "Tel-ho",
|
||||||
artist: "Lapso Laps",
|
artist: "Lapso Laps",
|
||||||
},
|
}),
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
isRandom: false,
|
isRandom: false,
|
||||||
isRepeat: true
|
isRepeat: true
|
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