Skip to content

Commit beca954

Browse files
committed
refactor(notes): 笔记预览行渲染迁入 markdownLine
1 parent ac202c9 commit beca954

2 files changed

Lines changed: 12 additions & 15 deletions

File tree

‎app/src/components/NotePreviewView.tsx‎

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
import { useCallback, useEffect, useState } from "react";
1414
import { invoke, convertFileSrc } from "@tauri-apps/api/core";
1515
import type { Note, NoteFilterResult, TextFilterDecision, TextFilterReview, TextFilterStatus } from "../types";
16-
import { escapeHtml, renderTimestampAnchors } from "../utils/html";
16+
import { escapeHtml } from "../utils/html";
17+
import { PREVIEW_MODE, mdLineHtml } from "../utils/markdownLine";
1718
import AiRefineCard from "./AiRefineCard";
1819
import { ConfirmDialog, Loading, Surface, Text } from "../ui/primitives";
1920

@@ -32,11 +33,15 @@ const REASON_LABEL: Record<string, string> = {
3233
rhetorical: "反问",
3334
};
3435

35-
/** 轻量 Markdown 渲染(标题/段落/列表/屏配图——笔记正文结构有限,避免引渲染库;
36+
/** 轻量 Markdown 渲染(标题/段落/列表/屏配图——笔记正文结构有限,避免引渲染库);
3637
* 所有文本经 escapeHtml(utils/html.ts 单一定义源)转义——本地内容仍按不可信输入处理;
3738
* v0.7.3:`![alt](session-images/...)` 配图行 → 本地图(baseUrl + convertFileSrc))
38-
* v0.12.0:时间戳锚点 `[⏱ MM:SS]([[ts:ms]])`/章节锚点 → 芯片(renderTimestampAnchors
39-
* ——修复笔记录库前预览仍显示原始锚点文本的真机验收问题) */
39+
* 批 7 T17(C10.1 的 #4 迁入):行级渲染改由 `utils/markdownLine.ts` 的 `mdLineHtml` 承担
40+
* ——它同时是精修工作台那条链的唯一实现;`PREVIEW_MODE` 的样式值逐字取自本函数迁移前的
41+
* h2/h3/quote/li/p 五档(§C11.1)⇒ 可见输出零变化(T16 的 34 条表征用例是回归网)。
42+
* 🔴 边界(§C37.3):`PREVIEW_MODE` **不覆盖图片行** —— 该分支需要 `convertFileSrc` +
43+
* 运行时 `baseUrl`/`dataDir` 两个注入值,塞不进模式常量 ⇒ **它的前置判断必须留在本容器侧**,
44+
* 否则配图行会退化成 `<p>`(T16 的 7 条图片用例即此判据)。 */
4045
function renderMarkdown(md: string, imageBaseUrl: string, dataDir: string): string {
4146
return md
4247
.split("\n")
@@ -60,16 +65,8 @@ function renderMarkdown(md: string, imageBaseUrl: string, dataDir: string): stri
6065
// convertFileSrc 虽已编码但直出分支无编码,统一 escapeHtml 兜底
6166
return `<img src="${escapeHtml(src)}" alt="${escapeHtml(img[1])}" loading="lazy" style="max-width:260px;border-radius:6px;border:1px solid #e5e7eb;margin:4px 0" />`;
6267
}
63-
// v0.12.0:先转义再替换锚点(锚点语法字符不在转义集,匹配安全)
64-
if (line.startsWith("# ")) return `<h2 style="font-size:15px;margin:10px 0 4px">${renderTimestampAnchors(escapeHtml(line.slice(2)))}</h2>`;
65-
if (line.startsWith("## ")) return `<h3 style="font-size:13px;margin:8px 0 4px;color:#0f766e">${renderTimestampAnchors(escapeHtml(line.slice(3)))}</h3>`;
66-
// v0.7.5(REQ-170):会话异常警示行(Markdown 引用行 → 警示块)
67-
if (line.startsWith("> ")) {
68-
return `<div style="font-size:12px;color:#b45309;background:#fffbeb;border:1px solid #fde68a;border-radius:6px;padding:6px 10px;margin:6px 0">${renderTimestampAnchors(escapeHtml(line.slice(2)))}</div>`;
69-
}
70-
if (line.startsWith("- ")) return `<div style="font-size:12px;color:#4b5563">• ${renderTimestampAnchors(escapeHtml(line.slice(2)))}</div>`;
71-
if (line.trim() === "") return "";
72-
return `<p style="font-size:13px;color:#374151;margin:4px 0">${renderTimestampAnchors(escapeHtml(line))}</p>`;
68+
// 其余各行(标题/引用/列表/空行/段落)—— 唯一实现,样式与迁移前逐字相同
69+
return mdLineHtml(line, PREVIEW_MODE);
7370
})
7471
.join("");
7572
}

