Merge branch 'feat/plugin-initialization' into feat/back-to-front

This commit is contained in:
Roe-xin
2025-12-17 10:07:08 +08:00
6 changed files with 1454 additions and 48 deletions

View File

@ -1,3 +1,13 @@
import {
getWaveformPreviewContent,
getWaveformPreviewScript,
} from "./waveformPreviewContent";
import {
getConversationHistoryBarContent,
getConversationHistoryBarStyles,
getConversationHistoryBarScript,
} from "./conversationHistoryBar";
/**
* 获取 WebView 面板的 HTML 内容
*/
@ -14,7 +24,7 @@ export function getWebviewContent(iconUri?: string): string {
background: var(--vscode-editor-background);
color: var(--vscode-foreground);
margin: 0;
padding: 20px;
padding: 0;
height: 100vh;
box-sizing: border-box;
display: flex;
@ -22,9 +32,16 @@ export function getWebviewContent(iconUri?: string): string {
}
.header {
text-align: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid var(--vscode-panel-border);
padding: 20px;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex: 1;
}
.header.hidden {
display: none;
}
.header h1 {
color: var(--vscode-button-background);
@ -36,6 +53,7 @@ export function getWebviewContent(iconUri?: string): string {
flex-direction: column;
min-height: 0;
overflow: hidden;
padding: 0 20px 20px 20px;
}
.messages {
flex: 1;
@ -177,6 +195,7 @@ export function getWebviewContent(iconUri?: string): string {
align-items: center;
justify-content: space-between;
gap: 10px;
margin-bottom: -17px;
}
.mode-selector {
display: flex;
@ -190,12 +209,13 @@ export function getWebviewContent(iconUri?: string): string {
}
.mode-selector select {
padding: 2px 4px;
background: transparent;
background: var(--vscode-input-background);
color: var(--vscode-foreground);
border: none;
cursor: pointer;
font-size: 12px;
outline: none;
border-radius: 4px;
}
.mode-selector select:hover {
background: var(--vscode-list-hoverBackground);
@ -381,6 +401,8 @@ export function getWebviewContent(iconUri?: string): string {
border-radius: 4px;
margin-top: 10px;
}
${getWaveformPreviewContent()}
${getConversationHistoryBarStyles()}
.file-editor-section {
margin-bottom: 15px;
padding: 15px;
@ -786,6 +808,7 @@ export function getWebviewContent(iconUri?: string): string {
</style>
</head>
<body>
${getConversationHistoryBarContent()}
<div class="header">
<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
<img src="${iconUri}" alt="IC Coder" style="width: 28px; height: 28px;" />
@ -795,35 +818,7 @@ export function getWebviewContent(iconUri?: string): string {
</div>
<div class="chat-container">
<div class="file-reader-section">
<h3>📁 文件读取</h3>
<div class="file-input-group">
<input
type="text"
id="filePathInput"
placeholder="输入文件路径(相对或绝对路径)..."
/>
<button onclick="readFile()">读取文件</button>
</div>
<div id="fileContent" class="file-content empty">
文件内容将在这里显示...
</div>
<div id="errorMessage" style="display: none;"></div>
</div>
<div id="fileEditorSection" class="file-editor-section">
<h3>✏️ 编辑文件: <span id="editingFileName"></span></h3>
<textarea id="fileEditorTextarea" class="file-editor-textarea"></textarea>
<div class="editor-actions">
<button onclick="saveFile()">保存修改</button>
<button onclick="cancelEdit()" style="background: var(--vscode-button-secondaryBackground); color: var(--vscode-button-secondaryForeground);">取消</button>
</div>
</div>
<div id="messages" class="messages">
<div class="message bot-message">
👋 你好!我是 IC Coder 助手,可以帮你生成代码、回答问题。
</div>
</div>
<div id="messages" class="messages"></div>
<!-- 状态栏 -->
<div id="statusBar" class="status-bar" style="display: none;">
@ -1074,10 +1069,20 @@ export function getWebviewContent(iconUri?: string): string {
div.appendChild(actionsDiv);
} else {
div.textContent = text;
// 当添加用户消息时,隐藏 header
hideHeaderIfNeeded();
}
messagesEl.appendChild(div);
messagesEl.scrollTop = messagesEl.scrollHeight;
// 添加消息后检查 header 显示状态
checkHeaderVisibility();
}
// 检查是否需要隐藏 header
function hideHeaderIfNeeded() {
checkHeaderVisibility();
}
function copyMessage(text, button) {
@ -1252,6 +1257,23 @@ export function getWebviewContent(iconUri?: string): string {
case 'showQuestion':
showUserQuestion(message.askId, message.question, message.options);
break;
case 'vcdGenerated':
// VCD 文件生成成功,显示带波形预览的消息
const messageDiv = document.createElement('div');
messageDiv.className = 'message bot-message';
const messageContent = document.createElement('div');
messageContent.textContent = message.text;
messageDiv.appendChild(messageContent);
// 添加波形预览组件
if (message.vcdFilePath && message.fileName) {
addWaveformPreviewToMessage(messageDiv, message.vcdFilePath, message.fileName);
}
messagesEl.appendChild(messageDiv);
messagesEl.scrollTop = messagesEl.scrollHeight;
break;
case 'fileContent':
displayFileContent(message.content, message.filePath);
break;
@ -1267,6 +1289,38 @@ export function getWebviewContent(iconUri?: string): string {
case 'fileUpdateError':
addMessage(\`\${message.error}\`, 'bot');
break;
case 'vcdInfo':
// 接收到 VCD 文件信息,渲染波形预览
if (message.containerId && message.vcdInfo) {
renderWaveformInfo(message.containerId, message.vcdInfo);
}
break;
case 'conversationHistory':
// 接收到会话历史数据
if (message.history) {
renderConversationHistory(message.history);
}
break;
case 'conversationLoaded':
// 会话加载成功,清空当前消息并显示历史消息
messagesEl.innerHTML = '';
if (message.messages && message.messages.length > 0) {
message.messages.forEach(msg => {
addMessage(msg.text, msg.sender);
});
}
currentConversationId = message.conversationId;
break;
case 'newConversationCreated':
// 新会话创建成功,清空消息区域
messagesEl.innerHTML = '';
currentConversationId = message.conversationId;
// 显示 header
const header = document.querySelector('.header');
if (header) {
header.classList.remove('hidden');
}
break;
}
});
@ -1553,7 +1607,24 @@ export function getWebviewContent(iconUri?: string): string {
// 初始化时调整一次高度
autoResizeTextarea();
// 初始化时检查是否需要显示 header
checkHeaderVisibility();
messageInput.focus();
// 检查 header 显示状态
function checkHeaderVisibility() {
const allMessages = messagesEl.querySelectorAll('.message');
const header = document.querySelector('.header');
if (allMessages.length > 0 && header) {
header.classList.add('hidden');
} else if (header) {
header.classList.remove('hidden');
}
}
${getWaveformPreviewScript()}
${getConversationHistoryBarScript()}
</script>
</body>
</html>`;