feat: 实现设备注册和精准控制功能,支持双屏管理;更新相关逻辑以优化设备状态跟踪
This commit is contained in:
+54
-15
@@ -10,8 +10,46 @@
|
||||
var fullscreen = !!init.fullscreen;
|
||||
var autostart = !!init.autostart;
|
||||
|
||||
/* 目标屏(双屏独立控制):both | main | secondary */
|
||||
var screenTarget = 'both';
|
||||
/* 目标屏幕(按 MQTT 客户端精准控制):client_id + role */
|
||||
var screenId = '';
|
||||
var screenRole = '';
|
||||
|
||||
function applyScreenTarget(sel) {
|
||||
sel = sel || document.getElementById('screenTarget');
|
||||
if (!sel) return;
|
||||
var v = sel.value || '';
|
||||
screenId = v;
|
||||
var opt = null;
|
||||
if (v) { for (var i = 0; i < sel.options.length; i++) { if (sel.options[i].value === v) { opt = sel.options[i]; break; } } }
|
||||
screenRole = opt ? (opt.getAttribute('data-role') || '') : '';
|
||||
}
|
||||
|
||||
function loadScreens() {
|
||||
fetch('/api/display/state', { cache: 'no-store' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (d) {
|
||||
var sel = document.getElementById('screenTarget');
|
||||
var cnt = document.getElementById('screenCount');
|
||||
if (!sel) return;
|
||||
var devices = (d && d.devices) || [];
|
||||
if (cnt) cnt.textContent = '在线设备:' + (devices.length || 0) + ' 台';
|
||||
var cur = sel.value;
|
||||
sel.innerHTML = '<option value="">全部屏幕</option>';
|
||||
devices.forEach(function (dev) {
|
||||
var role = dev.role || '';
|
||||
var name = role === 'main' ? '主屏' : role === 'secondary' ? '副屏' : (role || '屏幕');
|
||||
var parent = (dev.role === 'secondary' && dev.parent_id) ? '·属于:' + String(dev.parent_id).slice(0, 8) : '';
|
||||
var opt = document.createElement('option');
|
||||
opt.value = dev.device_id;
|
||||
opt.setAttribute('data-role', role);
|
||||
opt.textContent = name + parent + ' · ' + String(dev.device_id).slice(0, 16);
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
if (cur) sel.value = cur;
|
||||
applyScreenTarget(sel);
|
||||
})
|
||||
.catch(function () {});
|
||||
}
|
||||
|
||||
/* ---------- Toast ---------- */
|
||||
var toastContainer = document.getElementById('toastContainer');
|
||||
@@ -82,6 +120,7 @@
|
||||
setConn('api', true, '在线');
|
||||
setConn('mqtt', !!d.mqtt_connected, d.mqtt_connected ? '已连接(' + (d.mqtt_host || '') + ')' : '未连接');
|
||||
setConn('screens', (d.screens_online || 0) > 0, (d.screens_online || 0) + ' 台');
|
||||
loadScreens(); // 刷新目标屏幕下拉(按 MQTT 客户端)
|
||||
var lc = d.last_command;
|
||||
if (lc) {
|
||||
var names = { navigate: '页面切换', play: '播放', pause: '暂停', next: '下一项', prev: '上一项',
|
||||
@@ -98,6 +137,12 @@
|
||||
});
|
||||
}
|
||||
if (connEls.api) { pollStatus(); setInterval(pollStatus, 3000); }
|
||||
// 目标屏幕下拉:变更时记录目标 client_id + role;初始加载一次
|
||||
var screenSel = document.getElementById('screenTarget');
|
||||
if (screenSel) {
|
||||
screenSel.addEventListener('change', function () { applyScreenTarget(screenSel); });
|
||||
loadScreens();
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
事件委托:页面切换 / 播放控制 / 媒体操作
|
||||
@@ -110,19 +155,10 @@
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest ? e.target.closest('[data-nav], [data-mqtt], [data-control], [data-action], .copy-btn, [data-preview], .screen-target, #mqttAiSend, #mqttAlertSend') : null;
|
||||
var btn = e.target.closest ? e.target.closest('[data-nav], [data-mqtt], [data-control], [data-action], .copy-btn, [data-preview], #mqttAiSend, #mqttAlertSend') : null;
|
||||
if (!btn) return;
|
||||
e.stopPropagation();
|
||||
|
||||
// 目标屏选择(双屏独立控制)
|
||||
if (btn.classList.contains('screen-target')) {
|
||||
screenTarget = btn.getAttribute('data-screen') || 'both';
|
||||
var btns = document.querySelectorAll('.screen-target');
|
||||
for (var i = 0; i < btns.length; i++) btns[i].classList.toggle('active', btns[i] === btn);
|
||||
toast('目标屏:' + ({ both: '全部(镜像)', main: '仅主屏', secondary: '仅副屏' }[screenTarget] || screenTarget));
|
||||
return;
|
||||
}
|
||||
|
||||
// 预览
|
||||
if (btn.hasAttribute('data-preview')) { openPreview(btn.closest('.media-card')); return; }
|
||||
|
||||
@@ -141,10 +177,13 @@
|
||||
if (btn.hasAttribute('data-mqtt')) {
|
||||
var cmd = null;
|
||||
try { cmd = JSON.parse(btn.getAttribute('data-mqtt')); } catch (err) { toast('指令 JSON 错误', 'error'); return; }
|
||||
// 双屏独立控制:除「双屏开关」外,注入目标屏(main/secondary/both)
|
||||
if (cmd.action !== 'dual_screen') cmd.screen = screenTarget;
|
||||
// 屏幕终端精准控制:除「双屏开关」外,注入目标 client_id + role;全空=全局广播
|
||||
if (cmd.action !== 'dual_screen') { cmd.screen_id = screenId; cmd.screen_role = screenRole; }
|
||||
var tgtTxt = screenId
|
||||
? (cmd.screen_role === 'main' ? '主屏' : cmd.screen_role === 'secondary' ? '副屏' : '屏幕') + '·' + String(screenId).slice(0, 10)
|
||||
: '全部';
|
||||
post('/api/display/command', cmd, function (d) {
|
||||
toast(d && d.ok !== false ? '指令已发送:' + (cmd.action || '') : '发送失败(MQTT 未连接?)',
|
||||
toast(d && d.ok !== false ? ('指令已发送:' + (cmd.action || '') + ' → ' + tgtTxt) : '发送失败(MQTT 未连接?)',
|
||||
d && d.ok !== false ? 'ok' : 'error');
|
||||
});
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user