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 { 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 Layout from "@components/Layout";
|
||||||
|
import Loading from "@components/Loading";
|
||||||
|
|
||||||
const Watch: NextPage = () => {
|
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;
|
export default Watch;
|
||||||
|
Loading…
Reference in new issue