Skip to content

Conversation

@zhangligei
Copy link
Collaborator

@zhangligei zhangligei commented Nov 16, 2025

变更内容

  • 新功能
  • 修复 Bug
  • 增强重构
  • 其他(请描述)

简要描述本次 PR 的主要变更内容。

相关 Issue

请关联相关 Issue(如有):#编号

检查清单

默认已勾选,如不满足,请检查。

  • 已在本地测试通过
  • 已补充/更新相关文档
  • 代码风格已经过 pre-commit 钩子检查
  • 非企业版分支
  • 遵循 贡献者文档 中的最佳实践

其他说明

如有特殊说明或注意事项,请补充。

Sourcery 摘要

在聊天登录页和导航栏中引入动态主题,将教程菜单替换为外部文档链接,并刷新亮色主题的产品图片

新功能:

  • 引入 useTheme hook 以检测和管理暗/亮模式
  • 将主题感知样式应用于聊天登录页、英雄视差和头部组件
  • 将导航栏中的应用内教程组件替换为直接的外部文档链接
  • 更新产品缩略图 URL 为亮色模式变体
Original summary in English

Summary by Sourcery

Introduce dynamic theming across the chat landing page and navbar, swap the tutorial menu for an external docs link, and refresh product images for light theme

New Features:

  • Introduce a useTheme hook to detect and manage dark/light mode
  • Apply theme-aware styling to the chat landing page, hero parallax, and header components
  • Replace the in-app tutorial component in the navbar with a direct external documentation link
  • Update product thumbnail URLs to light-mode variants

- ♻️ refactor:Create /chat route with HeroParallax component for product showcase
- Add products.ts with Xyzen product data
- Implement chat page layout with animated parallax effect
- Add CTA button linking to Bohrium Xyzen application
- Update Navbar to include Projects menu with 5 ScienceOL products
- Add dark mode styling for better visual appearance
- Integrate React Router with new /chat route in router.tsx
- Create /chat route with HeroParallax component and product carousel
- Add Projects menu to navbar with 5 ScienceOL products (Studio, Xyzen, PROTIUM, Anti, Lab-OS)
- Implement responsive chat page with animated parallax and CTA button
- Add Tutorial menu item linking to documentation
- Create custom useTheme hook integrated with existing UiCore system
- Support dynamic theme switching (system/dark/light modes)
- Merge main branch and resolve conflicts
@sourcery-ai
Copy link

sourcery-ai bot commented Nov 16, 2025

审阅者指南

此 PR 在聊天登录页面中实现了动态主题,将应用内教程组件替换为导航栏中的外部文档链接,更新了亮模式下的产品缩略图,扩展了 HeroParallax 以支持主题,并引入了一个新的 useTheme 钩子用于检测暗/亮模式。

products.ts 中更新产品缩略图的实体关系图

erDiagram
  PRODUCT {
    string title
    string link
    string thumbnail
  }
Loading

新的 useTheme 钩子及其集成的类图

classDiagram
  class useTheme {
    +isDark: boolean
    +useTheme(): boolean
  }
  class useUI {
    +theme: string
  }
  useTheme --> useUI: uses

  class HeroParallax {
    +products: Product[]
    +isDark: boolean
    +HeroParallax(props)
  }
  HeroParallax --> useTheme: uses

  class Header {
    +isDark: boolean
    +Header(isDark)
  }
  Header <-- HeroParallax: passes isDark

  class ChatPage {
    +isDark: boolean
    +ChatPage()
  }
  ChatPage --> useTheme: uses
Loading

更新 NavbarMenu 和 Tutorials 集成的类图

classDiagram
  class NavbarMenu {
    +NavbarMenu()
    -TutorialComponent (removed)
    +External tutorial link
  }
  class Tutorial {
    +Tutorial()
    +uses useTranslation
    +renders external docs link
  }
  NavbarMenu --> Tutorial: renders link
Loading

文件级更改

更改 详情 文件
将应用内教程组件替换为外部文档链接并统一了样式
  • 在 Navbar 中注释掉了 Tutorial 导入和别名
  • 添加了链接到文档的锚标签,包含翻译和新类
  • 更新了 Tutorials.tsx 以使用翻译钩子和新样式
web/src/app/navbar/Navbar.tsx
web/src/app/navbar/Tutorials.tsx
在聊天页面启用了动态背景和文本颜色
  • 导入了 useTheme 并获取了 isDark
  • 使用条件性的 bg-white/bg-black 类包裹了容器 div
  • 对标题和段落应用了条件性的文本颜色类
