Fix some aria warnings and use immutable everywhere

This commit is contained in:
Lucas Verney 2016-08-06 15:30:03 +02:00
parent 34713cdcde
commit 9d1ef1b0bf
16 changed files with 101 additions and 71 deletions

@ -2,6 +2,7 @@ import React, { Component, PropTypes } from "react";
import CSSModules from "react-css-modules";
import { defineMessages, FormattedMessage } from "react-intl";
import FontAwesome from "react-fontawesome";
import Immutable from "immutable";
import { formatLength, messagesMap } from "../utils";
@ -32,9 +33,8 @@ class AlbumTrackRowCSS extends Component {
}
}
// TODO: Not object
AlbumTrackRowCSS.propTypes = {
track: PropTypes.object.isRequired
track: PropTypes.instanceOf(Immutable.Map).isRequired
};
export let AlbumTrackRow = CSSModules(AlbumTrackRowCSS, css);
@ -56,9 +56,8 @@ class AlbumTracksTableCSS extends Component {
}
}
// TODO: Not object
AlbumTracksTableCSS.propTypes = {
tracks: PropTypes.object.isRequired
tracks: PropTypes.instanceOf(Immutable.List).isRequired
};
export let AlbumTracksTable = CSSModules(AlbumTracksTableCSS, css);
@ -85,10 +84,9 @@ class AlbumRowCSS extends Component {
}
}
// TODO: Not object
AlbumRowCSS.propTypes = {
album: PropTypes.object.isRequired,
songs: PropTypes.object.isRequired
album: PropTypes.instanceOf(Immutable.Map).isRequired,
songs: PropTypes.instanceOf(Immutable.List).isRequired
};
export let AlbumRow = CSSModules(AlbumRowCSS, css);
@ -101,8 +99,7 @@ export default class Album extends Component {
}
}
// TODO: Not object
Album.propTypes = {
album: PropTypes.object.isRequired,
songs: PropTypes.object.isRequired
album: PropTypes.instanceOf(Immutable.Map).isRequired,
songs: PropTypes.instanceOf(Immutable.List).isRequired
};

