Files
u-desktop/web/settings.html
绝尘 92bca936d8 修复: 打开设置窗口不再触发桌面刷新
- enableBing() 调用加 initDone 守卫,初始化阶段跳过
2026-05-26 12:21:02 +08:00

751 lines
28 KiB
HTML

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<style>
:root {
--bg: #0f0f1a;
--card-bg: rgba(255,255,255,0.04);
--card-border: rgba(255,255,255,0.06);
--card-divider: rgba(255,255,255,0.04);
--text: #e0e0e0;
--text-strong: #fff;
--text-weak: rgba(255,255,255,0.25);
--text-muted: rgba(255,255,255,0.5);
--input-bg: rgba(255,255,255,0.08);
--input-border: rgba(255,255,255,0.1);
--input-border-focus: #4f8cff;
--accent: #4f8cff;
--toggle-track: rgba(255,255,255,0.1);
--toggle-thumb: rgba(255,255,255,0.5);
--option-bg: #1a1a2e;
--footer-color: rgba(255,255,255,0.3);
}
.light {
--bg: #f5f5f5;
--card-bg: rgba(0,0,0,0.03);
--card-border: rgba(0,0,0,0.08);
--card-divider: rgba(0,0,0,0.05);
--text: #333;
--text-strong: #111;
--text-weak: rgba(0,0,0,0.35);
--text-muted: rgba(0,0,0,0.55);
--input-bg: rgba(0,0,0,0.04);
--input-border: rgba(0,0,0,0.12);
--input-border-focus: #2b6cb0;
--accent: #2b6cb0;
--toggle-track: rgba(0,0,0,0.12);
--toggle-thumb: rgba(0,0,0,0.45);
--option-bg: #fff;
--footer-color: rgba(0,0,0,0.35);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, "Segoe UI", "Microsoft YaHei", sans-serif;
background: var(--bg);
color: var(--text);
padding: 16px 18px;
user-select: none;
-webkit-font-smoothing: antialiased;
overflow-y: auto;
}
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.22); }
.light ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.12); }
.light ::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.22); }
.header { margin-bottom: 14px; }
.header h1 { font-size: 16px; font-weight: 600; color: var(--text-strong); }
.header p { font-size: 11px; color: var(--text-weak); margin-top: 2px; }
.section { margin-bottom: 12px; }
.section-label {
font-size: 10px; font-weight: 600; color: var(--text-weak);
text-transform: uppercase; letter-spacing: 1.5px;
margin-bottom: 4px; padding-left: 2px;
}
.card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 8px;
}
.item {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 14px;
}
.item + .item { border-top: 1px solid var(--card-divider); }
.item-label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.item-desc { font-size: 10px; color: var(--text-weak); margin-top: 1px; }
.item-sub { padding-left: 32px; }
/* Toggle */
.switch { position: relative; width: 36px; height: 20px; flex-shrink: 0; }
.switch input { display: none; }
.switch .track {
position: absolute; inset: 0;
background: var(--toggle-track);
border-radius: 10px; cursor: pointer; transition: background 0.2s;
}
.switch .thumb {
position: absolute; width: 14px; height: 14px; top: 3px; left: 3px;
background: var(--toggle-thumb);
border-radius: 50%; transition: all 0.2s; pointer-events: none;
}
.switch input:checked + .track { background: var(--accent); }
.switch input:checked + .track .thumb { transform: translateX(16px); background: var(--text-strong); }
/* Select */
select {
background: var(--input-bg); border: 1px solid var(--input-border);
border-radius: 6px; color: var(--text); font-size: 11px; padding: 3px 6px;
font-family: inherit; cursor: pointer; outline: none;
min-width: 80px; max-width: 160px;
}
select:focus { border-color: var(--input-border-focus); }
select option { background: var(--option-bg); color: var(--text); }
/* Button */
.btn {
background: var(--input-bg); border: 1px solid var(--input-border);
border-radius: 6px; color: var(--text); font-size: 11px; padding: 4px 10px;
font-family: inherit; cursor: pointer; transition: background 0.15s; white-space: nowrap;
}
.btn:hover { background: var(--card-border); }
.btn:active { background: var(--input-bg); }
.btn.active { background: var(--accent); border-color: var(--accent); color: var(--text-strong); }
.btn-sm { padding: 3px 8px; font-size: 10px; }
.btn-group { display: flex; gap: 4px; }
.radio-tabs { display: flex; flex-wrap: wrap; gap: 4px; }
.bing-nav { display: flex; gap: 4px; align-items: center; }
.wp-type-section { display: none; }
.wp-type-section.visible { display: block; }
input[type="text"] {
background: var(--input-bg); border: 1px solid var(--input-border);
border-radius: 6px; color: var(--text); font-size: 11px; padding: 4px 8px;
font-family: inherit; outline: none; width: 140px;
}
input[type="text"]:focus { border-color: var(--input-border-focus); }
/* City Picker */
.city-picker {
position: relative;
background: var(--input-bg); border: 1px solid var(--input-border);
border-radius: 6px; padding: 4px 24px 4px 8px; cursor: pointer;
font-size: 11px; min-width: 140px; max-width: 180px;
}
.city-picker:focus, .city-picker.open { border-color: var(--input-border-focus); }
.city-picker-text { color: var(--text); }
.city-picker-arrow {
position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
color: var(--text-weak); font-size: 10px; pointer-events: none;
}
.city-panel {
display: none; position: absolute; right: -1px; bottom: calc(100% + 4px);
background: var(--option-bg); border: 1px solid var(--input-border);
border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.25);
z-index: 1000; width: 260px; height: 200px; overflow: hidden;
}
.city-picker.open .city-panel { display: flex; }
.city-col {
flex: 1; overflow-y: auto; border-right: 1px solid var(--card-divider);
}
.city-col:last-child { border-right: none; }
.city-col div {
padding: 5px 10px; font-size: 11px; color: var(--text); cursor: pointer;
white-space: nowrap;
}
.city-col div:hover { background: var(--input-bg); }
.city-col div.active { color: var(--accent); font-weight: 600; }
/* Saved colors */
.color-swatch {
width: 28px; height: 28px; border-radius: 6px; cursor: pointer;
border: 2px solid transparent; transition: border-color 0.15s; position: relative;
}
.color-swatch:hover { border-color: var(--accent); }
.color-swatch .del {
display: none; position: absolute; top: -6px; right: -6px;
width: 14px; height: 14px; border-radius: 50%;
background: #e53e3e; color: #fff; font-size: 9px; line-height: 14px;
text-align: center; cursor: pointer;
}
.color-swatch:hover .del { display: block; }
.footer {
text-align: center; font-size: 11px; color: var(--footer-color); margin-top: 12px;
padding: 6px 0; letter-spacing: 0.5px;
}
</style>
</head>
<body>
<div class="header">
<h1>桌面设置</h1>
<p>壁纸 · 布局 · 信息显示</p>
</div>
<!-- 显示控制 -->
<div class="section">
<div class="section-label">显示控制</div>
<div class="card">
<div class="item">
<div><div class="item-label">显示壁纸</div></div>
<label class="switch"><input type="checkbox" id="wallpaper" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item">
<div><div class="item-label">时间日期</div></div>
<label class="switch"><input type="checkbox" id="time" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item item-sub">
<div><div class="item-label">显示秒</div></div>
<label class="switch"><input type="checkbox" id="showSeconds" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item">
<div><div class="item-label">天气信息</div></div>
<label class="switch"><input type="checkbox" id="weather" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item">
<div><div class="item-label">星座运势</div></div>
<label class="switch"><input type="checkbox" id="zodiacCard" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item">
<div><div class="item-label">知识卡片</div></div>
<label class="switch"><input type="checkbox" id="knowledgeCard" checked><span class="track"><span class="thumb"></span></span></label>
</div>
<div class="item">
<div><div class="item-label">AI 资讯</div></div>
<label class="switch"><input type="checkbox" id="ainewsCard" checked><span class="track"><span class="thumb"></span></span></label>
</div>
</div>
</div>
<!-- 壁纸类型 -->
<div class="section">
<div class="section-label">壁纸类型</div>
<div class="card">
<div class="item">
<div class="item-label">类型选择</div>
<div class="radio-tabs" id="wpTypeTabs">
<button class="btn" data-type="theme">主题</button>
<button class="btn" data-type="image">本地图片</button>
<button class="btn" data-type="bing">Bing</button>
<button class="btn" data-type="color">纯色/渐变</button>
</div>
</div>
</div>
</div>
<!-- 主题选择 -->
<div class="section wp-type-section" id="sec-theme">
<div class="section-label">壁纸主题</div>
<div class="card">
<div class="item">
<div class="item-label">选择主题</div>
<select id="themeSelect"></select>
</div>
<div class="item" id="textInputRow" style="display:none">
<div class="item-label">自定义文字</div>
<input type="text" id="wallpaperText" placeholder="输入显示文字">
</div>
</div>
</div>
<!-- 本地图片 -->
<div class="section wp-type-section" id="sec-image">
<div class="section-label">本地图片</div>
<div class="card">
<div class="item">
<div class="item-desc" id="imagePathDisplay">未选择图片</div>
<button class="btn" id="btnPickImage">选择图片</button>
</div>
</div>
</div>
<!-- Bing -->
<div class="section wp-type-section" id="sec-bing">
<div class="section-label">Bing 每日壁纸</div>
<div class="card">
<div class="item">
<div style="display:flex;align-items:center;gap:8px;flex:1;min-width:0">
<img id="bingPreview" style="width:64px;height:40px;object-fit:cover;border-radius:4px;flex-shrink:0;display:none">
<div style="min-width:0;overflow:hidden">
<div class="item-label" id="bingCopyright" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Bing 每日壁纸</div>
<div class="item-desc" id="bingIdx"></div>
</div>
</div>
<div class="bing-nav" style="flex-shrink:0">
<button class="btn btn-sm" id="btnBingPrev"></button>
<button class="btn btn-sm" id="btnBingNext"></button>
<button class="btn btn-sm" id="btnBingFav"></button>
</div>
</div>
<div class="item">
<div><div class="item-label">定时切换</div><div class="item-desc">每小时自动切换壁纸</div></div>
<label class="switch"><input type="checkbox" id="bingAutoRefresh"><span class="track"><span class="thumb"></span></span></label>
</div>
</div>
<div id="bingFavSection" style="display:none;margin-top:6px">
<div class="section-label">收藏列表</div>
<div class="card" id="bingFavList"></div>
</div>
</div>
<!-- 纯色/渐变 -->
<div class="section wp-type-section" id="sec-color">
<div class="section-label">纯色 / 渐变</div>
<div class="card">
<div class="item">
<div class="item-label">选择颜色</div>
<div class="btn-group">
<button class="btn" id="btnSolidColor">纯色</button>
<button class="btn" id="btnGradientColor">渐变</button>
</div>
</div>
<div class="item" id="currentColorRow" style="display:none">
<div class="item-label">当前颜色</div>
<div style="display:flex;align-items:center;gap:6px">
<span id="currentColorPreview" style="display:inline-block;width:24px;height:16px;border-radius:3px;border:1px solid var(--input-border)"></span>
<button class="btn btn-sm" id="btnSaveColor">收藏</button>
</div>
</div>
</div>
<div id="savedColorsSection" style="display:none;margin-top:6px">
<div class="card" id="savedColorsGrid" style="padding:8px 12px;display:flex;flex-wrap:wrap;gap:6px">
</div>
</div>
</div>
<!-- 布局 -->
<div class="section">
<div class="section-label">布局</div>
<div class="card">
<div class="item">
<div class="item-label">信息布局</div>
<select id="layout">
<option value="single">合并卡片</option>
<option value="multi">独立卡片</option>
</select>
</div>
</div>
</div>
<!-- 相册 -->
<div class="section">
<div class="section-label">相册</div>
<div class="card">
<div class="item">
<div class="item-desc" id="photoDirDisplay">未选择目录</div>
<div class="btn-group">
<button class="btn" id="btnPickPhotoDir">选择目录</button>
<button class="btn btn-sm" id="btnClearPhotoDir" style="display:none">清除</button>
</div>
</div>
<div class="item">
<div class="item-label">切换间隔</div>
<select id="photoInterval">
<option value="5">5 秒</option>
<option value="10">10 秒</option>
<option value="15" selected>15 秒</option>
<option value="20">20 秒</option>
<option value="30">30 秒</option>
<option value="60">60 秒</option>
</select>
</div>
</div>
</div>
<!-- 星座 + 城市 -->
<div class="section">
<div class="section-label">个性化</div>
<div class="card">
<div class="item">
<div class="item-label">我的星座</div>
<select id="zodiacSelect">
<option>白羊座</option><option>金牛座</option><option>双子座</option>
<option>巨蟹座</option><option>狮子座</option><option>处女座</option>
<option>天秤座</option><option>天蝎座</option><option>射手座</option>
<option>摩羯座</option><option>水瓶座</option><option>双鱼座</option>
</select>
</div>
<div class="item">
<div><div class="item-label">知识关键字</div><div class="item-desc">AI 将根据关键字生成知识小卡片</div></div>
<input type="text" id="knowledgeKeyword" placeholder="如: 历史、科学、冷知识">
</div>
<div class="item">
<div><div class="item-label">知识提示词</div><div class="item-desc">自定义生成风格,不会显示在桌面</div></div>
<input type="text" id="knowledgePrompt" placeholder="如: 用幽默口吻、面向程序员">
</div>
<div class="item" style="position:relative">
<div class="item-label">天气城市</div>
<div class="city-picker" id="cityPicker" tabindex="0">
<span class="city-picker-text" id="cityPickerText">未选择</span>
<span class="city-picker-arrow"></span>
<div class="city-panel" id="cityPanel">
<div class="city-col" id="provCol"></div>
<div class="city-col" id="cityCol"></div>
</div>
</div>
</div>
</div>
</div>
<div class="footer">u-desktop v1.0</div>
<script>
var toggleKeys = ['wallpaper', 'time', 'showSeconds', 'weather', 'zodiacCard', 'knowledgeCard', 'ainewsCard'];
var initDone = false;
function sendToggle() {
if (!initDone) return;
var data = {};
toggleKeys.forEach(function(k) { data[k] = document.getElementById(k).checked; });
if (window.saveToggles) window.saveToggles(JSON.stringify(data));
}
toggleKeys.forEach(function(k) {
document.getElementById(k).addEventListener('change', sendToggle);
});
document.getElementById('layout').addEventListener('change', function() {
if (window.saveLayout) window.saveLayout(this.value);
});
document.getElementById('zodiacSelect').addEventListener('change', function() {
if (window.saveZodiac) window.saveZodiac(this.value);
});
var kwTimer = null;
document.getElementById('knowledgeKeyword').addEventListener('input', function() {
clearTimeout(kwTimer);
var val = this.value;
kwTimer = setTimeout(function() {
if (window.saveKnowledgeKeyword) window.saveKnowledgeKeyword(val);
}, 500);
});
var kpTimer = null;
document.getElementById('knowledgePrompt').addEventListener('input', function() {
clearTimeout(kpTimer);
var val = this.value;
kpTimer = setTimeout(function() {
if (window.saveKnowledgePrompt) window.saveKnowledgePrompt(val);
}, 500);
});
// City picker
var cityMap = {};
var selectedCityId = '';
var selectedCityName = '';
var picker = document.getElementById('cityPicker');
var pickerText = document.getElementById('cityPickerText');
var provCol = document.getElementById('provCol');
var cityCol = document.getElementById('cityCol');
var activeProv = '';
function renderProvinces(provinces) {
provCol.innerHTML = '';
provinces.forEach(function(p) {
var div = document.createElement('div');
div.textContent = p;
if (p === activeProv) div.className = 'active';
div.addEventListener('click', function(e) {
e.stopPropagation();
activeProv = p;
renderProvinces(provinces);
renderCities(p);
});
provCol.appendChild(div);
});
}
function renderCities(prov) {
cityCol.innerHTML = '';
var list = cityMap[prov] || [];
list.forEach(function(c) {
var div = document.createElement('div');
div.textContent = c.name;
if (c.id === selectedCityId) div.className = 'active';
div.addEventListener('click', function(e) {
e.stopPropagation();
selectedCityId = c.id;
selectedCityName = c.name;
pickerText.textContent = activeProv + ' · ' + c.name;
picker.classList.remove('open');
renderCities(prov);
if (window.saveCity) window.saveCity(c.id);
});
cityCol.appendChild(div);
});
}
picker.addEventListener('click', function(e) {
e.stopPropagation();
this.classList.toggle('open');
this.focus();
});
document.addEventListener('click', function(e) {
if (!picker.contains(e.target)) picker.classList.remove('open');
});
document.getElementById('themeSelect').addEventListener('change', function() {
if (window.saveWallpaperType) window.saveWallpaperType('theme', this.value);
document.getElementById('textInputRow').style.display = this.value === 'text' ? 'flex' : 'none';
});
document.getElementById('btnPickPhotoDir').addEventListener('click', function() {
if (!window.pickPhotoDir) return;
window.pickPhotoDir().then(function(dir) {
if (dir) {
document.getElementById('photoDirDisplay').textContent = dir;
document.getElementById('btnClearPhotoDir').style.display = '';
}
});
});
document.getElementById('btnClearPhotoDir').addEventListener('click', function() {
if (!window.clearPhotoDir) return;
window.clearPhotoDir().then(function() {
document.getElementById('photoDirDisplay').textContent = '未选择目录';
document.getElementById('btnClearPhotoDir').style.display = 'none';
});
});
document.getElementById('photoInterval').addEventListener('change', function() {
if (window.savePhotoInterval) window.savePhotoInterval(parseInt(this.value));
});
var textTimer = null;
document.getElementById('wallpaperText').addEventListener('input', function() {
clearTimeout(textTimer);
var val = this.value;
textTimer = setTimeout(function() {
if (window.saveWallpaperText) window.saveWallpaperText(val);
}, 500);
});
var wpTypeTabs = document.querySelectorAll('#wpTypeTabs .btn');
var currentWpType = '';
function setWpType(type) {
wpTypeTabs.forEach(function(b) { b.classList.toggle('active', b.dataset.type === type); });
document.querySelectorAll('.wp-type-section').forEach(function(s) { s.classList.remove('visible'); });
var sec = document.getElementById('sec-' + type);
if (sec) sec.classList.add('visible');
if (initDone && type === 'bing' && currentWpType !== 'bing') {
if (window.enableBing) window.enableBing();
}
currentWpType = type;
}
wpTypeTabs.forEach(function(b) {
b.addEventListener('click', function() { setWpType(b.dataset.type); });
});
document.getElementById('btnPickImage').addEventListener('click', function() {
if (!window.pickLocalImage) return;
window.pickLocalImage().then(function(path) {
if (path) document.getElementById('imagePathDisplay').textContent = path;
});
});
function updateBingUI(stateJson) {
if (!stateJson) return;
var s = JSON.parse(stateJson);
document.getElementById('btnBingFav').textContent = s.label;
document.getElementById('bingCopyright').textContent = s.copyright || 'Bing 每日壁纸';
document.getElementById('bingIdx').textContent = (s.total > 0) ? ((s.idx + 1) + ' / ' + s.total) : '';
// load preview thumbnail
if (s.filename && window.bingThumbDataURI) {
var preview = document.getElementById('bingPreview');
window.bingThumbDataURI(s.filename).then(function(uri) {
if (uri) { preview.src = uri; preview.style.display = 'block'; }
});
}
}
function loadBingFavorites() {
if (!window.getBingFavorites) return;
window.getBingFavorites().then(function(json) {
var favs = JSON.parse(json);
var sec = document.getElementById('bingFavSection');
var list = document.getElementById('bingFavList');
list.innerHTML = '';
if (!favs || favs.length === 0) { sec.style.display = 'none'; return; }
sec.style.display = 'block';
list.style.cssText = 'padding:8px 12px;display:flex;flex-wrap:wrap;gap:6px';
favs.forEach(function(f) {
var img = document.createElement('img');
img.style.cssText = 'width:64px;height:40px;object-fit:cover;border-radius:4px;cursor:pointer;border:2px solid transparent;transition:border-color 0.15s';
img.title = f.copyright + ' (' + f.date + ')';
img.addEventListener('click', function() {
if (window.bingSetByIdx) window.bingSetByIdx(f.idx).then(function(s) { updateBingUI(s); });
});
img.addEventListener('mouseenter', function() { this.style.borderColor = 'var(--accent)'; });
img.addEventListener('mouseleave', function() { this.style.borderColor = 'transparent'; });
list.appendChild(img);
if (window.bingThumbDataURI) {
window.bingThumbDataURI(f.filename).then(function(uri) {
if (uri) img.src = uri;
});
}
});
});
}
document.getElementById('btnBingPrev').addEventListener('click', function() {
if (window.bingNext) window.bingNext().then(function(s) { updateBingUI(s); });
});
document.getElementById('btnBingNext').addEventListener('click', function() {
if (window.bingPrev) window.bingPrev().then(function(s) { updateBingUI(s); });
});
document.getElementById('btnBingFav').addEventListener('click', function() {
if (window.bingToggleFavorite) {
window.bingToggleFavorite().then(function(s) { updateBingUI(s); loadBingFavorites(); });
}
});
document.getElementById('bingAutoRefresh').addEventListener('change', function() {
if (window.saveBingAutoRefresh) window.saveBingAutoRefresh(this.checked);
});
document.getElementById('btnSolidColor').addEventListener('click', function() {
if (window.pickSolidColor) {
window.pickSolidColor().then(function(c) {
if (c) { currentColor1 = c; currentColor2 = ''; currentGradient = false; updateColorPreview(); }
});
}
});
document.getElementById('btnGradientColor').addEventListener('click', function() {
if (window.pickGradientColor) {
window.pickGradientColor().then(function(res) {
if (res) {
var parts = res.split(',');
currentColor1 = parts[0]; currentColor2 = parts[1] || ''; currentGradient = true;
updateColorPreview();
}
});
}
});
// Color favorites
var currentColor1 = '', currentColor2 = '', currentGradient = false;
var savedColors = [];
function updateColorPreview() {
var row = document.getElementById('currentColorRow');
var preview = document.getElementById('currentColorPreview');
if (!currentColor1) { row.style.display = 'none'; return; }
row.style.display = 'flex';
if (currentGradient && currentColor2) {
preview.style.background = 'linear-gradient(135deg,' + currentColor1 + ',' + currentColor2 + ')';
} else {
preview.style.background = currentColor1;
}
}
function renderSavedColors() {
var sec = document.getElementById('savedColorsSection');
var grid = document.getElementById('savedColorsGrid');
grid.innerHTML = '';
if (!savedColors || savedColors.length === 0) { sec.style.display = 'none'; return; }
sec.style.display = 'block';
savedColors.forEach(function(sc, idx) {
var swatch = document.createElement('div');
swatch.className = 'color-swatch';
if (sc.gradient && sc.color2) {
swatch.style.background = 'linear-gradient(135deg,' + sc.color1 + ',' + sc.color2 + ')';
} else {
swatch.style.background = sc.color1;
}
var del = document.createElement('span');
del.className = 'del'; del.textContent = 'x';
del.addEventListener('click', function(e) {
e.stopPropagation();
if (window.removeSavedColor) window.removeSavedColor(idx).then(function() {
savedColors.splice(idx, 1);
renderSavedColors();
});
});
swatch.appendChild(del);
swatch.addEventListener('click', function() {
if (window.applySavedColor) window.applySavedColor(idx);
currentColor1 = sc.color1; currentColor2 = sc.color2; currentGradient = sc.gradient;
updateColorPreview();
});
grid.appendChild(swatch);
});
}
document.getElementById('btnSaveColor').addEventListener('click', function() {
if (!currentColor1) return;
if (window.addSavedColor) window.addSavedColor(currentColor1, currentColor2, currentGradient).then(function() {
savedColors.push({color1: currentColor1, color2: currentColor2, gradient: currentGradient});
renderSavedColors();
});
});
if (window.loadAllSettings) {
window.loadAllSettings().then(function(raw) {
var s = JSON.parse(raw);
// Apply system theme
if (s.lightTheme) {
document.documentElement.className = 'light';
}
// Province-city cascade
cityMap = s.citiesByProv || {};
selectedCityId = s.city || '';
activeProv = '';
if (s.provinces && s.provinces.length) {
for (var p in cityMap) {
for (var ci = 0; ci < cityMap[p].length; ci++) {
if (cityMap[p][ci].id === selectedCityId) { activeProv = p; selectedCityName = cityMap[p][ci].name; break; }
}
if (activeProv) break;
}
renderProvinces(s.provinces);
if (activeProv) renderCities(activeProv);
if (activeProv && selectedCityName) {
pickerText.textContent = activeProv + ' · ' + selectedCityName;
}
}
if (s.themes && s.themes.length) {
var themeSel = document.getElementById('themeSelect');
s.themes.forEach(function(t) {
var opt = document.createElement('option');
opt.value = t.value;
opt.textContent = t.label;
themeSel.appendChild(opt);
});
}
toggleKeys.forEach(function(k) {
if (s[k] !== undefined) document.getElementById(k).checked = s[k];
});
if (s.layout) document.getElementById('layout').value = s.layout;
if (s.zodiac) document.getElementById('zodiacSelect').value = s.zodiac;
if (s.theme) document.getElementById('themeSelect').value = s.theme;
if (s.wallpaperText) document.getElementById('wallpaperText').value = s.wallpaperText;
if (s.imagePath) document.getElementById('imagePathDisplay').textContent = s.imagePath;
if (s.knowledgeKeyword) document.getElementById('knowledgeKeyword').value = s.knowledgeKeyword;
if (s.knowledgePrompt) document.getElementById('knowledgePrompt').value = s.knowledgePrompt;
if (s.theme === 'text') document.getElementById('textInputRow').style.display = 'flex';
// Photo state
if (s.photoDir) {
document.getElementById('photoDirDisplay').textContent = s.photoDir;
document.getElementById('btnClearPhotoDir').style.display = '';
}
if (s.photoInterval) document.getElementById('photoInterval').value = s.photoInterval;
// Color state
if (s.color1) { currentColor1 = s.color1; currentColor2 = s.color2 || ''; currentGradient = s.colorGradient || false; }
if (s.wallpaperType === 'color') updateColorPreview();
savedColors = s.savedColors || [];
renderSavedColors();
setWpType(s.wallpaperType || 'theme');
// Bing state
if (s.wallpaperType === 'bing' && window.getBingInfo) {
window.getBingInfo().then(function(si) { updateBingUI(si); });
}
if (s.wallpaperType === 'bing') loadBingFavorites();
if (s.bingAutoRefresh !== undefined) document.getElementById('bingAutoRefresh').checked = s.bingAutoRefresh;
// resize window to fit content
setTimeout(function() {
var el = document.documentElement;
var cw = el.scrollWidth;
var ch = el.scrollHeight + 8;
if (window.resizeToFit) window.resizeToFit(cw, ch);
}, 100);
initDone = true;
});
}
</script>
</body>
</html>