- 星座运势: 天聚数行API集成,5维进度条+幸运标签+今日概述 - AI资讯: 天聚数行API,图文布局5条展示,文件缓存2小时刷新 - 知识卡片: AI生成,关键字+提示词配置,30分钟刷新 - 桌面设置: 独立WebView2窗口,760x1350,含壁纸/布局/城市/颜色等配置 - 显示控制: 壁纸/时间/天气/星座/知识/AI资讯独立开关,秒显示开关 - 文件缓存: 星座运势+AI资讯缓存到本地,启动即显示上次数据 - initDone防抖: 防止设置窗口初始化触发卡片重载
181 lines
4.5 KiB
Go
181 lines
4.5 KiB
Go
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(`<img src="%s" style="position:fixed;top:0;left:0;width:100%%;height:100%%;object-fit:cover;z-index:1;">`, src)
|
|
}
|
|
}
|
|
case WPBing:
|
|
if p := getCurrentBingPath(); p != "" {
|
|
if _, err := os.Stat(p); err == nil {
|
|
src := imageToDataURI(p)
|
|
if src != "" {
|
|
bg = fmt.Sprintf(`<img src="%s" style="position:fixed;top:0;left:0;width:100%%;height:100%%;object-fit:cover;z-index:1;">`, src)
|
|
}
|
|
}
|
|
}
|
|
case WPColor:
|
|
if cfg.ColorGradient && cfg.Color2 != "" {
|
|
bg = fmt.Sprintf(`<div style="position:fixed;top:0;left:0;width:100%%;height:100%%;z-index:1;background:linear-gradient(135deg,%s,%s);"></div>`, cfg.Color1, cfg.Color2)
|
|
} else {
|
|
bg = fmt.Sprintf(`<div style="position:fixed;top:0;left:0;width:100%%;height:100%%;z-index:1;background:%s;"></div>`, cfg.Color1)
|
|
}
|
|
}
|
|
|
|
if bg == "" {
|
|
bg = themeAurora
|
|
}
|
|
bgWrapped := fmt.Sprintf(`<div id="bg-layer">%s</div>`, bg)
|
|
if cfg.HideWallpaper {
|
|
bgWrapped = `<div id="bg-layer" style="display:none"></div>`
|
|
}
|
|
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, "</script>", `window.wallpaperText = "`+escaped+`";</script>`, 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))
|
|
}
|