Clicking on artist in results now opens its tab.

pull/20/head
Sander Vocke 5 years ago
parent d4d4c67672
commit e02c99954a
  1. 3
      client/src/components/MainWindow.tsx
  2. 36
      client/src/components/tables/ResultsTable.tsx
  3. 15
      client/src/components/windows/ArtistWindow.tsx
  4. 11
      client/src/components/windows/QueryWindow.tsx

@ -47,6 +47,7 @@ export function MainWindowReducer(state: MainWindowState, action: any) {
activeTab: state.activeTab >= (newSize - 1) ? (newSize - 1) : state.activeTab,
}
case MainWindowStateActions.AddTab:
console.log("Add tab: ", action)
return {
...state,
tabStates: [...state.tabStates, action.tabState],
@ -98,11 +99,13 @@ export default function MainWindow(props: any) {
return <QueryWindow
state={tabState}
dispatch={tabDispatch}
mainDispatch={dispatch}
/>
case WindowType.Artist:
return <ArtistWindow
state={tabState}
dispatch={tabDispatch}
mainDispatch={dispatch}
/>
default:
throw new Error("Unimplemented window type");

@ -1,17 +1,21 @@
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';
export interface SongGetters {
getTitle: (song: any) => string,
getArtist: (song: any) => string,
getAlbum: (song: any) => string,
getTags: (song: any) => string[][], // Each tag is represented as a series of strings.
getArtistNames: (song: any) => string[],
getArtistIds: (song: any) => number[],
getAlbumNames: (song: any) => string[],
getTagNames: (song: any) => string[][], // Each tag is represented as a series of strings.
}
export interface IProps {
songs: any[],
songGetters: SongGetters,
mainDispatch: (action: any) => void,
}
export function SongTable(props: IProps) {
@ -36,9 +40,11 @@ export function SongTable(props: IProps) {
<TableBody>
{props.songs.map((song: any) => {
const title = props.songGetters.getTitle(song);
const artist = props.songGetters.getArtist(song);
const album = props.songGetters.getAlbum(song);
const tags = props.songGetters.getTags(song).map((tag: string[]) => {
// TODO / FIXME: display artists and albums separately!
const artist = stringifyList(props.songGetters.getArtistNames(song));
const mainArtistId = props.songGetters.getArtistIds(song)[0];
const album = stringifyList(props.songGetters.getAlbumNames(song));
const tags = props.songGetters.getTagNames(song).map((tag: string[]) => {
return <Box ml={0.5} mr={0.5}>
<Chip size="small" label={stringifyList(tag, undefined, (idx: number, e: string) => {
return (idx === 0) ? e : " / " + e;
@ -46,6 +52,20 @@ export function SongTable(props: IProps) {
</Box>
});
const onClickArtist = () => {
console.log("onClick!")
props.mainDispatch({
type: MainWindowStateActions.AddTab,
tabState: {
artistId: mainArtistId,
metadata: null,
},
tabLabel: "Artist " + mainArtistId,
tabReducer: newWindowReducer[WindowType.Artist],
tabType: WindowType.Artist,
})
}
const TextCell = (props: any) => {
const classes = makeStyles({
button: {
@ -56,7 +76,7 @@ export function SongTable(props: IProps) {
}
})();
return <TableCell padding="none" {...props}>
<Button className={classes.button} fullWidth={true}>
<Button className={classes.button} fullWidth={true} onClick={props._onClick}>
<Box
width="100%"
display="flex"
@ -71,7 +91,7 @@ export function SongTable(props: IProps) {
return <TableRow key={title}>
<TextCell align="left">{title}</TextCell>
<TextCell align="left">{artist}</TextCell>
<TextCell align="left" _onClick={onClickArtist}>{artist}</TextCell>
<TextCell align="left">{album}</TextCell>
<TableCell padding="none" align="left" width="25%">
<Box display="flex" alignItems="center">

@ -1,5 +1,6 @@
import React, { useEffect } from 'react';
import { Box } from '@material-ui/core';
import { Box, Typography } from '@material-ui/core';
import PersonIcon from '@material-ui/icons/Person';
import * as serverApi from '../../api';
export interface ArtistMetadata {
@ -26,7 +27,8 @@ export function ArtistWindowReducer(state: ArtistWindowState, action: any) {
export interface IProps {
state: ArtistWindowState,
dispatch: (action: any) => void
dispatch: (action: any) => void,
mainDispatch: (action: any) => void,
}
export async function getArtistMetadata(id: number) {
@ -83,9 +85,16 @@ export default function ArtistWindow(props: IProps) {
return <Box width="100%" justifyContent="center" display="flex" flexWrap="wrap">
<Box
m={1}
mt={4}
width="80%"
>
{metadata && metadata.name}
<PersonIcon style={{ fontSize: 80 }}/>
</Box>
<Box
m={1}
width="80%"
>
{metadata && <Typography variant="h4">{metadata.name}</Typography>}
</Box>
</Box>
}

@ -50,7 +50,8 @@ export function QueryWindowReducer(state: QueryWindowState, action: any) {
export interface IProps {
state: QueryWindowState,
dispatch: (action: any) => void
dispatch: (action: any) => void,
mainDispatch: (action: any) => void,
}
export default function QueryWindow(props: IProps) {
@ -72,9 +73,10 @@ export default function QueryWindow(props: IProps) {
const songGetters = {
getTitle: (song: any) => song.title,
getArtist: (song: any) => stringifyList(song.artists, (a: any) => a.name),
getAlbum: (song: any) => stringifyList(song.albums, (a: any) => a.name),
getTags: (song: any) => {
getArtistNames: (song: any) => song.artists.map((a: any) => a.name),
getArtistIds: (song: any) => song.artists.map((a: any) => a.artistId),
getAlbumNames: (song: any) => song.albums.map((a: any) => a.name),
getTagNames: (song: any) => {
// Recursively resolve the name.
const resolveTag = (tag: any) => {
var r = [tag.name];
@ -152,6 +154,7 @@ export default function QueryWindow(props: IProps) {
<SongTable
songs={showResults}
songGetters={songGetters}
mainDispatch={props.mainDispatch}
/>
{loading && <LinearProgress />}
</Box>

Loading…
Cancel
Save