131 lines
3.9 KiB
JavaScript
131 lines
3.9 KiB
JavaScript
// UI elements.
|
|
const input = document.getElementById("channelInput");
|
|
const linkInput = document.getElementById("channelLinkInput");
|
|
const addBtn = document.getElementById("addBtn");
|
|
const maxInput = document.getElementById("maxInput");
|
|
const saveMaxBtn = document.getElementById("saveMaxBtn");
|
|
const addError = document.getElementById("addError");
|
|
const clearArchiveBtn = document.getElementById("clearArchiveBtn");
|
|
const clearWhitelistBtn = document.getElementById("clearWhitelistBtn");
|
|
const list = document.getElementById("channelList");
|
|
const debugToggle = document.getElementById("debugToggle");
|
|
const resetBtn = document.getElementById("resetBtn");
|
|
|
|
// Default settings payload.
|
|
const DEFAULTS = {
|
|
whitelist: [],
|
|
debug: false,
|
|
maxArchive: 200
|
|
};
|
|
|
|
// Render whitelist and debug state.
|
|
function loadChannels() {
|
|
chrome.storage.local.get(DEFAULTS, ({ whitelist, debug, maxArchive }) => {
|
|
list.innerHTML = "";
|
|
debugToggle.checked = Boolean(debug);
|
|
maxInput.value = String(maxArchive);
|
|
const entries = normalizeWhitelist(whitelist);
|
|
entries.forEach((entry, index) => {
|
|
const li = document.createElement("li");
|
|
const text = entry.handle
|
|
? `${entry.name} (@${entry.handle})`
|
|
: entry.name;
|
|
li.textContent = text;
|
|
|
|
const remove = document.createElement("button");
|
|
remove.textContent = "x";
|
|
remove.onclick = () => removeChannel(index);
|
|
|
|
li.appendChild(remove);
|
|
list.appendChild(li);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Add a new whitelist entry with name + handle.
|
|
function addChannel() {
|
|
const name = input.value.trim();
|
|
const link = linkInput.value.trim();
|
|
if (!name || !link) {
|
|
addError.textContent = "Need both name + @handle/link.";
|
|
return;
|
|
}
|
|
const handle = normalizeHandle(link);
|
|
if (!handle) {
|
|
addError.textContent = "Invalid link or @handle.";
|
|
return;
|
|
}
|
|
addError.textContent = "";
|
|
|
|
chrome.storage.local.get(DEFAULTS, ({ whitelist }) => {
|
|
const entries = normalizeWhitelist(whitelist);
|
|
entries.push({ name, handle });
|
|
chrome.storage.local.set({ whitelist: entries }, loadChannels);
|
|
});
|
|
|
|
input.value = "";
|
|
linkInput.value = "";
|
|
}
|
|
|
|
// Normalize storage entries to { name, handle } objects.
|
|
function normalizeWhitelist(whitelist) {
|
|
return (whitelist || []).map(item => {
|
|
if (typeof item === "string") {
|
|
return { name: item, handle: "" };
|
|
}
|
|
return { name: item.name || "", handle: item.handle || "" };
|
|
});
|
|
}
|
|
|
|
// Remove a whitelist entry by index.
|
|
function removeChannel(index) {
|
|
chrome.storage.local.get(DEFAULTS, ({ whitelist }) => {
|
|
const entries = normalizeWhitelist(whitelist);
|
|
entries.splice(index, 1);
|
|
chrome.storage.local.set({ whitelist: entries }, loadChannels);
|
|
});
|
|
}
|
|
|
|
// Persist debug toggle.
|
|
function setDebug(enabled) {
|
|
chrome.storage.local.set({ debug: Boolean(enabled) });
|
|
}
|
|
|
|
// Reset all settings to defaults.
|
|
function resetDefaults() {
|
|
chrome.storage.local.set(DEFAULTS, loadChannels);
|
|
}
|
|
|
|
// Accept @handle or full channel URL.
|
|
function normalizeHandle(value) {
|
|
const atMatch = value.match(/@([^/?#]+)/);
|
|
if (atMatch) return atMatch[1].trim();
|
|
const clean = value.replace(/^https?:\/\//i, "").trim();
|
|
const urlMatch = clean.match(/youtube\.com\/@([^/?#]+)/i);
|
|
if (urlMatch) return urlMatch[1].trim();
|
|
return "";
|
|
}
|
|
|
|
function saveMaxArchive() {
|
|
const value = parseInt(maxInput.value, 10);
|
|
if (Number.isNaN(value)) return;
|
|
chrome.storage.local.set({ maxArchive: value }, loadChannels);
|
|
}
|
|
|
|
function clearArchive() {
|
|
chrome.storage.local.set({ memberOnlyHidden: [] }, loadChannels);
|
|
}
|
|
|
|
function clearWhitelist() {
|
|
chrome.storage.local.set({ whitelist: [] }, loadChannels);
|
|
}
|
|
|
|
// Wire UI events.
|
|
addBtn.onclick = addChannel;
|
|
saveMaxBtn.onclick = saveMaxArchive;
|
|
clearArchiveBtn.onclick = clearArchive;
|
|
clearWhitelistBtn.onclick = clearWhitelist;
|
|
debugToggle.onchange = e => setDebug(e.target.checked);
|
|
resetBtn.onclick = resetDefaults;
|
|
loadChannels();
|