‎docs/standards/line-limit-exemptions.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
| app/src-tauri/src/live_session_pause.rs | 353 | 批 2 暂停边沿收敛域 + 审查修复轮 1(own_pending 吸收/丢采样恢复沿补发)净增——2026-09-09 纠偏实测 353(交付口径 258 失真),300-600 档登记 | 若再增长:合成事件对构造拆至 live_session_pause_synth.rs |
9696
| app/src-tauri/src/ai_client_tests.rs | 352 | ai_client.rs 单测域(22 例:payload 构造族 build_chat_payload/build_plain_payload、JSON 前置条件提示、chat_completions_url 拼接、响应提取与弱化解析、fallback_provider_ids;env 变量以静态 Mutex 串行化,不触网)——测试模块由 `#[cfg(test)] #[path]` 单点挂载(ai_client.rs:504),纯函数用例与实现同域便于契约对齐。**本条目由生成器补登(该文件无 @ai-context 头注释),理由为 2026-09-11 重建时人工补写** | 若再增长:payload 构造组拆至 ai_client_payload_tests.rs |
9797
| app/src/components/NoteLinkToSystem.tsx | 352 | v0.19.7(REQ-286)重构:挂体系选择器(体系下拉 + 三 tab + LinkEntityPicker 搜索树列表 + 三类内联轻建编排 + 既有反查/撤链/钳制语义保持)——实体选择/创建交互已下沉 LinkEntityPicker.tsx(134 行),本文件保留编排与数据装载内聚 | 若再增长:树行构建(flattenNodeRows)与实体装载拆至 useSystemEntities.ts hook |
98-
| app/src/components/NotePreviewView.tsx | 352 | 原料/产物/笔记预览三视图之一:过滤后笔记正文(标题+讲述内容+画面要点)+ 过滤统计卡(UI 垃圾 x/重复 y/碎片 z/低置信 w)+被过滤内容折叠对照(可复查误杀,点击定位原料)+ 一键落库(复用 session_to_note 单一管线)+「✨ AI 复核」按需触发(REQ-085:授权默认关——上传前确认;判定结果就地更新预览;merge 段以拼接形态展示,落库仍按原始段——原料不动原则)。(自动摘取,待细化) | 若再增长:按职责拆分 |
98+
| app/src/components/NotePreviewView.tsx | 349 | 原料/产物/笔记预览三视图之一:过滤后笔记正文(标题+讲述内容+画面要点)+ 过滤统计卡(UI 垃圾 x/重复 y/碎片 z/低置信 w)+被过滤内容折叠对照(可复查误杀,点击定位原料)+ 一键落库(复用 session_to_note 单一管线)+「✨ AI 复核」按需触发(REQ-085:授权默认关——上传前确认;判定结果就地更新预览;merge 段以拼接形态展示,落库仍按原始段——原料不动原则)。批 7 T17:行级渲染迁入 utils/markdownLine.ts(PREVIEW 模式,352→349;图片行分支按 §C37.3 留在容器侧)。(自动摘取,待细化) | 若再增长:按职责拆分 |
9999
| app/src-tauri/src/structure_models.rs | 343 | v0.5.0 模型版:模型清单/独立状态机下载器(进度事件/.part 原子写/按需启用三分类)+ 磁盘就绪判定(disk_done)内聚 | 若再增长:download_one 拆至 structure_download.rs |
100100
| app/src/components/NoteReadingView.tsx | 343 | v0.20.13 批 8(REQ-317)正文选区右键菜单接线(正文容器 ref 化 + 选区判定/全选 + 共享菜单渲染,259→316)——选区纯逻辑已拆 utils/noteSelectionMenu.ts 与 note-selection/SelectionActionMenu.tsx,本文件仅留宿主接线 | 若再增长:搜索态/选区态/大纲态拆至 useNoteReadingViewState.ts |
101101
| app/src-tauri/src/db_ai_tasks.rs | 340 | 任务注册表在 AppState 内存(HashMap)——重启即失、未采纳结果无法恢复。本模块把任务记录落 SQLite(ai_tasks 表):状态/结果 JSON/成本/耗时/模型/错误全量可查;应用启动时恢复未采纳的成功结果到注册表(重启不丢,任务面板可见历史);采纳落库时标记 adopted(防重启后重复采纳产生重复笔记)。(自动摘取,待细化) | 若再增长:按职责拆分 |

0 commit comments

Comments
 (0)