1package config
2
3import (
4 "github.com/bnema/dumber/internal/application/dto"
5 "github.com/bnema/dumber/internal/application/port"
6)
7
8// BuildSystemviewConfigPayload projects the full config into the stable DTO used by
9// the settings page across engines.
10func BuildSystemviewConfigPayload(cfg *Config, hw *port.HardwareInfo) dto.SystemviewConfigPayload {
11 payload := dto.SystemviewConfigPayload{
12 SearchShortcuts: map[string]dto.SearchShortcut{},
13 }
14 if cfg == nil {
15 return payload
16 }
17
18 perfCfg := PerformanceConfigFromEngine(&cfg.Engine)
19 resolved := ResolvePerformanceProfile(&perfCfg, hw)
20
21 payload.Appearance = buildSystemviewAppearancePayload(cfg.Appearance)
22 payload.DefaultUIScale = cfg.DefaultUIScale
23 payload.DefaultSearchEngine = cfg.DefaultSearchEngine
24 payload.SearchShortcuts = buildSystemviewSearchShortcutsPayload(cfg.SearchShortcuts)
25 payload.EngineType = cfg.Engine.ResolveEngineType()
26 payload.Performance = dto.SystemviewPerformancePayload{
27 Profile: string(cfg.Engine.Profile),
28 Custom: dto.SystemviewCustomPerformancePayload{
29 SkiaCPUThreads: cfg.Engine.WebKit.SkiaCPUPaintingThreads,
30 SkiaGPUThreads: cfg.Engine.WebKit.SkiaGPUPaintingThreads,
31 WebProcessMemoryMB: cfg.Engine.WebKit.WebProcessMemoryLimitMB,
32 NetworkProcessMemoryMB: cfg.Engine.WebKit.NetworkProcessMemoryLimitMB,
33 WebViewPoolPrewarm: cfg.Engine.PoolPrewarmCount,
34 },
35 Resolved: dto.SystemviewResolvedPerformancePayload{
36 SkiaCPUThreads: resolved.SkiaCPUPaintingThreads,
37 SkiaGPUThreads: resolved.SkiaGPUPaintingThreads,
38 WebProcessMemoryMB: resolved.WebProcessMemoryLimitMB,
39 NetworkProcessMemoryMB: resolved.NetworkProcessMemoryLimitMB,
40 WebViewPoolPrewarm: resolved.WebViewPoolPrewarmCount,
41 ConservativeThreshold: resolved.WebProcessMemoryConservativeThreshold,
42 StrictThreshold: resolved.WebProcessMemoryStrictThreshold,
43 },
44 Hardware: buildSystemviewHardwarePayload(hw),
45 }
46
47 return payload
48}
49
50func buildSystemviewAppearancePayload(appearance AppearanceConfig) dto.WebUIAppearanceConfig {
51 defaults := DefaultConfig().Appearance
52 return dto.WebUIAppearanceConfig{
53 SansFont: appearance.SansFont,
54 SerifFont: appearance.SerifFont,
55 MonospaceFont: appearance.MonospaceFont,
56 GtkFont: appearance.GtkFont,
57 DefaultFontSize: appearance.DefaultFontSize,
58 ColorScheme: appearance.ColorScheme,
59 LightPalette: buildSystemviewPalettePayload(appearance.LightPalette, defaults.LightPalette),
60 DarkPalette: buildSystemviewPalettePayload(appearance.DarkPalette, defaults.DarkPalette),
61 }
62}
63
64func buildSystemviewPalettePayload(palette, fallback ColorPalette) dto.ColorPalette {
65 return dto.ColorPalette{
66 Background: nonEmptyColor(palette.Background, fallback.Background),
67 Surface: nonEmptyColor(palette.Surface, fallback.Surface),
68 SurfaceVariant: nonEmptyColor(palette.SurfaceVariant, fallback.SurfaceVariant),
69 Text: nonEmptyColor(palette.Text, fallback.Text),
70 Muted: nonEmptyColor(palette.Muted, fallback.Muted),
71 Accent: nonEmptyColor(palette.Accent, fallback.Accent),
72 Border: nonEmptyColor(palette.Border, fallback.Border),
73 }
74}
75
76func nonEmptyColor(value, fallback string) string {
77 if value != "" {
78 return value
79 }
80 return fallback
81}
82
83func buildSystemviewSearchShortcutsPayload(shortcuts map[string]SearchShortcut) map[string]dto.SearchShortcut {
84 if len(shortcuts) == 0 {
85 return map[string]dto.SearchShortcut{}
86 }
87
88 result := make(map[string]dto.SearchShortcut, len(shortcuts))
89 for key, shortcut := range shortcuts {
90 result[key] = dto.SearchShortcut{URL: shortcut.URL, Description: shortcut.Description}
91 }
92 return result
93}
94
95func buildSystemviewHardwarePayload(hw *port.HardwareInfo) dto.SystemviewHardwarePayload {
96 if hw == nil {
97 return dto.SystemviewHardwarePayload{}
98 }
99 return dto.SystemviewHardwarePayload{
100 CPUCores: hw.CPUCores,
101 CPUThreads: hw.CPUThreads,
102 TotalRAMMB: hw.TotalRAMMB(),
103 GPUVendor: string(hw.GPUVendor),
104 GPUName: hw.GPUName,
105 VRAMMB: hw.VRAMMB(),
106 }
107}