diff --git a/design/prototype/screens/ui-desktop.html b/design/prototype/screens/ui-desktop.html index fd43d7d..15ab4ff 100644 --- a/design/prototype/screens/ui-desktop.html +++ b/design/prototype/screens/ui-desktop.html @@ -167,6 +167,13 @@ background:transparent; color:var(--fg3); cursor:pointer; border-radius:var(--radius-sm); } .dv-more:hover{ background:var(--bg-subtle); } .dv-more svg{ width:18px; height:18px; } + /* 设备行 ⋮ 弹出菜单(复用 .menu / .menu-item 原子,加图标 + 危险项) */ + .dv-menu{ position:relative; display:inline-flex; } + .dv-menu .menu{ min-width:172px; } + .dv-menu .menu-item{ display:flex; align-items:center; gap:var(--space-2); } + .dv-menu .menu-item svg{ width:15px; height:15px; flex:none; } + .dv-menu .menu-item.is-danger{ color:var(--danger); } + .dv-menu .menu-item.is-danger:hover{ background:var(--danger-subtle); } /* ---- 设置视图 ---- */ .settings-view{ padding:var(--space-5) var(--space-6) var(--space-6); max-width:none; } @@ -634,7 +641,7 @@
-
+ '; } var curPill = ''+I18N['dev.current'][lang]+''; - var moreBtn = ''; + // 本机(isLocal)只给「重命名」;非本机三项全给(清除=危险项)。菜单靠 #deviceList 委托处理。 + function devMenu(id, isLocal){ + function mi(act, icon, key, danger){ + return ''; + } + var items = mi('rename','pencil','dev.mRename',false); + if(!isLocal){ + items += mi('logout','log-out','dev.mForceLogout',false) + + mi('clear','trash-2','dev.mClearLogin',true); + } + return '' + + ''; + } var last = I18N['dev.lastOnline'][lang]; - var html = row('laptop','MacBook Pro', I18N['dev.current'][lang]+' · '+last+' '+I18N['dev.now'][lang], curPill); + var html = row('laptop','MacBook Pro', I18N['dev.current'][lang]+' · '+last+' '+I18N['dev.now'][lang], curPill + devMenu('macbook', true)); if(S.persp==='pro'){ - html += row('smartphone','iPhone 15', last+' '+I18N['dev.h2'][lang], moreBtn); - html += row('monitor','iPad Air', last+' '+I18N['dev.yesterday'][lang], moreBtn); + html += row('smartphone','iPhone 15', last+' '+I18N['dev.h2'][lang], devMenu('iphone', false)); + html += row('monitor','iPad Air', last+' '+I18N['dev.yesterday'][lang], devMenu('ipad', false)); } list.innerHTML = html; var cnt = S.persp==='pro' ? 3 : 1; @@ -1512,6 +1535,36 @@ document.addEventListener('click', function(){ if(!devMenu.hasAttribute('hidden')){ devMenu.setAttribute('hidden',''); devTrig.setAttribute('aria-expanded','false'); devSel.classList.remove('is-open'); } }); +/* 设备行 ⋮ 弹出菜单:委托处理(行随语言/视角重渲,用委托绑在静态容器上) */ +(function(){ + var list = document.getElementById('deviceList'); + if(!list) return; + function closeAll(){ + list.querySelectorAll('.dv-menu .menu').forEach(function(m){ m.setAttribute('hidden',''); }); + list.querySelectorAll('.dv-menu .dv-more').forEach(function(b){ b.setAttribute('aria-expanded','false'); }); + } + list.addEventListener('click', function(e){ + var more = e.target.closest('.dv-more'); + if(more){ + e.stopPropagation(); + var menu = more.parentNode.querySelector('.menu'); + var willOpen = menu.hasAttribute('hidden'); + closeAll(); + if(willOpen){ menu.removeAttribute('hidden'); more.setAttribute('aria-expanded','true'); } + return; + } + var mi = e.target.closest('.dv-mi'); + if(mi){ + e.stopPropagation(); + var act = mi.dataset.act; + var key = act==='rename' ? 'dev.tRenamed' : (act==='logout' ? 'dev.tLoggedOut' : 'dev.tCleared'); + closeAll(); + pvToast(I18N[key][S.lang]); + } + }); + document.addEventListener('click', closeAll); +})(); + /* ========= 购买流程(兑换 & 购买,接入主框架内容区) ========= */ /* 各币种一口价(pay 侧每 SKU 按结算币种各定价,不做实时汇率换算) */ var PV_PRICES = { diff --git a/design/prototype/screens/ui-mobile.html b/design/prototype/screens/ui-mobile.html index fcf431c..12b7c1e 100644 --- a/design/prototype/screens/ui-mobile.html +++ b/design/prototype/screens/ui-mobile.html @@ -166,6 +166,13 @@ .icon-mini:hover{ color:var(--danger); background:var(--danger-subtle); } .icon-mini svg{ width:18px; height:18px; } .icon-mini.plain:hover{ color:var(--accent); background:var(--accent-subtle); } + /* 设备行 ⋮ 弹出菜单(复用 .menu / .menu-item 原子 + 图标 + 危险项) */ + .dv-menu{ position:relative; display:inline-flex; } + .dv-menu .menu{ min-width:168px; } + .dv-menu .menu-item{ display:flex; align-items:center; gap:var(--space-2); } + .dv-menu .menu-item svg{ width:15px; height:15px; flex:none; } + .dv-menu .menu-item.is-danger{ color:var(--danger); } + .dv-menu .menu-item.is-danger:hover{ background:var(--danger-subtle); } .search-wrap{ position:relative; } .search-wrap > svg{ position:absolute; left:var(--space-4); top:50%; transform:translateY(-50%); @@ -989,7 +996,7 @@
iPhone 15本机
当前在线
-
+
@@ -1002,7 +1009,7 @@
iPhone 15本机
当前在线
-
+
@@ -1010,7 +1017,7 @@
MacBook Pro
最后在线 2 小时前
-
+
@@ -1018,7 +1025,7 @@
iPad Air
最后在线 昨天
-
+
@@ -1181,6 +1188,8 @@ const I18N = { devFreeLbl:'我的设备 · 1 / 1 台', devProLbl:'我的设备 · 3 / 5 台', secDevices:'设备', myDevices:'我的设备', devMgmt:'设备管理', thisDevice:'本机', devOnlineNow:'当前在线', lastOnline:'最后在线', rel2h:'2 小时前', relYday:'昨天', + devRename:'重命名', devForceLogout:'强制退出', devClearLogin:'清除登录信息', + devRenamedToast:'已重命名(演示)', devLoggedOutToast:'已强制退出(演示)', devClearedToast:'已清除登录信息(演示)', secPref:'偏好', prefLang:'语言', prefTheme:'深色外观', prefProtocol:'协议', followLight:'跟随浅色', stateOn:'已开启', secMore:'更多', navDevices:'设备管理', navSettings:'设置', navRedeem:'兑换 & 购买', navContact:'联系我们', navWebUC:'网页用户中心', logout:'退出登录', @@ -1253,6 +1262,8 @@ const I18N = { devFreeLbl:'My devices · 1 / 1', devProLbl:'My devices · 3 / 5', secDevices:'Devices', myDevices:'My Devices', devMgmt:'Device management', thisDevice:'This device', devOnlineNow:'Online now', lastOnline:'Last online', rel2h:'2h ago', relYday:'yesterday', + devRename:'Rename', devForceLogout:'Force logout', devClearLogin:'Clear login info', + devRenamedToast:'Renamed (demo)', devLoggedOutToast:'Force logged out (demo)', devClearedToast:'Login info cleared (demo)', secPref:'Preferences', prefLang:'Language', prefTheme:'Dark appearance', prefProtocol:'Protocol', followLight:'Follow light', stateOn:'On', secMore:'More', navDevices:'Devices', navSettings:'Settings', navRedeem:'Redeem & Buy', navContact:'Contact us', navWebUC:'Web user center', logout:'Sign out', @@ -1918,6 +1929,32 @@ function subShow(name){ function subOpen(name){ subShow(name); subOverlay.classList.add('is-open'); } function subClose(){ subOverlay.classList.remove('is-open'); } function subToast(msg){ const t=$('#subToast'); $('#subToastText').textContent=msg; t.classList.add('show'); clearTimeout(subToastTimer); subToastTimer=setTimeout(()=>t.classList.remove('show'),1800); } +/* 设备行 ⋮ 弹出菜单(重命名 / 强制退出 / 清除登录信息;本机仅重命名。设备为静态屏,直接绑定) */ +(function(){ + function closeDevMenus(){ + document.querySelectorAll('#subOverlay .dv-menu .menu').forEach(m=>m.hidden=true); + document.querySelectorAll('#subOverlay .dv-menu .dv-more').forEach(b=>b.setAttribute('aria-expanded','false')); + } + document.querySelectorAll('#subOverlay .dv-menu .dv-more').forEach(function(btn){ + btn.addEventListener('click', function(e){ + e.stopPropagation(); + var menu=btn.parentNode.querySelector('.menu'); + var willOpen=menu.hidden; + closeDevMenus(); + if(willOpen){ menu.hidden=false; btn.setAttribute('aria-expanded','true'); } + }); + }); + document.querySelectorAll('#subOverlay .dv-mi').forEach(function(it){ + it.addEventListener('click', function(e){ + e.stopPropagation(); + var act=it.dataset.act; + var key = act==='rename' ? 'devRenamedToast' : (act==='logout' ? 'devLoggedOutToast' : 'devClearedToast'); + closeDevMenus(); + subToast(D()[key]); + }); + }); + document.addEventListener('click', closeDevMenus); +})(); /* 语言切换时同步子屏标题(由 render() 调用) */ function subLangSync(){ if(subOverlay && subOverlay.classList.contains('is-open')) subShow(subOverlay.dataset.sub||'settings'); }