diff --git a/frontend/package.json b/frontend/package.json index 0ba6de8a9..5d230d35d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -87,6 +87,7 @@ "vite-plugin-eslint": "^1.6.0", "vite-plugin-html": "^3.2.0", "vite-plugin-vue-setup-extend": "^0.4.0", + "vite-svg-loader": "^5.1.0", "vue-tsc": "^0.29.8" }, "overrides": { diff --git a/frontend/src/assets/images/1panel-logo-dark.png b/frontend/src/assets/images/1panel-logo-dark.png deleted file mode 100644 index bf5369b71..000000000 Binary files a/frontend/src/assets/images/1panel-logo-dark.png and /dev/null differ diff --git a/frontend/src/assets/images/1panel-logo-light.png b/frontend/src/assets/images/1panel-logo-light.png deleted file mode 100644 index 6f82a12d5..000000000 Binary files a/frontend/src/assets/images/1panel-logo-light.png and /dev/null differ diff --git a/frontend/src/assets/images/1panel-logo.svg b/frontend/src/assets/images/1panel-logo.svg new file mode 100644 index 000000000..97d2a71a8 --- /dev/null +++ b/frontend/src/assets/images/1panel-logo.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/assets/images/1panel-menu-dark.png b/frontend/src/assets/images/1panel-menu-dark.png deleted file mode 100644 index 759f81d00..000000000 Binary files a/frontend/src/assets/images/1panel-menu-dark.png and /dev/null differ diff --git a/frontend/src/assets/images/1panel-menu-light.png b/frontend/src/assets/images/1panel-menu-light.png deleted file mode 100644 index d7b869ebe..000000000 Binary files a/frontend/src/assets/images/1panel-menu-light.png and /dev/null differ diff --git a/frontend/src/assets/images/1panel-menu-logo.svg b/frontend/src/assets/images/1panel-menu-logo.svg new file mode 100644 index 000000000..125714954 --- /dev/null +++ b/frontend/src/assets/images/1panel-menu-logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/src/components/license-import/index.vue b/frontend/src/components/license-import/index.vue index efcd24e5b..8e5b62a06 100644 --- a/frontend/src/components/license-import/index.vue +++ b/frontend/src/components/license-import/index.vue @@ -1,8 +1,8 @@ - + - {{ $t('license.levelUpPro') }} + {{ $t('license.levelUpPro') }} - + @@ -88,7 +84,10 @@ import { MsgSuccess } from '@/utils/message'; import { onMounted, ref } from 'vue'; import { GlobalStore } from '@/store'; import { ElMessageBox } from 'element-plus'; +import { storeToRefs } from 'pinia'; + const globalStore = GlobalStore(); +const { isDarkTheme } = storeToRefs(globalStore); const version = ref(''); const isProductPro = ref(); diff --git a/frontend/src/components/v-charts/components/Line.vue b/frontend/src/components/v-charts/components/Line.vue index 0658b3f7c..0a408257f 100644 --- a/frontend/src/components/v-charts/components/Line.vue +++ b/frontend/src/components/v-charts/components/Line.vue @@ -6,7 +6,10 @@ import { onMounted, nextTick, watch, onBeforeUnmount } from 'vue'; import * as echarts from 'echarts'; import { GlobalStore } from '@/store'; import { computeSizeFromKBs, computeSizeFromKB, computeSizeFromMB } from '@/utils/util'; +import { storeToRefs } from 'pinia'; const globalStore = GlobalStore(); +const { isDarkTheme } = storeToRefs(globalStore); + const props = defineProps({ id: { type: String, @@ -89,8 +92,6 @@ function initChart() { itemChart = echarts.init(document.getElementById(props.id) as HTMLElement); } - const theme = globalStore.$state.themeConfig.theme || 'light'; - const series = []; if (props.option?.yData?.length) { props.option?.yData.forEach((item: any, index: number) => { @@ -112,7 +113,7 @@ function initChart() { show: true, lineStyle: { type: 'dashed', - opacity: theme === 'dark' ? 0.1 : 1, + opacity: isDarkTheme.value ? 0.1 : 1, }, }, ...item, @@ -184,7 +185,7 @@ function initChart() { //分隔辅助线 lineStyle: { type: 'dashed', //线的类型 虚线0 - opacity: theme === 'dark' ? 0.1 : 1, //透明度 + opacity: isDarkTheme.value ? 0.1 : 1, //透明度 }, }, }, diff --git a/frontend/src/components/v-charts/components/Pie.vue b/frontend/src/components/v-charts/components/Pie.vue index 87fee0d80..693bc046c 100644 --- a/frontend/src/components/v-charts/components/Pie.vue +++ b/frontend/src/components/v-charts/components/Pie.vue @@ -5,7 +5,10 @@ import { onMounted, nextTick, watch, onBeforeUnmount } from 'vue'; import * as echarts from 'echarts'; import { GlobalStore } from '@/store'; +import { storeToRefs } from 'pinia'; const globalStore = GlobalStore(); +const { isDarkGoldTheme, isDarkTheme } = storeToRefs(globalStore); + const props = defineProps({ id: { type: String, @@ -30,7 +33,6 @@ function initChart() { if (myChart === null || myChart === undefined) { myChart = echarts.init(document.getElementById(props.id) as HTMLElement); } - const theme = globalStore.$state.themeConfig.theme || 'light'; let percentText = String(props.option.data).split('.'); const option = { title: [ @@ -47,7 +49,7 @@ function initChart() { }, }, - color: theme === 'dark' ? '#ffffff' : '#0f0f0f', + color: isDarkTheme.value ? '#ffffff' : '#0f0f0f', lineHeight: 25, // fontSize: 20, fontWeight: 500, @@ -56,7 +58,7 @@ function initChart() { top: '32%', subtext: props.option.title, subtextStyle: { - color: theme === 'dark' ? '#BBBFC4' : '#646A73', + color: isDarkTheme.value ? '#BBBFC4' : '#646A73', fontSize: 13, }, textAlign: 'center', @@ -91,17 +93,17 @@ function initChart() { showBackground: true, coordinateSystem: 'polar', backgroundStyle: { - color: theme === 'dark' ? 'rgba(255, 255, 255, 0.05)' : 'rgba(0, 94, 235, 0.05)', + color: isDarkTheme.value ? 'rgba(255, 255, 255, 0.05)' : 'rgba(0, 94, 235, 0.05)', }, color: [ new echarts.graphic.LinearGradient(0, 1, 0, 0, [ { offset: 0, - color: 'rgba(81, 192, 255, .1)', + color: isDarkGoldTheme.value ? '#836c4c' : 'rgba(81, 192, 255, .1)', }, { offset: 1, - color: '#4261F6', + color: isDarkGoldTheme.value ? '#eaba63' : '#4261F6', }, ]), ], @@ -117,12 +119,12 @@ function initChart() { label: { show: false, }, - color: theme === 'dark' ? '#16191D' : '#fff', + color: isDarkTheme.value ? '#16191D' : '#fff', data: [ { value: 0, itemStyle: { - shadowColor: theme === 'dark' ? '#16191D' : 'rgba(0, 94, 235, 0.1)', + shadowColor: isDarkTheme.value ? '#16191D' : 'rgba(0, 94, 235, 0.1)', shadowBlur: 5, }, }, diff --git a/frontend/src/hooks/use-logo.ts b/frontend/src/hooks/use-logo.ts index dedff5f07..575280375 100644 --- a/frontend/src/hooks/use-logo.ts +++ b/frontend/src/hooks/use-logo.ts @@ -1,14 +1,16 @@ import { GlobalStore } from '@/store'; -import { searchXSetting } from '@/xpack/api/modules/setting'; +import { getXpackSetting } from '@/utils/xpack'; export const useLogo = async () => { const globalStore = GlobalStore(); - const res = await searchXSetting(); - localStorage.setItem('1p-favicon', res.data.logo); - globalStore.themeConfig.title = res.data.title; - globalStore.themeConfig.logo = res.data.logo; - globalStore.themeConfig.logoWithText = res.data.logoWithText; - globalStore.themeConfig.favicon = res.data.favicon; + const res = await getXpackSetting(); + if (res) { + localStorage.setItem('1p-favicon', res.data.logo); + globalStore.themeConfig.title = res.data.title; + globalStore.themeConfig.logo = res.data.logo; + globalStore.themeConfig.logoWithText = res.data.logoWithText; + globalStore.themeConfig.favicon = res.data.favicon; + } const link = (document.querySelector("link[rel*='icon']") || document.createElement('link')) as HTMLLinkElement; link.type = 'image/x-icon'; diff --git a/frontend/src/hooks/use-theme.ts b/frontend/src/hooks/use-theme.ts index 4cca68798..f56f35385 100644 --- a/frontend/src/hooks/use-theme.ts +++ b/frontend/src/hooks/use-theme.ts @@ -1,48 +1,62 @@ -import { computed, onBeforeMount } from 'vue'; -import { getLightColor, getDarkColor } from '@/utils/theme/tool'; +import { onBeforeMount, watch } from 'vue'; import { GlobalStore } from '@/store'; -import { MsgSuccess } from '@/utils/message'; +import { storeToRefs } from 'pinia'; export const useTheme = () => { - const globalStore = GlobalStore(); - const themeConfig = computed(() => globalStore.themeConfig); + const { themeConfig } = storeToRefs(GlobalStore()); + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); - const switchDark = () => { + /** + * This method is only executed when loading or manually switching for the first time. + */ + const switchTheme = () => { if (themeConfig.value.theme === 'auto') { - const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); themeConfig.value.theme = prefersDark.matches ? 'dark' : 'light'; + if (prefersDark.addEventListener) { + prefersDark.addEventListener('change', switchAccordingUserProxyTheme); + } else if (prefersDark.addListener) { + prefersDark.addListener(switchAccordingUserProxyTheme); + } + } else { + prefersDark.removeEventListener('change', switchAccordingUserProxyTheme); + prefersDark.removeListener(switchAccordingUserProxyTheme); } - const body = document.documentElement as HTMLElement; - if (themeConfig.value.theme === 'dark') body.setAttribute('class', 'dark'); - else body.setAttribute('class', ''); + updateTheme(themeConfig.value.theme); }; - const changePrimary = (val: string) => { - if (!val) { - val = '#409EFF'; - MsgSuccess('主题颜色已重置为 #409EFF'); - } - globalStore.setThemeConfig({ ...themeConfig.value, primary: val }); - document.documentElement.style.setProperty( - '--el-color-primary-dark-2', - `${getDarkColor(themeConfig.value.primary, 0.1)}`, - ); - document.documentElement.style.setProperty('--el-color-primary', themeConfig.value.primary); - for (let i = 1; i <= 9; i++) { - document.documentElement.style.setProperty( - `--el-color-primary-light-${i}`, - `${getLightColor(themeConfig.value.primary, i / 10)}`, - ); - } + const switchAccordingUserProxyTheme = (event: MediaQueryListEvent) => { + const preferTheme = event.matches ? 'dark' : 'light'; + + themeConfig.value.theme = preferTheme; + updateTheme(preferTheme); + }; + + const updateTheme = (theme: string) => { + const body = document.documentElement as HTMLElement; + body.setAttribute('class', theme); }; onBeforeMount(() => { - switchDark(); - changePrimary(themeConfig.value.primary); + updateTheme(themeConfig.value.theme); + }); + + /** + * Called internally by the system for automatically switching themes + */ + const autoSwitchTheme = () => { + let preferTheme = themeConfig.value.theme; + if (themeConfig.value.theme === 'auto') { + preferTheme = prefersDark.matches ? 'dark' : 'light'; + } + updateTheme(preferTheme); + }; + + watch(themeConfig, () => { + autoSwitchTheme(); }); return { - switchDark, - changePrimary, + autoSwitchTheme, + switchTheme, }; }; diff --git a/frontend/src/layout/components/Sidebar/components/Logo.vue b/frontend/src/layout/components/Sidebar/components/Logo.vue index bafb9906e..34efac09b 100644 --- a/frontend/src/layout/components/Sidebar/components/Logo.vue +++ b/frontend/src/layout/components/Sidebar/components/Logo.vue @@ -1,35 +1,34 @@ - - + + + + + + + + +