深色主题切换功能初步实现

This commit is contained in:
kwicxy
2025-05-29 01:28:45 +08:00
parent 51666464b9
commit 88ad373c9b
21 changed files with 288 additions and 201 deletions
@@ -340,12 +340,12 @@ export default {
.config-title {
font-weight: 600;
font-size: 1rem;
color: var(--v-primary-darken1);
color: var(--v-theme-primaryText);
}
.config-hint {
font-size: 0.75rem;
color: rgba(0, 0, 0, 0.6);
color: var(--v-theme-secondaryText);
margin-top: 2px;
}
@@ -400,12 +400,12 @@ export default {
.property-name {
font-size: 0.875rem;
font-weight: 600;
color: rgba(0, 0, 0, 0.87);
color: var(--v-theme-primaryText);
}
.property-hint {
font-size: 0.75rem;
color: rgba(0, 0, 0, 0.6);
color: var(--v-theme-secondaryText);
margin-top: 2px;
}
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { ref, computed, inject } from 'vue';
import {useCustomizerStore} from "@/stores/customizer";
const props = defineProps({
extension: {
@@ -75,7 +76,7 @@ const viewReadme = () => {
<template>
<v-card class="mx-auto d-flex flex-column" :elevation="highlight ? 0 : 1"
:style="{ height: $vuetify.display.xs ? '250px' : '220px', backgroundColor: highlight ? '#FAF0DB' : '#ffffff', color: highlight ? '#000' : '#000000' }">
:style="{ height: $vuetify.display.xs ? '250px' : '220px', backgroundColor: useCustomizerStore().uiTheme==='PurpleThemeDark' ? 'var(--v-theme-surface)' : 'var(--v-theme-lightprimary)', color: 'var(--v-theme-primaryText)' }">
<v-card-text style="padding: 16px; padding-bottom: 0px; display: flex; justify-content: space-between;">
<div class="flex-grow-1">
@@ -104,11 +104,11 @@ export default {
<style scoped>
.list-config-item {
border: 1px solid #e0e0e0;
border: 1px solid var(--v-theme-border);
padding: 16px;
margin-bottom: 8px;
border-radius: 10px;
background-color: #ffffff;
background-color: var(--v-theme-background);
}
.v-list-item {
+2
View File
@@ -3,6 +3,7 @@ export type ConfigProps = {
Customizer_drawer: boolean;
mini_sidebar: boolean;
fontTheme: string;
uiTheme: string;
inputBg: boolean;
};
@@ -11,6 +12,7 @@ const config: ConfigProps = {
Customizer_drawer: false,
mini_sidebar: false,
fontTheme: 'Roboto',
uiTheme: 'PurpleThemeDark',
inputBg: false
};
+1 -1
View File
@@ -9,7 +9,7 @@ const customizer = useCustomizerStore();
<template>
<v-locale-provider>
<v-app
theme="PurpleTheme"
:theme="useCustomizerStore().uiTheme"
:class="[customizer.fontTheme, customizer.mini_sidebar ? 'mini-sidebar' : '', customizer.inputBg ? 'inputWithbg' : '']"
>
<VerticalHeaderVue />
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useCustomizerStore } from '../../../stores/customizer';
import {ref} from 'vue';
import {useCustomizerStore} from '@/stores/customizer';
import axios from 'axios';
import { md5 } from 'js-md5';
import { useAuthStore } from '@/stores/auth';
import { useCommonStore } from '@/stores/common';
import { marked } from 'marked';
import {md5} from 'js-md5';
import {useAuthStore} from '@/stores/auth';
import {useCommonStore} from '@/stores/common';
import {marked} from 'marked';
const customizer = useCustomizerStore();
let dialog = ref(false);
@@ -30,11 +30,11 @@ let installLoading = ref(false);
let tab = ref(0);
let releasesHeader = [
{ title: '标签', key: 'tag_name' },
{ title: '发布时间', key: 'published_at' },
{ title: '内容', key: 'body' },
{ title: '源码地址', key: 'zipball_url' },
{ title: '操作', key: 'switch' }
{title: '标签', key: 'tag_name'},
{title: '发布时间', key: 'published_at'},
{title: '内容', key: 'body'},
{title: '源码地址', key: 'zipball_url'},
{title: '操作', key: 'switch'}
];
const open = (link: string) => {
@@ -56,78 +56,78 @@ function accountEdit() {
new_password: newPassword.value,
new_username: newUsername.value
})
.then((res) => {
if (res.data.status == 'error') {
.then((res) => {
if (res.data.status == 'error') {
status.value = res.data.message;
password.value = '';
newPassword.value = '';
return;
}
dialog.value = !dialog.value;
status.value = res.data.message;
setTimeout(() => {
const authStore = useAuthStore();
authStore.logout();
}, 1000);
})
.catch((err) => {
console.log(err);
status.value = err
password.value = '';
newPassword.value = '';
return;
}
dialog.value = !dialog.value;
status.value = res.data.message;
setTimeout(() => {
const authStore = useAuthStore();
authStore.logout();
}, 1000);
})
.catch((err) => {
console.log(err);
status.value = err
password.value = '';
newPassword.value = '';
});
});
}
function getVersion() {
axios.get('/api/stat/version')
.then((res) => {
botCurrVersion.value = "v" + res.data.data.version;
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
})
.catch((err) => {
console.log(err);
});
.then((res) => {
botCurrVersion.value = "v" + res.data.data.version;
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
})
.catch((err) => {
console.log(err);
});
}
function checkUpdate() {
updateStatus.value = '正在检查更新...';
axios.get('/api/update/check')
.then((res) => {
hasNewVersion.value = res.data.data.has_new_version;
.then((res) => {
hasNewVersion.value = res.data.data.has_new_version;
if (res.data.data.has_new_version) {
releaseMessage.value = res.data.message;
updateStatus.value = '有新版本!';
} else {
updateStatus.value = res.data.message;
}
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
})
.catch((err) => {
if (err.response.status == 401) {
console.log("401");
const authStore = useAuthStore();
authStore.logout();
return;
}
console.log(err);
updateStatus.value = err
});
if (res.data.data.has_new_version) {
releaseMessage.value = res.data.message;
updateStatus.value = '有新版本!';
} else {
updateStatus.value = res.data.message;
}
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
})
.catch((err) => {
if (err.response.status == 401) {
console.log("401");
const authStore = useAuthStore();
authStore.logout();
return;
}
console.log(err);
updateStatus.value = err
});
}
function getReleases() {
axios.get('/api/update/releases')
.then((res) => {
// releases.value = res.data.data;
// 更新 published_at 的时间为本地时间
releases.value = res.data.data.map((item: any) => {
item.published_at = new Date(item.published_at).toLocaleString();
return item;
.then((res) => {
// releases.value = res.data.data;
// 更新 published_at 的时间为本地时间
releases.value = res.data.data.map((item: any) => {
item.published_at = new Date(item.published_at).toLocaleString();
return item;
})
})
})
.catch((err) => {
console.log(err);
});
.catch((err) => {
console.log(err);
});
}
function getDevCommits() {
@@ -137,17 +137,17 @@ function getDevCommits() {
'Referer': 'https://api.github.com'
}
})
.then(response => response.json())
.then(data => {
devCommits.value = data.map((commit: any) => ({
sha: commit.sha,
date: new Date(commit.commit.author.date).toLocaleString(),
message: commit.commit.message
}));
})
.catch(err => {
console.log(err);
});
.then(response => response.json())
.then(data => {
devCommits.value = data.map((commit: any) => ({
sha: commit.sha,
date: new Date(commit.commit.author.date).toLocaleString(),
message: commit.commit.message
}));
})
.catch(err => {
console.log(err);
});
}
function switchVersion(version: string) {
@@ -157,37 +157,41 @@ function switchVersion(version: string) {
version: version,
proxy: localStorage.getItem('selectedGitHubProxy') || ''
})
.then((res) => {
updateStatus.value = res.data.message;
if (res.data.status == 'ok') {
setTimeout(() => {
window.location.reload();
}, 1000);
}
})
.catch((err) => {
console.log(err);
updateStatus.value = err
}).finally(() => {
installLoading.value = false;
});
.then((res) => {
updateStatus.value = res.data.message;
if (res.data.status == 'ok') {
setTimeout(() => {
window.location.reload();
}, 1000);
}
})
.catch((err) => {
console.log(err);
updateStatus.value = err
}).finally(() => {
installLoading.value = false;
});
}
function updateDashboard() {
updateStatus.value = '正在更新...';
axios.post('/api/update/dashboard')
.then((res) => {
updateStatus.value = res.data.message;
if (res.data.status == 'ok') {
setTimeout(() => {
window.location.reload();
}, 1000);
}
})
.catch((err) => {
console.log(err);
updateStatus.value = err
});
.then((res) => {
updateStatus.value = res.data.message;
if (res.data.status == 'ok') {
setTimeout(() => {
window.location.reload();
}, 1000);
}
})
.catch((err) => {
console.log(err);
updateStatus.value = err
});
}
function toggleDarkMode() {
customizer.SET_UI_THEME(customizer.uiTheme === 'PurpleThemeDark' ? 'PurpleTheme' : 'PurpleThemeDark');
}
getVersion();
@@ -210,21 +214,21 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
<v-app-bar elevation="0" height="55">
<v-btn style="margin-left: 22px;" class="hidden-md-and-down text-secondary" color="lightsecondary" icon rounded="sm"
variant="flat" @click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
variant="flat" @click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
<v-icon>mdi-menu</v-icon>
</v-btn>
<v-btn class="hidden-lg-and-up text-secondary ms-3" color="lightsecondary" icon rounded="sm" variant="flat"
@click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
@click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
<v-icon>mdi-menu</v-icon>
</v-btn>
<div style="margin-left: 16px; display: flex; align-items: center; gap: 8px;">
<span style=" font-size: 24px; font-weight: 1000;">Astr<span style="font-weight: normal;">Bot</span>
</span>
<span style="font-size: 12px; color: #333333;">{{ botCurrVersion }}</span>
<span style="font-size: 12px; color: color(var(--v-theme-secondaryText));">{{ botCurrVersion }}</span>
</div>
<v-spacer />
<v-spacer/>
<div class="mr-4">
<small v-if="hasNewVersion">
@@ -235,11 +239,16 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
</small>
</div>
<v-btn size="small" @click="toggleDarkMode();" class="text-primary mr-2" color="color(var(--v-theme-surface))"
variant="flat" rounded="sm">
<v-icon>mdi-lightbulb-night-outline</v-icon>
</v-btn>
<v-dialog v-model="updateStatusDialog" width="1000">
<template v-slot:activator="{ props }">
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="text-primary mr-2" color="lightprimary"
variant="flat" rounded="sm" v-bind="props">
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="text-primary mr-2"
color="color(var(--v-theme-surface))"
variant="flat" rounded="sm" v-bind="props">
更新
</v-btn>
</template>
@@ -257,15 +266,16 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
</div>
<div
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
v-html="marked(releaseMessage)" class="markdown-content">
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
v-html="marked(releaseMessage)" class="markdown-content">
</div>
<div class="mb-4 mt-4">
<small>💡 TIP: 跳到旧版本或者切换到某个版本不会重新下载管理面板文件这可能会造成部分数据显示错误您可在 <a
href="https://github.com/Soulter/AstrBot/releases">此处</a>
找到对应的面板文件 dist.zip解压后替换 data/dist 文件夹即可当然前端源代码在 dashboard 目录下你也可以自己使用 npm install npm build
找到对应的面板文件 dist.zip解压后替换 data/dist 文件夹即可当然前端源代码在 dashboard 目录下你也可以自己使用
npm install npm build
构建</small>
</div>
@@ -278,12 +288,13 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
<!-- 发行版 -->
<v-tabs-window-item key="0" v-show="tab == 0">
<v-btn class="mt-4 mb-4" @click="switchVersion('latest')" color="primary" style="border-radius: 10px;"
:disabled="!hasNewVersion">
:disabled="!hasNewVersion">
更新到最新版本
</v-btn>
<div class="mb-4">
<small>`更新到最新版本` 按钮会同时尝试更新机器人主程序和管理面板如果您正在使用 Docker 部署也可以重新拉取镜像或者使用 <a
href="https://containrrr.dev/watchtower/usage-overview/">watchtower</a> 来自动监控拉取</small>
<small>`更新到最新版本` 按钮会同时尝试更新机器人主程序和管理面板如果您正在使用 Docker
部署也可以重新拉取镜像或者使用 <a
href="https://containrrr.dev/watchtower/usage-overview/">watchtower</a> 来自动监控拉取</small>
</div>
<v-data-table :headers="releasesHeader" :items="releases" item-key="name">
@@ -306,8 +317,8 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
<v-tabs-window-item key="1" v-show="tab == 1">
<div style="margin-top: 16px;">
<v-data-table
:headers="[{ title: 'SHA', key: 'sha' }, { title: '日期', key: 'date' }, { title: '信息', key: 'message' }, { title: '操作', key: 'switch' }]"
:items="devCommits" item-key="sha">
:headers="[{ title: 'SHA', key: 'sha' }, { title: '日期', key: 'date' }, { title: '信息', key: 'message' }, { title: '操作', key: 'switch' }]"
:items="devCommits" item-key="sha">
<template v-slot:item.switch="{ item }: { item: { sha: string } }">
<v-btn @click="switchVersion(item.sha)" rounded="xl" variant="plain" color="primary">
切换
@@ -322,12 +333,13 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
<h3 class="mb-4">手动输入版本号或 Commit SHA</h3>
<v-text-field label="输入版本号或 master 分支下的 commit hash。" v-model="version" required
variant="outlined"></v-text-field>
variant="outlined"></v-text-field>
<div class="mb-4">
<small> v3.3.16 (不带 SHA) 42e5ec5d80b93b6bfe8b566754d45ffac4c3fe0b</small>
<br>
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>查看 master 分支提交记录点击右边的 copy
即可复制</small></a>
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>查看 master 分支提交记录点击右边的
copy
即可复制</small></a>
</div>
<v-btn color="error" style="border-radius: 10px;" @click="switchVersion(version)">
确定切换
@@ -352,7 +364,7 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
</div>
<v-btn color="primary" style="border-radius: 10px;" @click="updateDashboard()"
:disabled="!dashboardHasNewVersion">
:disabled="!dashboardHasNewVersion">
下载并更新
</v-btn>
</div>
@@ -369,7 +381,7 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
<v-dialog v-model="dialog" persistent width="700">
<template v-slot:activator="{ props }">
<v-btn size="small" class="text-primary mr-4" color="lightprimary" variant="flat" rounded="sm" v-bind="props">
<v-btn size="small" class="text-primary mr-4" color="color(var(--v-theme-surface))" variant="flat" rounded="sm" v-bind="props">
账户
</v-btn>
</template>
@@ -387,12 +399,12 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
</v-alert>
<v-text-field label="原密码*" type="password" v-model="password" required
variant="outlined"></v-text-field>
variant="outlined"></v-text-field>
<v-text-field label="新用户名" v-model="newUsername" required variant="outlined"></v-text-field>
<v-text-field label="新密码" type="password" v-model="newPassword" required
variant="outlined"></v-text-field>
variant="outlined"></v-text-field>
</v-col>
</v-row>
</v-container>
+4 -2
View File
@@ -3,15 +3,17 @@ import '@mdi/font/css/materialdesignicons.css';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import { PurpleTheme } from '@/theme/LightTheme';
import {PurpleThemeDark} from "@/theme/DarkTheme";
export default createVuetify({
components,
directives,
theme: {
defaultTheme: 'PurpleTheme',
defaultTheme: 'PurpleThemeDark',
themes: {
PurpleTheme
PurpleTheme,
PurpleThemeDark
}
},
defaults: {
+1 -1
View File
@@ -6,7 +6,7 @@
.listitem {
height: calc(100vh - 100px);
.v-list {
color: rgb(var(--v-theme-lightText));
color: rgb(var(--v-theme-secondaryText));
}
.v-list-group__items .v-list-item,
.v-list-item {
+5 -1
View File
@@ -8,6 +8,7 @@ export const useCustomizerStore = defineStore({
Customizer_drawer: config.Customizer_drawer,
mini_sidebar: config.mini_sidebar,
fontTheme: "Poppins",
uiTheme: config.uiTheme,
inputBg: config.inputBg
}),
@@ -21,6 +22,9 @@ export const useCustomizerStore = defineStore({
},
SET_FONT(payload: string) {
this.fontTheme = payload;
}
},
SET_UI_THEME(payload: string) {
this.uiTheme = payload;
},
}
});
+46
View File
@@ -0,0 +1,46 @@
import type { ThemeTypes } from '@/types/themeTypes/ThemeType';
const PurpleThemeDark: ThemeTypes = {
name: 'PurpleThemeDark',
dark: true,
variables: {
'border-color': '#1677ff',
'carousel-control-size': 10
},
colors: {
primary: '#1677ff',
secondary: '#722ed1',
info: '#03c9d7',
success: '#52c41a',
accent: '#FFAB91',
warning: '#faad14',
error: '#ff4d4f',
lightprimary: '#eef2f6',
lightsecondary: '#ede7f6',
lightsuccess: '#b9f6ca',
lighterror: '#f9d8d8',
lightwarning: '#fff8e1',
primaryText: '#ffffff',
secondaryText: '#ffffffcc',
darkprimary: '#1565c0',
darksecondary: '#4527a0',
borderLight: '#d0d0d0',
border: '#333333ee',
inputBorder: '#787878',
containerBg: '#1a1a1a',
surface: '#1f1f1f',
'on-surface-variant': '#000',
facebook: '#4267b2',
twitter: '#1da1f2',
linkedin: '#0e76a8',
gray100: '#cccccccc',
primary200: '#90caf9',
secondary200: '#b39ddb',
background: '#111111',
overlay: '#111111aa',
codeBg: '#282833',
code: '#ffffffdd'
}
};
export { PurpleThemeDark };
+9 -4
View File
@@ -20,11 +20,12 @@ const PurpleTheme: ThemeTypes = {
lightsuccess: '#b9f6ca',
lighterror: '#f9d8d8',
lightwarning: '#fff8e1',
darkText: '#212121',
lightText: '#616161',
primaryText: '#000000dd',
secondaryText: '#000000aa',
darkprimary: '#1565c0',
darksecondary: '#4527a0',
borderLight: '#d0d0d0',
border: '#d0d0d0',
inputBorder: '#787878',
containerBg: '#eef2f6',
surface: '#fff',
@@ -32,9 +33,13 @@ const PurpleTheme: ThemeTypes = {
facebook: '#4267b2',
twitter: '#1da1f2',
linkedin: '#0e76a8',
gray100: '#fafafa',
gray100: '#fafafacc',
primary200: '#90caf9',
secondary200: '#b39ddb'
secondary200: '#b39ddb',
background: '#f9fafc',
overlay: '#ffffffaa',
codeBg: '#f5f0ff',
code: '#673ab7'
}
};
+6 -2
View File
@@ -17,13 +17,15 @@ export type ThemeTypes = {
lightwarning?: string;
darkprimary?: string;
darksecondary?: string;
darkText?: string;
lightText?: string;
primaryText?: string;
secondaryText?: string;
borderLight?: string;
border?: string;
inputBorder?: string;
containerBg?: string;
surface?: string;
background?: string;
overlay?: string;
'on-surface-variant'?: string;
facebook?: string;
twitter?: string;
@@ -31,5 +33,7 @@ export type ThemeTypes = {
gray100?: string;
primary200?: string;
secondary200?: string;
codeBg?: string;
code?: string;
};
};
+18 -7
View File
@@ -11,7 +11,7 @@
</div>
<div class="title-container">
<h1 class="text-h2 font-weight-bold">AstrBot</h1>
<p class="text-subtitle-1" style="color: #777;">A project out of interests and loves </p>
<p class="text-subtitle-1" style="color: color(var(--v-theme-secondaryText));">A project out of interests and loves </p>
<div class="action-buttons">
<v-btn @click="open('https://github.com/Soulter/AstrBot')"
color="primary" variant="elevated" prepend-icon="mdi-star">
@@ -32,16 +32,20 @@
<v-row justify="center" align="center">
<v-col cols="12" md="6" class="pr-md-8 contributors-info">
<h2 class="text-h4 font-weight-medium">贡献者</h2>
<p class="mb-4 text-body-1" style="color: #777;">
<p class="mb-4 text-body-1" style="color: color(var(--v-theme-secondaryText));">
本项目由众多开源社区成员共同维护感谢每一位贡献者的付出
</p>
<p class="text-body-1" style="color: #777;">
<p class="text-body-1" style="color: color(var(--v-theme-secondaryText));">
<a href="https://github.com/Soulter/AstrBot/graphs/contributors" class="text-decoration-none custom-link">查看 AstrBot 贡献者</a>
</p>
</v-col>
<v-col cols="12" md="6">
<v-card variant="outlined" class="overflow-hidden" elevation="2">
<v-img
<v-img v-if="useCustomizerStore().uiTheme==='PurpleThemeDark'"
alt="Active Contributors of Soulter/AstrBot"
src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=575865240&limit=365&image_size=auto&color_scheme=dark">
</v-img>
<v-img v-else
alt="Active Contributors of Soulter/AstrBot"
src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=575865240&limit=365&image_size=auto&color_scheme=light">
</v-img>
@@ -60,12 +64,16 @@
<div class="license-container mt-8">
<img v-bind="props" src="https://www.gnu.org/graphics/agplv3-with-text-100x42.png" style="cursor: pointer;"/>
<p class="text-caption mt-2" style="color: #777;">AstrBot 采用 AGPL v3 协议开源</p>
<p class="text-caption mt-2" style="color: color(var(--v-theme-secondaryText));">AstrBot 采用 AGPL v3 协议开源</p>
</div>
</v-col>
<v-col cols="12" md="6">
<v-card variant="outlined" class="overflow-hidden" elevation="2">
<v-img
<v-img v-if="useCustomizerStore().uiTheme==='PurpleThemeDark'"
alt="Stars Map of Soulter/AstrBot"
src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?activity=stars&repo_id=575865240&image_size=auto&color_scheme=dark">
</v-img>
<v-img v-else
alt="Stars Map of Soulter/AstrBot"
src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?activity=stars&repo_id=575865240&image_size=auto&color_scheme=light">
</v-img>
@@ -80,6 +88,8 @@
</template>
<script>
import {useCustomizerStore} from "@/stores/customizer";
export default {
name: 'AboutPage',
data() {
@@ -89,6 +99,7 @@ export default {
},
methods: {
useCustomizerStore,
open(url) {
window.open(url, '_blank');
}
@@ -137,7 +148,7 @@ export default {
}
.contributors-section {
background-color: #f9f9fb;
background-color: color(var(--v-theme-containerBg, #f9f9fb));
}
.contributors-info, .stats-info {
+18 -18
View File
@@ -674,7 +674,7 @@ export default {
height: 100%;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05) !important;
background-color: #fff;
background-color: color(var(--v-theme-background));
}
.chat-page-container {
@@ -697,7 +697,7 @@ export default {
flex-direction: column;
padding: 0;
border-right: 1px solid rgba(0, 0, 0, 0.05);
background-color: #fcfcfc;
background-color: color(var(--v-theme-background));
height: 100%;
position: relative;
}
@@ -720,7 +720,7 @@ export default {
.sidebar-section-title {
font-size: 12px;
font-weight: 500;
color: #666;
color: color(var(--v-theme-secondaryText));
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 12px;
@@ -778,7 +778,7 @@ export default {
.timestamp {
font-size: 11px;
color: #999;
color: color(var(--v-theme-secondaryText));
line-height: 1;
}
@@ -821,7 +821,7 @@ export default {
.no-conversations-text {
font-size: 14px;
color: #999;
color: color(var(--v-theme-secondaryText));
}
/* 聊天内容区域 */
@@ -857,21 +857,21 @@ export default {
.bot-name {
font-weight: 700;
margin-left: 8px;
color: #673ab7;
color: color(var(--v-theme-secondary));
}
.welcome-hint {
margin-top: 8px;
color: #666;
color: color(var(--v-theme-secondaryText));
font-size: 14px;
}
.welcome-hint code {
background-color: #f5f0ff;
background-color: color(var(--v-theme-codeBg));
padding: 2px 6px;
margin: 0 4px;
border-radius: 4px;
color: #673ab7;
color: #ffffffcolor(var(--v-theme-code));
font-family: 'Fira Code', monospace;
font-size: 13px;
}
@@ -910,15 +910,15 @@ export default {
}
.user-bubble {
background-color: #f5f0ff;
color: #333;
background-color: color(var(--v-theme-background));
color: color(var(--v-theme-primaryText));
border-top-right-radius: 4px;
}
.bot-bubble {
background-color: #fff;
border: 1px solid #e8e8e8;
color: #333;
background-color: color(var(--v-theme-surface));
border: 1px solid var(--v-theme-border);
color: color(var(--v-theme-primaryText));
border-top-left-radius: 4px;
}
@@ -965,9 +965,9 @@ export default {
/* 输入区域样式 */
.input-area {
padding: 16px;
background-color: #fff;
background-color: color(var(--v-theme-surface));
position: relative;
border-top: 1px solid #f5f5f5;
border-top: 1px solid var(--v-theme-border);
}
.message-input {
@@ -1037,12 +1037,12 @@ export default {
margin-top: 16px;
margin-bottom: 10px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
}
.markdown-content h1 {
font-size: 1.8em;
border-bottom: 1px solid #eee;
border-bottom: 1px solid var(--v-theme-border);
padding-bottom: 6px;
}
+2 -2
View File
@@ -42,7 +42,7 @@ import config from '@/config';
<div v-for="(val2, key2, index2) in metadata[key]['metadata']">
<!-- <h3>{{ metadata[key]['metadata'][key2]['description'] }}</h3> -->
<div v-if="metadata[key]['metadata'][key2]?.config_template"
v-show="key2 !== 'platform' && key2 !== 'provider'" style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px">
v-show="key2 !== 'platform' && key2 !== 'provider'" style="border: 1px solid var(--v-theme-border); padding: 8px; margin-bottom: 16px; border-radius: 10px">
<!-- 带有 config_template 的配置项 -->
<v-list-item-title style="font-weight: bold;">
{{ metadata[key]['metadata'][key2]['description'] }} ({{ key2 }})
@@ -88,7 +88,7 @@ import config from '@/config';
<div v-else>
<!-- 如果配置项是一个 object那么 iterable 需要取到这个 object 的值否则取到整个 config_data -->
<div v-if="metadata[key]['metadata'][key2]['type'] == 'object'" style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px">
<div v-if="metadata[key]['metadata'][key2]['type'] == 'object'" style="border: 1px solid var(--v-theme-border); padding: 8px; margin-bottom: 16px; border-radius: 10px">
<AstrBotConfig
:metadata="metadata[key]['metadata']" :iterable="config_data[key2]" :metadataKey="key2">
</AstrBotConfig>
+1 -1
View File
@@ -7,7 +7,7 @@ import axios from 'axios';
<template>
<div style="height: 100%;">
<div
style="background-color: white; padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px; display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
style="background-color: color(var(--v-theme-surface)); padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px; display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
<h4>控制台</h4>
<div class="d-flex align-center">
<v-switch
+2 -2
View File
@@ -52,7 +52,7 @@ import 'highlight.js/styles/github.css';
<v-card-text>
<small style="color: #bbb;">每个插件都是作者无偿提供的的劳动成果如果您喜欢某个插件 Star</small>
<small style="color: color(var(--v-theme-secondaryText, #bbb));">每个插件都是作者无偿提供的的劳动成果如果您喜欢某个插件 Star</small>
<div v-if="pinnedPlugins.length > 0" class="mt-4">
<h2>🥳 推荐</h2>
@@ -77,7 +77,7 @@ import 'highlight.js/styles/github.css';
style="height: 80px; width: 80px; margin-right: 8px; border-radius: 8px; margin-top: 8px; margin-bottom: 8px;"
alt="logo">
<span v-if="item?.repo"><a :href="item?.repo"
style="color: #000; text-decoration:none">{{
style="color: color(var(--v-theme-primaryText, #000)); text-decoration:none">{{
item.name }}</a></span>
<span v-else>{{ item.name }}</span>
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div style="background-color: white; padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px;">
<div style="background-color: color(var(--v-theme-surface, #fff)); padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px;">
<v-list lines="two">
<v-list-subheader>网络</v-list-subheader>
@@ -155,7 +155,7 @@ export default {
<style scoped>
.dashboard-container {
padding: 16px;
background-color: #f9fafc;
background-color: color(var(--v-theme-background));
min-height: calc(100vh - 64px);
border-radius: 10px;
@@ -170,13 +170,13 @@ export default {
.dashboard-title {
font-size: 24px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
margin-bottom: 4px;
}
.dashboard-subtitle {
font-size: 14px;
color: #666;
color: color(var(--v-theme-secondaryText));
}
.notice-row {
@@ -194,18 +194,18 @@ export default {
.plugin-card {
border-radius: 8px;
background-color: white;
background-color: color(var(--v-theme-surface));
}
.plugin-title {
font-size: 18px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
}
.plugin-subtitle {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
margin-top: 4px;
}
@@ -225,7 +225,7 @@ export default {
.plugin-version {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText, #666));
}
.dashboard-footer {
@@ -167,7 +167,7 @@ export default {
},
},
grid: {
borderColor: '#f1f1f1',
borderColor: "gray100",
row: {
colors: ['transparent', 'transparent'],
opacity: 0.2
@@ -293,12 +293,12 @@ export default {
.chart-title {
font-size: 18px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
}
.chart-subtitle {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
margin-top: 4px;
}
@@ -315,31 +315,31 @@ export default {
.stat-box {
padding: 12px 16px;
background: #f5f5f5;
background: color(var(--v-theme-surface));
border-radius: 8px;
flex: 1;
}
.stat-label {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
margin-bottom: 4px;
}
.stat-number {
font-size: 18px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
display: flex;
align-items: center;
}
.trend-up .stat-number {
color: #4caf50;
color: color(var(--v-theme-success));
}
.trend-down .stat-number {
color: #f44336;
color: color(var(--v-theme-error));
}
.chart-container {
@@ -354,7 +354,7 @@ export default {
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
background: color(var(--v-theme-overlay));
display: flex;
flex-direction: column;
justify-content: center;
@@ -365,6 +365,6 @@ export default {
.loading-text {
margin-top: 12px;
font-size: 14px;
color: #666;
color: color(var(--v-theme-secondaryText));
}
</style>
@@ -132,12 +132,12 @@ export default {
.platform-title {
font-size: 18px;
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
}
.platform-subtitle {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
margin-top: 4px;
}
@@ -171,16 +171,16 @@ export default {
width: 24px;
height: 24px;
border-radius: 50%;
background-color: #f0f0f0;
color: #333;
background-color: color(var(--v-theme-surface));
color: color(var(--v-theme-primaryText));
font-weight: 600;
font-size: 14px;
margin-right: 12px;
}
.top-rank {
background-color: #5e35b1;
color: white;
background-color: color(var(--v-theme-secondary));
color: color(var(--v-theme-surface));
}
.platform-name {
@@ -195,19 +195,19 @@ export default {
.count-value {
font-weight: 600;
font-size: 14px;
color: #5e35b1;
color: color(var(--v-theme-secondary));
margin-right: 4px;
}
.count-label {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
}
.platform-stats-summary {
display: flex;
justify-content: space-between;
background-color: #f5f5f5;
background-color: color(var(--v-theme-containerBg));
border-radius: 8px;
padding: 12px;
margin-bottom: 16px;
@@ -220,13 +220,13 @@ export default {
.stat-label {
font-size: 12px;
color: #666;
color: color(var(--v-theme-secondaryText));
margin-bottom: 4px;
}
.stat-value {
font-weight: 600;
color: #333;
color: color(var(--v-theme-primaryText));
}
.platform-chart {
@@ -246,7 +246,7 @@ export default {
}
.no-data-text {
color: #999;
color: color(var(--v-theme-secondaryText));
margin-top: 16px;
font-size: 14px;
}