mirror of
https://github.com/tubearchivist/tubearchivist-frontend.git
synced 2024-11-22 11:50:14 +00:00
chore: more code cleanup and use better env vars
This commit is contained in:
parent
526c98ca8a
commit
df30173ba3
@ -3,15 +3,17 @@ import NextImage from "next/image";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useQuery } from "react-query";
|
import { useQuery } from "react-query";
|
||||||
import IconPlay from "../../images/icon-play.svg";
|
import IconPlay from "../../images/icon-play.svg";
|
||||||
import { TA_BASE_URL } from "../../lib/constants";
|
import { getTAUrl } from "../../lib/constants";
|
||||||
import { getVideos } from "../../lib/getVideos";
|
import { getVideos } from "../../lib/getVideos";
|
||||||
import type { Datum } from "../../types/video";
|
import type { Data } from "../../types/video";
|
||||||
import VideoPlayer from "../VideoPlayer";
|
import VideoPlayer from "../VideoPlayer";
|
||||||
|
|
||||||
type ViewStyle = "grid" | "list";
|
type ViewStyle = "grid" | "list";
|
||||||
|
|
||||||
|
const TA_BASE_URL = getTAUrl();
|
||||||
|
|
||||||
const VideoList = () => {
|
const VideoList = () => {
|
||||||
const [selectedVideoUrl, setSelectedVideoUrl] = useState<Datum>();
|
const [selectedVideoUrl, setSelectedVideoUrl] = useState<Data>();
|
||||||
const [viewStyle, setViewStyle] = useState<ViewStyle>("grid");
|
const [viewStyle, setViewStyle] = useState<ViewStyle>("grid");
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const { data, error, isLoading } = useQuery(
|
const { data, error, isLoading } = useQuery(
|
||||||
@ -22,7 +24,7 @@ const VideoList = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSelectedVideo = (video: Datum) => {
|
const handleSelectedVideo = (video: Data) => {
|
||||||
setSelectedVideoUrl(video);
|
setSelectedVideoUrl(video);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ const VideoList = () => {
|
|||||||
<>
|
<>
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
handleRemoveVideoPlayer={handleRemoveVideoPlayer}
|
handleRemoveVideoPlayer={handleRemoveVideoPlayer}
|
||||||
selectedVideoUrl={selectedVideoUrl}
|
selectedVideo={selectedVideoUrl}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="boxed-content">
|
<div className="boxed-content">
|
||||||
@ -135,10 +137,10 @@ const VideoList = () => {
|
|||||||
<div className="video-thumb-wrap list">
|
<div className="video-thumb-wrap list">
|
||||||
<div className="video-thumb">
|
<div className="video-thumb">
|
||||||
<NextImage
|
<NextImage
|
||||||
src={`${TA_BASE_URL}/cache/${video.vid_thumb_url}`}
|
src={`${TA_BASE_URL.client}/cache/${video.vid_thumb_url}`}
|
||||||
alt="video-thumb"
|
alt="video-thumb"
|
||||||
width={325}
|
width={640}
|
||||||
height={190}
|
height={360}
|
||||||
blurDataURL={video.vid_thumb_base64}
|
blurDataURL={video.vid_thumb_base64}
|
||||||
placeholder="blur"
|
placeholder="blur"
|
||||||
/>
|
/>
|
||||||
|
@ -1,14 +1,28 @@
|
|||||||
import NextImage from "next/image";
|
import NextImage from "next/image";
|
||||||
|
import NextLink from "next/link";
|
||||||
import ReactPlayer from "react-player";
|
import ReactPlayer from "react-player";
|
||||||
|
import IconClose from "../../images/icon-close.svg";
|
||||||
import { TA_BASE_URL } from "../../lib/constants";
|
import { TA_BASE_URL } from "../../lib/constants";
|
||||||
import { formatNumbers } from "../../lib/utils";
|
import { formatNumbers } from "../../lib/utils";
|
||||||
import IconClose from "../../images/icon-close.svg";
|
import { Data } from "../../types/video";
|
||||||
|
|
||||||
const VideoPlayer = ({ selectedVideoUrl, handleRemoveVideoPlayer }) => {
|
type VideoPlayerProps = {
|
||||||
if (!selectedVideoUrl) return;
|
selectedVideo: Data;
|
||||||
|
handleRemoveVideoPlayer?: () => void;
|
||||||
|
isHome?: boolean;
|
||||||
|
showStats?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const VideoPlayer = ({
|
||||||
|
selectedVideo,
|
||||||
|
handleRemoveVideoPlayer,
|
||||||
|
isHome = true,
|
||||||
|
showStats = true,
|
||||||
|
}: VideoPlayerProps) => {
|
||||||
|
if (!selectedVideo) return;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{selectedVideoUrl && (
|
{selectedVideo && (
|
||||||
<div className="player-wrapper">
|
<div className="player-wrapper">
|
||||||
<div className="video-player">
|
<div className="video-player">
|
||||||
<ReactPlayer
|
<ReactPlayer
|
||||||
@ -18,8 +32,14 @@ const VideoPlayer = ({ selectedVideoUrl, handleRemoveVideoPlayer }) => {
|
|||||||
light={false}
|
light={false}
|
||||||
playing // TODO: Not currently working
|
playing // TODO: Not currently working
|
||||||
playsinline
|
playsinline
|
||||||
url={`${TA_BASE_URL}/media/${selectedVideoUrl?.media_url}`}
|
url={
|
||||||
|
isHome
|
||||||
|
? `${TA_BASE_URL}/media/${selectedVideo?.media_url}`
|
||||||
|
: `${TA_BASE_URL}/${selectedVideo?.media_url}`
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
<SponsorBlock />
|
||||||
|
{showStats ? (
|
||||||
<div className="player-title boxed-content">
|
<div className="player-title boxed-content">
|
||||||
<NextImage
|
<NextImage
|
||||||
className="close-button"
|
className="close-button"
|
||||||
@ -30,32 +50,32 @@ const VideoPlayer = ({ selectedVideoUrl, handleRemoveVideoPlayer }) => {
|
|||||||
onClick={handleRemoveVideoPlayer}
|
onClick={handleRemoveVideoPlayer}
|
||||||
title="Close player"
|
title="Close player"
|
||||||
/>
|
/>
|
||||||
{/* ${watchStatusIndicator}
|
|
||||||
${castButton}
|
|
||||||
*/}
|
|
||||||
<div className="thumb-icon player-stats">
|
<div className="thumb-icon player-stats">
|
||||||
<img src="/img/icon-eye.svg" alt="views icon" />
|
<img src="/img/icon-eye.svg" alt="views icon" />
|
||||||
<span>
|
<span>
|
||||||
{formatNumbers(selectedVideoUrl.stats.view_count.toString())}
|
{formatNumbers(selectedVideo.stats.view_count.toString())}
|
||||||
</span>
|
</span>
|
||||||
<span>|</span>
|
<span>|</span>
|
||||||
<img src="/img/icon-thumb.svg" alt="thumbs-up" />
|
<img src="/img/icon-thumb.svg" alt="thumbs-up" />
|
||||||
<span>
|
<span>
|
||||||
{formatNumbers(selectedVideoUrl.stats.like_count.toString())}
|
{formatNumbers(selectedVideo.stats.like_count.toString())}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="player-channel-playlist">
|
<div className="player-channel-playlist">
|
||||||
<h3>
|
<h3>
|
||||||
<a href="/channel/${channelId}/">
|
<a href="/channel/${channelId}/">
|
||||||
{selectedVideoUrl.channel.channel_name}
|
{selectedVideo.channel.channel_name}
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
{/* ${playlist} */}
|
{/* ${playlist} */}
|
||||||
</div>
|
</div>
|
||||||
<a href="/video/${videoId}/">
|
<NextLink href={`/video/${selectedVideo.youtube_id}/`}>
|
||||||
<h2 id="video-title">{selectedVideoUrl.title}</h2>
|
<a>
|
||||||
|
<h2 id="video-title">{selectedVideo.title}</h2>
|
||||||
</a>
|
</a>
|
||||||
|
</NextLink>
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -64,3 +84,45 @@ const VideoPlayer = ({ selectedVideoUrl, handleRemoveVideoPlayer }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default VideoPlayer;
|
export default VideoPlayer;
|
||||||
|
|
||||||
|
function SponsorBlock() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* <div className="notifications" id="notifications"></div> */}
|
||||||
|
<div className="sponsorblock" id="sponsorblock">
|
||||||
|
{/* {% if video.sponsorblock.is_enabled %} */}
|
||||||
|
{/* {% if video.sponsorblock.segments|length == 0 %} */}
|
||||||
|
<h4>
|
||||||
|
This video doesn't have any sponsor segments added. To add a
|
||||||
|
segment go to{" "}
|
||||||
|
<u>
|
||||||
|
<a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">
|
||||||
|
this video on YouTube
|
||||||
|
</a>
|
||||||
|
</u>{" "}
|
||||||
|
and add a segment using the{" "}
|
||||||
|
<u>
|
||||||
|
<a href="https://sponsor.ajay.app/">SponsorBlock</a>
|
||||||
|
</u>{" "}
|
||||||
|
extension.
|
||||||
|
</h4>
|
||||||
|
{/* {% elif video.sponsorblock.has_unlocked %} */}
|
||||||
|
<h4>
|
||||||
|
This video has unlocked sponsor segments. Go to{" "}
|
||||||
|
<u>
|
||||||
|
<a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">
|
||||||
|
this video on YouTube
|
||||||
|
</a>
|
||||||
|
</u>{" "}
|
||||||
|
and vote on the segments using the{" "}
|
||||||
|
<u>
|
||||||
|
<a href="https://sponsor.ajay.app/">SponsorBlock</a>
|
||||||
|
</u>{" "}
|
||||||
|
extension.
|
||||||
|
</h4>
|
||||||
|
{/* {% endif %} */}
|
||||||
|
{/* {% endif %} */}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -1 +1,12 @@
|
|||||||
export const TA_BASE_URL = process.env.NEXT_PUBLIC_TUBEARCHIVIST_URL;
|
export const getTAUrl = () => {
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
return {
|
||||||
|
client: process.env.NEXT_PUBLIC_TUBEARCHIVIST_URL,
|
||||||
|
server: process.env.NEXT_PUBLIC_TUBEARCHIVIST_URL,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
client: process.env.NEXT_PUBLIC_TUBEARCHIVIST_URL,
|
||||||
|
server: process.env.TUBEARCHIVIST_URL,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
import { Channel } from "../types/channel";
|
import { Channel } from "../types/channel";
|
||||||
import { TA_BASE_URL } from "./constants";
|
import { getTAUrl } from "./constants";
|
||||||
|
|
||||||
|
const TA_BASE_URL = getTAUrl();
|
||||||
|
|
||||||
export const getChannels = async (token: string): Promise<Channel> => {
|
export const getChannels = async (token: string): Promise<Channel> => {
|
||||||
const response = await fetch(`${TA_BASE_URL}/api/channel/`, {
|
if (!token) {
|
||||||
|
throw new Error(`Unable to fetch channels, no token provided`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${TA_BASE_URL.server}/api/channel/`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import { Playlist } from "../types/playlist";
|
import { Playlist } from "../types/playlist";
|
||||||
|
import { Playlists } from "../types/playlists";
|
||||||
import { TA_BASE_URL } from "./constants";
|
import { TA_BASE_URL } from "./constants";
|
||||||
|
|
||||||
export const getPlaylists = async (token: string): Promise<Playlist> => {
|
export const getPlaylists = async (token: string): Promise<Playlists> => {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error(`No token provided when fetching a playlists`);
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(`${TA_BASE_URL}/api/playlist/`, {
|
const response = await fetch(`${TA_BASE_URL}/api/playlist/`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
@ -11,7 +16,35 @@ export const getPlaylists = async (token: string): Promise<Playlist> => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Error getting channel information");
|
throw new Error(
|
||||||
|
`Error getting playlists information: ${response.statusText}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPlaylist = async (
|
||||||
|
token: string,
|
||||||
|
playlistId: string
|
||||||
|
): Promise<Playlist> => {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error(
|
||||||
|
`No token provided when fetching a playlist: ${playlistId}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`${TA_BASE_URL}/api/playlist/${playlistId}`, {
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Token ${token}`,
|
||||||
|
mode: "no-cors",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
`Error getting playlists information: ${response.statusText}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return response.json();
|
return response.json();
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,37 @@
|
|||||||
import { Videos } from "../types/video";
|
import { Video } from "../types/video";
|
||||||
import { TA_BASE_URL } from "./constants";
|
import { Videos } from "../types/videos";
|
||||||
|
import { getTAUrl } from "./constants";
|
||||||
|
|
||||||
|
const TA_BASE_URL = getTAUrl();
|
||||||
|
|
||||||
export const getVideos = async (token: string): Promise<Videos> => {
|
export const getVideos = async (token: string): Promise<Videos> => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new Error("Missing API token in request to get videos");
|
throw new Error("Missing API token in request to get videos");
|
||||||
}
|
}
|
||||||
const response = await fetch(`${TA_BASE_URL}/api/video/`, {
|
const response = await fetch(`${TA_BASE_URL.server}/api/video/`, {
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Token ${token}`,
|
||||||
|
mode: "no-cors",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to fetch videos");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getVideo = async (
|
||||||
|
token: string,
|
||||||
|
videoId: string
|
||||||
|
): Promise<Video> => {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error("Missing API token in request to get video");
|
||||||
|
}
|
||||||
|
const response = await fetch(`${TA_BASE_URL.server}/api/video/${videoId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import NextAuth from "next-auth";
|
import NextAuth from "next-auth";
|
||||||
import CredentialsProvider from "next-auth/providers/credentials";
|
import CredentialsProvider from "next-auth/providers/credentials";
|
||||||
import { TA_BASE_URL } from "../../../lib/constants";
|
import { getTAUrl } from "../../../lib/constants";
|
||||||
|
|
||||||
|
const TA_BASE_URL = getTAUrl();
|
||||||
|
|
||||||
type TA_Token = {
|
type TA_Token = {
|
||||||
token: string;
|
token: string;
|
||||||
@ -30,7 +32,7 @@ export default NextAuth({
|
|||||||
password: credentials.password,
|
password: credentials.password,
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await fetch(`${TA_BASE_URL}/api/login/`, {
|
const res = await fetch(`${TA_BASE_URL.server}/api/login/`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { CustomHead } from "../../components/CustomHead";
|
|
||||||
import { Layout } from "../../components/Layout";
|
|
||||||
import NextImage from "next/image";
|
|
||||||
import Logo from "../../images/logo-tube-archivist-dark.png";
|
|
||||||
import { getCsrfToken } from "next-auth/react";
|
|
||||||
import { NextPageContext } from "next";
|
import { NextPageContext } from "next";
|
||||||
|
import { getCsrfToken } from "next-auth/react";
|
||||||
|
import NextImage from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
import { CustomHead } from "../../components/CustomHead";
|
||||||
|
import Logo from "../../images/logo-tube-archivist-dark.png";
|
||||||
|
|
||||||
export async function getServerSideProps(context: NextPageContext) {
|
export async function getServerSideProps(context: NextPageContext) {
|
||||||
return {
|
return {
|
||||||
|
@ -4,9 +4,11 @@ import { useState } from "react";
|
|||||||
import { dehydrate, QueryClient, useQuery } from "react-query";
|
import { dehydrate, QueryClient, useQuery } from "react-query";
|
||||||
import { CustomHead } from "../components/CustomHead";
|
import { CustomHead } from "../components/CustomHead";
|
||||||
import { Layout } from "../components/Layout";
|
import { Layout } from "../components/Layout";
|
||||||
import { TA_BASE_URL } from "../lib/constants";
|
import { getTAUrl } from "../lib/constants";
|
||||||
import { getChannels } from "../lib/getChannels";
|
import { getChannels } from "../lib/getChannels";
|
||||||
|
|
||||||
|
const TA_BASE_URL = getTAUrl();
|
||||||
|
|
||||||
type ViewStyle = "grid" | "list";
|
type ViewStyle = "grid" | "list";
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
@ -54,6 +56,23 @@ const Channel: NextPage = () => {
|
|||||||
setViewStyle(selectedViewStyle);
|
setViewStyle(selectedViewStyle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<h1>Loading...</h1>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<h1>Error</h1>
|
||||||
|
<pre>{JSON.stringify(error, null, 2)}</pre>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CustomHead title="Channels" />
|
<CustomHead title="Channels" />
|
||||||
@ -128,7 +147,7 @@ const Channel: NextPage = () => {
|
|||||||
<div className={`channel-banner ${viewStyle}`}>
|
<div className={`channel-banner ${viewStyle}`}>
|
||||||
<a href="{% url 'channel_id' channel.source.channel_id %}">
|
<a href="{% url 'channel_id' channel.source.channel_id %}">
|
||||||
<img
|
<img
|
||||||
src={`${TA_BASE_URL}${channel?.channel_banner_url}`}
|
src={`${TA_BASE_URL.client}${channel?.channel_banner_url}`}
|
||||||
alt="{{ channel.source.channel_id }}-banner"
|
alt="{{ channel.source.channel_id }}-banner"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
@ -138,7 +157,7 @@ const Channel: NextPage = () => {
|
|||||||
<div className="round-img">
|
<div className="round-img">
|
||||||
<a href="{% url 'channel_id' channel.source.channel_id %}">
|
<a href="{% url 'channel_id' channel.source.channel_id %}">
|
||||||
<img
|
<img
|
||||||
src={`${TA_BASE_URL}${channel?.channel_thumb_url}`}
|
src={`${TA_BASE_URL.client}${channel?.channel_thumb_url}`}
|
||||||
alt="channel-thumb"
|
alt="channel-thumb"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
Loading…
Reference in New Issue
Block a user