|
|
@@ -27,6 +27,32 @@ function CategoryFlatList(props) {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+function formatDuration(duration) {
|
|
|
+ var seconds = duration % 60;
|
|
|
+ const minutes = Math.floor(duration / 60);
|
|
|
+ if (seconds < 10) {
|
|
|
+ seconds = '0' + seconds;
|
|
|
+ }
|
|
|
+ return minutes + ':' + seconds;
|
|
|
+}
|
|
|
+
|
|
|
+function mapAlbums(items) {
|
|
|
+ var artists = [], curArtist = {}, curType = {};
|
|
|
+ for (const album of items) {
|
|
|
+ if (album.artist !== curArtist.name) {
|
|
|
+ curArtist = {name: album.artist, types: []}
|
|
|
+ curType = {}
|
|
|
+ artists.push(curArtist)
|
|
|
+ }
|
|
|
+ if (album.type !== curType.type) {
|
|
|
+ curType = {type: album.type, albums: []}
|
|
|
+ curArtist.types.push(curType)
|
|
|
+ }
|
|
|
+ curType.albums.push(album);
|
|
|
+ }
|
|
|
+ return artists;
|
|
|
+}
|
|
|
+
|
|
|
function AlbumList(props) {
|
|
|
const { error, isLoaded, items } = props.state;
|
|
|
|
|
|
@@ -36,16 +62,35 @@ function AlbumList(props) {
|
|
|
} else if (!isLoaded) {
|
|
|
content = <div>Loading</div>
|
|
|
} else {
|
|
|
- content = (
|
|
|
- <ul>
|
|
|
- {items.map(item => (
|
|
|
- <li key={item.id}>{item.artist} - {item.year} - {item.album}</li>
|
|
|
+ const artists = mapAlbums(items);
|
|
|
+
|
|
|
+ content = artists.map(artist => (
|
|
|
+ <div key={artist.name}>
|
|
|
+ <h3>{artist.name}</h3>
|
|
|
+ {artist.types.map(type => (
|
|
|
+ <div key={type.type}>
|
|
|
+ <h4>{type.type}</h4>
|
|
|
+ <table><tbody>
|
|
|
+ {type.albums.map(album => (
|
|
|
+ <tr key={album.id}>
|
|
|
+ <td><img src={album.cover} alt={album.album} /></td>
|
|
|
+ <td>{album.year}</td>
|
|
|
+ <td>{album.album}</td>
|
|
|
+ <td>{album.publisher}</td>
|
|
|
+ <td>{album.country}</td>
|
|
|
+ <td>{album.genre}</td>
|
|
|
+ <td>{album.track_count}</td>
|
|
|
+ <td>{formatDuration(album.total_duration)}</td>
|
|
|
+ </tr>
|
|
|
+ ))}
|
|
|
+ </tbody></table>
|
|
|
+ </div>
|
|
|
))}
|
|
|
- </ul>
|
|
|
- );
|
|
|
+ </div>
|
|
|
+ ))
|
|
|
}
|
|
|
return (
|
|
|
- <div className="AlbumList">
|
|
|
+ <div className="AlbumList">
|
|
|
<h2>{props.title}</h2>
|
|
|
{content}
|
|
|
</div>
|
|
|
@@ -142,12 +187,12 @@ class Player extends Component {
|
|
|
}
|
|
|
render() {
|
|
|
return (
|
|
|
- <div>
|
|
|
+ <div className="Player">
|
|
|
<div className="PlayerFilters">
|
|
|
{this.categories.map(({type, title}) => (
|
|
|
- <CategoryFlatList key={type} title={title} state={this.state[type]} onChange={e => this.handleCategoryChange(type, e.target.value)}/>
|
|
|
- ))}
|
|
|
- </div><div style={{clear:'both', paddingBottom:'20px'}}/>
|
|
|
+ <CategoryFlatList key={type} title={title} state={this.state[type]} onChange={e => this.handleCategoryChange(type, e.target.value)}/>
|
|
|
+ ))}
|
|
|
+ </div><div style={{clear:'both', paddingBottom:'20px'}}/>
|
|
|
<input type="text" placeholder="Search albums" onChange={this.handleFilterChange} size={150} />
|
|
|
<AlbumList title="Albums" state={this.state.album} />
|
|
|
</div>
|
|
|
@@ -163,7 +208,7 @@ class App extends Component {
|
|
|
<img src={logo} className="App-logo" alt="logo" />
|
|
|
<h1 className="App-title">Chad Music</h1>
|
|
|
</header>
|
|
|
- <Player/>
|
|
|
+ <Player />
|
|
|
</div>
|
|
|
);
|
|
|
}
|