release: v0.17.0
GitHub Pages / build (push) Canceled after 0s
GitHub Pages / deploy (push) Canceled after 0s
Docker image / meta (push) Successful in 24s
Docs Docker image / meta (push) Successful in 7s
Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 59s
Docs Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 30s
Docker image / merge (push) Canceled after 0s
Docs Docker image / merge (push) Canceled after 0s
Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Docs Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
GitHub Pages / build (push) Canceled after 0s
GitHub Pages / deploy (push) Canceled after 0s
Docker image / meta (push) Successful in 24s
Docs Docker image / meta (push) Successful in 7s
Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 59s
Docs Docker image / build (amd64, linux/amd64, ubuntu-latest) (push) Failing after 30s
Docker image / merge (push) Canceled after 0s
Docs Docker image / merge (push) Canceled after 0s
Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
Docs Docker image / build (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { ETheme } from 'types/index.d';
|
||||
import { Color } from 'tvision-color';
|
||||
import { CHART_COLORS, defaultColor } from 'configs/color';
|
||||
import { generateColorMap, insertThemeStylesheet } from 'utils/color';
|
||||
import { RootState } from '../store';
|
||||
import { version } from '../../../package.json';
|
||||
|
||||
const namespace = 'global';
|
||||
|
||||
export enum ELayout {
|
||||
side = 1,
|
||||
top,
|
||||
mix,
|
||||
fullPage,
|
||||
}
|
||||
|
||||
export interface IGlobalState {
|
||||
loading: boolean;
|
||||
collapsed: boolean;
|
||||
/**
|
||||
* 是否显示面包屑导航
|
||||
*/
|
||||
setting: boolean;
|
||||
version: string;
|
||||
color: string;
|
||||
/**
|
||||
* 主题:深色 浅色
|
||||
*/
|
||||
theme: ETheme;
|
||||
/**
|
||||
* 是否开启跟随系统主题
|
||||
*/
|
||||
systemTheme: boolean;
|
||||
layout: ELayout;
|
||||
isFullPage: boolean;
|
||||
showHeader: boolean;
|
||||
showBreadcrumbs: boolean;
|
||||
showFooter: boolean;
|
||||
chartColors: Record<string, string>;
|
||||
}
|
||||
|
||||
const defaultTheme = ETheme.light;
|
||||
|
||||
const initialState: IGlobalState = {
|
||||
loading: true,
|
||||
collapsed: window.innerWidth < 1000, // 宽度小于1000 菜单闭合
|
||||
setting: false,
|
||||
version,
|
||||
theme: defaultTheme,
|
||||
systemTheme: false,
|
||||
layout: ELayout.side,
|
||||
isFullPage: false,
|
||||
color: defaultColor?.[0],
|
||||
showHeader: true,
|
||||
showBreadcrumbs: true,
|
||||
showFooter: true,
|
||||
chartColors: CHART_COLORS[defaultTheme],
|
||||
};
|
||||
|
||||
// 创建带有命名空间的reducer
|
||||
const globalSlice = createSlice({
|
||||
name: namespace,
|
||||
initialState,
|
||||
reducers: {
|
||||
toggleMenu: (state, action) => {
|
||||
if (action.payload === null) {
|
||||
state.collapsed = !state.collapsed;
|
||||
} else {
|
||||
state.collapsed = !!action.payload;
|
||||
}
|
||||
},
|
||||
toggleSetting: (state) => {
|
||||
state.setting = !state.setting;
|
||||
},
|
||||
toggleShowHeader: (state) => {
|
||||
state.showHeader = !state.showHeader;
|
||||
},
|
||||
toggleShowBreadcrumbs: (state) => {
|
||||
state.showBreadcrumbs = !state.showBreadcrumbs;
|
||||
},
|
||||
toggleShowFooter: (state) => {
|
||||
state.showFooter = !state.showFooter;
|
||||
},
|
||||
switchTheme: (state, action: PayloadAction<ETheme>) => {
|
||||
const finalTheme = action?.payload;
|
||||
// 切换 chart 颜色
|
||||
state.chartColors = CHART_COLORS[finalTheme];
|
||||
// 切换主题颜色
|
||||
state.theme = finalTheme;
|
||||
// 关闭跟随系统
|
||||
state.systemTheme = false;
|
||||
document.documentElement.setAttribute('theme-mode', finalTheme);
|
||||
},
|
||||
openSystemTheme: (state) => {
|
||||
const media = window.matchMedia('(prefers-color-scheme:dark)');
|
||||
if (media.matches) {
|
||||
const finalTheme = media.matches ? ETheme.dark : ETheme.light;
|
||||
state.chartColors = CHART_COLORS[finalTheme];
|
||||
// 切换主题颜色
|
||||
state.theme = finalTheme;
|
||||
state.systemTheme = true;
|
||||
document.documentElement.setAttribute('theme-mode', finalTheme);
|
||||
}
|
||||
},
|
||||
switchColor: (state, action) => {
|
||||
if (action?.payload) {
|
||||
state.color = action?.payload;
|
||||
const mode = state.theme;
|
||||
|
||||
const hex = action?.payload;
|
||||
|
||||
const { colors: newPalette, primary: brandColorIndex } = Color.getColorGradations({
|
||||
colors: [hex],
|
||||
step: 10,
|
||||
remainInput: false, // 是否保留输入 不保留会矫正不合适的主题色
|
||||
})[0];
|
||||
const newColorMap = generateColorMap(hex, newPalette, mode, brandColorIndex);
|
||||
insertThemeStylesheet(hex, newColorMap, mode);
|
||||
|
||||
document.documentElement.setAttribute('theme-color', hex || '');
|
||||
}
|
||||
},
|
||||
switchLayout: (state, action) => {
|
||||
if (action?.payload) {
|
||||
state.layout = action?.payload;
|
||||
}
|
||||
},
|
||||
switchFullPage: (state, action) => {
|
||||
state.isFullPage = !!action?.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: () => {},
|
||||
});
|
||||
|
||||
export const selectGlobal = (state: RootState) => state.global;
|
||||
|
||||
export const {
|
||||
toggleMenu,
|
||||
toggleSetting,
|
||||
toggleShowHeader,
|
||||
toggleShowBreadcrumbs,
|
||||
toggleShowFooter,
|
||||
switchTheme,
|
||||
switchColor,
|
||||
switchLayout,
|
||||
switchFullPage,
|
||||
openSystemTheme,
|
||||
} = globalSlice.actions;
|
||||
|
||||
export default globalSlice.reducer;
|
||||
Reference in New Issue
Block a user