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.
 
 
 
 

164 lines
7.8 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 { MainWindowStateActions } from '../MainWindow';
import { newWindowReducer, WindowType } from '../windows/Windows';
import PersonIcon from '@material-ui/icons/Person';
import AlbumIcon from '@material-ui/icons/Album';
import AudiotrackIcon from '@material-ui/icons/Audiotrack';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
export interface SongGetters {
getTitle: (song: any) => string,
getId: (song: any) => number,
getArtistNames: (song: any) => string[],
getArtistIds: (song: any) => number[],
getAlbumNames: (song: any) => string[],
getAlbumIds: (song: any) => number[],
getTagNames: (song: any) => string[][], // Each tag is represented as a series of strings.
getTagIds: (song: any) => number[][], // Each tag is represented as a series of ids.
}
export interface IProps {
songs: any[],
songGetters: SongGetters,
mainDispatch: (action: any) => void,
}
export function SongTable(props: IProps) {
const useTableStyles = makeStyles({
table: {
minWidth: 650,
},
});
const classes = useTableStyles();
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.songs.map((song: any) => {
const title = props.songGetters.getTitle(song);
// TODO / FIXME: display artists and albums separately!
const artistNames = props.songGetters.getArtistNames(song);
const artist = stringifyList(artistNames);
const mainArtistId = props.songGetters.getArtistIds(song)[0];
const mainArtistName = artistNames[0];
const albumNames = props.songGetters.getAlbumNames(song);
const album = stringifyList(albumNames);
const mainAlbumName = albumNames[0];
const mainAlbumId = props.songGetters.getAlbumIds(song)[0];
const songId = props.songGetters.getId(song);
const tagIds = props.songGetters.getTagIds(song);
const onClickArtist = () => {
props.mainDispatch({
type: MainWindowStateActions.AddTab,
tabState: {
tabLabel: <><PersonIcon />{mainArtistName}</>,
artistId: mainArtistId,
metadata: null,
},
tabReducer: newWindowReducer[WindowType.Artist],
tabType: WindowType.Artist,
})
}
const onClickAlbum = () => {
props.mainDispatch({
type: MainWindowStateActions.AddTab,
tabState: {
tabLabel: <><AlbumIcon />{mainAlbumName}</>,
albumId: mainAlbumId,
metadata: null,
},
tabReducer: newWindowReducer[WindowType.Album],
tabType: WindowType.Album,
})
}
const onClickSong = () => {
props.mainDispatch({
type: MainWindowStateActions.AddTab,
tabState: {
tabLabel: <><AudiotrackIcon />{title}</>,
songId: songId,
metadata: null,
},
tabReducer: newWindowReducer[WindowType.Song],
tabType: WindowType.Song,
})
}
const onClickTag = (id: number, name: string) => {
props.mainDispatch({
type: MainWindowStateActions.AddTab,
tabState: {
tabLabel: <><LocalOfferIcon />{name}</>,
tagId: id,
metadata: null,
},
tabReducer: newWindowReducer[WindowType.Tag],
tabType: WindowType.Tag,
})
}
const tags = props.songGetters.getTagNames(song).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) => {
const classes = makeStyles({
button: {
textTransform: "none",
fontWeight: 400,
paddingLeft: '0',
textAlign: 'left',
}
})();
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={title}>
<TextCell align="left" _onClick={onClickSong}>{title}</TextCell>
<TextCell align="left" _onClick={onClickArtist}>{artist}</TextCell>
<TextCell align="left" _onClick={onClickAlbum}>{album}</TextCell>
<TableCell padding="none" align="left" width="25%">
<Box display="flex" alignItems="center">
{tags}
</Box>
</TableCell>
</TableRow>
})}
</TableBody>
</Table>
</TableContainer>
);
}