Conversation
审查者指南介绍了一个本地化的文章分享卡片,可延迟生成可下载且支持主题的画布海报,其中包含文章元数据、图片、作者信息和二维码,同时替换之前的社交分享实现,并将该功能接入文章页面。 延迟生成文章海报的时序图sequenceDiagram
actor Reader
participant SharePoster
participant QRCode
participant ImageLoader
participant Canvas
participant Browser
Reader->>SharePoster: generatePoster()
SharePoster->>QRCode: toDataURL(url)
QRCode-->>SharePoster: qrCodeUrl
SharePoster->>ImageLoader: loadImage(qrCodeUrl)
SharePoster->>ImageLoader: loadImage(coverImage)
SharePoster->>ImageLoader: loadImage(avatar)
ImageLoader-->>SharePoster: loaded images
SharePoster->>Canvas: calculateDimensions()
SharePoster->>Canvas: draw poster content
Canvas-->>SharePoster: canvas.toDataURL()
SharePoster-->>Reader: display generated poster
Reader->>SharePoster: downloadPoster()
SharePoster->>Browser: download PNG
文件级变更
提示和命令与 Sourcery 交互
自定义你的使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's GuideIntroduces a localized article-sharing card that lazily generates downloadable, theme-aware canvas posters containing article metadata, imagery, author details, and a QR code, while replacing the previous social-share implementation and wiring the feature into post pages. Sequence diagram for lazy article poster generationsequenceDiagram
actor Reader
participant SharePoster
participant QRCode
participant ImageLoader
participant Canvas
participant Browser
Reader->>SharePoster: generatePoster()
SharePoster->>QRCode: toDataURL(url)
QRCode-->>SharePoster: qrCodeUrl
SharePoster->>ImageLoader: loadImage(qrCodeUrl)
SharePoster->>ImageLoader: loadImage(coverImage)
SharePoster->>ImageLoader: loadImage(avatar)
ImageLoader-->>SharePoster: loaded images
SharePoster->>Canvas: calculateDimensions()
SharePoster->>Canvas: draw poster content
Canvas-->>SharePoster: canvas.toDataURL()
SharePoster-->>Reader: display generated poster
Reader->>SharePoster: downloadPoster()
SharePoster->>Browser: download PNG
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
嗨——我发现了 3 个问题
AI Agent 提示词
请处理本次代码审查中的评论:
## 个别评论
### 评论 1
<location path="src/components/misc/SharePoster.svelte" line_range="96-99" />
<code_context>
+
+ const observer = new MutationObserver(() => {
+ const currentIsDark = isDarkMode();
+ if (currentIsDark !== lastIsDark) {
+ lastIsDark = currentIsDark;
+ posterImage = null;
+ errorMessage = null;
+ }
+ });
</code_context>
<issue_to_address>
**issue (bug_risk):** 当海报生成仍在进行时主题发生变化,MutationObserver 会清除 `posterImage`,但正在进行的生成任务稍后会将旧主题的画布重新赋值给 `posterImage`,因此显示的海报与当前主题不匹配。
**触发条件:** 用户在封面/头像加载或二维码导入仍处于等待状态时,在浅色和深色主题之间切换。
**建议修复:** 跟踪生成时使用的主题,或使用生成令牌,并丢弃在最近一次主题变更之前生成的结果。
</issue_to_address>
### 评论 2
<location path="src/components/misc/SharePoster.svelte" line_range="386-401" />
<code_context>
+const COPY_FEEDBACK_DURATION = 2000;
+
+async function copyLink() {
+ try {
+ if (!navigator.clipboard?.writeText) {
+ throw new Error("Clipboard API is not available");
+ }
+
+ await navigator.clipboard.writeText(url);
+ copied = true;
+ if (copyTimeout) {
+ clearTimeout(copyTimeout);
+ }
+ copyTimeout = setTimeout(() => {
+ copied = false;
+ }, COPY_FEEDBACK_DURATION);
+ } catch (error) {
+ console.error("Failed to copy link:", error);
+ }
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** 当剪贴板 API 不可用或 `writeText` 被拒绝时,`copyLink` 只记录异常,而 UI 保持不变的“复制链接”状态,因此用户不会获知复制失败。
**触发条件:** 页面未获得剪贴板权限、处于非安全上下文,或浏览器拒绝剪贴板写入时。
**建议修复:** 在 catch 分支中设置错误或失败反馈状态,并向用户显示本地化消息。
</issue_to_address>
### 评论 3
<location path="src/components/misc/utils/poster-renderer.ts" line_range="64-67" />
<code_context>
+ const lines: string[] = [];
+ let currentLine = "";
+
+ for (const char of text) {
+ if (ctx.measureText(currentLine + char).width < maxWidth) {
+ currentLine += char;
+ } else {
+ lines.push(currentLine);
+ currentLine = char;
+ }
+ }
+
</code_context>
<issue_to_address>
**nitpick (bug_risk):** 当第一个字形宽于 `maxWidth` 时,`getLines` 会在将该字形放到下一行之前先推入一个空字符串,从而增加一个空白渲染行,并高估计算出的海报高度。
**触发条件:** 标题或描述包含宽于可用画布宽度的字形时。
**建议修复:** 仅在 `currentLine` 非空时推入它,或显式处理超宽字形,避免创建空行。
```suggestion
} else {
if (currentLine) {
lines.push(currentLine);
}
currentLine = char;
}
```
</issue_to_address>Sourcery 评估
需要人工审查。 需要先处理 2 个发现;此外,此更改用大规模的客户端海报生成器替换了现有的分享行为,并添加了 qrcode 依赖,因此错误的实现可能会生成损坏或具有误导性的下载海报,还可能通过外部回退代理触发图片请求。回滚可以恢复旧 UI,但在回滚前已经下载的海报以及已经发出的代理请求仍会保留。
阻塞性发现:src/components/misc/SharePoster.svelte:99、src/components/misc/SharePoster.svelte:401
帮助我变得更有用!请对每条评论点击 👍 或 👎,我会利用反馈来改进审查结果。
Original comment in English
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/components/misc/SharePoster.svelte" line_range="96-99" />
<code_context>
+
+ const observer = new MutationObserver(() => {
+ const currentIsDark = isDarkMode();
+ if (currentIsDark !== lastIsDark) {
+ lastIsDark = currentIsDark;
+ posterImage = null;
+ errorMessage = null;
+ }
+ });
</code_context>
<issue_to_address>
**issue (bug_risk):** When the theme changes while poster generation is still in progress, the mutation observer clears `posterImage`, but the in-flight generation later assigns its old-theme canvas back to `posterImage`, so the displayed poster does not match the current theme.
**Triggers:** When a cover/avatar load or QR-code import is still pending while the user switches between light and dark themes.
**Suggested fix:** Track the generation theme or use a generation token, and discard results produced before the latest theme change.
</issue_to_address>
### Comment 2
<location path="src/components/misc/SharePoster.svelte" line_range="386-401" />
<code_context>
+const COPY_FEEDBACK_DURATION = 2000;
+
+async function copyLink() {
+ try {
+ if (!navigator.clipboard?.writeText) {
+ throw new Error("Clipboard API is not available");
+ }
+
+ await navigator.clipboard.writeText(url);
+ copied = true;
+ if (copyTimeout) {
+ clearTimeout(copyTimeout);
+ }
+ copyTimeout = setTimeout(() => {
+ copied = false;
+ }, COPY_FEEDBACK_DURATION);
+ } catch (error) {
+ console.error("Failed to copy link:", error);
+ }
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** When the Clipboard API is unavailable or `writeText` rejects, `copyLink` only logs the exception and leaves the UI in the unchanged “Copy Link” state, so the user receives no indication that copying failed.
**Triggers:** When the page is served without clipboard permission, outside a secure context, or the browser rejects the clipboard write.
**Suggested fix:** Set an error or failure-feedback state in the catch branch and render a localized message to the user.
</issue_to_address>
### Comment 3
<location path="src/components/misc/utils/poster-renderer.ts" line_range="64-67" />
<code_context>
+ const lines: string[] = [];
+ let currentLine = "";
+
+ for (const char of text) {
+ if (ctx.measureText(currentLine + char).width < maxWidth) {
+ currentLine += char;
+ } else {
+ lines.push(currentLine);
+ currentLine = char;
+ }
+ }
+
</code_context>
<issue_to_address>
**nitpick (bug_risk):** When the first glyph is wider than `maxWidth`, `getLines` pushes an empty string before placing that glyph on the next line, adding a blank rendered line and overstating the calculated poster height.
**Triggers:** When a title or description contains a glyph wider than the available canvas width.
**Suggested fix:** Only push `currentLine` when it is non-empty, or explicitly handle an over-wide glyph without creating an empty line.
```suggestion
} else {
if (currentLine) {
lines.push(currentLine);
}
currentLine = char;
}
```
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and this replaces the existing sharing behavior with a substantial client-side poster generator and adds the qrcode dependency, so an incorrect implementation could produce broken or misleading downloaded posters and trigger image requests through the external fallback proxy. Reverting restores the old UI, but posters already downloaded and any proxy requests made before the revert would remain.
Blocking findings: src/components/misc/SharePoster.svelte:99, src/components/misc/SharePoster.svelte:401
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Type of change
Checklist
Related Issue
Changes
How To Test
Screenshots (if applicable)
Additional Notes
Sourcery 摘要
将现有的社交分享控件替换为本地化的文章海报分享体验。
新功能:
增强功能:
构建:
Original summary in English
Sourcery 总结
将现有的社交分享控件替换为本地化的文章海报分享体验。
新功能:
增强功能:
构建:
Original summary in English
Summary by Sourcery
Replace the existing social sharing controls with a localized article poster sharing experience.
New Features:
Enhancements:
Build: