(function () { "use strict"; var config = window.DesktopClock; var background = window.DesktopClockBackground; var form = document.getElementById("settings-form"); var toast = document.getElementById("toast"); var preview = document.getElementById("background-preview"); var previewImage = document.getElementById("background-preview-image"); var backgroundEmpty = document.getElementById("background-empty"); var backgroundFile = document.getElementById("background-file"); var removeBackground = document.getElementById("remove-background"); var primaryColorInput = form.elements.primaryColor; var secondaryColorInput = form.elements.secondaryColor; var backgroundColorInput = form.elements.backgroundColor; var paletteMode = "dark"; var backgroundPaletteMode = "dark"; var settingsState = config.loadSettings(); var backgroundPresets = { dark: ["#101311", "#14242a", "#211925", "#2a2017", "#18271d"], light: ["#f3f4ef", "#eaf2f4", "#f4edf2", "#f8f0e4", "#ebf3e8"] }; var themePresets = { dark: [ { name: "青柠晨光", primary: "#b9f46a", secondary: "#ff9b74" }, { name: "冰川薄荷", primary: "#58d6c0", secondary: "#79aaff" }, { name: "莓果夜色", primary: "#e68ac0", secondary: "#f4b36a" }, { name: "琥珀余晖", primary: "#f3b25f", secondary: "#df755e" }, { name: "月光蓝", primary: "#91b5ff", secondary: "#c5a5ed" } ], light: [ { name: "林地绿", primary: "#547d1c", secondary: "#c34f2d" }, { name: "湖岸青", primary: "#167e76", secondary: "#3777bb" }, { name: "玫瑰红", primary: "#aa4a80", secondary: "#b46d26" }, { name: "陶土橙", primary: "#a85d16", secondary: "#a9403d" }, { name: "深海蓝", primary: "#3869a9", secondary: "#765aa3" } ] }; function cloneThemeColors(colors) { return { dark: Object.assign({}, colors.dark), light: Object.assign({}, colors.light) }; } function cloneBackgroundColors(colors) { return { dark: colors.dark, light: colors.light }; } function fillForm(settings) { Object.keys(settings).forEach(function (key) { var field = form.elements[key]; if (!field) return; if (field instanceof RadioNodeList) field.value = settings[key]; else if (field.type === "checkbox") field.checked = settings[key]; else field.value = settings[key]; }); } function readForm() { var themeColors = cloneThemeColors(settingsState.themeColors); var backgroundColors = cloneBackgroundColors(settingsState.backgroundColors); themeColors[paletteMode] = { primary: primaryColorInput.value, secondary: secondaryColorInput.value }; backgroundColors[backgroundPaletteMode] = backgroundColorInput.value; return { hourCycle: form.elements.hourCycle.value, showSeconds: form.elements.showSeconds.checked, showDate: form.elements.showDate.checked, theme: form.elements.theme.value, themeColors: themeColors, backgroundColorEnabled: form.elements.backgroundColorEnabled.checked, backgroundColors: backgroundColors, backgroundEnabled: form.elements.backgroundEnabled.checked, backgroundBlur: Number(form.elements.backgroundBlur.value), backgroundBrightness: Number(form.elements.backgroundBrightness.value), soundEnabled: form.elements.soundEnabled.checked, keepAwake: form.elements.keepAwake.checked }; } function applySettings(settings) { config.applyTheme(settings.theme, settings.themeColors); config.applyBackgroundColor(settings.backgroundColorEnabled, settings.backgroundColors, settings.theme); } function showMessage(message) { toast.textContent = message; toast.classList.add("is-visible"); clearTimeout(showMessage.timeout); showMessage.timeout = setTimeout(function () { toast.classList.remove("is-visible"); }, 1400); } function updatePaletteEditor() { var colors = settingsState.themeColors[paletteMode]; primaryColorInput.value = colors.primary; secondaryColorInput.value = colors.secondary; document.querySelectorAll("[data-palette]").forEach(function (tab) { var selected = tab.dataset.palette === paletteMode; tab.classList.toggle("is-active", selected); tab.setAttribute("aria-selected", String(selected)); }); document.querySelectorAll(".theme-preset").forEach(function (swatch, index) { var preset = themePresets[paletteMode][index]; swatch.style.setProperty("--primary", preset.primary); swatch.style.setProperty("--secondary", preset.secondary); swatch.title = preset.name; swatch.setAttribute("aria-label", preset.name); swatch.classList.toggle("is-selected", preset.primary === colors.primary && preset.secondary === colors.secondary); }); } function updateBackgroundColorEditor() { var color = settingsState.backgroundColors[backgroundPaletteMode]; backgroundColorInput.value = color; document.querySelectorAll("[data-background-palette]").forEach(function (tab) { var selected = tab.dataset.backgroundPalette === backgroundPaletteMode; tab.classList.toggle("is-active", selected); tab.setAttribute("aria-selected", String(selected)); }); document.querySelectorAll(".background-swatch").forEach(function (swatch, index) { var preset = backgroundPresets[backgroundPaletteMode][index]; swatch.style.setProperty("--swatch", preset); swatch.title = preset; swatch.classList.toggle("is-selected", preset.toLowerCase() === color.toLowerCase()); }); } function updateRangeLabels(settings) { document.getElementById("blur-value").textContent = settings.backgroundBlur + " px"; document.getElementById("brightness-value").textContent = settings.backgroundBrightness + "%"; background.setEffects(preview, settings); } async function loadBackgroundPreview(settings) { try { var url = await background.getUrl(); var hasImage = Boolean(url); previewImage.src = url; previewImage.hidden = !hasImage; backgroundEmpty.hidden = hasImage; removeBackground.disabled = !hasImage; updateRangeLabels(settings); } catch (error) { backgroundEmpty.textContent = "无法读取背景图片"; } } form.addEventListener("change", function (event) { if (event.target === backgroundFile) return; settingsState = config.saveSettings(readForm()); applySettings(settingsState); if (event.target.name === "theme") { paletteMode = config.getEffectiveTheme(settingsState.theme); backgroundPaletteMode = paletteMode; } updatePaletteEditor(); updateBackgroundColorEditor(); showMessage("设置已保存"); }); form.addEventListener("input", function (event) { if (event.target.type === "range") updateRangeLabels(readForm()); if (event.target === primaryColorInput || event.target === secondaryColorInput) { applySettings(readForm()); } if (event.target === backgroundColorInput) { form.elements.backgroundColorEnabled.checked = true; var backgroundSettings = readForm(); applySettings(backgroundSettings); } }); document.querySelectorAll("[data-palette]").forEach(function (tab) { tab.addEventListener("click", function () { var pendingSettings = readForm(); settingsState.themeColors = pendingSettings.themeColors; paletteMode = tab.dataset.palette; updatePaletteEditor(); }); }); document.querySelectorAll(".theme-preset").forEach(function (swatch, index) { swatch.addEventListener("click", function () { var preset = themePresets[paletteMode][index]; primaryColorInput.value = preset.primary; secondaryColorInput.value = preset.secondary; settingsState = config.saveSettings(readForm()); applySettings(settingsState); updatePaletteEditor(); showMessage("主题配色已更新"); }); }); document.querySelectorAll("[data-background-palette]").forEach(function (tab) { tab.addEventListener("click", function () { var pendingSettings = readForm(); settingsState.backgroundColors = pendingSettings.backgroundColors; backgroundPaletteMode = tab.dataset.backgroundPalette; updateBackgroundColorEditor(); }); }); document.querySelectorAll(".background-swatch").forEach(function (swatch, index) { swatch.addEventListener("click", function () { backgroundColorInput.value = backgroundPresets[backgroundPaletteMode][index]; form.elements.backgroundColorEnabled.checked = true; settingsState = config.saveSettings(readForm()); applySettings(settingsState); updateBackgroundColorEditor(); showMessage("背景颜色已更新"); }); }); backgroundFile.addEventListener("change", async function () { var file = backgroundFile.files[0]; if (!file) return; if (!file.type.startsWith("image/")) { showMessage("请选择有效的图片文件"); backgroundFile.value = ""; return; } if (file.size > 20 * 1024 * 1024) { showMessage("图片不能超过 20 MB"); backgroundFile.value = ""; return; } try { await background.save(file); form.elements.backgroundEnabled.checked = true; settingsState = config.saveSettings(readForm()); await loadBackgroundPreview(settingsState); showMessage("背景已更新"); } catch (error) { showMessage("无法保存背景图片"); } backgroundFile.value = ""; }); removeBackground.addEventListener("click", async function () { try { await background.remove(); form.elements.backgroundEnabled.checked = false; settingsState = config.saveSettings(readForm()); await loadBackgroundPreview(settingsState); showMessage("背景已移除"); } catch (error) { showMessage("无法移除背景图片"); } }); document.getElementById("reset-settings").addEventListener("click", function () { settingsState = config.saveSettings(config.defaults); fillForm(settingsState); paletteMode = config.getEffectiveTheme(settingsState.theme); backgroundPaletteMode = paletteMode; applySettings(settingsState); updatePaletteEditor(); updateBackgroundColorEditor(); updateRangeLabels(settingsState); showMessage("设置已恢复"); }); fillForm(settingsState); paletteMode = config.getEffectiveTheme(settingsState.theme); backgroundPaletteMode = paletteMode; applySettings(settingsState); updatePaletteEditor(); updateBackgroundColorEditor(); loadBackgroundPreview(settingsState); }());