@ -1,24 +1,51 @@
import React, { Component, PropTypes } from "react";
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 commonMessages from "../locales/messagesDescriptors/common";
import css from "../styles/Artist.scss";
const artistMessages = defineMessages(messagesMap(Array.concat([], commonMessages)));
class ArtistCSS extends Component {
render () {
const loading = (
<div className="row text-center">
<p>
<FontAwesome name="spinner" className="fa-pulse fa-3x fa-fw" aria-hidden="true" />
<span className="sr-only"><FormattedMessage {...artistMessages["app.common.loading"]} /></span>
</p>
</div>
);
if (!this.props.artist) {
// Loading
return loading;
}
let albumsRows = [];
if (this.props.artist.get("albums").size > 0) {
const artistAlbums = this.props.albums;
const artistSongs = this.props.songs;
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 = artistAlbums.get(album);
const songs = album.get("tracks").map(
id => artistSongs.get(id)
album = albums.get(album);
const albumSongs = album.get("tracks").map(
id => songs.get(id)
);
albumsRows.push(<AlbumRow album={album} songs={songs} key={album.get("id")} />);
albumsRows.push(<AlbumRow album={album} songs={albumSongs} key={album.get("id")} />);
});
}
else {
// Loading
albumsRows = loading;
}
return (
<div>
<div className="row" styleName="name">
@ -41,11 +68,11 @@ class ArtistCSS extends Component {
}
}
// TODO: Not object
ArtistCSS.propTypes = {
artist: PropTypes.object.isRequired,
albums: PropTypes.object.isRequired,
songs: PropTypes.object.isRequired
isFetching: PropTypes.bool.isRequired,
artist: PropTypes.instanceOf(Immutable.Map),
albums: PropTypes.instanceOf(Immutable.Map),
songs: PropTypes.instanceOf(Immutable.Map)
};
export default CSSModules(ArtistCSS, css);

@ -43,7 +43,7 @@ class SongsTableRowCSS extends Component {
}
SongsTableRowCSS.propTypes = {
song: PropTypes.object.isRequired
song: PropTypes.instanceOf(Immutable.Map).isRequired
};
export let SongsTableRow = CSSModules(SongsTableRowCSS, css);

@ -25,8 +25,8 @@ class GridItemCSSIntl extends Component {
const {formatMessage} = this.props.intl;
let nSubItems = this.props.item.get(this.props.subItemsType);
if (Array.isArray(nSubItems)) {
nSubItems = nSubItems.length;
if (Immutable.List.isList(nSubItems)) {
nSubItems = nSubItems.size;
}
let subItemsLabel = formatMessage(gridMessages[this.props.subItemsLabel], { itemCount: nSubItems });
@ -48,7 +48,7 @@ class GridItemCSSIntl extends Component {
}
GridItemCSSIntl.propTypes = {
item: PropTypes.object.isRequired,
item: PropTypes.instanceOf(Immutable.Map).isRequired,
itemsType: PropTypes.string.isRequired,
itemsLabel: PropTypes.string.isRequired,
subItemsType: PropTypes.string.isRequired,

@ -2,6 +2,7 @@ import React, { Component, PropTypes } from "react";
import CSSModules from "react-css-modules";
import { defineMessages, injectIntl, intlShape, FormattedMessage } from "react-intl";
import FontAwesome from "react-fontawesome";
import Immutable from "immutable";
import { messagesMap } from "../../utils";
@ -45,12 +46,12 @@ class WebPlayerCSSIntl extends Component {
<div className="col-xs-12">
<div className="row" styleName="artRow" onMouseOver={this.artOpacityHandler} onMouseOut={this.artOpacityHandler}>
<div className="col-xs-12">
<img src={this.props.song.art} width="200" height="200" ref="art" styleName="art" />
<h2>{this.props.song.title}</h2>
<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.get("title")}</h2>
<h3>
<span className="text-capitalize">
<FormattedMessage {...webplayerMessages["app.webplayer.by"]} />
</span> {this.props.song.artist}
</span> {this.props.song.get("artist")}
</h3>
</div>
</div>
@ -89,7 +90,7 @@ class WebPlayerCSSIntl extends Component {
}
WebPlayerCSSIntl.propTypes = {
song: PropTypes.object.isRequired,
song: PropTypes.instanceOf(Immutable.Map).isRequired,
isPlaying: PropTypes.bool.isRequired,
isRandom: PropTypes.bool.isRequired,
isRepeat: PropTypes.bool.isRequired,

@ -7,7 +7,7 @@ import { messagesMap } from "../../utils";
import commonMessages from "../../locales/messagesDescriptors/common";
import messages from "../../locales/messagesDescriptors/layouts/Sidebar";
import WebPlayer from "../../containers/WebPlayer";
import WebPlayer from "../../views/WebPlayer";
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.error": "Unknown API error.", // An unknown error occurred from the API
"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.cancel": "Cancel", // Cancel
"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.error": "Erreur inconnue.", // An unknown error occurred from the API
"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.cancel": "Annuler", // Cancel
"app.common.close": "Fermer", // Close

@ -14,6 +14,11 @@ const messages = [
description: "Go",
defaultMessage: "Go"
},
{
id: "app.common.art",
description: "Art",
defaultMessage: "Art"
},
{
id: "app.common.artist",
description: "Artist",

@ -99,7 +99,7 @@ button.toggle {
*/
.main-panel {
padding: $mainPadding;
z-index: -10; /** TODO: z-index issue */
z-index: -10;
}
/*

@ -43,9 +43,9 @@ const mapStateToProps = (state, ownProps) => {
// Get songs
const tracks = album.get("tracks");
if (Immutable.List.isList(tracks)) {
songs = new Immutable.Map(
songs = new Immutable.List(
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 () {
if (this.props.artist) {
return (
<Artist artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
);
}
return (
<div></div>
); // TODO: Loading
<Artist isFetching={this.props.isFetching} artist={this.props.artist} albums={this.props.albums} songs={this.props.songs} />
);
}
}
const mapStateToProps = (state, ownProps) => {
const artists = state.api.entities.get("artist");
let artist = undefined;
let albums = new Immutable.List();
let songs = new Immutable.List();
let albums = new Immutable.Map();
let songs = new Immutable.Map();
if (artists) {
// Get artist
artist = artists.find(
@ -59,6 +54,7 @@ const mapStateToProps = (state, ownProps) => {
}
}
return {
isFetching: state.api.isFetching,
artist: artist,
albums: albums,
songs: songs

@ -1,15 +1,17 @@
import React, { Component } from "react";
import Immutable from "immutable";
import WebPlayerComponent from "../components/elements/WebPlayer";
export default class WebPlayer extends Component {
render () {
const webplayerProps = {
song: {
song: new Immutable.Map({
art: "http://albumartcollection.com/wp-content/uploads/2011/07/summer-album-art.jpg",
title: "Tel-ho",
artist: "Lapso Laps",
},
}),
isPlaying: false,
isRandom: false,
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