Browse Source

Add custom playlist grid image

master
jeffvli 3 years ago
committed by Jeff
parent
commit
8779e68835
  1. 60
      src/components/layout/GenericPageHeader.tsx
  2. 12
      src/components/layout/styled.tsx
  3. 49
      src/components/playlist/PlaylistView.tsx
  4. 10
      src/shared/utils.ts

60
src/components/layout/GenericPageHeader.tsx

@ -12,6 +12,8 @@ import {
} from '../shared/styled';
import {
CoverArtWrapper,
CustomImageGrid,
CustomImageGridWrapper,
PageHeaderSubtitleWrapper,
PageHeaderTitle,
PageHeaderWrapper,
@ -48,7 +50,7 @@ const GenericPageHeader = ({
return (
<>
{image && (
{image && !Array.isArray(image) && (
<CoverArtWrapper>
<LazyLoadImage
src={image}
@ -68,6 +70,62 @@ const GenericPageHeader = ({
</CoverArtWrapper>
)}
{image && Array.isArray(image) && (
<CoverArtWrapper>
<CustomImageGridWrapper>
<CustomImageGrid $gridArea="1 / 1 / 2 / 2">
<LazyLoadImage
src={image[0]}
alt="header-img"
height={imageHeight / 2}
width={imageHeight / 2}
/>
</CustomImageGrid>
<CustomImageGrid $gridArea="1 / 2 / 2 / 3">
<LazyLoadImage
src={image[1]}
alt="header-img"
height={imageHeight / 2}
width={imageHeight / 2}
/>
</CustomImageGrid>
<CustomImageGrid $gridArea="2 / 1 / 3 / 2">
<LazyLoadImage
src={image[2]}
alt="header-img"
height={imageHeight / 2}
width={imageHeight / 2}
/>
</CustomImageGrid>
<CustomImageGrid $gridArea="2 / 2 / 3 / 3">
<LazyLoadImage
src={image[3]}
alt="header-img"
height={imageHeight / 2}
width={imageHeight / 2}
/>
</CustomImageGrid>
</CustomImageGridWrapper>
</CoverArtWrapper>
/* <CoverArtWrapper>
<LazyLoadImage
src={image[0]}
alt="header-img"
height={imageHeight || '195px'}
width={imageHeight || '195px'}
visibleByDefault
afterLoad={() => {
if (cacheImages.enabled) {
cacheImage(
`${cacheImages.cacheType}_${cacheImages.id}.jpg`,
image[0].replace(/size=\d+/, 'size=500')
);
}
}}
/>
</CoverArtWrapper> */
)}
<PageHeaderWrapper isDark={isDark} hasImage={image} imageHeight={imageHeight || 195}>
<div
style={{

12
src/components/layout/styled.tsx

@ -300,3 +300,15 @@ export const GradientBackground = styled.div<{ $expanded: boolean; $color: strin
user-select: none;
pointer-events: none;
`;
export const CustomImageGridWrapper = styled.div`
display: grid;
grid-template-columns: repeat(2, 92px);
grid-template-rows: repeat(2, 92px);
grid-column-gap: 0px;
grid-row-gap: 0px;
`;
export const CustomImageGrid = styled.div<{ $gridArea: string }>`
grid-area: ${(props) => props.$gridArea};
`;

49
src/components/playlist/PlaylistView.tsx

@ -48,9 +48,12 @@ import {
createRecoveryFile,
errorMessages,
filterPlayQueue,
formatDate,
formatDuration,
getCurrentEntryList,
getPlayedSongsNotification,
getRecoveryPath,
getUniqueRandomNumberArr,
isFailedResponse,
} from '../../shared/utils';
import useSearchQuery from '../../hooks/useSearchQuery';
@ -69,6 +72,8 @@ import {
setPlaylistRate,
setPlaylistStar,
} from '../../redux/playlistSlice';
import { PageHeaderSubtitleDataLine } from '../layout/styled';
import CustomTooltip from '../shared/CustomTooltip';
interface PlaylistParams {
id: string;
@ -89,6 +94,9 @@ const PlaylistView = ({ ...rest }) => {
const { isLoading, isError, data, error }: any = useQuery(['playlist', playlistId], () =>
getPlaylist(playlistId)
);
const [customPlaylistImage, setCustomPlaylistImage] = useState<string | string[]>(
'img/placeholder.jpg'
);
const [editName, setEditName] = useState('');
const [editDescription, setEditDescription] = useState('');
const [editPublic, setEditPublic] = useState(false);
@ -349,6 +357,24 @@ const PlaylistView = ({ ...rest }) => {
dispatch(setPlaylistRate({ id: [rowData.id], rating: e }));
};
useEffect(() => {
if (data?.image.match('placeholder')) {
const uniqueAlbums: any = _.uniqBy(data?.song, 'albumId');
if (uniqueAlbums.length === 0) {
setCustomPlaylistImage('img/placeholder.jpg');
} // If less than 4 images, we'll just set a single random image
else if (uniqueAlbums.length > 0 && uniqueAlbums.length < 4) {
setCustomPlaylistImage(uniqueAlbums[_.random(0, uniqueAlbums.length - 1)]?.image);
} else if (uniqueAlbums.length >= 4) {
const randomUniqueNumbers = getUniqueRandomNumberArr(4, uniqueAlbums.length);
const randomAlbumImages = randomUniqueNumbers.map((num) => uniqueAlbums[num].image);
setCustomPlaylistImage(randomAlbumImages);
}
}
}, [data?.image, data?.song]);
if (isLoading) {
return <PageLoader />;
}
@ -362,24 +388,37 @@ const PlaylistView = ({ ...rest }) => {
hideDivider
header={
<GenericPageHeader
image={data.image}
image={data?.image.match('placeholder') ? customPlaylistImage : data.image}
cacheImages={{
enabled: settings.getSync('cacheImages'),
cacheType: 'playlist',
id: data.id,
}}
imageHeight={184}
title={data.name}
subtitle={
<div>
<div
<PageHeaderSubtitleDataLine $top>
<strong>PLAYLIST</strong> {data.songCount} songs {formatDuration(data.duration)}
</PageHeaderSubtitleDataLine>
<PageHeaderSubtitleDataLine>
by <strong>{data.owner}</strong> created {formatDate(data.created)} modified{' '}
{formatDate(data.changed)}
</PageHeaderSubtitleDataLine>
<CustomTooltip text={data.comment}>
<PageHeaderSubtitleDataLine
style={{
minHeight: '1.2rem',
maxHeight: '1.2rem',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
whiteSpace: 'pre-wrap',
}}
>
{data.comment ? data.comment : <span>&#8203;</span>}
</div>
<span>{data.comment ? data.comment : 'No description'}</span>
</PageHeaderSubtitleDataLine>
</CustomTooltip>
<div style={{ marginTop: '10px' }}>
<ButtonToolbar>
<PlayButton

10
src/shared/utils.ts

@ -477,3 +477,13 @@ export const getPlayedSongsNotification = (options: {
return `Added ${options.filtered} songs [${options.original - options.filtered} filtered]`;
};
export const getUniqueRandomNumberArr = (count: number, maxRange: number) => {
const arr = [];
while (arr.length < count) {
const r = Math.floor(Math.random() * maxRange);
if (arr.indexOf(r) === -1) arr.push(r);
}
return arr;
};

Loading…
Cancel
Save