package main import ( _ "embed" "encoding/base64" "fmt" "log" "os" "path/filepath" "strings" "time" ) //go:embed web/overlay.html var overlayHTML string //go:embed web/themes/aurora.html var themeAurora string //go:embed web/themes/starfield.html var themeStarfield string //go:embed web/themes/gradient.html var themeGradient string //go:embed web/themes/particles.html var themeParticles string //go:embed web/themes/fractal.html var themeFractal string //go:embed web/themes/text.html var themeText string var themeMap = map[ThemeName]string{ ThemeAurora: themeAurora, ThemeStar: themeStarfield, ThemeGradient: themeGradient, ThemeParticle: themeParticles, ThemeFractal: themeFractal, ThemeText: themeText, } func buildWallpaperHTML(cfg *Config) string { var bg string switch cfg.WallpaperType { case WPTheme: if t, ok := themeMap[cfg.Theme]; ok { bg = t } else { bg = themeAurora } case WPImage: if cfg.ImagePath != "" { src := imageToDataURI(cfg.ImagePath) if src != "" { bg = fmt.Sprintf(``, src) } } case WPBing: if p := getCurrentBingPath(); p != "" { if _, err := os.Stat(p); err == nil { src := imageToDataURI(p) if src != "" { bg = fmt.Sprintf(``, src) } } } case WPColor: if cfg.ColorGradient && cfg.Color2 != "" { bg = fmt.Sprintf(`
`, cfg.Color1, cfg.Color2) } else { bg = fmt.Sprintf(`
`, cfg.Color1) } } if bg == "" { bg = themeAurora } bgWrapped := fmt.Sprintf(`
%s
`, bg) if cfg.HideWallpaper { bgWrapped = `` } html := strings.Replace(overlayHTML, "{{BACKGROUND}}", bgWrapped, 1) html = strings.Replace(html, "{{LAYOUT}}", string(cfg.Layout), 1) var bodyClasses []string if cfg.HideTime { bodyClasses = append(bodyClasses, "hide-time") } if cfg.HideWeather { bodyClasses = append(bodyClasses, "hide-weather") } if cfg.HideZodiac { bodyClasses = append(bodyClasses, "hide-zodiac") } showSec := "false" if cfg.ShowSeconds { showSec = "true" } html = strings.Replace(html, "{{SHOW_SECONDS}}", showSec, 1) if cfg.HideAINews { bodyClasses = append(bodyClasses, "hide-ainews") } if cfg.HideKnowledge { bodyClasses = append(bodyClasses, "hide-knowledge") } if len(bodyClasses) > 0 { cls := strings.Join(bodyClasses, " ") html = strings.Replace(html, `layout-`+string(cfg.Layout), `layout-`+string(cfg.Layout)+" "+cls, 1) } // 注入自定义文字 if cfg.WallpaperType == WPTheme && cfg.Theme == ThemeText && cfg.WallpaperText != "" { escaped := strings.ReplaceAll(cfg.WallpaperText, `\`, `\\`) escaped = strings.ReplaceAll(escaped, `"`, `\"`) html = strings.Replace(html, "", `window.wallpaperText = "`+escaped+`";`, 1) } return html } func imageToDataURI(path string) string { data, err := os.ReadFile(path) if err != nil { log.Println("读取图片失败:", err) return "" } ext := strings.ToLower(filepath.Ext(path)) mime := "image/jpeg" switch ext { case ".png": mime = "image/png" case ".gif": mime = "image/gif" case ".webp": mime = "image/webp" case ".bmp": mime = "image/bmp" } return fmt.Sprintf("data:%s;base64,%s", mime, base64.StdEncoding.EncodeToString(data)) } func reloadWallpaper() { if wv == nil || wvHwnd == 0 { return } cfg := loadConfig() html := buildWallpaperHTML(cfg) select { case htmlQueue <- html: default: } procPostMessageW.Call(wvHwnd, wmSetHtml, 0, 0) go func() { time.Sleep(1 * time.Second) evalJS(fmt.Sprintf(`window.userZodiac = %q;`, cfg.Zodiac)) if cfg.Theme == ThemeText && cfg.WallpaperText != "" { evalJS(fmt.Sprintf(`window.wallpaperText = %q; var el=document.getElementById("wallpaper-text"); if(el){el.textContent=%q;}`, cfg.WallpaperText, cfg.WallpaperText)) } city := getCurrentCity() go fetchAndPushWeather(city) }() } func bingReloadImage() { if wv == nil || wvHwnd == 0 { return } p := getCurrentBingPath() if p == "" { return } src := imageToDataURI(p) if src == "" { return } evalJS(fmt.Sprintf(`var bg=document.querySelector('#bg-layer img'); if(bg) bg.src=%q;`, src)) }