// 设置页: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);
};
// 判断当前是否深色主题(与 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();
};
slider.onclick = (e) => {
const rect = slider.getBoundingClientRect();
const a = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width));
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 + '%';
sliderEl.onclick = (e) => {
e.stopPropagation();
const rect = sliderEl.getBoundingClientRect();
const v = Math.round(Math.min(255, Math.max(0, (e.clientX - rect.left) / rect.width)) * 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');
input.focus();
const save = () => {
bridge.call('setServerUrl', input.value.trim()).then(() => {
editing = false;
refresh();
}).catch(() => {});
};
input.onkeydown = (e) => { if (e.key === 'Enter') save(); };
input.onblur = () => { 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 n = 0;
try { n = JSON.parse(result).count || 0; } catch (e) {}
state.textContent = n > 0 ? '已更新 ' + n + ' 个 ›' : '无更新 ›';
}).catch(() => {
state.textContent = '失败 ›';
});
};
}