Phase 3: HTMX & Alpine.js integration, router refactoring, and UI modernization
- Modernized the frontend with HTMX for server-driven UI and Alpine.js for client state. - Refactored anime, player, and recommendation logic into modular routers. - Updated README.md to reflect the latest project state and technologies (v2.4). - Added Plyr.io for an improved streaming experience. - Improved project structure with componentized templates. - Added Playwright and Vitest configuration for frontend testing.
This commit is contained in:
@@ -176,16 +176,20 @@ async def search_anime_unified(
|
||||
|
||||
@router.get("/series/search")
|
||||
async def search_series_unified(
|
||||
request: Request,
|
||||
q: str,
|
||||
lang: str = "vf",
|
||||
html: bool = Query(False),
|
||||
):
|
||||
"""
|
||||
Search across all TV series providers (FS7, etc.)
|
||||
Returns HTML for HTMX requests or if html=True parameter is set.
|
||||
"""
|
||||
import asyncio
|
||||
from app.downloaders.series_sites import FS7Downloader
|
||||
|
||||
print(f"\n[SERIES SEARCH] Starting search for '{q}' in {lang}")
|
||||
print(f"\n[SERIES SEARCH] Starting search for '{q}' in {lang}. html={html}")
|
||||
start_time = time.time()
|
||||
results = {}
|
||||
series_downloaders = {"fs7": FS7Downloader()}
|
||||
search_tasks = []
|
||||
@@ -205,6 +209,17 @@ async def search_series_unified(
|
||||
elif result:
|
||||
results[provider_id] = result
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
total_found = sum(len(r) for r in results.values())
|
||||
print(f"[SERIES SEARCH] Finished in {elapsed:.2f}s. Found {total_found} results. HX-Request={request.headers.get('HX-Request')}")
|
||||
|
||||
# Return HTML for HTMX or JSON for API
|
||||
if html or request.headers.get("HX-Request"):
|
||||
return templates.TemplateResponse(
|
||||
"components/series_search_results.html",
|
||||
{"request": request, "results": results}
|
||||
)
|
||||
|
||||
return {"query": q, "lang": lang, "results": results}
|
||||
|
||||
|
||||
@@ -224,12 +239,38 @@ async def get_anime_metadata(url: str):
|
||||
|
||||
@router.get("/anime/episodes")
|
||||
async def get_anime_episodes(
|
||||
request: Request,
|
||||
url: str,
|
||||
lang: str = "vostfr",
|
||||
html: bool = Query(False),
|
||||
):
|
||||
"""Get list of episodes for an anime"""
|
||||
"""
|
||||
Get list of episodes for an anime.
|
||||
Returns HTML for HTMX requests or JSON for API.
|
||||
"""
|
||||
downloader = get_downloader(url)
|
||||
episodes = await downloader.get_episodes(url, lang)
|
||||
|
||||
if html or request.headers.get("HX-Request"):
|
||||
# Extract title from first episode or URL for the display
|
||||
anime_title = "Épisodes"
|
||||
if episodes and len(episodes) > 0:
|
||||
# Try to get a cleaner title from the first episode if available
|
||||
first_ep = episodes[0]
|
||||
if "|" in first_ep.get("url", ""):
|
||||
anime_title = first_ep.get("url").split("|")[-1].split(" - ")[0]
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"components/episode_list.html",
|
||||
{
|
||||
"request": request,
|
||||
"episodes": episodes,
|
||||
"anime_url": url,
|
||||
"anime_title": anime_title,
|
||||
"lang": lang
|
||||
}
|
||||
)
|
||||
|
||||
return {"url": url, "lang": lang, "episodes": episodes}
|
||||
|
||||
|
||||
@@ -243,6 +284,7 @@ async def get_anime_providers_list():
|
||||
async def download_anime_episode(
|
||||
url: str,
|
||||
background_tasks: BackgroundTasks,
|
||||
response: Response,
|
||||
episode: str | None = None,
|
||||
download_manager: DownloadManager = Depends(get_download_manager),
|
||||
):
|
||||
@@ -253,6 +295,10 @@ async def download_anime_episode(
|
||||
request = DownloadRequest(url=url)
|
||||
task = download_manager.create_task(request)
|
||||
background_tasks.add_task(download_manager.start_download, task.id)
|
||||
|
||||
# Add toast notification for HTMX
|
||||
response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": f"Téléchargement lancé : {task.filename}", "type": "success"}})
|
||||
|
||||
return {"task_id": task.id, "task": task}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user