Schedule pickers, and target progress at one row

"Check feeds every" becomes a number plus a unit dropdown in both global
and per-feed settings; parse_interval gained weeks to back it. The
per-feed dropdown can select the global default, clearing the override.

Fixes progress painting every pending row: the event carried no enclosure
id, so the handler had nothing to target and set the width on all of them.
Adding a feed looked like it was downloading everything. Progress,
DownloadDone and DownloadError now carry the enclosure id.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
This commit is contained in:
2026-09-10 02:38:14 +00:00
parent 9960befed5
commit e97f2b9c2f
8 changed files with 155 additions and 30 deletions

View File

@@ -154,6 +154,8 @@ struct FeedRow {
auto_download: bool,
max_new_per_check: Option<usize>,
schedule: Option<String>,
/// The feed's own override in minutes, so the UI need not re-parse the string.
schedule_mins: Option<u64>,
/// Effective schedule in minutes, after the global default and the feed's <ttl>.
every_mins: u64,
last_checked: Option<i64>,
@@ -181,6 +183,10 @@ async fn feeds(State(state): State<WebState>) -> Result<Json<Vec<FeedRow>>, ApiE
auto_download: feed.auto_download,
max_new_per_check: feed.max_new_per_check,
schedule: feed.schedule.clone(),
schedule_mins: feed
.schedule
.as_deref()
.and_then(crate::config::parse_interval),
every_mins: crate::due_after(&cfg, feed, st.ttl_mins) / 60,
last_checked: s.last_checked,
next_check: s