1111 */
1212
1313import { atom } from 'jotai'
14- import { THEME_STYLES , type ThemeMode , type ThemeStyle } from '../../types'
14+ import { DEFAULT_INTERFACE_VARIANT , THEME_STYLES , type InterfaceVariant , type ThemeMode , type ThemeStyle } from '../../types'
1515
1616/** localStorage 缓存键 */
1717const THEME_CACHE_KEY = 'proma-theme-mode'
1818const THEME_STYLE_CACHE_KEY = 'proma-theme-style'
19+ const INTERFACE_VARIANT_CACHE_KEY = 'proma-interface-variant'
1920
2021/**
2122 * 从 localStorage 读取缓存的主题模式
@@ -47,6 +48,21 @@ function getCachedThemeStyle(): ThemeStyle {
4748 return 'default'
4849}
4950
51+ /**
52+ * 从 localStorage 读取缓存的界面风格
53+ */
54+ function getCachedInterfaceVariant ( ) : InterfaceVariant {
55+ try {
56+ const cached = localStorage . getItem ( INTERFACE_VARIANT_CACHE_KEY )
57+ if ( cached === 'classic' || cached === 'modern' ) {
58+ return cached
59+ }
60+ } catch {
61+ // localStorage 不可用时忽略
62+ }
63+ return DEFAULT_INTERFACE_VARIANT
64+ }
65+
5066/**
5167 * 缓存主题模式到 localStorage
5268 */
@@ -69,12 +85,26 @@ function cacheThemeStyle(style: ThemeStyle): void {
6985 }
7086}
7187
88+ /**
89+ * 缓存界面风格到 localStorage
90+ */
91+ function cacheInterfaceVariant ( variant : InterfaceVariant ) : void {
92+ try {
93+ localStorage . setItem ( INTERFACE_VARIANT_CACHE_KEY , variant )
94+ } catch {
95+ // localStorage 不可用时忽略
96+ }
97+ }
98+
7299/** 用户选择的主题模式 */
73100export const themeModeAtom = atom < ThemeMode > ( getCachedThemeMode ( ) )
74101
75102/** 用户选择的特殊风格 */
76103export const themeStyleAtom = atom < ThemeStyle > ( getCachedThemeStyle ( ) )
77104
105+ /** 用户选择的界面风格 */
106+ export const interfaceVariantAtom = atom < InterfaceVariant > ( getCachedInterfaceVariant ( ) )
107+
78108/** 系统当前是否为深色模式 */
79109export const systemIsDarkAtom = atom < boolean > ( true )
80110
@@ -150,6 +180,28 @@ export function applyThemeToDOM(themeMode: ThemeMode, themeStyle: ThemeStyle = '
150180 }
151181}
152182
183+ /**
184+ * 应用界面风格到 DOM
185+ */
186+ export function applyInterfaceVariantToDOM ( variant : InterfaceVariant = DEFAULT_INTERFACE_VARIANT ) : void {
187+ const html = document . documentElement
188+ const targetClass = variant === 'classic' ? 'ui-classic' : 'ui-modern'
189+ const currentClass = html . classList . contains ( 'ui-classic' )
190+ ? 'ui-classic'
191+ : html . classList . contains ( 'ui-modern' )
192+ ? 'ui-modern'
193+ : null
194+
195+ if ( currentClass === targetClass ) {
196+ return
197+ }
198+
199+ if ( currentClass ) {
200+ html . classList . remove ( currentClass )
201+ }
202+ html . classList . add ( targetClass )
203+ }
204+
153205/**
154206 * 初始化主题系统
155207 *
@@ -160,6 +212,7 @@ export async function initializeTheme(
160212 setThemeMode : ( mode : ThemeMode ) => void ,
161213 setSystemIsDark : ( isDark : boolean ) => void ,
162214 setThemeStyle ?: ( style : ThemeStyle ) => void ,
215+ setInterfaceVariant ?: ( variant : InterfaceVariant ) => void ,
163216) : Promise < ( ) => void > {
164217 // 从主进程加载持久化设置
165218 const settings = await window . electronAPI . getSettings ( )
@@ -172,6 +225,12 @@ export async function initializeTheme(
172225 cacheThemeStyle ( settings . themeStyle )
173226 }
174227
228+ const interfaceVariant = settings . interfaceVariant || DEFAULT_INTERFACE_VARIANT
229+ if ( setInterfaceVariant ) {
230+ setInterfaceVariant ( interfaceVariant )
231+ }
232+ cacheInterfaceVariant ( interfaceVariant )
233+
175234 // 获取系统主题
176235 const isDark = await window . electronAPI . getSystemTheme ( )
177236 setSystemIsDark ( isDark )
@@ -185,12 +244,17 @@ export async function initializeTheme(
185244 const cleanupThemeSettings = window . electronAPI . onThemeSettingsChanged ( ( payload ) => {
186245 const mode = payload . themeMode as ThemeMode
187246 const style = ( payload . themeStyle || 'default' ) as ThemeStyle
247+ const variant = ( payload . interfaceVariant || DEFAULT_INTERFACE_VARIANT ) as InterfaceVariant
188248 setThemeMode ( mode )
189249 cacheThemeMode ( mode )
190250 if ( setThemeStyle ) {
191251 setThemeStyle ( style )
192252 cacheThemeStyle ( style )
193253 }
254+ if ( setInterfaceVariant ) {
255+ setInterfaceVariant ( variant )
256+ cacheInterfaceVariant ( variant )
257+ }
194258 } )
195259
196260 return ( ) => {
@@ -216,3 +280,11 @@ export async function updateThemeStyle(style: ThemeStyle): Promise<void> {
216280 cacheThemeStyle ( style )
217281 await window . electronAPI . updateSettings ( { themeStyle : style } )
218282}
283+
284+ /**
285+ * 更新界面风格并持久化
286+ */
287+ export async function updateInterfaceVariant ( variant : InterfaceVariant ) : Promise < void > {
288+ cacheInterfaceVariant ( variant )
289+ await window . electronAPI . updateSettings ( { interfaceVariant : variant } )
290+ }
0 commit comments