[3.2] - 2025-01
Backend
Features
- Added WebAuthn Passkey passwordless login support
- Register, authenticate, and manage Passkey credentials
- Multi-device credential backup detection (iCloud Keychain, etc.)
- Clone attack protection (sign_count verification)
- Authentication strategy pattern unifying password and Passkey login interfaces
- Usernameless login support via discoverable credentials (resident keys)
- Added season/episode offset auto-detection
- Analyzes TMDB episode air dates to detect "virtual seasons" (e.g., Frieren S1 split into two parts)
- Auto-identifies different parts when broadcast gap exceeds 6 months
- Calculates episode offset (e.g., RSS shows S2E1 ā TMDB S1E29)
- Background scan thread automatically detects offset issues in existing subscriptions
- New API endpoints:
POST /bangumi/detect-offset,PATCH /bangumi/dismiss-review/{id}
- Added bangumi archive functionality
- Manual archive/unarchive support
- Auto-archive completed series
- New API endpoints:
PATCH /bangumi/archive/{id},PATCH /bangumi/unarchive/{id},GET /bangumi/refresh/metadata
- Added search provider configuration API
GET /search/provider/config- Get search provider configPUT /search/provider/config- Update search provider config
- Added RSS connection status tracking
- Records
connection_status(healthy/error),last_checked_at, andlast_errorafter each refresh
- Records
- Added first-run setup wizard
- 7-step guided configuration: account, downloader, RSS source, media path, notifications
- Downloader connection test, RSS source validation
- Optional steps can be skipped and configured later in settings
- Sentinel file mechanism (
config/.setup_complete) prevents re-triggering - Unauthenticated setup API (only available on first run, returns 403 after completion)
- Added calendar view with Bangumi.tv broadcast schedule integration
- Added downloader API and management interface
- Full async migration
- Database layer async support (aiosqlite) for non-blocking I/O in Passkey operations
UserDatabasesupports both sync/async modes for backward compatibilityDatabasecontext manager supports bothwith(sync) andasync with(async)- RSS engine, downloader, checker, and parser fully converted to async
- Network requests migrated from
requeststohttpx(AsyncClient)
- Backend migrated to
uvpackage manager (pyproject.toml + uv.lock) - Server startup uses background tasks to avoid blocking (fixes #891, #929)
- Database migration auto-fills NULL values with model defaults
- Database adds
needs_reviewandneeds_review_reasonfields for offset detection
Performance
- Shared HTTP client connection pool, reuses TCP/SSL connections
- RSS refresh now concurrent (
asyncio.gather), ~10x faster with multiple sources - Torrent file download now concurrent, ~5x faster for multiple torrents
- Rename module concurrent file list fetching, ~20x faster
- Notification sending now concurrent, removed 2-second hardcoded delay
- Added TMDB and Mikan parser result caching to avoid duplicate API calls
- Database indexes added for
Torrent.url,Torrent.rss_id,Bangumi.title_raw,Bangumi.deleted,RSSItem.url - RSS batch enable/disable uses single transaction instead of per-item commits
- Pre-compiled regex patterns for torrent name parsing and filter matching
SeasonCollectorcreated outside loops, reuses single authentication- RSS parsing deduplication changed from O(n²) list lookup to O(1) set lookup
Episode/SeasonInfodataclasses use__slots__for reduced memory footprint
Changes
- Upgraded WebAuthn dependency to py_webauthn 2.7.0
_get_webauthn_from_requestprioritizes browser Origin header, fixing verification issues in cross-port development environmentsauth_userandupdate_user_infoconverted to async functionsTitleParser.tmdb_parserconverted to async functionRSSEnginemethods fully async (pull_rss,refresh_rss,download_bangumi,add_rss)Checker.check_downloaderconverted to async functionProgramStatusmigrated from threading to asyncio (Event, Lock)
Bugfixes
- Fixed downloader connection check with max retry limit
- Fixed transient network errors when adding torrents with retry logic
- Fixed multiple issues in search and subscription flow
- Improved torrent fetch reliability and error handling
- Fixed
aaguidtype error (nowstrin py_webauthn 2.7.0, no longerbytes) - Fixed missing
credential_backup_eligiblefield (replaced withcredential_device_type) - Fixed
verify_authentication_responsereceiving invalidcredential_idparameter causing TypeError - Fixed program startup blocking the server (fixes #891, #929, #886, #917, #946)
- Fixed search interface export not matching component expectations
- Fixed poster endpoint path check incorrectly intercepting all requests (fixes #933, #934)
- Fixed OpenAI parser security issue
- Fixed database tests using async sessions with sync code mismatch
- Fixed config field conflicts when upgrading from 3.1.x to 3.2 causing settings loss (fixes #956)
program.sleep_time/program.timesauto-migrated torss_time/rename_time- Removed deprecated
rss_parserfields (type,custom_url,token,enable_tmdb) - Fixed
ENV_TO_ATTRenvironment variable mapping pointing to non-existent model fields - Fixed
DEFAULT_SETTINGSinconsistency with current config model
- Fixed version upgrade migration logic errors (all upgrades calling 3.0ā3.1 migration)
- Added version-aware migration dispatch based on source version
- Added
from_31_to_32()migration function for database schema changes
Frontend
Features
- Complete UI design system redesign
- Unified design tokens (colors, fonts, spacing, shadows, animations)
- Light/dark theme toggle support
- Comprehensive accessibility support (ARIA, keyboard navigation, focus management)
- Responsive layout for mobile devices
- Added first-run setup wizard page
- Multi-step wizard component (progress bar + step navigation)
- Route guard auto-detection and redirect to setup page
- Downloader/RSS/notification connection test feedback
- Chinese and English i18n support
- Added Passkey management panel (settings page)
- WebAuthn browser support detection
- Automatic device name identification
- Passkey list display and deletion
- Added Passkey fingerprint login button on login page (supports usernameless login)
- Added calendar view page
- Added downloader management page
- Added Bangumi card hover overlay (showing title and tags)
- Added
resolvePosterUrlutility function for unified external URL and local path handling (fixes #934) - Redesigned search panel with modal and filter system
- Redesigned login panel with modern glassmorphism style
- Added log level filter in log view
- Redesigned LLM settings panel (fixes #938)
- Redesigned settings, downloader, player, and log page styles
- Added search provider settings panel
- View, add, edit, delete search sources in UI
- Default sources (mikan, nyaa, dmhy) cannot be deleted
- URL template validation ensures
%splaceholder
- Added iOS-style notification badge system
- Yellow badge + purple border for subscriptions needing review
- Combined display support (e.g.,
! | 2for warning + multiple rules) - Yellow glow animation on cards needing attention
- Edit modal warning banner with one-click auto-detect and dismiss
- Rule selection modal highlights rules with warnings
- Calendar page bangumi grouping: same anime with multiple rules merged, click to select specific rule
- Bangumi list page collapsible "Archived" section
- Bangumi list page skeleton loading animation
- Rule editor episode offset field with "Auto Detect" button
- RSS management page connection status labels: green "Connected" when healthy, red "Error" with tooltip for details
- New mobile-first responsive design
- Three-tier breakpoint system: mobile (<640px), tablet (640-1023px), desktop (ā„1024px)
- Mobile bottom navigation bar (with icons and text labels)
- Tablet mini sidebar (56px icon navigation)
- Mobile popups automatically switch to bottom sheets
- Pull-to-refresh support
- Horizontal swipe container support
- Mobile card list replacing data tables (RSS page)
- CSS Grid responsive layout (Bangumi card grid)
- Form labels stack vertically on mobile, full-width inputs
- Touch targets minimum 44px, meeting accessibility standards
- Safe area support (notched devices)
100dvhdynamic viewport height (fixes mobile browser address bar issue)viewport-fit=coverfor full-screen devices
New Components
ab-bottom-sheetā Touch-driven bottom sheet component (drag to close, max height limit)ab-adaptive-modalā Adaptive modal (bottom sheet on mobile / centered dialog on desktop)ab-pull-refreshā Pull-to-refresh wrapper componentab-swipe-containerā Horizontal swipe container (CSS scroll-snap)ab-data-listā Mobile-friendly card list (replacing NDataTable)ab-mobile-navā Enhanced bottom navigation bar (icon + label + active indicator)useSafeAreaā Safe area composable
Performance
- Downloader store uses
shallowRefinstead ofrefto avoid deep reactive proxy on large arrays - Table column definitions moved to
computedto avoid rebuilding on each render - RSS table columns separated from data, column config not rebuilt on data changes
- Calendar page removed duplicate
getAll()calls ab-selectwatchEffectchanged towatch, eliminates invalid emit on mountuseClipboardhoisted to store top level, avoids creating new instance on eachcopy()setIntervalreplaced withuseIntervalFnfor automatic lifecycle management
Changes
- Refactored search logic, removed rxjs dependency
- Search store export refactored to match component expectations
- Upgraded frontend dependencies
- Breakpoint system expanded from single 1024px to 640px + 1024px two-tier
useBreakpointQueryaddedisTablet,isMobileOrTablet,isTabletOrPCmedia-query.vueadded#tabletslot (falls back to#mobile)- UnoCSS added
sm: 640pxbreakpoint ab-inputmobile full-width + increased touch target styling- Layout uses
dvhunits instead ofvh, supports safe-area-inset - Fixed calendar page unknown column width
- Unified action bar button sizes in downloader page
CI/Infrastructure
- CI added build test on PR open (dev branch PRs to main auto-trigger build)
- CI upgraded
actions/upload-artifactandactions/download-artifactto v4 - Docker build removed
linux/arm/v7platform (uv image doesn't support it) - Added CLAUDE.md development guide