add context by menu

This commit is contained in:
bobo.yang 2023-05-04 13:50:06 +08:00 committed by Rankin Zheng
parent 2799d30c08
commit 4b842048a8
7 changed files with 192 additions and 1 deletions

View File

@ -179,3 +179,37 @@ pre {
#send-button:hover {
background-color: var(--vscode-button-hover-bg);
}
.popup-context-menu {
display: none;
position: absolute;
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding: 12px 16px;
z-index: 1;
}
.popup-context-menu a {
color: black;
text-decoration: none;
display: block;
}
.popup-context-menu a:hover {
background-color: #f1f1f1;
}
.popup-command-menu {
display: none;
position: absolute;
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding: 12px 16px;
z-index: 1;
}
.popup-command-menu a {
color: black;
text-decoration: none;
display: block;
}
.popup-command-menu a:hover {
background-color: #f1f1f1;
}

View File

@ -24,7 +24,9 @@
<div id="input-resize-handle" class="input-resize-handle"></div>
<div id="input-container">
<textarea id="message-input" placeholder="Type your message..."></textarea>
<button id="send-button">Send</button>
<button id="add-context-button">+</button>
<div id="popupContextMenu" class="popup-context-menu"></div><button id="add-command-button">Commands</button>
<div id="popupCommandMenu" class="popup-command-menu"></div><button id="send-button">Send</button>
</div>
</div>

View File

@ -19,6 +19,13 @@ autoResizeTextarea();
function initInputContainer() {
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const addContextButton = document.getElementById('add-context-button');
const addCommandButton = document.getElementById('add-command-button');
const popupContextMenu = document.getElementById('popupContextMenu');
const popupCommandMenu = document.getElementById('popupCommandMenu');
let contextList = [];
let commandList = [];
messageInput.addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
@ -54,6 +61,20 @@ function initInputContainer() {
}
});
addContextButton.addEventListener('click', (event) => {
popupContextMenu.style.display = popupContextMenu.style.display === 'block' ? 'none' : 'block';
// 设置弹出菜单的位置
popupContextMenu.style.left = event.pageX + 'px';
popupContextMenu.style.top = event.pageY + 'px';
});
addCommandButton.addEventListener('click', (event) => {
popupCommandMenu.style.display = popupCommandMenu.style.display === 'block' ? 'none' : 'block';
// 设置弹出菜单的位置
popupCommandMenu.style.left = event.pageX + 'px';
popupCommandMenu.style.top = event.pageY + 'px';
});
messageUtil.registerHandler('file_select', (message) => {
addFileToMessageInput(message.filePath);
});
@ -61,6 +82,73 @@ function initInputContainer() {
messageUtil.registerHandler('code_select', (message) => {
addCodeToMessageInput(message.codeBlock);
});
messageUtil.registerHandler('appendContext', (message) => {
addCodeToMessageInput(message.context);
});
messageUtil.registerHandler('regContextList', (message) => {
contextList = message.result;
const menuItems = [];
for (let i = 0; i < contextList.length; i++) {
menuItems.push({
text: contextList[i].name,
href: contextList[i].name
});
}
menuItems.forEach(item => {
const menuItem = document.createElement('a');
menuItem.textContent = 'add ' + item.text;
menuItem.href = item.text;
popupContextMenu.appendChild(menuItem);
// 为每个菜单项添加点击事件监听器
menuItem.addEventListener('click', (event) => {
// 阻止<a>标签的默认行为(例如导航到链接)
event.preventDefault();
// 在此处定义点击处理逻辑
messageUtil.sendMessage({command: 'addContext', selected: item.href})
// 隐藏弹出菜单
popupContextMenu.style.display = 'none';
});
});
});
messageUtil.registerHandler('regCommandList', (message) => {
commandList = message.result;
const menuItems = [];
for (let i = 0; i < commandList.length; i++) {
menuItems.push({
text: commandList[i].pattern,
href: commandList[i].pattern
});
}
menuItems.forEach(item => {
const menuItem = document.createElement('a');
menuItem.textContent = item.text;
menuItem.href = item.href;
popupCommandMenu.appendChild(menuItem);
// 为每个菜单项添加点击事件监听器
menuItem.addEventListener('click', (event) => {
// 阻止<a>标签的默认行为(例如导航到链接)
event.preventDefault();
// 在此处定义点击处理逻辑
addCodeToMessageInput("/" + item.href);
// 隐藏弹出菜单
popupCommandMenu.style.display = 'none';
});
});
});
messageUtil.sendMessage({command: 'regContextList'});
messageUtil.sendMessage({command: 'regCommandList'});
}
function addFileToMessageInput(filePath) {

41
src/contextManager.ts Normal file
View File

@ -0,0 +1,41 @@
export interface ChatContext {
name: string;
description: string;
handler: () => Promise<string>;
}
class ChatContextManager {
private static instance: ChatContextManager;
private contexts: ChatContext[] = [];
private constructor() {}
public static getInstance(): ChatContextManager {
if (!ChatContextManager.instance) {
ChatContextManager.instance = new ChatContextManager();
}
return ChatContextManager.instance;
}
registerContext(context: ChatContext): void {
this.contexts.push(context);
}
getContextList(): ChatContext[] {
return this.contexts;
}
async processText(command: string): Promise<string> {
// 处理所有命令
for (const contextObj of this.contexts) {
if (contextObj.name == command) {
return await contextObj.handler();
}
}
return '';
}
}
export default ChatContextManager;

9
src/exampleContext.ts Normal file
View File

@ -0,0 +1,9 @@
import { ChatContext } from './contextManager';
export const exampleContext: ChatContext = {
name: 'exampleContext',
description: '这是一个示例上下文',
handler: async () => {
return `[context|example file name]`;
},
};

7
src/loadContexts.ts Normal file
View File

@ -0,0 +1,7 @@
import ChatContextManager from './contextManager';
import { exampleContext } from './exampleContext';
const chatContextManager = ChatContextManager.getInstance();
// 注册命令
chatContextManager.registerContext(exampleContext);

View File

@ -9,7 +9,9 @@ import DtmWrapper from './dtm';
import applyCode, {applyCodeFile} from './applyCode';
import './loadCommands';
import './loadContexts'
import CommandManager, { Command } from './commandManager';
import ChatContextManager from './contextManager';
import * as vscode3 from 'vscode';
@ -178,6 +180,14 @@ async function handleMessage(
vscode.window.showErrorMessage(`Error commit fail: ${commitResult.message} ${commitResult.log}`);
}
return;
case 'regContextList':
const contextList = ChatContextManager.getInstance().getContextList();
panel.webview.postMessage({ command: 'regContextList', result: contextList });
return;
case 'addContext':
const contextStr = await ChatContextManager.getInstance().processText(message.selected);
panel.webview.postMessage({ command: 'appendContext', context: contextStr });
return;
}
}