Destructive-action safety:
- Rule-delete dialog no longer deletes on "No": clear message, "also
delete downloaded files" checkbox, real Cancel + single red Delete
- RSS bulk delete, torrent bulk delete, clear-log and notification
provider removal now behind NPopconfirm
Honest feedback and data states:
- axios interceptor gains per-request `silent` flag; background fetches
(status/log/downloader polls, passkey list) stop toasting errors
- failed downloader poll keeps last data instead of faking "no torrents";
failed first bangumi load shows error+retry instead of onboarding;
search SSE failure distinct from "no results"; RSS table loading state;
calendar refresh + provider save success toasts; wizard submit failures
show the backend reason
Setup wizard dead ends:
- downloader step no longer hard-gated on a passing connection test
(passwordless qB testable, editing fields re-arms untested state)
- inline username validation; progress persists to sessionStorage
Accessibility and touch:
- keyboard: logout button, search variant/filter chips as real buttons,
Space on card buttons, Escape closes add/edit modals, rule-list rows
focusable; visible close button on the search modal (was backdrop-only)
- air-weekday select in the rule editor — weekday assignment now works on
mobile/keyboard, not just desktop drag
- mobile nav actually fixed to the bottom (was rendering in-flow at top)
- 44px touch targets: topbar, chips, modal close, offsets, fold headers,
wizard controls (with 16px inputs to stop iOS zoom)
Performance:
- self-hosted Inter variable font replaces render-blocking Google Fonts
- lazy poster loading on the landing grid; log page bounded to newest
1000 lines; KeepAlive capped at 3 pages
Design tokens: new warning bg/border/text tokens (light+dark) replace
hard-coded ambers; add-RSS and notification config use NSwitch/NSelect
instead of hand-rolled controls; ab-data-list selection is controllable
(mobile RSS checkboxes no longer desync after bulk actions).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs