Files
PR-Helper/docs/03-frontend-interaction.md
T

340 lines
5.8 KiB
Markdown
Raw Normal View History

# 前端交互设计
## 概述
PR-Helper 前端采用渐进式增强设计,结合 HTMX、D3.js、diff2html 等库,提供流畅的交互体验。
## 技术栈
| 技术 | 用途 |
|------|------|
| Go html/template | 服务端渲染 |
| HTMX 2.x | 动态交互 |
| D3.js 7.x | Git 图形可视化 |
| diff2html 3.x | 差异渲染 |
| highlight.js 11.x | 语法高亮 |
| marked.js | Markdown 渲染 |
| Tailwind CSS | 样式框架 |
## 核心组件
### 1. SSE 客户端 (sse.js)
#### 设计目标
- 支持 POST 请求的 SSE(EventSource 只支持 GET)
- 流式读取响应体
- 事件分发机制
#### API 设计
```javascript
const SSE = {
async post(url, body, handlers = {}) {
// 返回 controller,支持 abort()
return { abort: () => controller.abort() };
}
};
// 使用示例
SSE.post('/api/repos/1/review', { base: 'main', head: 'feature' }, {
start: (data) => console.log('开始', data),
content: (data) => console.log('内容', data.content),
suggestion: (data) => console.log('建议', data),
summary: (data) => console.log('汇总', data),
done: () => console.log('完成'),
error: (data) => console.error('错误', data.message)
});
```
#### 实现细节
- 使用 `fetch()` + `ReadableStream`
- 手动解析 SSE 协议(event: / data:)
- 支持中断请求
- 自动处理 JSON 解析
### 2. Git 图形 (graph.js)
#### 功能特性
- D3.js SVG 渲染
- 多分支彩色泳道
- 交互式 base/head 选择
- 分支标签右对齐
- 图例显示
#### 布局算法
```javascript
assignLanes() {
// 1. HEAD 分支获得泳道 0
// 2. 其他分支按顺序分配泳道
// 3. 合并提交的第二父提交获得新泳道
// 4. 未访问的提交分配到泳道 0
}
```
#### 交互设计
- **点击**: 选择 base/head 提交
- **悬停**: 高亮节点
- **选择状态**:
- 绿色: base 提交
- 橙色: head 提交
- 蓝色: 普通提交
#### 回调机制
```javascript
gitGraph.onSelectionChange = (baseHash, headHash) => {
// 更新 base/head 选择
// 触发差异加载
};
```
### 3. 差异查看器 (diff-viewer.js)
#### 功能特性
- diff2html 渲染
- 文件树侧边栏
- 增量渲染(非阻塞)
- 懒加载语法高亮
- 滚动同步
- 大型差异保护
#### 增量渲染
```javascript
_renderBatch(outputFormat, startIndex) {
const FILES_PER_BATCH = 5;
// 每帧渲染 5 个文件
// 使用 requestAnimationFrame
// 避免阻塞主线程
}
```
#### 大型差异保护
```javascript
_isTooLarge(files) {
const MAX_FILES = 300;
const MAX_LINES = 10000;
return files.length > MAX_FILES || (totalAdd + totalDel) > MAX_LINES;
}
```
- 超过阈值显示警告
- 用户确认后强制渲染
- 避免浏览器卡顿
#### 文件树
- 目录折叠/展开
- 文件类型图标
- 变更统计(+/-)
- 严重程度标记
#### 滚动同步
```javascript
_setupScrollSpy() {
// IntersectionObserver 监听文件可见性
// 自动高亮侧边栏对应文件
// 点击侧边栏滚动到文件
}
```
### 4. 内联建议 (review-inline.js)
#### 功能
- 在差异中嵌入 AI 建议
- 按严重程度着色
- 支持文件级和行级建议
#### 插入机制
```javascript
insertSuggestion(filename, line, side, severity, content, suggestionId) {
// 1. 懒加载文件索引
// 2. 查找目标行
// 3. 创建建议卡片
// 4. 插入到行后
}
```
#### 严重程度样式
```javascript
const severityStyles = {
critical: 'border-l-4 border-red-500 bg-red-50',
warning: 'border-l-4 border-yellow-500 bg-yellow-50',
info: 'border-l-4 border-green-500 bg-green-50',
};
```
### 5. Markdown 渲染 (markdown.js)
#### 功能
- 使用 marked.js 渲染
- 代码块语法高亮
- 支持内联代码
#### 集成
```javascript
function renderMarkdown(text) {
return marked.parse(text, {
highlight: function(code, lang) {
return hljs.highlightAuto(code).value;
}
});
}
```
### 6. 笔记编辑器 (note-editor.js)
#### 功能
- 内联编辑审查笔记
- 自动保存
- 三种作用域
## 页面结构
### 首页 (/)
- 仓库列表
- 克隆表单
- 快速操作
### 仓库详情页 (/repo/:id)
- Git 图形
- 分支选择器
- 差异查看器
- PR 生成
- AI 代码审查
### 设置页 (/settings)
- LLM 配置
- 审查参数
- 缓存设置
## HTMX 集成
### 动态加载
```html
<div hx-get="/api/repos/1/graph" hx-trigger="load">
<!-- 图形将在这里渲染 -->
</div>
```
### 表单提交
```html
<form hx-post="/api/repos" hx-target="#repo-list">
<input type="text" name="url" required>
<button type="submit">克隆</button>
</form>
```
### 事件触发
```html
<button hx-post="/api/repos/1/pull"
hx-trigger="click"
hx-indicator="#spinner">
拉取更新
</button>
```
## 响应式设计
### 断点
- 移动端: < 640px
- 平板: 640px - 1024px
- 桌面: > 1024px
### 适配策略
- 文件树侧边栏可折叠
- 差异查看器自适应宽度
- 图形可横向滚动
## 性能优化
### 1. 增量渲染
- 分批渲染文件
- requestAnimationFrame
- 避免长任务阻塞
### 2. 懒加载
- 语法高亮按需执行
- 文件索引按需构建
- IntersectionObserver
### 3. 虚拟滚动
- 大型差异只渲染可见部分
- 减少 DOM 节点数
### 4. 缓存
- 静态资源缓存
- API 响应缓存
- 本地状态缓存
## 错误处理
### 网络错误
- 显示错误消息
- 提供重试按钮
- 自动重连(SSE)
### 渲染错误
- 降级到纯文本
- 显示原始数据
- 记录错误日志
## 无障碍
### 键盘导航
- Tab 切换焦点
- Enter 确认选择
- Escape 取消操作
### 屏幕阅读器
- ARIA 标签
- 语义化 HTML
- 焦点管理
## 浏览器兼容性
### 支持的浏览器
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
### 依赖的现代 API
- fetch
- ReadableStream
- IntersectionObserver
- requestAnimationFrame
- CSS Grid/Flexbox