import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; function CategoryFlatList(props) { const { error, isLoaded, items } = props.state; var content; if (error) { content =
Error: {error.message}
} else if (!isLoaded) { content =
Loading
} else { content = ( ); } return (

{props.title}

{content}
); } 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; var content; if (error) { content =
Error: {error.message}
} else if (!isLoaded) { content =
Loading
} else { const artists = mapAlbums(items); content = artists.map(artist => (

{artist.name}

{artist.types.map(type => (

{type.type}

{type.albums.map(album => ( ))}
{album.album} {album.year} {album.album} {album.publisher} {album.country} {album.genre} {album.track_count} {formatDuration(album.total_duration)}
))}
)) } return (

{props.title}

{content}
); } class Player extends Component { stateLoading = { error: null, isLoaded: false, items: [] }; constructor(props) { super(props); this.categories = [{type: 'artist', title: 'Artists'}, {type: 'year', title: 'Years'}, {type: 'genre', title: 'Genres'}, {type: 'publisher', title: 'Labels'}, {type: 'country', title: 'Countries'}, {type: 'type', title: 'Album types'}, {type: 'status', title: 'Album statuses'}]; this.state = {}; for (var {type} of this.categories) { this.state[type] = Object.assign({}, this.stateLoading); } this.state.album = Object.assign({}, this.stateLoading); this.filterTimeout = null; } fetchCategory(cat) { const {restrictions, filter} = this.state; function getQueryString(params) { var esc = encodeURIComponent; return Object.keys(params) .map(k => esc(k) + '=' + esc(params[k])) .join('&'); } var params = Object.assign({}, restrictions, {offset:0, limit:100}); if (cat === 'album' && filter) { params.filter = filter; } const qs = getQueryString(params); fetch('/cat/' + cat + (qs ? ('?' + qs) : '')) .then(res => (res.ok ? res.json() : Promise.reject({message:res.statusText}))) .then(result => { this.setState({[cat]: { isLoaded: true, items: result }}); }) .catch(error => { this.setState({[cat]: { isLoaded: true, error: error }}); }); this.setState({[cat]: Object.assign({}, this.stateLoading)}); } fetchAll() { const {restrictions} = this.state; console.log(restrictions); this.categories.map(({type}) => !restrictions[type] && this.fetchCategory(type)) this.fetchCategory('album'); } componentDidMount() { this.setState({restrictions: {}}); } componentDidUpdate(prevProps, prevState) { console.log('stateChange'); if (this.state.restrictions !== prevState.restrictions) { // Reload category filters on restriction changes this.fetchAll(); } else if (this.state.filter !== prevState.filter) { this.fetchCategory('album'); } } handleCategoryChange(type, value) { console.log(type, value); var restrictions = Object.assign({}, this.state.restrictions); if (value) { restrictions[type] = value; } else { delete restrictions[type]; } this.setState({restrictions: restrictions}); } handleFilterChange = (e) => { if (this.filterTimeout) { clearInterval(this.filterTimeout); } const value = e.target.value; this.filterTimeout = setTimeout(() => this.setState({filter:value}), 500); } render() { return (
{this.categories.map(({type, title}) => ( this.handleCategoryChange(type, e.target.value)}/> ))}
); } } class App extends Component { render() { return (
logo

Chad Music

); } } export default App;