web/src/app/chat/page.tsx
将产品缩略图替换为亮模式变体
  • 将每个缩略图 URL 从 .png 替换为 _light.png
web/src/app/chat/products.ts
扩展 HeroParallax 和 Header 组件以支持主题
  • 导入了 useTheme 并将 isDark 传递给 HeroParallax
  • 条件性的包装器背景并更新 Header 以接受 isDark 属性
  • 在 Header 中应用了条件性的文本颜色类
web/src/components/ui/hero-parallax.tsx
引入 useTheme 钩子用于暗/亮模式检测
  • 创建了 useTheme 从 useUI 获取主题
  • 设置了效果以跟踪系统 prefers-color-scheme 更改
web/src/hooks/useTheme.ts

提示和命令

与 Sourcery 互动

  • 触发新审查: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 通过回复审查评论,要求 Sourcery 从中创建 issue。您也可以回复审查评论并添加 @sourcery-ai issue 来创建 issue。
  • 生成拉取请求标题: 随时在拉取请求标题的任意位置写入 @sourcery-ai 以生成标题。您也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 随时在拉取请求正文的任意位置写入 @sourcery-ai summary 以生成 PR 摘要,并将其放置在您希望的位置。您也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成审阅者指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果您已经处理了所有评论并且不想再看到它们,这会很有用。
  • 驳回所有 Sourcery 审查: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有 Sourcery 审查。如果您想重新开始新的审查,这尤其有用——别忘了评论 @sourcery-ai review 来触发新的审查!

自定义您的体验

访问您的 仪表板 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审阅者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

This PR implements dynamic theming across the chat landing page, replaces the in-app tutorial component with an external docs link in the navbar, updates product thumbnails for light mode, extends HeroParallax with theme support, and introduces a new useTheme hook for detecting dark/light mode.

Entity relationship diagram for updated product thumbnails in products.ts

erDiagram
  PRODUCT {
    string title
    string link
    string thumbnail
  }
Loading

Class diagram for the new useTheme hook and its integration

classDiagram
  class useTheme {
    +isDark: boolean
    +useTheme(): boolean
  }
  class useUI {
    +theme: string
  }
  useTheme --> useUI: uses

  class HeroParallax {
    +products: Product[]
    +isDark: boolean
    +HeroParallax(props)
  }
  HeroParallax --> useTheme: uses

  class Header {
    +isDark: boolean
    +Header(isDark)
  }
  Header <-- HeroParallax: passes isDark

  class ChatPage {
    +isDark: boolean
    +ChatPage()
  }
  ChatPage --> useTheme: uses
Loading

Class diagram for updated NavbarMenu and Tutorials integration

classDiagram
  class NavbarMenu {
    +NavbarMenu()
    -TutorialComponent (removed)
    +External tutorial link
  }
  class Tutorial {
    +Tutorial()
    +uses useTranslation
    +renders external docs link
  }
  NavbarMenu --> Tutorial: renders link
Loading

File-Level Changes

Change Details Files
Replaced in-app tutorial component with external docs link and unified styling
  • Commented out Tutorial import and alias in Navbar
  • Added anchor tag linking to docs with translation and new classes
  • Updated Tutorials.tsx to use translation hook and new styling
web/src/app/navbar/Navbar.tsx
web/src/app/navbar/Tutorials.tsx
Enabled dynamic background and text colors on chat page
  • Imported useTheme and retrieved isDark
  • Wrapped container div with conditional bg-white/bg-black classes
  • Applied conditional text color classes to headings and paragraphs
web/src/app/chat/page.tsx
Swapped product thumbnails to light-mode variants
  • Replaced each thumbnail URL from .png to _light.png
web/src/app/chat/products.ts
Extended HeroParallax and Header components with theme support
  • Imported useTheme and passed isDark into HeroParallax
  • Conditional wrapper background and updated Header to accept isDark prop
  • Applied conditional text color classes in Header
web/src/components/ui/hero-parallax.tsx
Introduced useTheme hook for dark/light mode detection
  • Created useTheme retrieving theme from useUI
  • Set up effect to track system prefers-color-scheme changes
web/src/hooks/useTheme.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@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.

你好 - 我已审阅了你的更改,它们看起来很棒!

AI 代理的提示
请处理此代码审查中的评论:

## 独立评论

### 评论 1
<location> `web/src/app/navbar/Navbar.tsx:40-45` </location>
<code_context>
         setOpen={setOpen}
       />
-      <TutorialComponent
+      <a
+        className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
+        href='https://docs.sciol.ac.cn'
+      >
+        <span>{t('navbar.tutorial')}</span>
+      </a>
+      {/* <Tutorial
         index={4}
</code_context>

<issue_to_address>
**🚨 suggestion (security):** 教程链接的新锚点不会在新标签页中打开。

请添加 target="_blank" 和 rel="noopener noreferrer" 到锚点,以恢复新标签页行为并维护安全性。

```suggestion
      <a
        className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
        href='https://docs.sciol.ac.cn'
        target="_blank"
        rel="noopener noreferrer"
      >
        <span>{t('navbar.tutorial')}</span>
      </a>
```
</issue_to_address>

### 评论 2
<location> `web/src/hooks/useTheme.ts:20-23` </location>
<code_context>
+
+    // 监听系统主题变化(当主题设置为 system 时)
+    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+    mediaQuery.addEventListener('change', updateIsDark);
+
+    return () => {
+      mediaQuery.removeEventListener('change', updateIsDark);
+    };
+  }, [theme]);
</code_context>

<issue_to_address>
**issue (bug_risk):** 直接在 MediaQueryList 上使用 addEventListener 可能不受所有浏览器的支持。

某些浏览器仅支持 MediaQueryList 的 'addListener' 和 'removeListener'。请添加兼容性检查或回退以确保可靠的主题更新。
</issue_to_address>

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

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `web/src/app/navbar/Navbar.tsx:40-45` </location>
<code_context>
         setOpen={setOpen}
       />
-      <TutorialComponent
+      <a
+        className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
+        href='https://docs.sciol.ac.cn'
+      >
+        <span>{t('navbar.tutorial')}</span>
+      </a>
+      {/* <Tutorial
         index={4}
</code_context>

<issue_to_address>
**🚨 suggestion (security):** The new anchor for the tutorial link does not open in a new tab.

Please add target="_blank" and rel="noopener noreferrer" to the anchor to restore new tab behavior and maintain security.

```suggestion
      <a
        className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
        href='https://docs.sciol.ac.cn'
        target="_blank"
        rel="noopener noreferrer"
      >
        <span>{t('navbar.tutorial')}</span>
      </a>
```
</issue_to_address>

### Comment 2
<location> `web/src/hooks/useTheme.ts:20-23` </location>
<code_context>
+
+    // 监听系统主题变化(当主题设置为 system 时)
+    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+    mediaQuery.addEventListener('change', updateIsDark);
+
+    return () => {
+      mediaQuery.removeEventListener('change', updateIsDark);
+    };
+  }, [theme]);
</code_context>

<issue_to_address>
**issue (bug_risk):** Directly using addEventListener on MediaQueryList may not be supported in all browsers.

Some browsers only support 'addListener' and 'removeListener' for MediaQueryList. Please add a compatibility check or fallback to ensure reliable theme updates.
</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.

Comment on lines +40 to +45
<a
className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
href='https://docs.sciol.ac.cn'
>
<span>{t('navbar.tutorial')}</span>
</a>
Copy link

Choose a reason for hiding this comment

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

🚨 suggestion (security): 教程链接的新锚点不会在新标签页中打开。

请添加 target="_blank" 和 rel="noopener noreferrer" 到锚点,以恢复新标签页行为并维护安全性。

Suggested change
<a
className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
href='https://docs.sciol.ac.cn'
>
<span>{t('navbar.tutorial')}</span>
</a>
<a
className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
href='https://docs.sciol.ac.cn'
target="_blank"
rel="noopener noreferrer"
>
<span>{t('navbar.tutorial')}</span>
</a>
Original comment in English

🚨 suggestion (security): The new anchor for the tutorial link does not open in a new tab.

Please add target="_blank" and rel="noopener noreferrer" to the anchor to restore new tab behavior and maintain security.

Suggested change
<a
className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
href='https://docs.sciol.ac.cn'
>
<span>{t('navbar.tutorial')}</span>
</a>
<a
className={`inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-neutral-900 focus:outline-none dark:text-neutral-100 ${'hover:text-indigo-600 dark:hover:text-indigo-500'}`}
href='https://docs.sciol.ac.cn'
target="_blank"
rel="noopener noreferrer"
>
<span>{t('navbar.tutorial')}</span>
</a>

@Mile-Away Mile-Away merged commit 9ee1071 into main Nov 16, 2025
1 check passed
@Mile-Away Mile-Away deleted the feat/xyzen-chat-landing-page branch November 16, 2025 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants