Reworked interface folder, added fetching to /watch
parent
8e2b0e5d6b
commit
8fb529d21c
@ -0,0 +1,19 @@
|
||||
import { FC } from "react";
|
||||
|
||||
import Box from "@mui/material/Box";
|
||||
import CircularProgress from "@mui/material/CircularProgress";
|
||||
|
||||
const Loading: FC = () => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
mt: 5
|
||||
}}
|
||||
>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
);
|
||||
|
||||
export default Loading;
|
@ -0,0 +1,27 @@
|
||||
interface Trending {
|
||||
type: string;
|
||||
title: string;
|
||||
videoId: string;
|
||||
author: string;
|
||||
authorId: string;
|
||||
authorUrl: string;
|
||||
videoThumbnails: VideoThumbnail[];
|
||||
description: string;
|
||||
descriptionHtml: string;
|
||||
viewCount: number;
|
||||
published: number;
|
||||
publishedText: string;
|
||||
lengthSeconds: number;
|
||||
liveNow: boolean;
|
||||
premium: boolean;
|
||||
isUpcoming: boolean;
|
||||
}
|
||||
|
||||
interface VideoThumbnail {
|
||||
quality: string;
|
||||
url: string;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export default Trending;
|
@ -0,0 +1,129 @@
|
||||
export interface Video {
|
||||
type: string;
|
||||
title: string;
|
||||
videoId: string;
|
||||
videoThumbnails: Thumbnail[];
|
||||
storyboards: Storyboard[];
|
||||
description: string;
|
||||
descriptionHtml: string;
|
||||
published: number;
|
||||
publishedText: string;
|
||||
keywords: string[];
|
||||
viewCount: number;
|
||||
likeCount: number;
|
||||
dislikeCount: number;
|
||||
paid: boolean;
|
||||
premium: boolean;
|
||||
isFamilyFriendly: boolean;
|
||||
allowedRegions: string[];
|
||||
premiereTimestamp?: number;
|
||||
genre: string;
|
||||
genreUrl: string;
|
||||
author: string;
|
||||
authorId: string;
|
||||
authorUrl: string;
|
||||
authorThumbnails: Thumbnail[];
|
||||
subCountText: string;
|
||||
lengthSeconds: number;
|
||||
allowRatings: boolean;
|
||||
rating: number;
|
||||
isListed: boolean;
|
||||
liveNow: boolean;
|
||||
isUpcoming: boolean;
|
||||
dashUrl: string;
|
||||
adaptiveFormats: AdaptiveFormat[];
|
||||
formatStreams: FormatStream[];
|
||||
captions: Caption[];
|
||||
recommendedVideos: RecommendedVideo[];
|
||||
}
|
||||
|
||||
export interface AdaptiveFormat {
|
||||
index: string;
|
||||
bitrate: string;
|
||||
init: string;
|
||||
url: string;
|
||||
itag: string;
|
||||
type: string;
|
||||
clen: string;
|
||||
lmt: string;
|
||||
projectionType: ProjectionType;
|
||||
fps?: number;
|
||||
container?: Container;
|
||||
encoding?: string;
|
||||
resolution?: string;
|
||||
qualityLabel?: string;
|
||||
}
|
||||
|
||||
export interface FormatStream {
|
||||
url: string;
|
||||
itag: string;
|
||||
type: string;
|
||||
quality: string;
|
||||
fps: number;
|
||||
container: string;
|
||||
encoding: string;
|
||||
resolution: string;
|
||||
qualityLabel: string;
|
||||
size: string;
|
||||
}
|
||||
|
||||
enum Container {
|
||||
M4A = "m4a",
|
||||
Mp4 = "mp4",
|
||||
Webm = "webm"
|
||||
}
|
||||
|
||||
enum ProjectionType {
|
||||
Rectangular = "RECTANGULAR"
|
||||
}
|
||||
|
||||
interface Thumbnail {
|
||||
url: string;
|
||||
width: number;
|
||||
height: number;
|
||||
quality?: Quality;
|
||||
}
|
||||
|
||||
enum Quality {
|
||||
Default = "default",
|
||||
End = "end",
|
||||
High = "high",
|
||||
Maxres = "maxres",
|
||||
Maxresdefault = "maxresdefault",
|
||||
Medium = "medium",
|
||||
Middle = "middle",
|
||||
Sddefault = "sddefault",
|
||||
Start = "start"
|
||||
}
|
||||
|
||||
export interface Caption {
|
||||
label: string;
|
||||
language_code: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface RecommendedVideo {
|
||||
videoId: string;
|
||||
title: string;
|
||||
videoThumbnails: Thumbnail[];
|
||||
author: string;
|
||||
authorUrl: string;
|
||||
authorId: string;
|
||||
lengthSeconds: number;
|
||||
viewCountText: string;
|
||||
viewCount: number;
|
||||
}
|
||||
|
||||
interface Storyboard {
|
||||
url: string;
|
||||
templateUrl: string;
|
||||
width: number;
|
||||
height: number;
|
||||
count: number;
|
||||
interval: number;
|
||||
storyboardWidth: number;
|
||||
storyboardHeight: number;
|
||||
storyboardCount: number;
|
||||
}
|
||||
|
||||
export default Video;
|
@ -1,9 +1,61 @@
|
||||
import NotFound from "./404";
|
||||
import axios, { AxiosError } from "axios";
|
||||
|
||||
import { NextPage } from "next";
|
||||
import { NextSeo } from "next-seo";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { useQuery } from "react-query";
|
||||
|
||||
import { Error } from "@interfaces/api";
|
||||
import Video from "@interfaces/api/video";
|
||||
|
||||
import { videoToVideo } from "@utils/conversions";
|
||||
|
||||
import Layout from "@components/Layout";
|
||||
import Loading from "@components/Loading";
|
||||
|
||||
const Watch: NextPage = () => {
|
||||
return <Layout></Layout>;
|
||||
const router = useRouter();
|
||||
|
||||
const videoId = router.query["v"];
|
||||
|
||||
const { isLoading, error, data, refetch } = useQuery<
|
||||
Video,
|
||||
AxiosError<Error>
|
||||
>(
|
||||
["videoData", videoId],
|
||||
() =>
|
||||
axios
|
||||
.get(`https://invidious.privacy.gd/api/v1/videos/${videoId}`, {
|
||||
params: {}
|
||||
})
|
||||
.then((res) => res.data),
|
||||
{ enabled: false }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (videoId) refetch();
|
||||
}, [videoId, refetch]);
|
||||
|
||||
if (!videoId) {
|
||||
return <NotFound />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo
|
||||
title={data ? data.title : isLoading ? "Loading video..." : "Not Found"}
|
||||
/>
|
||||
|
||||
<Layout>
|
||||
{isLoading && <Loading />}
|
||||
{}
|
||||
</Layout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Watch;
|
||||
|
Loading…
Reference in new issue