mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-03 19:03:56 +08:00
⛄ Sync 2026-06-13 08:49:35
This commit is contained in:
1 parent
600c92a402
commit
a84e33d37f
11 files changed
+97
-40
No files matched your search
@@ -5,8 +5,8 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-daede
|
PKG_NAME:=luci-app-daede
|
||||||
PKG_VERSION:=1.10
|
PKG_VERSION:=1.10.3
|
||||||
PKG_RELEASE:=3
|
PKG_RELEASE:=4
|
||||||
PKG_MAINTAINER:=kenzok8
|
PKG_MAINTAINER:=kenzok8
|
||||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,16 @@ return view.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render: function(ctx) {
|
render: function(ctx) {
|
||||||
|
/* themes signal dark differently — BootstrapDark sets data-darkmode,
|
||||||
|
Argon just loads a dark stylesheet with no flag. Detect dark from the
|
||||||
|
page background luminance and set data-darkmode so our dark rules
|
||||||
|
(keyed on it) fire uniformly across every theme's dark mode. */
|
||||||
|
try {
|
||||||
|
const bg = getComputedStyle(document.body).backgroundColor.match(/\d+/g);
|
||||||
|
if (bg && (0.299 * bg[0] + 0.587 * bg[1] + 0.114 * bg[2]) < 128)
|
||||||
|
document.documentElement.setAttribute('data-darkmode', 'true');
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
const listenAddr = uci.get('daed', 'config', 'listen_addr') || backend.BACKENDS.daed.defaultListen;
|
const listenAddr = uci.get('daed', 'config', 'listen_addr') || backend.BACKENDS.daed.defaultListen;
|
||||||
const children = [
|
const children = [
|
||||||
E('style', {}, styles.CSS),
|
E('style', {}, styles.CSS),
|
||||||
|
|||||||
@@ -110,7 +110,9 @@ const GEN = '/usr/share/luci-app-daede/gen-dae-config.sh';
|
|||||||
stays visible in the edit dialog and on hover. */
|
stays visible in the edit dialog and on hover. */
|
||||||
function ellipsisCell(section_id) {
|
function ellipsisCell(section_id) {
|
||||||
const v = this.cfgvalue(section_id) || '';
|
const v = this.cfgvalue(section_id) || '';
|
||||||
const short = v.length > 52 ? v.slice(0, 52) + '…' : v;
|
/* middle-ellipsis keeps the host head + tail visible (the meaningful parts
|
||||||
|
of a sub link) while staying short enough for one line on a phone */
|
||||||
|
const short = v.length > 30 ? v.slice(0, 18) + '…' + v.slice(-9) : v;
|
||||||
return E('span', { 'title': v, 'style': 'font-family:ui-monospace,Menlo,monospace;font-size:12px' }, short);
|
return E('span', { 'title': v, 'style': 'font-family:ui-monospace,Menlo,monospace;font-size:12px' }, short);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +226,16 @@ function renderDaeForms(ctx) {
|
|||||||
s.anonymous = true;
|
s.anonymous = true;
|
||||||
o = s.option(form.Value, 'name', _('Name'));
|
o = s.option(form.Value, 'name', _('Name'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
o.default = 'proxy'; /* real default value, editable — a bright placeholder looked filled and tripped the required check */
|
||||||
o.placeholder = 'proxy';
|
o.placeholder = 'proxy';
|
||||||
|
o.validate = function(sid, v) {
|
||||||
|
if (!v) return _('Name is required');
|
||||||
|
/* dae fatals on duplicate outbound names — keep group names unique */
|
||||||
|
const dup = (uci.sections('dae', 'group') || []).some(function(g) {
|
||||||
|
return g['.name'] !== sid && g.name === v;
|
||||||
|
});
|
||||||
|
return dup ? _('Group name must be unique') : true;
|
||||||
|
};
|
||||||
o = s.option(form.ListValue, 'policy', _('Policy'));
|
o = s.option(form.ListValue, 'policy', _('Policy'));
|
||||||
o.value('min_moving_avg', _('Min moving average latency'));
|
o.value('min_moving_avg', _('Min moving average latency'));
|
||||||
o.value('min', _('Min last latency'));
|
o.value('min', _('Min last latency'));
|
||||||
@@ -256,6 +267,7 @@ function renderDaeForms(ctx) {
|
|||||||
o.default = '0';
|
o.default = '0';
|
||||||
o = s.option(form.Value, 'fallback', _('Fallback group'),
|
o = s.option(form.Value, 'fallback', _('Fallback group'),
|
||||||
_('Default outbound for everything else.'));
|
_('Default outbound for everything else.'));
|
||||||
|
o.default = 'proxy'; /* matches the default proxy group so the box works out of the box */
|
||||||
if (groupNames.length)
|
if (groupNames.length)
|
||||||
groupNames.forEach(function(n) { o.value(n, n); });
|
groupNames.forEach(function(n) { o.value(n, n); });
|
||||||
else
|
else
|
||||||
@@ -476,7 +488,10 @@ function renderDaeImportBanner() {
|
|||||||
if (hasForms)
|
if (hasForms)
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
|
|
||||||
return fs.read_direct(backend.BACKENDS.dae.config, 'text').then(function(content) {
|
/* stat first (ubus): avoid a 404 when config.dae doesn't exist yet */
|
||||||
|
return fs.stat(backend.BACKENDS.dae.config).then(function() {
|
||||||
|
return fs.read_direct(backend.BACKENDS.dae.config, 'text');
|
||||||
|
}).then(function(content) {
|
||||||
if (!content || !/\b(subscription|node)\s*\{/.test(content))
|
if (!content || !/\b(subscription|node)\s*\{/.test(content))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -650,7 +665,11 @@ function renderDaeEditor() {
|
|||||||
textarea.addEventListener('input', refreshPlaceholders);
|
textarea.addEventListener('input', refreshPlaceholders);
|
||||||
|
|
||||||
function loadConfig() {
|
function loadConfig() {
|
||||||
return fs.read_direct(backend.BACKENDS.dae.config, 'text').then(function(content) {
|
/* stat first (ubus, no HTTP): a fresh install has no config.dae yet, and
|
||||||
|
reading a missing file via fs.read_direct logs a noisy 404 */
|
||||||
|
return fs.stat(backend.BACKENDS.dae.config).then(function() {
|
||||||
|
return fs.read_direct(backend.BACKENDS.dae.config, 'text');
|
||||||
|
}).then(function(content) {
|
||||||
textarea.value = content || '';
|
textarea.value = content || '';
|
||||||
}).catch(function() {
|
}).catch(function() {
|
||||||
textarea.value = '';
|
textarea.value = '';
|
||||||
|
|||||||
@@ -69,9 +69,11 @@ const CSS = [
|
|||||||
as an off-colour band on the white card — keep it transparent */
|
as an off-colour band on the white card — keep it transparent */
|
||||||
'.dd-settings-card .cbi-section-table-titles,.dd-settings-card .cbi-section-table-titles .cbi-section-table-cell{background:transparent !important;background-image:none !important}',
|
'.dd-settings-card .cbi-section-table-titles,.dd-settings-card .cbi-section-table-titles .cbi-section-table-cell{background:transparent !important;background-image:none !important}',
|
||||||
'.dd-settings-card .cbi-section-table-cell:nth-child(1){width:14% !important}',
|
'.dd-settings-card .cbi-section-table-cell:nth-child(1){width:14% !important}',
|
||||||
'.dd-settings-card .cbi-section-table-cell:nth-child(2){width:50% !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
'.dd-settings-card .cbi-section-table-cell:nth-child(2){width:62% !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
||||||
'.dd-settings-card .cbi-section-table-cell:nth-child(3){width:12% !important}',
|
'.dd-settings-card .cbi-section-table-cell:nth-child(3){width:10% !important}',
|
||||||
'.dd-settings-card .cbi-section-table-cell:nth-child(4){width:24% !important;min-width:210px}',
|
'.dd-settings-card .cbi-section-table-cell:nth-child(4){width:auto !important;min-width:0 !important;white-space:nowrap;text-align:right}',
|
||||||
|
/* icon row-action buttons stay narrow, never stretch to fill the cell */
|
||||||
|
'.dd-settings-card .cbi-section-actions .cbi-button-edit,.dd-settings-card .cbi-section-actions .cbi-button-remove{width:auto !important;min-width:0 !important;display:inline-block !important;flex:0 0 auto !important}',
|
||||||
/* proxy-test result coloring */
|
/* proxy-test result coloring */
|
||||||
'.dd-meta.dd-ok{color:#3da66a;font-weight:600}',
|
'.dd-meta.dd-ok{color:#3da66a;font-weight:600}',
|
||||||
'.dd-meta.dd-err{color:#d96d6d;font-weight:600}',
|
'.dd-meta.dd-err{color:#d96d6d;font-weight:600}',
|
||||||
@@ -89,9 +91,9 @@ const CSS = [
|
|||||||
real editor (caret, selection, insert-at-cursor, jump-to-line all native) */
|
real editor (caret, selection, insert-at-cursor, jump-to-line all native) */
|
||||||
'.dd-edit-wrap{position:relative}',
|
'.dd-edit-wrap{position:relative}',
|
||||||
'.dd-edit-wrap .dd-editor,.dd-edit-wrap .dd-hl{margin:0;padding:10px 12px;border-width:1px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;font-size:12px;line-height:1.5;letter-spacing:0;tab-size:4;white-space:pre-wrap;word-break:break-word;box-sizing:border-box}',
|
'.dd-edit-wrap .dd-editor,.dd-edit-wrap .dd-hl{margin:0;padding:10px 12px;border-width:1px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;font-size:12px;line-height:1.5;letter-spacing:0;tab-size:4;white-space:pre-wrap;word-break:break-word;box-sizing:border-box}',
|
||||||
'.dd-edit-wrap .dd-hl{position:absolute;inset:0;margin:0;overflow:hidden;border:1px solid transparent;border-radius:6px 6px 0 0;pointer-events:none;background:transparent;color:#3b4252;z-index:1}',
|
'.dd-edit-wrap .dd-hl{position:absolute;inset:0;margin:0;overflow:hidden;border:1px solid transparent;border-radius:6px 6px 0 0;pointer-events:none;background:#f6f8fa;color:#3b4252;z-index:1}',
|
||||||
'.dd-edit-wrap .dd-hl code{font:inherit;white-space:inherit;word-break:inherit;display:block}',
|
'.dd-edit-wrap .dd-hl code{font:inherit;white-space:inherit;word-break:inherit;display:block}',
|
||||||
'.dd-edit-wrap .dd-editor-hl{position:relative;z-index:2;color:transparent;background:transparent;caret-color:#2f7288;border:1px solid rgba(128,128,128,.28)}',
|
'.dd-edit-wrap .dd-editor-hl{position:relative;z-index:2;color:transparent !important;background:transparent !important;caret-color:#2f7288;border:1px solid rgba(128,128,128,.28)}',
|
||||||
'.dd-edit-wrap .dd-editor-hl::placeholder{color:rgba(128,128,128,.55)}',
|
'.dd-edit-wrap .dd-editor-hl::placeholder{color:rgba(128,128,128,.55)}',
|
||||||
'.dd-edit-wrap .dd-editor-hl::selection{background:rgba(56,134,161,.25)}',
|
'.dd-edit-wrap .dd-editor-hl::selection{background:rgba(56,134,161,.25)}',
|
||||||
'.dh-c{color:#8a919a;font-style:italic}',
|
'.dh-c{color:#8a919a;font-style:italic}',
|
||||||
@@ -100,7 +102,7 @@ const CSS = [
|
|||||||
'.dh-f{color:#2f7288}',
|
'.dh-f{color:#2f7288}',
|
||||||
'.dh-o{color:#c2772a}',
|
'.dh-o{color:#c2772a}',
|
||||||
'.dh-g{color:#b0226a}',
|
'.dh-g{color:#b0226a}',
|
||||||
'html[data-darkmode="true"] .dd-edit-wrap .dd-hl,body.dark .dd-edit-wrap .dd-hl,html[data-bs-theme="dark"] .dd-edit-wrap .dd-hl{color:#c8cdd6}',
|
'html[data-darkmode="true"] .dd-edit-wrap .dd-hl,body.dark .dd-edit-wrap .dd-hl,html[data-bs-theme="dark"] .dd-edit-wrap .dd-hl{color:#c8cdd6;background:#1e2228}',
|
||||||
'html[data-darkmode="true"] .dd-edit-wrap .dd-editor-hl,body.dark .dd-edit-wrap .dd-editor-hl,html[data-bs-theme="dark"] .dd-edit-wrap .dd-editor-hl{caret-color:#7fd0e8}',
|
'html[data-darkmode="true"] .dd-edit-wrap .dd-editor-hl,body.dark .dd-edit-wrap .dd-editor-hl,html[data-bs-theme="dark"] .dd-edit-wrap .dd-editor-hl{caret-color:#7fd0e8}',
|
||||||
'html[data-darkmode="true"] .dh-c,body.dark .dh-c{color:#6b7280}',
|
'html[data-darkmode="true"] .dh-c,body.dark .dh-c{color:#6b7280}',
|
||||||
'html[data-darkmode="true"] .dh-s,body.dark .dh-s{color:#7ec699}',
|
'html[data-darkmode="true"] .dh-s,body.dark .dh-s{color:#7ec699}',
|
||||||
@@ -150,15 +152,32 @@ const CSS = [
|
|||||||
'body.dark .dd-card,html[data-theme="dark"] .dd-card,html[data-bs-theme="dark"] .dd-card,html[data-darkmode="true"] .dd-card{border-color:rgba(255,255,255,.08);background:rgba(255,255,255,.02)}',
|
'body.dark .dd-card,html[data-theme="dark"] .dd-card,html[data-bs-theme="dark"] .dd-card,html[data-darkmode="true"] .dd-card{border-color:rgba(255,255,255,.08);background:rgba(255,255,255,.02)}',
|
||||||
'body.dark .dd-adv-bar,html[data-theme="dark"] .dd-adv-bar,html[data-bs-theme="dark"] .dd-adv-bar,html[data-darkmode="true"] .dd-adv-bar{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.10)}',
|
'body.dark .dd-adv-bar,html[data-theme="dark"] .dd-adv-bar,html[data-bs-theme="dark"] .dd-adv-bar,html[data-darkmode="true"] .dd-adv-bar{background:rgba(255,255,255,.04);border-color:rgba(255,255,255,.10)}',
|
||||||
'body.dark .dd-settings-card .cbi-value-field input,body.dark .dd-settings-card .cbi-value-field select,body.dark .dd-settings-card .cbi-value-field textarea,html[data-theme="dark"] .dd-settings-card .cbi-value-field input,html[data-theme="dark"] .dd-settings-card .cbi-value-field select,html[data-theme="dark"] .dd-settings-card .cbi-value-field textarea,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field input,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field select,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field textarea,html[data-darkmode="true"] .dd-settings-card .cbi-value-field input,html[data-darkmode="true"] .dd-settings-card .cbi-value-field select,html[data-darkmode="true"] .dd-settings-card .cbi-value-field textarea{border-color:rgba(255,255,255,.18)}',
|
'body.dark .dd-settings-card .cbi-value-field input,body.dark .dd-settings-card .cbi-value-field select,body.dark .dd-settings-card .cbi-value-field textarea,html[data-theme="dark"] .dd-settings-card .cbi-value-field input,html[data-theme="dark"] .dd-settings-card .cbi-value-field select,html[data-theme="dark"] .dd-settings-card .cbi-value-field textarea,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field input,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field select,html[data-bs-theme="dark"] .dd-settings-card .cbi-value-field textarea,html[data-darkmode="true"] .dd-settings-card .cbi-value-field input,html[data-darkmode="true"] .dd-settings-card .cbi-value-field select,html[data-darkmode="true"] .dd-settings-card .cbi-value-field textarea{border-color:rgba(255,255,255,.18)}',
|
||||||
/* phone: render each subscription/node row as a self-contained card instead
|
/* status card line-2 meta (backend · pid), below the badge+toggle line */
|
||||||
of a cramped table (LuCI already block-stacks the cells; we add the card
|
'.dd-status-meta{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px}',
|
||||||
frame, drop the desktop column widths, and shrink the action buttons) */
|
/* compact icon-only row actions — the 编辑/删除 text buttons are too wide
|
||||||
|
(esp. Bootstrap); show a pencil / trash glyph instead, both themes */
|
||||||
|
'.dd-settings-card .cbi-section-actions .cbi-button-edit,.dd-settings-card .cbi-section-actions .cbi-button-remove{font-size:0 !important;padding:4px 7px !important;min-width:0 !important}',
|
||||||
|
'.dd-settings-card .cbi-section-actions .cbi-button-edit::before{content:"\\270E";font-size:13px;line-height:1}',
|
||||||
|
'.dd-settings-card .cbi-section-actions .cbi-button-remove::before{content:"\\1F5D1\\FE0E";font-size:13px;line-height:1}',
|
||||||
|
/* phone: keep each subscription/node row on ONE line; the URL cell
|
||||||
|
middle-ellipsizes (via ellipsisCell) and flex-shrinks to fit the screen */
|
||||||
'@media (max-width:600px){',
|
'@media (max-width:600px){',
|
||||||
'.dd-settings-card .cbi-section-table-cell:nth-child(1),.dd-settings-card .cbi-section-table-cell:nth-child(2),.dd-settings-card .cbi-section-table-cell:nth-child(3),.dd-settings-card .cbi-section-table-cell:nth-child(4){width:auto !important;min-width:0 !important;white-space:normal !important;overflow:visible !important;text-overflow:clip !important}',
|
'.dd-settings-card .cbi-section-table-titles{display:none !important}',
|
||||||
'.dd-settings-card .cbi-section-table-row{display:block;border:1px solid rgba(128,128,128,.2);border-radius:8px;padding:6px 10px;margin:0 0 8px;background:rgba(128,128,128,.03)}',
|
/* drop table layout so flex rows are constrained to the card width and the
|
||||||
'.dd-settings-card .cbi-section-table-cell{display:block;padding:3px 0 !important}',
|
URL cell can actually shrink (a flex <tr> inside table-layout:fixed grows
|
||||||
'.dd-settings-card .cbi-section-actions{display:flex;flex-wrap:wrap;gap:6px;padding-top:6px !important}',
|
past the table and overflows the screen on narrow/Argon) */
|
||||||
'.dd-settings-card .cbi-section-actions .cbi-button{width:auto;margin:0;flex:0 0 auto}',
|
'.dd-settings-card .cbi-section-table{display:block !important;table-layout:auto !important;width:auto !important;overflow:visible !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table>tbody,.dd-settings-card .cbi-section-table>div{display:block !important;width:auto !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row{display:flex !important;flex-wrap:nowrap !important;width:auto !important;align-items:center;gap:6px;padding:5px 0;margin:0;border:0;border-bottom:1px solid rgba(128,128,128,.15);background:transparent}',
|
||||||
|
/* target the real cells (td.cbi-value-field / actions) — LuCI forces them
|
||||||
|
block+full-width at mobile, so override on the direct children */
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td{display:inline-block !important;align-self:center !important;width:auto !important;padding:0 !important;border:0 !important;background:transparent !important;box-shadow:none !important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0 !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td::before{content:none !important;display:none !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td input{vertical-align:middle !important;margin:0 !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td:nth-child(1){flex:0 0 auto !important;max-width:60px;opacity:.6;font-size:11px}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td:nth-child(2){flex:1 1 auto !important}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td:nth-child(3){flex:0 0 auto !important;text-align:center}',
|
||||||
|
'.dd-settings-card .cbi-section-table-row>td.cbi-section-actions{flex:0 0 auto !important;display:flex;gap:4px}',
|
||||||
'}'
|
'}'
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
|
|||||||
@@ -140,8 +140,6 @@ function renderStatusCard(ctx, listenAddr) {
|
|||||||
|
|
||||||
if (state.running && state.pid)
|
if (state.running && state.pid)
|
||||||
meta.push(E('span', { 'class': 'dd-meta' }, [ E('span', { 'class': 'dd-meta-label' }, 'PID'), state.pid ]));
|
meta.push(E('span', { 'class': 'dd-meta' }, [ E('span', { 'class': 'dd-meta-label' }, 'PID'), state.pid ]));
|
||||||
if (be.hasWebUI)
|
|
||||||
meta.push(E('span', { 'class': 'dd-meta' }, [ E('span', { 'class': 'dd-meta-label' }, _('Listen')), listenAddr || be.defaultListen ]));
|
|
||||||
|
|
||||||
const swErr = E('span', { 'class': 'dd-meta dd-err', 'style': 'display:none' }, '');
|
const swErr = E('span', { 'class': 'dd-meta dd-err', 'style': 'display:none' }, '');
|
||||||
const sw = E('button', { 'class': 'dd-switch' + (state.running ? ' is-on' : ''), 'type': 'button', 'aria-label': _('Toggle service') }, [
|
const sw = E('button', { 'class': 'dd-switch' + (state.running ? ' is-on' : ''), 'type': 'button', 'aria-label': _('Toggle service') }, [
|
||||||
@@ -173,15 +171,19 @@ function renderStatusCard(ctx, listenAddr) {
|
|||||||
.finally(function() { sw.disabled = false; });
|
.finally(function() { sw.disabled = false; });
|
||||||
});
|
});
|
||||||
|
|
||||||
const row = E('div', { 'class': 'dd-status-row' }, [ badge ].concat(meta).concat([
|
/* line 1: badge + toggle (always aligned, never wraps); line 2: meta */
|
||||||
|
const row = E('div', { 'class': 'dd-status-row' }, [
|
||||||
|
badge,
|
||||||
E('span', { 'class': 'dd-grow' }),
|
E('span', { 'class': 'dd-grow' }),
|
||||||
swErr,
|
swErr,
|
||||||
E('span', { 'class': 'dd-switch-wrap' }, [
|
E('span', { 'class': 'dd-switch-wrap' }, [
|
||||||
E('span', { 'class': 'dd-switch-label' }, state.running ? 'ON' : 'OFF'),
|
E('span', { 'class': 'dd-switch-label' }, state.running ? 'ON' : 'OFF'),
|
||||||
sw
|
sw
|
||||||
])
|
])
|
||||||
]));
|
]);
|
||||||
body.appendChild(row);
|
body.appendChild(row);
|
||||||
|
if (meta.length)
|
||||||
|
body.appendChild(E('div', { 'class': 'dd-status-meta' }, meta));
|
||||||
|
|
||||||
const actions = [];
|
const actions = [];
|
||||||
if (be.hasWebUI && state.running) {
|
if (be.hasWebUI && state.running) {
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ emit_group() {
|
|||||||
config_get policy "$s" policy "min_moving_avg"
|
config_get policy "$s" policy "min_moving_avg"
|
||||||
name="$(sanitize "$name")"
|
name="$(sanitize "$name")"
|
||||||
[ -n "$name" ] || return 0
|
[ -n "$name" ] || return 0
|
||||||
|
# dae fatals on duplicate outbound names; keep the first, skip later dupes
|
||||||
|
case " $GROUP_NAMES_SEEN " in *" $name "*) return 0 ;; esac
|
||||||
|
GROUP_NAMES_SEEN="$GROUP_NAMES_SEEN $name"
|
||||||
[ -n "$FIRST_GROUP" ] || FIRST_GROUP="$name"
|
[ -n "$FIRST_GROUP" ] || FIRST_GROUP="$name"
|
||||||
|
|
||||||
GROUP_BUF="${GROUP_BUF} ${name} {
|
GROUP_BUF="${GROUP_BUF} ${name} {
|
||||||
@@ -191,7 +194,7 @@ generate() {
|
|||||||
config_get wan_interface config wan_interface "auto"
|
config_get wan_interface config wan_interface "auto"
|
||||||
config_get lan_interface config lan_interface ""
|
config_get lan_interface config lan_interface ""
|
||||||
|
|
||||||
SUB_BUF=""; NODE_BUF=""; GROUP_BUF=""; FIRST_GROUP=""
|
SUB_BUF=""; NODE_BUF=""; GROUP_BUF=""; FIRST_GROUP=""; GROUP_NAMES_SEEN=""
|
||||||
SUB_TAGS=""
|
SUB_TAGS=""
|
||||||
config_foreach collect_subtag subscription
|
config_foreach collect_subtag subscription
|
||||||
config_foreach emit_sub subscription
|
config_foreach emit_sub subscription
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=luci-app-gecoosac
|
PKG_NAME:=luci-app-gecoosac
|
||||||
PKG_VERSION:=2.2
|
PKG_VERSION:=2.2
|
||||||
PKG_RELEASE:=7
|
PKG_RELEASE:=8
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI Support for gecoosac
|
LUCI_TITLE:=LuCI Support for gecoosac
|
||||||
LUCI_DEPENDS:=+luci-compat +gecoosac
|
LUCI_DEPENDS:=+luci-compat +gecoosac
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function act_status()
|
|||||||
local enabled = cur:get("gecoosac", "config", "enabled") == "1"
|
local enabled = cur:get("gecoosac", "config", "enabled") == "1"
|
||||||
local e = {
|
local e = {
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
running = service_running()
|
running = enabled and service_running()
|
||||||
}
|
}
|
||||||
luci.http.prepare_content("application/json")
|
luci.http.prepare_content("application/json")
|
||||||
luci.http.write_json(e)
|
luci.http.write_json(e)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2025 gSpot (https://github.com/gSpotx2f/luci-app-log)
|
# Copyright (C) 2026 gSpot (https://github.com/gSpotx2f/luci-app-log)
|
||||||
#
|
#
|
||||||
# This is free software, licensed under the MIT License.
|
# This is free software, licensed under the MIT License.
|
||||||
#
|
#
|
||||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=luci-app-log-viewer
|
PKG_NAME:=luci-app-log-viewer
|
||||||
PKG_VERSION:=1.5.0
|
PKG_VERSION:=1.5.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
LUCI_TITLE:=Advanced syslog and kernel log (tail, search, etc)
|
LUCI_TITLE:=Advanced syslog and kernel log (tail, search, etc)
|
||||||
LUCI_DEPENDS:=+ucode +ucode-mod-fs
|
LUCI_DEPENDS:=+ucode +ucode-mod-fs
|
||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|||||||
+12
-12
@@ -11,29 +11,29 @@ Supported LuCI themes: luci-theme-bootstrap, luci-theme-material, luci-theme-ope
|
|||||||
|
|
||||||
**OpenWrt >= 25.12:**
|
**OpenWrt >= 25.12:**
|
||||||
|
|
||||||
wget --no-check-certificate -O /tmp/luci-app-log-viewer-1.5.0-r2.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-log-viewer-1.5.0-r2.apk
|
wget --no-check-certificate -O /tmp/luci-app-log-viewer-1.5.0-r3.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-app-log-viewer-1.5.0-r3.apk
|
||||||
apk --allow-untrusted add /tmp/luci-app-log-viewer-1.5.0-r2.apk
|
apk --allow-untrusted add /tmp/luci-app-log-viewer-1.5.0-r3.apk
|
||||||
rm /tmp/luci-app-log-viewer-1.5.0-r2.apk
|
rm /tmp/luci-app-log-viewer-1.5.0-r3.apk
|
||||||
service rpcd restart
|
service rpcd restart
|
||||||
|
|
||||||
i18n-ru:
|
i18n-ru:
|
||||||
|
|
||||||
wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-log-viewer-ru-1.5.0-r2.apk
|
wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru-1.5.0-r3.apk https://github.com/gSpotx2f/packages-openwrt/raw/master/25.12/luci-i18n-log-viewer-ru-1.5.0-r3.apk
|
||||||
apk --allow-untrusted add /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk
|
apk --allow-untrusted add /tmp/luci-i18n-log-viewer-ru-1.5.0-r3.apk
|
||||||
rm /tmp/luci-i18n-log-viewer-ru-1.5.0-r2.apk
|
rm /tmp/luci-i18n-log-viewer-ru-1.5.0-r3.apk
|
||||||
|
|
||||||
**OpenWrt <= 24.10:**
|
**OpenWrt <= 24.10:**
|
||||||
|
|
||||||
wget --no-check-certificate -O /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-log-viewer_1.5.0-r2_all.ipk
|
wget --no-check-certificate -O /tmp/luci-app-log-viewer_1.5.0-r3_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-app-log-viewer_1.5.0-r3_all.ipk
|
||||||
opkg install /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk
|
opkg install /tmp/luci-app-log-viewer_1.5.0-r3_all.ipk
|
||||||
rm /tmp/luci-app-log-viewer_1.5.0-r2_all.ipk
|
rm /tmp/luci-app-log-viewer_1.5.0-r3_all.ipk
|
||||||
service rpcd restart
|
service rpcd restart
|
||||||
|
|
||||||
i18n-ru:
|
i18n-ru:
|
||||||
|
|
||||||
wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk
|
wget --no-check-certificate -O /tmp/luci-i18n-log-viewer-ru_1.5.0-r3_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/24.10/luci-i18n-log-viewer-ru_1.5.0-r3_all.ipk
|
||||||
opkg install /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk
|
opkg install /tmp/luci-i18n-log-viewer-ru_1.5.0-r3_all.ipk
|
||||||
rm /tmp/luci-i18n-log-viewer-ru_1.5.0-r2_all.ipk
|
rm /tmp/luci-i18n-log-viewer-ru_1.5.0-r3_all.ipk
|
||||||
|
|
||||||
## Screenshots:
|
## Screenshots:
|
||||||
|
|
||||||
|
|||||||
@@ -302,12 +302,15 @@ return baseclass.extend({
|
|||||||
actionButtons : [],
|
actionButtons : [],
|
||||||
|
|
||||||
htmlEntities(str) {
|
htmlEntities(str) {
|
||||||
|
/*
|
||||||
return String(str).replace(
|
return String(str).replace(
|
||||||
/&/g, '&').replace(
|
/&/g, '&').replace(
|
||||||
/</g, '<').replace(
|
/</g, '<').replace(
|
||||||
/>/g, '>').replace(
|
/>/g, '>').replace(
|
||||||
/"/g, '"').replace(
|
/"/g, '"').replace(
|
||||||
/'/g, ''');
|
/'/g, ''');
|
||||||
|
*/
|
||||||
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
checkZeroValue(value) {
|
checkZeroValue(value) {
|
||||||
@@ -721,6 +724,7 @@ return baseclass.extend({
|
|||||||
if(!fPattern) {
|
if(!fPattern) {
|
||||||
return entriesArray;
|
return entriesArray;
|
||||||
};
|
};
|
||||||
|
fPattern = this.htmlEntities(fPattern);
|
||||||
return (this.msgFilterReValue) ?
|
return (this.msgFilterReValue) ?
|
||||||
this.setRegexpFilter(entriesArray, 5, fPattern) :
|
this.setRegexpFilter(entriesArray, 5, fPattern) :
|
||||||
this.setStringFilter(entriesArray, 5, fPattern);
|
this.setStringFilter(entriesArray, 5, fPattern);
|
||||||
|
|||||||
Reference in new issue
Block a user