Files
luci-app-led-scheduler/htdocs/luci-static/resources/view/led-scheduler/main.js
T
2026-09-08 20:01:03 +08:00

151 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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 {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[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();
}
});