feat: 大屏增强——一键亮屏按钮、卡片显示设备名+IP+熄屏状态(thumb 响应头 X-Screen-State)、点击卡片进入设备操作弹窗(实时流+触控+按键+文字),工具页远程看屏子分栏移除并入大屏

This commit is contained in:
2026-08-19 14:17:33 +08:00
parent c78f17d72f
commit e07b339a51
5 changed files with 269 additions and 199 deletions
-1
View File
@@ -112,7 +112,6 @@ function showSubTab(tabId, name){
const tab = document.getElementById('tab-'+tabId);
tab.querySelectorAll('.sub-tab').forEach(b=>b.classList.toggle('active', b.dataset.sub===name));
tab.querySelectorAll('.sub-panel').forEach(p=>p.classList.toggle('active', p.id===tabId+'-sub-'+name));
if(name==='screen' && typeof loadScreenDevices==='function') loadScreenDevices();
if(name==='devpool' && typeof loadDevPool==='function') loadDevPool();
}
-121
View File
@@ -277,127 +277,6 @@ function copyTsKey(){
}
// ================== Tab: 工具 - 远程看屏(MJPEG 流 + u2 触控) ==================
let _screenViewOn = false;
async function loadScreenDevices(force){
const sel=document.getElementById('screen-device');
if(!sel)return;
const list=await _fetchAdbDevices(force);
if(list===null)return;
const cur=sel.value;
const stateTxt={device:'在线',offline:'离线',pool:'设备池(未连接)'};
sel.innerHTML=list.map(d=>
'<option value="'+esc(d.serial)+'">'+esc(d.serial)+' ('+(stateTxt[d.state]||d.state)+')</option>'
).join('');
if(cur)sel.value=cur;
}
function _screenSerial(){
const sel=document.getElementById('screen-device');
return sel?sel.value:'';
}
function startScreenView(){
const serial=_screenSerial();
if(!serial){showToast('请先选择设备','error');return;}
stopScreenView();
const img=document.getElementById('screen-img');
const loading=document.getElementById('screen-loading');
loading.style.display='flex';
document.getElementById('screen-status').textContent='';
img.src='/api/screen/stream?serial='+encodeURIComponent(serial);
img.onload=()=>{loading.style.display='none';_screenViewOn=true;document.getElementById('screen-status').textContent='观看中';};
img.onerror=()=>{loading.style.display='none';_screenViewOn=false;showToast('画面流中断(设备离线或已停止)','error');};
}
function stopScreenView(){
const img=document.getElementById('screen-img');
if(img)img.src='';
_screenViewOn=false;
const loading=document.getElementById('screen-loading');
if(loading)loading.style.display='none';
const st=document.getElementById('screen-status');
if(st)st.textContent='';
}
// 显示尺寸 -> 设备原生分辨率(img.naturalWidth/Height 即设备分辨率)
function _screenCoords(ev){
const img=document.getElementById('screen-img');
if(!img.naturalWidth)return [null,null];
const r=img.getBoundingClientRect();
return [
Math.round((ev.clientX-r.left)/r.width*img.naturalWidth),
Math.round((ev.clientY-r.top)/r.height*img.naturalHeight),
];
}
function _screenTap(x,y){
const serial=_screenSerial();
if(!serial||x==null||y==null)return;
apiPost('/api/screen/tap',{serial,x,y}).then(r=>{if(r&&!r.ok)showToast(r.error,'error');});
}
function _screenSwipe(x1,y1,x2,y2){
const serial=_screenSerial();
if(!serial||x1==null)return;
apiPost('/api/screen/swipe',{serial,x1,y1,x2,y2}).then(r=>{if(r&&!r.ok)showToast(r.error,'error');});
}
function screenKey(key){
const serial=_screenSerial();
if(!serial){showToast('请先选择设备','error');return;}
apiPost('/api/screen/key',{serial,key}).then(r=>{if(r&&!r.ok)showToast(r.error,'error');});
}
function screenSendText(){
const serial=_screenSerial();
const inp=document.getElementById('screen-text');
const text=(inp.value||'').trim();
if(!serial){showToast('请先选择设备','error');return;}
if(!text){showToast('请输入文字','error');return;}
apiPost('/api/screen/text',{serial,text}).then(r=>{
if(r&&!r.ok)showToast(r.error,'error');
else inp.value='';
});
}
// 鼠标 + 触控:拖拽=滑动,点按=轻触
(function(){
const img=document.getElementById('screen-img');
if(!img)return;
let dragging=false, sx=0, sy=0;
function onDown(ev){
if(!_screenViewOn)return;
ev.preventDefault();
dragging=true;
const [x,y]=_screenCoords(ev);
sx=x; sy=y;
}
function onUp(ev){
if(!dragging)return;
dragging=false;
const [x,y]=_screenCoords(ev);
if(x==null)return;
if(Math.abs(x-sx)<8 && Math.abs(y-sy)<8){
_screenTap(x,y); // 位移小 → 点击
}else{
_screenSwipe(sx,sy,x,y); // 有位移 → 滑动
}
}
img.addEventListener('mousedown',onDown);
img.addEventListener('mousemove',ev=>{if(dragging)ev.preventDefault();});
window.addEventListener('mouseup',onUp);
img.addEventListener('touchstart',onDown,{passive:false});
img.addEventListener('touchend',ev=>{
if(!dragging)return;
const t=ev.changedTouches[0];
onUp({clientX:t.clientX,clientY:t.clientY,preventDefault(){}});
},{passive:false});
})();
// ================== Tab: 工具 - 设备池管理(本地 SQLite 清单) ==================
async function loadDevPool(){
const tb=document.getElementById('tb-devpool');