Commit Graph
17 Commits
Author SHA1 Message Date
jozamudi 2752d49411 fix: "view all" link pointed at /history path (404); use ?history query 2026-08-23 21:28:24 +00:00
jozamudi 50d30a8d3f ui: default to sub (jpn) instead of dub for playback 2026-08-23 21:28:24 +00:00
jozamudi bb1297f8e2 ui: watched-episode state (dimmed + check, next-up highlight), favicon 2026-08-19 18:49:29 +00:00
jozamudi 98fb4e5461 features: auto-next w/ 5s countdown, prev/next, playback speed, hide fillers, recent searches 2026-08-19 18:41:13 +00:00
jozamudi 2ec0f8a034 ui: loading states, player failure overlay + retry, toasts, back nav, full history page with delete
Bundle 1-4+7 from PLAN.md: skeleton loaders, player Loading/Buffering/fatal overlay with Retry, action toasts, back-to-home crumb + logo fix, ?history full-history view with per-entry delete (GET /api/history?all=1, DELETE /api/history). 14/14 tests green.
2026-08-19 18:20:42 +00:00
jozamudi 0a86e70a54 fix: backfill posters for ALL history entries; skip <img> when no poster
- backfill script deduped by slug_id, so a second entry for the same
  anime kept no poster -> rendered as a broken <img src="">
- re-backfilled from the already-fetched poster per slug
- showHome now only emits an <img> when the entry has a poster
2026-08-19 17:32:58 +00:00
jozamudi 2efb537edc home polish: continue-watching hero, progress bars, posters, time-ago
- showHome(): most recent entry renders as a hero card (poster,
  episode/lang/position, progress bar, Resume); the rest become
  mini poster cards with progress + relative timestamp
- history entries now persist dur (video.duration) and poster;
  /api/anime returns poster (parsed from the details page)
- old entries without dur render without a bar (backward compatible)
- browser test asserts the seeded entry, not a section header that
  only existed via a cross-test side effect
2026-08-19 17:01:04 +00:00
jozamudi e0f5427002 ui: move logout into the hamburger menu too 2026-08-19 16:42:34 +00:00
jozamudi 1fb6db475c ui: hide delete-account behind a header hamburger menu 2026-08-19 16:41:11 +00:00
jozamudi 7e6db5a41c frontend: prefix-agnostic fetch paths (reverse-proxy subpath safe)
login.html/app.js now resolve fetch targets relative to the page's
directory (BASE), so the app works served at / or under a path prefix
(https://host/ani/) as long as the proxy strips the prefix.
2026-08-19 16:24:22 +00:00
jozamudi c697500c7d multi-user auth (CLI-created accounts), per-user history, test suite
- server/users.py replaces credentials.py: users.json (0600), PBKDF2,
  one-time migration of the legacy single password to user admin
  (history.json -> history/admin.json)
- accounts are CLI-managed only: python -m server.users add|rm|list
  (no self-signup on an internet-exposed app); /signup route removed,
  login page back to username + password
- per-user 30-day signed session cookie (payload carries the
  username), per-user lockout, GET /api/me, POST /account/delete
- per-user watch history: server/data/history/<user>.json; ANIWEB_DATA
  env override for the data dir
- header chip: logged-in user, logout, delete account
- tests/: throwaway-server suite (port 8399, temp data dir) — 9 HTTP
  tests + 2 Playwright browser tests (login UI, real video playback
  behind auth); runs via python tests/run.py
2026-08-19 16:17:56 +00:00
jozamudi 76c45a8f29 single-user login screen
- server/credentials.py: PBKDF2 password + session secret, 0600 json,
  one-time setup command (server refuses to start without it)
- app.py: signed 30-day cookie (itsdangerous), middleware 401s API /
  redirects pages to /login?next=, 5-fail/15-min lockout, /logout
- static/login.html: dark-themed form, inline error display
- app.js: api() 401 -> redirect to /login preserving current URL
- docs: README quick start + features, SPEC auth section
2026-08-19 15:54:50 +00:00
jozamudi a8426b5922 server-persisted watch history with position + resume
- POST/GET /api/history: JSON file in data/history.json (50 entries
  kept, top 5 shown on home), upsert per (anime, episode)
- watch position saved every ~10s of playback + on pause/unload
- resume: opening an anime seeks to the saved position unless
  >=95% through (then starts fresh); position shown on home items
- drops localStorage; server is the source of truth (verified:
  fresh watch -> new session resumes at saved pos -> home lists it)
2026-08-19 15:28:00 +00:00
jozamudi 32f93c0f65 autoplay first episode by default, resume watched
- no ?ep= param: resume last watched ep of the season from history,
  else start at ep 1 (verified in headless Chromium, no click needed)
- if the browser blocks autoplay (no user gesture yet), show a
  'click to play' overlay instead of a silent black screen
2026-08-19 15:21:15 +00:00
jozamudi a3a58e7d3c ui: no-store cache headers, synopsis below episode grid
- no-store on everything except /stream: stale cached app.js (old CDN
  hls.js ref) was the cause of the black screen — video plays fine in a
  real Chromium once the fresh JS loads (verified via playwright)
- synopsis moved under the episode grid
2026-08-19 15:18:14 +00:00
jozamudi 6c752ae5bc fix playback: vendor hls.js locally, surface stream/API errors visibly
- jsdelivr CDN was a silent single point of failure (Hls undefined ->
  unhandled rejection -> black screen with no feedback)
- play() now catches API errors; hls fatal + video media errors render
  'Stream error: ...' under the player
- server now binds 0.0.0.0 (LAN access); was 127.0.0.1 only
2026-08-19 15:13:51 +00:00
jozamudi e4dde86d85 ani-web: FastAPI + HLS proxy over anidb.app, vanilla UI
- upstream.py: Cloudflare-proof fetchers (curl_cffi), self-checking
- app.py: /api/* routes + /stream/{token} HLS proxy (CDN has no CORS)
- static/: search -> detail/seasons/episodes -> hls.js player, history
- verified end-to-end: search chainsaw man -> ep1 dub 1080p segment
2026-08-19 15:06:43 +00:00