import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { Route, Switch } from 'react-router-dom'; import ErrorMessage from '../components/ErrorMessage'; import Link from '../components/Link'; import TrackList from '../components/TrackList'; import AlbumGrid from '../components/AlbumGrid'; import Thumbnail from '../components/Thumbnail'; import Parallax from '../components/Parallax'; import ArtistGrid from '../components/ArtistGrid'; import RelatedArtists from '../components/RelatedArtists'; import FollowButton from '../components/Fields/FollowButton'; import ContextMenuTrigger from '../components/ContextMenuTrigger'; import DropdownField from '../components/Fields/DropdownField'; import FilterField from '../components/Fields/FilterField'; import Icon from '../components/Icon'; import Loader from '../components/Loader'; import * as coreActions from '../services/core/actions'; import * as uiActions from '../services/ui/actions'; import * as mopidyActions from '../services/mopidy/actions'; import { uriSource, sourceIcon, titleCase, } from '../util/helpers'; import { collate } from '../util/format'; import { sortItems, applyFilter, arrayOf } from '../util/arrays'; import { i18n, I18n } from '../locale'; import Button from '../components/Button'; import { trackEvent } from '../components/Trackable'; import { makeItemSelector, makeLoadingSelector, } from '../util/selectors'; import { nice_number } from '../components/NiceNumber'; class Artist extends React.Component { constructor(props) { super(props); this.state = { albumsFilter: '', tracksFilter: '', }; } componentDidMount() { const { uri, coreActions: { loadArtist, }, } = this.props; this.setWindowTitle(); loadArtist(uri, { full: true }); } componentDidUpdate = ({ uri: prevUri, artist: prevArtist, }) => { const { uri, artist, coreActions: { loadArtist, }, } = this.props; if (uri !== prevUri) { loadArtist(uri, { full: true }); } if (!prevArtist && artist) this.setWindowTitle(artist); if (prevUri !== uri && artist) this.setWindowTitle(artist); } onChangeTracksFilter = (value) => { this.onChangeFilter('tracks', value); } onChangeAlbumsFilter = (value) => { this.onChangeFilter('albums', value); } onChangeFilter = (type, value) => { const { uiActions: { set, hideContextMenu } } = this.props; set({ [`artist_${type}_filter`]: value }); hideContextMenu(); trackEvent({ category: 'Artist', action: `Filter${type}`, label: value }); } onChangeTracksSort = (value) => { this.onChangeSort('tracks', value); } onChangeAlbumsSort = (value) => { this.onChangeSort('albums', value); } onChangeSort = (type, value) => { const { [`${type}_sort`]: sort, [`${type}_sort_reverse`]: sort_reverse, uiActions: { set, hideContextMenu, }, } = this.props; let reverse = false; if (value !== null && sort === value) { reverse = !sort_reverse; } set({ [`artist_${type}_sort_reverse`]: reverse, [`artist_${type}_sort`]: value, }); hideContextMenu(); trackEvent({ category: 'Artist', action: `Sort${type}`, label: `${value} ${reverse ? 'DESC' : 'ASC'}` }); } onPlayAll = () => { const { artist: { uri, tracks, albums_uris, }, uiActions: { createNotification, }, mopidyActions: { playURIs, }, } = this.props; if ((!albums_uris || !albums_uris.length) && (!tracks || !tracks.length)) { createNotification({ content: i18n('errors.no_results'), level: 'warning' }); return; } playURIs(arrayOf('uri', tracks) || albums_uris, uri); } setWindowTitle = (artist = this.props.artist) => { const { uiActions: { setWindowTitle } } = this.props; if (artist) { setWindowTitle(i18n('artist.title_window', { name: artist.name })); } else { setWindowTitle(i18n('artist.title')); } } handleContextMenu = (e) => { const { artist, uri, uiActions: { showContextMenu }, } = this.props; showContextMenu({ e, context: 'artist', items: [artist], uris: [uri], tracklist_uri: uri, }); } inLibrary = () => { const { uri } = this.props; const libraryName = `${uriSource(uri)}_library_artists`; const { [libraryName]: { items_uris } } = this.props; return items_uris.indexOf(uri) > -1; } renderOverview = () => { const { uri, uiActions, artist, albums_sort: sort, albums_sort_reverse: sort_reverse, filterType, } = this.props; const { albumsFilter: filter, } = this.state; let { tracks, related_artists, } = artist; let { albums } = this.props; if (sort && albums) { albums = sortItems(albums, sort, sort_reverse); } if (filterType && albums) { albums = applyFilter('type', filterType, albums); } if (filter && filter !== '') { albums = applyFilter('name', filter, albums); } const sort_options = [ { value: null, label: i18n('artist.albums.sort.default'), }, { value: 'name', label: i18n('artist.albums.sort.name'), }, { value: 'release_date', label: i18n('artist.albums.sort.release_date'), }, { value: 'tracks', label: i18n('artist.albums.sort.track_count'), }, ]; const filter_type_options = [ { value: null, label: i18n('artist.albums.filter.all'), }, { value: 'album', label: i18n('artist.albums.filter.albums'), }, { value: 'single', label: i18n('artist.albums.filter.singles'), }, ]; return (