From 59678b6a5974fc2355ca82c54273f90e616489fd Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Sat, 15 Feb 2025 17:32:37 +0100 Subject: [PATCH] feat: loader on images --- src/components/home/HeroSection.tsx | 16 ++++-- src/components/home/MediaRow.tsx | 16 ++++-- src/components/library/SeriesGrid.tsx | 38 ++++++++++----- src/components/reader/BookReader.tsx | 50 ++++++++++++------- src/components/series/BookGrid.tsx | 51 +++++++++++++++++--- src/components/series/SeriesHeader.tsx | 15 +++++- src/components/ui/image-loader.tsx | 67 ++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 49 deletions(-) create mode 100644 src/components/ui/image-loader.tsx diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx index 0c89f3f..d5581c5 100644 --- a/src/components/home/HeroSection.tsx +++ b/src/components/home/HeroSection.tsx @@ -5,6 +5,7 @@ import Image from "next/image"; import { useState } from "react"; import { ImageOff } from "lucide-react"; import { cn } from "@/lib/utils"; +import { ImageLoader } from "@/components/ui/image-loader"; interface HeroSectionProps { series: KomgaSeries[]; @@ -47,23 +48,28 @@ interface CoverImageProps { function CoverImage({ series }: CoverImageProps) { const [imageError, setImageError] = useState(false); + const [imageLoading, setImageLoading] = useState(true); return (
{!imageError ? ( -
+ <> + {`Couverture setImageError(true)} + onLoad={() => setImageLoading(false)} /> -
+ ) : (
diff --git a/src/components/home/MediaRow.tsx b/src/components/home/MediaRow.tsx index 69942a2..3d62a91 100644 --- a/src/components/home/MediaRow.tsx +++ b/src/components/home/MediaRow.tsx @@ -5,6 +5,7 @@ import { ChevronLeft, ChevronRight, ImageOff } from "lucide-react"; import Image from "next/image"; import { useRef, useState } from "react"; import { cn } from "@/lib/utils"; +import { ImageLoader } from "@/components/ui/image-loader"; interface MediaRowProps { title: string; @@ -82,6 +83,7 @@ interface MediaCardProps { function MediaCard({ item, onClick }: MediaCardProps) { const [imageError, setImageError] = useState(false); + const [imageLoading, setImageLoading] = useState(true); // Déterminer si c'est une série ou un livre const isSeries = "booksCount" in item; @@ -106,19 +108,23 @@ function MediaCard({ item, onClick }: MediaCardProps) { {/* Image de couverture */}
{!imageError ? ( -
+ <> + {`Couverture setImageError(true)} + onLoad={() => setImageLoading(false)} /> -
+ ) : (
diff --git a/src/components/library/SeriesGrid.tsx b/src/components/library/SeriesGrid.tsx index f971da6..1452965 100644 --- a/src/components/library/SeriesGrid.tsx +++ b/src/components/library/SeriesGrid.tsx @@ -1,10 +1,12 @@ "use client"; import { KomgaSeries } from "@/types/komga"; -import { Book, ImageOff } from "lucide-react"; +import { Book, ImageOff, Loader2 } from "lucide-react"; import Image from "next/image"; import { useState } from "react"; import { useRouter } from "next/navigation"; +import { ImageLoader } from "@/components/ui/image-loader"; +import { cn } from "@/lib/utils"; interface SeriesGridProps { series: KomgaSeries[]; @@ -66,27 +68,37 @@ interface SeriesCardProps { function SeriesCard({ series, onClick }: SeriesCardProps) { const [imageError, setImageError] = useState(false); + const [isLoading, setIsLoading] = useState(true); const statusInfo = getReadingStatusInfo(series); + const isCompleted = series.booksCount === series.booksReadCount; return (