hosts: add per-URL enable/disable toggle for remote hosts lists
- Backend: get_hosts_urls() now reads hosts_list_disabled list and filters out disabled URLs before downloading. - Backend: hosts_list_status() now returns total and disabled counts. - Frontend: Added hidden hosts_list_disabled DynamicList option. - Frontend: Overrode renderWidget on hosts_list_urls to prepend a toggle switch (ON/OFF) next to each URL. Toggle syncs with hosts_list_disabled via uci.set().
This commit is contained in:
@@ -1232,6 +1232,65 @@ function createSettingsContent(section, capabilities) {
|
|||||||
);
|
);
|
||||||
hostsListUrlsOpt.placeholder = "https://raw.githubusercontent.com/.../hosts";
|
hostsListUrlsOpt.placeholder = "https://raw.githubusercontent.com/.../hosts";
|
||||||
|
|
||||||
|
const hostsListDisabledOpt = section.option(
|
||||||
|
form.DynamicList,
|
||||||
|
"hosts_list_disabled",
|
||||||
|
);
|
||||||
|
hostsListDisabledOpt.anonymous = true;
|
||||||
|
hostsListDisabledOpt.hidden = true;
|
||||||
|
|
||||||
|
const _origHostsListRenderWidget = hostsListUrlsOpt.renderWidget;
|
||||||
|
hostsListUrlsOpt.renderWidget = function (section_id, option_index, cfgvalue) {
|
||||||
|
const node = _origHostsListRenderWidget.call(this, section_id, option_index, cfgvalue);
|
||||||
|
const disabledValues = uci.get(UCI_PACKAGE, "settings", "hosts_list_disabled") || [];
|
||||||
|
|
||||||
|
function syncToggles() {
|
||||||
|
const container = node.querySelector(".cbi-dynlist") || node;
|
||||||
|
const items = container.querySelectorAll(".cbi-dynlist-item, .item");
|
||||||
|
items.forEach((item) => {
|
||||||
|
if (item.querySelector(".hosts-toggle")) return;
|
||||||
|
const valueEl = item.querySelector(".cbi-dynlist-item-value, input");
|
||||||
|
if (!valueEl) return;
|
||||||
|
const url = (valueEl.textContent || valueEl.value || "").trim();
|
||||||
|
if (!url) return;
|
||||||
|
|
||||||
|
const isDisabled = disabledValues.includes(url);
|
||||||
|
const toggle = E("label", {
|
||||||
|
class: "hosts-toggle",
|
||||||
|
style: "display:inline-flex;align-items:center;cursor:pointer;margin-right:6px;flex-shrink:0;",
|
||||||
|
}, [
|
||||||
|
E("input", {
|
||||||
|
type: "checkbox",
|
||||||
|
checked: !isDisabled,
|
||||||
|
style: "margin-right:4px;",
|
||||||
|
change: function () {
|
||||||
|
const enabled = this.checked;
|
||||||
|
let currentDisabled = uci.get(UCI_PACKAGE, "settings", "hosts_list_disabled") || [];
|
||||||
|
if (!Array.isArray(currentDisabled)) currentDisabled = [currentDisabled];
|
||||||
|
if (enabled) {
|
||||||
|
currentDisabled = currentDisabled.filter((d) => d !== url);
|
||||||
|
} else {
|
||||||
|
if (!currentDisabled.includes(url)) currentDisabled.push(url);
|
||||||
|
}
|
||||||
|
uci.set(UCI_PACKAGE, "settings", "hosts_list_disabled", currentDisabled.length ? currentDisabled : null);
|
||||||
|
uci.save();
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
E("span", {
|
||||||
|
style: "font-size:0.8rem;color:" + (isDisabled ? "var(--text-color-danger,#e53935)" : "var(--text-color-success,#43a047)"),
|
||||||
|
}, isDisabled ? "OFF" : "ON"),
|
||||||
|
]);
|
||||||
|
item.prepend(toggle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new MutationObserver(syncToggles);
|
||||||
|
observer.observe(node, { childList: true, subtree: true });
|
||||||
|
setTimeout(syncToggles, 100);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
o = section.option(
|
o = section.option(
|
||||||
form.Flag,
|
form.Flag,
|
||||||
"hosts_list_auto_update",
|
"hosts_list_auto_update",
|
||||||
|
|||||||
@@ -145,15 +145,32 @@ function get_hosts_urls() {
|
|||||||
if (uci_urls == "")
|
if (uci_urls == "")
|
||||||
return urls;
|
return urls;
|
||||||
|
|
||||||
|
let disabled = [];
|
||||||
|
let uci_disabled = uci.get(CONFIG_NAME + ".settings.hosts_list_disabled");
|
||||||
|
if (type(uci_disabled) == "array") {
|
||||||
|
for (let d in uci_disabled) {
|
||||||
|
let s = trim(d);
|
||||||
|
if (s != "") push(disabled, s);
|
||||||
|
}
|
||||||
|
} else if (uci_disabled != null && uci_disabled != "") {
|
||||||
|
push(disabled, trim(uci_disabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_disabled = function(url) {
|
||||||
|
for (let d in disabled)
|
||||||
|
if (d == url) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
if (type(uci_urls) == "array") {
|
if (type(uci_urls) == "array") {
|
||||||
for (let url in uci_urls) {
|
for (let url in uci_urls) {
|
||||||
let s = trim(url);
|
let s = trim(url);
|
||||||
if (s != "")
|
if (s != "" && !is_disabled(s))
|
||||||
push(urls, s);
|
push(urls, s);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let s = trim(uci_urls);
|
let s = trim(uci_urls);
|
||||||
if (s != "")
|
if (s != "" && !is_disabled(s))
|
||||||
push(urls, s);
|
push(urls, s);
|
||||||
}
|
}
|
||||||
return urls;
|
return urls;
|
||||||
@@ -208,6 +225,17 @@ function hosts_list_update(target_url) {
|
|||||||
|
|
||||||
function hosts_list_status() {
|
function hosts_list_status() {
|
||||||
let urls = get_hosts_urls();
|
let urls = get_hosts_urls();
|
||||||
|
let all_urls = [];
|
||||||
|
let uci_urls = uci.get(CONFIG_NAME + ".settings.hosts_list_urls");
|
||||||
|
if (type(uci_urls) == "array") {
|
||||||
|
for (let url in uci_urls) {
|
||||||
|
let s = trim(url);
|
||||||
|
if (s != "") push(all_urls, s);
|
||||||
|
}
|
||||||
|
} else if (uci_urls != null && uci_urls != "") {
|
||||||
|
push(all_urls, trim(uci_urls));
|
||||||
|
}
|
||||||
|
let disabled_count = length(all_urls) - length(urls);
|
||||||
let st = fs.stat(HOSTS_CACHE_FILE);
|
let st = fs.stat(HOSTS_CACHE_FILE);
|
||||||
let cache_exists = st != null;
|
let cache_exists = st != null;
|
||||||
let entry_count = 0;
|
let entry_count = 0;
|
||||||
@@ -216,7 +244,7 @@ function hosts_list_status() {
|
|||||||
entry_count = int(st.size);
|
entry_count = int(st.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
print('{"urls":' + length(urls) + ',"cache_exists":' + (cache_exists ? 'true' : 'false') + ',"cache_size":' + entry_count + '}');
|
print('{"urls":' + length(urls) + ',"total":' + length(all_urls) + ',"disabled":' + disabled_count + ',"cache_exists":' + (cache_exists ? 'true' : 'false') + ',"cache_size":' + entry_count + '}');
|
||||||
}
|
}
|
||||||
|
|
||||||
let command = ARGV[0] || "";
|
let command = ARGV[0] || "";
|
||||||
|
|||||||
Reference in New Issue
Block a user