Artist page improvements (#1391)
* Seperate mobile desktop components * Fix err * Rename classes and fix some styles * Add lastFM button and remove console log * Add Mbiz Icon * render bio as dangerouslySetInnerHTML and remove unused css classes * Add Fav and Stars * Remove unstandardised class selector * Remove ext link from m view * Fix naming and simplify rounded styling * Refactor ArtistShow: - Extracted DesktopArtistDetails to its own file - Removed album count as it was incorrect, it is not considering compilations - Show bio and image from Native API, if it is available, before calling `getArtistInfo` Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
7505b5c554
commit
1d742cf8c7
|
@ -0,0 +1,50 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslate } from 'react-admin'
|
||||||
|
import { IconButton, Tooltip, Link, useMediaQuery } from '@material-ui/core'
|
||||||
|
|
||||||
|
import { ImLastfm2 } from 'react-icons/im'
|
||||||
|
import MusicBrainz from '../icons/MusicBrainz'
|
||||||
|
import { intersperse } from '../utils'
|
||||||
|
|
||||||
|
const ArtistExternalLinks = ({ artistInfo, record }) => {
|
||||||
|
const translate = useTranslate()
|
||||||
|
let links = []
|
||||||
|
let linkButtons = []
|
||||||
|
const lastFMlink = artistInfo?.biography?.match(
|
||||||
|
/<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1/
|
||||||
|
)
|
||||||
|
|
||||||
|
if (lastFMlink) {
|
||||||
|
links.push(lastFMlink[2])
|
||||||
|
}
|
||||||
|
if (artistInfo && artistInfo.musicBrainzId) {
|
||||||
|
links.push(`https://musicbrainz.org/artist/${artistInfo.musicBrainzId}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))
|
||||||
|
|
||||||
|
const addLink = (url, title, icon) => {
|
||||||
|
const translatedTitle = translate(title)
|
||||||
|
const link = (
|
||||||
|
<Link href={url} target="_blank" rel="noopener noreferrer">
|
||||||
|
<Tooltip title={translatedTitle}>
|
||||||
|
<IconButton size={'small'} aria-label={translatedTitle}>
|
||||||
|
{icon}
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
const id = linkButtons.length
|
||||||
|
linkButtons.push(<span key={`link-${record.id}-${id}`}>{link}</span>)
|
||||||
|
}
|
||||||
|
|
||||||
|
isDesktop && addLink(links[0], 'message.openIn.lastfm', <ImLastfm2 />)
|
||||||
|
|
||||||
|
isDesktop &&
|
||||||
|
artistInfo?.musicBrainzId &&
|
||||||
|
addLink(links[1], 'message.openIn.musicbrainz', <MusicBrainz />)
|
||||||
|
|
||||||
|
return isDesktop && <div>{intersperse(linkButtons, ' ')}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArtistExternalLinks
|
|
@ -1,11 +1,6 @@
|
||||||
import React, { useState, useEffect, useCallback } from 'react'
|
import React, { useState, createElement, useEffect } from 'react'
|
||||||
import { Typography, Collapse, Link } from '@material-ui/core'
|
import { useMediaQuery } from '@material-ui/core'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
|
||||||
import Card from '@material-ui/core/Card'
|
|
||||||
import CardContent from '@material-ui/core/CardContent'
|
|
||||||
import CardMedia from '@material-ui/core/CardMedia'
|
|
||||||
import {
|
import {
|
||||||
useTranslate,
|
|
||||||
useShowController,
|
useShowController,
|
||||||
ShowContextProvider,
|
ShowContextProvider,
|
||||||
useRecordContext,
|
useRecordContext,
|
||||||
|
@ -14,152 +9,22 @@ import {
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import AlbumGridView from '../album/AlbumGridView'
|
import AlbumGridView from '../album/AlbumGridView'
|
||||||
|
import MobileArtistDetails from './MobileArtistDetails'
|
||||||
|
import DesktopArtistDetails from './DesktopArtistDetails'
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const ArtistDetails = (props) => {
|
||||||
(theme) => ({
|
const record = useRecordContext(props)
|
||||||
root: {
|
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))
|
||||||
display: 'flex',
|
|
||||||
padding: '1em',
|
|
||||||
'& .MuiTypography-h5': {
|
|
||||||
wordBreak: 'break-word',
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
padding: 'unset',
|
|
||||||
background: ({ img }) => `url(${img})`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
bgContainer: {
|
|
||||||
display: 'flex',
|
|
||||||
width: '100%',
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
height: '15rem',
|
|
||||||
width: '100vw',
|
|
||||||
padding: 'unset',
|
|
||||||
backdropFilter: 'blur(1px)',
|
|
||||||
backgroundPosition: '50% 30%',
|
|
||||||
background: `linear-gradient(to bottom, rgba(52 52 52 / 72%), rgba(21 21 21))`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
albumList: {
|
|
||||||
margin: '20px',
|
|
||||||
display: 'grid',
|
|
||||||
},
|
|
||||||
details: {
|
|
||||||
display: 'flex',
|
|
||||||
flex: '1',
|
|
||||||
flexDirection: 'column',
|
|
||||||
},
|
|
||||||
bioBlock: {
|
|
||||||
display: 'inline-block',
|
|
||||||
marginTop: '1em',
|
|
||||||
float: 'left',
|
|
||||||
wordBreak: 'break-word',
|
|
||||||
cursor: 'pointer',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
margin: '1px',
|
|
||||||
},
|
|
||||||
mdetails: {
|
|
||||||
display: 'none',
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
width: '7rem',
|
|
||||||
marginLeft: '0.5rem',
|
|
||||||
flex: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mbio: {
|
|
||||||
display: 'none',
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
display: 'flex',
|
|
||||||
marginLeft: '3%',
|
|
||||||
marginRight: '3%',
|
|
||||||
zIndex: '1',
|
|
||||||
'& p': {
|
|
||||||
whiteSpace: ({ expanded }) => (expanded ? 'unset' : 'nowrap'),
|
|
||||||
overflow: 'hidden',
|
|
||||||
width: '95vw',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
content: {
|
|
||||||
flex: '1 0 auto',
|
|
||||||
},
|
|
||||||
cover: {
|
|
||||||
width: 151,
|
|
||||||
boxShadow: '0px 0px 6px 0px #565656',
|
|
||||||
borderRadius: '5px',
|
|
||||||
[theme.breakpoints.up('sm')]: {
|
|
||||||
borderRadius: '7em',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
martImage: {
|
|
||||||
marginLeft: '1em',
|
|
||||||
maxHeight: '10rem',
|
|
||||||
backgroundColor: 'inherit',
|
|
||||||
display: 'none',
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
marginTop: '4rem',
|
|
||||||
maxHeight: '7rem',
|
|
||||||
width: '7rem',
|
|
||||||
display: 'flex',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
artImage: {
|
|
||||||
maxHeight: '9.5rem',
|
|
||||||
backgroundColor: 'inherit',
|
|
||||||
display: 'flex',
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
marginTop: '4rem',
|
|
||||||
maxHeight: '7rem',
|
|
||||||
width: '7rem',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
artDetail: {
|
|
||||||
flex: '1',
|
|
||||||
padding: '3%',
|
|
||||||
display: 'flex',
|
|
||||||
minHeight: '10rem',
|
|
||||||
'& .MuiPaper-elevation1': {
|
|
||||||
boxShadow: 'none',
|
|
||||||
padding: '4px',
|
|
||||||
},
|
|
||||||
[theme.breakpoints.down('xs')]: {
|
|
||||||
display: 'none',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
artistSummary: {
|
|
||||||
marginBottom: '1em',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
{ name: 'NDArtistPage' }
|
|
||||||
)
|
|
||||||
|
|
||||||
const ArtistDetails = () => {
|
|
||||||
const [artistInfo, setArtistInfo] = useState()
|
const [artistInfo, setArtistInfo] = useState()
|
||||||
const [expanded, setExpanded] = useState(false)
|
|
||||||
const record = useRecordContext()
|
|
||||||
const artistId = record?.id
|
|
||||||
|
|
||||||
const title = record.name
|
const biography =
|
||||||
let completeBioLink = ''
|
artistInfo?.biography?.replace(new RegExp('<.*>', 'g'), '') ||
|
||||||
const link = artistInfo?.biography?.match(
|
record.biography
|
||||||
/<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1/
|
const img = artistInfo?.largeImageUrl || record.largeImageUrl
|
||||||
)
|
|
||||||
if (link) {
|
|
||||||
completeBioLink = link[2]
|
|
||||||
}
|
|
||||||
const biography = artistInfo?.biography?.replace(new RegExp('<.*>', 'g'), '')
|
|
||||||
const translate = useTranslate()
|
|
||||||
|
|
||||||
const img = artistInfo?.largeImageUrl
|
|
||||||
const classes = useStyles({ img, expanded })
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
subsonic
|
subsonic
|
||||||
.getArtistInfo(artistId)
|
.getArtistInfo(record.id)
|
||||||
.then((resp) => resp.json['subsonic-response'])
|
.then((resp) => resp.json['subsonic-response'])
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.status === 'ok') {
|
if (data.status === 'ok') {
|
||||||
|
@ -169,106 +34,21 @@ const ArtistDetails = () => {
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('error on artist page', e)
|
console.error('error on artist page', e)
|
||||||
})
|
})
|
||||||
}, [artistId, record])
|
}, [record])
|
||||||
|
|
||||||
const handleExpandClick = useCallback(() => {
|
|
||||||
setExpanded(!expanded)
|
|
||||||
}, [expanded, setExpanded])
|
|
||||||
|
|
||||||
|
const component = isDesktop ? DesktopArtistDetails : MobileArtistDetails
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={classes.root}>
|
{createElement(component, {
|
||||||
<div className={classes.bgContainer}>
|
img,
|
||||||
<Card className={classes.martImage}>
|
artistInfo,
|
||||||
{artistInfo && (
|
record,
|
||||||
<CardMedia
|
biography,
|
||||||
className={classes.cover}
|
})}
|
||||||
image={`${artistInfo.mediumImageUrl}`}
|
|
||||||
title={title}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
<div className={classes.mdetails}>
|
|
||||||
<Typography component="h5" variant="h5">
|
|
||||||
{title}
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
<Card className={classes.artDetail}>
|
|
||||||
<Card className={classes.artImage}>
|
|
||||||
{artistInfo && (
|
|
||||||
<CardMedia
|
|
||||||
className={classes.cover}
|
|
||||||
image={`${artistInfo.mediumImageUrl}`}
|
|
||||||
title={title}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
<div className={classes.details}>
|
|
||||||
<CardContent className={classes.content}>
|
|
||||||
<Typography component="h5" variant="h5">
|
|
||||||
{title}
|
|
||||||
</Typography>
|
|
||||||
<Collapse
|
|
||||||
collapsedHeight={'4.5em'}
|
|
||||||
in={expanded}
|
|
||||||
timeout={'auto'}
|
|
||||||
className={classes.bioBlock}
|
|
||||||
>
|
|
||||||
<Typography variant={'body1'} onClick={handleExpandClick}>
|
|
||||||
<span dangerouslySetInnerHTML={{ __html: biography }} />
|
|
||||||
{completeBioLink !== '' && (
|
|
||||||
<Link
|
|
||||||
href={completeBioLink}
|
|
||||||
className={classes.link}
|
|
||||||
target="_blank"
|
|
||||||
rel="nofollow"
|
|
||||||
>
|
|
||||||
{translate('message.lastfmLink')}
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</Typography>
|
|
||||||
</Collapse>
|
|
||||||
</CardContent>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={classes.mbio}>
|
|
||||||
<Collapse collapsedHeight={'1.5em'} in={expanded} timeout={'auto'}>
|
|
||||||
<Typography variant={'body1'} onClick={handleExpandClick}>
|
|
||||||
{biography}
|
|
||||||
<Link
|
|
||||||
href={completeBioLink}
|
|
||||||
className={classes.link}
|
|
||||||
target="_blank"
|
|
||||||
rel="nofollow"
|
|
||||||
>
|
|
||||||
{translate('message.lastfmLink')}
|
|
||||||
</Link>
|
|
||||||
</Typography>
|
|
||||||
</Collapse>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArtistAlbums = ({ ...props }) => {
|
|
||||||
const { ids } = props
|
|
||||||
const classes = useStyles()
|
|
||||||
const translate = useTranslate()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes.albumList}>
|
|
||||||
<div className={classes.artistSummary}>
|
|
||||||
{ids.length +
|
|
||||||
' ' +
|
|
||||||
translate('resources.album.name', { smart_count: ids.length })}
|
|
||||||
</div>
|
|
||||||
<AlbumGridView {...props} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const AlbumShowLayout = (props) => {
|
const AlbumShowLayout = (props) => {
|
||||||
const showContext = useShowContext(props)
|
const showContext = useShowContext(props)
|
||||||
const record = useRecordContext()
|
const record = useRecordContext()
|
||||||
|
@ -287,7 +67,7 @@ const AlbumShowLayout = (props) => {
|
||||||
perPage={0}
|
perPage={0}
|
||||||
pagination={null}
|
pagination={null}
|
||||||
>
|
>
|
||||||
<ArtistAlbums />
|
<AlbumGridView {...props} />
|
||||||
</ReferenceManyField>
|
</ReferenceManyField>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { Typography, Collapse } from '@material-ui/core'
|
||||||
|
import { makeStyles } from '@material-ui/core'
|
||||||
|
import Card from '@material-ui/core/Card'
|
||||||
|
import CardContent from '@material-ui/core/CardContent'
|
||||||
|
import CardMedia from '@material-ui/core/CardMedia'
|
||||||
|
import ArtistExternalLinks from './ArtistExternalLink'
|
||||||
|
import config from '../config'
|
||||||
|
import { LoveButton, RatingField } from '../common'
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
(theme) => ({
|
||||||
|
root: {
|
||||||
|
display: 'flex',
|
||||||
|
padding: '1em',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
display: 'flex',
|
||||||
|
flex: '1',
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
biography: {
|
||||||
|
display: 'inline-block',
|
||||||
|
marginTop: '1em',
|
||||||
|
float: 'left',
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
cursor: 'pointer',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
flex: '1 0 auto',
|
||||||
|
},
|
||||||
|
cover: {
|
||||||
|
width: 151,
|
||||||
|
borderRadius: '6em',
|
||||||
|
},
|
||||||
|
artistImage: {
|
||||||
|
maxHeight: '9.5rem',
|
||||||
|
backgroundColor: 'inherit',
|
||||||
|
display: 'flex',
|
||||||
|
boxShadow: 'none',
|
||||||
|
},
|
||||||
|
artistDetail: {
|
||||||
|
flex: '1',
|
||||||
|
padding: '3%',
|
||||||
|
display: 'flex',
|
||||||
|
minHeight: '10rem',
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
marginLeft: '0.9em',
|
||||||
|
},
|
||||||
|
loveButton: {
|
||||||
|
top: theme.spacing(-0.2),
|
||||||
|
left: theme.spacing(0.5),
|
||||||
|
},
|
||||||
|
rating: {
|
||||||
|
marginTop: '5px',
|
||||||
|
},
|
||||||
|
artistName: {
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{ name: 'NDDesktopArtistDetails' }
|
||||||
|
)
|
||||||
|
|
||||||
|
const DesktopArtistDetails = ({ img, artistInfo, record, biography }) => {
|
||||||
|
const [expanded, setExpanded] = useState(false)
|
||||||
|
const classes = useStyles({ img, expanded })
|
||||||
|
const title = record.name
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.root}>
|
||||||
|
<Card className={classes.artistDetail}>
|
||||||
|
<Card className={classes.artistImage}>
|
||||||
|
{artistInfo && (
|
||||||
|
<CardMedia
|
||||||
|
className={classes.cover}
|
||||||
|
image={`${artistInfo.mediumImageUrl}`}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
<div className={classes.details}>
|
||||||
|
<CardContent className={classes.content}>
|
||||||
|
<Typography
|
||||||
|
component="h5"
|
||||||
|
variant="h5"
|
||||||
|
className={classes.artistName}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
{config.enableFavourites && (
|
||||||
|
<LoveButton
|
||||||
|
className={classes.loveButton}
|
||||||
|
record={record}
|
||||||
|
resource={'artist'}
|
||||||
|
size={'default'}
|
||||||
|
aria-label="love"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
{config.enableStarRating && (
|
||||||
|
<div>
|
||||||
|
<RatingField
|
||||||
|
record={record}
|
||||||
|
resource={'artist'}
|
||||||
|
size={'small'}
|
||||||
|
className={classes.rating}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Collapse
|
||||||
|
collapsedHeight={'4.5em'}
|
||||||
|
in={expanded}
|
||||||
|
timeout={'auto'}
|
||||||
|
className={classes.biography}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant={'body1'}
|
||||||
|
onClick={() => setExpanded(!expanded)}
|
||||||
|
>
|
||||||
|
<span dangerouslySetInnerHTML={{ __html: biography }} />
|
||||||
|
</Typography>
|
||||||
|
</Collapse>
|
||||||
|
</CardContent>
|
||||||
|
<Typography component={'div'} className={classes.button}>
|
||||||
|
<ArtistExternalLinks artistInfo={artistInfo} record={record} />
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DesktopArtistDetails
|
|
@ -0,0 +1,134 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import { Typography, Collapse } from '@material-ui/core'
|
||||||
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
|
import Card from '@material-ui/core/Card'
|
||||||
|
import CardMedia from '@material-ui/core/CardMedia'
|
||||||
|
import config from '../config'
|
||||||
|
import { LoveButton, RatingField } from '../common'
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
(theme) => ({
|
||||||
|
root: {
|
||||||
|
display: 'flex',
|
||||||
|
background: ({ img }) => `url(${img})`,
|
||||||
|
},
|
||||||
|
bgContainer: {
|
||||||
|
display: 'flex',
|
||||||
|
height: '15rem',
|
||||||
|
width: '100vw',
|
||||||
|
padding: 'unset',
|
||||||
|
backdropFilter: 'blur(1px)',
|
||||||
|
backgroundPosition: '50% 30%',
|
||||||
|
background: `linear-gradient(to bottom, rgba(52 52 52 / 72%), rgba(21 21 21))`,
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
margin: '1px',
|
||||||
|
},
|
||||||
|
details: {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginLeft: '0.5rem',
|
||||||
|
},
|
||||||
|
biography: {
|
||||||
|
display: 'flex',
|
||||||
|
marginLeft: '3%',
|
||||||
|
marginRight: '3%',
|
||||||
|
marginTop: '-2em',
|
||||||
|
zIndex: '1',
|
||||||
|
'& p': {
|
||||||
|
whiteSpace: ({ expanded }) => (expanded ? 'unset' : 'nowrap'),
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '95vw',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cover: {
|
||||||
|
width: 151,
|
||||||
|
boxShadow: '0px 0px 6px 0px #565656',
|
||||||
|
borderRadius: '5px',
|
||||||
|
},
|
||||||
|
artistImage: {
|
||||||
|
marginLeft: '1em',
|
||||||
|
maxHeight: '7rem',
|
||||||
|
backgroundColor: 'inherit',
|
||||||
|
marginTop: '4rem',
|
||||||
|
width: '7rem',
|
||||||
|
minWidth: '7rem',
|
||||||
|
display: 'flex',
|
||||||
|
borderRadius: '5em',
|
||||||
|
},
|
||||||
|
loveButton: {
|
||||||
|
top: theme.spacing(-0.2),
|
||||||
|
left: theme.spacing(0.5),
|
||||||
|
},
|
||||||
|
rating: {
|
||||||
|
marginTop: '5px',
|
||||||
|
},
|
||||||
|
artistName: {
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{ name: 'NDMobileArtistDetails' }
|
||||||
|
)
|
||||||
|
|
||||||
|
const MobileArtistDetails = ({ img, artistInfo, biography, record }) => {
|
||||||
|
const [expanded, setExpanded] = useState(false)
|
||||||
|
const classes = useStyles({ img, expanded })
|
||||||
|
const title = record.name
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={classes.root}>
|
||||||
|
<div className={classes.bgContainer}>
|
||||||
|
<Card className={classes.artistImage}>
|
||||||
|
{artistInfo && (
|
||||||
|
<CardMedia
|
||||||
|
className={classes.cover}
|
||||||
|
image={`${artistInfo.mediumImageUrl}`}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
<div className={classes.details}>
|
||||||
|
<Typography
|
||||||
|
component="h5"
|
||||||
|
variant="h5"
|
||||||
|
className={classes.artistName}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
{config.enableFavourites && (
|
||||||
|
<LoveButton
|
||||||
|
className={classes.loveButton}
|
||||||
|
record={record}
|
||||||
|
resource={'artist'}
|
||||||
|
size={'small'}
|
||||||
|
aria-label="love"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
{config.enableStarRating && (
|
||||||
|
<RatingField
|
||||||
|
record={record}
|
||||||
|
resource={'artist'}
|
||||||
|
size={'small'}
|
||||||
|
className={classes.rating}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={classes.biography}>
|
||||||
|
<Collapse collapsedHeight={'1.5em'} in={expanded} timeout={'auto'}>
|
||||||
|
<Typography variant={'body1'} onClick={() => setExpanded(!expanded)}>
|
||||||
|
<span dangerouslySetInnerHTML={{ __html: biography }} />
|
||||||
|
</Typography>
|
||||||
|
</Collapse>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MobileArtistDetails
|
|
@ -32,14 +32,11 @@ export default {
|
||||||
boxShadow: '3px 3px 5px #000000a3',
|
boxShadow: '3px 3px 5px #000000a3',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NDArtistPage: {
|
NDMobileArtistDetails: {
|
||||||
bgContainer: {
|
bgContainer: {
|
||||||
background:
|
background:
|
||||||
'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',
|
'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',
|
||||||
},
|
},
|
||||||
more: {
|
|
||||||
boxShadow: '-10px 0px 18px 5px #303030!important',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
|
|
|
@ -27,14 +27,11 @@ export default {
|
||||||
color: '#eee',
|
color: '#eee',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NDArtistPage: {
|
NDMobileArtistDetails: {
|
||||||
bgContainer: {
|
bgContainer: {
|
||||||
background:
|
background:
|
||||||
'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',
|
'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',
|
||||||
},
|
},
|
||||||
more: {
|
|
||||||
boxShadow: '-10px 0px 18px 5px #303030!important',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
|
|
|
@ -359,14 +359,11 @@ export default {
|
||||||
marginTop: '-50px',
|
marginTop: '-50px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NDArtistPage: {
|
NDMobileArtistDetails: {
|
||||||
bgContainer: {
|
bgContainer: {
|
||||||
background:
|
background:
|
||||||
'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(240 242 245))!important',
|
'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(240 242 245))!important',
|
||||||
},
|
},
|
||||||
more: {
|
|
||||||
boxShadow: '-10px 0px 18px 5px #f0f2f5!important',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
RaLayout: {
|
RaLayout: {
|
||||||
content: {
|
content: {
|
||||||
|
|
|
@ -46,14 +46,11 @@ export default {
|
||||||
color: '#0085ff',
|
color: '#0085ff',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NDArtistPage: {
|
NDMobileArtistDetails: {
|
||||||
bgContainer: {
|
bgContainer: {
|
||||||
background:
|
background:
|
||||||
'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(250 250 250))!important',
|
'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(250 250 250))!important',
|
||||||
},
|
},
|
||||||
more: {
|
|
||||||
boxShadow: '-10px 0px 18px 5px #fafafa!important',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
|
|
Loading…
Reference in New Issue