xref: /MusicFree/src/core/theme.ts (revision 0843c497437a8fb91a7c5d2af35edffea2013d9f)
1a27adc20S猫头猫import Config from '@/core/config';
2a27adc20S猫头猫
3a27adc20S猫头猫import {
4a27adc20S猫头猫    DarkTheme as _DarkTheme,
5a27adc20S猫头猫    DefaultTheme as _DefaultTheme,
6a27adc20S猫头猫} from '@react-navigation/native';
7a27adc20S猫头猫import {GlobalState} from '@/utils/stateMapper';
8a27adc20S猫头猫import {CustomizedColors} from '@/hooks/useColors';
9277c5280S猫头猫import Color from 'color';
10a27adc20S猫头猫
11a27adc20S猫头猫export const lightTheme = {
12a27adc20S猫头猫    id: 'p-light',
13a27adc20S猫头猫    ..._DefaultTheme,
14a27adc20S猫头猫    colors: {
15a27adc20S猫头猫        ..._DefaultTheme.colors,
16a27adc20S猫头猫        background: 'transparent',
17a27adc20S猫头猫        text: '#333333',
18277c5280S猫头猫        textSecondary: Color('#333333').alpha(0.7).toString(),
19277c5280S猫头猫        primary: '#f17d34',
20277c5280S猫头猫        pageBackground: '#fafafa',
21277c5280S猫头猫        shadow: '#000',
22277c5280S猫头猫        appBar: '#f17d34',
23277c5280S猫头猫        appBarText: '#fefefe',
24277c5280S猫头猫        musicBar: '#f2f2f2',
25277c5280S猫头猫        musicBarText: '#333333',
26277c5280S猫头猫        divider: 'rgba(0,0,0,0.1)',
27a27adc20S猫头猫        listActive: 'rgba(0,0,0,0.1)', // 在手机上表现是ripple
28a27adc20S猫头猫        mask: 'rgba(51,51,51,0.2)',
29a27adc20S猫头猫        backdrop: '#f0f0f0',
30277c5280S猫头猫        tabBar: '#f0f0f0',
31a27adc20S猫头猫        placeholder: '#eaeaea',
32a27adc20S猫头猫        success: '#08A34C',
33a27adc20S猫头猫        danger: '#FC5F5F',
34a27adc20S猫头猫        info: '#0A95C8',
35277c5280S猫头猫        card: '#e0e0e033',
36a27adc20S猫头猫    },
37a27adc20S猫头猫};
38a27adc20S猫头猫
39a27adc20S猫头猫export const darkTheme = {
40a27adc20S猫头猫    id: 'p-dark',
41a27adc20S猫头猫    ..._DarkTheme,
42a27adc20S猫头猫    colors: {
43a27adc20S猫头猫        ..._DarkTheme.colors,
44a27adc20S猫头猫        background: 'transparent',
45a27adc20S猫头猫        text: '#fcfcfc',
46277c5280S猫头猫        textSecondary: Color('#fcfcfc').alpha(0.7).toString(),
47277c5280S猫头猫        primary: '#3FA3B5',
48277c5280S猫头猫        pageBackground: '#202020',
49277c5280S猫头猫        shadow: '#999',
50277c5280S猫头猫        appBar: '#262626',
51277c5280S猫头猫        appBarText: '#fcfcfc',
52277c5280S猫头猫        musicBar: '#262626',
53277c5280S猫头猫        musicBarText: '#fcfcfc',
54277c5280S猫头猫        divider: 'rgba(255,255,255,0.1)',
55a27adc20S猫头猫        listActive: 'rgba(255,255,255,0.1)', // 在手机上表现是ripple
56a27adc20S猫头猫        mask: 'rgba(33,33,33,0.8)',
57a27adc20S猫头猫        backdrop: '#303030',
58277c5280S猫头猫        tabBar: '#303030',
59a27adc20S猫头猫        placeholder: '#424242',
60a27adc20S猫头猫        success: '#08A34C',
61a27adc20S猫头猫        danger: '#FC5F5F',
62a27adc20S猫头猫        info: '#0A95C8',
63277c5280S猫头猫        card: '#33333366',
64a27adc20S猫头猫    },
65a27adc20S猫头猫};
66a27adc20S猫头猫
67a27adc20S猫头猫interface IBackgroundInfo {
68a27adc20S猫头猫    url?: string;
69a27adc20S猫头猫    blur?: number;
70a27adc20S猫头猫    opacity?: number;
71a27adc20S猫头猫}
72a27adc20S猫头猫
73a27adc20S猫头猫const themeStore = new GlobalState(darkTheme);
74a27adc20S猫头猫const backgroundStore = new GlobalState<IBackgroundInfo | null>(null);
75a27adc20S猫头猫
76a27adc20S猫头猫function setup() {
77a27adc20S猫头猫    const currentTheme = Config.get('setting.theme.selectedTheme') ?? 'p-dark';
78a27adc20S猫头猫
79a27adc20S猫头猫    if (currentTheme === 'p-dark') {
80a27adc20S猫头猫        themeStore.setValue(darkTheme);
81a27adc20S猫头猫    } else if (currentTheme === 'p-light') {
82a27adc20S猫头猫        themeStore.setValue(lightTheme);
83a27adc20S猫头猫    } else {
84a27adc20S猫头猫        themeStore.setValue({
85a27adc20S猫头猫            id: currentTheme,
86a27adc20S猫头猫            dark: true,
87a27adc20S猫头猫            // @ts-ignore
88a27adc20S猫头猫            colors:
89a27adc20S猫头猫                (Config.get('setting.theme.colors') as CustomizedColors) ??
90a27adc20S猫头猫                darkTheme.colors,
91a27adc20S猫头猫        });
92a27adc20S猫头猫    }
93a27adc20S猫头猫
94a27adc20S猫头猫    const bgUrl = Config.get('setting.theme.background');
95a27adc20S猫头猫    const bgBlur = Config.get('setting.theme.backgroundBlur');
96a27adc20S猫头猫    const bgOpacity = Config.get('setting.theme.backgroundOpacity');
97a27adc20S猫头猫
98a27adc20S猫头猫    backgroundStore.setValue({
99a27adc20S猫头猫        url: bgUrl,
100a27adc20S猫头猫        blur: bgBlur ?? 20,
101a27adc20S猫头猫        opacity: bgOpacity ?? 0.6,
102a27adc20S猫头猫    });
103a27adc20S猫头猫}
104a27adc20S猫头猫
105a27adc20S猫头猫function setTheme(
106a27adc20S猫头猫    themeName: string,
107a27adc20S猫头猫    extra?: {
108b4a87dd6S猫头猫        colors?: Partial<CustomizedColors>;
109a27adc20S猫头猫        background?: IBackgroundInfo;
110a27adc20S猫头猫    },
111a27adc20S猫头猫) {
112a27adc20S猫头猫    if (themeName === 'p-light') {
113a27adc20S猫头猫        themeStore.setValue(lightTheme);
114a27adc20S猫头猫    } else if (themeName === 'p-dark') {
115a27adc20S猫头猫        themeStore.setValue(darkTheme);
116a27adc20S猫头猫    } else {
117a27adc20S猫头猫        themeStore.setValue({
118a27adc20S猫头猫            id: themeName,
119a27adc20S猫头猫            dark: true,
120a27adc20S猫头猫            colors: {
121a27adc20S猫头猫                ...darkTheme.colors,
122a27adc20S猫头猫                ...(extra?.colors ?? {}),
123a27adc20S猫头猫            },
124a27adc20S猫头猫        });
125a27adc20S猫头猫    }
126a27adc20S猫头猫
127a27adc20S猫头猫    Config.set('setting.theme.selectedTheme', themeName);
128a27adc20S猫头猫    Config.set('setting.theme.colors', themeStore.getValue().colors);
129a27adc20S猫头猫
130a27adc20S猫头猫    if (extra?.background) {
131a27adc20S猫头猫        const currentBg = backgroundStore.getValue();
132b4a87dd6S猫头猫        let newBg: IBackgroundInfo = {
133a27adc20S猫头猫            blur: 20,
134a27adc20S猫头猫            opacity: 0.6,
135a27adc20S猫头猫            ...(currentBg ?? {}),
136a27adc20S猫头猫            url: undefined,
137a27adc20S猫头猫        };
138*0843c497STheo        if (typeof extra.background.blur === 'number') {
139a27adc20S猫头猫            newBg.blur = extra.background.blur;
140a27adc20S猫头猫        }
141*0843c497STheo        if (typeof extra.background.opacity === 'number') {
142a27adc20S猫头猫            newBg.opacity = extra.background.opacity;
143a27adc20S猫头猫        }
144b4a87dd6S猫头猫        if (extra.background.url) {
145b4a87dd6S猫头猫            newBg.url = extra.background.url;
146b4a87dd6S猫头猫        }
147a27adc20S猫头猫
148a27adc20S猫头猫        Config.set('setting.theme.background', newBg.url);
149a27adc20S猫头猫        Config.set('setting.theme.backgroundBlur', newBg.blur);
150a27adc20S猫头猫        Config.set('setting.theme.backgroundOpacity', newBg.opacity);
151a27adc20S猫头猫
152a27adc20S猫头猫        backgroundStore.setValue(newBg);
153a27adc20S猫头猫    }
154a27adc20S猫头猫}
155a27adc20S猫头猫
156a27adc20S猫头猫function setColors(colors: Partial<CustomizedColors>) {
157a27adc20S猫头猫    const currentTheme = themeStore.getValue();
158a27adc20S猫头猫    if (currentTheme.id !== 'p-light' && currentTheme.id !== 'p-dark') {
159a27adc20S猫头猫        const newTheme = {
160a27adc20S猫头猫            ...currentTheme,
161a27adc20S猫头猫            colors: {
162a27adc20S猫头猫                ...currentTheme.colors,
163a27adc20S猫头猫                ...colors,
164a27adc20S猫头猫            },
165a27adc20S猫头猫        };
166a27adc20S猫头猫
167a27adc20S猫头猫        Config.set('setting.theme.colors', newTheme.colors);
168a27adc20S猫头猫        themeStore.setValue(newTheme);
169a27adc20S猫头猫    }
170a27adc20S猫头猫}
171a27adc20S猫头猫
172a27adc20S猫头猫function setBackground(backgroundInfo: Partial<IBackgroundInfo>) {
173a27adc20S猫头猫    const currentBackgroundInfo = backgroundStore.getValue();
174a27adc20S猫头猫    let newBgInfo = {
175a27adc20S猫头猫        ...(currentBackgroundInfo ?? {
176a27adc20S猫头猫            opacity: 0.6,
177a27adc20S猫头猫            blur: 20,
178a27adc20S猫头猫        }),
179a27adc20S猫头猫    };
18019003909STheo    if (typeof backgroundInfo.blur === 'number') {
181a27adc20S猫头猫        Config.set('setting.theme.backgroundBlur', backgroundInfo.blur);
182a27adc20S猫头猫        newBgInfo.blur = backgroundInfo.blur;
183a27adc20S猫头猫    }
18419003909STheo    if (typeof backgroundInfo.opacity === 'number') {
185a27adc20S猫头猫        Config.set('setting.theme.backgroundOpacity', backgroundInfo.opacity);
186a27adc20S猫头猫        newBgInfo.opacity = backgroundInfo.opacity;
187a27adc20S猫头猫    }
188a27adc20S猫头猫    if (backgroundInfo.url !== undefined) {
189a27adc20S猫头猫        Config.set('setting.theme.background', backgroundInfo.url);
190a27adc20S猫头猫        newBgInfo.url = backgroundInfo.url;
191a27adc20S猫头猫    }
192a27adc20S猫头猫    backgroundStore.setValue(newBgInfo);
193a27adc20S猫头猫}
194a27adc20S猫头猫
195a27adc20S猫头猫const configableColorKey: Array<keyof CustomizedColors> = [
196277c5280S猫头猫    'primary',
197f643c584S猫头猫    'text',
198277c5280S猫头猫    'appBar',
199277c5280S猫头猫    'appBarText',
200277c5280S猫头猫    'musicBar',
201277c5280S猫头猫    'musicBarText',
202277c5280S猫头猫    'pageBackground',
203277c5280S猫头猫    'backdrop',
204277c5280S猫头猫    'card',
205277c5280S猫头猫    'placeholder',
206a27adc20S猫头猫];
207a27adc20S猫头猫
208a27adc20S猫头猫const colorDesc: Record<string, string> = {
209a27adc20S猫头猫    text: '文字颜色',
210a27adc20S猫头猫    primary: '主题色',
211277c5280S猫头猫    appBar: '标题栏背景色',
212277c5280S猫头猫    appBarText: '标题栏文字颜色',
213277c5280S猫头猫    musicBar: '音乐栏背景色',
214277c5280S猫头猫    musicBarText: '音乐栏文字颜色',
215277c5280S猫头猫    pageBackground: '页面背景色',
216277c5280S猫头猫    backdrop: '弹窗、浮层背景色',
217277c5280S猫头猫    card: '卡片背景色',
218277c5280S猫头猫    placeholder: '输入框背景色',
219a27adc20S猫头猫};
220a27adc20S猫头猫
221a27adc20S猫头猫const Theme = {
222a27adc20S猫头猫    setup,
223a27adc20S猫头猫    setTheme,
224a27adc20S猫头猫    setBackground,
225a27adc20S猫头猫    setColors,
226a27adc20S猫头猫    useTheme: themeStore.useValue,
227fdcf4127S猫头猫    getTheme: themeStore.getValue,
228a27adc20S猫头猫    useBackground: backgroundStore.useValue,
229a27adc20S猫头猫    configableColorKey,
230a27adc20S猫头猫    colorDesc,
231a27adc20S猫头猫};
232a27adc20S猫头猫
233a27adc20S猫头猫export default Theme;
234