xref: /MusicFree/src/core/theme.ts (revision a27adc201796bd0be4a6a41893461b099d480a34)
1*a27adc20S猫头猫import Config from '@/core/config';
2*a27adc20S猫头猫
3*a27adc20S猫头猫import {
4*a27adc20S猫头猫    DarkTheme as _DarkTheme,
5*a27adc20S猫头猫    DefaultTheme as _DefaultTheme,
6*a27adc20S猫头猫} from '@react-navigation/native';
7*a27adc20S猫头猫import {GlobalState} from '@/utils/stateMapper';
8*a27adc20S猫头猫import {CustomizedColors} from '@/hooks/useColors';
9*a27adc20S猫头猫
10*a27adc20S猫头猫export const lightTheme = {
11*a27adc20S猫头猫    id: 'p-light',
12*a27adc20S猫头猫    ..._DefaultTheme,
13*a27adc20S猫头猫    colors: {
14*a27adc20S猫头猫        ..._DefaultTheme.colors,
15*a27adc20S猫头猫        primary: '#f17d34',
16*a27adc20S猫头猫        background: 'transparent',
17*a27adc20S猫头猫        _background: '#fafafa',
18*a27adc20S猫头猫        divider: 'rgba(0,0,0,0.1)',
19*a27adc20S猫头猫        text: '#333333',
20*a27adc20S猫头猫        listActive: 'rgba(0,0,0,0.1)', // 在手机上表现是ripple
21*a27adc20S猫头猫        mask: 'rgba(51,51,51,0.2)',
22*a27adc20S猫头猫        shadow: '#000',
23*a27adc20S猫头猫        backdrop: '#f0f0f0',
24*a27adc20S猫头猫        placeholder: '#eaeaea',
25*a27adc20S猫头猫        success: '#08A34C',
26*a27adc20S猫头猫        danger: '#FC5F5F',
27*a27adc20S猫头猫        info: '#0A95C8',
28*a27adc20S猫头猫        musicBar: '#fff',
29*a27adc20S猫头猫        appBar: '#f17d34',
30*a27adc20S猫头猫        headerText: '#fefefe',
31*a27adc20S猫头猫    },
32*a27adc20S猫头猫};
33*a27adc20S猫头猫
34*a27adc20S猫头猫export const darkTheme = {
35*a27adc20S猫头猫    id: 'p-dark',
36*a27adc20S猫头猫    ..._DarkTheme,
37*a27adc20S猫头猫    colors: {
38*a27adc20S猫头猫        ..._DarkTheme.colors,
39*a27adc20S猫头猫        primary: '#3FA3B5',
40*a27adc20S猫头猫        background: 'transparent',
41*a27adc20S猫头猫        _background: '#202020',
42*a27adc20S猫头猫        divider: 'rgba(255,255,255,0.1)',
43*a27adc20S猫头猫        text: '#fcfcfc',
44*a27adc20S猫头猫        listActive: 'rgba(255,255,255,0.1)', // 在手机上表现是ripple
45*a27adc20S猫头猫        mask: 'rgba(33,33,33,0.8)',
46*a27adc20S猫头猫        shadow: '#666',
47*a27adc20S猫头猫        backdrop: '#303030',
48*a27adc20S猫头猫        placeholder: '#424242',
49*a27adc20S猫头猫        success: '#08A34C',
50*a27adc20S猫头猫        danger: '#FC5F5F',
51*a27adc20S猫头猫        info: '#0A95C8',
52*a27adc20S猫头猫        appBar: '#262626',
53*a27adc20S猫头猫        musicBar: '#262626',
54*a27adc20S猫头猫        headerText: '#fcfcfc',
55*a27adc20S猫头猫    },
56*a27adc20S猫头猫};
57*a27adc20S猫头猫
58*a27adc20S猫头猫interface IBackgroundInfo {
59*a27adc20S猫头猫    url?: string;
60*a27adc20S猫头猫    blur?: number;
61*a27adc20S猫头猫    opacity?: number;
62*a27adc20S猫头猫}
63*a27adc20S猫头猫
64*a27adc20S猫头猫const themeStore = new GlobalState(darkTheme);
65*a27adc20S猫头猫const backgroundStore = new GlobalState<IBackgroundInfo | null>(null);
66*a27adc20S猫头猫
67*a27adc20S猫头猫function setup() {
68*a27adc20S猫头猫    const currentTheme = Config.get('setting.theme.selectedTheme') ?? 'p-dark';
69*a27adc20S猫头猫
70*a27adc20S猫头猫    if (currentTheme === 'p-dark') {
71*a27adc20S猫头猫        themeStore.setValue(darkTheme);
72*a27adc20S猫头猫    } else if (currentTheme === 'p-light') {
73*a27adc20S猫头猫        themeStore.setValue(lightTheme);
74*a27adc20S猫头猫    } else {
75*a27adc20S猫头猫        themeStore.setValue({
76*a27adc20S猫头猫            id: currentTheme,
77*a27adc20S猫头猫            dark: true,
78*a27adc20S猫头猫            // @ts-ignore
79*a27adc20S猫头猫            colors:
80*a27adc20S猫头猫                (Config.get('setting.theme.colors') as CustomizedColors) ??
81*a27adc20S猫头猫                darkTheme.colors,
82*a27adc20S猫头猫        });
83*a27adc20S猫头猫    }
84*a27adc20S猫头猫
85*a27adc20S猫头猫    const bgUrl = Config.get('setting.theme.background');
86*a27adc20S猫头猫    const bgBlur = Config.get('setting.theme.backgroundBlur');
87*a27adc20S猫头猫    const bgOpacity = Config.get('setting.theme.backgroundOpacity');
88*a27adc20S猫头猫
89*a27adc20S猫头猫    backgroundStore.setValue({
90*a27adc20S猫头猫        url: bgUrl,
91*a27adc20S猫头猫        blur: bgBlur ?? 20,
92*a27adc20S猫头猫        opacity: bgOpacity ?? 0.6,
93*a27adc20S猫头猫    });
94*a27adc20S猫头猫}
95*a27adc20S猫头猫
96*a27adc20S猫头猫function setTheme(
97*a27adc20S猫头猫    themeName: string,
98*a27adc20S猫头猫    extra?: {
99*a27adc20S猫头猫        colors?: CustomizedColors;
100*a27adc20S猫头猫        background?: IBackgroundInfo;
101*a27adc20S猫头猫    },
102*a27adc20S猫头猫) {
103*a27adc20S猫头猫    if (themeName === 'p-light') {
104*a27adc20S猫头猫        themeStore.setValue(lightTheme);
105*a27adc20S猫头猫    } else if (themeName === 'p-dark') {
106*a27adc20S猫头猫        themeStore.setValue(darkTheme);
107*a27adc20S猫头猫    } else {
108*a27adc20S猫头猫        themeStore.setValue({
109*a27adc20S猫头猫            id: themeName,
110*a27adc20S猫头猫            dark: true,
111*a27adc20S猫头猫            colors: {
112*a27adc20S猫头猫                ...darkTheme.colors,
113*a27adc20S猫头猫                ...(extra?.colors ?? {}),
114*a27adc20S猫头猫            },
115*a27adc20S猫头猫        });
116*a27adc20S猫头猫    }
117*a27adc20S猫头猫
118*a27adc20S猫头猫    Config.set('setting.theme.selectedTheme', themeName);
119*a27adc20S猫头猫    Config.set('setting.theme.colors', themeStore.getValue().colors);
120*a27adc20S猫头猫
121*a27adc20S猫头猫    if (extra?.background) {
122*a27adc20S猫头猫        const currentBg = backgroundStore.getValue();
123*a27adc20S猫头猫        let newBg = {
124*a27adc20S猫头猫            blur: 20,
125*a27adc20S猫头猫            opacity: 0.6,
126*a27adc20S猫头猫            ...(currentBg ?? {}),
127*a27adc20S猫头猫            url: undefined,
128*a27adc20S猫头猫        };
129*a27adc20S猫头猫        if (extra.background.blur) {
130*a27adc20S猫头猫            newBg.blur = extra.background.blur;
131*a27adc20S猫头猫        }
132*a27adc20S猫头猫        if (extra.background.opacity) {
133*a27adc20S猫头猫            newBg.opacity = extra.background.opacity;
134*a27adc20S猫头猫        }
135*a27adc20S猫头猫
136*a27adc20S猫头猫        Config.set('setting.theme.background', newBg.url);
137*a27adc20S猫头猫        Config.set('setting.theme.backgroundBlur', newBg.blur);
138*a27adc20S猫头猫        Config.set('setting.theme.backgroundOpacity', newBg.opacity);
139*a27adc20S猫头猫
140*a27adc20S猫头猫        backgroundStore.setValue(newBg);
141*a27adc20S猫头猫    }
142*a27adc20S猫头猫}
143*a27adc20S猫头猫
144*a27adc20S猫头猫function setColors(colors: Partial<CustomizedColors>) {
145*a27adc20S猫头猫    const currentTheme = themeStore.getValue();
146*a27adc20S猫头猫    if (currentTheme.id !== 'p-light' && currentTheme.id !== 'p-dark') {
147*a27adc20S猫头猫        const newTheme = {
148*a27adc20S猫头猫            ...currentTheme,
149*a27adc20S猫头猫            colors: {
150*a27adc20S猫头猫                ...currentTheme.colors,
151*a27adc20S猫头猫                ...colors,
152*a27adc20S猫头猫            },
153*a27adc20S猫头猫        };
154*a27adc20S猫头猫
155*a27adc20S猫头猫        Config.set('setting.theme.colors', newTheme.colors);
156*a27adc20S猫头猫        themeStore.setValue(newTheme);
157*a27adc20S猫头猫    }
158*a27adc20S猫头猫}
159*a27adc20S猫头猫
160*a27adc20S猫头猫function setBackground(backgroundInfo: Partial<IBackgroundInfo>) {
161*a27adc20S猫头猫    const currentBackgroundInfo = backgroundStore.getValue();
162*a27adc20S猫头猫    let newBgInfo = {
163*a27adc20S猫头猫        ...(currentBackgroundInfo ?? {
164*a27adc20S猫头猫            opacity: 0.6,
165*a27adc20S猫头猫            blur: 20,
166*a27adc20S猫头猫        }),
167*a27adc20S猫头猫    };
168*a27adc20S猫头猫    if (backgroundInfo.blur) {
169*a27adc20S猫头猫        Config.set('setting.theme.backgroundBlur', backgroundInfo.blur);
170*a27adc20S猫头猫        newBgInfo.blur = backgroundInfo.blur;
171*a27adc20S猫头猫    }
172*a27adc20S猫头猫    if (backgroundInfo.opacity) {
173*a27adc20S猫头猫        Config.set('setting.theme.backgroundOpacity', backgroundInfo.opacity);
174*a27adc20S猫头猫        newBgInfo.opacity = backgroundInfo.opacity;
175*a27adc20S猫头猫    }
176*a27adc20S猫头猫    if (backgroundInfo.url !== undefined) {
177*a27adc20S猫头猫        Config.set('setting.theme.background', backgroundInfo.url);
178*a27adc20S猫头猫        newBgInfo.url = backgroundInfo.url;
179*a27adc20S猫头猫    }
180*a27adc20S猫头猫    backgroundStore.setValue(newBgInfo);
181*a27adc20S猫头猫}
182*a27adc20S猫头猫
183*a27adc20S猫头猫const configableColorKey: Array<keyof CustomizedColors> = [
184*a27adc20S猫头猫    'appBar',
185*a27adc20S猫头猫    'musicBar',
186*a27adc20S猫头猫    'primary',
187*a27adc20S猫头猫    'background',
188*a27adc20S猫头猫    'headerText',
189*a27adc20S猫头猫    'text',
190*a27adc20S猫头猫];
191*a27adc20S猫头猫
192*a27adc20S猫头猫const colorDesc: Record<string, string> = {
193*a27adc20S猫头猫    appBar: '标题栏背景色',
194*a27adc20S猫头猫    headerText: '标题栏文字颜色',
195*a27adc20S猫头猫    text: '文字颜色',
196*a27adc20S猫头猫    musicBar: '音乐栏背景色',
197*a27adc20S猫头猫    primary: '主题色',
198*a27adc20S猫头猫    background: '背景色',
199*a27adc20S猫头猫};
200*a27adc20S猫头猫
201*a27adc20S猫头猫const Theme = {
202*a27adc20S猫头猫    setup,
203*a27adc20S猫头猫    setTheme,
204*a27adc20S猫头猫    setBackground,
205*a27adc20S猫头猫    setColors,
206*a27adc20S猫头猫    useTheme: themeStore.useValue,
207*a27adc20S猫头猫    useBackground: backgroundStore.useValue,
208*a27adc20S猫头猫    configableColorKey,
209*a27adc20S猫头猫    colorDesc,
210*a27adc20S猫头猫};
211*a27adc20S猫头猫
212*a27adc20S猫头猫export default Theme;
213