feat: skeleton for videos

This commit is contained in:
Artemy 2023-08-09 18:54:05 +03:00
parent f437be86c7
commit ce520717e0
4 changed files with 54 additions and 14 deletions

View file

@ -1,13 +1,16 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head>
<head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title> <title>Vite + React + TS</title>
</head> </head>
<body>
<body>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/main.tsx"></script> <script type="module" src="/src/main.tsx"></script>
</body> </body>
</html> </html>

View file

@ -1,4 +1,11 @@
import { Avatar, Card, CardBody, CardHeader, Link } from "@nextui-org/react"; import {
Avatar,
Card,
CardBody,
CardHeader,
Link,
Skeleton,
} from "@nextui-org/react";
import { Video } from "piped-api/dist/types"; import { Video } from "piped-api/dist/types";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { CheckCircleIcon, EyeIcon } from "@heroicons/react/24/solid"; import { CheckCircleIcon, EyeIcon } from "@heroicons/react/24/solid";
@ -23,7 +30,7 @@ export function VideoComponent({ video }: VideoComponentProps) {
{video.title} {video.title}
</Link> </Link>
<Link color="foreground" href={`#${video.uploaderUrl}`}> <Link color="foreground" href={`#${video.uploaderUrl}`}>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center break-all">
<p className="flex-none text-md">{video.uploaderName}</p> <p className="flex-none text-md">{video.uploaderName}</p>
{video.uploaderVerified && ( {video.uploaderVerified && (
<CheckCircleIcon className="w-6 h-6 p-1" /> <CheckCircleIcon className="w-6 h-6 p-1" />
@ -42,6 +49,19 @@ export function VideoComponent({ video }: VideoComponentProps) {
); );
} }
export function SkeletonVideoComponent() {
return (
<Card isBlurred isPressable shadow="none" className="space-y-5 p-4">
<Skeleton className="rounded-lg">
<div className="rounded-lg h-56 bg-default-300 p-4"></div>
</Skeleton>
<CardBody className="flex gap-3 flex-row">
<Skeleton className="flex rounded-full w-12 h-12" />
</CardBody>
</Card>
);
}
type VideoComponentProps = { type VideoComponentProps = {
video: Video; video: Video;
}; };

View file

@ -1,3 +1,10 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@layer base {
body {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32' fill='none' stroke='%23f1f5f9'%3e%3cpath d='M0 .5H31.5V32'/%3e%3c/svg%3e");
@apply bg-gray-200;
}
}

View file

@ -1,6 +1,6 @@
import { Video } from "piped-api/dist/types"; import { Video } from "piped-api/dist/types";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { VideoComponent } from "../components/video"; import { SkeletonVideoComponent, VideoComponent } from "../components/video";
export default function Trending() { export default function Trending() {
const [trending, setTrending] = useState([] as Video[]); const [trending, setTrending] = useState([] as Video[]);
@ -16,6 +16,16 @@ export default function Trending() {
} }
}); });
if (trending.length === 0) {
return (
<div className="grid md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 gap-2 p-4">
{[...Array(20).keys()].map((num) => (
<SkeletonVideoComponent key={num} />
))}
</div>
);
}
return ( return (
<div className="grid md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 gap-2 p-4"> <div className="grid md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 gap-2 p-4">
{trending.map((video) => ( {trending.map((video) => (