transcend-spotify-components-react
Version:
Various react components to display spotify data using Transcend
693 lines (567 loc) • 18.5 kB
JavaScript
import React from 'react'
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import {imageFormatter} from 'transcend-formats';
import {SpotifyIdColumn, SpotifyGenresColumn, SpotifyNumTracksColumn, SpotifyPublicColumn, SpotifyTimestampColumn,
SpotifyIndexColumn, SpotifyNameColumn, SpotifyAlbumColumn, SpotifyArtistColumn, SpotifyAlbumArtColumn, SpotifyDurationRawColumn,
SpotifyUserSavedTracksCsvColumn, SpotifyPlayedAtColumn, SpotifyTrackNumberColumn, SpotifyContextTypeColumn,
SpotifyUserSavedTracksIndicatorColumn, SpotifyAddedAtColumn, SpotifyAcousticnessColumn, SpotifyDanceabilityColumn,
SpotifyDurationColumn, SpotifyEnergyColumn, SpotifyInstrumentalnessColumn, SpotifyKeyColumn, SpotifyLivenessColumn,
SpotifyLoudnessColumn, SpotifySpeechinessColumn, SpotifyTempoColumn, SpotifySignatureColumn, SpotifyValenceColumn,
SpotifyPopularityColumn, SpotifyUserSavedTracksColumns} from 'transcend-spotify-columns-react'
import {collapseObjectAttribute, collapseObjectArrayToCsv, splitObjectArrayToOrderedElements,
splitObjectArrayToIndicators, mergeOnElement, maxAttribute} from 'transcend-helpers'
import { TranscendChart } from 'transcend-plots-react'
class SpotifyComponent extends React.Component {
state = {
options : {
paginationSize: 10,
sizePerPage: 30,
onRowClick: function(row, col){
if(col && row.previewUrl) window.open(row.previewUrl, '_blank')
else if(col && row.uri) window.open(row.uri);
}
}
}
constructor(props) {
super(props)
if(props.options) {
this.state.options = props.options
}
}
plot(plotOptions) {
return <div/>;
}
render() {
return <div>
<BootstrapTable className="bootstrap-table" data={this.props.display} striped={true} hover={true} options={ this.state.options } pagination>
{(() => {
return this.props.columns.map((Column, ind) => {
return (new Column()).renderColumn();
});
})()}
</BootstrapTable>
</div>;
}
}
class SpotifyAllComponent extends React.Component {
state = {
options : {
paginationSize: 10,
sizePerPage: 30,
onRowClick: function(row, col){
if(col && row.previewUrl) window.open(row.previewUrl, '_blank')
else if(col && row.uri) window.open(row.uri);
}
}
}
constructor(props) {
super(props)
if(props.options) {
this.state.options = props.options
}
}
render() {
return <div>
<BootstrapTable className="bootstrap-table" data={this.props.display} striped={true} hover={true} options={ this.state.options } pagination>
<TableHeaderColumn dataField="id" isKey={true} dataAlign="center" hidden>id</TableHeaderColumn>
{(() => {
return this.props.columns.map((tuple) => {
let Column = tuple[0];
let key = tuple[1];
return (new Column({
displayState : this.props.displayState[key],
user : this.props.user,
})).renderColumn();
});
})()}
</BootstrapTable>
</div>;
}
}
class SpotifySavedTracksComponent extends React.Component {
state = {
key : "savedTracks",
displayName: "Saved Tracks",
headers : ['friends'],
columns : [
SpotifyIdColumn, SpotifyAlbumArtColumn, SpotifyNameColumn, SpotifyAlbumColumn, SpotifyArtistColumn, SpotifyAcousticnessColumn,
SpotifyDanceabilityColumn, SpotifyDurationColumn, SpotifyEnergyColumn, SpotifyInstrumentalnessColumn,
SpotifyKeyColumn, SpotifyLivenessColumn, SpotifyLoudnessColumn, SpotifySpeechinessColumn,
SpotifyTempoColumn, SpotifySignatureColumn, SpotifyValenceColumn, SpotifyPopularityColumn, SpotifyAddedAtColumn
],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let savedTracksDisplay = [...user.savedTracks];
let maxArtists = maxAttribute(savedTracksDisplay, 'artists');
// Process each track
savedTracksDisplay = savedTracksDisplay.map((track) => {
// Collapse metadata
track = collapseObjectAttribute(track, 'metaData');
// Collapse artist
if(typeof(track.artists) === "object"){
track = splitObjectArrayToOrderedElements(track, 'artists', maxArtists);
track = collapseObjectArrayToCsv(track, 'artists');
}
// Convert str to date
track.addedAt = new Date(track.addedAt);
return track;
});
this.state.data = savedTracksDisplay
return savedTracksDisplay;
}
plot(plotOptions){
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifyFollowedArtistsComponent extends React.Component {
state = {
key : "followedArtists",
dislayName : "Followed Artists",
headers : ['friends'],
columns : [SpotifyIdColumn, SpotifyNameColumn, SpotifyGenresColumn, SpotifyPopularityColumn],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let followedArtistsDisplay = [...user.followedArtists];
let maxGenres = maxAttribute(followedArtistsDisplay, 'genres');
return followedArtistsDisplay.map((artist) => {
// Collapse genres
if(typeof(artist.genres) === "object"){
artist = splitObjectArrayToOrderedElements(artist, 'genres', maxGenres);
artist = collapseObjectArrayToCsv(artist, 'genres');
}
return artist;
});
}
plot(plotOptions){
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifySavedPlaylistsComponent extends React.Component {
state = {
key : "savedPlaylists",
displayName : "Saved Playlists",
headers : ['friends'],
columns : [SpotifyIdColumn, SpotifyNameColumn, SpotifyNumTracksColumn, SpotifyPublicColumn, SpotifyTimestampColumn],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let savedPlaylistsDisplay = [...user.savedPlaylists];
savedPlaylistsDisplay = savedPlaylistsDisplay.map((playlist) => {
playlist.timestamp = new Date(playlist.timestamp);
return playlist;
});
this.state.data = savedPlaylistsDisplay;
return savedPlaylistsDisplay;
}
plot(plotOptions){
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifyTopTracksComponent extends React.Component {
state = {
key : "topTracks",
displayName : "Top Tracks",
headers : ['friends', 'pullHistory'],
columns : [SpotifyIdColumn, SpotifyIndexColumn, SpotifyNameColumn, SpotifyAlbumColumn, SpotifyArtistColumn, SpotifyPopularityColumn],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let topTracksDisplay = [...user.topTracks];
topTracksDisplay = topTracksDisplay.map((trackPull) => {
let maxArtists = maxAttribute(trackPull.tracks, 'artists');
trackPull.tracks = trackPull.tracks.map((track, ind) => {
track.index = ind + 1;
// Collapse artist
if(typeof(track.artists) === "object"){
track = splitObjectArrayToOrderedElements(track, 'artists', maxArtists);
track = collapseObjectArrayToCsv(track, 'artists');
}
return track;
})
trackPull.timePulled = new Date(trackPull.timePulled);
return trackPull;
})
this.state.data = topTracksDisplay[0].tracks;
return topTracksDisplay[0].tracks;
}
plot(plotOptions){
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifyTopArtistsComponent extends React.Component {
state = {
key : "topArtists",
displayName : "Top Artists",
headers : ['friends', 'pullHistory'],
columns : [SpotifyIdColumn, SpotifyIndexColumn, SpotifyNameColumn, SpotifyGenresColumn, SpotifyPopularityColumn],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let topArtistsDisplay = [...user.topArtists];
topArtistsDisplay = topArtistsDisplay.map((artistPull) => {
let maxGenres = maxAttribute(artistPull.artists, 'genres');
artistPull.artists = artistPull.artists.map((artist, ind) => {
artist.index = ind + 1;
// Collapse genres
if(typeof(artist.genres) === "object"){
artist = splitObjectArrayToOrderedElements(artist, 'genres', maxGenres);
artist = collapseObjectArrayToCsv(artist, 'genres');
}
return artist;
})
artistPull.timePulled = new Date(artistPull.timePulled);
return artistPull;
});
this.state.data = topArtistsDisplay[0].artists;
return topArtistsDisplay[0].artists;
}
plot(plotOptions){
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifyPlayHistoryComponent extends React.Component {
state = {
key : "playHistory",
displayName : "Play History",
headers : ['friends'],
columns : [SpotifyIdColumn, SpotifyIndexColumn, SpotifyPlayedAtColumn, SpotifyContextTypeColumn,
SpotifyDurationRawColumn, SpotifyNameColumn, SpotifyPopularityColumn, SpotifyTrackNumberColumn,
SpotifyArtistColumn],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let user = (this.props.user.getDisplayUser ? this.props.user.getDisplayUser() : this.props.user);
let playHistoryDisplay = [...user.playHistory];
playHistoryDisplay = playHistoryDisplay.map((track, ind) => {
track.index = ind;
track.context_uri = (track.context ? track.context.uri : null);
track.context_type = (track.context ? track.context.type : null);
track.duration_ms = track.track.duration_ms;
track.explicit = track.track.explicit;
track.name = track.track.name;
track.id = track.track.id;
track.popularity = track.track.popularity;
track.preview_url = track.track.preview_url;
track.track_number = track.track.track_number;
track.artists = track.track.artists;
track.played_at = new Date(track.played_at);
return track;
})
let maxArtists = maxAttribute(playHistoryDisplay, 'artists');
playHistoryDisplay = playHistoryDisplay.map((track, ind) => {
// Collapse artist
if(typeof(track.artists) === "object"){
track = splitObjectArrayToOrderedElements(track, 'artists', maxArtists, false, ["name", "id"]);
track = collapseObjectArrayToCsv(track, 'artists', 'name');
}
return track;
});
this.state.data = playHistoryDisplay;
return playHistoryDisplay;
}
plot(plotOptions) {
return <div/>;
}
render(){
return <SpotifyComponent display={this.state.data} columns={this.state.columns} />;
}
}
class SpotifyAllTracksComponent extends React.Component {
state = {
key : "allTracks",
displayName : "All Tracks",
headers : ['collapser'],
columns : [
[SpotifyNameColumn, "name"],
[SpotifyAlbumColumn, "album"],
[SpotifyArtistColumn, "artist"],
[SpotifyAlbumArtColumn, "albumArt"],
[SpotifyUserSavedTracksColumns, "savedTracks_Users"],
// [SpotifyAddedAtColumn, "addedAt"],
[SpotifyAcousticnessColumn, "metaData_acousticness"],
[SpotifyDanceabilityColumn, "metaData_danceability"],
[SpotifyDurationColumn, "metaData_duration"],
[SpotifyEnergyColumn, "metaData_energy"],
[SpotifyInstrumentalnessColumn, "metaData_instrumentalness"],
[SpotifyKeyColumn, "metaData_key"],
[SpotifyLivenessColumn, "metaData_liveness"],
[SpotifyLoudnessColumn, "metaData_loudness"],
[SpotifySpeechinessColumn, "metaData_speechiness"],
[SpotifyTempoColumn, "metaData_tempo"],
[SpotifySignatureColumn, "metaData_signature"],
[SpotifyValenceColumn, "metaData_valence"],
[SpotifyPopularityColumn, "metaData_popularity"],
],
displayStates : {
name : {
states : ["raw_string"],
displayName: "Name",
plot: []
},
album : {
states : ["raw_string"],
displayName: "Album",
plot: []
},
artist : {
states : ["csv_string"],
displayName: "Artist",
plot: []
},
albumArt : {
states : [],
displayName: "Album Art",
plot: []
},
savedTracks_Users : {
states : ["csv_string", "indicators"],
displayName: "Users Saved Tracks",
plot: []
},
// addedAt : {
// states : ["time_added"],
// displayName: "Added At"
// },
metaData_acousticness : {
states : ["raw"],
displayName: "Acousticness",
plot: ["histogram", "pdf", "cdf"]
},
metaData_danceability : {
states : ["raw"],
displayName: "Danceability",
plot: ["histogram", "pdf", "cdf"]
},
metaData_duration_ms : {
states : ["raw"],
displayName: "Duration",
plot: ["histogram", "pdf", "cdf"]
},
metaData_energy : {
states : ["raw"],
displayName: "Energy",
plot: ["histogram", "pdf", "cdf"]
},
metaData_instrumentalness : {
states : ["raw"],
displayName: "Instrumentalness",
plot: ["histogram", "pdf", "cdf"]
},
metaData_key : {
states : ["raw"],
displayName: "Key",
plot: ["histogram", "pdf", "cdf"]
},
metaData_liveness : {
states : ["raw"],
displayName: "Liveness",
plot: ["histogram", "pdf", "cdf"]
},
metaData_loudness : {
states : ["raw"],
displayName: "Loudness",
plot: ["histogram", "pdf", "cdf"]
},
metaData_speechiness : {
states : ["raw"],
displayName: "Speechiness",
plot: ["histogram", "pdf", "cdf"]
},
metaData_tempo : {
states : ["raw"],
displayName: "Tempo",
plot: ["histogram", "pdf", "cdf"]
},
metaData_time_signature : {
states : ["raw"],
displayName: "Signature",
plot: ["histogram", "pdf", "cdf"]
},
metaData_valence : {
states : ["raw"],
displayName: "Valence",
plot: ["histogram", "pdf", "cdf"]
},
popularity : {
states : ["raw"],
displayName: "Popularity",
plot: ["histogram", "pdf", "cdf"]
},
},
displayState : {
name : ["raw_string"],
album : ["raw_string"],
artist : ["csv_string"],
albumArt : [],
savedTracks_Users : ["csv_string"],
// addedAt : ["time_added"],
metaData_acousticness : ["raw"],
metaData_danceability : ["raw"],
metaData_duration_ms : ["raw"],
metaData_energy : ["raw"],
metaData_instrumentalness : ["raw"],
metaData_key : ["raw"],
metaData_liveness : ["raw"],
metaData_loudness : ["raw"],
metaData_speechiness : ["raw"],
metaData_tempo : ["raw"],
metaData_time_signature : ["raw"],
metaData_valence : ["raw"],
popularity : ["raw"]
},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let users = [this.props.user.data].concat(this.props.user.friends);
users = users.map((user) => {
return {
"name" : user.details.display_name,
"userId" : user.userId,
"savedTracks" : (new SpotifySavedTracksComponent({user : user})).preProcess(),
"topTracks" : (new SpotifyTopTracksComponent({user : user})).preProcess(),
"playHistory" : (new SpotifyPlayHistoryComponent({user : user})).preProcess()
};
});
let allTracks = mergeOnElement(users, "savedTracks", "id", ["userId", "name"], "savedTracks_Users");
allTracks = splitObjectArrayToIndicators(allTracks, 'savedTracks_Users', users, 'userId', 'name');
allTracks = allTracks.map((track) => {
track = collapseObjectArrayToCsv(track, 'savedTracks_Users', 'name');
return track;
});
this.state.data = allTracks;
return allTracks;
}
plot(plotOptions) {
return <TranscendChart data={this.state.data} plotOptions={plotOptions} parent={this.props.parent}/>;
}
render(){
return <SpotifyAllComponent display={this.state.data} user={this.props.user} columns={this.state.columns} displayState={this.state.displayState}/>;
}
}
class SpotifyAllArtistsComponent extends React.Component {
state = {
key : "allArtists",
displayName : "All Artists",
headers : [],
columns : [],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let artistDisplay = [];
this.state.data = artistDisplay;
return artistDisplay;
}
plot(plotOptions) {
return <div/>;
}
render(){
return <SpotifyAllComponent user={this.state.data} display={this.state.data} columns={this.state.columns} displayState={this.state.displayState}/>;
}
}
class SpotifyAllFriendsComponent extends React.Component {
state = {
key : "allFriends",
displayName : "All Friends",
headers : [],
columns : [],
displayStates : {},
displayState : {},
data : []
}
constructor(props) {
super(props)
if (this.state.data.length === 0) this.preProcess();
}
preProcess(){
let friendsDisplay = [];
this.state.data = friendsDisplay;
return friendsDisplay;
}
plot(plotOptions) {
return <div/>;
}
render(){
return <SpotifyAllComponent user={this.props.user} display={this.state.data} columns={this.state.columns} displayState={this.state.displayState}/>;
}
}
module.exports = {
SpotifyComponent : SpotifyComponent,
SpotifyAllComponent : SpotifyAllComponent,
SpotifySavedTracksComponent : SpotifySavedTracksComponent,
SpotifyFollowedArtistsComponent : SpotifyFollowedArtistsComponent,
SpotifySavedPlaylistsComponent : SpotifySavedPlaylistsComponent,
SpotifyTopTracksComponent : SpotifyTopTracksComponent,
SpotifyTopArtistsComponent : SpotifyTopArtistsComponent,
SpotifyPlayHistoryComponent : SpotifyPlayHistoryComponent,
SpotifyAllTracksComponent : SpotifyAllTracksComponent,
SpotifyAllArtistsComponent : SpotifyAllArtistsComponent,
SpotifyAllFriendsComponent : SpotifyAllFriendsComponent
}