From 95d10deddc4b3bd69e2d50862226d2e936eb1695 Mon Sep 17 00:00:00 2001 From: nnivxix Date: Mon, 25 Mar 2024 11:43:28 +0700 Subject: [PATCH 1/6] wip: image loading --- src/components/CardItem.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/CardItem.tsx b/src/components/CardItem.tsx index 4021684..e17b37c 100644 --- a/src/components/CardItem.tsx +++ b/src/components/CardItem.tsx @@ -3,6 +3,7 @@ import { Link } from "react-router-dom"; import { MovieTv } from "@/types/response"; import { Button } from "./ui/button"; import imageUrl from "@/utils/image-url"; +import type { SyntheticEvent } from "react"; interface CardItemProps { movie: MovieTv; @@ -17,6 +18,16 @@ export default function CardItem({ movie, media }: CardItemProps) { const mediaType = media ?? movie.media_type; + const imageFallback = (event: SyntheticEvent) => { + event.currentTarget.src = "/poster-fallback.png"; + }; + const imageLoaded = (event: SyntheticEvent) => { + event.currentTarget.src = imageUrl({ + path: movie.poster_path, + type: "poster", + }); + }; + return (
{movieTitle}
From a96e8b46227350a01b7a62bfb790cdfcc0a7f324 Mon Sep 17 00:00:00 2001 From: nnivxix Date: Mon, 25 Mar 2024 12:11:26 +0700 Subject: [PATCH 2/6] wip: implemented custom image component on `CardItem` --- src/components/CardItem.tsx | 21 +++++---------------- src/components/Image.tsx | 29 +++++++++++++++++++++++++++++ src/components/SeasonCardItem.tsx | 6 ++++-- src/components/SimilarCardItem.tsx | 10 +++++----- src/hooks/useImageFallback.ts | 26 ++++++++++++++++++++++++++ src/pages/Show/Movie.tsx | 1 + 6 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 src/components/Image.tsx create mode 100644 src/hooks/useImageFallback.ts diff --git a/src/components/CardItem.tsx b/src/components/CardItem.tsx index e17b37c..1e718fa 100644 --- a/src/components/CardItem.tsx +++ b/src/components/CardItem.tsx @@ -3,7 +3,7 @@ import { Link } from "react-router-dom"; import { MovieTv } from "@/types/response"; import { Button } from "./ui/button"; import imageUrl from "@/utils/image-url"; -import type { SyntheticEvent } from "react"; +import Image from "./Image"; interface CardItemProps { movie: MovieTv; @@ -18,16 +18,6 @@ export default function CardItem({ movie, media }: CardItemProps) { const mediaType = media ?? movie.media_type; - const imageFallback = (event: SyntheticEvent) => { - event.currentTarget.src = "/poster-fallback.png"; - }; - const imageLoaded = (event: SyntheticEvent) => { - event.currentTarget.src = imageUrl({ - path: movie.poster_path, - type: "poster", - }); - }; - return (
- {movieTitle}
diff --git a/src/components/Image.tsx b/src/components/Image.tsx new file mode 100644 index 0000000..716db77 --- /dev/null +++ b/src/components/Image.tsx @@ -0,0 +1,29 @@ +import type { SyntheticEvent } from "react"; +import type { TypeImage } from "@/hooks/useImageFallback"; +import useImageFallback from "@/hooks/useImageFallback"; + +// forward props like shadcn +interface ImageProps { + src: string; + alt: string; + type: TypeImage; +} +export default function Image({ src, alt, type }: ImageProps) { + const { fallback } = useImageFallback(type); + + const imageFallback = (event: SyntheticEvent) => { + event.currentTarget.src = fallback; + }; + const imageLoaded = (event: SyntheticEvent) => { + event.currentTarget.src = src; + }; + + return ( + {alt} + ); +} diff --git a/src/components/SeasonCardItem.tsx b/src/components/SeasonCardItem.tsx index 2e9ad41..1efde45 100644 --- a/src/components/SeasonCardItem.tsx +++ b/src/components/SeasonCardItem.tsx @@ -2,6 +2,7 @@ import { Season } from "@/types/tv"; import getYear from "@/utils/get-year"; import imageUrl from "@/utils/image-url"; import { Star } from "lucide-react"; +import Image from "./Image"; interface SeasonCardItemProps { season: Season; @@ -12,9 +13,10 @@ export default function SeasonCardItem({ season }: SeasonCardItemProps) {

{season.overview ?? ""}

- {season.overview

{season.name} (E:{season.episode_count}) diff --git a/src/components/SimilarCardItem.tsx b/src/components/SimilarCardItem.tsx index 446318f..767fb30 100644 --- a/src/components/SimilarCardItem.tsx +++ b/src/components/SimilarCardItem.tsx @@ -3,6 +3,7 @@ import { Star } from "lucide-react"; import { Link } from "react-router-dom"; import { Button } from "./ui/button"; import imageUrl from "@/utils/image-url"; +import Image from "./Image"; interface SimilarCardItemProps { card: SimilarType; @@ -36,11 +37,10 @@ export default function SimilarCardItem<

- {movieTitle}
diff --git a/src/hooks/useImageFallback.ts b/src/hooks/useImageFallback.ts new file mode 100644 index 0000000..965c569 --- /dev/null +++ b/src/hooks/useImageFallback.ts @@ -0,0 +1,26 @@ +import { useEffect, useState } from "react"; + +export type TypeImage = "poster" | "backdrop"; + +const useImageFallback = (type: TypeImage) => { + const [fallback, setFallback] = useState("/poster-fallback.png"); + + useEffect(() => { + switch (type) { + case "poster": + setFallback("/poster-fallback.png"); + break; + case "backdrop": + setFallback("/backdrop-fallback.png"); + break; + default: + setFallback("/poster-fallback.png"); + } + }, [setFallback, type]); + + return { + fallback, + }; +}; + +export default useImageFallback; diff --git a/src/pages/Show/Movie.tsx b/src/pages/Show/Movie.tsx index 8900b63..3ab16ce 100644 --- a/src/pages/Show/Movie.tsx +++ b/src/pages/Show/Movie.tsx @@ -83,6 +83,7 @@ export default function Movie() { key={image.file_path} className="basis-1/2 lg:basis-1/3" > + {/* TODO: tag custom image component */} Date: Mon, 25 Mar 2024 13:27:25 +0700 Subject: [PATCH 3/6] wip: implemented custom image component on page `/movie` and `/tv` --- src/components/Image.tsx | 10 ++++++---- src/pages/Show/Movie.tsx | 6 ++++-- src/pages/Show/Tv.tsx | 4 +++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 716db77..36e307a 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,14 +1,15 @@ import type { SyntheticEvent } from "react"; import type { TypeImage } from "@/hooks/useImageFallback"; import useImageFallback from "@/hooks/useImageFallback"; +import React from "react"; -// forward props like shadcn -interface ImageProps { +type ImageProps = React.HTMLAttributes & { src: string; alt: string; type: TypeImage; -} -export default function Image({ src, alt, type }: ImageProps) { +}; +export default function Image(props: ImageProps) { + const { src, alt, type, ...restProps } = props; const { fallback } = useImageFallback(type); const imageFallback = (event: SyntheticEvent) => { @@ -20,6 +21,7 @@ export default function Image({ src, alt, type }: ImageProps) { return ( {alt}
-
diff --git a/src/pages/Show/Tv.tsx b/src/pages/Show/Tv.tsx index eb4c406..0fcc64c 100644 --- a/src/pages/Show/Tv.tsx +++ b/src/pages/Show/Tv.tsx @@ -18,6 +18,7 @@ import pickRandomImages from "@/utils/pick-random-images"; import SeasonCardItem from "@/components/SeasonCardItem"; import WatchProviderContainer from "@/components/WatchProviderContainer"; import PopupYoutubeTrailer from "@/components/PopupYoutubeTrailer"; +import Image from "@/components/Image"; export default function Tv() { const params = useParams(); @@ -107,13 +108,14 @@ export default function Tv() { {/* Backgroud */}
-
From 84534c96a4cb598975d2ac7016e0d7908c588ed8 Mon Sep 17 00:00:00 2001 From: nnivxix Date: Mon, 25 Mar 2024 14:01:30 +0700 Subject: [PATCH 4/6] fix: component custom image --- src/components/Image.tsx | 13 +++++-------- src/pages/Show/Movie.tsx | 4 ++-- src/pages/Show/Tv.tsx | 3 ++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 36e307a..2568913 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -1,17 +1,14 @@ -import type { SyntheticEvent } from "react"; +import type { ImgHTMLAttributes, SyntheticEvent } from "react"; import type { TypeImage } from "@/hooks/useImageFallback"; import useImageFallback from "@/hooks/useImageFallback"; -import React from "react"; -type ImageProps = React.HTMLAttributes & { +interface ImageProps extends ImgHTMLAttributes { src: string; alt: string; type: TypeImage; -}; -export default function Image(props: ImageProps) { - const { src, alt, type, ...restProps } = props; +} +export default function Image({ src, alt, type, ...props }: ImageProps) { const { fallback } = useImageFallback(type); - const imageFallback = (event: SyntheticEvent) => { event.currentTarget.src = fallback; }; @@ -21,7 +18,7 @@ export default function Image(props: ImageProps) { return ( {alt} - {/* TODO: tag custom image component */} - {image.file_path} diff --git a/src/pages/Show/Tv.tsx b/src/pages/Show/Tv.tsx index 0fcc64c..06ae1c8 100644 --- a/src/pages/Show/Tv.tsx +++ b/src/pages/Show/Tv.tsx @@ -77,12 +77,13 @@ export default function Tv() { key={image.file_path} className="basis-1/2 lg:basis-1/3" > - {image.file_path} From a302b6e8be8ad38830b52ff33e6223ec504f97aa Mon Sep 17 00:00:00 2001 From: nnivxix Date: Mon, 25 Mar 2024 14:05:23 +0700 Subject: [PATCH 5/6] fix: type image on carousel --- src/pages/Show/Tv.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Show/Tv.tsx b/src/pages/Show/Tv.tsx index 06ae1c8..cbcdc19 100644 --- a/src/pages/Show/Tv.tsx +++ b/src/pages/Show/Tv.tsx @@ -82,6 +82,7 @@ export default function Tv() { src={imageUrl({ path: image.file_path, size: "w500", + type: "backdrop", })} type="backdrop" alt={image.file_path} From 851d67d3378bf39594b0e6be6b72fc2dc4695a28 Mon Sep 17 00:00:00 2001 From: nnivxix Date: Mon, 25 Mar 2024 14:13:34 +0700 Subject: [PATCH 6/6] fix: default state fallback image --- src/hooks/useImageFallback.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useImageFallback.ts b/src/hooks/useImageFallback.ts index 965c569..d8e3dad 100644 --- a/src/hooks/useImageFallback.ts +++ b/src/hooks/useImageFallback.ts @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; export type TypeImage = "poster" | "backdrop"; const useImageFallback = (type: TypeImage) => { - const [fallback, setFallback] = useState("/poster-fallback.png"); + const [fallback, setFallback] = useState(""); useEffect(() => { switch (type) {