From 7574e8326df84c1fb2fb4bf6a4cfd833bbfb8c2e Mon Sep 17 00:00:00 2001 From: Harshith Mohan <26010946+harshithmohan@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:53:29 +0530 Subject: [PATCH] Refactor how images are selected to be shown (#1087) --- .../BackgroundImagePlaceholderDiv.tsx | 2 +- src/components/Collection/SeriesTopPanel.tsx | 22 ++++++++--------- src/components/SeriesPoster.tsx | 2 +- src/hooks/useEpisodeThumbnail.ts | 4 ++-- src/hooks/useMainPoster.ts | 10 ++++---- src/pages/collection/Series.tsx | 24 +++++++++---------- 6 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/components/BackgroundImagePlaceholderDiv.tsx b/src/components/BackgroundImagePlaceholderDiv.tsx index 966579eef..e5631a50c 100644 --- a/src/components/BackgroundImagePlaceholderDiv.tsx +++ b/src/components/BackgroundImagePlaceholderDiv.tsx @@ -11,7 +11,7 @@ type Props = { children?: React.ReactNode; className?: string; contain?: boolean; - image: ImageType | null; + image?: ImageType; hidePlaceholderOnHover?: boolean; overlayOnHover?: boolean; zoomOnHover?: boolean; diff --git a/src/components/Collection/SeriesTopPanel.tsx b/src/components/Collection/SeriesTopPanel.tsx index d9db7f2f1..e98b37d55 100644 --- a/src/components/Collection/SeriesTopPanel.tsx +++ b/src/components/Collection/SeriesTopPanel.tsx @@ -47,25 +47,25 @@ const SeriesTag = React.memo(({ text, type }: { text: string, type: 'User' | 'An }); const SeriesTopPanel = React.memo(({ series }: { series: SeriesType }) => { - const { WebUI_Settings: { collection: { image: { showRandomPoster } } } } = useSettingsQuery().data; - const [poster, setPoster] = useState(null); const { seriesId } = useParams(); + const tagsQuery = useSeriesTagsQuery(toNumber(seriesId!), { excludeDescriptions: true, filter: 1 }, !!seriesId); - const imagesQuery = useSeriesImagesQuery(toNumber(seriesId!), !!seriesId); const tags = useMemo(() => tagsQuery?.data ?? [], [tagsQuery.data]); + const { showRandomPoster } = useSettingsQuery().data.WebUI_Settings.collection.image; + const imagesQuery = useSeriesImagesQuery(toNumber(seriesId!), !!seriesId && showRandomPoster); + const [poster, setPoster] = useState(); useEffect(() => { - if (!imagesQuery.isSuccess) return; + if (!showRandomPoster) { + setPoster(series.Images?.Posters?.[0]); + return; + } - const allPosters: ImageType[] = imagesQuery.data?.Posters ?? []; + const allPosters = imagesQuery.data?.Posters ?? []; if (allPosters.length === 0) return; - if (showRandomPoster) { - setPoster(allPosters[Math.floor(Math.random() * allPosters.length)]); - return; - } - setPoster(allPosters.find(art => art.Preferred) ?? allPosters[0]); - }, [imagesQuery.data, imagesQuery.isSuccess, showRandomPoster]); + setPoster(allPosters[Math.floor(Math.random() * allPosters.length)]); + }, [imagesQuery.data, series, showRandomPoster]); // TODO: try to make this a grid for better responsiveness... but we'll have v3 soon so maybe not right now. return ( diff --git a/src/components/SeriesPoster.tsx b/src/components/SeriesPoster.tsx index 8285ea16f..50c92fad3 100644 --- a/src/components/SeriesPoster.tsx +++ b/src/components/SeriesPoster.tsx @@ -10,7 +10,7 @@ type Props = { children?: React.ReactNode; title: string; subtitle?: string; - image: ImageType | null; + image?: ImageType; shokoId?: number | null; anidbSeriesId?: number; anidbEpisodeId?: number; diff --git a/src/hooks/useEpisodeThumbnail.ts b/src/hooks/useEpisodeThumbnail.ts index e45607930..1d170909b 100644 --- a/src/hooks/useEpisodeThumbnail.ts +++ b/src/hooks/useEpisodeThumbnail.ts @@ -8,7 +8,7 @@ import type { EpisodeType } from '@/core/types/api/episode'; function useEpisodeThumbnail( episode: EpisodeType, backdrop: ImageType | undefined, -): ImageType | null { +) { const { useThumbnailFallback } = useSettingsQuery().data.WebUI_Settings.collection.image; return useMemo(() => { if (episode.Images.Thumbnails.length) { @@ -20,7 +20,7 @@ function useEpisodeThumbnail( } if (useThumbnailFallback && backdrop) return backdrop; - return null; + return undefined; }, [episode, useThumbnailFallback, backdrop]); } diff --git a/src/hooks/useMainPoster.ts b/src/hooks/useMainPoster.ts index d4982513e..890a5a6ae 100644 --- a/src/hooks/useMainPoster.ts +++ b/src/hooks/useMainPoster.ts @@ -1,14 +1,12 @@ import { useMemo } from 'react'; import type { CollectionGroupType } from '@/core/types/api/collection'; -import type { ImageType } from '@/core/types/api/common'; import type { SeriesType } from '@/core/types/api/series'; -function useMainPoster(target: SeriesType | CollectionGroupType | null | undefined): ImageType | null { - return useMemo(() => { - const posters = target?.Images?.Posters ?? []; - return posters.find(poster => poster.Preferred) ?? posters[0] ?? null; - }, [target]); +function useMainPoster(target: SeriesType | CollectionGroupType | null | undefined) { + // There is only 1 poster in the series/collection and if preferred image exists, it will always be that. + // So checking for preferred image is not needed. + return useMemo(() => target?.Images?.Posters?.[0], [target]); } export default useMainPoster; diff --git a/src/pages/collection/Series.tsx b/src/pages/collection/Series.tsx index b7d4a91ce..60a9de1c7 100644 --- a/src/pages/collection/Series.tsx +++ b/src/pages/collection/Series.tsx @@ -16,7 +16,7 @@ import { } from '@mdi/js'; import { Icon } from '@mdi/react'; import cx from 'classnames'; -import { get, toNumber } from 'lodash'; +import { toNumber } from 'lodash'; import EditSeriesModal from '@/components/Collection/Series/EditSeriesModal'; import SeriesTopPanel from '@/components/Collection/SeriesTopPanel'; @@ -54,13 +54,10 @@ const Series = () => { const navigate = useNavigate(); const { seriesId } = useParams(); - const { showRandomBackdrop } = useSettingsQuery().data.WebUI_Settings.collection.image; const seriesQuery = useSeriesQuery(toNumber(seriesId!), { includeDataFrom: ['AniDB', 'TMDB'] }, !!seriesId); const series = useMemo(() => seriesQuery?.data ?? {} as SeriesType, [seriesQuery.data]); - const imagesQuery = useSeriesImagesQuery(toNumber(seriesId!), !!seriesId); const groupQuery = useGroupQuery(series?.IDs?.ParentGroup ?? 0, !!series?.IDs?.ParentGroup); - const [backdrop, setBackdrop] = useState(); const { scrollRef } = useOutletContext<{ scrollRef: React.RefObject }>(); const dispatch = useDispatch(); @@ -80,19 +77,20 @@ const Series = () => { dispatch(setSeriesId(toNumber(seriesId) ?? -1)); }); + const { showRandomBackdrop } = useSettingsQuery().data.WebUI_Settings.collection.image; + const imagesQuery = useSeriesImagesQuery(toNumber(seriesId!), !!seriesId && showRandomBackdrop); + const [backdrop, setBackdrop] = useState(); useEffect(() => { - if (!imagesQuery.isSuccess) return; - - const allBackdrops: ImageType[] = get(imagesQuery.data, 'Backdrops', []); - if (!Array.isArray(allBackdrops) || allBackdrops.length === 0) return; - - if (showRandomBackdrop) { - setBackdrop(allBackdrops[Math.floor(Math.random() * allBackdrops.length)]); + if (!showRandomBackdrop) { + setBackdrop(series.Images?.Backdrops?.[0]); return; } - setBackdrop(allBackdrops.find(image => image.Preferred) ?? allBackdrops[0]); - }, [imagesQuery.data, imagesQuery.isSuccess, series, showRandomBackdrop]); + const allBackdrops = imagesQuery.data?.Backdrops ?? []; + if (allBackdrops.length === 0) return; + + setBackdrop(allBackdrops[Math.floor(Math.random() * allBackdrops.length)]); + }, [imagesQuery.data, series, showRandomBackdrop]); const [containerRef, containerBounds] = useMeasure();