From 052e649012ecd950b7967bd58e8776b3403a6681 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Sun, 24 Aug 2025 23:21:07 +0500 Subject: [PATCH 01/32] anix/fix: incorrect format of watched time statistic --- app/api/utils.ts | 58 +++++++++++-------- app/components/Profile/Profile.Stats.tsx | 2 +- .../ReleaseInfo/ReleaseInfo.Info.tsx | 2 +- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/api/utils.ts b/app/api/utils.ts index fabc2b7..0567993 100644 --- a/app/api/utils.ts +++ b/app/api/utils.ts @@ -248,31 +248,43 @@ export function sinceUnixDate(unixInSeconds: number) { ); } -export function minutesToTime( - min: number, - type?: "full" | "daysOnly" | "daysHours" -) { - const d = Math.floor(min / 1440); // 60*24 - const h = Math.floor((min - d * 1440) / 60); - const m = Math.round(min % 60); +export function minutesToTime(min: number) { + const seconds = min * 60; + const epoch = new Date(0); + const date = new Date(seconds * 1000); - var dDisplay = - d > 0 ? `${d} ${numberDeclension(d, "день", "дня", "дней")}` : ""; - var hDisplay = - h > 0 ? `${h} ${numberDeclension(h, "час", "часа", "часов")}` : ""; - var mDisplay = - m > 0 ? `${m} ${numberDeclension(m, "минута", "минуты", "минут")}` : ""; + const diffInMinutes = + new Date(date.getTime() - epoch.getTime()).getTime() / 1000 / 60; - if (type == "daysOnly") { - if (d > 0) return dDisplay; - return "? дней"; - } else if (type == "daysHours") { - if (d > 0 && h > 0) return dDisplay + ", " + hDisplay; - if (h > 0) return hDisplay; - if (m > 0) return mDisplay; - } else { - return `${d > 0 ? dDisplay : ""}${h > 0 ? ", " + hDisplay : ""}${m > 0 ? ", " + mDisplay : ""}`; - } + let days = Math.floor(diffInMinutes / 1440); + if (days < 0) days = 0; + const daysToMinutes = days * 1440; + + let hours = Math.floor((diffInMinutes - daysToMinutes) / 60); + if (hours < 0) hours = 0; + const hoursToMinutes = hours * 60; + + let minutes = diffInMinutes - daysToMinutes - hoursToMinutes; + if (minutes < 0) minutes = 0; + + const dayDisplay = + days > 0 ? `${days} ${numberDeclension(days, "день", "дня", "дней")}` : ""; + const hourDisplay = + hours > 0 ? + `${hours} ${numberDeclension(hours, "час", "часа", "часов")}` + : ""; + const minuteDisplay = + minutes > 0 ? + `${minutes} ${numberDeclension(minutes, "минута", "минуты", "минут")}` + : ""; + + if (days > 0 && hours > 0 && minutes > 0) return `${dayDisplay}, ${hourDisplay}, ${minuteDisplay}`; + if (days > 0 && hours > 0) return `${dayDisplay}, ${hourDisplay}`; + if (days > 0 && minutes > 0) return `${dayDisplay}, ${minuteDisplay}`; + if (hours > 0 && minutes > 0) return `${hourDisplay}, ${minuteDisplay}`; + if (days > 0) return dayDisplay; + if (hours > 0) return hourDisplay; + if (minutes > 0) return minuteDisplay; } const StatusList: Record = { diff --git a/app/components/Profile/Profile.Stats.tsx b/app/components/Profile/Profile.Stats.tsx index 214c1cb..e264905 100644 --- a/app/components/Profile/Profile.Stats.tsx +++ b/app/components/Profile/Profile.Stats.tsx @@ -112,7 +112,7 @@ export const ProfileStats = (props: {

Время просмотра:{" "} - ~{minutesToTime(props.watched_time, "daysHours")} + ~{minutesToTime(props.watched_time)}

diff --git a/app/components/ReleaseInfo/ReleaseInfo.Info.tsx b/app/components/ReleaseInfo/ReleaseInfo.Info.tsx index 631ca88..0ec3cd3 100644 --- a/app/components/ReleaseInfo/ReleaseInfo.Info.tsx +++ b/app/components/ReleaseInfo/ReleaseInfo.Info.tsx @@ -59,7 +59,7 @@ export const ReleaseInfoInfo = (props: { {"/"} {props.episodes.total ? props.episodes.total + " эп. " : "? эп. "} {props.duration != 0 && - `по ${minutesToTime(props.duration, "daysHours")}`} + `по ${minutesToTime(props.duration)}`} From b93aeeed04d40d63ecfcaacec7d1bfda1157effb Mon Sep 17 00:00:00 2001 From: Radiquum Date: Sun, 24 Aug 2025 23:39:48 +0500 Subject: [PATCH 02/32] anix/style: change user card in search --- app/components/UserSection/UserSection.tsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/components/UserSection/UserSection.tsx b/app/components/UserSection/UserSection.tsx index 4dc7bfe..896ebd2 100644 --- a/app/components/UserSection/UserSection.tsx +++ b/app/components/UserSection/UserSection.tsx @@ -12,20 +12,19 @@ export const UserSection = (props: { sectionTitle?: string; content: any }) => { )}
-
+
{props.content.map((user) => { return ( - - - -
- {user.login} -
+ + +
+ +

{user.login}

+
); })} - {props.content.length == 1 &&
}
From c636c843ed4906be2e7abcbbb2196326bd909fe8 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 01:48:56 +0500 Subject: [PATCH 03/32] anix/feat: add new stats anix/fix: search links from release page --- app/components/Profile/Profile.Stats.tsx | 129 +++++++++++++----- .../ReleaseInfo/ReleaseInfo.SearchLink.tsx | 14 +- app/pages/Profile.tsx | 3 + 3 files changed, 102 insertions(+), 44 deletions(-) diff --git a/app/components/Profile/Profile.Stats.tsx b/app/components/Profile/Profile.Stats.tsx index e264905..b31f77d 100644 --- a/app/components/Profile/Profile.Stats.tsx +++ b/app/components/Profile/Profile.Stats.tsx @@ -3,12 +3,21 @@ import Link from "next/link"; import ApexCharts from "apexcharts"; import { useEffect } from "react"; import { minutesToTime } from "#/api/utils"; +import { ReleaseInfoSearchLink } from "../ReleaseInfo/ReleaseInfo.SearchLink"; + +type preferredItem = { + name: string; + percentage: number; +}; export const ProfileStats = (props: { lists: Array; watched_count: number; watched_time: number; - profile_id: number + profile_id: number; + preferred_genres: Array; + preferred_audiences: Array; + preferred_themes: Array; }) => { const getChartOptions = () => { return { @@ -81,41 +90,95 @@ export const ProfileStats = (props: {
-

- {" "} - Смотрю {props.lists[0]} -

-

- {" "} - В планах {props.lists[1]} -

-

- {" "} - Просмотрено {props.lists[2]} -

-

- {" "} - Отложено {props.lists[3]} -

-

- {" "} - Брошено {props.lists[4]} -

+
+

+ {" "} + Смотрю {props.lists[0]} +

+

+ {" "} + В планах {props.lists[1]} +

+

+ {" "} + Просмотрено {props.lists[2]} +

+

+ {" "} + Отложено {props.lists[3]} +

+

+ {" "} + Брошено {props.lists[4]} +

+
+
+

+ Жанры:{" "} + + {props.preferred_genres.map((item, index) => { + return ( +

+ {index > 0 && ", "} + {" "} + {item.percentage}% +
+ ); + })} + +

+

+ Аудитория:{" "} + + {props.preferred_audiences.map((item, index) => { + return ( +

+ {index > 0 && ", "} + {" "} + {item.percentage}% +
+ ); + })} + +

+

+ Тематика:{" "} + + {props.preferred_themes.map((item, index) => { + return ( +

+ {index > 0 && ", "} + {" "} + {item.percentage}% +
+ ); + })} + +

+ +

+ Просмотрено серий:{" "} + {props.watched_count} +

+

+ Время просмотра:{" "} + + ~{minutesToTime(props.watched_time)} + +

+
-
-

- Просмотрено серий:{" "} - {props.watched_count} -

-

- Время просмотра:{" "} - - ~{minutesToTime(props.watched_time)} - -

-
); }; diff --git a/app/components/ReleaseInfo/ReleaseInfo.SearchLink.tsx b/app/components/ReleaseInfo/ReleaseInfo.SearchLink.tsx index db19124..f7524a8 100644 --- a/app/components/ReleaseInfo/ReleaseInfo.SearchLink.tsx +++ b/app/components/ReleaseInfo/ReleaseInfo.SearchLink.tsx @@ -1,19 +1,11 @@ import Link from "next/link"; -// const searchBy = { -// title: 0, -// studio: 1, -// director: 2, -// author: 3, -// genre: 4 -// } - // TODO: сделать какую-нибудь анимацию на ссылке при наведении и фокусе -export const ReleaseInfoSearchLink = (props: { title: string, searchBy: string | number | null }) => { +export const ReleaseInfoSearchLink = (props: { title: string, searchBy: string }) => { return ( {props.title} diff --git a/app/pages/Profile.tsx b/app/pages/Profile.tsx index fdd44b4..6eab266 100644 --- a/app/pages/Profile.tsx +++ b/app/pages/Profile.tsx @@ -164,6 +164,9 @@ export const ProfilePage = (props: any) => { watched_count={user.watched_episode_count} watched_time={user.watched_time} profile_id={user.id} + preferred_genres={user.preferred_genres || []} + preferred_audiences={user.preferred_audiences || []} + preferred_themes={user.preferred_themes || []} />
From 48345244f3610de234c774a218f66983f269493c Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 01:51:12 +0500 Subject: [PATCH 04/32] stats style --- app/components/Profile/Profile.Stats.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/Profile/Profile.Stats.tsx b/app/components/Profile/Profile.Stats.tsx index b31f77d..659ea91 100644 --- a/app/components/Profile/Profile.Stats.tsx +++ b/app/components/Profile/Profile.Stats.tsx @@ -90,7 +90,7 @@ export const ProfileStats = (props: {
-
+

{" "} Смотрю {props.lists[0]} From 6b84a312f7a703a061361d3be5be23dafaf5b703 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 04:35:32 +0500 Subject: [PATCH 05/32] anix/refactor: navbar --- app/App.tsx | 12 +- app/components/Navbar/NavBarMobile.tsx | 168 ++++++++++++++ app/components/Navbar/NavBarPc.tsx | 139 +++++++++++ app/components/Navbar/NavbarUpdate.tsx | 215 ------------------ .../RelatedSection/RelatedSection.tsx | 2 +- .../ReleaseSection/ReleaseSection.tsx | 4 +- .../SettingsModal/SettingsModal.tsx | 18 +- app/menu/page.tsx | 11 - app/pages/MobileMenuPage.tsx | 130 ----------- app/pages/Search.tsx | 2 +- app/store/preferences.ts | 5 +- 11 files changed, 332 insertions(+), 374 deletions(-) create mode 100644 app/components/Navbar/NavBarMobile.tsx create mode 100644 app/components/Navbar/NavBarPc.tsx delete mode 100644 app/components/Navbar/NavbarUpdate.tsx delete mode 100644 app/menu/page.tsx delete mode 100644 app/pages/MobileMenuPage.tsx diff --git a/app/App.tsx b/app/App.tsx index 8cccbd0..34052c1 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -1,7 +1,6 @@ "use client"; import { useUserStore } from "./store/auth"; import { usePreferencesStore } from "./store/preferences"; -import { Navbar } from "./components/Navbar/NavbarUpdate"; import { Inter } from "next/font/google"; import { useEffect, useState } from "react"; import { @@ -14,6 +13,9 @@ import { import { Spinner } from "./components/Spinner/Spinner"; import { ChangelogModal } from "#/components/ChangelogModal/ChangelogModal"; import { Bounce, ToastContainer } from "react-toastify"; +import { NavBarPc } from "./components/Navbar/NavBarPc"; +import { NavBarMobile } from "./components/Navbar/NavBarMobile"; +import { SettingsModal } from "./components/SettingsModal/SettingsModal"; const inter = Inter({ subsets: ["latin"] }); @@ -23,6 +25,7 @@ export const App = (props) => { const [showChangelog, setShowChangelog] = useState(false); const [currentVersion, setCurrentVersion] = useState(""); const [previousVersions, setPreviousVersions] = useState([]); + const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); useEffect(() => { async function _checkVersion() { @@ -68,7 +71,7 @@ export const App = (props) => { - +

{props.children}
@@ -123,6 +126,11 @@ export const App = (props) => { theme="colored" transition={Bounce} /> + + ); }; diff --git a/app/components/Navbar/NavBarMobile.tsx b/app/components/Navbar/NavBarMobile.tsx new file mode 100644 index 0000000..3431566 --- /dev/null +++ b/app/components/Navbar/NavBarMobile.tsx @@ -0,0 +1,168 @@ +"use client"; +import { + Avatar, + Dropdown, + DropdownDivider, + DropdownItem, +} from "flowbite-react"; +import { useUserStore } from "#/store/auth"; +import Link from "next/link"; +import { usePathname, useRouter } from "next/navigation"; +import { usePreferencesStore } from "#/store/preferences"; + +const NavbarItems = [ + { + title: "Домашняя", + icon: "mdi--home", + href: "/", + auth: false, + }, + { + title: "Поиск", + icon: "mdi--search", + href: "/search", + auth: false, + }, + { + title: "Закладки", + icon: "mdi--bookmark-multiple", + href: "/bookmarks", + auth: true, + }, +]; + +const FifthButton = { + favorites: { + title: "Избранное", + icon: "mdi--favorite", + href: "/favorites", + auth: true, + }, + collections: { + title: "Коллекции", + icon: "mdi--collections-bookmark", + href: "/collections", + auth: true, + }, + history: { + title: "История", + icon: "mdi--history", + href: "/history", + auth: true, + }, + discovery: { + title: "Обзор", + icon: "mdi--compass", + href: "/discovery", + auth: true, + }, +}; + +export const NavBarMobile = (props: { setIsSettingModalOpen: any }) => { + const userStore = useUserStore(); + const router = useRouter(); + const pathname = usePathname(); + const preferenceStore = usePreferencesStore(); + + return ( + <> +
+
+ {NavbarItems.map((item) => { + if (item.auth && !userStore.isAuth) return <>; + return ( + + + {item.title} + + ); + })} + {userStore.isAuth && preferenceStore.flags.showFifthButton ? + + + + {FifthButton[preferenceStore.flags.showFifthButton].title} + + + : ""} + + +

+ {userStore.isAuth ? userStore.user.login : "Аноним"} +

+
+ } + > + {userStore.isAuth && ( + <> + router.push(`/profile/${userStore.user.id}`)} + > + + Профиль + + {Object.entries(FifthButton).map(([key, item]) => { + if (item.auth && !userStore.isAuth) return <>; + if (preferenceStore.flags.showFifthButton === key) + return <>; + return ( + router.push(item.href)} + > + + {item.title} + + ); + })} + + + )} + props.setIsSettingModalOpen(true)} + className="relative flex" + > + + Настройки + + {userStore.isAuth ? + userStore.logout()}> + + Выйти + + : router.push(`/login?redirect=${pathname}`)} + > + + Войти + + } + +
+ + + ); +}; diff --git a/app/components/Navbar/NavBarPc.tsx b/app/components/Navbar/NavBarPc.tsx new file mode 100644 index 0000000..b8886f4 --- /dev/null +++ b/app/components/Navbar/NavBarPc.tsx @@ -0,0 +1,139 @@ +"use client"; +import { + Avatar, + Dropdown, + DropdownDivider, + DropdownItem, +} from "flowbite-react"; +import { useUserStore } from "#/store/auth"; +import Link from "next/link"; +import { usePathname, useRouter } from "next/navigation"; + +const NavbarItems = [ + { + title: "Домашняя", + icon: "mdi--home", + href: "/", + auth: false, + }, + { + title: "Поиск", + icon: "mdi--search", + href: "/search", + auth: false, + }, + { + title: "Закладки", + icon: "mdi--bookmark-multiple", + href: "/bookmarks", + auth: true, + }, + { + title: "Избранное", + icon: "mdi--favorite", + href: "/favorites", + auth: true, + }, + { + title: "Коллекции", + icon: "mdi--collections-bookmark", + href: "/collections", + auth: true, + }, + { + title: "История", + icon: "mdi--history", + href: "/history", + auth: true, + }, + { + title: "Обзор", + icon: "mdi--compass", + href: "/discovery", + auth: true, + }, +]; + +export const NavBarPc = (props: { setIsSettingModalOpen: any }) => { + const userStore = useUserStore(); + const router = useRouter(); + const pathname = usePathname(); + + return ( + <> +
+
+
+ {NavbarItems.map((item) => { + if (item.auth && !userStore.isAuth) return <>; + return ( + + + {item.title} + + ); + })} +
+ + +

+ {userStore.isAuth ? userStore.user.login : "Аноним"} +

+
+ } + > + {userStore.isAuth ? + router.push(`/profile/${userStore.user.id}`)} + className="relative flex" + > + + Профиль + + : ""} + props.setIsSettingModalOpen(true)} + className="relative flex" + > + + Настройки + + {userStore.isAuth ? + userStore.logout()} + className="relative flex" + > + + Выйти + + : router.push(`/login?redirect=${pathname}`)} + className="relative flex" + > + + Войти + + } + +
+ + + ); +}; diff --git a/app/components/Navbar/NavbarUpdate.tsx b/app/components/Navbar/NavbarUpdate.tsx deleted file mode 100644 index a6219c0..0000000 --- a/app/components/Navbar/NavbarUpdate.tsx +++ /dev/null @@ -1,215 +0,0 @@ -"use client"; - -import Link from "next/link"; -import Image from "next/image"; -import { useUserStore } from "#/store/auth"; -import { usePathname } from "next/navigation"; -import { useState } from "react"; -import { SettingsModal } from "#/components/SettingsModal/SettingsModal"; -import { usePreferencesStore } from "#/store/preferences"; - -export const Navbar = () => { - const pathname = usePathname(); - const userStore = useUserStore(); - const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); - const preferenceStore = usePreferencesStore(); - - const menuItems = [ - { - id: 1, - title: "Домашняя", - href: "/", - hrefInCategory: "/home", - icon: { - default: "material-symbols--home-outline", - active: "material-symbols--home", - }, - isAuthRequired: false, - isShownOnMobile: true, - }, - { - id: 2, - title: "Поиск", - href: "/search", - icon: { - default: "material-symbols--search", - active: "material-symbols--search", - }, - isAuthRequired: false, - isShownOnMobile: true, - }, - { - id: 3, - title: "Закладки", - href: "/bookmarks", - icon: { - default: "material-symbols--bookmarks-outline", - active: "material-symbols--bookmarks", - }, - isAuthRequired: true, - isShownOnMobile: true, - }, - { - id: 4, - title: "Избранное", - href: "/favorites", - icon: { - default: "material-symbols--favorite-outline", - active: "material-symbols--favorite", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - { - id: 5, - title: "Коллекции", - href: "/collections", - icon: { - default: "material-symbols--collections-bookmark-outline", - active: "material-symbols--collections-bookmark", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - { - id: 6, - title: "История", - href: "/history", - icon: { - default: "material-symbols--history", - active: "material-symbols--history", - }, - isAuthRequired: true, - isShownOnMobile: false, - }, - ]; - - return ( - <> -
-
-
- {menuItems.map((item) => { - return ( - - - - {item.title} - - - ); - })} -
-
- {!userStore.isAuth ? - - - - Войти - - - : <> - - - - {userStore.user.login} - - - {preferenceStore.flags.showFifthButton ? - - - - {menuItems[preferenceStore.flags.showFifthButton].title} - - - : ""} - - - - {userStore.user.login} - - - - } - - {userStore.isAuth && ( - - )} -
-
-
- - - ); -}; diff --git a/app/components/RelatedSection/RelatedSection.tsx b/app/components/RelatedSection/RelatedSection.tsx index 368793d..fa640b8 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/components/SettingsModal/SettingsModal.tsx b/app/components/SettingsModal/SettingsModal.tsx index 56d9291..8a703b6 100644 --- a/app/components/SettingsModal/SettingsModal.tsx +++ b/app/components/SettingsModal/SettingsModal.tsx @@ -43,9 +43,10 @@ const NavbarTitles = { }; const FifthButton = { - 3: "Избранное", - 4: "Коллекции", - 5: "История", + favorites: "Избранное", + collections: "Коллекции", + history: "История", + discovery: "Обзор", }; export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { @@ -56,7 +57,8 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { const [isPlayerConfigured, setIsPlayerConfigured] = useState(false); useEffect(() => { - const NEXT_PUBLIC_PLAYER_PARSER_URL = env("NEXT_PUBLIC_PLAYER_PARSER_URL") || null; + const NEXT_PUBLIC_PLAYER_PARSER_URL = + env("NEXT_PUBLIC_PLAYER_PARSER_URL") || null; if (NEXT_PUBLIC_PLAYER_PARSER_URL) { setIsPlayerConfigured(true); } @@ -204,7 +206,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
{userStore.isAuth ? -
+

Пятый пункт в навигации

@@ -229,11 +231,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { return ( - preferenceStore.setFlags({ - showFifthButton: Number(key) as 3 | 4 | 5, - }) - } + onClick={() => preferenceStore.setFlags({showFifthButton: key})} > {FifthButton[key]} diff --git a/app/menu/page.tsx b/app/menu/page.tsx deleted file mode 100644 index 61305cc..0000000 --- a/app/menu/page.tsx +++ /dev/null @@ -1,11 +0,0 @@ -export const metadata = { - title: "Меню", -}; - -import { MenuPage } from "#/pages/MobileMenuPage"; - -export const dynamic = "force-static"; - -export default function Index() { - return ; -} diff --git a/app/pages/MobileMenuPage.tsx b/app/pages/MobileMenuPage.tsx deleted file mode 100644 index f1f73b8..0000000 --- a/app/pages/MobileMenuPage.tsx +++ /dev/null @@ -1,130 +0,0 @@ -"use client"; -import { Card } from "flowbite-react"; -import { useUserStore } from "#/store/auth"; -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { SettingsModal } from "#/components/SettingsModal/SettingsModal"; -import { useEffect, useState } from "react"; -import Image from "next/image"; -import { usePreferencesStore } from "#/store/preferences"; - -export const MenuPage = () => { - const userStore = useUserStore(); - const preferenceStore = usePreferencesStore(); - const router = useRouter(); - const [isSettingModalOpen, setIsSettingModalOpen] = useState(false); - - useEffect(() => { - if (!userStore.user) { - router.push("/"); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [userStore.user]); - - return ( - <> - {userStore.user && ( -
-
- - -
- -
-

- {userStore.user.login} -

-

- {userStore.user.status} -

-
-
-
- -
- - -
-
- {preferenceStore.flags.showFifthButton != 3 ? - - -
- -

Избранное

-
-
- - : ""} - {preferenceStore.flags.showFifthButton != 4 ? - - -
- -

Коллекции

-
-
- - : ""} - {preferenceStore.flags.showFifthButton != 5 ? - - -
- -

История

-
-
- - : ""} - -
- )} - - ); -}; diff --git a/app/pages/Search.tsx b/app/pages/Search.tsx index c5ee065..6647906 100644 --- a/app/pages/Search.tsx +++ b/app/pages/Search.tsx @@ -279,7 +279,7 @@ export function SearchPage() { return (
diff --git a/app/store/preferences.ts b/app/store/preferences.ts index 1225c2d..bfce3af 100644 --- a/app/store/preferences.ts +++ b/app/store/preferences.ts @@ -10,7 +10,7 @@ interface preferencesState { saveWatchHistory?: boolean; showChangelog?: boolean; showNavbarTitles?: "always" | "links" | "selected" | "never"; - showFifthButton?: null | 3 | 4 | 5; + showFifthButton?: null | string; }; params: { isFirstLaunch?: boolean; @@ -80,6 +80,7 @@ export const usePreferencesStore = create()( persistedState as preferencesState ); }, - } + version: 2, + }, ) ); From 8d2800c2f211c7e122c56080f4713e58fd183d06 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 05:20:03 +0500 Subject: [PATCH 06/32] anix/style: change sections columns from 1 to 2 on mobile --- .../CollectionLink/CollectionLink.tsx | 83 ++++++++----------- .../CollectionsSection/CollectionsSection.tsx | 3 +- .../ReleasePoster/PosterWithStuff.tsx | 8 +- .../ReleaseSection/ReleaseSection.tsx | 2 +- app/components/UserSection/UserSection.tsx | 4 +- 5 files changed, 41 insertions(+), 59 deletions(-) diff --git a/app/components/CollectionLink/CollectionLink.tsx b/app/components/CollectionLink/CollectionLink.tsx index aee2010..a7887d1 100644 --- a/app/components/CollectionLink/CollectionLink.tsx +++ b/app/components/CollectionLink/CollectionLink.tsx @@ -5,60 +5,43 @@ import Image from "next/image"; export const CollectionLink = (props: any) => { return ( -
-
- {props.title + {""} +
+
+ -
+ {props.comment_count && ( - {props.comment_count && ( - - )} - {props.is_private && ( -
- -
- )} - {props.is_favorite && ( -
- -
- )} -
-
-
-

- {props.title} -

+ )} + {props.is_private && ( +
+
- {props.description && ( -

- {`${props.description.slice(0, 125)}${ - props.description.length > 125 ? "..." : "" - }`} -

- )} -
+ )} + {props.is_favorite && ( +
+ +
+ )} +
+
+

+ {props.title} +

+

+ {props.description} +

diff --git a/app/components/CollectionsSection/CollectionsSection.tsx b/app/components/CollectionsSection/CollectionsSection.tsx index c7b0775..6e03911 100644 --- a/app/components/CollectionsSection/CollectionsSection.tsx +++ b/app/components/CollectionsSection/CollectionsSection.tsx @@ -16,7 +16,7 @@ export const CollectionsSection = (props: {
)}
-
+
{props.isMyCollections && } {props.content.map((collection) => { return ( @@ -25,7 +25,6 @@ export const CollectionsSection = (props: {
); })} - {props.content.length == 1 && !props.isMyCollections &&
}
diff --git a/app/components/ReleasePoster/PosterWithStuff.tsx b/app/components/ReleasePoster/PosterWithStuff.tsx index 7ffbee2..4482a5a 100644 --- a/app/components/ReleasePoster/PosterWithStuff.tsx +++ b/app/components/ReleasePoster/PosterWithStuff.tsx @@ -83,7 +83,7 @@ export const PosterWithStuff = (props: { return ( {index > 0 && ", "} {genre} @@ -91,18 +91,18 @@ export const PosterWithStuff = (props: { ); })} {props.title_ru && ( -

+

{props.title_ru}

)} {props.title_original && ( -

+

{props.title_original}

)}
{settings.showDescription && props.description && ( -

+

{props.description}

)} diff --git a/app/components/ReleaseSection/ReleaseSection.tsx b/app/components/ReleaseSection/ReleaseSection.tsx index 1c23d9b..95c4763 100644 --- a/app/components/ReleaseSection/ReleaseSection.tsx +++ b/app/components/ReleaseSection/ReleaseSection.tsx @@ -14,7 +14,7 @@ export const ReleaseSection = (props: {
)}
-
+
{props.content.map((release) => { return (
diff --git a/app/components/UserSection/UserSection.tsx b/app/components/UserSection/UserSection.tsx index 896ebd2..ece64fc 100644 --- a/app/components/UserSection/UserSection.tsx +++ b/app/components/UserSection/UserSection.tsx @@ -18,8 +18,8 @@ export const UserSection = (props: { sectionTitle?: string; content: any }) => {
- -

{user.login}

+ +

{user.login}

From 93205fdb4e7f9d056909a49d07f52e7224304223 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 05:38:06 +0500 Subject: [PATCH 07/32] anix/fix: search in bookmarks, user collections, user favorites, user history --- app/discover/page.tsx | 12 ++++++++++++ app/pages/BookmarksCategory.tsx | 6 ++++-- app/pages/Collections.tsx | 4 +++- app/pages/Discover.tsx | 19 +++++++++++++++++++ app/pages/Favorites.tsx | 19 ++++++++++--------- app/pages/History.tsx | 14 +++++++------- 6 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 app/discover/page.tsx create mode 100644 app/pages/Discover.tsx diff --git a/app/discover/page.tsx b/app/discover/page.tsx new file mode 100644 index 0000000..448f517 --- /dev/null +++ b/app/discover/page.tsx @@ -0,0 +1,12 @@ +import { DiscoverPage } from "#/pages/Discover"; + +export const metadata = { + title: "Обзор", + description: "Рекомендации и популярное", +}; + +export const dynamic = "force-static"; + +export default function Discover() { + return ; +} diff --git a/app/pages/BookmarksCategory.tsx b/app/pages/BookmarksCategory.tsx index b53b3fa..3590e50 100644 --- a/app/pages/BookmarksCategory.tsx +++ b/app/pages/BookmarksCategory.tsx @@ -82,7 +82,7 @@ export function BookmarksCategoryPage(props: any) {
); - }; + } if (error) { return ( @@ -105,7 +105,9 @@ export function BookmarksCategoryPage(props: any) { className="flex-1 max-w-full mx-4" onSubmit={(e) => { e.preventDefault(); - router.push(`/search?q=${searchVal}&where=list&list=${props.slug}`); + router.push( + `/search?query=${searchVal}¶ms={"where"%3A"list"%2C"searchBy"%3A"${props.slug}"}` + ); }} >
- {content && content.length > 0 ? ( + {content && content.length > 0 ? - ) : isLoading ? ( + : isLoading ?
- ) : ( -
+ :

В избранном пока ничего нет...

- )} + } {data && data[data.length - 1].current_page < data[data.length - 1].total_page_count && ( diff --git a/app/pages/History.tsx b/app/pages/History.tsx index 73c9f10..7b4c495 100644 --- a/app/pages/History.tsx +++ b/app/pages/History.tsx @@ -10,7 +10,6 @@ import { Button } from "flowbite-react"; import { useRouter } from "next/navigation"; import { useSWRfetcher } from "#/api/utils"; - export function HistoryPage() { const token = useUserStore((state) => state.token); const authState = useUserStore((state) => state.state); @@ -62,7 +61,9 @@ export function HistoryPage() { className="flex-1 max-w-full mx-4 mb-4" onSubmit={(e) => { e.preventDefault(); - router.push(`/search?q=${searchVal}&where=history`); + router.push( + `/search?query=${searchVal}¶ms={"where"%3A"history"%2C"searchBy"%3A"none"}` + ); }} >
- {content && content.length > 0 ? ( + {content && content.length > 0 ? <> {data && data[0].total_count != content.length && ( @@ -122,16 +123,15 @@ export function HistoryPage() { )} - ) : isLoading ? ( + : isLoading ?
- ) : ( -
+ :

В истории пока ничего нет...

- )} + } ); } From bfb361a0a88e613e2c33110a4cbbfdaf11b2425f Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 06:46:51 +0500 Subject: [PATCH 08/32] anix/feat: add interesting carousel to discovery page --- app/api/config.ts | 3 + .../Discovery/InterestingCarousel.module.css | 21 +++++ .../Discovery/InterestingCarousel.tsx | 91 +++++++++++++++++++ app/{discover => discovery}/page.tsx | 0 app/pages/Discover.tsx | 21 ++--- 5 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 app/components/Discovery/InterestingCarousel.module.css create mode 100644 app/components/Discovery/InterestingCarousel.tsx rename app/{discover => discovery}/page.tsx (100%) diff --git a/app/api/config.ts b/app/api/config.ts index 316d19e..a685cb3 100644 --- a/app/api/config.ts +++ b/app/api/config.ts @@ -74,5 +74,8 @@ export const ENDPOINTS = { releaseInCollections: `${API_PREFIX}/collection/all/release`, userCollections: `${API_PREFIX}/collection/all/profile`, favoriteCollections: `${API_PREFIX}/collectionFavorite`, + }, + discover: { + interesting: `${API_PREFIX}/discover/interesting`, } }; diff --git a/app/components/Discovery/InterestingCarousel.module.css b/app/components/Discovery/InterestingCarousel.module.css new file mode 100644 index 0000000..ed205c5 --- /dev/null +++ b/app/components/Discovery/InterestingCarousel.module.css @@ -0,0 +1,21 @@ +.swiper-button:global(.swiper-button-disabled) { + opacity: 0 !important; +} + +.swiper-button { + display: none !important; +} + +@media (hover: hover) and (min-width: 1024px) { + .swiper { + overflow: visible !important; + } +} + +@media (hover: hover) { + .swiper:hover .swiper-button { + display: flex !important; + width: 64px; + height: 64px; + } +} diff --git a/app/components/Discovery/InterestingCarousel.tsx b/app/components/Discovery/InterestingCarousel.tsx new file mode 100644 index 0000000..7740c8f --- /dev/null +++ b/app/components/Discovery/InterestingCarousel.tsx @@ -0,0 +1,91 @@ +"use client"; + +import { ENDPOINTS } from "#/api/config"; +import { useSWRfetcher } from "#/api/utils"; +import useSWR from "swr"; +import Image from "next/image"; +import { Swiper, SwiperSlide } from "swiper/react"; +import "swiper/css"; +import "swiper/css/navigation"; +import { Navigation } from "swiper/modules"; +import Styles from "./InterestingCarousel.module.css"; +import Link from "next/link"; + +export const InterestingCarousel = () => { + const { data, isLoading, error } = useSWR( + ENDPOINTS.discover.interesting, + useSWRfetcher, + { + revalidateOnFocus: false, + revalidateIfStale: false, + revalidateOnReconnect: false, + } + ); + + if (error) + return ( +
+
+

Произошла ошибка загрузки интересных релизов

+
+
+ ); + if (isLoading) return <>; + + return ( +
+ + {data.content.map((item) => { + return ( + + +
+ +
+
+

{item.title}

+

{item.description}

+
+
+ +
+ ); + })} +
+
+
+
+ ); +}; diff --git a/app/discover/page.tsx b/app/discovery/page.tsx similarity index 100% rename from app/discover/page.tsx rename to app/discovery/page.tsx diff --git a/app/pages/Discover.tsx b/app/pages/Discover.tsx index 2695dc3..068f412 100644 --- a/app/pages/Discover.tsx +++ b/app/pages/Discover.tsx @@ -1,19 +1,10 @@ "use client"; -import { useState, useEffect } from "react"; -import { useUserStore } from "../store/auth"; -import { useRouter } from "next/navigation"; +import { InterestingCarousel } from "#/components/Discovery/InterestingCarousel"; export const DiscoverPage = () => { - const token = useUserStore((state) => state.token); - const authState = useUserStore((state) => state.state); - const router = useRouter(); - - useEffect(() => { - if (authState === "finished" && !token) { - router.push("/login?redirect=/discover"); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [authState, token]); - - return <>; + return ( + <> + + + ); }; From 61baffd295a604baa8560cc0175b3bfcf0e24dfe Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 07:30:10 +0500 Subject: [PATCH 09/32] anix/: add buttons to discovery page --- app/components/Discovery/InterestingCarousel.tsx | 4 ++-- app/pages/Discover.tsx | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/components/Discovery/InterestingCarousel.tsx b/app/components/Discovery/InterestingCarousel.tsx index 7740c8f..d6c4c41 100644 --- a/app/components/Discovery/InterestingCarousel.tsx +++ b/app/components/Discovery/InterestingCarousel.tsx @@ -37,7 +37,7 @@ export const InterestingCarousel = () => { { style={{ maxWidth: "fit-content" }} > -
+
{ return ( <> +
+ + + + +
); }; From 5d2a4cbe67551a0af68ab642e759c7e4fcd2e83d Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 07:47:37 +0500 Subject: [PATCH 10/32] anix/remove: show title in navbar setting --- .../SettingsModal/SettingsModal.tsx | 42 +++---------------- app/store/preferences.ts | 3 -- 2 files changed, 5 insertions(+), 40 deletions(-) diff --git a/app/components/SettingsModal/SettingsModal.tsx b/app/components/SettingsModal/SettingsModal.tsx index 8a703b6..54a26a8 100644 --- a/app/components/SettingsModal/SettingsModal.tsx +++ b/app/components/SettingsModal/SettingsModal.tsx @@ -35,13 +35,6 @@ const BookmarksCategory = { abandoned: "Заброшено", }; -const NavbarTitles = { - always: "Всегда", - links: "Только ссылки", - selected: "Только выбранные", - never: "Никогда", -}; - const FifthButton = { favorites: "Избранное", collections: "Коллекции", @@ -178,33 +171,6 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
: ""} -
-

- Показывать название пункта в навигации -

- - {Object.keys(NavbarTitles).map( - (key: "always" | "links" | "selected" | "never") => { - return ( - - preferenceStore.setFlags({ - showNavbarTitles: key, - }) - } - > - {NavbarTitles[key]} - - ); - } - )} - -
{userStore.isAuth ?

@@ -231,7 +197,9 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => { return ( preferenceStore.setFlags({showFifthButton: key})} + onClick={() => + preferenceStore.setFlags({ showFifthButton: key }) + } > {FifthButton[key]} @@ -260,7 +228,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {

Сохранять историю просмотра

-

+

При отключении, история не будет сохранятся как локально, так и на аккаунте

@@ -283,7 +251,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {

Новый плеер

-

+

Поддерживаемые источники: Kodik, Sibnet, Libria

diff --git a/app/store/preferences.ts b/app/store/preferences.ts index bfce3af..36c9cdf 100644 --- a/app/store/preferences.ts +++ b/app/store/preferences.ts @@ -9,7 +9,6 @@ interface preferencesState { // saveSearchHistory: boolean; saveWatchHistory?: boolean; showChangelog?: boolean; - showNavbarTitles?: "always" | "links" | "selected" | "never"; showFifthButton?: null | string; }; params: { @@ -39,10 +38,8 @@ export const usePreferencesStore = create()( (set, get) => ({ _hasHydrated: false, flags: { - // saveSearchHistory: true, saveWatchHistory: true, showChangelog: true, - showNavbarTitles: "always", showFifthButton: null, }, params: { From 01e2903e7b81637cd4bab5af1a5b923ea3a5c101 Mon Sep 17 00:00:00 2001 From: Radiquum Date: Mon, 25 Aug 2025 08:00:42 +0500 Subject: [PATCH 11/32] anix/fix: navbar text on white theme --- app/components/Navbar/NavBarMobile.tsx | 2 +- app/components/Navbar/NavBarPc.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/Navbar/NavBarMobile.tsx b/app/components/Navbar/NavBarMobile.tsx index 3431566..e0be96b 100644 --- a/app/components/Navbar/NavBarMobile.tsx +++ b/app/components/Navbar/NavBarMobile.tsx @@ -66,7 +66,7 @@ export const NavBarMobile = (props: { setIsSettingModalOpen: any }) => { return ( <> -