feat: channel blocklist, search duration filter, feed-wide live filtering #51
Loading…
Reference in a new issue
No description provided.
Delete branch "refs/pull/51/head"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Three gaps found while surveying the existing ~90 settings, plus the audit follow-up from #50. No version bump — nothing is being packaged in this PR, so the CHANGELOG entry sits under
## Unreleased.Channel blocklist (Dashboard → Blocked channels)
There genuinely was no way to block a channel. The only workaround was the Keyword Blocklist, which matches title and channel in a single string — so blocking a channel called "Vox" also hid every video with "vox" anywhere in its title. That's why it felt like the feature existed: typing a channel name mostly works, right up until a title collision eats something unrelated.
This matches the channel itself via name,
@handle, or URL, reusing the existinggetFeedItemChannelIdentifiers()resolution. It applies everywhere including search — a blocked channel is an explicit "never show me this", not a feed-tidiness preference — and wins over the Trusted channels allowlist if a channel somehow lands on both.Search duration filter (off by default)
A range control above the search results: "videos between 30 and 45 minutes", which YouTube's own filter cannot express — it offers only under 4 min, 4–20 min, or over 20 min.
Search-only, deliberately. As a standing home-feed rule a narrow band would hide almost the entire feed; a range like 30–45 is a discovery query, not a preference. Duration comes from the thumbnail time badge, which is numeric and language-independent — no relative-date guessing and no localization problem. Items with no duration (live, upcoming, playlists, channel rows) are never hidden.
Live / premiere / upcoming on every feed
These were CSS-scoped to
ytd-browse[page-subtype="subscriptions"]. Moved to Home & Feeds → Feed filtering, labels now read "(all feeds)".⚠️ Behaviour change: anyone who already has either toggle on will now have those videos hidden everywhere, not just on Subscriptions. That matches the intent of the setting, but it is a change on upgrade. Storage keys keep their historical
hideSubscriptions*names so existing synced settings need no migration — the mismatch between key name and scope is documented at both the CSS and the settings definition.Audit + tests (60 → 68)
Added the single-selector features to the audit registry: watched-progress (which hangs off
.ytThumbnailOverlayProgressBarHostWatchedProgressBarSegment, one long private class name), the duration badge, the live/upcoming overlays, and the search results host.Fixed a TDZ crash I introduced: the audit registry referenced selector constants declared after it in
defaults.js, which would have thrown on load in the browser and taken the whole content script down.node --checkpasses on that file happily — it only surfaced because I ran it. Worth remembering that syntax-checking a file proves very little about load order.The audit test also caught the DOM fixture being unrepresentative twice — first no video titles, then no duration badges. An unrepresentative fixture is worse than no fixture, so that guard is doing real work.
Review notes
applyMembershipFeedFiltersnow skips elements the blocklist already claimed, otherwise the second key recordsdisplay: noneas the element's "original" and the item never comes back. Same class of bug as in #49.ytd-search ytd-section-list-renderer→ytd-search→#page-managerif YouTube reshuffles the search chrome, and is in the audit registry.Test plan
npm test— 68/68node --checkon every touched script, plus actually loadingdefaults.js(which is what caught the TDZ)__CW_AUDIT_SELECTORS__()on home, watch and searchUpdate — this PR now also cuts the release and refreshes the site download.
The original description said "no version bump — nothing is being packaged in this PR". That is no longer accurate; please read this comment as superseding it.
Added in
1083fcc:manifest.json+package.json. Minor bump because this branch adds user-facing features (channel blocklist, search duration filter, feed-wide live filtering), matching the 1.15.0 → 1.16.0 convention for SponsorBlock. Without it the download would have gone out labelled 1.17.0 while containing features 1.17.0 does not have — same version string, different contents.## Unreleased→## 1.18.0.website/downloads/cleanwatch-latest.ziprebuilt vianpm run build:store.Zip verified: manifest reports
1.18.0, 30 files,manifest.jsonat the zip root, byte-identical toCleanWatch-store-upload.zip, and notest/,node_modules/,website/,package*.json,scripts/or.DS_Storeleakage.No website markup changes were needed —
index.htmllinks the fixed path/downloads/cleanwatch-latest.zip, so the refreshed file is picked up automatically.npm teststill 68/68. The manual browser checks in the test plan above remain outstanding.