From: Dirk Brenken Date: Sat, 24 Jan 2026 13:39:03 +0000 (+0100) Subject: luci-app-adblock: sync with adblock 4.5.0-2 X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=e3478e4ebb45b0ac01a0982f17f6b305c1629a77;p=openwrt-luci.git luci-app-adblock: sync with adblock 4.5.0-2 Signed-off-by: Dirk Brenken --- diff --git a/applications/luci-app-adblock/Makefile b/applications/luci-app-adblock/Makefile index 516c404e7a..264b2c9549 100644 --- a/applications/luci-app-adblock/Makefile +++ b/applications/luci-app-adblock/Makefile @@ -7,7 +7,7 @@ LUCI_TITLE:=LuCI support for Adblock LUCI_DEPENDS:=+luci-base +adblock PKG_VERSION:=4.5.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_LICENSE:=Apache-2.0 PKG_MAINTAINER:=Dirk Brenken diff --git a/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/dnsreport.js b/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/dnsreport.js index c41a490700..e79dccfb48 100644 --- a/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/dnsreport.js +++ b/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/dnsreport.js @@ -317,6 +317,7 @@ return view.extend({ E('th', { 'class': 'th' }, _('Date')), E('th', { 'class': 'th' }, _('Time')), E('th', { 'class': 'th' }, _('Client')), + E('th', { 'class': 'th' }, _('Type')), E('th', { 'class': 'th' }, _('Domain')), E('th', { 'class': 'th' }, _('Answer')), E('th', { 'class': 'th' }, _('Action')) @@ -351,6 +352,7 @@ return view.extend({ content[0].requests[i].date, content[0].requests[i].time, content[0].requests[i].client, + content[0].requests[i].type, '' + content[0].requests[i].domain + '', content[0].requests[i].rc, button @@ -361,35 +363,40 @@ return view.extend({ const page = E('div', { 'class': 'cbi-map', 'id': 'map' }, [ E('div', { 'class': 'cbi-section' }, [ - E('p', _('This tab shows the last generated DNS Report, press the \'Refresh\' button to get a current one.')), - E('p', '\xa0'), - E('div', { 'class': 'cbi-value' }, [ - E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Start Timestamp')), - E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, (content[0].start_date || '-') + ', ' + (content[0].start_time || '-')) - ]), - E('div', { 'class': 'cbi-value' }, [ - E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('End Timestamp')), - E('div', { 'class': 'cbi-value-title', 'id': 'end', 'style': 'float:left;color:#37c' }, (content[0].end_date || '-') + ', ' + (content[0].end_time || '-')) - ]), - E('div', { 'class': 'cbi-value' }, [ - E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Total DNS Requests')), - E('div', { 'class': 'cbi-value-title', 'id': 'total', 'style': 'float:left;color:#37c' }, content[0].total || '-') - ]), - E('div', { 'class': 'cbi-value' }, [ - E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Blocked DNS Requests')), - E('div', { 'class': 'cbi-value-title', 'id': 'blocked', 'style': 'float:left;color:#37c' }, (content[0].blocked || '-') + ' (' + (content[0].percent || '-') + ')') + E('p', _('This tab displays the most recently generated DNS report. Use the \‘Refresh\’ button to update it.')), + E('div', { 'class': 'cbi-value', 'style': 'position:relative;min-height:220px' }, [ + E('div', { + 'style': 'position:absolute; top:0; right:0; text-align:center' + }, [ + E('div', { 'style': 'font-size:12px; color:#37c; margin-bottom:8px; font-family:monospace; line-height:1.3; text-align:right' }, [ + E('div', { 'style': 'font-size:12px; color:#37c; margin-bottom:8px' }, [ + E('div', {}, 'Start: ' + (content[0].start_date || '-') + ' ' + (content[0].start_time || '-')), + E('div', {}, 'End: ' + (content[0].end_date || '-') + ' ' + (content[0].end_time || '-')) + ]) + ]), + E('canvas', { + 'id': 'dnsPie', + 'width': 160, + 'height': 160, + 'style': 'max-width:160px; width:28vw; height:auto; cursor:pointer;' + }), + E('div', { 'style': 'margin-top:5px; font-size:12px' }, [ + E('span', { 'style': 'color:#b04a4a' }, '■ Blocked'), + E('span', { 'style': 'margin-left:10px;color:#6a8f6a' }, '■ Allowed') + ]) + ]) ]) ]), E('div', { 'class': 'cbi-section' }, [ E('div', { 'class': 'left' }, [ - E('h3', _('Top Statistics')), + E('h3', { 'style': 'white-space:nowrap' }, _('Top Statistics')), tbl_top ]) ]), E('br'), E('div', { 'class': 'cbi-section' }, [ E('div', { 'class': 'left' }, [ - E('h3', _('Latest DNS Requests')), + E('h3', { 'style': 'white-space:nowrap' }, _('Latest DNS Requests')), tbl_requests ]) ]), @@ -446,6 +453,105 @@ return view.extend({ btn.removeAttribute('disabled'); } } + /* Draw Pie Chart with Tooltip */ + const tooltip = E('div', { + id: 'dnsPieTooltip', + style: 'position:absolute; padding:6px 10px; background:#333; color:#fff; border-radius:4px; font-size:12px; pointer-events:none; opacity:0; transition:opacity .15s; z-index:9999' + }); + document.body.appendChild(tooltip); + setTimeout(function() { + const total = Number(content[0].total || 0); + const blocked = Number(content[0].blocked || 0); + const allowed = Math.max(total - blocked, 0); + + const canvas = document.getElementById('dnsPie'); + if (!canvas || total <= 0) + return; + + const ctx = canvas.getContext('2d'); + const colors = { + blocked: '#b04a4a', + allowed: '#6a8f6a' + }; + + function drawPie(rotation = 0) { + const w = canvas.clientWidth; + canvas.width = w; + canvas.height = w; + const cx = w / 2; + const cy = w / 2; + const r = (w / 2) - 4; + const blockedAngle = (blocked / total) * 2 * Math.PI; + const allowedAngle = (allowed / total) * 2 * Math.PI; + + ctx.clearRect(0, 0, w, w); + ctx.beginPath(); + ctx.moveTo(cx, cy); + ctx.fillStyle = colors.blocked; + ctx.arc(cx, cy, r, rotation, rotation + blockedAngle); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(cx, cy); + ctx.fillStyle = colors.allowed; + ctx.arc(cx, cy, r, rotation + blockedAngle, rotation + blockedAngle + allowedAngle); + ctx.fill(); + + ctx.beginPath(); + ctx.arc(cx, cy, r, 0, 2 * Math.PI); + ctx.strokeStyle = '#fff'; + ctx.lineWidth = 2; + ctx.stroke(); + } + let rot = 0; + function animate() { + rot += 0.10; + drawPie(rot); + if (rot < Math.PI * 2) + requestAnimationFrame(animate); + } + animate(); + window.addEventListener('resize', function() { + drawPie(rot); + }); + + const tooltip = document.getElementById('dnsPieTooltip'); + canvas.addEventListener('mousemove', function(ev) { + const rect = canvas.getBoundingClientRect(); + const x = ev.clientX - rect.left; + const y = ev.clientY - rect.top; + const cx = canvas.width / 2; + const cy = canvas.height / 2; + const dx = x - cx; + const dy = y - cy; + const dist = Math.sqrt(dx*dx + dy*dy); + if (dist > canvas.width/2 - 4) { + tooltip.style.opacity = 0; + return; + } + let angle = Math.atan2(dy, dx); + if (angle < 0) angle += 2 * Math.PI; + + const blockedAngle = (blocked / total) * 2 * Math.PI; + let label, abs, pct; + if (angle < blockedAngle) { + label = 'Blocked'; + abs = blocked; + pct = ((blocked / total) * 100).toFixed(1) + '%'; + } else { + label = 'Allowed'; + abs = allowed; + pct = ((allowed / total) * 100).toFixed(1) + '%'; + } + tooltip.textContent = `${label}: ${abs} (${pct})`; + tooltip.style.left = ev.pageX + 12 + 'px'; + tooltip.style.top = ev.pageY + 12 + 'px'; + tooltip.style.opacity = 1; + }); + canvas.addEventListener('mouseleave', function() { + tooltip.style.opacity = 0; + }); + }, 0); return page; }, handleSaveApply: null, diff --git a/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/overview.js b/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/overview.js index c87eb38a56..badee722be 100644 --- a/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/overview.js +++ b/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/overview.js @@ -502,8 +502,11 @@ return view.extend({ o.datatype = 'range(1,10)'; o.rmempty = true; - o = s.taboption('adv_report', form.Value, 'adb_replisten', _('Report Ports'), _('Space separated list of ports used by tcpdump.')); + o = s.taboption('adv_report', form.DynamicList, 'adb_repport', _('Report Ports'), _('The list of ports used by tcpdump.')); + o.datatype = 'port'; o.placeholder = '53'; + o.multiple = true; + o.optional = true; o.rmempty = true; o = s.taboption('adv_report', form.Flag, 'adb_represolve', _('Resolve IPs'), _('Resolve reporting IP addresses by using reverse DNS (PTR) lookups.'));