mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
add loading skeloton
This commit is contained in:
parent
af7a2b9477
commit
5b7d92d478
3 changed files with 4336 additions and 5281 deletions
|
@ -65,6 +65,7 @@
|
||||||
"react-helmet-async": "^2.0.4",
|
"react-helmet-async": "^2.0.4",
|
||||||
"react-i18next": "^14.1.1",
|
"react-i18next": "^14.1.1",
|
||||||
"react-lazy-with-preload": "^2.2.1",
|
"react-lazy-with-preload": "^2.2.1",
|
||||||
|
"react-loading-skeleton": "^3.4.0",
|
||||||
"react-router-dom": "^6.23.0",
|
"react-router-dom": "^6.23.0",
|
||||||
"react-sticky-el": "^2.1.0",
|
"react-sticky-el": "^2.1.0",
|
||||||
"react-use": "^17.5.0",
|
"react-use": "^17.5.0",
|
||||||
|
|
8929
pnpm-lock.yaml
8929
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import Skeleton from "react-loading-skeleton";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { get } from "@/backend/metadata/tmdb";
|
import { get } from "@/backend/metadata/tmdb";
|
||||||
|
@ -23,11 +24,14 @@ type StyleState = {
|
||||||
visibility: "visible" | "hidden" | undefined;
|
visibility: "visible" | "hidden" | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatRuntime = (minutes: number): string => {
|
function formatRuntime(runtime: number) {
|
||||||
const hours = Math.floor(minutes / 60);
|
const hours = Math.floor(runtime / 60);
|
||||||
const mins = minutes % 60;
|
const minutes = runtime % 60;
|
||||||
return `${hours}h ${mins}m`;
|
if (hours > 0) {
|
||||||
};
|
return `${hours}h ${minutes}m`;
|
||||||
|
}
|
||||||
|
return `${minutes}m`;
|
||||||
|
}
|
||||||
|
|
||||||
export function PopupModal({
|
export function PopupModal({
|
||||||
isVisible,
|
isVisible,
|
||||||
|
@ -152,49 +156,73 @@ export function PopupModal({
|
||||||
className="rounded-xl p-3 m-6 bg-modal-background flex justify-center items-center transition-opacity duration-200 w-full max-w-3xl"
|
className="rounded-xl p-3 m-6 bg-modal-background flex justify-center items-center transition-opacity duration-200 w-full max-w-3xl"
|
||||||
style={{ opacity: style.opacity }}
|
style={{ opacity: style.opacity }}
|
||||||
>
|
>
|
||||||
<div className="aspect-w-16 aspect-h-9 w-full">
|
<div className="aspect-w-16 aspect-h-9 w-full overflow-y-auto">
|
||||||
|
<div className="rounded-xl w-full h-full">
|
||||||
|
{data?.backdrop_path ? (
|
||||||
<img
|
<img
|
||||||
src={`https://image.tmdb.org/t/p/original/${data?.backdrop_path}`}
|
src={`https://image.tmdb.org/t/p/original/${data.backdrop_path}`}
|
||||||
className="rounded-xl object-cover w-full h-full"
|
className="rounded-xl object-cover w-full h-full"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="flex pt-3 items-center gap-4">
|
<div className="flex pt-3 items-center gap-4">
|
||||||
<h1 className="relative text-2xl whitespace-normal font-bold text-white">
|
<h1 className="relative text-2xl whitespace-normal font-bold text-white">
|
||||||
{data?.title || data?.name}
|
{data?.title || data?.name ? (
|
||||||
|
data?.title || data?.name
|
||||||
|
) : (
|
||||||
|
<Skeleton />
|
||||||
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
<div className="font-semibold">
|
<div className="font-semibold">
|
||||||
{media.type === "movie" ? (
|
{media.type === "movie" ? (
|
||||||
|
displayCertification ? (
|
||||||
<div className="px-2 py-1 bg-search-background rounded">
|
<div className="px-2 py-1 bg-search-background rounded">
|
||||||
<span>{displayCertification}</span>
|
<span>{displayCertification}</span>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="animate-pulse h-6 w-12 bg-gray-300 rounded" />
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<div className="px-2 py-1 bg-search-background rounded">
|
<div className="px-2 py-1 bg-search-background rounded">
|
||||||
<span>
|
<span>
|
||||||
{(() => {
|
{(() => {
|
||||||
mediaInfo?.results?.find(
|
const releaseInfo = mediaInfo?.results?.find(
|
||||||
(result: any) => result.iso_3166_1 === "US",
|
(result: any) => result.iso_3166_1 === "US",
|
||||||
);
|
);
|
||||||
return usReleaseInfo && usReleaseInfo.rating
|
return releaseInfo && releaseInfo.rating ? (
|
||||||
? usReleaseInfo.rating
|
releaseInfo.rating
|
||||||
: "Not Rated";
|
) : (
|
||||||
|
<div className="animate-pulse inline-block h-6 w-12 bg-gray-300 rounded" />
|
||||||
|
);
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row gap-2 font-bold">
|
<div className="flex flex-row gap-2 font-bold">
|
||||||
{media.type === "movie" &&
|
{media.type === "movie" ? (
|
||||||
data?.runtime &&
|
data?.runtime ? (
|
||||||
formatRuntime(data.runtime)}
|
formatRuntime(data.runtime)
|
||||||
|
) : (
|
||||||
|
<div className="animate-pulse h-6 w-16 bg-gray-300 rounded" />
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
<div>
|
<div>
|
||||||
{media.type === "movie"
|
{media.type === "movie" ? (
|
||||||
? data?.release_date
|
data?.release_date ? (
|
||||||
? String(data.release_date).split("-")[0]
|
String(data.release_date).split("-")[0]
|
||||||
: null
|
) : (
|
||||||
: media.type === "show"
|
<div className="animate-pulse h-6 w-12 bg-gray-300 rounded" />
|
||||||
? data?.first_air_date
|
)
|
||||||
? String(data.first_air_date).split("-")[0]
|
) : media.type === "show" ? (
|
||||||
: null
|
data?.first_air_date ? (
|
||||||
: null}
|
String(data.first_air_date).split("-")[0]
|
||||||
|
) : (
|
||||||
|
<div className="animate-pulse h-6 w-12 bg-gray-300 rounded" />
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -212,18 +240,25 @@ export function PopupModal({
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
{data?.genres?.map((genre: { name: string }) => (
|
{data?.genres?.length > 0
|
||||||
|
? data.genres.map((genre: { name: string }) => (
|
||||||
<div
|
<div
|
||||||
key={genre.name}
|
key={genre.name}
|
||||||
className="px-2 py-1 bg-mediaCard-hoverBackground rounded hover:bg-search-background cursor-default duration-200 transition-colors"
|
className="px-2 py-1 bg-mediaCard-hoverBackground rounded hover:bg-search-background cursor-default duration-200 transition-colors"
|
||||||
>
|
>
|
||||||
{genre.name}
|
{genre.name}
|
||||||
</div>
|
</div>
|
||||||
|
))
|
||||||
|
: Array.from({ length: 3 }).map((_) => (
|
||||||
|
<div className="animate-pulse h-6 w-24 bg-gray-300 rounded" />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p className="relative whitespace-normal font-medium">
|
<div
|
||||||
|
className="relative whitespace-normal font-medium overflow-y-auto"
|
||||||
|
style={{ maxHeight: "100px" }}
|
||||||
|
>
|
||||||
{data?.overview}
|
{data?.overview}
|
||||||
</p>
|
</div>
|
||||||
<div className="flex justify-center items-center mt-4 mb-1">
|
<div className="flex justify-center items-center mt-4 mb-1">
|
||||||
<Button
|
<Button
|
||||||
theme="purple"
|
theme="purple"
|
||||||
|
|
Loading…
Reference in a new issue