Merge remote-tracking branch 'origin/feat_player'

This commit is contained in:
Kentai Radiquum 2024-07-29 21:39:37 +05:00
parent bb437fe7ca
commit 25e31a7799
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
62 changed files with 1508 additions and 701 deletions

359
app/pages/Release.tsx Normal file
View file

@ -0,0 +1,359 @@
"use client";
import useSWR from "swr";
import { Spinner } from "#/components/Spinner/Spinner";
const fetcher = (...args: any) =>
fetch([...args] as any).then((res) => res.json());
import { useUserStore } from "#/store/auth";
import { Card, Dropdown, Button } from "flowbite-react";
import { useEffect, useState } from "react";
import { unixToDate, getSeasonFromUnix, minutesToTime } from "#/api/utils";
import { ReleaseLink } from "#/components/ReleaseLink/ReleaseLink";
import { ReleasePlayer } from "#/components/ReleasePlayer/ReleasePlayer";
import { ENDPOINTS } from "#/api/config";
import { Table } from "flowbite-react";
import { ReleaseInfoSearchLink } from "#/components/ReleaseInfo/ReleaseInfo.SearchLink";
import Link from "next/link";
const lists = [
{ list: 0, name: "Не смотрю" },
{ list: 1, name: "Смотрю" },
{ list: 2, name: "В планах" },
{ list: 3, name: "Просмотрено" },
{ list: 4, name: "Отложено" },
{ list: 5, name: "Брошено" },
];
const weekDay = [
"_",
"каждый понедельник",
"каждый вторник",
"каждую среду",
"каждый четверг",
"каждую пятницу",
"каждую субботу",
"каждое воскресенье",
];
const YearSeason = ["_", "Зима", "Весна", "Лето", "Осень"];
const DropdownTheme = {
floating: {
target:
"flex-1 bg-blue-600 enabled:hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800",
},
};
export const ReleasePage = (props: any) => {
const token = useUserStore((state) => state.token);
const [userList, setUserList] = useState(0);
const [userFavorite, setUserFavorite] = useState(false);
function useFetch(id: number) {
let url: string;
url = `/api/release/${id}`;
if (token) {
url += `?token=${token}`;
}
const { data, isLoading, error } = useSWR(url, fetcher);
return [data, isLoading, error];
}
const [data, isLoading, error] = useFetch(props.id);
useEffect(() => {
if (data) {
const el = document.getElementById("note");
if (el) {
el.innerHTML = data.release.note;
}
setUserList(data.release.profile_list_status || 0);
setUserFavorite(data.release.is_favorite);
}
}, [data]);
function _addToFavorite() {
if (data && token) {
setUserFavorite(!userFavorite);
if (userFavorite) {
fetch(
`${ENDPOINTS.user.favorite}/delete/${data.release.id}?token=${token}`
);
} else {
fetch(
`${ENDPOINTS.user.favorite}/add/${data.release.id}?token=${token}`
);
}
}
}
function _addToList(list: number) {
if (data && token) {
setUserList(list);
fetch(
`${ENDPOINTS.user.bookmark}/add/${list}/${data.release.id}?token=${token}`
);
}
}
return data ? (
<main className="container px-4 pt-4 pb-24 mx-auto sm:pb-4">
<div className="grid grid-cols-[100%] lg:grid-cols-[70%_30%] gap-2 justify-center">
<div className="[grid-column:1] flex flex-col gap-2">
<Card className="lg:[grid-column:1]">
<div className="flex flex-col w-full h-full gap-4 lg:flex-row">
<img
className="w-[285px] max-h-[385px] object-cover border border-gray-200 rounded-lg shadow-md dark:border-gray-700"
src={data.release.image}
alt=""
></img>
<div className="flex flex-col max-w-2xl gap-2 text-sm md:text-base">
<div className="flex flex-col gap-1">
{data.release.title_ru && (
<p className="text-xl font-bold text-black md:text-2xl">
{data.release.title_ru}
</p>
)}
{data.release.title_original && (
<p className="text-sm text-gray-500 md:text-base">
{data.release.title_original}
</p>
)}
</div>
{data.release.note && (
<div className="py-2 bg-blue-100 border-l-4 border-blue-700 rounded-md ">
<div id="note" className="ml-2"></div>
</div>
)}
{data.release.description && <p>{data.release.description}</p>}
</div>
</div>
</Card>
{data.release.status.name.toLowerCase() != "анонс" && (
<ReleasePlayer id={props.id} />
)}
</div>
<div className="[grid-column:1] lg:[grid-column:2] flex flex-col gap-2">
<Card className="order-2 lg:order-1">
<Table>
<Table.Body>
<Table.Row>
<Table.Cell className="py-0">
{data.release.country ? (
data.release.country.toLowerCase() == "япония" ? (
<span className="w-8 h-8 iconify-color twemoji--flag-for-japan"></span>
) : (
<span className="w-8 h-8 iconify-color twemoji--flag-for-china"></span>
)
) : (
<span className="w-8 h-8 iconify-color twemoji--flag-for-united-nations "></span>
)}
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{data.release.country && data.release.country}
{(data.release.aired_on_date != 0 || data.release.year) &&
", "}
{data.release.aired_on_date != 0 &&
`${getSeasonFromUnix(data.release.aired_on_date)} `}
{data.release.year && `${data.release.year} г.`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
<span className="w-8 h-8 iconify-color mdi--animation-play "></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{data.release.episodes_released
? data.release.episodes_released
: "?"}
{"/"}
{data.release.episodes_total
? data.release.episodes_total + " эп. "
: "? эп. "}
{data.release.duration != 0 &&
`по ${minutesToTime(data.release.duration)}`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
<span className="w-8 h-8 iconify-color mdi--calendar "></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
{data.release.category.name}
{", "}
{data.release.broadcast == 0
? data.release.status.name.toLowerCase()
: `выходит ${weekDay[data.release.broadcast]}`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
<span className="w-8 h-8 iconify-color mdi--people "></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
{data.release.studio && (
<>
{"Студия: "}
{data.release.studio
.split(", ")
.map((studio: string, index: number) => {
return (
<>
{index > 0 && ", "}
<ReleaseInfoSearchLink
title={studio}
searchBy={1}
/>
</>
);
})}
{(data.release.author || data.release.director) && ", "}
</>
)}
{data.release.author && (
<>
{"Автор: "}
<ReleaseInfoSearchLink
title={data.release.author}
searchBy={3}
/>
{data.release.director && ", "}
</>
)}
{data.release.director && (
<>
{"Режиссёр: "}
<ReleaseInfoSearchLink
title={data.release.director}
searchBy={2}
/>
</>
)}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
<span className="w-8 h-8 iconify-color mdi--tag "></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
{data.release.genres &&
data.release.genres
.split(", ")
.map((genre: string, index: number) => {
return (
<>
{index > 0 && ", "}
<ReleaseInfoSearchLink
title={genre}
searchBy={4}
/>
</>
);
})}
</Table.Cell>
</Table.Row>
{data.release.status.name.toLowerCase() == "анонс" && (
<Table.Row>
<Table.Cell className="py-0">
<span className="w-8 h-8 iconify-color mdi--clock "></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{data.release.aired_on_date != 0 ? (
unixToDate(data.release.aired_on_date)
) : data.release.year ? (
<>
{data.release.season && data.release.season != 0
? `${YearSeason[data.release.season]} `
: ""}
{data.release.year && `${data.release.year} г.`}
</>
) : (
"Скоро"
)}
</Table.Cell>
</Table.Row>
)}
</Table.Body>
</Table>
</Card>
{token && (
<Card className="order-1 lg:order-2">
<div className="flex flex-wrap gap-2">
<Dropdown
label={lists[userList].name}
dismissOnClick={true}
theme={DropdownTheme}
>
{lists.map((list) => (
<Dropdown.Item
key={list.list}
onClick={() => _addToList(list.list)}
>
{list.name}
</Dropdown.Item>
))}
</Dropdown>
<Button
className="bg-blue-600 enabled:hover:bg-blue-700 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
onClick={() => {
_addToFavorite();
}}
>
<span
className={`iconify w-6 h-6 ${
userFavorite ? "mdi--heart" : "mdi--heart-outline"
}`}
></span>
</Button>
</div>
</Card>
)}
{data.release.related_releases.length > 0 && (
<Card className="order-3">
<div>
<div className="flex justify-between py-2 border-b-2 border-black">
<h1>Связанные релизы</h1>
{data.release.related && (
<Link href={`/related/${data.release.related.id}`}>
<div className="flex items-center">
<p className="hidden sm:block">Показать все</p>
<span className="w-6 h-6 iconify mdi--arrow-right"></span>
</div>
</Link>
)}
</div>
<div className="flex flex-col gap-1 mt-2">
{data.release.related_releases.map((release) => {
if (release.id == data.release.id) return null;
return <ReleaseLink key={release.id} {...release} />;
})}
</div>
</div>
</Card>
)}
</div>
</div>
</main>
) : (
<main className="flex h-[100dvh] w-full justify-center items-center">
<Spinner />
</main>
);
};
{
/* <Chip
bg_color={
data.release.grade.toFixed(1) == 0
? "hidden"
: data.release.grade.toFixed(1) < 2
? "bg-red-500"
: data.release.grade.toFixed(1) < 3
? "bg-orange-500"
: data.release.grade.toFixed(1) < 4
? "bg-yellow-500"
: "bg-green-500"
}
name={data.release.grade.toFixed(1)}
/> */
}