diff --git a/README.md b/README.md index 95b6877..7f7befb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -[![ci](https://github.com/devsavsis/anisav/actions/workflows/ci.yml/badge.svg)](https://github.com/devsavsis/anisav/actions/workflows/ci.yml) - Я че умный? # anisav diff --git a/src/renderer/index.html b/src/renderer/index.html index 446f2db..ea49316 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -11,7 +11,7 @@ diff --git a/src/renderer/src/components/AddToListButton.tsx b/src/renderer/src/components/AddToListButton.tsx index f863ed2..d149d3f 100644 --- a/src/renderer/src/components/AddToListButton.tsx +++ b/src/renderer/src/components/AddToListButton.tsx @@ -94,8 +94,8 @@ export default function AddToListButton({ releaseId }: { releaseId: number }) { onClick={() => setOpen((v) => !v)} disabled={busy} whileTap={{ scale: 0.96 }} - className={`rounded-full px-4 py-1.5 text-sm font-semibold transition-transform ${ - collectionType ? 'bg-white/10 hover:bg-white/15' : 'bg-accent-gradient hover:scale-105' + className={`rounded-full px-4 py-1.5 text-sm font-semibold transition-colors ${ + collectionType ? 'bg-white/10 hover:bg-white/15' : 'bg-accent hover:bg-accent-hover' }`} > {collectionType ? LABELS[collectionType] : '+ Добавить в список'} @@ -103,12 +103,12 @@ export default function AddToListButton({ releaseId }: { releaseId: number }) { {open && ( setOpen(false)} - className="glass absolute left-0 top-full z-10 mt-1 w-44 origin-top overflow-hidden rounded-xl border border-white/10 shadow-xl" + className="absolute left-0 top-full z-10 mt-1 w-44 origin-top overflow-hidden rounded-lg bg-surface-card shadow-xl" > {(Object.keys(LABELS) as CollectionType[]).map((t) => ( @@ -131,7 +123,7 @@ export default function Header() { ) : ( diff --git a/src/renderer/src/components/LoginModal.tsx b/src/renderer/src/components/LoginModal.tsx index 6c2b81d..479eeb1 100644 --- a/src/renderer/src/components/LoginModal.tsx +++ b/src/renderer/src/components/LoginModal.tsx @@ -17,6 +17,7 @@ export default function LoginModal({ onClose }: { onClose: () => void }) { await login(loginValue, password, remember) onClose() } catch { + // error is surfaced via context } finally { setSubmitting(false) } @@ -32,15 +33,15 @@ export default function LoginModal({ onClose }: { onClose: () => void }) { onClick={onClose} > e.stopPropagation()} onSubmit={onSubmit} - className="my-auto max-h-[90vh] w-full max-w-sm overflow-y-auto rounded-2xl border border-white/10 bg-surface-raised p-6 shadow-2xl" + className="my-auto max-h-[90vh] w-full max-w-sm overflow-y-auto rounded-2xl bg-surface-raised p-6 shadow-2xl" > -

Вход в AniLiberty

+

Вход в AniLiberty

Используй логин и пароль своего аккаунта на aniliberty.top

@@ -71,13 +72,13 @@ export default function LoginModal({ onClose }: { onClose: () => void }) { type="checkbox" checked={remember} onChange={(e) => setRemember(e.target.checked)} - className="h-3.5 w-3.5 accent-[#FF3D5A]" + className="h-3.5 w-3.5 accent-[#fe3635]" /> Запомнить меня - {error &&

{error}

} + {error &&

{error}

}
diff --git a/src/renderer/src/components/Logo.tsx b/src/renderer/src/components/Logo.tsx index 372556a..641dbc2 100644 --- a/src/renderer/src/components/Logo.tsx +++ b/src/renderer/src/components/Logo.tsx @@ -1,17 +1,9 @@ export default function Logo({ size = 28 }: { size?: number }) { return ( - - - - - - - - - - - - + + + + ) } diff --git a/src/renderer/src/components/Player.tsx b/src/renderer/src/components/Player.tsx index 74af441..e056249 100644 --- a/src/renderer/src/components/Player.tsx +++ b/src/renderer/src/components/Player.tsx @@ -55,6 +55,7 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props setQuality(available[0]?.key) skippedRanges.current = new Set() didAutoFullscreen.current = false + // eslint-disable-next-line react-hooks/exhaustive-deps }, [episode.id]) useEffect(() => { @@ -72,6 +73,10 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props }) hls.loadSource(src) hls.attachMedia(video) + // Network/media hiccups (CDN edge blip, transient segment fetch failure) + // are fatal by default in hls.js unless the app recovers them — without + // this, a single dropped segment can stall playback or force a reload + // that jumps back to position 0 instead of resuming where it was. hls.on(Hls.Events.ERROR, (_event, data) => { if (!data.fatal) return switch (data.type) { @@ -101,6 +106,7 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props hlsRef.current?.destroy() hlsRef.current = null } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [quality, episode.id]) const reportProgress = useCallback(() => { @@ -216,10 +222,12 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props } window.addEventListener('keydown', onKey) return () => window.removeEventListener('keydown', onKey) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [duration]) useEffect(() => { return () => reportProgress() + // eslint-disable-next-line react-hooks/exhaustive-deps }, [episode.id]) return ( @@ -245,7 +253,7 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props {showSkip && (
setShowSettings(false)} - className="glass absolute bottom-full right-0 mb-2 w-64 space-y-3 rounded-xl border border-white/10 p-3 text-sm shadow-2xl" + className="absolute bottom-full right-0 mb-2 w-64 space-y-3 rounded-xl bg-surface-raised p-3 text-sm shadow-2xl" > {available.length > 1 && ( @@ -321,8 +329,8 @@ export default function Player({ episode, resumeAt, onProgress, onEnded }: Props - + {page} / {totalPages} @@ -225,7 +225,7 @@ export default function Catalog() { function FilterGroup({ title, children }: { title: string; children: React.ReactNode }) { return (
-

{title}

+

{title}

{children}
) @@ -246,7 +246,7 @@ function Check({ type="checkbox" checked={checked} onChange={onChange} - className="h-3.5 w-3.5 accent-[#FF3D5A]" + className="h-3.5 w-3.5 accent-[#fe3635]" /> {label} diff --git a/src/renderer/src/pages/Genres.tsx b/src/renderer/src/pages/Genres.tsx index ed67552..efbbd44 100644 --- a/src/renderer/src/pages/Genres.tsx +++ b/src/renderer/src/pages/Genres.tsx @@ -22,7 +22,7 @@ export default function Genres() { return (
-

Жанры

+

Жанры

-

{g.name}

+

{g.name}

{g.total_releases != null && ( -

{g.total_releases} тайтлов

+

{g.total_releases} тайтлов

)}
diff --git a/src/renderer/src/pages/History.tsx b/src/renderer/src/pages/History.tsx index 6e23bdc..c0f5acb 100644 --- a/src/renderer/src/pages/History.tsx +++ b/src/renderer/src/pages/History.tsx @@ -32,19 +32,19 @@ export default function History() { return (
-

История просмотра

+

История просмотра

{items.length === 0 &&

История пуста

}
{items.filter((item) => item.release && item.release_episode).map((item) => (

{item.release.name.main}

@@ -52,14 +52,14 @@ export default function History() { Серия {item.release_episode.ordinal} {item.release_episode.name ? ` — ${item.release_episode.name}` : ''}

-

{formatDate(item.updated_at)}

+

{formatDate(item.updated_at)}

{item.is_watched ? ( - + Просмотрено ) : ( - + В процессе )} diff --git a/src/renderer/src/pages/Home.tsx b/src/renderer/src/pages/Home.tsx index b8a4e7e..f62ca1b 100644 --- a/src/renderer/src/pages/Home.tsx +++ b/src/renderer/src/pages/Home.tsx @@ -50,16 +50,16 @@ export default function Home() { transition={{ duration: 0.5, delay: 0.15 }} className="relative mx-auto flex h-full max-w-7xl flex-col justify-end px-6 pb-8" > - + Новинка -

+

{hero.name.main}

{hero.description}

Смотреть @@ -90,13 +90,13 @@ export default function Home() { />
-

+

Серия {c.episode.ordinal}

{c.episode.duration && (
diff --git a/src/renderer/src/pages/MyLists.tsx b/src/renderer/src/pages/MyLists.tsx index 6ac84f4..2d1de78 100644 --- a/src/renderer/src/pages/MyLists.tsx +++ b/src/renderer/src/pages/MyLists.tsx @@ -34,7 +34,7 @@ export default function MyLists() { return (
-

Мои списки

+

Мои списки

{TABS.map((t) => ( @@ -49,7 +49,7 @@ export default function MyLists() { )} {t.label} diff --git a/src/renderer/src/pages/Schedule.tsx b/src/renderer/src/pages/Schedule.tsx index f3cf76f..dd76db4 100644 --- a/src/renderer/src/pages/Schedule.tsx +++ b/src/renderer/src/pages/Schedule.tsx @@ -25,11 +25,11 @@ export default function Schedule() { return (
-

Расписание выхода серий

+

Расписание выхода серий

{DAY_ORDER.filter((d) => byDay.has(d)).map((day) => (
-

+

{byDay.get(day)![0].release.publish_day?.description}

diff --git a/src/renderer/src/pages/TitleDetail.tsx b/src/renderer/src/pages/TitleDetail.tsx index b4ccfe2..88ee31c 100644 --- a/src/renderer/src/pages/TitleDetail.tsx +++ b/src/renderer/src/pages/TitleDetail.tsx @@ -43,6 +43,8 @@ export default function TitleDetail() { }, [idOrAlias]) useEffect(() => { + // Local progress always applies (no account needed) — account timecodes + // (when logged in) are layered on top since they may be synced elsewhere. const local = getAllLocalProgress() const merged = new Map( Object.entries(local).map(([id, p]) => [ @@ -114,18 +116,18 @@ export default function TitleDetail() { transition={{ duration: 0.35 }} className="min-w-0" > -

{release.name.main}

+

{release.name.main}

{release.name.english && ( -

{release.name.english}

+

{release.name.english}

)} -
+
{release.type?.description} {release.year} {release.season?.description} {release.age_rating?.label} - {release.is_ongoing && Онгоинг} - {release.episodes_total != null && {release.episodes_total} эп.} + {release.is_ongoing && Онгоинг} + {release.episodes_total != null && {release.episodes_total} эп.}
@@ -201,7 +203,7 @@ export default function TitleDetail() { )}
@@ -247,7 +249,7 @@ export default function TitleDetail() {
@@ -260,20 +262,10 @@ export default function TitleDetail() { ) } -function Chip({ - children, - accent, - mono, -}: { - children: React.ReactNode - accent?: boolean - mono?: boolean -}) { +function Chip({ children, accent }: { children: React.ReactNode; accent?: boolean }) { return ( {children} diff --git a/src/renderer/src/pages/Wishlist.tsx b/src/renderer/src/pages/Wishlist.tsx index 696ec33..6a1352a 100644 --- a/src/renderer/src/pages/Wishlist.tsx +++ b/src/renderer/src/pages/Wishlist.tsx @@ -13,8 +13,8 @@ export default function Wishlist() { return (
-

Понравилось

-

+

Понравилось

+

Локальный список на этом устройстве — не требует входа в аккаунт AniLiberty

diff --git a/tailwind.config.js b/tailwind.config.js index aa78d08..2c77fa0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -5,22 +5,17 @@ export default { extend: { colors: { accent: { - DEFAULT: '#FF3D5A', - 2: '#FF8A4C', - soft: 'rgba(255,61,90,0.16)', + DEFAULT: '#fe3635', + hover: '#ff5352', }, surface: { - DEFAULT: '#0A0A13', - raised: '#1C1C2C', - card: '#161623', + DEFAULT: '#121212', + raised: '#1a1a1a', + card: '#1e1e1e', }, }, fontFamily: { sans: ['Inter', 'Roboto', 'sans-serif'], - mono: ['"Space Mono"', 'ui-monospace', 'monospace'], - }, - backgroundImage: { - 'accent-gradient': 'linear-gradient(135deg, #FF3D5A, #FF8A4C)', }, }, },