You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
8.6 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

let selectedCodeForContext = '';
const vscode = acquireVsCodeApi();
document.addEventListener('DOMContentLoaded', () => {
const chatForm = document.getElementById('chat-form');
const userInput = document.getElementById('user-input');
const chatBox = document.getElementById('chat-box');
const loading = document.getElementById('loading');
chatForm.addEventListener('submit', (e) => {
e.preventDefault();
const text = userInput.value.trim();
if (!text) return;
vscode.postMessage({
command: 'ask',
text,
fileContent: selectedCodeForContext
});
// addMessage('user', text);
showLoading();
userInput.value = '';
});
// 判断内容是否为 Markdown简单判断
function isMarkdown(content) {
if (!content || content.trim() === '') return false;
const markdownPatterns = [
/^#/m, // 标题 #
/\*\*[^*]+\*\*/g, // 加粗 **text**
/__[^_]+__/g, // 加粗 __text__
/^- /gm, // 无序列表
/^\* /gm, // 无序列表
/^\d+\. /gm, // 有序列表
/```/g // 代码块
];
return markdownPatterns.some(pattern => pattern.test(content));
}
// 处理添加消息
function addMessage(role, content, codeDiff) {
const msgDiv = document.createElement('div');
msgDiv.className = `message ${role}`;
// 渲染内容
if (isMarkdown(content)) {
console.log("content:", content);
msgDiv.innerHTML = marked.parse(content);
console.log("msgDiv.innerHTML:", msgDiv.innerHTML);
} else {
const div = document.createElement('div');
div.textContent = content;
msgDiv.appendChild(div);
}
// 如果有代码差异,添加查看差异按钮
if (codeDiff) {
const diffButton = document.createElement('button');
diffButton.className = 'diff-button';
diffButton.textContent = '查看代码差异';
diffButton.onclick = () => showCodeDiff(codeDiff);
msgDiv.appendChild(diffButton);
}
chatBox.appendChild(msgDiv);
// 高亮代码块
const codeBlocks = msgDiv.querySelectorAll('pre code');
codeBlocks.forEach(block => {
hljs.highlightElement(block);
});
// 滚动到底部
chatBox.scrollTop = chatBox.scrollHeight;
}
// 显示代码差异
function showCodeDiff(codeDiff) {
const diffModal = document.getElementById('diff-modal');
const diffContent = document.getElementById('diff-content');
diffContent.innerHTML = '';
// 显示添加的行
if (codeDiff.added && codeDiff.added.length > 0) {
codeDiff.added.forEach(line => {
const diffLine = document.createElement('div');
diffLine.className = 'diff-line diff-added';
diffLine.textContent = `+ ${line}`;
diffContent.appendChild(diffLine);
});
}
// 显示删除的行
if (codeDiff.removed && codeDiff.removed.length > 0) {
codeDiff.removed.forEach(line => {
const diffLine = document.createElement('div');
diffLine.className = 'diff-line diff-removed';
diffLine.textContent = `- ${line}`;
diffContent.appendChild(diffLine);
});
}
diffModal.classList.remove('hidden');
}
function showLoading() {
loading.classList.remove('hidden');
}
function hideLoading() {
loading.classList.add('hidden');
}
window.addEventListener('message', (event) => {
const message = event.data;
console.log(message)
if (message.command === 'addMessage') {
addMessage(message.role, message.content,message.codeDiff);
} else if (message.command === 'hideLoading') {
hideLoading();
} else if (message.command === 'addToInput') {
userInput.value = message.content; // 插入选中内容到输入框
selectedCodeForContext = message.content;
userInput.focus(); // 自动聚焦输入框
} else if (message.command === 'fileList') {
const fileListContainer = document.getElementById('file-list');
if (message.error) {
fileListContainer.innerHTML = `<div class="loading">错误: ${message.error}</div>`;
return;
}
if (!message.files || message.files.length === 0) {
fileListContainer.innerHTML = '<div class="loading">未找到文件</div>';
return;
}
// 渲染文件列表
fileListContainer.innerHTML = '';
message.files.forEach(file => {
const fileItem = document.createElement('div');
fileItem.className = 'file-item';
fileItem.innerHTML = ` <span class="file-icon">${file.isDirectory ? '📁' : '📄'}</span>
<span class="file-name" title="${file.relativePath}">${file.relativePath}</span>
`;
fileItem.addEventListener('click', () => {
// 选择文件
vscode.postMessage({
command: 'selectFileByPath',
filePath: file.path
});
// 关闭模态框
document.getElementById('file-browser-modal').classList.add('hidden');
});
fileListContainer.appendChild(fileItem);
});
} else if (message.command === 'setContextFile') {
const contextPlaceholder = document.getElementById('context-placeholder');
const contextTab = document.getElementById('context-tab');
const fileNameElement = document.getElementById('context-file-name');
const fullPath = message.fileName;
const fileName = fullPath.split(/[\/\\]/).pop();
fileNameElement.innerText = fileName;
fileNameElement.title = fullPath;
selectedCodeForContext = message.fileContent;
// 隐藏占位符,显示文件标签
contextPlaceholder.classList.add('hidden');
contextTab.classList.remove('hidden');
}
});
// 打开文件浏览器
document.getElementById('select-context-btn').addEventListener('click', () => {
// 显示模态框
document.getElementById('file-browser-modal').classList.remove('hidden');
// 请求文件列表
vscode.postMessage({
command: 'getFileList'
});
});
// 关闭模态框
document.getElementById('close-modal').addEventListener('click', () => {
document.getElementById('file-browser-modal').classList.add('hidden');
});
// 点击模态框外部关闭
document.getElementById('file-browser-modal').addEventListener('click', (e) => {
if (e.target.id === 'file-browser-modal') {
document.getElementById('file-browser-modal').classList.add('hidden');
}
});
// 文件搜索功能
document.getElementById('file-search-input').addEventListener('input', (e) => {
const searchTerm = e.target.value.toLowerCase();
const fileItems = document.querySelectorAll('.file-item');
fileItems.forEach(item => {
const fileName = item.querySelector('.file-name').textContent.toLowerCase();
if (fileName.includes(searchTerm)) {
item.style.display = '';
} else {
item.style.display = 'none';
}
});
});
// 添加关闭按钮事件监听
document.getElementById('close-context-btn').addEventListener('click', () => {
const contextPlaceholder = document.getElementById('context-placeholder');
const contextTab = document.getElementById('context-tab');
contextTab.classList.add('hidden');
contextPlaceholder.classList.remove('hidden');
selectedCodeForContext = '';
});
// 关闭差异模态框
document.getElementById('close-diff-modal').addEventListener('click', () => {
document.getElementById('diff-modal').classList.add('hidden');
});
// 点击模态框外部关闭
document.getElementById('diff-modal').addEventListener('click', (e) => {
if (e.target.id === 'diff-modal') {
document.getElementById('diff-modal').classList.add('hidden');
}
});
});