Compare commits

...

2 Commits

View File

@@ -1,81 +1,116 @@
<script setup lang="ts"> <script setup lang="ts">
import ManageLayout from '@/views/ManageLayout.vue'; import ManageLayout from '@/views/ManageLayout.vue';
import ViewerLayout from '@/views/ViewerLayout.vue'; import ViewerLayout from '@/views/ViewerLayout.vue';
import { import {
dateZhCN, dateZhCN,
NConfigProvider, NConfigProvider,
NDialogProvider, NDialogProvider,
NElement, NElement,
NLayoutContent, NLayoutContent,
NLoadingBarProvider, NLoadingBarProvider,
NMessageProvider, NMessageProvider,
NModalProvider, NModalProvider,
NNotificationProvider, NNotificationProvider,
NSpin, NSpin,
zhCN, zhCN,
} from 'naive-ui'; } from 'naive-ui';
import { computed } from 'vue'; import { computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import TempComponent from './components/TempComponent.vue'; import TempComponent from './components/TempComponent.vue';
import { isDarkMode, theme } from './Utils'; import { isDarkMode, theme } from './Utils';
import OBSLayout from './views/OBSLayout.vue'; import OBSLayout from './views/OBSLayout.vue';
import OpenLiveLayout from './views/OpenLiveLayout.vue'; import OpenLiveLayout from './views/OpenLiveLayout.vue';
import ClientLayout from './client/ClientLayout.vue'; import ClientLayout from './client/ClientLayout.vue';
import { ThemeType } from './api/api-models'; import { ThemeType } from './api/api-models';
const route = useRoute(); const route = useRoute();
const themeType = useStorage('Settings.Theme', ThemeType.Auto); const themeType = useStorage('Settings.Theme', ThemeType.Auto);
const layout = computed(() => { const layout = computed(() => {
if (route.path.startsWith('/user') || route.name == 'user' || route.path.startsWith('/@')) { if (route.path.startsWith('/user') || route.name == 'user' || route.path.startsWith('/@')) {
document.title = `${route.meta.title} · ${route.params.id} · VTsuru`; document.title = `${route.meta.title} · ${route.params.id} · VTsuru`;
return 'viewer'; return 'viewer';
} }
else if (route.path.startsWith('/manage')) { else if (route.path.startsWith('/manage')) {
document.title = `${route.meta.title} · 管理 · VTsuru`; document.title = `${route.meta.title} · 管理 · VTsuru`;
return 'manage'; return 'manage';
} }
else if (route.path.startsWith('/open-live')) { else if (route.path.startsWith('/open-live')) {
document.title = `${route.meta.title} · 开放平台 · VTsuru`; document.title = `${route.meta.title} · 开放平台 · VTsuru`;
return 'open-live'; return 'open-live';
} }
else if (route.path.startsWith('/obs')) { else if (route.path.startsWith('/obs')) {
document.title = `${route.meta.title} · OBS · VTsuru`; document.title = `${route.meta.title} · OBS · VTsuru`;
return 'obs'; return 'obs';
} }
else if (route.path.startsWith('/client')) { else if (route.path.startsWith('/client')) {
document.title = `${route.meta.title} · 客户端 · VTsuru`; document.title = `${route.meta.title} · 客户端 · VTsuru`;
return 'client'; return 'client';
} }
else { else {
document.title = `${route.meta.title} · VTsuru`; document.title = `${route.meta.title} · VTsuru`;
return ''; return '';
} }
}); });
watchEffect(() => { watchEffect(() => {
if (isDarkMode.value) { if (isDarkMode.value) {
document.documentElement.classList.add('dark'); document.documentElement.classList.add('dark');
} else { } else {
document.documentElement.classList.remove('dark'); document.documentElement.classList.remove('dark');
} }
}); });
const themeOverrides = { const themeOverrides = computed(() => {
return {
common: { common: {
// primaryColor: '#9ddddc', // 主色调 (中蓝色基调,调整对比度)
primaryColor: '#5A7A9E',
primaryColorHover: '#7390B1', // 略微提亮悬浮色
primaryColorPressed: '#4F7094', // 调整按下色,避免在暗色模式下过暗
primaryColorSuppl: '#8CA6C1', // 调整补充色,使其与背景有区分
// 信息色 (浅蓝色基调,调整对比度)
infoColor: '#8CB1C7', // 稍微加深基础信息色
infoColorHover: '#A6C3D6', // 提亮悬浮色
infoColorPressed: '#7DA0B5', // 调整按下色
infoColorSuppl: '#D0DDE8', // 调整补充色
// 成功色 (柔和青绿)
successColor: '#4DB6AC',
successColorHover: '#6BC4B9', // 调整悬浮色
successColorPressed: '#3E9A90', // 调整按下色
successColorSuppl: '#C1E7E2', // 调整补充色
// 警告色 (柔和橙色)
warningColor: '#FFB74D',
warningColorHover: '#FFC870', // 调整悬浮色
warningColorPressed: '#F8A830', // 调整按下色
warningColorSuppl: '#FFE9C7', // 调整补充色
// 错误色 (柔和红色)
errorColor: '#E57373',
errorColorHover: '#EC8F8F', // 调整悬浮色
errorColorPressed: '#D96060', // 调整按下色
errorColorSuppl: '#F5C7C7', // 调整补充色
// 保持字体设置
fontFamily: fontFamily:
'Inter ,"Noto Sans SC",-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"!important', 'Inter ,"Noto Sans SC",-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"!important',
}, },
// ... Tooltip: {
}; color: isDarkMode.value ? '#48484e' : '#FFFFFF',
const body = document.body; textColor: isDarkMode.value ? '#FFFFFF' : '#333639',
onMounted(() => {
if (isDarkMode.value) {
document.documentElement.classList.add('dark');
console.log('Added dark class to HTML'); // For debugging
} }
}); };
})
const body = document.body;
onMounted(() => {
if (isDarkMode.value) {
document.documentElement.classList.add('dark');
}
});
</script> </script>
<template> <template>
@@ -95,7 +130,10 @@
<Suspense> <Suspense>
<TempComponent> <TempComponent>
<NLayoutContent> <NLayoutContent>
<NElement style="height: 100vh;"> <NElement
style="height: 100vh;"
:theme-overrides="themeOverrides"
>
<ViewerLayout v-if="layout == 'viewer'" /> <ViewerLayout v-if="layout == 'viewer'" />
<ManageLayout v-else-if="layout == 'manage'" /> <ManageLayout v-else-if="layout == 'manage'" />
<OpenLiveLayout v-else-if="layout == 'open-live'" /> <OpenLiveLayout v-else-if="layout == 'open-live'" />
@@ -123,129 +161,129 @@
</template> </template>
<style> <style>
:root {
font-feature-settings: 'liga' 1, 'calt' 1;
--vtsuru-header-height: 50px;
--vtsuru-content-padding: 12px;
}
@supports (font-variation-settings: normal) {
:root { :root {
font-feature-settings: 'liga' 1, 'calt' 1; font-family: InterVariable, sans-serif;
--vtsuru-header-height: 50px;
--vtsuru-content-padding: 12px;
} }
}
@supports (font-variation-settings: normal) { /* 进入和离开过渡的样式 */
:root { .v-enter-from,
font-family: InterVariable, sans-serif; .v-leave-to {
} opacity: 0;
} }
/* 进入和离开过渡的样式 */ /* 离开和进入过程中的样式 */
.v-enter-from, .v-enter-active,
.v-leave-to { .v-leave-active {
/* 添加过渡动画 */
transition: opacity 0.5s ease;
}
/* 进入之后和离开之前的样式 */
.v-enter-to,
.v-leave-from {
opacity: 1;
}
.bounce-enter-active {
animation: bounce 0.3s;
}
.bounce-leave-active {
animation: bounce 0.3s reverse;
}
@keyframes bounce {
0% {
transform: scale(1);
opacity: 0; opacity: 0;
} }
/* 离开和进入过程中的样式 */ 60% {
.v-enter-active, transform: scale(1.1);
.v-leave-active {
/* 添加过渡动画 */
transition: opacity 0.5s ease;
} }
/* 进入之后和离开之前的样式 */ 100% {
.v-enter-to, transform: scale(1);
.v-leave-from {
opacity: 1; opacity: 1;
} }
}
.bounce-enter-active { .fade-enter-active,
animation: bounce 0.3s; .fade-leave-active {
} transition: opacity 0.3s ease;
}
.bounce-leave-active { .fade-enter-from,
animation: bounce 0.3s reverse; .fade-leave-to {
} opacity: 0;
}
@keyframes bounce { .scale-enter-active,
0% { .scale-leave-active {
transform: scale(1); transition: all 0.3s ease;
opacity: 0; }
}
60% { .scale-enter-from,
transform: scale(1.1); .scale-leave-to {
} opacity: 0;
transform: scale(0.9);
}
100% { .slide-enter-active,
transform: scale(1); .slide-leave-active {
opacity: 1; transition: all 0.5s ease-out;
} }
}
.fade-enter-active, .slide-enter-to {
.fade-leave-active { position: absolute;
transition: opacity 0.3s ease; right: 0;
} }
.fade-enter-from, .slide-enter-from {
.fade-leave-to { position: absolute;
opacity: 0; right: -100%;
} }
.scale-enter-active, .slide-leave-to {
.scale-leave-active { position: absolute;
transition: all 0.3s ease; left: -100%;
} }
.scale-enter-from, .slide-leave-from {
.scale-leave-to { position: absolute;
opacity: 0; left: 0;
transform: scale(0.9); }
}
.slide-enter-active, .slide-up-enter-active,
.slide-leave-active { .slide-up-leave-active {
transition: all 0.5s ease-out; transition: all 0.5s ease-out;
} }
.slide-enter-to { .slide-up-enter-to {
position: absolute; position: absolute;
right: 0; top: 0;
} }
.slide-enter-from { .slide-up-enter-from {
position: absolute; position: absolute;
right: -100%; top: -100%;
} }
.slide-leave-to { .slide-up-leave-to {
position: absolute; position: absolute;
left: -100%; bottom: -100%;
} }
.slide-leave-from { .slide-up-leave-from {
position: absolute; position: absolute;
left: 0; bottom: 0;
} }
.slide-up-enter-active,
.slide-up-leave-active {
transition: all 0.5s ease-out;
}
.slide-up-enter-to {
position: absolute;
top: 0;
}
.slide-up-enter-from {
position: absolute;
top: -100%;
}
.slide-up-leave-to {
position: absolute;
bottom: -100%;
}
.slide-up-leave-from {
position: absolute;
bottom: 0;
}
</style> </style>