Skip to content
This repository was archived by the owner on Mar 11, 2026. It is now read-only.

refactor: 重构项目配置和样式#30

Merged
Soulter merged 2 commits intoAstrBotDevs:v2from
YumeRiMoe:v2
Aug 1, 2025
Merged

refactor: 重构项目配置和样式#30
Soulter merged 2 commits intoAstrBotDevs:v2from
YumeRiMoe:v2

Conversation

@YumeYuka
Copy link
Copy Markdown
Contributor

@YumeYuka YumeYuka commented Jul 22, 2025

  • 重构配置文件结构,拆分 theme 配置便于维护
  • 重组样式文件到 styles 目录,添加字体配置
  • 修复 Sponsors 组件暗色主题兼容性问题
  • 新增文章分享组件和自定义容器样式
  • 完善界面中文本地化配置
  • 应用 Ubuntu 主字体和 JetBrains Mono 代码字体

部分配置来源于: https://github.com/OOM-WG/SSU_Docs

更改前后对比

图片 图片

Sourcery 摘要

重构网站配置和样式,增强主题和本地化,添加分享功能,并修复深色模式问题。

新功能:

  • 引入 ArticleShare 组件,以便轻松复制文章链接
  • 添加自定义容器样式(信息、提示、警告等),并支持浅色和深色主题

错误修复:

  • 修复 Sponsors 组件中的深色模式兼容性

增强:

  • 重构 VitePress 配置,将 themeConfig、head 标签和侧边栏拆分为单独的文件
  • 将样式导入移动到专门的 styles 目录并整合 CSS 文件
  • 将 Ubuntu 应用为主字体,将 JetBrains Mono 应用为代码字体
  • 将主题 UI 标签本地化为中文并改进 head 元数据

构建:

  • 将 Vue 依赖添加到 package.json
Original summary in English

Summary by Sourcery

Restructure site configuration and styling, enhance theming and localization, add sharing functionality, and fix dark mode issues.

New Features:

  • Introduce ArticleShare component for easy copying of article links
  • Add custom container styles (info, tip, warning, etc.) with light and dark theme support

Bug Fixes:

  • Fix dark mode compatibility in the Sponsors component

Enhancements:

  • Refactor VitePress configuration by splitting themeConfig, head tags, and sidebar into separate files
  • Move style imports into a dedicated styles directory and consolidate CSS files
  • Apply Ubuntu as the main font and JetBrains Mono as the code font
  • Localize theme UI labels in Chinese and improve head metadata

Build:

  • Add Vue dependency to package.json

- 重构配置文件结构,拆分 theme 配置便于维护
- 重组样式文件到 styles 目录,添加字体配置
- 修复 Sponsors 组件暗色主题兼容性问题
- 新增文章分享组件和自定义容器样式
- 完善界面中文本地化配置
- 应用 Ubuntu 主字体和 JetBrains Mono 代码字体

Signed-off-by: yumeyuka <yumeyuka@oom-wg.dev>
@netlify
Copy link
Copy Markdown

netlify Bot commented Jul 22, 2025

Deploy Preview for polite-sunflower-adff53 ready!

Name Link
🔨 Latest commit e524381
🔍 Latest deploy log https://app.netlify.com/projects/polite-sunflower-adff53/deploys/688c3a8573577a0008b86802
😎 Deploy Preview https://deploy-preview-30--polite-sunflower-adff53.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YumeYuka - 我已审阅了你的更改 - 以下是一些反馈:

  • sidebar.ts 文件包含大量重复的数组定义——考虑使用更小的数据结构或外部 JSON 来驱动它,以减少样板文件并简化未来的更新。
  • 存在可移除的注释掉的代码(例如 head.ts 中的 OG 元数据和 HomeFeaturesAfter 导入/插槽),以保持代码库的整洁。
  • 大量的自定义块 CSS 可以通过共享变量或 SCSS 混合来整合,以减少重复并提高可维护性。
