Handling long playlist comments (#2973)

Closes #1737

* wrapping playlist comment in a <Collapse> element

* Extract common collapsible logic into a component

---------

Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Tim 2024-04-26 02:28:25 +02:00 committed by GitHub
parent cf66594b6d
commit 8f9ed1b994
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 77 additions and 61 deletions

View File

@ -1,4 +1,4 @@
import React, { useMemo, useCallback, useState, useEffect } from 'react'
import { useState, useEffect, useCallback } from 'react'
import {
Card,
CardContent,
@ -17,7 +17,6 @@ import {
ChipField,
Link,
} from 'react-admin'
import clsx from 'clsx'
import Lightbox from 'react-image-lightbox'
import 'react-image-lightbox/style.css'
import subsonic from '../subsonic'
@ -29,11 +28,11 @@ import {
LoveButton,
RatingField,
useAlbumsPerPage,
CollapsibleComment,
} from '../common'
import config from '../config'
import { formatFullDate, intersperse } from '../utils'
import AlbumExternalLinks from './AlbumExternalLinks'
import AnchorMe from '../common/Linkify'
const useStyles = makeStyles(
(theme) => ({
@ -85,12 +84,6 @@ const useStyles = makeStyles(
top: theme.spacing(-0.2),
left: theme.spacing(0.5),
},
commentBlock: {
display: 'inline-block',
marginTop: '1em',
float: 'left',
wordBreak: 'break-word',
},
notes: {
display: 'inline-block',
marginTop: '1em',
@ -98,9 +91,6 @@ const useStyles = makeStyles(
wordBreak: 'break-word',
cursor: 'pointer',
},
pointerCursor: {
cursor: 'pointer',
},
recordName: {},
recordArtist: {},
recordMeta: {},
@ -116,41 +106,6 @@ const useStyles = makeStyles(
},
)
const AlbumComment = ({ record }) => {
const classes = useStyles()
const [expanded, setExpanded] = React.useState(false)
const lines = record.comment.split('\n')
const formatted = useMemo(() => {
return lines.map((line, idx) => (
<span key={record.id + '-comment-' + idx}>
<AnchorMe text={line} />
<br />
</span>
))
}, [lines, record.id])
const handleExpandClick = useCallback(() => {
setExpanded(!expanded)
}, [expanded, setExpanded])
return (
<Collapse
collapsedHeight={'1.5em'}
in={expanded}
timeout={'auto'}
className={clsx(
classes.commentBlock,
lines.length > 1 && classes.pointerCursor,
)}
>
<Typography variant={'body1'} onClick={handleExpandClick}>
{formatted}
</Typography>
</Collapse>
)
}
export const useGetHandleGenreClick = (width) => {
const [perPage] = useAlbumsPerPage(width)
@ -268,7 +223,7 @@ const AlbumDetails = (props) => {
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('lg'))
const classes = useStyles()
const [isLightboxOpen, setLightboxOpen] = React.useState(false)
const [isLightboxOpen, setLightboxOpen] = useState(false)
const [expanded, setExpanded] = useState(false)
const [albumInfo, setAlbumInfo] = useState()
@ -296,11 +251,8 @@ const AlbumDetails = (props) => {
const imageUrl = subsonic.getCoverArtUrl(record, 300)
const fullImageUrl = subsonic.getCoverArtUrl(record)
const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])
const handleCloseLightbox = React.useCallback(
() => setLightboxOpen(false),
[],
)
const handleOpenLightbox = useCallback(() => setLightboxOpen(true), [])
const handleCloseLightbox = useCallback(() => setLightboxOpen(false), [])
return (
<Card className={classes.root}>
<div className={classes.cardContents}>
@ -373,11 +325,15 @@ const AlbumDetails = (props) => {
</Typography>
</Collapse>
)}
{isDesktop && record['comment'] && <AlbumComment record={record} />}
{isDesktop && record['comment'] && (
<CollapsibleComment record={record} />
)}
</CardContent>
</div>
</div>
{!isDesktop && record['comment'] && <AlbumComment record={record} />}
{!isDesktop && record['comment'] && (
<CollapsibleComment record={record} />
)}
{!isDesktop && (
<div className={classes.notes}>
<Collapse collapsedHeight={'1.5em'} in={expanded} timeout={'auto'}>

View File

@ -0,0 +1,57 @@
import { useCallback, useMemo, useState } from 'react'
import { Typography, Collapse } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import AnchorMe from './Linkify'
import clsx from 'clsx'
const useStyles = makeStyles(
(theme) => ({
commentBlock: {
display: 'inline-block',
marginTop: '1em',
float: 'left',
wordBreak: 'break-word',
},
pointerCursor: {
cursor: 'pointer',
},
}),
{
name: 'NDCollapsibleComment',
},
)
export const CollapsibleComment = ({ record }) => {
const classes = useStyles()
const [expanded, setExpanded] = useState(false)
const lines = record.comment.split('\n')
const formatted = useMemo(() => {
return lines.map((line, idx) => (
<span key={record.id + '-comment-' + idx}>
<AnchorMe text={line} />
<br />
</span>
))
}, [lines, record.id])
const handleExpandClick = useCallback(() => {
setExpanded(!expanded)
}, [expanded, setExpanded])
return (
<Collapse
collapsedHeight={'2em'}
in={expanded}
timeout={'auto'}
className={clsx(
classes.commentBlock,
lines.length > 1 && classes.pointerCursor,
)}
>
<Typography variant={'h6'} onClick={handleExpandClick}>
{formatted}
</Typography>
</Collapse>
)
}

View File

@ -2,6 +2,7 @@ export * from './AddToPlaylistButton'
export * from './ArtistLinkField'
export * from './BatchPlayButton'
export * from './BitrateField'
export * from './CollapsibleComment'
export * from './ContextMenus'
export * from './DateField'
export * from './DocLink'

View File

@ -1,9 +1,7 @@
import React from 'react'
import { Card, CardContent, Typography } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import { useTranslate } from 'react-admin'
import { DurationField, SizeField } from '../common'
import Linkify from '../common/Linkify'
import { CollapsibleComment, DurationField, SizeField } from '../common'
const useStyles = makeStyles(
(theme) => ({
@ -52,9 +50,7 @@ const PlaylistDetails = (props) => {
<Typography variant="h5" className={classes.title}>
{record.name || translate('ra.page.loading')}
</Typography>
<Typography component="h6">
<Linkify text={record.comment} />
</Typography>
<CollapsibleComment record={record} />
<Typography component="p">
{record.songCount ? (
<span>

View File

@ -300,6 +300,8 @@ export default {
fontSize: '.875rem',
color: 'rgb(113 113 113 / 80%)',
},
},
NDCollapsibleComment: {
commentBlock: {
fontSize: '.875rem',
color: 'rgb(113 113 113 / 80%)',

View File

@ -289,6 +289,8 @@ export default {
fontSize: '.875rem',
color: 'rgba(255,255,255, 0.8)',
},
},
NDCollapsibleComment: {
commentBlock: {
fontSize: '.875rem',
color: 'rgba(255,255,255, 0.8)',

View File

@ -230,6 +230,8 @@ export default {
fontSize: '.875rem',
color: 'rgba(255,255,255, 0.8)',
},
},
NDCollapsibleComment: {
commentBlock: {
fontSize: '.875rem',
color: 'rgba(255,255,255, 0.8)',