diff --git a/content.js b/content.js index c2f2409..b0a74af 100644 --- a/content.js +++ b/content.js @@ -1,7 +1,5 @@ -console.log("[MemberFilter] content script loaded"); - -const seen = new WeakSet(); let whitelist = []; +let debugEnabled = false; /* ---------------- CSS injection ---------------- */ @@ -22,56 +20,73 @@ injectStyleOnce(); /* ---------------- load whitelist ---------------- */ -function loadWhitelist() { - chrome.storage.local.get({ whitelist: [] }, data => { +function debugLog(...args) { + if (!debugEnabled) return; + console.log("[MemberFilter]", ...args); +} + +function loadSettings() { + chrome.storage.local.get({ whitelist: [], debug: false }, data => { whitelist = data.whitelist.map(n => n.toLowerCase()); - console.log("[MemberFilter] whitelist loaded:", whitelist); + debugEnabled = Boolean(data.debug); + debugLog("settings loaded:", { whitelist, debugEnabled }); + process(); }); } -loadWhitelist(); +loadSettings(); -// Reload whitelist if popup changes it -chrome.storage.onChanged.addListener(loadWhitelist); +// Reload settings if popup changes them +chrome.storage.onChanged.addListener(loadSettings); /* ---------------- detection logic ---------------- */ +function isMemberOnly(video) { + const badges = video.querySelectorAll("badge-shape"); + for (const badge of badges) { + if (badge.textContent?.includes("Nur für Kanalmitglieder")) { + return true; + } + } + return false; +} + function process(root = document) { - const badges = root.querySelectorAll("badge-shape"); + const selector = + "ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer"; + const videos = root.querySelectorAll(selector); + const rootIsVideo = + root instanceof HTMLElement && root.matches && root.matches(selector); - badges.forEach(badge => { - if (!badge.textContent?.includes("Nur für Kanalmitglieder")) return; - - const video = badge.closest( - "ytd-rich-item-renderer, ytd-video-renderer, ytd-grid-video-renderer" - ); - - if (!video) return; - if (seen.has(video)) return; - - seen.add(video); + const allVideos = rootIsVideo ? [root, ...videos] : Array.from(videos); + allVideos.forEach(video => { const titleEl = video.querySelector("#video-title"); const channelEl = video.querySelector("ytd-channel-name a") || video.querySelector(".ytd-channel-name a"); - const title = titleEl?.textContent?.trim() ?? "(no title)"; - const url = titleEl?.href ?? "(no url)"; - const channel = channelEl?.textContent?.trim() ?? "(no channel)"; + const channel = channelEl?.textContent?.trim() ?? ""; const channelKey = channel.toLowerCase(); - const whitelisted = whitelist.includes(channelKey); + const memberOnly = isMemberOnly(video); - console.group("[MemberFilter]"); - console.log("Title :", title); - console.log("Channel:", channel); - console.log("URL :", url); - console.log("Whitelisted:", whitelisted); - console.groupEnd(); + if (debugEnabled) { + const title = titleEl?.textContent?.trim() ?? "(no title)"; + const url = titleEl?.href ?? "(no url)"; + console.group("[MemberFilter]"); + console.log("Title :", title); + console.log("Channel:", channel || "(no channel)"); + console.log("URL :", url); + console.log("MemberOnly:", memberOnly); + console.log("Whitelisted:", whitelisted); + console.groupEnd(); + } - if (!whitelisted) { + if (memberOnly && !whitelisted) { video.setAttribute("data-member-filter-hidden", "true"); + } else { + video.removeAttribute("data-member-filter-hidden"); } }); } diff --git a/popup.css b/popup.css index 038abba..d36dd96 100644 --- a/popup.css +++ b/popup.css @@ -1,14 +1,85 @@ body { - font-family: sans-serif; - min-width: 220px; + font-family: "Trebuchet MS", "Verdana", sans-serif; + min-width: 260px; + margin: 0; + padding: 12px; + background: linear-gradient(180deg, #f7f3e8, #efe6d2); + color: #2b2014; +} + +h3 { + margin: 0 0 10px; + letter-spacing: 0.4px; + text-transform: uppercase; + font-size: 13px; +} + +.row { + display: flex; + gap: 6px; + align-items: center; + margin-bottom: 8px; +} + +.row.settings { + justify-content: space-between; +} + +input { + flex: 1; + padding: 6px 8px; + border: 1px solid #cdbf9e; + border-radius: 6px; + background: #fffaf0; + font-size: 12px; +} + +button { + padding: 6px 10px; + border: 1px solid #b2985b; + border-radius: 6px; + background: #d9c18c; + color: #2b2014; + font-size: 12px; + cursor: pointer; +} + +button.ghost { + background: transparent; + border-color: #cdbf9e; +} + +button:hover { + filter: brightness(0.95); } ul { padding-left: 0; + margin: 0; + list-style: none; } li { display: flex; justify-content: space-between; margin: 4px 0; + padding: 6px 8px; + background: #fffaf0; + border: 1px solid #e2d7be; + border-radius: 6px; + font-size: 12px; +} + +li button { + padding: 2px 8px; + border-radius: 999px; + border-color: #c95a3a; + background: #f2a285; +} + +.toggle { + display: flex; + gap: 6px; + align-items: center; + font-size: 12px; } diff --git a/popup.html b/popup.html index 00455bd..038308b 100644 --- a/popup.html +++ b/popup.html @@ -8,8 +8,18 @@

Channel Whitelist

- - +
+ + +
+ +
+ + +
diff --git a/popup.js b/popup.js index bfeefe8..effdd58 100644 --- a/popup.js +++ b/popup.js @@ -1,10 +1,18 @@ const input = document.getElementById("channelInput"); const addBtn = document.getElementById("addBtn"); const list = document.getElementById("channelList"); +const debugToggle = document.getElementById("debugToggle"); +const resetBtn = document.getElementById("resetBtn"); + +const DEFAULTS = { + whitelist: [], + debug: false +}; function loadChannels() { - chrome.storage.local.get({ whitelist: [] }, ({ whitelist }) => { + chrome.storage.local.get(DEFAULTS, ({ whitelist, debug }) => { list.innerHTML = ""; + debugToggle.checked = Boolean(debug); whitelist.forEach((name, index) => { const li = document.createElement("li"); li.textContent = name; @@ -23,7 +31,7 @@ function addChannel() { const name = input.value.trim(); if (!name) return; - chrome.storage.local.get({ whitelist: [] }, ({ whitelist }) => { + chrome.storage.local.get(DEFAULTS, ({ whitelist }) => { whitelist.push(name); chrome.storage.local.set({ whitelist }, loadChannels); }); @@ -32,11 +40,21 @@ function addChannel() { } function removeChannel(index) { - chrome.storage.local.get({ whitelist: [] }, ({ whitelist }) => { + chrome.storage.local.get(DEFAULTS, ({ whitelist }) => { whitelist.splice(index, 1); chrome.storage.local.set({ whitelist }, loadChannels); }); } +function setDebug(enabled) { + chrome.storage.local.set({ debug: Boolean(enabled) }); +} + +function resetDefaults() { + chrome.storage.local.set(DEFAULTS, loadChannels); +} + addBtn.onclick = addChannel; +debugToggle.onchange = e => setDebug(e.target.checked); +resetBtn.onclick = resetDefaults; loadChannels();