Prompt for AI Agents
请解决此代码审查中的评论:
## Overall Comments
- sidebar.ts 文件包含大量重复的数组定义——考虑使用更小的数据结构或外部 JSON 来驱动它,以减少样板文件并简化未来的更新。
- 存在可移除的注释掉的代码(例如 head.ts 中的 OG 元数据和 HomeFeaturesAfter 导入/插槽),以保持代码库的整洁。
- 大量的自定义块 CSS 可以通过共享变量或 SCSS 混合来整合,以减少重复并提高可维护性。

## Individual Comments

### Comment 1
<location> `.vitepress/theme/components/ArticleShare.vue:46` </location>
<code_context>
+  if (copied.value || !isClient) return
+
+  try {
+    if (navigator.clipboard) {
+      await navigator.clipboard.writeText(shareLink.value)
+    } else {
</code_context>

<issue_to_address>
剪贴板 API 可能并非在所有浏览器或上下文中都可用。

考虑在剪贴板访问失败时通知用户,而不是只将错误记录到控制台。
</issue_to_address>

### Comment 2
<location> `.vitepress/theme/components/ArticleShare.vue:59` </location>
<code_context>
+    }
+
+    copied.value = true
+    setTimeout(() => {
+      copied.value = false
+    }, props.copiedTimeout)
</code_context>

<issue_to_address>
如果在超时前卸载组件,可能会导致内存泄漏。

在 onUnmounted 钩子中清除超时,以防止在已卸载的组件上进行状态更新。
</issue_to_address>

### Comment 3
<location> `.vitepress/config/sidebar.ts:3` </location>
<code_context>
+import { defineConfig, type DefaultTheme } from "vitepress";
+
+export const sidebar: DefaultTheme.Config['sidebar'] = [
+    {
+        text: "简介",
</code_context>

<issue_to_address>
考虑将所有侧边栏数据集中到一个结构化数组中,并使用递归构建器函数生成侧边栏配置。

```ts
// sidebarData.ts
export type MenuItem = {
  text: string
  link?: string
  children?: MenuItem[]
  collapsed?: boolean
}

export const sidebarData: MenuItem[] = [
  {
    text: "简介",
    children: [
      { text: "什么是 AstrBot", link: "/what-is-astrbot" },
      { text: "社区",        link: "/community"       },
      { text: "常见问题",    link: "/faq"             },
    ],
  },
  {
    text: "部署",
    collapsed: false,
    children: [
      {
        text: "部署 AstrBot",
        collapsed: true,
        children: [
          { text: "🦈 Docker 部署",    link: "/deploy/astrbot/docker" },
          { text: "☁️ 雨云一键云部署", link: "/deploy/astrbot/rainyun" },
          //
        ],
      },
      {
        text: "部署消息平台(协议端)",
        collapsed: true,
        children: [
          {
            text: "QQ 官方接口",
            collapsed: true,
            children: [
              { text: "Webhook 方式",   link: "/deploy/platform/qqofficial/webhook" },
              { text: "Websockets 方式", link: "/deploy/platform/qqofficial/websockets" },
            ],
          },
          //
        ],
      },
      { text: "部署好后…", link: "/deploy/when-deployed" },
    ],
  },
  // … 同理填充 config, use, dev_star
]
```

```ts
// .vitepress/config.ts
import { defineConfig, type DefaultTheme } from "vitepress"
import { sidebarData, type MenuItem } from "./sidebarData"

function buildSidebar(
  items: MenuItem[],
  base = ""
): DefaultTheme.SidebarItem[] {
  return items.map(({ text, link, children, collapsed }) => {
    const item: DefaultTheme.SidebarItem = { text, collapsed }
    if (link) {
      item.link = link.startsWith("/") ? link : `${base}/${link}`
    }
    if (children) {
      item.items = buildSidebar(children, item.link ?? base)
    }
    return item
  })
}

export default defineConfig({
  themeConfig: {
    sidebar: buildSidebar(sidebarData),
  },
})
```

应用步骤:

1. 将所有硬编码数组按所示移动到 `sidebarData.ts` 中。
2.`deploy()``config()``use()``dev_star()` 替换为单个 `buildSidebar` 递归构建器。
3. 在 VitePress 配置中导入 `sidebarData` 并调用 `buildSidebar(sidebarData)`。

这减少了样板文件,降低了嵌套,并将侧边栏结构集中到一个简单的数据文件中。
</issue_to_address>

Sourcery 对开源免费 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请在每条评论上点击 👍 或 👎,我将使用您的反馈来改进您的评论。
Original comment in English

Hey @YumeYuka - I've reviewed your changes - here's some feedback:

  • The sidebar.ts file contains a lot of repetitive array definitions—consider driving it from a smaller data structure or external JSON to reduce boilerplate and simplify future updates.
  • There’s commented-out code (e.g. OG metadata in head.ts and the HomeFeaturesAfter import/slot) that can be removed to keep the codebase clean.
  • The extensive custom-block CSS could be consolidated using shared variables or SCSS mixins to reduce duplication and improve maintainability.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The sidebar.ts file contains a lot of repetitive array definitions—consider driving it from a smaller data structure or external JSON to reduce boilerplate and simplify future updates.
- There’s commented-out code (e.g. OG metadata in head.ts and the HomeFeaturesAfter import/slot) that can be removed to keep the codebase clean.
- The extensive custom-block CSS could be consolidated using shared variables or SCSS mixins to reduce duplication and improve maintainability.

## Individual Comments

### Comment 1
<location> `.vitepress/theme/components/ArticleShare.vue:46` </location>
<code_context>
+  if (copied.value || !isClient) return
+
+  try {
+    if (navigator.clipboard) {
+      await navigator.clipboard.writeText(shareLink.value)
+    } else {
</code_context>

<issue_to_address>
Clipboard API may not be available in all browsers or contexts.

Consider notifying users if clipboard access fails, rather than only logging errors to the console.
</issue_to_address>

### Comment 2
<location> `.vitepress/theme/components/ArticleShare.vue:59` </location>
<code_context>
+    }
+
+    copied.value = true
+    setTimeout(() => {
+      copied.value = false
+    }, props.copiedTimeout)
</code_context>

<issue_to_address>
Potential memory leak if component is unmounted before timeout.

Clear the timeout in an onUnmounted hook to prevent state updates on an unmounted component.
</issue_to_address>

### Comment 3
<location> `.vitepress/config/sidebar.ts:3` </location>
<code_context>
+import { defineConfig, type DefaultTheme } from "vitepress";
+
+export const sidebar: DefaultTheme.Config['sidebar'] = [
+    {
+        text: "简介",
</code_context>

<issue_to_address>
Consider centralizing all sidebar data in a single structured array and using a recursive builder function to generate the sidebar configuration.

```ts
// sidebarData.ts
export type MenuItem = {
  text: string
  link?: string
  children?: MenuItem[]
  collapsed?: boolean
}

export const sidebarData: MenuItem[] = [
  {
    text: "简介",
    children: [
      { text: "什么是 AstrBot", link: "/what-is-astrbot" },
      { text: "社区",        link: "/community"       },
      { text: "常见问题",    link: "/faq"             },
    ],
  },
  {
    text: "部署",
    collapsed: false,
    children: [
      {
        text: "部署 AstrBot",
        collapsed: true,
        children: [
          { text: "🦈 Docker 部署",    link: "/deploy/astrbot/docker" },
          { text: "☁️ 雨云一键云部署", link: "/deploy/astrbot/rainyun" },
          //
        ],
      },
      {
        text: "部署消息平台(协议端)",
        collapsed: true,
        children: [
          {
            text: "QQ 官方接口",
            collapsed: true,
            children: [
              { text: "Webhook 方式",   link: "/deploy/platform/qqofficial/webhook" },
              { text: "Websockets 方式", link: "/deploy/platform/qqofficial/websockets" },
            ],
          },
          //
        ],
      },
      { text: "部署好后…", link: "/deploy/when-deployed" },
    ],
  },
  // … 同理填充 config, use, dev_star
]
```

```ts
// .vitepress/config.ts
import { defineConfig, type DefaultTheme } from "vitepress"
import { sidebarData, type MenuItem } from "./sidebarData"

function buildSidebar(
  items: MenuItem[],
  base = ""
): DefaultTheme.SidebarItem[] {
  return items.map(({ text, link, children, collapsed }) => {
    const item: DefaultTheme.SidebarItem = { text, collapsed }
    if (link) {
      item.link = link.startsWith("/") ? link : `${base}/${link}`
    }
    if (children) {
      item.items = buildSidebar(children, item.link ?? base)
    }
    return item
  })
}

export default defineConfig({
  themeConfig: {
    sidebar: buildSidebar(sidebarData),
  },
})
```

Steps to apply:

1. Move all hard-coded arrays into `sidebarData.ts` as shown.
2. Replace `deploy()`, `config()`, `use()`, `dev_star()` with a single `buildSidebar` recursive builder.
3. Import `sidebarData` in your VitePress config and call `buildSidebar(sidebarData)`. 

This collapses boilerplate, reduces nesting, and centralizes the sidebar structure in a simple data file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

if (copied.value || !isClient) return

try {
if (navigator.clipboard) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 剪贴板 API 可能并非在所有浏览器或上下文中都可用。

考虑在剪贴板访问失败时通知用户,而不是只将错误记录到控制台。

Original comment in English

suggestion: Clipboard API may not be available in all browsers or contexts.

Consider notifying users if clipboard access fails, rather than only logging errors to the console.

}

copied.value = true
setTimeout(() => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 如果在超时前卸载组件,可能会导致内存泄漏。

在 onUnmounted 钩子中清除超时,以防止在已卸载的组件上进行状态更新。

Original comment in English

issue (bug_risk): Potential memory leak if component is unmounted before timeout.

Clear the timeout in an onUnmounted hook to prevent state updates on an unmounted component.

@@ -0,0 +1,268 @@
import { defineConfig, type DefaultTheme } from "vitepress";

export const sidebar: DefaultTheme.Config['sidebar'] = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): 考虑将所有侧边栏数据集中到一个结构化数组中,并使用递归构建器函数生成侧边栏配置。

// sidebarData.ts
export type MenuItem = {
  text: string
  link?: string
  children?: MenuItem[]
  collapsed?: boolean
}

export const sidebarData: MenuItem[] = [
  {
    text: "简介",
    children: [
      { text: "什么是 AstrBot", link: "/what-is-astrbot" },
      { text: "社区",        link: "/community"       },
      { text: "常见问题",    link: "/faq"             },
    ],
  },
  {
    text: "部署",
    collapsed: false,
    children: [
      {
        text: "部署 AstrBot",
        collapsed: true,
        children: [
          { text: "🦈 Docker 部署",    link: "/deploy/astrbot/docker" },
          { text: "☁️ 雨云一键云部署", link: "/deploy/astrbot/rainyun" },
          // …
        ],
      },
      {
        text: "部署消息平台(协议端)",
        collapsed: true,
        children: [
          {
            text: "QQ 官方接口",
            collapsed: true,
            children: [
              { text: "Webhook 方式",   link: "/deploy/platform/qqofficial/webhook" },
              { text: "Websockets 方式", link: "/deploy/platform/qqofficial/websockets" },
            ],
          },
          // …
        ],
      },
      { text: "部署好后…", link: "/deploy/when-deployed" },
    ],
  },
  // … 同理填充 config, use, dev_star
]
// .vitepress/config.ts
import { defineConfig, type DefaultTheme } from "vitepress"
import { sidebarData, type MenuItem } from "./sidebarData"

function buildSidebar(
  items: MenuItem[],
  base = ""
): DefaultTheme.SidebarItem[] {
  return items.map(({ text, link, children, collapsed }) => {
    const item: DefaultTheme.SidebarItem = { text, collapsed }
    if (link) {
      item.link = link.startsWith("/") ? link : `${base}/${link}`
    }
    if (children) {
      item.items = buildSidebar(children, item.link ?? base)
    }
    return item
  })
}

export default defineConfig({
  themeConfig: {
    sidebar: buildSidebar(sidebarData),
  },
})

应用步骤:

  1. 将所有硬编码数组按所示移动到 sidebarData.ts 中。
  2. deploy()config()use()dev_star() 替换为单个 buildSidebar 递归构建器。
  3. 在 VitePress 配置中导入 sidebarData 并调用 buildSidebar(sidebarData)

这减少了样板文件,降低了嵌套,并将侧边栏结构集中到一个简单的数据文件中。

Original comment in English

issue (complexity): Consider centralizing all sidebar data in a single structured array and using a recursive builder function to generate the sidebar configuration.

// sidebarData.ts
export type MenuItem = {
  text: string
  link?: string
  children?: MenuItem[]
  collapsed?: boolean
}

export const sidebarData: MenuItem[] = [
  {
    text: "简介",
    children: [
      { text: "什么是 AstrBot", link: "/what-is-astrbot" },
      { text: "社区",        link: "/community"       },
      { text: "常见问题",    link: "/faq"             },
    ],
  },
  {
    text: "部署",
    collapsed: false,
    children: [
      {
        text: "部署 AstrBot",
        collapsed: true,
        children: [
          { text: "🦈 Docker 部署",    link: "/deploy/astrbot/docker" },
          { text: "☁️ 雨云一键云部署", link: "/deploy/astrbot/rainyun" },
          // …
        ],
      },
      {
        text: "部署消息平台(协议端)",
        collapsed: true,
        children: [
          {
            text: "QQ 官方接口",
            collapsed: true,
            children: [
              { text: "Webhook 方式",   link: "/deploy/platform/qqofficial/webhook" },
              { text: "Websockets 方式", link: "/deploy/platform/qqofficial/websockets" },
            ],
          },
          // …
        ],
      },
      { text: "部署好后…", link: "/deploy/when-deployed" },
    ],
  },
  // … 同理填充 config, use, dev_star
]
// .vitepress/config.ts
import { defineConfig, type DefaultTheme } from "vitepress"
import { sidebarData, type MenuItem } from "./sidebarData"

function buildSidebar(
  items: MenuItem[],
  base = ""
): DefaultTheme.SidebarItem[] {
  return items.map(({ text, link, children, collapsed }) => {
    const item: DefaultTheme.SidebarItem = { text, collapsed }
    if (link) {
      item.link = link.startsWith("/") ? link : `${base}/${link}`
    }
    if (children) {
      item.items = buildSidebar(children, item.link ?? base)
    }
    return item
  })
}

export default defineConfig({
  themeConfig: {
    sidebar: buildSidebar(sidebarData),
  },
})

Steps to apply:

  1. Move all hard-coded arrays into sidebarData.ts as shown.
  2. Replace deploy(), config(), use(), dev_star() with a single buildSidebar recursive builder.
  3. Import sidebarData in your VitePress config and call buildSidebar(sidebarData).

This collapses boilerplate, reduces nesting, and centralizes the sidebar structure in a simple data file.

@Soulter
Copy link
Copy Markdown
Member

Soulter commented Aug 1, 2025

WOW 感谢,好看了很多!!

@Soulter Soulter merged commit 4fadc67 into AstrBotDevs:v2 Aug 1, 2025
4 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants