返回 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 // The renderer calls this on every mount. Localized labels invalidate the
104 // presentation only; scheduling all source roots here restarts discovery
105 // that may already be running after startup admission.
106 a.emitProjectTreeChangedEvent()
107 return nil
108 }
109
110 // SetDesktopAppearance updates only desktop theme preferences. It does not
111 // rebuild the active controller and must stay out of provider-visible requests.
112 func (a *App) SetDesktopAppearance(theme, style string) error {
113 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopAppearance(theme, style) })
114 }
115
116 // SetDesktopTerminalTheme updates only the integrated terminal colours. It is
117 // applied live by the frontend and does not rebuild the active controller.
118 func (a *App) SetDesktopTerminalTheme(theme string) error {
119 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopTerminalTheme(theme) })
120 }
121
122 // SetDesktopLayoutStyle updates only the desktop layout style. It does not
123 // rebuild the active controller and must stay out of provider-visible requests.
124 func (a *App) SetDesktopLayoutStyle(style string) error {
125 if err := a.applyConfigOnly(func(c *config.Config) error {
126 return c.SetDesktopLayoutStyle(style)
127 }); err != nil {
128 return err
129 }
130 return a.applySingleSurfaceTabPolicy()
131 }
132
133 // SetDesktopCheckUpdates updates only the desktop startup update-check
134 // preference. Manual checks in Settings are unaffected.
135 func (a *App) SetDesktopCheckUpdates(enabled bool) error {
136 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopCheckUpdates(enabled) })
137 }
138
139 // SetDesktopUpdateChannel is retained for older Wails clients. The config layer
140 // clears the retired preference and every updater request uses Stable.
141 func (a *App) SetDesktopUpdateChannel(channel string) error {
142 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopUpdateChannel(channel) })
143 }
144
145 // SetDesktopTelemetry sets whether the desktop sends the anonymous launch ping.
146 func (a *App) SetDesktopTelemetry(enabled bool) error {
147 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopTelemetry(enabled) })
148 }
149
150 // SetDesktopMetrics sets whether the desktop sends aggregate desktop metrics,
151 // starting or stopping the live aggregator so the toggle takes effect immediately.
152 func (a *App) SetDesktopMetrics(enabled bool) error {
153 if err := a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopMetrics(enabled) }); err != nil {
154 return err
155 }
156 switch {
157 case enabled && a.metrics.Load() == nil && version != "dev":
158 a.metrics.Store(newMetricsAggregator(config.MemoryUserDir()))
159 if cfg, err := config.Load(); err == nil {
160 a.recordSettingsMetricsSnapshot(cfg)
161 }
162 case !enabled:
163 a.metrics.Store(nil)
164 }
165 return nil
166 }
167
168 // SetDesktopConversationWidth sets the max transcript width preference.
169 // standard = 960px fixed; full = 90% of the parent, with a 960px floor. Pure config-only.
170 func (a *App) SetDesktopConversationWidth(width string) error {
171 return a.applyConfigOnly(func(c *config.Config) error { return c.SetDesktopConversationWidth(width) })
172 }
173
174 // MigrateDesktopPreferences imports old browser-local desktop preferences into
175 // the user config once. Existing [desktop] values win so stale localStorage never
176 // overwrites an explicit config edit.
177 func (a *App) MigrateDesktopPreferences(language, theme, style string) error {
178 return a.applyConfigOnly(func(c *config.Config) error {
179 if strings.TrimSpace(c.Desktop.Language) == "" {
180 if err := c.SetDesktopLanguage(language); err != nil {
181 return err
182 }
183 }
184 if strings.TrimSpace(c.Desktop.Theme) == "" && strings.TrimSpace(c.Desktop.ThemeStyle) == "" {
185 if err := c.SetDesktopAppearance(theme, style); err != nil {
186 return err
187 }
188 }
189 return nil
190 })
191 }
192
192 lines GO