Skip to content

Commit

Permalink
Groups albums by type and relation of the artist to them
Browse files Browse the repository at this point in the history
  • Loading branch information
pedro-otero committed Jun 8, 2019
1 parent a94ef7d commit d430516
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 71 deletions.
31 changes: 19 additions & 12 deletions src/components/artist/artist.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import styled from 'styled-components';
Expand Down Expand Up @@ -44,17 +44,24 @@ export class Artist extends React.Component {
failedMessage="Could not load this artist">
<ArtistWork title={name} image={image} background={image} />
<Block>
{albums && albums.length && albums.map(album => (
<Link to={`/album/${album.id}`}>
<AlbumItem>
<Image src={album.image} size="4em" />
<AlbumInfo>
<div>{album.name}</div>
<div>{album.year}</div>
</AlbumInfo>
</AlbumItem>
</Link>
))}
{albums && albums.length && albums.map(category => (
<Fragment>
<h3>{category.name} ({category.items.length})</h3>
<hr />
{category.items.map(album => (
<Link to={`/album/${album.id}`}>
<AlbumItem>
<Image src={album.image} size="4em" />
<AlbumInfo>
<div>{album.name}</div>
<div>{album.year}</div>
</AlbumInfo>
</AlbumItem>
</Link>
))}
<br />
</Fragment>
))}
</Block>
</View>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/artist/artist.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ describe('Artist component', () => {
});

it('renders albums', () => {
const albums = [{ name: 'Albums', items: [{ id: 'AL1' }] }];

const wrapper = shallow(<Artist
name="Someone"
albums={[{ id: 'AL1' }]}
albums={albums}
viewArtist={() => {}} />);

expect(wrapper.find('AlbumItem').length).toEqual(1);
Expand Down
67 changes: 44 additions & 23 deletions src/components/artist/artist.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,51 @@ import { Artist } from './artist';
import { Album } from 'components/Album';

const albums = [{
id: 1,
name: 'Acclaimed Debut',
image: 'https://i.scdn.co/image/edb1577fa1a7b3e9e0f07297071cf6076a1946c3',
year: 2007,
name: 'Albums',
items: [{
id: 1,
name: 'Acclaimed Debut',
image: 'https://i.scdn.co/image/edb1577fa1a7b3e9e0f07297071cf6076a1946c3',
year: 2007,
}, {
id: 1,
name: 'Failing Too High Expectations',
image: 'https://i.scdn.co/image/20fccd3b7b907c57a1f8a21660843bac5967b5e8',
year: 2009,
}, {
id: 1,
name: 'Comeback',
image: 'https://i.scdn.co/image/44272fc0e3bd34b073f34c175dddac5414908730',
year: 2014,
}, {
id: 1,
name: 'Comeback (Deluxe Edition)',
image: 'https://i.scdn.co/image/44272fc0e3bd34b073f34c175dddac5414908730',
year: 2015,
}, {
id: 1,
name: 'Too Big To Fail',
image: 'https://i.scdn.co/image/617f0d587125577484d73dcd6492aa7f027d45b4',
year: 2017,
}],
}, {
id: 1,
name: 'Failing Too High Expectations',
image: 'https://i.scdn.co/image/20fccd3b7b907c57a1f8a21660843bac5967b5e8',
year: 2009,
}, {
id: 1,
name: 'Comeback',
image: 'https://i.scdn.co/image/44272fc0e3bd34b073f34c175dddac5414908730',
year: 2014,
}, {
id: 1,
name: 'Comeback (Deluxe Edition)',
image: 'https://i.scdn.co/image/44272fc0e3bd34b073f34c175dddac5414908730',
year: 2015,
}, {
id: 1,
name: 'Too Big To Fail',
image: 'https://i.scdn.co/image/617f0d587125577484d73dcd6492aa7f027d45b4',
year: 2017,
name: 'Singles',
items: [{
id: 1,
name: 'Chart Topper',
image: 'https://i.scdn.co/image/edb1577fa1a7b3e9e0f07297071cf6076a1946c3',
year: 2017,
}, {
id: 1,
name: 'Too Big To Fail',
image: 'https://i.scdn.co/image/20fccd3b7b907c57a1f8a21660843bac5967b5e8',
year: 2017,
}, {
id: 1,
name: 'Flop',
image: 'https://i.scdn.co/image/44272fc0e3bd34b073f34c175dddac5414908730',
year: 2018,
}],
}];

storiesOf('Artist', module)
Expand Down
46 changes: 34 additions & 12 deletions src/redux/artists.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,31 @@ export function artistToState({ id, name, images }) {
}

export function artistAlbumsToState({ items }) {
return items.map(({
id,
name,
release_date: releaseDate,
images: [firstImage = {}],
}) => ({
id,
name,
year: releaseDate.substring(0, 4),
image: firstImage.url,
}));
const group = (type, isFeatured) => ({
name: `${isFeatured ? 'Featured: ' : ''}${type}s`,
items: items
.filter(album => album.album_type === type.toLowerCase())
.filter(album => album.album_group === (isFeatured ? 'appears_on' : type.toLowerCase()))
.map(({
id,
name,
release_date: releaseDate,
images: [firstImage = {}],
}) => ({
id,
name,
year: releaseDate.substring(0, 4),
image: firstImage.url,
})),
});
return [
group('Album', false),
group('Single', false),
group('Compilation', false),
group('Album', true),
group('Single', true),
group('Compilation', true),
].filter(category => category.items.length > 0);
}

export function setArtistAlbums(id, response) {
Expand Down Expand Up @@ -114,7 +128,15 @@ export const reduce = buildReducer([
}],
[SET_ARTIST_ALBUMS, (state, { data: { id, items, nextPage } }) => {
const artist = state[id];
const jointItems = [...(artist.albums.items || []), ...items];
const currentGroups = artist.albums.items || [];
const newGroups = items.filter(item => !currentGroups.find(group => group.name === item.name));
const jointItems = currentGroups.map((item) => {
const matchingGroup = items.find(group => group.name === item.name) || { items: [] };
return {
...item,
items: item.items.concat(matchingGroup.items),
};
}).concat(newGroups);
return {
...state,
[id]: {
Expand Down
Loading

0 comments on commit d430516

Please sign in to comment.