feat: 添加工作区状态检查功能,优化用户体验

- 用户鼠标聚焦到输入框中就弹窗提示用户打开 优化用户体验
This commit is contained in:
Roe-xin
2025-12-30 16:02:36 +08:00
parent 0f458f6299
commit 3f0cc8ae29
4 changed files with 88 additions and 21 deletions

View File

@ -181,6 +181,26 @@ export async function showICHelperPanel(
case "abortDialog":
abortCurrentDialog();
break;
// 新增:检查工作区状态
case "checkWorkspace":
const hasWorkspace = !!(vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0);
if (!hasWorkspace) {
// 弹窗提示用户需要打开工作区
vscode.window.showWarningMessage(
"请先打开一个文件夹作为工作区,这样我就能更好地为您服务了 😊",
"打开文件夹"
).then((selection) => {
if (selection === "打开文件夹") {
vscode.commands.executeCommand("vscode.openFolder");
}
});
}
// 返回工作区状态给前端
panel.webview.postMessage({
command: "workspaceStatus",
hasWorkspace: hasWorkspace
});
break;
}
},
undefined,

View File

@ -16,7 +16,9 @@ export async function createFile(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法创建相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您创建文件了"
);
}
}
@ -28,7 +30,7 @@ export async function createFile(
throw new Error(`文件已存在: ${absolutePath}`);
} catch (error: any) {
// 如果文件不存在,继续创建
if (error.code !== 'FileNotFound') {
if (error.code !== "FileNotFound") {
throw error;
}
}
@ -65,7 +67,9 @@ export async function createOrOverwriteFile(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法创建相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您创建文件了"
);
}
}
@ -99,7 +103,9 @@ export async function createDirectory(dirPath: string): Promise<void> {
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, dirPath);
} else {
throw new Error("没有打开的工作区,无法创建相对路径的目录");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您创建目录了"
);
}
}
@ -115,7 +121,7 @@ export async function createDirectory(dirPath: string): Promise<void> {
}
} catch (error: any) {
// 如果目录不存在,继续创建
if (error.code !== 'FileNotFound') {
if (error.code !== "FileNotFound") {
throw error;
}
}
@ -161,7 +167,9 @@ export async function deleteFile(filePath: string): Promise<void> {
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法删除相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您删除文件了"
);
}
}
@ -197,7 +205,9 @@ export async function updateFile(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法修改相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您修改文件了"
);
}
}
@ -236,7 +246,9 @@ export async function appendToFile(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法追加相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您追加文件内容了"
);
}
}
@ -274,7 +286,9 @@ export async function replaceFile(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法修改相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您修改文件了"
);
}
}
@ -291,14 +305,17 @@ export async function replaceFile(
// 转义特殊字符,将字符串作为字面量处理
const escapeRegExp = (str: string) => {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
};
// 替换内容 - 如果是字符串,先转义特殊字符
let newContent: string;
if (typeof searchValue === 'string') {
if (typeof searchValue === "string") {
const escapedSearch = escapeRegExp(searchValue);
newContent = fileContent.replace(new RegExp(escapedSearch, "g"), replaceValue);
newContent = fileContent.replace(
new RegExp(escapedSearch, "g"),
replaceValue
);
} else {
newContent = fileContent.replace(searchValue, replaceValue);
}
@ -330,7 +347,9 @@ export async function insertAtLine(
if (workspaceFolders && workspaceFolders.length > 0) {
absolutePath = path.join(workspaceFolders[0].uri.fsPath, filePath);
} else {
throw new Error("没有打开的工作区,无法修改相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您修改文件了"
);
}
}
@ -382,7 +401,9 @@ export async function renameFile(
absoluteNewPath = path.join(workspaceRoot, newPath);
}
} else {
throw new Error("没有打开的工作区,无法重命名相对路径的文件");
throw new Error(
"请先打开一个文件夹作为工作区,这样我就能为您重命名文件了"
);
}
const oldUri = vscode.Uri.file(absoluteOldPath);
@ -401,10 +422,13 @@ export async function renameFile(
throw new Error(`目标文件已存在: ${absoluteNewPath}`);
} catch (error: any) {
// 如果文件不存在,继续重命名
if (error.code !== 'FileNotFound' && !error.message.includes('目标文件已存在')) {
if (
error.code !== "FileNotFound" &&
!error.message.includes("目标文件已存在")
) {
throw error;
}
if (error.message.includes('目标文件已存在')) {
if (error.message.includes("目标文件已存在")) {
throw error;
}
}

View File

@ -271,6 +271,10 @@ export function getInputAreaScript(): string {
// 对话状态管理
let isConversationActive = false;
// 工作区检测状态
let hasCheckedWorkspace = false; // 是否已经检测过工作区
let hasWorkspace = true; // 工作区状态
// 自动调整 textarea 高度
function autoResizeTextarea() {
if (messageInput) {
@ -283,11 +287,16 @@ export function getInputAreaScript(): string {
if (messageInput) {
messageInput.addEventListener('input', autoResizeTextarea);
// 监听点击事件,检测工作区状态
messageInput.addEventListener('focus', () => {
if (!hasCheckedWorkspace) {
hasCheckedWorkspace = true;
vscode.postMessage({ command: 'checkWorkspace' });
}
});
// 初始化时调整一次高度
autoResizeTextarea();
// 聚焦到输入框
messageInput.focus();
}
// 切换发送按钮状态
@ -326,6 +335,14 @@ export function getInputAreaScript(): string {
const text = messageInput.value.trim();
if (!text) return;
// 检查工作区状态
if (!hasWorkspace) {
// 如果没有工作区,阻止发送并清空输入框
messageInput.value = '';
autoResizeTextarea();
return;
}
const mode = getCurrentMode(); // 从模式选择器组件获取当前模式
const model = getCurrentModel(); // 从模型选择器组件获取当前模型

View File

@ -443,8 +443,6 @@ export function getWebviewContent(iconUri?: string): string {
}
}
messageInput.focus();
// 监听来自插件的消息
window.addEventListener('message', event => {
const message = event.data;
@ -516,6 +514,14 @@ export function getWebviewContent(iconUri?: string): string {
hideLoadingIndicator();
break;
case 'workspaceStatus':
// 更新工作区状态
if (typeof hasWorkspace !== 'undefined') {
hasWorkspace = message.hasWorkspace;
console.log('[WebView] 工作区状态:', hasWorkspace);
}
break;
case 'vcdInfo':
// 渲染迷你波形预览信息
try {