You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
5.4 KiB
130 lines
5.4 KiB
import React from 'react'; |
|
import { TableContainer, Table, TableHead, TableRow, TableCell, Paper, makeStyles, TableBody, Chip, Box, Button } from '@material-ui/core'; |
|
import stringifyList from '../../lib/stringifyList'; |
|
import { useHistory } from 'react-router'; |
|
import { Artist, QueryResponseTrackDetails, Tag, Name } from '../../api/api'; |
|
|
|
function getTagNames (track: QueryResponseTrackDetails) : string[][] { |
|
// Recursively resolve the name. |
|
const resolveTag = (tag: any) => { |
|
var r = [tag.name]; |
|
if (tag.parent) { r.unshift(resolveTag(tag.parent)); } |
|
return r; |
|
} |
|
|
|
return track.tags.map((tag: Tag) => resolveTag(tag)); |
|
} |
|
|
|
function getTagIds (track: QueryResponseTrackDetails) : number[][] { |
|
// Recursively resolve the id. |
|
const resolveTag = (tag: any) => { |
|
var r = [tag.tagId]; |
|
if (tag.parent) { r.unshift(resolveTag(tag.parent)); } |
|
return r; |
|
} |
|
|
|
return track.tags.map((tag: any) => resolveTag(tag)); |
|
} |
|
|
|
export default function TrackTable(props: { |
|
tracks: QueryResponseTrackDetails[] |
|
}) { |
|
const history = useHistory(); |
|
|
|
const classes = makeStyles({ |
|
button: { |
|
textTransform: "none", |
|
fontWeight: 400, |
|
paddingLeft: '0', |
|
textAlign: 'left', |
|
}, |
|
table: { |
|
minWidth: 650, |
|
}, |
|
})(); |
|
|
|
return ( |
|
<TableContainer component={Paper}> |
|
<Table className={classes.table} aria-label="a dense table"> |
|
<TableHead> |
|
<TableRow> |
|
<TableCell align="left">Title</TableCell> |
|
<TableCell align="left">Artist</TableCell> |
|
<TableCell align="left">Album</TableCell> |
|
<TableCell align="left">Tags</TableCell> |
|
</TableRow> |
|
</TableHead> |
|
<TableBody> |
|
{props.tracks.map((track: QueryResponseTrackDetails) => { |
|
const name = track.name; |
|
// TODO: display artists and albums separately! |
|
const artistNames = track.artists |
|
.filter( (a: Artist) => a.name ) |
|
.map( (a: (Artist & Name)) => a.name ); |
|
const artist = stringifyList(artistNames); |
|
const mainArtistId = |
|
(track.artists.length > 0 && track.artists[0].id) || undefined; |
|
const album = track.album?.name || undefined; |
|
const albumId = track.album?.id || undefined; |
|
const trackId = track.id; |
|
const tagIds = getTagIds(track); |
|
|
|
const onClickArtist = () => { |
|
history.push('/artist/' + mainArtistId); |
|
} |
|
|
|
const onClickAlbum = () => { |
|
history.push('/album/' + albumId || ''); |
|
} |
|
|
|
const onClickTrack = () => { |
|
history.push('/track/' + trackId); |
|
} |
|
|
|
const onClickTag = (id: number, name: string) => { |
|
history.push('/tag/' + id); |
|
} |
|
|
|
const tags = getTagNames(track).map((tag: string[], i: number) => { |
|
const fullTag = stringifyList(tag, undefined, (idx: number, e: string) => { |
|
return (idx === 0) ? e : " / " + e; |
|
}) |
|
return <Box ml={0.5} mr={0.5}> |
|
<Chip size="small" |
|
label={fullTag} |
|
onClick={() => onClickTag(tagIds[i][tagIds[i].length - 1], fullTag)} |
|
/> |
|
</Box> |
|
}); |
|
|
|
const TextCell = (props: any) => { |
|
return <TableCell padding="none" {...props}> |
|
<Button className={classes.button} fullWidth={true} onClick={props._onClick}> |
|
<Box |
|
width="100%" |
|
display="flex" |
|
alignItems="center" |
|
paddingLeft="16px" |
|
> |
|
{props.children} |
|
</Box> |
|
</Button> |
|
</TableCell>; |
|
} |
|
|
|
return <TableRow key={name}> |
|
<TextCell align="left" _onClick={onClickTrack}>{name}</TextCell> |
|
<TextCell align="left" _onClick={onClickArtist}>{artist}</TextCell> |
|
{album ? <TextCell align="left" _onClick={onClickAlbum}>{album}</TextCell> : <TextCell/>} |
|
<TableCell padding="none" align="left" width="25%"> |
|
<Box display="flex" alignItems="center"> |
|
{tags} |
|
</Box> |
|
</TableCell> |
|
</TableRow> |
|
})} |
|
</TableBody> |
|
</Table> |
|
</TableContainer> |
|
); |
|
} |