mirror of
https://github.com/tubearchivist/tubearchivist-frontend.git
synced 2024-11-22 20:00:15 +00:00
feat: add playlist page
This commit is contained in:
parent
2e4cd0b914
commit
3efd651db3
19
tubearchivist/www/src/lib/getPlaylists.ts
Normal file
19
tubearchivist/www/src/lib/getPlaylists.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Playlist } from "../types/playlist";
|
||||||
|
|
||||||
|
export const getPlaylists = async (token: string): Promise<Playlist> => {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.NEXT_PUBLIC_TUBEARCHIVIST_URL}/api/playlist/`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Token ${token}`,
|
||||||
|
mode: "no-cors",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Error getting channel information");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
178
tubearchivist/www/src/pages/playlist.tsx
Normal file
178
tubearchivist/www/src/pages/playlist.tsx
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import { GetServerSideProps } from "next";
|
||||||
|
import NextImage from "next/image";
|
||||||
|
import { getSession, useSession } from "next-auth/react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { dehydrate, QueryClient, useQuery } from "react-query";
|
||||||
|
import { CustomHead } from "../components/CustomHead";
|
||||||
|
import { Layout } from "../components/Layout";
|
||||||
|
import { TA_BASE_URL } from "../lib/constants";
|
||||||
|
import { getPlaylists } from "../lib/getPlaylists";
|
||||||
|
import IconAdd from "../images/icon-add.svg";
|
||||||
|
import IconListView from "../images/icon-listview.svg";
|
||||||
|
import IconGridView from "../images/icon-gridview.svg";
|
||||||
|
|
||||||
|
type ViewStyle = "grid" | "list";
|
||||||
|
|
||||||
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
const session = await getSession(context);
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
destination: "/auth/login",
|
||||||
|
permanent: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await queryClient.prefetchQuery("playlists", () =>
|
||||||
|
getPlaylists(session.ta_token.token)
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
dehydratedState: dehydrate(queryClient),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Playlist = () => {
|
||||||
|
const { data: session } = useSession();
|
||||||
|
const {
|
||||||
|
data: { data: playlists },
|
||||||
|
} = useQuery("playlists", () => getPlaylists(session.ta_token.token));
|
||||||
|
|
||||||
|
const [viewStyle, setViewStyle] = useState<ViewStyle>("grid");
|
||||||
|
|
||||||
|
const handleSetViewstyle = (selectedViewStyle: ViewStyle) => {
|
||||||
|
setViewStyle(selectedViewStyle);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<CustomHead title="Playlist" />
|
||||||
|
|
||||||
|
<div className="boxed-content">
|
||||||
|
<div className="title-split">
|
||||||
|
<div className="title-bar">
|
||||||
|
<h1>Playlists</h1>
|
||||||
|
</div>
|
||||||
|
<div className="title-split-form">
|
||||||
|
<NextImage
|
||||||
|
id="animate-icon"
|
||||||
|
// onClick="showForm()"
|
||||||
|
src={IconAdd}
|
||||||
|
width={45}
|
||||||
|
height={40}
|
||||||
|
alt="add-icon"
|
||||||
|
title="Subscribe to Playlists"
|
||||||
|
/>
|
||||||
|
<div className="show-form">
|
||||||
|
<form id="hidden-form" action="/playlist/" method="post">
|
||||||
|
{/* {% csrf_token %}
|
||||||
|
{{ subscribe_form }} */}
|
||||||
|
<button type="submit">Subscribe</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* <div id="notifications" data="playlist"></div> */}
|
||||||
|
<div className="view-controls">
|
||||||
|
<div className="toggle">
|
||||||
|
<span>Show subscribed only:</span>
|
||||||
|
<div className="toggleBox">
|
||||||
|
<input
|
||||||
|
id="show_subed_only"
|
||||||
|
// onClick="toggleCheckbox(this)"
|
||||||
|
type="checkbox"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
{/* {% if not show_subed_only %} */}
|
||||||
|
<label htmlFor="" className="ofbtn">
|
||||||
|
Off
|
||||||
|
</label>
|
||||||
|
{/* {% else %} */}
|
||||||
|
<label htmlFor="" className="onbtn">
|
||||||
|
On
|
||||||
|
</label>
|
||||||
|
{/* {% endif %} */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="view-icons">
|
||||||
|
<NextImage
|
||||||
|
src={IconGridView}
|
||||||
|
width={35}
|
||||||
|
height={30}
|
||||||
|
onClick={() => handleSetViewstyle("grid")}
|
||||||
|
alt="grid view"
|
||||||
|
/>
|
||||||
|
<NextImage
|
||||||
|
src={IconListView}
|
||||||
|
width={35}
|
||||||
|
height={30}
|
||||||
|
onClick={() => handleSetViewstyle("list")}
|
||||||
|
alt="list view"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`playlist-list ${viewStyle}`}>
|
||||||
|
{/* {% if results %}
|
||||||
|
{% for playlist in results %} */}
|
||||||
|
{!playlists ? (
|
||||||
|
<h2>No playlists found...</h2>
|
||||||
|
) : (
|
||||||
|
playlists?.map((playlist) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={playlist.playlist_id}
|
||||||
|
className={`playlist-item ${viewStyle}`}
|
||||||
|
>
|
||||||
|
<div className="playlist-thumbnail">
|
||||||
|
<a href="{% url 'playlist_id' playlist.source.playlist_id %}">
|
||||||
|
<img
|
||||||
|
src={`${TA_BASE_URL}/${playlist.playlist_thumbnail}`}
|
||||||
|
alt={`${playlist.playlist_id}-thumbnail`}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className={`playlist-desc ${viewStyle}`}>
|
||||||
|
<a href="{% url 'channel_id' playlist.source.playlist_channel_id %}">
|
||||||
|
<h3> {playlist.playlist_channel} </h3>
|
||||||
|
</a>
|
||||||
|
<a href="{% url 'playlist_id' playlist.source.playlist_id %}">
|
||||||
|
<h2> {playlist.playlist_name} </h2>
|
||||||
|
</a>
|
||||||
|
<p>Last refreshed: {playlist.playlist_last_refresh} </p>
|
||||||
|
{/* {% if playlist.source.playlist_subscribed %} */}
|
||||||
|
<button
|
||||||
|
className="unsubscribe"
|
||||||
|
type="button"
|
||||||
|
id="{{ playlist.source.playlist_id }}"
|
||||||
|
// onClick="unsubscribe(this.id)"
|
||||||
|
title="Unsubscribe from {{ playlist.source.playlist_name }}"
|
||||||
|
>
|
||||||
|
Unsubscribe
|
||||||
|
</button>
|
||||||
|
{/* {% else %} */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
id="{{ playlist.source.playlist_id }}"
|
||||||
|
// onClick="subscribe(this.id)"
|
||||||
|
title="Subscribe to {{ playlist.source.playlist_name }}"
|
||||||
|
>
|
||||||
|
Subscribe
|
||||||
|
</button>
|
||||||
|
{/* {% endif %} */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Playlist;
|
104
tubearchivist/www/src/types/playlist.ts
Normal file
104
tubearchivist/www/src/types/playlist.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
export interface Playlist {
|
||||||
|
data: Datum[];
|
||||||
|
config: Config;
|
||||||
|
paginate: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
archive: Archive;
|
||||||
|
default_view: DefaultView;
|
||||||
|
subscriptions: Subscriptions;
|
||||||
|
downloads: Downloads;
|
||||||
|
application: Application;
|
||||||
|
scheduler: Scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Application {
|
||||||
|
app_root: string;
|
||||||
|
cache_dir: string;
|
||||||
|
videos: string;
|
||||||
|
file_template: string;
|
||||||
|
colors: string;
|
||||||
|
enable_cast: boolean;
|
||||||
|
REDIS_HOST: string;
|
||||||
|
es_url: string;
|
||||||
|
es_auth: string[];
|
||||||
|
HOST_UID: number;
|
||||||
|
HOST_GID: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Archive {
|
||||||
|
sort_by: string;
|
||||||
|
sort_order: string;
|
||||||
|
page_size: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultView {
|
||||||
|
home: string;
|
||||||
|
channel: string;
|
||||||
|
downloads: string;
|
||||||
|
playlist: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Downloads {
|
||||||
|
limit_count: boolean;
|
||||||
|
limit_speed: boolean;
|
||||||
|
sleep_interval: number;
|
||||||
|
autodelete_days: boolean;
|
||||||
|
format: boolean;
|
||||||
|
add_metadata: boolean;
|
||||||
|
add_thumbnail: boolean;
|
||||||
|
subtitle: boolean;
|
||||||
|
subtitle_source: boolean;
|
||||||
|
subtitle_index: boolean;
|
||||||
|
throttledratelimit: boolean;
|
||||||
|
integrate_ryd: boolean;
|
||||||
|
integrate_sponsorblock: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Scheduler {
|
||||||
|
update_subscribed: boolean;
|
||||||
|
download_pending: boolean;
|
||||||
|
check_reindex: CheckReindex;
|
||||||
|
check_reindex_days: number;
|
||||||
|
thumbnail_check: CheckReindex;
|
||||||
|
run_backup: CheckReindex;
|
||||||
|
run_backup_rotate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CheckReindex {
|
||||||
|
minute: string;
|
||||||
|
hour: string;
|
||||||
|
day_of_week: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Subscriptions {
|
||||||
|
auto_search: boolean;
|
||||||
|
auto_download: boolean;
|
||||||
|
channel_size: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Datum {
|
||||||
|
playlist_active: boolean;
|
||||||
|
playlist_channel: PlaylistChannel;
|
||||||
|
playlist_channel_id: string;
|
||||||
|
playlist_description: boolean;
|
||||||
|
playlist_entries: PlaylistEntry[];
|
||||||
|
playlist_id: string;
|
||||||
|
playlist_last_refresh: string;
|
||||||
|
playlist_name: string;
|
||||||
|
playlist_subscribed: boolean;
|
||||||
|
playlist_thumbnail: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PlaylistChannel {
|
||||||
|
NileRed = "NileRed",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PlaylistEntry {
|
||||||
|
youtube_id: string;
|
||||||
|
title: string;
|
||||||
|
uploader: PlaylistChannel;
|
||||||
|
idx: number;
|
||||||
|
downloaded: boolean;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user