{
- console.log("[handlePlanAction] action:", action, "planTitle:", planTitle, "serviceTier:", serviceTier);
+ console.log(
+ "[handlePlanAction] action:",
+ action,
+ "planTitle:",
+ planTitle,
+ "serviceTier:",
+ serviceTier
+ );
switch (action) {
case "confirm":
diff --git a/src/views/contextButton.ts b/src/views/contextButton.ts
index 621069b..20bb559 100644
--- a/src/views/contextButton.ts
+++ b/src/views/contextButton.ts
@@ -14,9 +14,7 @@ export function getContextButtonContent(): string {
添加上下文
-
+
添加文件、文件夹、图片或文档作为上下文
diff --git a/src/views/exampleShowcase.ts b/src/views/exampleShowcase.ts
new file mode 100644
index 0000000..1d8ff39
--- /dev/null
+++ b/src/views/exampleShowcase.ts
@@ -0,0 +1,216 @@
+/**
+ * 获取展示区域的 HTML 内容
+ */
+export function getExampleShowcaseContent(): string {
+ return `
+
+
展示
+
+
+
📝
+
+
代码生成
+
生成一个 8 位全加器的 Verilog 代码
+
+
+
+
+
🔍
+
+
代码分析
+
分析当前项目中的时序逻辑设计
+
+
+
+
+
+
+ `;
+}
+
+/**
+ * 获取展示区域的样式
+ */
+export function getExampleShowcaseStyles(): string {
+ return `
+ .example-showcase {
+ margin-top: 24px;
+ padding: 0;
+ opacity: 1;
+ transition: opacity 0.3s ease;
+ }
+
+ .example-showcase.hidden {
+ display: none;
+ }
+
+ .showcase-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--vscode-foreground);
+ margin-bottom: 12px;
+ text-align: left;
+ }
+
+ .example-cards {
+ display: flex;
+ flex-direction: row;
+ gap: 12px;
+ margin-bottom: 20px;
+ }
+
+ .example-card {
+ flex: 1;
+ min-width: 0;
+ background: var(--vscode-input-background);
+ border: 1px solid var(--vscode-input-border);
+ border-radius: 8px;
+ padding: 14px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 12px;
+ }
+
+ .example-card:hover {
+ border-color: var(--vscode-focusBorder);
+ background: var(--vscode-list-hoverBackground);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ }
+
+ .example-icon {
+ font-size: 28px;
+ line-height: 1;
+ flex-shrink: 0;
+ }
+
+ .example-content {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ flex: 1;
+ min-width: 0;
+ }
+
+ .example-title {
+ font-size: 13px;
+ font-weight: 600;
+ color: var(--vscode-foreground);
+ }
+
+ .example-desc {
+ font-size: 11px;
+ color: var(--vscode-descriptionForeground);
+ line-height: 1.4;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ }
+
+ .web-link {
+ display: flex;
+ justify-content: center;
+ padding-top: 20px;
+ border-top: 1px solid var(--vscode-panel-border);
+ margin-top: 8px;
+ }
+
+ .web-link-button {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 10px 20px;
+ background: transparent;
+ border: none;
+ text-decoration: none;
+ font-size: 14px;
+ font-weight: 600;
+ transition: all 0.2s ease;
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 50%, #a855f7 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ outline: none;
+ }
+
+ .web-link-button:focus {
+ outline: none;
+ }
+
+ .web-link-button:hover {
+ transform: translateY(-1px);
+ opacity: 0.8;
+ }
+
+ .link-icon {
+ font-size: 16px;
+ }
+
+ .link-arrow {
+ font-size: 16px;
+ transition: transform 0.2s ease;
+ }
+
+ .web-link-button:hover .link-arrow {
+ transform: translateX(3px);
+ }
+ `;
+}
+
+/**
+ * 获取展示区域的脚本
+ */
+export function getExampleShowcaseScript(): string {
+ return `
+ // 示例文本数组
+ const exampleTexts = [
+ '生成一个 8 位全加器的 Verilog 代码',
+ '分析当前项目中的时序逻辑设计'
+ ];
+
+ // 填充示例到输入框
+ function fillExample(index) {
+ const messageInput = document.getElementById('messageInput');
+ if (messageInput && exampleTexts[index]) {
+ messageInput.value = exampleTexts[index];
+ messageInput.focus();
+ // 触发自动调整高度
+ if (typeof autoResizeTextarea === 'function') {
+ autoResizeTextarea();
+ }
+ }
+ }
+
+ // 监听消息变化,自动隐藏/显示展示区域
+ function updateShowcaseVisibility() {
+ const showcase = document.getElementById('exampleShowcase');
+ if (showcase) {
+ if (hasMessages) {
+ showcase.classList.add('hidden');
+ } else {
+ showcase.classList.remove('hidden');
+ }
+ }
+ }
+
+ // 扩展原有的布局更新函数
+ const originalUpdateInputAreaLayout = updateInputAreaLayout;
+ updateInputAreaLayout = function() {
+ if (originalUpdateInputAreaLayout) {
+ originalUpdateInputAreaLayout();
+ }
+ updateShowcaseVisibility();
+ };
+ `;
+}
diff --git a/src/views/inputArea.ts b/src/views/inputArea.ts
index 8aa6815..9baa1bd 100644
--- a/src/views/inputArea.ts
+++ b/src/views/inputArea.ts
@@ -29,16 +29,21 @@ import {
getOptimizeButtonStyles,
getOptimizeButtonScript,
} from "./optimizeButton";
+import {
+ getExampleShowcaseContent,
+ getExampleShowcaseStyles,
+ getExampleShowcaseScript,
+} from "./exampleShowcase";
import { sendIconSvg, stopIconSvg } from "../constants/toolIcons";
/**
* 获取输入区域的 HTML 内容
*/
export function getInputAreaContent(
- autoIcon: string = '',
- liteIcon: string = '',
- syIcon: string = '',
- maxIcon: string = ''
+ autoIcon: string = "",
+ liteIcon: string = "",
+ syIcon: string = "",
+ maxIcon: string = ""
): string {
return `
@@ -71,6 +76,8 @@ export function getInputAreaContent(
+
+ ${getExampleShowcaseContent()}
`;
}
@@ -86,6 +93,7 @@ export function getInputAreaStyles(): string {
${getContextDisplayStyles()}
${getContextCompressStyles()}
${getOptimizeButtonStyles()}
+ ${getExampleShowcaseStyles()}
.input-area {
border-top: 1px solid var(--vscode-panel-border);
padding-top: 15px;
@@ -95,7 +103,7 @@ export function getInputAreaStyles(): string {
/* 居中模式:未发起对话时 */
.input-area.centered {
position: absolute;
- top: 50%;
+ top: 55%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100% - 40px);
@@ -292,6 +300,7 @@ export function getInputAreaScript(): string {
${getContextDisplayScript()}
${getContextCompressScript()}
${getOptimizeButtonScript()}
+ ${getExampleShowcaseScript()}
// 对话状态管理
let isConversationActive = false;
diff --git a/src/views/messageArea.ts b/src/views/messageArea.ts
index 8350e2c..698ee4f 100644
--- a/src/views/messageArea.ts
+++ b/src/views/messageArea.ts
@@ -24,6 +24,7 @@ import {
knowledgeLoadIconSvg,
stateTransitionIconSvg,
userQuestionIconSvg,
+ updateStageIconSvg,
} from "../constants/toolIcons";
import {
getWaveformPreviewContent,
@@ -670,6 +671,7 @@ export function getMessageAreaScript(): string {
const knowledgeLoadIconSvg = \`${knowledgeLoadIconSvg}\`;
const stateTransitionIconSvg = \`${stateTransitionIconSvg}\`;
const userQuestionIconSvg = \`${userQuestionIconSvg}\`;
+ const updateStageIconSvg = \`${updateStageIconSvg}\`;
${getAgentCardScript()}
@@ -724,6 +726,7 @@ export function getMessageAreaScript(): string {
'updateNode': fileWriteIconSvg,
'addStateTransition': stateTransitionIconSvg,
'askUser': userQuestionIconSvg,
+ 'updatePhase': updateStageIconSvg,
};
return iconMap[toolName] || '';
}
@@ -756,6 +759,8 @@ export function getMessageAreaScript(): string {
'spawnExplorer': '代码探索',
'spawnDebugger': '波形调试',
'askUser': '用户提问',
+ 'updatePhase': '已更新阶段',
+ 'iverilog': '已完成编译',
};
return toolNameMap[toolName] || toolName;
}
diff --git a/src/views/planCard.ts b/src/views/planCard.ts
index c83f6f4..706ec37 100644
--- a/src/views/planCard.ts
+++ b/src/views/planCard.ts
@@ -62,9 +62,9 @@ export function getPlanCardStyles(): string {
.plan-summary p { margin: 8px 0; }
.plan-summary ul, .plan-summary ol {
margin: 8px 0;
- padding-left: 24px;
+ padding-left: 0;
}
- .plan-summary li { margin: 4px 0; }
+ .plan-summary li { margin: 4px 0 4px 27px; }
.plan-summary code {
background: var(--vscode-textCodeBlock-background);
padding: 2px 6px;
@@ -403,6 +403,12 @@ export function getPlanCardScript(): string {
.replace(//g, '>');
+ // 标题(必须在转义之后、其他处理之前)
+ html = html.replace(/^#### (.+)$/gm, '$1
');
+ html = html.replace(/^### (.+)$/gm, '$1
');
+ html = html.replace(/^## (.+)$/gm, '$1
');
+ html = html.replace(/^# (.+)$/gm, '$1
');
+
// 代码块 (\`\`\`code\`\`\`)
html = html.replace(/\\x60\\x60\\x60([\\s\\S]*?)\\x60\\x60\\x60/g, '$1
');
@@ -428,12 +434,6 @@ export function getPlanCardScript(): string {
return table;
});
- // 标题
- html = html.replace(/^#### (.+)$/gm, '$1
');
- html = html.replace(/^### (.+)$/gm, '$1
');
- html = html.replace(/^## (.+)$/gm, '$1
');
- html = html.replace(/^# (.+)$/gm, '$1
');
-
// 粗体和斜体
html = html.replace(/\\*\\*(.+?)\\*\\*/g, '$1');
html = html.replace(/\\*(.+?)\\*/g, '$1');
diff --git a/src/views/userInfoComponent.ts b/src/views/userInfoComponent.ts
index 444ad59..95bb043 100644
--- a/src/views/userInfoComponent.ts
+++ b/src/views/userInfoComponent.ts
@@ -250,14 +250,27 @@ export function getUserInfoComponentScript(): string {
// 更新剩余 Credits
const creditsDetail = document.getElementById('creditsDetail');
+ console.log('[UserInfoComponent] 更新 Credits 显示');
+ console.log('[UserInfoComponent] currentUserInfo.credits:', currentUserInfo.credits);
+ console.log('[UserInfoComponent] creditsDetail 元素:', creditsDetail);
if (creditsDetail) {
- creditsDetail.textContent = currentUserInfo.credits !== undefined ? currentUserInfo.credits.toString() : '-';
+ const creditsText = currentUserInfo.credits !== undefined ? currentUserInfo.credits.toString() : '-';
+ creditsDetail.textContent = creditsText;
+ console.log('[UserInfoComponent] Credits 已更新为:', creditsText);
+ } else {
+ console.warn('[UserInfoComponent] creditsDetail 元素未找到');
}
}
// 更新用户信息显示
function updateUserInfoDisplay(userInfo) {
currentUserInfo = userInfo;
+ console.log('[UserInfoComponent] 更新用户信息:', userInfo);
+ // 如果下拉面板已打开,立即更新显示
+ const dropdown = document.getElementById('userDetailDropdown');
+ if (dropdown && dropdown.classList.contains('active')) {
+ updateUserDetailModal();
+ }
}
// 绑定下拉面板事件
diff --git a/src/views/waveformPreviewContent.ts b/src/views/waveformPreviewContent.ts
index 73135ea..83568dd 100644
--- a/src/views/waveformPreviewContent.ts
+++ b/src/views/waveformPreviewContent.ts
@@ -174,7 +174,7 @@ export function getWaveformPreviewScript(): string {
const content = document.createElement('div');
content.className = 'waveform-preview-content';
- const miniViewerId = 'waveform-mini-' + Date.now();
+ const miniViewerId = 'waveform-mini-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
const miniViewer = document.createElement('div');
miniViewer.id = miniViewerId;
miniViewer.className = 'waveform-mini-viewer';
diff --git a/src/views/webviewContent.ts b/src/views/webviewContent.ts
index 9cd5e20..a4d03be 100644
--- a/src/views/webviewContent.ts
+++ b/src/views/webviewContent.ts
@@ -588,20 +588,25 @@ export function getWebviewContent(
case 'updateUserInfo':
// 更新用户信息
console.log('[WebView] 收到用户信息:', message.userInfo);
+ console.log('[WebView] Credits 字段值:', message.userInfo?.credits);
if (message.userInfo) {
const userInfoData = {
nickname: message.userInfo.nickname || message.userInfo.username || '用户',
userId: message.userInfo.userId || message.userInfo.id,
tierName: message.userInfo.tierName,
tierIconUrl: message.tierIconUrl,
- registerTime: message.userInfo.registerTime || message.userInfo.createdAt
+ registerTime: message.userInfo.registerTime || message.userInfo.createdAt,
+ credits: message.userInfo.credits
};
console.log('[WebView] 显示用户信息:', userInfoData);
+ console.log('[WebView] userInfoData.credits:', userInfoData.credits);
// 调用更新用户头像图标按钮的函数
if (typeof updateUserAvatarIconButton === 'function') {
updateUserAvatarIconButton(userInfoData);
+ } else {
+ console.warn('[WebView] updateUserAvatarIconButton 函数不存在');
}
}
break;