mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-27 08:29:40 +05:00
Compare commits
No commits in common. "8ab668dcd6757c76845152f5aec083a15cad961b" and "07c93338cb733074cf2cd25c139fe18603b2e637" have entirely different histories.
8ab668dcd6
...
07c93338cb
12 changed files with 113 additions and 334 deletions
README.md
app
about
api
components
Navbar
ReleasePlayer
ReleasePoster
SettingsModal
pages
store
docs
public/changelog
|
@ -6,10 +6,10 @@ AniX is an unofficial web client for the Android application Anixart. It allows
|
||||||
|
|
||||||
## Changelog [RU]
|
## Changelog [RU]
|
||||||
|
|
||||||
- [3.5.0](./public/changelog/3.5.0.md)
|
|
||||||
- [3.4.0](./public/changelog/3.4.0.md)
|
- [3.4.0](./public/changelog/3.4.0.md)
|
||||||
- [3.3.0](./public/changelog/3.3.0.md)
|
- [3.3.0](./public/changelog/3.3.0.md)
|
||||||
- [3.2.3](./public/changelog/3.2.3.md)
|
- [3.2.3](./public/changelog/3.2.3.md)
|
||||||
|
- [3.2.2](./public/changelog/3.2.2.md)
|
||||||
|
|
||||||
[other versions](./public/changelog)
|
[other versions](./public/changelog)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
export const metadata = {
|
|
||||||
title: "О приложении",
|
|
||||||
openGraph: {
|
|
||||||
title: "AniX - Неофициальный веб клиент для Anixart",
|
|
||||||
description:
|
|
||||||
"AniX - это неофициальный веб-клиент для Android-приложения Anixart. Он позволяет вам получать доступ к своей учетной записи Anixart и управлять ею из веб-браузера. Так-же можно синхронизировать и управлять списками и избранным. И самое главное смотреть все доступные аниме из базы Anixart.",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const dynamic = "force-static";
|
|
||||||
|
|
||||||
import { AboutPage } from "#/pages/About";
|
|
||||||
|
|
||||||
export default function Index() {
|
|
||||||
return <AboutPage />;
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const CURRENT_APP_VERSION = "3.5.0";
|
export const CURRENT_APP_VERSION = "3.4.0";
|
||||||
|
|
||||||
export const API_URL = "https://api.anixart.tv";
|
export const API_URL = "https://api.anixart.tv";
|
||||||
export const API_PREFIX = "/api/proxy";
|
export const API_PREFIX = "/api/proxy";
|
||||||
|
|
|
@ -87,8 +87,8 @@ export const Navbar = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<header className="fixed bottom-0 left-0 z-50 w-full text-white bg-black rounded-t-lg sm:sticky sm:top-0 sm:rounded-t-none sm:rounded-b-lg">
|
<header className="fixed bottom-0 left-0 z-50 w-full text-white bg-black rounded-t-lg sm:sticky sm:top-0 sm:rounded-t-none sm:rounded-b-lg">
|
||||||
<div className={`container flex items-center min-h-[76px] justify-center ${preferenceStore.flags.showFifthButton && preferenceStore.flags.showNavbarTitles == "always" ? "gap-0" : "gap-4"} mx-auto sm:gap-0 sm:justify-between`}>
|
<div className="container flex items-center justify-center gap-4 mx-auto sm:gap-0 sm:justify-between">
|
||||||
<div className={`flex items-center ${preferenceStore.flags.showFifthButton && preferenceStore.flags.showNavbarTitles == "always" ? "gap-4" : "gap-8"} px-2 py-4 sm:gap-4`}>
|
<div className="flex items-center gap-8 px-2 py-4 sm:gap-4">
|
||||||
{menuItems.map((item) => {
|
{menuItems.map((item) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
|
@ -98,7 +98,7 @@ export const Navbar = () => {
|
||||||
item.isAuthRequired && !userStore.isAuth ? "hidden"
|
item.isAuthRequired && !userStore.isAuth ? "hidden"
|
||||||
: item.isShownOnMobile ? "flex"
|
: item.isShownOnMobile ? "flex"
|
||||||
: "hidden sm:flex"
|
: "hidden sm:flex"
|
||||||
} ${[item.href, item.hrefInCategory].includes("/" + pathname.split("/")[1]) ? "font-bold" : "font-medium"} transition-all`}
|
} ${[item.href, item.hrefInCategory].includes("/" + pathname.split("/")[1]) ? "font-bold" : "font-medium"}`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`w-6 h-6 iconify ${[item.href, item.hrefInCategory].includes("/" + pathname.split("/")[1]) ? item.icon.active : item.icon.default}`}
|
className={`w-6 h-6 iconify ${[item.href, item.hrefInCategory].includes("/" + pathname.split("/")[1]) ? item.icon.active : item.icon.default}`}
|
||||||
|
@ -112,13 +112,13 @@ export const Navbar = () => {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className={`flex items-center ${preferenceStore.flags.showFifthButton && preferenceStore.flags.showNavbarTitles == "always" ? "gap-4" : "gap-8"} px-2 py-4 sm:gap-4`}>
|
<div className="flex items-center gap-8 px-2 py-4 sm:gap-4">
|
||||||
{!userStore.isAuth ?
|
{!userStore.isAuth ?
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
pathname != "/login" ? `/login?redirect=${pathname}` : "#"
|
pathname != "/login" ? `/login?redirect=${pathname}` : "#"
|
||||||
}
|
}
|
||||||
className={`flex items-center flex-col lg:flex-row gap-1 ${pathname == "/login" ? "font-bold" : "font-medium"} transition-all`}
|
className={`flex items-center flex-col lg:flex-row gap-1 ${pathname == "/login" ? "font-bold" : "font-medium"}`}
|
||||||
>
|
>
|
||||||
<span className="w-6 h-6 iconify material-symbols--login"></span>
|
<span className="w-6 h-6 iconify material-symbols--login"></span>
|
||||||
<span
|
<span
|
||||||
|
@ -130,7 +130,7 @@ export const Navbar = () => {
|
||||||
: <>
|
: <>
|
||||||
<Link
|
<Link
|
||||||
href={`/profile/${userStore.user.id}`}
|
href={`/profile/${userStore.user.id}`}
|
||||||
className={`hidden lg:flex flex-col lg:flex-row items-center gap-1 ${pathname == `/profile/${userStore.user.id}` ? "font-bold" : "font-medium"} transition-all`}
|
className={`hidden lg:flex flex-col lg:flex-row items-center gap-1 ${pathname == `/profile/${userStore.user.id}` ? "font-bold" : "font-medium"}`}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={userStore.user.avatar}
|
src={userStore.user.avatar}
|
||||||
|
@ -139,30 +139,13 @@ export const Navbar = () => {
|
||||||
width={24}
|
width={24}
|
||||||
height={24}
|
height={24}
|
||||||
/>
|
/>
|
||||||
<span
|
<span className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" || preferenceStore.flags.showNavbarTitles == "links" || (preferenceStore.flags.showNavbarTitles == "selected" && pathname == `/profile/${userStore.user.id}`) ? "block" : "hidden"}`}>
|
||||||
className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" || preferenceStore.flags.showNavbarTitles == "links" || (preferenceStore.flags.showNavbarTitles == "selected" && pathname == `/profile/${userStore.user.id}`) ? "block" : "hidden"}`}
|
|
||||||
>
|
|
||||||
{userStore.user.login}
|
{userStore.user.login}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
{preferenceStore.flags.showFifthButton ?
|
|
||||||
<Link
|
|
||||||
href={menuItems[preferenceStore.flags.showFifthButton].href}
|
|
||||||
className={`flex flex-col sm:hidden items-center gap-1 ${pathname == menuItems[preferenceStore.flags.showFifthButton].href ? "font-bold" : "font-medium"} transition-all`}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={`w-6 h-6 iconify ${pathname == menuItems[preferenceStore.flags.showFifthButton].href ? menuItems[preferenceStore.flags.showFifthButton].icon.active : menuItems[preferenceStore.flags.showFifthButton].icon.default}`}
|
|
||||||
></span>
|
|
||||||
<span
|
|
||||||
className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" || preferenceStore.flags.showNavbarTitles == "links" || (preferenceStore.flags.showNavbarTitles == "selected" && pathname == menuItems[preferenceStore.flags.showFifthButton].href) ? "block" : "hidden"}`}
|
|
||||||
>
|
|
||||||
{menuItems[preferenceStore.flags.showFifthButton].title}
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
: ""}
|
|
||||||
<Link
|
<Link
|
||||||
href={`/menu`}
|
href={`/menu`}
|
||||||
className={`flex flex-col lg:hidden items-center gap-1 ${pathname == `/menu` || pathname == `/profile/${userStore.user.id}` ? "font-bold" : "font-medium"} transition-all`}
|
className={`flex flex-col lg:hidden items-center gap-1 ${pathname == `/menu` || pathname == `/profile/${userStore.user.id}` ? "font-bold" : "font-medium"}`}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={userStore.user.avatar}
|
src={userStore.user.avatar}
|
||||||
|
@ -171,9 +154,7 @@ export const Navbar = () => {
|
||||||
width={24}
|
width={24}
|
||||||
height={24}
|
height={24}
|
||||||
/>
|
/>
|
||||||
<span
|
<span className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" || preferenceStore.flags.showNavbarTitles == "links" || (preferenceStore.flags.showNavbarTitles == "selected" && (pathname == `/menu` || pathname == `/profile/${userStore.user.id}`)) ? "block" : "hidden"}`}>
|
||||||
className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" || preferenceStore.flags.showNavbarTitles == "links" || (preferenceStore.flags.showNavbarTitles == "selected" && (pathname == `/menu` || pathname == `/profile/${userStore.user.id}`)) ? "block" : "hidden"}`}
|
|
||||||
>
|
|
||||||
{userStore.user.login}
|
{userStore.user.login}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -184,11 +165,7 @@ export const Navbar = () => {
|
||||||
onClick={() => setIsSettingModalOpen(true)}
|
onClick={() => setIsSettingModalOpen(true)}
|
||||||
>
|
>
|
||||||
<span className="w-6 h-6 iconify material-symbols--settings-outline-rounded"></span>
|
<span className="w-6 h-6 iconify material-symbols--settings-outline-rounded"></span>
|
||||||
<span
|
<span className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" ? "block" : "hidden"}`}>Настройки</span>
|
||||||
className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" ? "block" : "hidden"}`}
|
|
||||||
>
|
|
||||||
Настройки
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
{userStore.isAuth && (
|
{userStore.isAuth && (
|
||||||
<button
|
<button
|
||||||
|
@ -196,9 +173,7 @@ export const Navbar = () => {
|
||||||
onClick={() => userStore.logout()}
|
onClick={() => userStore.logout()}
|
||||||
>
|
>
|
||||||
<span className="w-6 h-6 iconify material-symbols--logout"></span>
|
<span className="w-6 h-6 iconify material-symbols--logout"></span>
|
||||||
<span
|
<span className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" ? "lg:hidden xl:block" : "hidden"}`}>
|
||||||
className={`text-xs sm:text-base ${preferenceStore.flags.showNavbarTitles == "always" ? "lg:hidden xl:block" : "hidden"}`}
|
|
||||||
>
|
|
||||||
Выйти
|
Выйти
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -342,8 +342,6 @@ export const ReleasePlayerCustom = (props: {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
if (episode.selected) {
|
if (episode.selected) {
|
||||||
setIsLoading(true);
|
|
||||||
setPlayerError(null);
|
|
||||||
__getInfo();
|
__getInfo();
|
||||||
}
|
}
|
||||||
}, [episode.selected]);
|
}, [episode.selected]);
|
||||||
|
|
|
@ -83,7 +83,7 @@ export const PosterWithStuff = (props: {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={`release_${props.id}_genre_${genre}_${index}`}
|
key={`release_${props.id}_genre_${genre}_${index}`}
|
||||||
className="font-light leading-none text-white md:text-sm lg:text-base xl:text-lg"
|
className="font-light text-white md:text-sm lg:text-base xl:text-lg"
|
||||||
>
|
>
|
||||||
{index > 0 && ", "}
|
{index > 0 && ", "}
|
||||||
{genre}
|
{genre}
|
||||||
|
@ -91,18 +91,18 @@ export const PosterWithStuff = (props: {
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{props.title_ru && (
|
{props.title_ru && (
|
||||||
<p className="py-1 text-xl font-bold leading-none text-white md:text-2xl md:py-0">
|
<p className="text-xl font-bold text-white md:text-2xl">
|
||||||
{props.title_ru}
|
{props.title_ru}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{props.title_original && (
|
{props.title_original && (
|
||||||
<p className="text-sm leading-none text-gray-300 md:text-base">
|
<p className="text-sm text-gray-300 md:text-base">
|
||||||
{props.title_original}
|
{props.title_original}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{settings.showDescription && props.description && (
|
{settings.showDescription && props.description && (
|
||||||
<p className="mt-2 text-sm font-light leading-none text-white lg:text-base xl:text-lg line-clamp-4">
|
<p className="mt-2 text-sm font-light text-white lg:text-base xl:text-lg line-clamp-4">
|
||||||
{props.description}
|
{props.description}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { CURRENT_APP_VERSION } from "#/api/config";
|
|
||||||
import { useUserStore } from "#/store/auth";
|
|
||||||
import { usePreferencesStore } from "#/store/preferences";
|
import { usePreferencesStore } from "#/store/preferences";
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
|
@ -34,17 +32,10 @@ const NavbarTitles = {
|
||||||
links: "Только ссылки",
|
links: "Только ссылки",
|
||||||
selected: "Только выбранные",
|
selected: "Только выбранные",
|
||||||
never: "Никогда",
|
never: "Никогда",
|
||||||
};
|
}
|
||||||
|
|
||||||
const FifthButton = {
|
|
||||||
3: "Избранное",
|
|
||||||
4: "Коллекции",
|
|
||||||
5: "История",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
|
export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
|
||||||
const preferenceStore = usePreferencesStore();
|
const preferenceStore = usePreferencesStore();
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
const { computedMode, setMode } = useThemeMode();
|
const { computedMode, setMode } = useThemeMode();
|
||||||
|
|
||||||
|
@ -177,66 +168,26 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
|
||||||
</p>
|
</p>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
color="blue"
|
color="blue"
|
||||||
label={NavbarTitles[preferenceStore.flags.showNavbarTitles]}
|
label={
|
||||||
|
NavbarTitles[preferenceStore.flags.showNavbarTitles]
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{Object.keys(NavbarTitles).map(
|
{Object.keys(NavbarTitles).map((key: "always" | "links" | "selected" | "never") => {
|
||||||
(key: "always" | "links" | "selected" | "never") => {
|
return (
|
||||||
return (
|
<Dropdown.Item
|
||||||
<Dropdown.Item
|
key={`navbar-titles-${key}`}
|
||||||
className={`${key == "links" ? "hidden lg:flex" : ""}`}
|
onClick={() =>
|
||||||
key={`navbar-titles-${key}`}
|
preferenceStore.setFlags({
|
||||||
onClick={() =>
|
showNavbarTitles: key,
|
||||||
preferenceStore.setFlags({
|
})
|
||||||
showNavbarTitles: key,
|
}
|
||||||
})
|
>
|
||||||
}
|
{NavbarTitles[key]}
|
||||||
>
|
</Dropdown.Item>
|
||||||
{NavbarTitles[key]}
|
);
|
||||||
</Dropdown.Item>
|
})}
|
||||||
);
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
{userStore.isAuth ?
|
|
||||||
<div className="flex items-center justify-between sm:hidden">
|
|
||||||
<p className=" dark:text-white max-w-96">
|
|
||||||
Пятый пункт в навигации
|
|
||||||
</p>
|
|
||||||
<Dropdown
|
|
||||||
color="blue"
|
|
||||||
label={
|
|
||||||
preferenceStore.flags.showFifthButton ?
|
|
||||||
FifthButton[preferenceStore.flags.showFifthButton]
|
|
||||||
: "Нет"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Dropdown.Item
|
|
||||||
onClick={() =>
|
|
||||||
preferenceStore.setFlags({
|
|
||||||
showFifthButton: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Не показывать
|
|
||||||
</Dropdown.Item>
|
|
||||||
{Object.keys(FifthButton).map((key) => {
|
|
||||||
return (
|
|
||||||
<Dropdown.Item
|
|
||||||
key={`navbar-fifthbutton-${key}`}
|
|
||||||
onClick={() =>
|
|
||||||
preferenceStore.setFlags({
|
|
||||||
showFifthButton: Number(key) as 3 | 4 | 5,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{FifthButton[key]}
|
|
||||||
</Dropdown.Item>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
|
||||||
: ""}
|
|
||||||
<HR className="my-4 dark:bg-slate-400" />
|
<HR className="my-4 dark:bg-slate-400" />
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="w-6 h-6 iconify material-symbols--settings-outline"></span>
|
<span className="w-6 h-6 iconify material-symbols--settings-outline"></span>
|
||||||
|
@ -327,15 +278,26 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
|
||||||
<HR className="my-4 dark:bg-slate-400" />
|
<HR className="my-4 dark:bg-slate-400" />
|
||||||
<div>
|
<div>
|
||||||
<Link
|
<Link
|
||||||
href={"/about"}
|
href={"https://t.me/anix_web"}
|
||||||
className="flex items-center gap-2 p-2 text-left rounded-md hover:bg-gray-100 dark:hover:bg-gray-900"
|
className="flex items-center gap-2 p-2 text-left rounded-md hover:bg-gray-100 dark:hover:bg-gray-900"
|
||||||
onClick={() => props.setIsOpen(false)}
|
|
||||||
>
|
>
|
||||||
<span className="w-8 h-8 iconify material-symbols--info"></span>
|
<span className="w-8 h-8 iconify fa6-brands--telegram"></span>
|
||||||
<div>
|
<div>
|
||||||
<p>О приложении</p>
|
<p>Телеграм канал</p>
|
||||||
<p className="text-sm text-gray-400 dark:text-gray-200">
|
<p className="text-sm text-gray-400 dark:text-gray-200">
|
||||||
v{CURRENT_APP_VERSION}
|
@anix_web
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href={"https://wah.su/radiquum"}
|
||||||
|
className="flex items-center gap-2 p-2 text-left rounded-md hover:bg-gray-100 dark:hover:bg-gray-900"
|
||||||
|
>
|
||||||
|
<span className="w-8 h-8 iconify mdi--code"></span>
|
||||||
|
<div>
|
||||||
|
<p>Разработчик</p>
|
||||||
|
<p className="text-sm text-gray-400 dark:text-gray-200">
|
||||||
|
Radiquum
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
"use server";
|
|
||||||
|
|
||||||
import { Card } from "flowbite-react";
|
|
||||||
import Image from "next/image";
|
|
||||||
|
|
||||||
import * as fs from "node:fs";
|
|
||||||
import * as path from "node:path";
|
|
||||||
import { CURRENT_APP_VERSION } from "#/api/config";
|
|
||||||
import Styles from "../components/ChangelogModal/ChangelogModal.module.css";
|
|
||||||
import Markdown from "markdown-to-jsx";
|
|
||||||
|
|
||||||
import {
|
|
||||||
Accordion,
|
|
||||||
AccordionContent,
|
|
||||||
AccordionPanel,
|
|
||||||
AccordionTitle,
|
|
||||||
} from "flowbite-react";
|
|
||||||
import { version } from "node:os";
|
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export const AboutPage = () => {
|
|
||||||
const directoryPath = path.join(process.cwd(), "public/changelog");
|
|
||||||
const files = fs.readdirSync(directoryPath);
|
|
||||||
const current = {
|
|
||||||
version: CURRENT_APP_VERSION,
|
|
||||||
changelog: `#${CURRENT_APP_VERSION}\r\nНет списка изменений`,
|
|
||||||
};
|
|
||||||
const previous = [];
|
|
||||||
|
|
||||||
if (files.includes(`${CURRENT_APP_VERSION}.md`)) {
|
|
||||||
const changelog = fs.readFileSync(
|
|
||||||
path.join(directoryPath, `${CURRENT_APP_VERSION}.md`),
|
|
||||||
"utf8"
|
|
||||||
);
|
|
||||||
current.changelog = changelog;
|
|
||||||
}
|
|
||||||
|
|
||||||
files.forEach((file) => {
|
|
||||||
if (file != `${CURRENT_APP_VERSION}.md`) {
|
|
||||||
const changelog = fs.readFileSync(path.join(directoryPath, file), "utf8");
|
|
||||||
previous.push({
|
|
||||||
version: file.replace(".md", ""),
|
|
||||||
changelog: changelog,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="grid grid-cols-1 gap-2 md:grid-cols-2 lg:grid-cols-3">
|
|
||||||
<Card className="md:col-span-2 lg:col-span-3">
|
|
||||||
<div className="flex flex-col items-center gap-4 md:flex-row">
|
|
||||||
<Image
|
|
||||||
src="/images/icons/icon-512x512.png"
|
|
||||||
className="flex-shrink-0 w-32 h-32 rounded-full"
|
|
||||||
alt="about image"
|
|
||||||
width={128}
|
|
||||||
height={128}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<h1 className="text-xl font-bold">
|
|
||||||
AniX - Неофициальный веб клиент для Anixart
|
|
||||||
</h1>
|
|
||||||
<p className="max-w-[900px]">
|
|
||||||
AniX - это неофициальный веб-клиент для Android-приложения
|
|
||||||
Anixart. Он позволяет вам получать доступ к своей учетной записи
|
|
||||||
Anixart и управлять ею из веб-браузера. Так-же можно
|
|
||||||
синхронизировать и управлять списками и избранным. И самое главное
|
|
||||||
смотреть все доступные аниме из базы Anixart.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
<Link href={"https://wah.su/radiquum"} target="_blank">
|
|
||||||
<Card>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<Image
|
|
||||||
src="https://radiquum.wah.su/static/avatar_512.jpg"
|
|
||||||
className="flex-shrink-0 w-16 h-16 rounded-full"
|
|
||||||
alt="developer image"
|
|
||||||
width={128}
|
|
||||||
height={128}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<h1 className="text-xl font-bold">Radiquum</h1>
|
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-200">
|
|
||||||
Разработчик
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Link>
|
|
||||||
<Link href={"https://t.me/anix_web"} target="_blank">
|
|
||||||
<Card>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<span className="w-16 h-16 iconify fa6-brands--telegram text-[#001725] dark:text-[#faf8f9]"></span>
|
|
||||||
<div>
|
|
||||||
<h1 className="text-xl font-bold">Телеграм канал</h1>
|
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-200">
|
|
||||||
@anix_web
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Link>
|
|
||||||
<Link href={"https://github.com/Radiquum/AniX"} target="_blank">
|
|
||||||
<Card>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<span className="flex-shrink-0 w-16 h-16 iconify fa6-brands--github text-[#001725] dark:text-[#faf8f9]"></span>
|
|
||||||
<div>
|
|
||||||
<h1 className="text-xl font-bold">Код на GitHub</h1>
|
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-200">
|
|
||||||
github.com/Radiquum/AniX
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Link>
|
|
||||||
<Card className="md:col-span-2 lg:col-span-3">
|
|
||||||
<h1 className="text-2xl font-bold">Список изменений</h1>
|
|
||||||
<Markdown className={Styles.markdown}>{current.changelog}</Markdown>
|
|
||||||
<Accordion collapseAll={true}>
|
|
||||||
{previous.reverse().map((changelog) => (
|
|
||||||
<AccordionPanel key={changelog.version}>
|
|
||||||
<AccordionTitle>v{changelog.version}</AccordionTitle>
|
|
||||||
<AccordionContent>
|
|
||||||
<Markdown className={Styles.markdown}>
|
|
||||||
{changelog.changelog}
|
|
||||||
</Markdown>
|
|
||||||
</AccordionContent>
|
|
||||||
</AccordionPanel>
|
|
||||||
))}
|
|
||||||
</Accordion>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -6,11 +6,9 @@ import { useRouter } from "next/navigation";
|
||||||
import { SettingsModal } from "#/components/SettingsModal/SettingsModal";
|
import { SettingsModal } from "#/components/SettingsModal/SettingsModal";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { usePreferencesStore } from "#/store/preferences";
|
|
||||||
|
|
||||||
export const MenuPage = () => {
|
export const MenuPage = () => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const preferenceStore = usePreferencesStore();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [isSettingModalOpen, setIsSettingModalOpen] = useState(false);
|
const [isSettingModalOpen, setIsSettingModalOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -24,7 +22,7 @@ export const MenuPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{userStore.user && (
|
{userStore.user && (
|
||||||
<div className="fixed flex flex-col justify-end gap-2 left-4 right-4 bottom-24 sm:static">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
<Link
|
<Link
|
||||||
href={`/profile/${userStore.user.id}`}
|
href={`/profile/${userStore.user.id}`}
|
||||||
|
@ -83,42 +81,62 @@ export const MenuPage = () => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{preferenceStore.flags.showFifthButton != 3 ?
|
<Link href="/favorites" className="flex-1 sm:hidden">
|
||||||
<Link href="/favorites" className="flex-1 sm:hidden">
|
<Card>
|
||||||
<Card>
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<span
|
||||||
<span
|
className={`iconify material-symbols--favorite-outline w-6 h-6`}
|
||||||
className={`iconify material-symbols--favorite-outline w-6 h-6`}
|
></span>
|
||||||
></span>
|
<p>Избранное</p>
|
||||||
<p>Избранное</p>
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
<Link href="/collections" className="flex-1 sm:hidden">
|
||||||
|
<Card>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
className={`iconify material-symbols--collections-bookmark-outline w-6 h-6`}
|
||||||
|
></span>
|
||||||
|
<p>Коллекции</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
<Link href="/history" className="flex-1 sm:hidden">
|
||||||
|
<Card>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
className={`iconify material-symbols--history w-6 h-6`}
|
||||||
|
></span>
|
||||||
|
<p>История</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
<Link href={"https://t.me/anix_web"} className="flex-1">
|
||||||
|
<Card>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="w-8 h-8 iconify fa6-brands--telegram"></span>
|
||||||
|
<div>
|
||||||
|
<p>Телеграм канал</p>
|
||||||
|
<p className="text-sm text-gray-400 dark:text-gray-200">
|
||||||
|
@anix_web
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</div>
|
||||||
</Link>
|
</Card>
|
||||||
: ""}
|
</Link>
|
||||||
{preferenceStore.flags.showFifthButton != 4 ?
|
<Link href={"https://wah.su/radiquum"} className="flex-1">
|
||||||
<Link href="/collections" className="flex-1 sm:hidden">
|
<Card>
|
||||||
<Card>
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<span className="w-8 h-8 iconify mdi--code"></span>
|
||||||
<span
|
<div>
|
||||||
className={`iconify material-symbols--collections-bookmark-outline w-6 h-6`}
|
<p>Разработчик</p>
|
||||||
></span>
|
<p className="text-sm text-gray-400 dark:text-gray-200">
|
||||||
<p>Коллекции</p>
|
Radiquum
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</div>
|
||||||
</Link>
|
</Card>
|
||||||
: ""}
|
</Link>
|
||||||
{preferenceStore.flags.showFifthButton != 5 ?
|
|
||||||
<Link href="/history" className="flex-1 sm:hidden">
|
|
||||||
<Card>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span
|
|
||||||
className={`iconify material-symbols--history w-6 h-6`}
|
|
||||||
></span>
|
|
||||||
<p>История</p>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
</Link>
|
|
||||||
: ""}
|
|
||||||
<SettingsModal
|
<SettingsModal
|
||||||
isOpen={isSettingModalOpen}
|
isOpen={isSettingModalOpen}
|
||||||
setIsOpen={setIsSettingModalOpen}
|
setIsOpen={setIsSettingModalOpen}
|
||||||
|
|
|
@ -11,7 +11,6 @@ interface preferencesState {
|
||||||
showChangelog?: boolean;
|
showChangelog?: boolean;
|
||||||
enableAnalytics?: boolean;
|
enableAnalytics?: boolean;
|
||||||
showNavbarTitles?: "always" | "links" | "selected" | "never";
|
showNavbarTitles?: "always" | "links" | "selected" | "never";
|
||||||
showFifthButton?: null | 3 | 4 | 5;
|
|
||||||
};
|
};
|
||||||
params: {
|
params: {
|
||||||
isFirstLaunch?: boolean;
|
isFirstLaunch?: boolean;
|
||||||
|
@ -23,7 +22,7 @@ interface preferencesState {
|
||||||
};
|
};
|
||||||
experimental?: {
|
experimental?: {
|
||||||
newPlayer: boolean;
|
newPlayer: boolean;
|
||||||
};
|
}
|
||||||
// color: {
|
// color: {
|
||||||
// primary: string;
|
// primary: string;
|
||||||
// secondary: string;
|
// secondary: string;
|
||||||
|
@ -45,7 +44,6 @@ export const usePreferencesStore = create<preferencesState>()(
|
||||||
showChangelog: true,
|
showChangelog: true,
|
||||||
enableAnalytics: true,
|
enableAnalytics: true,
|
||||||
showNavbarTitles: "always",
|
showNavbarTitles: "always",
|
||||||
showFifthButton: null,
|
|
||||||
},
|
},
|
||||||
params: {
|
params: {
|
||||||
isFirstLaunch: true,
|
isFirstLaunch: true,
|
||||||
|
@ -56,8 +54,8 @@ export const usePreferencesStore = create<preferencesState>()(
|
||||||
bookmarksCategory: "watching",
|
bookmarksCategory: "watching",
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
newPlayer: false,
|
newPlayer: false
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
setHasHydrated: (state) => {
|
setHasHydrated: (state) => {
|
||||||
set({
|
set({
|
||||||
|
@ -76,12 +74,9 @@ export const usePreferencesStore = create<preferencesState>()(
|
||||||
onRehydrateStorage: (state) => {
|
onRehydrateStorage: (state) => {
|
||||||
return () => state.setHasHydrated(true);
|
return () => state.setHasHydrated(true);
|
||||||
},
|
},
|
||||||
merge: (persistedState, currentState) => {
|
merge: (persistedState , currentState) => {
|
||||||
return deepmerge(
|
return deepmerge(currentState as preferencesState, persistedState as preferencesState);
|
||||||
currentState as preferencesState,
|
}
|
||||||
persistedState as preferencesState
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,10 +6,10 @@ AniX - это неофициальный веб-клиент для Android-пр
|
||||||
|
|
||||||
## Список изменений
|
## Список изменений
|
||||||
|
|
||||||
- [3.5.0](/public/changelog/3.5.0.md)
|
|
||||||
- [3.4.0](/public/changelog/3.4.0.md)
|
- [3.4.0](/public/changelog/3.4.0.md)
|
||||||
- [3.3.0](/public/changelog/3.3.0.md)
|
- [3.3.0](/public/changelog/3.3.0.md)
|
||||||
- [3.2.3](/public/changelog/3.2.3.md)
|
- [3.2.3](/public/changelog/3.2.3.md)
|
||||||
|
- [3.2.2](/public/changelog/3.2.2.md)
|
||||||
|
|
||||||
[другие версии](/public/changelog)
|
[другие версии](/public/changelog)
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
# 3.5.0
|
|
||||||
|
|
||||||
## Добавлено
|
|
||||||
|
|
||||||
- Добавлена страница о приложении
|
|
||||||
- Добавлена возможность добавить пятую кнопку в меню навигации на мобильных устройствах
|
|
||||||
|
|
||||||
## Изменено
|
|
||||||
|
|
||||||
- Стиль карточек для релизов был изменён на вертикальный
|
|
||||||
- На мобильных устройствах постер на странице релиза теперь по середине
|
|
||||||
- Позиция лицензированных сервисов теперь под постером
|
|
||||||
- На мобильных устройствах позиция меню была смещена вниз
|
|
||||||
|
|
||||||
## Исправлено
|
|
||||||
|
|
||||||
- Ошибка своего плеера не сбрасывалась, если удалось получить ссылку при переключении серии
|
|
Loading…
Add table
Add a link
Reference in a new issue