This commit is contained in:
2026-09-20 23:35:03 +08:00
parent 941ce4baab
commit 388c700996
19 changed files with 393 additions and 71 deletions

View File

@@ -40,7 +40,10 @@
const { get, set, clearHistory, openDir, chooseDir, openExternal } = window.settingsApi;
const $auto=document.getElementById('opt-autolaunch'),$hotkey=document.getElementById('opt-hotkey'),$max=document.getElementById('opt-maxitems'),$display=document.getElementById('opt-displaylimit'),$poll=document.getElementById('opt-pollms'),$dir=document.getElementById('opt-datadir'),$change=document.getElementById('btn-change-dir'),$open=document.getElementById('btn-open-dir'),$clear=document.getElementById('btn-clear'),$close=document.getElementById('close-btn'),$status=document.getElementById('status-left');
function flash(msg){$status.textContent=msg;setTimeout(()=>$status.textContent='就绪',2000)}
// 连发两条提示时,第一条的 2 秒定时器会把第二条提前刷回「就绪」——
// 每次 flash 先清掉上一个定时器,重置时间以最后一条消息为准。
let flashTimer=null;
function flash(msg){$status.textContent=msg;clearTimeout(flashTimer);flashTimer=setTimeout(()=>$status.textContent='就绪',2000)}
// settings:set 在主进程先改运行时状态、后写盘;写盘失败(磁盘满/只读/杀软锁文件)
// 会带 saved:false 回来 —— 本次会话已生效但重启还原,必须明确提示,
// 不能让用户以为设置已经保存。
@@ -48,7 +51,19 @@ function flashIfNotSaved(res){
if(res&&res.saved===false){flash('⚠ 设置未保存到磁盘,重启后还原');return true}
return false
}
async function refresh(){const c=await get();$auto.checked=!!c.autoLaunch;$hotkey.value=c.hotkey||'';$max.value=String(c.maxItems);$display.value=String(c.displayLimit);$poll.value=String(c.pollMs);$dir.textContent=c.dataDir}
async function refresh(){
const c=await get();
$auto.checked=!!c.autoLaunch;$hotkey.value=c.hotkey||'';$max.value=String(c.maxItems);$display.value=String(c.displayLimit);$poll.value=String(c.pollMs);
// 显示实际在用的目录(dataDirEffective,含 session 兜底);与配置目录不
// 一致时(配置位置暂不可用)两个都给出来,并解释当前数据在哪。
if(c.dataDirEffective&&c.dataDirEffective!==c.dataDir){
$dir.textContent=c.dataDirEffective;
$dir.title='配置位置 '+c.dataDir+' 当前不可用,本会话暂用此目录(重启后若恢复会自动切回)';
}else{
$dir.textContent=c.dataDir;
$dir.title='';
}
}
$auto.addEventListener('change',async()=>{const res=await set('autoLaunch',$auto.checked);if(!flashIfNotSaved(res))flash('已'+($auto.checked?'开启':'关闭')+'开机自启动')});
$max.addEventListener('change',async()=>{const res=await set('maxItems',parseInt($max.value,10));if(!flashIfNotSaved(res))flash('最大条数已设为 '+$max.value)});
$display.addEventListener('change',async()=>{const res=await set('displayLimit',parseInt($display.value,10));if(!flashIfNotSaved(res))flash('界面显示条数已设为 '+$display.value)});
@@ -117,6 +132,10 @@ function renderThemes(currentTheme) {
const card = document.createElement('div');
card.className = 'theme-card' + (t.id === currentTheme ? ' active' : '');
card.dataset.theme = t.id;
// div + click 对键盘不可达:补 button 语义。Enter/Space 触发与鼠标一致的 click。
card.tabIndex = 0;
card.setAttribute('role', 'button');
card.setAttribute('aria-pressed', String(t.id === currentTheme));
card.innerHTML = `
<div class="theme-preview" style="background:${t.bg};color:${t.text}">
<span class="theme-preview-text">Aa</span>
@@ -127,7 +146,14 @@ function renderThemes(currentTheme) {
<div class="theme-desc">${t.desc}</div>
</div>
`;
card.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); card.click(); }
});
card.addEventListener('click', async () => {
// renderThemes 会销毁全部旧卡片:焦点卡没了焦点就掉到 body,键盘用户
// 迷失位置。重建后把焦点还到同名新卡(Chromium 会沿用 focus-visible 状态,
// 鼠标点击不会因此多出焦点框)。
const hadFocus = document.activeElement === card;
const res = await themeSet(t.id);
if (res) {
const eff = res.effectiveTheme || res.theme;
@@ -145,6 +171,10 @@ function renderThemes(currentTheme) {
} catch (_) {}
document.getElementById('opt-follow-system').checked = false;
renderThemes(eff);
if (hadFocus) {
const next = grid.querySelector(`[data-theme="${t.id}"]`);
if (next) next.focus();
}
flashIfNotSaved(res);
}
});