Enhance comment viewer + make SponsorBlock configurable (3.6 + parity)
Comment viewer (web UI): the flat tree gains search (highlight + keep ancestor context), sort (threaded / top / newest / oldest), per-thread collapse/expand with collapse-all/expand-all, an OP badge for the uploader, and a "new since last visit" highlight + count (localStorage per-video timestamp). API now returns each comment's `timestamp` and `author_is_uploader`. SponsorBlock: was a hardcoded `--sponsorblock-mark all`. Now a real setting (off / mark / remove) with a per-channel override, threaded through the full five touchpoints — config `[backup].sponsorblock_mode` (default "mark", preserving prior behavior), DownloadOptions override, a downloader resolver (apply_sponsorblock), and both UIs (egui Settings + channel dialog; web Settings modal + channel dialog + SettingsPayload). Integration tests extended: settings round-trip asserts the sponsorblock default + persistence; channel-options round-trip asserts the override. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
6f174f703b
commit
3031b5b0e5
7 changed files with 219 additions and 20 deletions
|
|
@ -207,6 +207,7 @@ fn settings_roundtrip_and_persist() {
|
|||
let (code, body) = s.get("/api/settings");
|
||||
assert_eq!(code, 200);
|
||||
assert_eq!(field(&body, "convert_mode"), Some(""), "default convert off");
|
||||
assert_eq!(field(&body, "sponsorblock_mode"), Some("mark"), "default sponsorblock = mark");
|
||||
|
||||
// Flip a few global settings.
|
||||
let (code, _) = s.post("/api/settings", r#"{
|
||||
|
|
@ -214,6 +215,7 @@ fn settings_roundtrip_and_persist() {
|
|||
"max_concurrent":5,"use_bundled_ytdlp":false,"use_pot_provider":false,
|
||||
"subtitles_enabled":true,"subtitles_auto":false,"subtitles_embed":true,
|
||||
"subtitle_langs":"en","subtitle_format":"srt","youtube_player_clients":"tv,mweb",
|
||||
"sponsorblock_mode":"remove",
|
||||
"convert_mode":"h264-mp4","convert_crf":28,"convert_preset":"fast",
|
||||
"convert_audio_format":"","convert_keep_original":true
|
||||
}"#);
|
||||
|
|
@ -224,12 +226,14 @@ fn settings_roundtrip_and_persist() {
|
|||
assert_eq!(field(&body, "convert_mode"), Some("h264-mp4"));
|
||||
assert_eq!(field(&body, "convert_crf"), Some("28"));
|
||||
assert_eq!(field(&body, "youtube_player_clients"), Some("tv,mweb"));
|
||||
assert_eq!(field(&body, "sponsorblock_mode"), Some("remove"));
|
||||
assert_eq!(field(&body, "subtitle_format"), Some("srt"));
|
||||
|
||||
// …and so does config.toml on disk.
|
||||
let cfg = std::fs::read_to_string(s.dir.join("config.toml")).unwrap();
|
||||
assert!(cfg.contains("mode = \"h264-mp4\""), "config persisted convert mode:\n{cfg}");
|
||||
assert!(cfg.contains("youtube_player_clients = \"tv,mweb\""), "config persisted clients");
|
||||
assert!(cfg.contains("sponsorblock_mode = \"remove\""), "config persisted sponsorblock");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -288,12 +292,13 @@ fn channel_options_roundtrip_and_clear() {
|
|||
// Store an override.
|
||||
let (code, _) = s.post(
|
||||
"/api/channels/channels/SomeChannel/options",
|
||||
r#"{"convert_mode":"audio","youtube_player_clients":"tv","subtitles_enabled":false}"#,
|
||||
r#"{"convert_mode":"audio","youtube_player_clients":"tv","sponsorblock_mode":"off","subtitles_enabled":false}"#,
|
||||
);
|
||||
assert_eq!(code, 200);
|
||||
let (_, opts) = s.get("/api/channels/channels/SomeChannel/options");
|
||||
assert_eq!(field(&opts, "convert_mode"), Some("audio"));
|
||||
assert_eq!(field(&opts, "youtube_player_clients"), Some("tv"));
|
||||
assert_eq!(field(&opts, "sponsorblock_mode"), Some("off"));
|
||||
|
||||
// An all-default body hits the is_empty() delete path → back to defaults.
|
||||
let (code, _) = s.post("/api/channels/channels/SomeChannel/options", r#"{}"#);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue