Skip to content

feat: 添加VNDB页面 - #542

Open
lizzzhh wants to merge 5 commits into
CuteLeaf:masterfrom
lizzzhh:feat/vndb
Open

feat: 添加VNDB页面#542
lizzzhh wants to merge 5 commits into
CuteLeaf:masterfrom
lizzzhh:feat/vndb

Conversation

@lizzzhh

@lizzzhh lizzzhh commented Aug 4, 2026

Copy link
Copy Markdown

Type of change

  • Bug fix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Other (please describe):

Checklist

  • I have read the CONTRIBUTING document.
  • I have checked to ensure that this Pull Request is not for personal changes.
  • I have performed a self-review of my own code.
  • My changes generate no new warnings.

Related Issue

#540

Changes

  • 新增 /vndb/ 页面,支持 static(构建时拉取 VNDB API 并静态渲染)和 dynamic(浏览器端实时拉取)两种模式。
  • 新增组件:Card.svelte、VndbGrid.svelte、VndbSection.svelte、TabNav.svelte、FilterControls.svelte;新增类型 src/types/vndb.ts 和工具 src/utils/vndb-utils.ts。
  • 新增封面下载脚本 scripts/generate-vndb-covers.ts,构建时下载并压缩封面到 public/vndb-covers/(已加入 .gitignore),并接入 pnpm build。
  • siteConfig 新增 pages.vndb 开关和 vndb 配置块(userId、mode、downloadCovers、apiUrl、vnBaseUrl、apiToken),导航栏新增 VNDB 链接。
  • 新增 siteConfig.vndb.blurNsfw(默认 true),并通过 vndb.astro → VndbGrid → VndbSection → Card 传递;开启时 NSFW 封面应用 blur(20px) 模糊滤镜。
  • 补齐 6 种语言的 i18n 文案(en/ja/ko/ru/zh_CN/zh_TW)。

How To Test

  1. 在 siteConfig.ts 中填入自己的 vndb.userId(例如 u2),否则页面只会显示未配置提示。
  2. 运行 pnpm check 和 pnpm type-check 确认类型与 Astro 诊断通过。
  3. 运行 pnpm dev,打开 http://localhost:4321/vndb/,验证:列表、状态 Tab(想玩/在玩/已玩等)、筛选(全部/已评分/未评分/有笔记)和分页正常。
  4. 卡片展示封面、评分、时长、标签、笔记和 VNDB 外链。
  5. 导航栏出现 VNDB 入口。
  6. 在 siteConfig.ts 里把 blurNsfw 分别设为 true/false,刷新页面确认 NSFW 封面是否模糊。
  7. 运行 pnpm build,确认封面下载脚本执行、public/vndb-covers/ 生成且静态页面正常构建。

Screenshots (if applicable)

image

Additional Notes

Summary by Sourcery

添加一个带有静态和动态模式的 VNDB 视觉小说列表页面,包括本地封面处理和导航集成。

New Features:

  • 引入一个可配置的 /vndb/ 页面,以静态或动态模式显示用户的 VNDB 视觉小说列表,并支持状态标签页、过滤器和分页。
  • 添加针对 VNDB 的 Svelte 组件、类型和工具函数,用于渲染视觉小说卡片、章节和标签导航,并支持对 NSFW 封面进行模糊处理。
  • 提供一个构建时脚本,用于获取 VNDB 用户数据并下载/压缩封面到本地目录,将其接入构建流程,并在 LQIP 生成中排除其输出目录。

Enhancements:

  • 扩展站点和导航配置以启用 VNDB 页面,包括与 VNDB 相关的设置,例如用户 ID、API 端点、模式选择和 NSFW 模糊选项。
  • 更新已支持语言中的 i18n 键值和翻译,以覆盖 VNDB 标签、状态、过滤器、错误信息以及篇幅长度描述。

Build:

  • 将 VNDB 封面生成脚本挂接到构建流水线中,并在 LQIP 生成和版本控制中忽略其输出目录。
Original summary in English

Summary by Sourcery

Add a VNDB visual novel list page with static and dynamic modes, including local cover handling and navigation integration.

New Features:

  • Introduce a configurable /vndb/ page that displays a user’s VNDB visual novel list with status tabs, filters, and pagination in static or dynamic mode.
  • Add VNDB-specific Svelte components, types, and utilities to render visual novel cards, sections, and tab navigation with NSFW cover blurring support.
  • Provide a build-time script to fetch VNDB user data and download/compress covers into a local directory, wiring it into the build process and excluding outputs from LQIP generation.

Enhancements:

  • Extend site and navigation configuration to enable the VNDB page, including VNDB-related settings such as user ID, API endpoints, mode selection, and NSFW blur options.
  • Update i18n keys and translations across supported languages to cover VNDB labels, statuses, filters, error messages, and length descriptors.

Build:

  • Hook a VNDB cover-generation script into the build pipeline and ignore its output directory in LQIP generation and version control.

@netlify

netlify Bot commented Aug 4, 2026

Copy link
Copy Markdown

Deploy Preview for demo-firefly ready!

Name Link
🔨 Latest commit dc3bcbb
🔍 Latest deploy log https://app.netlify.com/projects/demo-firefly/deploys/6a719b065d4537000854361f
😎 Deploy Preview https://deploy-preview-542--demo-firefly.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.

@sourcery-ai

sourcery-ai Bot commented Aug 4, 2026

Copy link
Copy Markdown

审阅者指南

实现了一个新的 VNDB 视觉小说列表页面,支持静态(构建时)和动态(客户端)两种数据模式,包括 VNDB 专用配置、API 集成、构建时本地封面下载/压缩、用于标签/筛选/卡片的 Svelte UI 组件,以及完整的 i18n 国际化支持。

VNDB 页面静态 vs 动态数据流时序图

sequenceDiagram
    actor User
    participant VndbPage as vndb.astro
    participant VndbGrid as VndbGrid
    participant VndbUtils as fetchVndbUlist

    User->>VndbPage: HTTP GET /vndb/
    VndbPage->>VndbPage: read siteConfig.vndb
    alt static mode
        VndbPage->>VndbUtils: fetchVndbUlist(apiUrl, userId, apiToken, results, page)
        VndbUtils-->>VndbPage: VndbUlistResponse
        VndbPage->>VndbPage: buildVndbTabs(allItems)
        VndbPage->>VndbGrid: VndbGrid(tabs, vndbData, vnBaseUrl, blurNsfw)
        Note right of VndbGrid: client:load
        VndbGrid->>VndbGrid: getVndbItemsForTab(all, activeTab)
    else dynamic mode
        VndbPage->>VndbGrid: VndbGrid(fetchConfig)
        Note right of VndbGrid: client:load
        VndbGrid->>VndbGrid: onMount
        VndbGrid->>VndbUtils: fetchVndbUlist(apiUrl, userId, apiToken, results, page)
        VndbUtils-->>VndbGrid: VndbUlistResponse
        VndbGrid->>VndbGrid: buildVndbTabs(allItems)
        VndbGrid->>VndbGrid: getVndbItemsForTab(all, activeTab)
    end
    VndbGrid-->>User: Render VN cards with Card
Loading

文件级改动

Change Details Files
新增支持静态/动态数据加载和 VN 列表渲染的 VNDB 页面。
  • 新增 vndb.astro 页面,用于检查 siteConfig.pages.vndb、读取 siteConfig.vndb,并接好静态 vs 动态两种模式。
  • 在静态模式下,在构建时以分页循环方式调用 fetchVndbUlist,可选地在本地存在封面时将图片 URL 重写为本地 /vndb-covers/*.webp。
  • 在动态模式下,渲染一个空壳页面,将获取配置传递给客户端加载的 VndbGrid Svelte 组件。
  • 针对缺失 userId、空列表和获取失败情况,提供专门的错误/空状态以及本地化提示信息。
src/pages/vndb.astro
将 VNDB 网格、分区、卡片和控制组件实现为 Svelte 组件。
  • 新增 VndbGrid.svelte,用于编排标签页、动态获取(当提供 fetchConfig 时),以及使用 fetchVndbUlist/buildVndbTabs/getVndbItemsForTab 处理错误/加载状态。
  • 新增 VndbSection.svelte,用于处理每个标签页的筛选(all/voted/unvoted/notes)、客户端分页,以及使用 ClientPagination 渲染卡片网格布局。
  • 新增 Card.svelte,用于渲染单个 VN 条目卡片,包括封面、NSFW 模糊、状态、用户评分、VNDB 评分、元数据、标签,以及通过 localStorage 记录本地封面加载失败。
  • 新增 TabNav.svelte 和 FilterControls.svelte,用于与 URL hash 同步的标签页导航,以及带计数的筛选胶囊 UI。
src/components/pages/vndb/VndbGrid.svelte
src/components/pages/vndb/VndbSection.svelte
src/components/pages/vndb/Card.svelte
src/components/pages/vndb/TabNav.svelte
src/components/pages/vndb/FilterControls.svelte
新增 VNDB API 工具方法和类型,用于类型安全的获取和标签页构建。
  • 在专门的 vndb.ts 类型文件中定义 VNDB UL 列表类型(entries、VN、images、tags、producers)。
  • 实现 fetchVndbUlist,对 /ulist 执行 POST 请求,包含必要字段、可选的 token 认证,并在结果上进行后处理(标签规范化、开发者/标签扁平化和截断)。
  • 新增用于标签规范化、通过 i18n 解析状态文本、构建标签页及按标签页过滤的辅助函数,以及基于 i18n key 的 VN 时长/游玩时间格式化工具。
src/types/vndb.ts
src/utils/vndb-utils.ts
引入构建时 VNDB 封面下载与压缩流水线,并接入构建流程。
  • 新增 generate-vndb-covers.ts 脚本,用于获取所有 VNDB ulist 条目,在并发与节流控制下下载缺失封面,将其通过 sharp 转换为调整尺寸后的 WEBP,并存储到 public/vndb-covers。
  • 在 package.json 中,将新脚本集成到构建流水线,在 astro build 之前执行。
  • 更新 LQIP 生成忽略列表和 gitignore,将 public/vndb-covers 输出目录排除在外。
scripts/generate-vndb-covers.ts
package.json
scripts/generate-lqips.ts
.gitignore
扩展站点配置和导航,以支持 VNDB 页面及相关行为开关。
  • 在 siteConfig 和 SiteConfig 类型中新增 pages.vndb 布尔标志和 vndb 配置块(userId、mode、downloadCovers、apiUrl、vnBaseUrl、apiToken、blurNsfw)。
  • 使用 blurNsfw 标志,通过从 vndb.astro → VndbGrid → VndbSection → Card 逐级传递的 props,控制 NSFW 封面模糊效果。
  • 在 navBarConfig 中新增 VNDB 导航预设,并在启用 pages.vndb 时将其包含到动态导航栏中。
src/config/siteConfig.ts
src/types/siteConfig.ts
src/config/navBarConfig.ts
为 VNDB 相关内容在所有支持语言中新增 i18n key 与翻译。
  • 扩展 I18nKey 枚举,新增 VNDB 专用 key,用于标签、筛选、错误/空状态、评分、时长变体和时间戳等。
  • 在 en、ja、ko、ru、zh_CN 和 zh_TW 语言包中提供相应翻译,保持与现有风格和术语一致。
src/i18n/i18nKey.ts
src/i18n/languages/en.ts
src/i18n/languages/ja.ts
src/i18n/languages/ko.ts
src/i18n/languages/ru.ts
src/i18n/languages/zh_CN.ts
src/i18n/languages/zh_TW.ts

可能关联的 Issue


提示与命令

与 Sourcery 交互

  • 触发新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 在审查评论下回复,请求 Sourcery 从该评论生成 issue。你也可以在审查评论中回复 @sourcery-ai issue 来创建对应的 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary 来在任意时间(重新)生成摘要。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可标记所有 Sourcery 评论为已解决。如果你已经处理了所有评论且不再希望看到它们,这会非常有用。
  • 撤销所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可撤销所有现有的 Sourcery 审查。特别适用于你想从头开始新的审查——别忘了再评论 @sourcery-ai review 来触发新的审查!

自定义你的体验

访问你的 dashboard 以:

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

获取帮助

Original review guide in English

Reviewer's Guide

Implements a new VNDB visual novel list page with both static (build-time) and dynamic (client-side) data modes, including VNDB-specific config, API integration, local cover download/compression at build, Svelte UI components for tabs/filters/cards, and full i18n support.

Sequence diagram for VNDB page static vs dynamic data flow

sequenceDiagram
    actor User
    participant VndbPage as vndb.astro
    participant VndbGrid as VndbGrid
    participant VndbUtils as fetchVndbUlist

    User->>VndbPage: HTTP GET /vndb/
    VndbPage->>VndbPage: read siteConfig.vndb
    alt static mode
        VndbPage->>VndbUtils: fetchVndbUlist(apiUrl, userId, apiToken, results, page)
        VndbUtils-->>VndbPage: VndbUlistResponse
        VndbPage->>VndbPage: buildVndbTabs(allItems)
        VndbPage->>VndbGrid: VndbGrid(tabs, vndbData, vnBaseUrl, blurNsfw)
        Note right of VndbGrid: client:load
        VndbGrid->>VndbGrid: getVndbItemsForTab(all, activeTab)
    else dynamic mode
        VndbPage->>VndbGrid: VndbGrid(fetchConfig)
        Note right of VndbGrid: client:load
        VndbGrid->>VndbGrid: onMount
        VndbGrid->>VndbUtils: fetchVndbUlist(apiUrl, userId, apiToken, results, page)
        VndbUtils-->>VndbGrid: VndbUlistResponse
        VndbGrid->>VndbGrid: buildVndbTabs(allItems)
        VndbGrid->>VndbGrid: getVndbItemsForTab(all, activeTab)
    end
    VndbGrid-->>User: Render VN cards with Card
Loading

File-Level Changes

Change Details Files
Add VNDB page with static/dynamic data loading and VN list rendering.
  • Introduce vndb.astro page that checks siteConfig.pages.vndb, reads siteConfig.vndb, and wires static vs dynamic modes.
  • In static mode, call fetchVndbUlist in a paginated loop at build time, optionally rewriting image URLs to local /vndb-covers/*.webp when present.
  • In dynamic mode, render an empty shell that passes fetch configuration to a client-loaded VndbGrid Svelte component.
  • Handle missing userId, empty list, and fetch failures with dedicated error/empty states and localized messaging.
src/pages/vndb.astro
Implement VNDB grid, sections, cards, and controls as Svelte components.
  • Add VndbGrid.svelte to orchestrate tabs, dynamic fetching (when given fetchConfig), and error/loading states using fetchVndbUlist/buildVndbTabs/getVndbItemsForTab.
  • Add VndbSection.svelte to handle per-tab filtering (all/voted/unvoted/notes), client-side pagination, and grid layout of cards using ClientPagination.
  • Add Card.svelte to render a VN entry card with cover, NSFW blur, status, user vote, VNDB rating, metadata, tags, and local failed-cover tracking via localStorage.
  • Add TabNav.svelte and FilterControls.svelte for tab navigation synced to URL hash and filter pill UI with counts.
src/components/pages/vndb/VndbGrid.svelte
src/components/pages/vndb/VndbSection.svelte
src/components/pages/vndb/Card.svelte
src/components/pages/vndb/TabNav.svelte
src/components/pages/vndb/FilterControls.svelte
Add VNDB API utilities and types for typed fetching and tab building.
  • Define VNDB UL list types (entries, VN, images, tags, producers) in a dedicated vndb.ts type file.
  • Implement fetchVndbUlist to POST to /ulist with required fields, optional token auth, and post-process results (label normalization, developer/tag flattening and truncation).
  • Add helpers for label normalization, status text resolution via i18n, tab construction and per-tab filtering, and VN length/playtime formatting with i18n keys.
src/types/vndb.ts
src/utils/vndb-utils.ts
Introduce a build-time VNDB cover download and compression pipeline and integrate into build.
  • Add generate-vndb-covers.ts script that fetches all VNDB ulist entries, downloads missing covers with concurrency and throttling, converts them to resized WEBP via sharp, and stores them in public/vndb-covers.
  • Integrate the new script into the build pipeline before astro build in package.json.
  • Update LQIP generation ignore list and gitignore to exclude public/vndb-covers output.
scripts/generate-vndb-covers.ts
package.json
scripts/generate-lqips.ts
.gitignore
Extend site configuration and navigation to support VNDB page and behavior toggles.
  • Add pages.vndb boolean flag and vndb configuration block (userId, mode, downloadCovers, apiUrl, vnBaseUrl, apiToken, blurNsfw) to siteConfig and SiteConfig type.
  • Use blurNsfw flag to drive NSFW cover blurring via props passed vndb.astro → VndbGrid → VndbSection → Card.
  • Add VNDB nav preset to navBarConfig and include it in the dynamic navbar when pages.vndb is enabled.
src/config/siteConfig.ts
src/types/siteConfig.ts
src/config/navBarConfig.ts
Add VNDB-related i18n keys and translations in all supported languages.
  • Extend I18nKey enum with VNDB-specific keys for labels, filters, error/empty states, votes, length variants, and timestamps.
  • Provide corresponding translations for en, ja, ko, ru, zh_CN, and zh_TW language bundles, matching existing style and terminology.
src/i18n/i18nKey.ts
src/i18n/languages/en.ts
src/i18n/languages/ja.ts
src/i18n/languages/ko.ts
src/i18n/languages/ru.ts
src/i18n/languages/zh_CN.ts
src/i18n/languages/zh_TW.ts

Possibly linked issues


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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - 我发现了两个问题,并给出了一些整体性的反馈:

  • TabNav.svelte 在一个 $effect 中注册了 hashchange 监听器并访问 window,但没有任何运行时保护,这在 SSR 时可能会抛错;建议用 typeof window !== 'undefined' 来包裹这些引用,或者把它们移动到 onMount 中。
  • line-clamp 样式在 Card.svelte 和 vndb.astro 中被重复定义;建议将这部分样式集中管理(例如通过共享的 CSS 工具类,或使用现有的 Tailwind line-clamp 工具类),以避免不同实现之间出现偏差。
  • vndb.astro 同时使用了硬编码的中文字符串(例如「未配置 VNDB 用户ID」)和基于 i18n 的消息;建议为这些文本添加对应的 i18n key,这样 VNDB 页面文案在不同语言中都可以一致地本地化。
给 AI Agent 的提示
请根据这次代码评审中的评论进行修改:

## 总体评论
- TabNav.svelte 在一个 $effect 中注册了 hashchange 监听器并访问 window,但没有任何运行时保护,这在 SSR 时可能会抛错;建议用 `typeof window !== 'undefined'` 来包裹这些引用,或者把它们移动到 onMount 中。
- line-clamp 样式在 Card.svelte 和 vndb.astro 中被重复定义;建议将这部分样式集中管理(例如通过共享的 CSS 工具类,或使用现有的 Tailwind line-clamp 工具类),以避免不同实现之间出现偏差。
- vndb.astro 同时使用了硬编码的中文字符串(例如「未配置 VNDB 用户ID」)和基于 i18n 的消息;建议为这些文本添加对应的 i18n key,这样 VNDB 页面文案在不同语言中都可以一致地本地化。

## 单独评论

### 评论 1
<location path="src/components/pages/vndb/VndbSection.svelte" line_range="27-36" />
<code_context>
const filterCounts = $derived(() => {
</code_context>
<issue_to_address>
**issue (bug_risk):** 派生值被当作函数来使用,这会在运行时出错。

在这个 runes 文件中,`filterCounts``filters``filteredItems``totalPages``pagedItems` 都是通过 `$derived` 创建的,而 `$derived` 返回的是值而不是可调用函数。后续却将它们当作函数来调用(例如 `filters()``filteredItems().length`),这会在运行时抛出错误。请将它们作为普通值来使用(例如 `filters``filteredItems.length`),包括在分页逻辑和模板绑定中。
</issue_to_address>

### 评论 2
<location path="src/components/pages/vndb/Card.svelte" line_range="232-240" />
<code_context>
+</a>
+
+<style>
+  .line-clamp-2 {
+    display: -webkit-box;
+    line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+  }
+  .line-clamp-1 {
+    display: -webkit-box;
+    line-clamp: 1;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
</code_context>
<issue_to_address>
**issue (bug_risk):** 自定义的 line-clamp CSS 使用了非标准的 `line-clamp` 属性,因此可能无法生效。

`.line-clamp-1``.line-clamp-2` 使用的是 `line-clamp` 而不是 `-webkit-line-clamp`,所以在大多数浏览器中不会起到截断效果。请对齐 `src/pages/vndb.astro` 中的实现(使用 `-webkit-line-clamp`,并配合 `display: -webkit-box``-webkit-box-orient: vertical`),或者抽取成一个共享工具类,以保持行为一致。
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请对每条评论点击 👍 或 👎,我会根据你的反馈持续改进评审质量。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • TabNav.svelte attaches a hashchange listener and accesses window in a $effect without any runtime guard, which can throw during SSR; consider wrapping those references in a typeof window !== 'undefined' check or moving them into onMount.
  • Line-clamp styles are duplicated in Card.svelte and vndb.astro; consider centralizing this styling (e.g., via a shared CSS utility or existing Tailwind line-clamp utilities) to avoid drift between implementations.
  • vndb.astro mixes hardcoded Chinese strings (e.g. 未配置 VNDB 用户ID) with i18n-based messages; it may be clearer to add corresponding i18n keys so that the VNDB page text is consistently localizable across languages.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- TabNav.svelte attaches a hashchange listener and accesses window in a $effect without any runtime guard, which can throw during SSR; consider wrapping those references in a typeof window !== 'undefined' check or moving them into onMount.
- Line-clamp styles are duplicated in Card.svelte and vndb.astro; consider centralizing this styling (e.g., via a shared CSS utility or existing Tailwind line-clamp utilities) to avoid drift between implementations.
- vndb.astro mixes hardcoded Chinese strings (e.g. 未配置 VNDB 用户ID) with i18n-based messages; it may be clearer to add corresponding i18n keys so that the VNDB page text is consistently localizable across languages.

## Individual Comments

### Comment 1
<location path="src/components/pages/vndb/VndbSection.svelte" line_range="27-36" />
<code_context>
const filterCounts = $derived(() => {
</code_context>
<issue_to_address>
**issue (bug_risk):** Derived values are being used as functions, which will break at runtime.

In this runes file, `filterCounts`, `filters`, `filteredItems`, `totalPages`, and `pagedItems` are all created with `$derived`, which returns values, not callables. Later they’re invoked like functions (e.g. `filters()`, `filteredItems().length`), which will throw at runtime. Use them as plain values instead (e.g. `filters`, `filteredItems.length`), including in the pagination logic and template bindings.
</issue_to_address>

### Comment 2
<location path="src/components/pages/vndb/Card.svelte" line_range="232-240" />
<code_context>
+</a>
+
+<style>
+  .line-clamp-2 {
+    display: -webkit-box;
+    line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+  }
+  .line-clamp-1 {
+    display: -webkit-box;
+    line-clamp: 1;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
</code_context>
<issue_to_address>
**issue (bug_risk):** Custom line-clamp CSS uses the nonstandard `line-clamp` property, so clamping may not work.

`.line-clamp-1` and `.line-clamp-2` use `line-clamp` instead of `-webkit-line-clamp`, so they won’t clamp in most browsers. Please match the implementation in `src/pages/vndb.astro` (use `-webkit-line-clamp` plus `display: -webkit-box` and `-webkit-box-orient: vertical`), or extract a shared utility so the behavior stays consistent.
</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 thread src/components/pages/vndb/VndbSection.svelte Outdated
Comment thread src/components/pages/vndb/Card.svelte Outdated
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.

1 participant