新增: 文件浏览器增强(窗口分离/Git 变更/行号/Diff/分页提交历史)
- 窗口分离: FileExplorer 可弹出独立 Tauri 窗口 - 行号显示: 文件预览左侧显示行号列 - 按后缀图标: rs/ts/js/vue/css/html 等 20+ 类型彩色图标 - Diff 视图: 有 Git 变更的文件可切换 diff 红绿视图 - Git 变更面板: 变更文件列表(按目录缩进分组)+提交历史(分页加载) - 提交详情: 点击提交查看变更文件列表及文件级 diff - 时间显示: 提交历史显示相对时间/具体日期 - 面包屑导航不丢预览: 导航时不改变当前预览文件 - 刷新保留选中文件: 只清树缓存不清预览 - 中文编码修复: git 命令注入 LANG/LC_ALL 环境变量 - 自适应布局: 弹性 flex 布局,窄窗口适配 - 滚动条优化: 内容区内部滚动,不溢出页面层 - 多工程管理: 工具栏添加工程按钮+弹窗表单 - 审批加载超时缩短: 130s 降至 30s - 文件变更自动刷新: write_file/patch_file 触发 df-data-changed
This commit is contained in:
@@ -10,15 +10,15 @@
|
||||
import { ref, reactive, computed, watch, onBeforeUnmount, type Ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useConfirm } from '@/composables/useConfirm'
|
||||
import { STREAM_TIMEOUT_MS } from '@/composables/ai/useAiStream'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
|
||||
/**
|
||||
* 审批按钮 loading 超时兜底(B-260616-08)。
|
||||
* 后端回事件使 tc.status 离开 pending_approval → watch 复位。
|
||||
* 兜底计时到点复位 + toast 提示(对齐全局看门狗 STREAM_TIMEOUT_MS,后端无回执时给用户重试入口)。
|
||||
* 兜底计时到点复位 + toast 提示(后端 IPC 应在 1~3s 内返回;30s 兜底远足超时后允许用户重试)。
|
||||
* 与 stream 看门狗(130s)解耦:审批是按钮级交互,不是后台流,不需要对齐后端 120s 空闲超时。
|
||||
*/
|
||||
const APPROVE_LOADING_TIMEOUT_MS = STREAM_TIMEOUT_MS
|
||||
const APPROVE_LOADING_TIMEOUT_MS = 30_000
|
||||
|
||||
/** AE-2025-05:High 风险工具白名单(后端 tool_registry.rs RiskLevel::High 对齐) */
|
||||
const HIGH_RISK_TOOLS = new Set<string>([
|
||||
|
||||
76
src/composables/project/useFileExplorerWindow.ts
Normal file
76
src/composables/project/useFileExplorerWindow.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 文件浏览器窗口分离 — 弹出/分离/附加 FileExplorer 独立窗口。
|
||||
*
|
||||
* 对标 useAiWindow 的 detach/reattach 模式,复用 WebviewWindow API。
|
||||
* 分离窗口以独立 Tauri 窗口打开 FileExplorerDetached 视图,
|
||||
* 通过 URL query `?projectId=xxx` 传参。
|
||||
*/
|
||||
const DETACHED_LABEL_PREFIX = 'fe-detached-'
|
||||
|
||||
function detachedLabel(projectId: string): string {
|
||||
return DETACHED_LABEL_PREFIX + projectId
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件浏览器弹出到独立窗口。
|
||||
* 若该项目的窗口已存在则聚焦,不重复创建。
|
||||
*
|
||||
* @param projectId 项目 id(传给分离窗口加载工程列表)
|
||||
* @param title 窗口标题(可选,默认"文件浏览器")
|
||||
*/
|
||||
export async function detachFileExplorer(
|
||||
projectId: string,
|
||||
title?: string,
|
||||
): Promise<void> {
|
||||
if (!projectId) return
|
||||
const { WebviewWindow } = await import('@tauri-apps/api/webviewWindow')
|
||||
const label = detachedLabel(projectId)
|
||||
|
||||
// 已存在则聚焦
|
||||
const existing = await WebviewWindow.getByLabel(label)
|
||||
if (existing) {
|
||||
await existing.setFocus()
|
||||
return
|
||||
}
|
||||
|
||||
const url =
|
||||
window.location.origin +
|
||||
window.location.pathname +
|
||||
`#/file-explorer-detached?projectId=${encodeURIComponent(projectId)}`
|
||||
|
||||
const win = new WebviewWindow(label, {
|
||||
url,
|
||||
title: title || '文件浏览器',
|
||||
width: 900,
|
||||
height: 600,
|
||||
minWidth: 640,
|
||||
minHeight: 400,
|
||||
center: true,
|
||||
decorations: true,
|
||||
})
|
||||
|
||||
win.once('tauri://created', () => {
|
||||
console.log('[FileExplorer] 分离窗口已创建:', label)
|
||||
})
|
||||
|
||||
win.once('tauri://error', (e) => {
|
||||
console.error('[FileExplorer] 窗口创建失败:', e)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭指定项目的文件浏览器分离窗口。
|
||||
*/
|
||||
export async function reattachFileExplorer(projectId: string): Promise<void> {
|
||||
if (!projectId) return
|
||||
const { WebviewWindow } = await import('@tauri-apps/api/webviewWindow')
|
||||
const label = detachedLabel(projectId)
|
||||
const existing = await WebviewWindow.getByLabel(label)
|
||||
if (existing) {
|
||||
try {
|
||||
await existing.close()
|
||||
} catch {
|
||||
// 忽略关闭失败
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user