diff --git a/api-prox/index.ts b/api-prox/index.ts index 5603aa3..7bcd03c 100644 --- a/api-prox/index.ts +++ b/api-prox/index.ts @@ -18,7 +18,7 @@ app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", req.headers.origin || "*"); res.header( "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept, Sign" + "Origin, X-Requested-With, Content-Type, Accept, Sign, Allow, User-Agent, Api-Version" ); res.header("Access-Control-Allow-Methods", "GET,HEAD,POST,OPTIONS"); next(); diff --git a/api-prox/shared.ts b/api-prox/shared.ts index e50ed78..f241fd3 100644 --- a/api-prox/shared.ts +++ b/api-prox/shared.ts @@ -1,7 +1,7 @@ export const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": - "Origin, X-Requested-With, Content-Type, Accept, Sign", + "Origin, X-Requested-With, Content-Type, Accept, Sign, Allow, User-Agent, Api-Version", "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", "Cache-Control": "no-cache", }; diff --git a/app/api/config.ts b/app/api/config.ts index 853a361..9f3a2ba 100644 --- a/app/api/config.ts +++ b/app/api/config.ts @@ -1,4 +1,4 @@ -export const CURRENT_APP_VERSION = "3.7.0"; +export const CURRENT_APP_VERSION = "3.8.0"; import { env } from "next-runtime-env"; const NEXT_PUBLIC_API_URL = env("NEXT_PUBLIC_API_URL") || null; @@ -51,7 +51,14 @@ export const ENDPOINTS = { } }, filter: `${API_PREFIX}/filter`, - search: `${API_URL}/search`, + search: { + profileList: `${API_PREFIX}/search/profile/list`, + profileHistory: `${API_PREFIX}/search/history`, + profileFavoriteCollection: `${API_PREFIX}/search/favoriteCollections`, + profileFavorites: `${API_PREFIX}/search/favorites`, + profiles: `${API_PREFIX}/search/profiles`, + releases: `${API_PREFIX}/search/releases`, + }, statistic: { addHistory: `${API_PREFIX}/history/add`, markWatched: `${API_PREFIX}/episode/watch`, diff --git a/app/api/search/route.ts b/app/api/search/route.ts deleted file mode 100644 index d07dea9..0000000 --- a/app/api/search/route.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { NextResponse } from "next/server"; -import { NextRequest } from "next/server"; -import { fetchDataViaPost } from "../utils"; -import { ENDPOINTS } from "../config"; - -export async function GET(request: NextRequest) { - const page = parseInt(request.nextUrl.searchParams.get("page")) || 0; - const query = decodeURI(request.nextUrl.searchParams.get("q")) || null; - const token = request.nextUrl.searchParams.get("token") || null; - - const where = request.nextUrl.searchParams.get("where") || "releases"; - const searchBy = parseInt(request.nextUrl.searchParams.get("searchBy")) || 0; - const list = parseInt(request.nextUrl.searchParams.get("list")) || null; - - let url: URL; - - if (where == "list") { - if (!list) { - return NextResponse.json( - { message: "List ID required" }, - { status: 400 } - ); - } - if (!token) { - return NextResponse.json({ message: "token required" }, { status: 400 }); - } - url = new URL(`${ENDPOINTS.search}/profile/list/${list}/${page}`); - } else if (where == "history") { - if (!token) { - return NextResponse.json({ message: "token required" }, { status: 400 }); - } - url = new URL(`${ENDPOINTS.search}/history/${page}`); - } else if (where == "favorites") { - if (!token) { - return NextResponse.json({ message: "token required" }, { status: 400 }); - } - url = new URL(`${ENDPOINTS.search}/favorites/${page}`); - } else if (where == "collections") { - if (!token) { - return NextResponse.json({ message: "token required" }, { status: 400 }); - } - url = new URL(`${ENDPOINTS.search}/favoriteCollections/${page}`); - } else if (where == "profiles") { - url = new URL(`${ENDPOINTS.search}/profiles/${page}`); - } else { - url = new URL(`${ENDPOINTS.search}/releases/${page}`); - } - - if (token) { - url.searchParams.set("token", token); - } - const body = { query, searchBy }; - - const { data, error } = await fetchDataViaPost( - url.toString(), - JSON.stringify(body), - true - ); - if (error) { - return new Response(JSON.stringify(error), { - status: 500, - headers: { - "Content-Type": "application/json", - }, - }); - } - - return new Response(JSON.stringify(data), { - status: 200, - headers: { - "Content-Type": "application/json", - }, - }); -} diff --git a/app/bookmarks/page.tsx b/app/bookmarks/page.tsx index 56a5985..eaf51fa 100644 --- a/app/bookmarks/page.tsx +++ b/app/bookmarks/page.tsx @@ -2,6 +2,8 @@ export const metadata = { title: "Закладки", }; +export const dynamic = "force-static"; + import { BookmarksPage } from "#/pages/Bookmarks"; export default function Index() { return ; diff --git a/app/collection/[id]/page.tsx b/app/collection/[id]/page.tsx index f70d285..976efb8 100644 --- a/app/collection/[id]/page.tsx +++ b/app/collection/[id]/page.tsx @@ -1,7 +1,7 @@ import { ViewCollectionPage } from "#/pages/ViewCollection"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/collection/${id}` + `${API_URL}/collection/${id}` ); const previousOG = (await parent).openGraph; diff --git a/app/collections/create/page.tsx b/app/collections/create/page.tsx index 67b95bf..796b6cd 100644 --- a/app/collections/create/page.tsx +++ b/app/collections/create/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: "Создание новой коллекции", }; +export const dynamic = "force-static"; + export default function Collections() { return ; } diff --git a/app/collections/favorites/page.tsx b/app/collections/favorites/page.tsx index 628070e..0a0496b 100644 --- a/app/collections/favorites/page.tsx +++ b/app/collections/favorites/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: "Просмотр избранных коллекций", }; +export const dynamic = "force-static"; + export default function Collections() { return ; } diff --git a/app/collections/page.tsx b/app/collections/page.tsx index cd68b69..10ba0ab 100644 --- a/app/collections/page.tsx +++ b/app/collections/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: "Просмотр и управление коллекциями", } +export const dynamic = "force-static"; + export default function Collections() { return ; } diff --git a/app/components/RelatedSection/RelatedSection.tsx b/app/components/RelatedSection/RelatedSection.tsx index 1ed7c43..368793d 100644 --- a/app/components/RelatedSection/RelatedSection.tsx +++ b/app/components/RelatedSection/RelatedSection.tsx @@ -15,7 +15,7 @@ export const RelatedSection = (props: any) => {
{props.images.map((item, index) => { return ( -
+
; } diff --git a/app/history/page.tsx b/app/history/page.tsx index 2815aa3..21bac4b 100644 --- a/app/history/page.tsx +++ b/app/history/page.tsx @@ -4,6 +4,8 @@ export const metadata = { import { HistoryPage } from "#/pages/History"; +export const dynamic = "force-static"; + export default function Index() { return ; } diff --git a/app/login/page.tsx b/app/login/page.tsx index dae1809..cca130c 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: "Вход в аккаунт anixart", } +export const dynamic = "force-static"; + export default function Login() { return ; } diff --git a/app/menu/page.tsx b/app/menu/page.tsx index 1350fbc..61305cc 100644 --- a/app/menu/page.tsx +++ b/app/menu/page.tsx @@ -4,6 +4,8 @@ export const metadata = { import { MenuPage } from "#/pages/MobileMenuPage"; +export const dynamic = "force-static"; + export default function Index() { return ; } diff --git a/app/page.tsx b/app/page.tsx index b54ae5b..6731436 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,5 +1,7 @@ import { IndexPage } from "./pages/Index"; +export const dynamic = "force-static"; + export default function Index() { return ; } diff --git a/app/pages/Search.tsx b/app/pages/Search.tsx index bba699e..b06d000 100644 --- a/app/pages/Search.tsx +++ b/app/pages/Search.tsx @@ -1,138 +1,258 @@ "use client"; -import useSWRInfinite from "swr/infinite"; -import { ReleaseSection } from "#/components/ReleaseSection/ReleaseSection"; -import { RelatedSection } from "#/components/RelatedSection/RelatedSection"; -import { Spinner } from "#/components/Spinner/Spinner"; + import { useState, useEffect } from "react"; -import { useScrollPosition } from "#/hooks/useScrollPosition"; -import { useRouter } from "next/navigation"; import { useSearchParams } from "next/navigation"; -import { useUserStore } from "../store/auth"; -import { Button, Dropdown, DropdownItem, Modal, ModalBody, ModalFooter, ModalHeader } from "flowbite-react"; -import { CollectionsSection } from "#/components/CollectionsSection/CollectionsSection"; +import { useRouter } from "next/navigation"; + +import { Dropdown, DropdownItem } from "flowbite-react"; +import { useUserStore } from "#/store/auth"; +import { ENDPOINTS } from "#/api/config"; +import { tryCatchAPI } from "#/api/utils"; +import useSWRInfinite from "swr/infinite"; +import { Spinner } from "#/components/Spinner/Spinner"; +import { ReleaseSection } from "#/components/ReleaseSection/ReleaseSection"; import { UserSection } from "#/components/UserSection/UserSection"; -import { useSWRfetcher } from "#/api/utils"; +import { CollectionsSection } from "#/components/CollectionsSection/CollectionsSection"; +import { useScrollPosition } from "#/hooks/useScrollPosition"; +import { RelatedSection } from "#/components/RelatedSection/RelatedSection"; -const ListsMapping = { - watching: { - name: "Смотрю", - id: 1, - }, - planned: { - name: "В планах", - id: 2, - }, - watched: { - name: "Просмотрено", - id: 3, - }, - delayed: { - name: "Отложено", - id: 4, - }, - abandoned: { - name: "Заброшено", - id: 5, - }, +const postFetcher = async (url: string, payload: string) => { + const { data, error } = await tryCatchAPI( + fetch(url, { + method: "POST", + headers: { + "Api-Version": "v2", + "Content-Type": "application/json", + }, + body: payload, + }) + ); + + if (error) { + throw error; + } + return data; }; -const TagMapping = { - name: { - name: "Названию", - id: 0, +const whereMapping = [ + { + id: "releases", + label: "Релизах", + auth: false, }, - studio: { - name: "Студии", - id: 1, + { + id: "profiles", + label: "Профилях", + auth: false, }, - director: { - name: "Режиссёру", - id: 2, + { + id: "list", + label: "Списках", + auth: true, }, - author: { - name: "Автору", - id: 3, + { + id: "history", + label: "Истории", + auth: true, }, - tag: { - name: "Тегу", - id: 4, + { + id: "favorites", + label: "Избранном", + auth: true, }, -}; + { + id: "collections", + label: "Коллекциях", + auth: true, + }, +]; -const WhereMapping = { - releases: "Релизах", - list: "Списках", - history: "Истории", - favorites: "Избранном", - collections: "Коллекциях", - profiles: "Профилях", +const searchByMapping = { + releases: [ + { + id: "name", + label: "Названию", + value: 0, + }, + { + id: "studio", + label: "Студии", + value: 1, + }, + { + id: "director", + label: "Режиссёру", + value: 2, + }, + { + id: "author", + label: "Автору", + value: 3, + }, + { + id: "tag", + label: "Тегу", + value: 4, + }, + ], + list: [ + { + id: "watching", + label: "Смотрю", + value: 1, + }, + { + id: "planned", + label: "В планах", + value: 2, + }, + { + id: "watched", + label: "Просмотрено", + value: 3, + }, + { + id: "delayed", + label: "Отложено", + value: 4, + }, + { + id: "abandoned", + label: "Заброшено", + value: 5, + }, + ], + none: [{ id: "none", label: "Нет", value: 0 }], }; export function SearchPage() { const router = useRouter(); const searchParams = useSearchParams(); - const [query, setQuery] = useState(searchParams.get("q") || ""); - const [searchVal, setSearchVal] = useState(searchParams.get("q") || ""); - const [where, setWhere] = useState(searchParams.get("where") || "releases"); - const [searchBy, setSearchBy] = useState( - searchParams.get("searchBy") || "name" - ); - const [list, setList] = useState(searchParams.get("list") || "watching"); - const [filtersModalOpen, setFiltersModalOpen] = useState(false); - const userStore = useUserStore(); + const [query, setQuery] = useState(searchParams.get("query") || ""); + const [params, setParams] = useState(null); + const [content, setContent] = useState(null); + + const [HeaderH, setHeaderH] = useState(null); + + useEffect(() => { + const queryParams = searchParams.get("params"); + + if (queryParams) { + try { + setParams(JSON.parse(queryParams)); + } catch (e) { + setParams({ + where: "releases", + searchBy: "name", + }); + } + } else { + setParams({ + where: "releases", + searchBy: "name", + }); + } + + if (window) { + setHeaderH(document.querySelector("header").clientHeight); + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (!params) return; + + const url = new URL(`/search`, window.location.origin); + url.searchParams.set("query", query); + url.searchParams.set("params", JSON.stringify(params)); + router.replace(url.toString()); + setContent(null); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [params]); + + useEffect(() => { + setContent(null); + + const url = new URL(`/search`, window.location.origin); + url.searchParams.set("query", query); + url.searchParams.set("params", JSON.stringify(params)); + router.replace(url.toString()); + }, [query]); const getKey = (pageIndex: number, previousPageData: any) => { - if (where == "releases") { - if (previousPageData && !previousPageData.releases.length) return null; - } else { - if (previousPageData && !previousPageData.content.length) return null; + if (!params) return null; + if (!query) return null; + + if (previousPageData) { + if (params.where == "releases") { + if (!previousPageData.releases.length) return null; + } else { + if (!previousPageData.content.length) return null; + } } - const url = new URL("/api/search", window.location.origin); - url.searchParams.set("page", pageIndex.toString()); + let url = null; + switch (params.where) { + case "releases": + url = `${ENDPOINTS.search.releases}/${pageIndex}`; + break; + case "profiles": + url = `${ENDPOINTS.search.profiles}/${pageIndex}`; + break; + case "list": + const list = searchByMapping[params.where].find( + (item) => item.id == params.searchBy + ); + if (!list) break; + url = `${ENDPOINTS.search.profileList}/${list.value}/${pageIndex}`; + break; + case "history": + url = `${ENDPOINTS.search.profileHistory}/${pageIndex}`; + break; + case "favorites": + url = `${ENDPOINTS.search.profileFavorites}/${pageIndex}`; + break; + case "collections": + url = `${ENDPOINTS.search.profileFavoriteCollection}/${pageIndex}`; + break; + } if (userStore.token) { - url.searchParams.set("token", userStore.token); + url += `?token=${userStore.token}`; } - if (where) { - url.searchParams.set("where", where); + let searchBy = null; + const _sbym = searchByMapping[params.where]; + if (_sbym) { + searchBy = _sbym.find((item) => item.id == params.searchBy).value; + } else { + searchBy = searchByMapping["none"][0].value; } - if (where == "list" && list && ListsMapping.hasOwnProperty(list)) { - url.searchParams.set("list", ListsMapping[list].id); - } - - url.searchParams.set("searchBy", TagMapping[searchBy].id); - - if (query) { - url.searchParams.set("q", query); - return url.toString(); - } - return; + return [url, JSON.stringify({ query, searchBy })]; }; - const { data, error, isLoading, size, setSize } = useSWRInfinite( + const { data, error, isLoading, size, setSize, mutate } = useSWRInfinite( getKey, - useSWRfetcher, - { initialSize: 2, revalidateFirstPage: false } + ([url, payload]) => postFetcher(url, payload), + { initialSize: 2 } ); - const [content, setContent] = useState(null); useEffect(() => { if (data) { - let allReleases = []; - if (where == "releases") { + let _content = []; + if (params.where == "releases") { for (let i = 0; i < data.length; i++) { - allReleases.push(...data[i].releases); + _content.push(...data[i].releases); } } else { for (let i = 0; i < data.length; i++) { - allReleases.push(...data[i].content); + _content.push(...data[i].content); } } - setContent(allReleases); + setContent(_content); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [data]); @@ -145,52 +265,22 @@ export function SearchPage() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [scrollPosition]); - function _executeSearch(value: string) { - const Params = new URLSearchParams(window.location.search); - Params.set("q", value); - const url = new URL(`/search?${Params.toString()}`, window.location.origin); - setContent(null); - setQuery(value); - router.push(url.toString()); - } - - useEffect(() => { - if (searchVal && searchVal.length % 4 == 1) { - _executeSearch(searchVal.trim()); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchVal]); - - if (error) - return ( -
-
-

Ошибка

-

- Произошла ошибка поиска. Попробуйте обновить страницу или зайдите - позже. -

-
-
- ); + if (!params) return <>; return ( - <> -
-
{ - e.preventDefault(); - _executeSearch(searchVal.trim()); - }} - > +
+
+
-
+
setSearchVal(e.target.value)} + value={query} + onChange={(e) => setQuery(e.target.value)} /> -
- - +
+
+ item.id == params.where).label}`} + color="light" + className="w-full lg:w-fit" + > + {whereMapping.map((item) => { + return item.auth && !userStore.isAuth ? + <> + : + searchByMapping[item.id] ? + setParams({ + where: item.id, + searchBy: searchByMapping[item.id][0].id, + }) + : setParams({ where: item.id, searchBy: "none" }) + } + key={`filter--where--${item.id}`} + > + {item.label} + ; + })} + +
+ {searchByMapping[params.where] ? +
+ item.id == params.searchBy + ).label + }`} + color="light" + className="w-full lg:w-fit" + > + {searchByMapping[params.where].map((item) => { + return ( + + setParams({ + where: params.where, + searchBy: item.id, + }) + } + key={`filter--where--${params.where}--searchBy--${item.id}`} + > + {item.label} + + ); + })} + +
+ : <>} +
+
-
+ +
+ {error ? +
+
+

Произошла ошибка поиска

+
+
+ : <>} + {data && data[0].related && } {content ? content.length > 0 ? - <> - {where == "collections" ? - - : where == "profiles" ? - - : - } - + params.where == "profiles" ? + + : params.where == "collections" ? + + : :

Странно, аниме не найдено, попробуйте другой запрос...

- : isLoading && ( -
- -
- ) - } + + : <>} + {!content && !isLoading && !query && (

Введите ваш запрос что-бы найти любимый тайтл

)} -
- {( - data && - data.length > 1 && - (where == "releases" ? - data[data.length - 1].releases.length == 25 - : data[data.length - 1].content.length == 25) - ) ? - - : ""} - - + : ""} +
+
); } - -const FiltersModal = (props: { - isOpen: boolean; - setIsOpen: any; - where: string; - setWhere: any; - list: string; - setList: any; - isAuth: boolean; - searchBy: string; - setSearchBy: any; - setContent: any; -}) => { - const router = useRouter(); - const [where, setWhere] = useState(props.where); - const [list, setList] = useState(props.list); - const [searchBy, setSearchBy] = useState(props.searchBy); - - function _cancel() { - setWhere(props.where); - setList(props.list); - setSearchBy(props.searchBy); - props.setIsOpen(false); - } - - function _accept() { - const Params = new URLSearchParams(window.location.search); - - if (props.where != where) { - Params.set("where", where); - props.setWhere(where); - } - - if (where == "list") { - Params.set("list", list); - props.setList(list); - } else { - Params.delete("list"); - } - - if (!["profiles", "collections"].includes(where)) { - Params.set("searchBy", searchBy); - props.setSearchBy(searchBy); - } else { - Params.delete("searchBy"); - props.setSearchBy("name"); - } - - props.setContent(null); - - const url = new URL(`/search?${Params.toString()}`, window.location.origin); - router.push(url.toString()); - } - - return ( - _cancel()}> - Фильтры - -
-
-

Искать в

- - {Object.keys(WhereMapping).map((item) => { - if ( - ["list", "history", "collections", "favorites"].includes( - item - ) && - !props.isAuth - ) { - return <>; - } else { - return ( - setWhere(item)} - key={`where--${item}`} - > - {WhereMapping[item]} - - ); - } - })} - -
-
- {props.isAuth && where == "list" && ListsMapping.hasOwnProperty(list) ? -
-
-

Список

- - {Object.keys(ListsMapping).map((item) => { - return ( - setList(item)} - key={`list--${item}`} - > - {ListsMapping[item].name} - - ); - })} - -
-
- : ""} - {!["profiles", "collections"].includes(where) ? -
-
-

Искать по

- - {Object.keys(TagMapping).map((item) => { - return ( - setSearchBy(item)} - key={`tag--${item}`} - > - {TagMapping[item].name} - - ); - })} - -
-
- : ""} -
- -
- - -
-
-
- ); -}; diff --git a/app/profile/[id]/bookmarks/[slug]/page.tsx b/app/profile/[id]/bookmarks/[slug]/page.tsx index a3fb3e1..525159e 100644 --- a/app/profile/[id]/bookmarks/[slug]/page.tsx +++ b/app/profile/[id]/bookmarks/[slug]/page.tsx @@ -1,7 +1,7 @@ import { BookmarksCategoryPage } from "#/pages/BookmarksCategory"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = 'force-static'; +import { API_URL } from "#/api/config"; const SectionTitleMapping = { watching: "Смотрю", @@ -17,7 +17,7 @@ export async function generateMetadata( ): Promise { const id: string = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/profile/${id}` + `${API_URL}/profile/${id}` ); const previousOG = (await parent).openGraph; diff --git a/app/profile/[id]/bookmarks/page.tsx b/app/profile/[id]/bookmarks/page.tsx index afd66f5..fc2848d 100644 --- a/app/profile/[id]/bookmarks/page.tsx +++ b/app/profile/[id]/bookmarks/page.tsx @@ -1,7 +1,7 @@ import { BookmarksPage } from "#/pages/Bookmarks"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id: string = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/profile/${id}` + `${API_URL}/profile/${id}` ); const previousOG = (await parent).openGraph; diff --git a/app/profile/[id]/collections/page.tsx b/app/profile/[id]/collections/page.tsx index ce018fd..2fb0bf3 100644 --- a/app/profile/[id]/collections/page.tsx +++ b/app/profile/[id]/collections/page.tsx @@ -1,7 +1,7 @@ import { CollectionsFullPage } from "#/pages/CollectionsFull"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id: string = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/profile/${id}` + `${API_URL}/profile/${id}` ); const previousOG = (await parent).openGraph; @@ -38,7 +38,7 @@ export async function generateMetadata( export default async function Collections({ params }) { const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/profile/${params.id}` + `${API_URL}/profile/${params.id}` ); if (error) { diff --git a/app/profile/[id]/page.tsx b/app/profile/[id]/page.tsx index 0c28386..12424a1 100644 --- a/app/profile/[id]/page.tsx +++ b/app/profile/[id]/page.tsx @@ -1,7 +1,7 @@ import { ProfilePage } from "#/pages/Profile"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id: string = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/profile/${id}` + `${API_URL}/profile/${id}` ); const previousOG = (await parent).openGraph; diff --git a/app/related/[id]/page.tsx b/app/related/[id]/page.tsx index 3ce2b33..61bc966 100644 --- a/app/related/[id]/page.tsx +++ b/app/related/[id]/page.tsx @@ -1,7 +1,7 @@ import { RelatedPage } from "#/pages/Related"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = 'force-static'; +import { API_URL } from "#/api/config"; const _getData = async (url: string) => { const { data, error } = await fetchDataViaGet(url); @@ -12,7 +12,7 @@ export async function generateMetadata({ params }, parent: ResolvingMetadata): P const id:string = params.id; const previousOG = (await parent).openGraph; - const [ related, relatedError ] = await _getData(`https://api.anixart.tv/related/${id}/0`); + const [ related, relatedError ] = await _getData(`${API_URL}/related/${id}/0`); if (relatedError || related.content.length == 0) { return { title: "Ошибка", @@ -20,7 +20,7 @@ export async function generateMetadata({ params }, parent: ResolvingMetadata): P }; }; - const [ firstRelease, firstReleaseError ] = await _getData(`https://api.anixart.tv/release/${related.content[0].id}`); + const [ firstRelease, firstReleaseError ] = await _getData(`${API_URL}/release/${related.content[0].id}`); if (firstReleaseError) { return { title: "Ошибка", @@ -46,7 +46,7 @@ export async function generateMetadata({ params }, parent: ResolvingMetadata): P export default async function Related({ params }) { const id: string = params.id; - const [ related, relatedError ] = await _getData(`https://api.anixart.tv/related/${id}/0`); + const [ related, relatedError ] = await _getData(`${API_URL}/related/${id}/0`); if (relatedError || related.content.length == 0) { return
@@ -56,7 +56,7 @@ export default async function Related({ params }) {
}; - const [ firstRelease, firstReleaseError ] = await _getData(`https://api.anixart.tv/release/${related.content[0].id}`); + const [ firstRelease, firstReleaseError ] = await _getData(`${API_URL}/release/${related.content[0].id}`); if (firstReleaseError) { return
diff --git a/app/release/[id]/collections/page.tsx b/app/release/[id]/collections/page.tsx index b9dcded..28f1892 100644 --- a/app/release/[id]/collections/page.tsx +++ b/app/release/[id]/collections/page.tsx @@ -1,7 +1,7 @@ import { CollectionsFullPage } from "#/pages/CollectionsFull"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/release/${id}` + `${API_URL}/release/${id}` ); const previousOG = (await parent).openGraph; @@ -38,7 +38,7 @@ export async function generateMetadata( export default async function Collections({ params }) { const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/release/${params.id}` + `${API_URL}/release/${params.id}` ); if (error) { diff --git a/app/release/[id]/page.tsx b/app/release/[id]/page.tsx index ba70944..d11f353 100644 --- a/app/release/[id]/page.tsx +++ b/app/release/[id]/page.tsx @@ -1,7 +1,7 @@ import { ReleasePage } from "#/pages/Release"; import { fetchDataViaGet } from "#/api/utils"; import type { Metadata, ResolvingMetadata } from "next"; -export const dynamic = "force-static"; +import { API_URL } from "#/api/config"; export async function generateMetadata( { params }, @@ -9,7 +9,7 @@ export async function generateMetadata( ): Promise { const id = params.id; const { data, error } = await fetchDataViaGet( - `https://api.anixart.tv/release/${id}` + `${API_URL}/release/${id}` ); const previousOG = (await parent).openGraph; diff --git a/app/search/page.tsx b/app/search/page.tsx index 13b9981..3e70827 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: "Поиск аниме релизов", }; +export const dynamic = "force-static"; + export default function Search() { return ; } diff --git a/package.json b/package.json index ec1be21..10c8582 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "next dev", + "dev-with-services": "node ./run-all.dev.js", "build": "next build", "start": "next start", "lint": "next lint", diff --git a/player-parser/index.ts b/player-parser/index.ts index 9f3cf5f..f98aab4 100644 --- a/player-parser/index.ts +++ b/player-parser/index.ts @@ -9,7 +9,7 @@ app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", req.headers.origin || "*"); res.header( "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept" + "Origin, X-Requested-With, Content-Type, Accept, Allow, User-Agent" ); res.header("Access-Control-Allow-Methods", "GET,HEAD,POST,OPTIONS"); next(); diff --git a/player-parser/shared.ts b/player-parser/shared.ts index b03c5eb..a5e1a0a 100644 --- a/player-parser/shared.ts +++ b/player-parser/shared.ts @@ -1,6 +1,6 @@ export const corsHeaders = { "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept", + "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Allow, User-Agent", "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", "Cache-Control": "no-cache", }; diff --git a/public/changelog/3.8.0.md b/public/changelog/3.8.0.md new file mode 100644 index 0000000..a2c50b9 --- /dev/null +++ b/public/changelog/3.8.0.md @@ -0,0 +1,8 @@ +# 3.8.0 + +## Изменено + +- Фильтры на странице поиска были перемещены рядом с полем ввода +- ТЕХ: механизм запросов поиска стал работать так-же как и остальные запросы +- Динамическая метадата (пред просмотра) снова включена +- ТЕХ: генераторы метадаты (пред просмотра) используют ссылку API (API_URL) с конфига \ No newline at end of file diff --git a/run-all.dev.js b/run-all.dev.js new file mode 100644 index 0000000..13fbc9b --- /dev/null +++ b/run-all.dev.js @@ -0,0 +1,29 @@ +const { spawn } = require("child_process"); + +const npm = /^win/.test(process.platform) ? "npm.cmd" : "npm"; + +const client = spawn(npm, ["run", "dev"], { shell: true }); +const parser = spawn(npm, ["run", "serve"], { shell: true, cwd: "./player-parser" }); +const proxy = spawn(npm, ["run", "serve"], { shell: true, cwd: "./api-prox" }); + +const clientInfo = "\x1b[36m[client]\x1b[0m"; +const parserInfo = "\x1b[33m[parser]\x1b[0m"; +const proxyInfo = "\x1b[31m[proxy]\x1b[0m"; + +console.log(`${clientInfo} CMD: ${client.spawnargs.toString()}`); +console.log(`${clientInfo} PID: ${client.pid}`); +console.log(`${parserInfo} CMD: ${parser.spawnargs.toString()}`); +console.log(`${parserInfo} PID: ${parser.pid}`); +console.log(`${proxyInfo} CMD: ${proxy.spawnargs.toString()}`); +console.log(`${proxyInfo} PID: ${proxy.pid}`); +console.log(`\n`); + +client.stdout.on("data", (data) => + console.log(clientInfo, data.toString()) +); +parser.stdout.on("data", (data) => + console.log(parserInfo, data.toString()) +); +proxy.stdout.on("data", (data) => + console.log(proxyInfo, data.toString()) +);