diff --git a/src/features/chapter/components/cards/ChapterCardThumbnail.tsx b/src/features/chapter/components/cards/ChapterCardThumbnail.tsx index ae61c533..2e8c91b0 100644 --- a/src/features/chapter/components/cards/ChapterCardThumbnail.tsx +++ b/src/features/chapter/components/cards/ChapterCardThumbnail.tsx @@ -11,21 +11,30 @@ import { AppRoutes } from '@/base/AppRoute.constants.ts'; import { Mangas } from '@/features/manga/services/Mangas.ts'; import type { MangaIdInfo, MangaThumbnailInfo, MangaTitleInfo } from '@/features/manga/Manga.types.ts'; import { ListCardAvatar } from '@/base/components/lists/cards/ListCardAvatar.tsx'; +import type { ComponentProps } from 'react'; +import merge from 'lodash/fp/merge'; export const ChapterCardThumbnail = ({ mangaId, mangaTitle, thumbnailUrl, thumbnailUrlLastFetched, + slots, }: MangaThumbnailInfo & { mangaId: MangaIdInfo['id']; mangaTitle: MangaTitleInfo['title']; + slots?: { + listCardAvatar?: Omit, 'alt' | 'iconUrl'>; + }; }) => ( ); diff --git a/src/features/updates/components/ChapterUpdateCard.tsx b/src/features/updates/components/ChapterUpdateCard.tsx index 61b8fd78..bb21cd8c 100644 --- a/src/features/updates/components/ChapterUpdateCard.tsx +++ b/src/features/updates/components/ChapterUpdateCard.tsx @@ -10,7 +10,7 @@ import Box from '@mui/material/Box'; import CardActionArea from '@mui/material/CardActionArea'; import Card from '@mui/material/Card'; import { Link } from 'react-router-dom'; -import { memo, useMemo } from 'react'; +import { memo, useState } from 'react'; import { DownloadStateIndicator } from '@/base/components/downloads/DownloadStateIndicator.tsx'; import type { ChapterUpdateListFieldsFragment } from '@/lib/graphql/generated/graphql.ts'; import { AppRoutes } from '@/base/AppRoute.constants.ts'; @@ -20,49 +20,31 @@ import { ChapterDownloadButton } from '@/features/chapter/components/buttons/Cha import { ChapterDownloadRetryButton } from '@/features/chapter/components/buttons/ChapterDownloadRetryButton.tsx'; import { Chapters } from '@/features/chapter/services/Chapters.ts'; import { ListCardContent } from '@/base/components/lists/cards/ListCardContent.tsx'; -import { useLingui } from '@lingui/react/macro'; import { plural } from '@lingui/core/macro'; +import Stack from '@mui/material/Stack'; +import Button from '@mui/material/Button'; +import { MUIUtil } from '@/lib/mui/MUI.util.ts'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import ExpandLessIcon from '@mui/icons-material/ExpandLess'; +import Collapse from '@mui/material/Collapse'; +import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts'; +import { useTheme } from '@mui/material/styles'; export const ChapterUpdateCard = memo( ({ chapter, - otherChapters, + otherChapters = STABLE_EMPTY_ARRAY, }: { chapter: ChapterUpdateListFieldsFragment; - otherChapters: ChapterUpdateListFieldsFragment[]; + otherChapters?: ChapterUpdateListFieldsFragment[]; }) => { const { manga } = chapter; - const { t } = useLingui(); + const theme = useTheme(); - const uniqueOtherChapters = useMemo( - () => Chapters.removeDuplicates(chapter, otherChapters), - [chapter, otherChapters], - ); - const otherChaptersCount = uniqueOtherChapters.length; - const firstFewOtherChapters = uniqueOtherChapters.slice(-3); + const [isExpanded, setIsExpanded] = useState(false); - const otherChaptersText = (() => { - if (!otherChaptersCount) { - return ''; - } - - const firstFewUpdatesString = firstFewOtherChapters - .map((otherChapter) => `#${otherChapter.chapterNumber}`) - .toReversed() - .join(', '); - - if (otherChaptersCount > firstFewOtherChapters.length) { - const remainingUpdatesCount = otherChaptersCount - firstFewOtherChapters.length; - - return t`Plus chapters ${firstFewUpdatesString} and ${remainingUpdatesCount} more`; - } - - return plural(firstFewOtherChapters.length, { - one: `Plus chapter ${firstFewUpdatesString}`, - other: `Plus chapters ${firstFewUpdatesString}`, - }); - })(); + const isGroup = !!otherChapters.length; return ( @@ -71,7 +53,7 @@ export const ChapterUpdateCard = memo( to={AppRoutes.reader.path(chapter.manga.id, chapter.sourceOrder)} state={Chapters.getReaderOpenChapterLocationState(chapter)} sx={{ - color: (theme) => theme.palette.text[chapter.isRead ? 'disabled' : 'primary'], + color: theme.palette.text[chapter.isRead ? 'disabled' : 'primary'], }} > @@ -82,18 +64,66 @@ export const ChapterUpdateCard = memo( mangaTitle={manga.title} thumbnailUrl={manga.thumbnailUrl} thumbnailUrlLastFetched={manga.thumbnailUrlLastFetched} + slots={ + isGroup + ? { + listCardAvatar: { + slots: { + spinnerImageProps: { + spinnerStyle: { + height: 74, + aspectRatio: '3 / 4', + }, + imgStyle: { + height: 74, + aspectRatio: '3 / 4', + }, + }, + avatarProps: { + sx: { + height: 74, + }, + }, + }, + }, + } + : undefined + } /> - + + + {isGroup && ( + + )} + + {isGroup && ( + + {otherChapters.map((otherChapter) => ( + + ))} + + )} ); },