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

View File

@ -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
};

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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";

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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])
)
);
}

View File

@ -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

View File

@ -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