// 设置页:Miuix Preference 分组 + 玻璃条目,含主题/遮罩/亮度/权限/网络交互 // Settings page: Miuix Preference groups + glass items with interactions for // theme / mask / brightness / permission / network window.loadSettings = function () { const page = document.querySelector('[data-page="settings"]'); if (page.dataset.loaded) return; page.dataset.loaded = '1'; page.innerHTML = `
显示
主题 跟随系统
玻璃效果
屏幕亮度
权限
通知使用权(媒体卡)
网络
webAPP 服务器地址
检查更新
关于
导出日志
版本 0.1.0
`; setupTheme(page); setupGlass(page); setupMask(page); setupNotificationAccess(page); setupBrightness(page); setupServerUrl(page); setupCheckUpdate(page); setupExportLog(page); }; // 判断当前是否深色主题(与 mask.js 逻辑一致) // Whether the current theme is dark (same logic as mask.js) function isDarkTheme() { const t = theme.get(); if (t === 'dark') return true; if (t === 'light') return false; return matchMedia('(prefers-color-scheme: dark)').matches; } // 主题三态循环:跟随系统 → 浅色 → 深色 // Theme tri-state cycle: system → light → dark function setupTheme(page) { const state = page.querySelector('#theme-state'); const refresh = () => { state.textContent = theme.label(theme.get()); }; refresh(); page.querySelector('#theme-item').onclick = () => { theme.cycle(); refresh(); window.mask.apply(); setupMask(page); // 主题切换后重算遮罩项的显示与状态 }; } // 玻璃效果开关:普通半透明 ↔ 液态玻璃(backdrop-filter 磨砂 + 边缘高光) // Glass effect toggle: plain translucent vs liquid glass function setupGlass(page) { const sw = page.querySelector('#glass-sw'); const refresh = () => sw.classList.toggle('on', glass.enabled()); refresh(); page.querySelector('#glass-item').onclick = () => { glass.setEnabled(!glass.enabled()); refresh(); }; } // 背景遮罩:开关 + 明暗度(仅夜间主题显示) // Wallpaper dim: toggle + opacity (shown only under dark theme) function setupMask(page) { const group = page.querySelector('#mask-group'); const maskItem = page.querySelector('#mask-item'); const alphaItem = page.querySelector('#mask-alpha-item'); const sw = page.querySelector('#mask-sw'); const slider = page.querySelector('#mask-slider'); const thumb = slider.querySelector('i'); const dark = isDarkTheme(); const show = dark; group.style.display = show ? '' : 'none'; maskItem.style.display = show ? '' : 'none'; alphaItem.style.display = show ? '' : 'none'; const refresh = () => { sw.classList.toggle('on', window.mask.enabled()); const a = window.mask.alpha(); thumb.style.left = (a * 100) + '%'; slider.style.setProperty('--fill', (a * 100) + '%'); }; refresh(); sw.onclick = () => { window.mask.setEnabled(!window.mask.enabled()); refresh(); }; makeSliderDraggable(slider, (a) => { window.mask.setAlpha(Math.round(a * 100) / 100); refresh(); }); } // 通知使用权授权项:异步查状态,未授权点击跳转系统授权页 // Notification-access item: async state check, tap to open the system grant page function setupNotificationAccess(page) { const item = page.querySelector('#notif-access'); const state = page.querySelector('#notif-access-state'); bridge.call('getNotificationAccess').then(granted => { state.textContent = granted ? '已开启 ✓' : '去开启 ›'; if (granted) state.style.color = 'var(--accent)'; }).catch(() => {}); item.onclick = () => { bridge.call('requestNotificationAccess').catch(() => {}); }; } // 屏幕亮度:未授权「修改系统设置」时跳授权页,已授权点击滑块调整系统亮度 // Screen brightness: jump to grant page when lacking WRITE_SETTINGS; adjust via // slider click once granted function setupBrightness(page) { const item = page.querySelector('#brightness-item'); const state = page.querySelector('#brightness-state'); let sliderEl = null; const renderSlider = (value) => { if (sliderEl) sliderEl.remove(); sliderEl = document.createElement('span'); sliderEl.className = 'slider brightness-slider'; sliderEl.innerHTML = ''; sliderEl.style.width = '160px'; const pct = value / 255 * 100; sliderEl.style.setProperty('--fill', pct + '%'); sliderEl.querySelector('i').style.left = pct + '%'; makeSliderDraggable(sliderEl, (ratio) => { const v = Math.round(ratio * 255); bridge.call('setSystemBrightness', v).then(() => renderSlider(v)).catch(() => {}); }); item.appendChild(sliderEl); }; const refresh = () => { bridge.call('canWriteSettings').then(canWrite => { if (!canWrite) { state.textContent = '去授权 ›'; if (sliderEl) { sliderEl.remove(); sliderEl = null; } } else { bridge.call('getSystemBrightness').then(v => { state.textContent = ''; renderSlider(v); }).catch(() => {}); } }).catch(() => {}); }; refresh(); item.onclick = () => { bridge.call('canWriteSettings').then(canWrite => { if (!canWrite) bridge.call('requestWriteSettings'); }).catch(() => {}); }; } // webAPP 服务器地址:点击展开输入框,保存后重新拉取清单 // webAPP server URL: expand an input on tap, re-fetch manifest after saving function setupServerUrl(page) { const item = page.querySelector('#server-url-item'); const state = page.querySelector('#server-url-state'); let editing = false; const startEdit = (current) => { editing = true; item.innerHTML = '' + ''; const input = item.querySelector('#server-url-input'); const saveBtn = item.querySelector('#server-url-save'); input.focus(); const save = () => { const v = input.value.trim(); if (!v) return; bridge.call('setServerUrl', v).then(() => { editing = false; refresh(); }).catch(() => {}); }; saveBtn.onclick = save; input.onkeydown = (e) => { if (e.key === 'Enter') save(); }; }; const refresh = () => { bridge.call('getServerUrl').then(url => { state.textContent = (url || '未设置') + ' ›'; }).catch(() => {}); }; refresh(); item.onclick = () => { if (editing) return; bridge.call('getServerUrl').then(startEdit).catch(() => startEdit('')); }; } // 检查更新:触发重新拉取 webAPP 清单 + 卡片目录,完成后提示 // Check update: re-fetch the webAPP manifest + card catalog, then show a hint function setupCheckUpdate(page) { const item = page.querySelector('#check-update-item'); const state = page.querySelector('#check-update-state'); item.onclick = () => { state.textContent = '检查中…'; bridge.call('refreshManifest').then(result => { let r = { added: 0, removed: 0, changed: 0 }; try { r = JSON.parse(result); } catch (e) {} const parts = []; if (r.added > 0) parts.push('新增 ' + r.added); if (r.removed > 0) parts.push('移除 ' + r.removed); if (r.changed > 0) parts.push('更新 ' + r.changed); state.textContent = parts.length ? parts.join(',') + ' ›' : '无更新 ›'; }).catch(() => { state.textContent = '失败 ›'; }); }; } // 导出日志:点击导出到 Download,显示结果 // Export log: tap to export to Download, show the result function setupExportLog(page) { const item = page.querySelector('#export-log-item'); const state = page.querySelector('#export-log-state'); item.onclick = () => { state.textContent = '导出中…'; bridge.call('exportLog').then(result => { state.textContent = result + ' ›'; }).catch(() => { state.textContent = '失败 ›'; }); }; } // 通用滑块拖动:touch 拖动实时回调(保留 click 兼容桌面调试) // Generic draggable slider: touch-drag with live callback (click kept for desktop) function makeSliderDraggable(slider, onRatio) { let dragging = false; const ratioAt = (clientX) => { const rect = slider.getBoundingClientRect(); return Math.min(1, Math.max(0, (clientX - rect.left) / rect.width)); }; slider.addEventListener('touchstart', (e) => { dragging = true; onRatio(ratioAt(e.touches[0].clientX)); }, { passive: true }); slider.addEventListener('touchmove', (e) => { if (dragging) onRatio(ratioAt(e.touches[0].clientX)); }, { passive: true }); slider.addEventListener('touchend', () => { dragging = false; }, { passive: true }); slider.addEventListener('click', (e) => onRatio(ratioAt(e.clientX))); }