返回 DeepSeek-Reasonix
settings_preferences.go
根目录 / desktop / settings_preferences.go
1 package main
2
3 import (
4 "reasonix/internal/config"
5 "strings"
6 )
7
8 // SetCloseBehavior updates desktop-only window close behavior without rebuilding
9 // the active controller. It must stay out of provider-visible prompt/request data.
10 func (a *App) SetCloseBehavior(mode string) error {
11 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopCloseBehavior(mode) })
12 }
13
14 // SetStatusBarStyle updates the desktop status bar metric label style. UI-only,
15 // no rebuild needed.
16 func (a *App) SetStatusBarStyle(style string) error {
17 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopStatusBarStyle(style) })
18 }
19
20 // SetStatusBarItems updates the ordered visible desktop status bar items.
21 // UI-only, no rebuild needed.
22 func (a *App) SetStatusBarItems(items []string) error {
23 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopStatusBarItems(items) })
24 }
25
26 // SetDesktopLanguage updates the desktop UI language and the user-level response
27 // language preference used by model-facing desktop sessions.
28 func (a *App) SetDesktopLanguage(lang string) error {
29 responseLanguage := ""
30 mutate := func(c *config.Config) error {
31 if err := c.SetDesktopLanguage(lang); err != nil {
32 return err
33 }
34 if err := c.SetLanguage(lang); err != nil {
35 return err
36 }
37 responseLanguage = c.ResponseLanguage()
38 return nil
39 }
40 err := a.applyConfigOnly(mutate)
41 if err != nil {
42 return err
43 }
44 if strings.TrimSpace(lang) != "" && !strings.EqualFold(strings.TrimSpace(lang), "auto") {
45 a.setDesktopLocale(lang)
46 }
47 refreshBackendNoticeLocale(lang)
48 a.updateTrayLocale(lang)
49 a.applyResponseLanguageToLiveControllers(responseLanguage)
50 return nil
51 }
52
53 // SetDesktopCurrency persists a display-only preference and re-selects the
54 // occurrence-time valuations already stored in each tab. Provider price tables
55 // and live controllers are intentionally untouched.
56 func (a *App) SetDesktopCurrency(currency string) error {
57 err := a.applyConfigOnly(func(c *config.Config) error {
58 return c.SetDesktopCurrency(currency)
59 })
60 if err != nil {
61 return err
62 }
63
64 a.sessionRemovalMu.Lock()
65 defer a.sessionRemovalMu.Unlock()
66 a.mu.RLock()
67 tabs := append([]*WorkspaceTab(nil), a.runtimeTabsLocked()...)
68 a.mu.RUnlock()
69 for _, tab := range tabs {
70 a.repriceTabUsageForCurrentCurrency(tab)
71 }
72 return nil
73 }
74
75 func (a *App) desktopEffectivePricingCurrency(cfg *config.Config) string {
76 // Display currency only — never the provider list-price region.
77 if cfg == nil {
78 return ""
79 }
80 if pref := cfg.DisplayCurrencyPref(); pref != "" {
81 return pref
82 }
83 return cfg.ExplicitDisplayCurrency()
84 }
85
86 func (a *App) desktopOfficialPricingLanguage(cfg *config.Config) string {
87 // Used only for display-language adjacent UI; list prices use billing_currency.
88 if a.desktopEffectivePricingCurrency(cfg) == "CNY" {
89 return "zh"
90 }
91 return "en"
92 }
93
94 // SetTrayLocale mirrors the resolved desktop UI language into the native tray
95 // menu. It is runtime-only; the persisted preference remains [desktop].language.
96 func (a *App) SetTrayLocale(locale string) error {
97 a.setDesktopLocale(locale)
98 trayLocale := "en"
99 if strings.HasPrefix(strings.ToLower(strings.TrimSpace(locale)), "zh") {
100 trayLocale = "zh"
101 }
102 a.updateTrayLocale(trayLocale)
103 a.emitProjectTreeChanged()
104 return nil
105 }
106
107 // SetDesktopAppearance updates only desktop theme preferences. It does not
108 // rebuild the active controller and must stay out of provider-visible requests.
109 func (a *App) SetDesktopAppearance(theme, style string) error {
110 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopAppearance(theme, style) })
111 }
112
113 // SetDesktopTerminalTheme updates only the integrated terminal colours. It is
114 // applied live by the frontend and does not rebuild the active controller.
115 func (a *App) SetDesktopTerminalTheme(theme string) error {
116 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopTerminalTheme(theme) })
117 }
118
119 // SetDesktopLayoutStyle updates only the desktop layout style. It does not
120 // rebuild the active controller and must stay out of provider-visible requests.
121 func (a *App) SetDesktopLayoutStyle(style string) error {
122 if err := a.applyConfigOnly(func(c *config.Config) error {
123 return c.SetDesktopLayoutStyle(style)
124 }); err != nil {
125 return err
126 }
127 return a.applySingleSurfaceTabPolicy()
128 }
129
130 // SetDesktopCheckUpdates updates only the desktop startup update-check
131 // preference. Manual checks in Settings are unaffected.
132 func (a *App) SetDesktopCheckUpdates(enabled bool) error {
133 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopCheckUpdates(enabled) })
134 }
135
136 // SetDesktopUpdateChannel is retained for older Wails clients. The config layer
137 // clears the retired preference and every updater request uses Stable.
138 func (a *App) SetDesktopUpdateChannel(channel string) error {
139 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopUpdateChannel(channel) })
140 }
141
142 // SetDesktopTelemetry sets whether the desktop sends the anonymous launch ping.
143 func (a *App) SetDesktopTelemetry(enabled bool) error {
144 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopTelemetry(enabled) })
145 }
146
147 // SetDesktopMetrics sets whether the desktop sends aggregate desktop metrics,
148 // starting or stopping the live aggregator so the toggle takes effect immediately.
149 func (a *App) SetDesktopMetrics(enabled bool) error {
150 if err := a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopMetrics(enabled) }); err != nil {
151 return err
152 }
153 switch {
154 case enabled && a.metrics.Load() == nil && version != "dev":
155 a.metrics.Store(newMetricsAggregator(config.MemoryUserDir()))
156 if cfg, err := config.Load(); err == nil {
157 a.recordSettingsMetricsSnapshot(cfg)
158 }
159 case !enabled:
160 a.metrics.Store(nil)
161 }
162 return nil
163 }
164
165 // SetDesktopConversationWidth sets the max transcript width preference.
166 // standard = 960px fixed; full = 90% of the parent, with a 960px floor. Pure config-only.
167 func (a *App) SetDesktopConversationWidth(width string) error {
168 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopConversationWidth(width) })
169 }
170
171 // MigrateDesktopPreferences imports old browser-local desktop preferences into
172 // the user config once. Existing [desktop] values win so stale localStorage never
173 // overwrites an explicit config edit.
174 func (a *App) MigrateDesktopPreferences(language, theme, style string) error {
175 return a.applyConfigOnly(func(c *config.Config) error {
176 if strings.TrimSpace(c.Desktop.Language) == "" {
177 if err := c.SetDesktopLanguage(language); err != nil {
178 return err
179 }
180 }
181 if strings.TrimSpace(c.Desktop.Theme) == "" && strings.TrimSpace(c.Desktop.ThemeStyle) == "" {
182 if err := c.SetDesktopAppearance(theme, style); err != nil {
183 return err
184 }
185 }
186 return nil
187 })
188 }
189
189 lines GO