3.0.0
This commit is contained in:
commit
645c461d2a
12 files changed
+886
No files matched your search
@@ -0,0 +1,150 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require form';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require uci';
|
||||
|
||||
function validateTime(section_id, value) {
|
||||
if (!/^\d{2}:\d{2}$/.test(value))
|
||||
return _('时间格式必须为 HH:MM,例如 23:00');
|
||||
var parts = value.split(':');
|
||||
var hour = Number(parts[0]);
|
||||
var minute = Number(parts[1]);
|
||||
if (hour < 0 || hour > 23 || minute < 0 || minute > 59)
|
||||
return _('请输入有效时间,例如 07:30');
|
||||
return true;
|
||||
}
|
||||
|
||||
function showTimedNotification(message, style, timeout) {
|
||||
var content = E('p', {}, message);
|
||||
|
||||
/*
|
||||
* OpenWrt 25.12 LuCI provides addTimeLimitedNotification().
|
||||
* Keep a fallback for older/custom FriendlyWrt builds.
|
||||
*/
|
||||
if (typeof ui.addTimeLimitedNotification === 'function')
|
||||
return ui.addTimeLimitedNotification(null, content, timeout, style);
|
||||
|
||||
var node = ui.addNotification(null, content, style);
|
||||
|
||||
window.setTimeout(function() {
|
||||
if (!node || !node.parentNode)
|
||||
return;
|
||||
|
||||
node.classList.add('fade-out');
|
||||
node.classList.remove('fade-in');
|
||||
|
||||
window.setTimeout(function() {
|
||||
if (node.parentNode)
|
||||
node.parentNode.removeChild(node);
|
||||
}, 300);
|
||||
}, timeout);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function runControl(action, successMessage) {
|
||||
return fs.exec('/usr/bin/led-control', [ action ]).then(function(res) {
|
||||
if (!res || res.code !== 0) {
|
||||
var message = (res && res.stderr) ? res.stderr.trim() : _('未知错误');
|
||||
throw new Error(message || _('命令执行失败'));
|
||||
}
|
||||
|
||||
showTimedNotification(successMessage, 'info', 3000);
|
||||
}).catch(function(err) {
|
||||
showTimedNotification(
|
||||
_('操作失败:%s').format(err.message || String(err)),
|
||||
'error',
|
||||
6000
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([ uci.load('system'), uci.load('led-scheduler') ]);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var m, s, o;
|
||||
var leds = [];
|
||||
|
||||
uci.sections('system', 'led', function(section) {
|
||||
if (!section.sysfs) return;
|
||||
leds.push({
|
||||
name: section.name || section.sysfs,
|
||||
sysfs: section.sysfs,
|
||||
trigger: section.trigger || _('未指定')
|
||||
});
|
||||
});
|
||||
leds.sort(function(a, b) { return a.name.localeCompare(b.name); });
|
||||
|
||||
m = new form.Map('led-scheduler', _('LED 定时'),
|
||||
_('这里只负责“什么时候关灯、什么时候恢复”。LED 平时的触发器、网口联动等行为仍由“系统 → LED 配置”管理。'));
|
||||
|
||||
s = m.section(form.NamedSection, 'main', 'scheduler', _('定时设置'));
|
||||
s.addremove = false;
|
||||
|
||||
o = s.option(form.Flag, 'enabled', _('启用 LED 定时'));
|
||||
o.default = '0'; o.rmempty = false;
|
||||
o.description = _('关闭此开关并保存应用后,会立即恢复 OpenWrt 原生 LED 配置。');
|
||||
|
||||
o = s.option(form.Value, 'off_time', _('关闭时间'));
|
||||
o.default = '23:00'; o.placeholder = '23:00'; o.rmempty = false; o.validate = validateTime;
|
||||
|
||||
o = s.option(form.Value, 'on_time', _('恢复时间'));
|
||||
o.default = '07:00'; o.placeholder = '07:00'; o.rmempty = false; o.validate = validateTime;
|
||||
o.description = _('支持跨午夜,例如 23:00 关闭、07:00 恢复。');
|
||||
|
||||
o = s.option(form.Flag, 'all_system_leds', _('控制“系统 → LED 配置”中的全部 LED'));
|
||||
o.default = '1'; o.rmempty = false;
|
||||
|
||||
o = s.option(form.MultiValue, 'led', _('控制对象'));
|
||||
o.depends('all_system_leds', '0'); o.rmempty = true;
|
||||
if (leds.length) {
|
||||
leds.forEach(function(led) {
|
||||
o.value(led.sysfs, _('%s(%s,触发器:%s)').format(led.name, led.sysfs, led.trigger));
|
||||
});
|
||||
o.description = _('这些项目直接读取自 /etc/config/system,不会复制或修改原有 LED 行为。');
|
||||
} else {
|
||||
o.description = _('当前没有从“系统 → LED 配置”中读取到 LED 项目。');
|
||||
}
|
||||
|
||||
s = m.section(form.NamedSection, 'main', 'scheduler', _('手动控制'));
|
||||
s.addremove = false;
|
||||
o = s.option(form.Button, '_off_now', _('立即关闭'));
|
||||
o.inputstyle = 'remove';
|
||||
o.description = _('临时将所选 LED 的 trigger 设为 none,并将亮度设为 0。');
|
||||
o.onclick = function() { return runControl('off', _('所选 LED 已关闭。')); };
|
||||
|
||||
o = s.option(form.Button, '_on_now', _('立即恢复'));
|
||||
o.inputstyle = 'apply';
|
||||
o.description = _('重新加载 OpenWrt 原生 LED 配置,恢复 WAN/LAN 等原有触发方式。');
|
||||
o.onclick = function() { return runControl('on', _('OpenWrt 原生 LED 配置已恢复。')); };
|
||||
|
||||
o = s.option(form.Button, '_apply_now', _('按当前时间应用'));
|
||||
o.inputstyle = 'action';
|
||||
o.onclick = function() { return runControl('apply', _('已按当前时间应用 LED 状态。')); };
|
||||
|
||||
o = s.option(form.Button, '_sync_cron', _('重新同步定时任务'));
|
||||
o.inputstyle = 'action';
|
||||
o.description = _('正常情况下保存并应用会自动同步,无需手动点击。');
|
||||
o.onclick = function() { return runControl('sync', _('定时任务已同步。')); };
|
||||
|
||||
s = m.section(form.TypedSection, '_native_led_info', _('已读取的系统 LED'));
|
||||
s.anonymous = true; s.addremove = false;
|
||||
o = s.option(form.DummyValue, '_info');
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function() {
|
||||
if (!leds.length) return '<em>' + _('没有检测到系统 LED 配置。') + '</em>';
|
||||
function esc(v) { return String(v).replace(/[&<>"']/g, function(c) { return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; }); }
|
||||
var rows = leds.map(function(led) {
|
||||
return '<tr><td>' + esc(led.name) + '</td><td><code>' + esc(led.sysfs) + '</code></td><td>' + esc(led.trigger) + '</td></tr>';
|
||||
}).join('');
|
||||
return '<table class="table"><tr class="tr table-titles"><th>' + _('名称') + '</th><th>' + _('LED 名称') + '</th><th>' + _('触发器') + '</th></tr>' + rows + '</table>';
|
||||
};
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user