Implement UI improvements and download management features

- Switch to light mode with black and white color scheme
- Simplify channel subscription to use channel ID only instead of RSS URL
- Add Downloads page to track all video download jobs
- Fix Flask-Login session management bug in user loader
- Always filter YouTube Shorts from feeds (case-insensitive)
- Fix download service video URL attribute error
- Fix watch page enum comparison for download status display

UI Changes:
- Update CSS to pure black/white/grayscale theme
- Remove colored text and buttons
- Use underlines for hover states instead of color changes
- Improve visual hierarchy with grayscale shades

Channel Subscription:
- Accept channel ID directly instead of full RSS URL
- Add validation for channel ID format (UC/UU prefix)
- Update help text and examples for easier onboarding

Downloads Page:
- New route at /downloads showing all video download jobs
- Display status, progress, and metadata for each download
- Sortable by status (downloading, pending, failed, completed)
- Actions to download, retry, or watch videos
- Responsive grid layout with thumbnails

Bug Fixes:
- Fix user loader to properly use database session context manager
- Fix download service accessing wrong attribute (link → video_url)
- Fix watch page template enum value comparisons
- Fix session detachment issues when accessing channel data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-26 15:36:26 -05:00
parent 067926e80d
commit acb2ec0654
10 changed files with 296 additions and 80 deletions

View File

@@ -5,12 +5,12 @@
{% block content %}
<div class="watch-page">
<div class="video-player-container">
{% if video.download_status == 'completed' and video.download_path %}
{% if video.download_status.value == 'completed' and video.download_path %}
<video controls class="video-player">
<source src="/api/video/stream/{{ video.id }}" type="video/mp4">
Your browser does not support the video tag.
</video>
{% elif video.download_status == 'downloading' %}
{% elif video.download_status.value == 'downloading' %}
<div class="video-placeholder">
<div class="placeholder-content">
<h3>Video is downloading...</h3>
@@ -18,7 +18,7 @@
<button class="btn btn-secondary" onclick="location.reload()">Refresh</button>
</div>
</div>
{% elif video.download_status == 'failed' %}
{% elif video.download_status.value == 'failed' %}
<div class="video-placeholder error">
<div class="placeholder-content">
<h3>Download failed</h3>
@@ -49,7 +49,7 @@
</div>
<div class="video-stats">
<span class="publish-date">Published: {{ video.published_at.strftime('%B %d, %Y') }}</span>
{% if video.download_status == 'completed' and video.download_completed_at %}
{% if video.download_status.value == 'completed' and video.download_completed_at %}
<span class="download-date">Downloaded: {{ video.download_completed_at.strftime('%B %d, %Y') }}</span>
{% endif %}
</div>
@@ -64,7 +64,7 @@
<div class="video-links">
<a href="{{ video.video_url }}" target="_blank" class="btn btn-link">Watch on YouTube</a>
{% if video.download_status == 'completed' and video.download_path %}
{% if video.download_status.value == 'completed' and video.download_path %}
<a href="/api/video/stream/{{ video.id }}?download=1" class="btn btn-secondary" download>Download MP4</a>
{% endif %}
</div>
@@ -103,7 +103,7 @@
}
// Auto-refresh if video is downloading
{% if video.download_status == 'downloading' %}
{% if video.download_status.value == 'downloading' %}
setTimeout(() => location.reload(), 10000); // Refresh every 10 seconds
{% endif %}
</script>