/** * 添加上下文按钮组件 */ /** * 获取添加上下文按钮的 HTML 内容 */ export function getContextButtonContent(): string { return `
添加文件、文件夹作为上下文
文件
文件夹
`; } /** * 获取添加上下文按钮的样式 */ export function getContextButtonStyles(): string { return ` /* 上下文选择器容器 */ .context-selector-wrapper { position: relative; display: inline-block; } /* 添加上下文按钮样式 */ .add-context-button { display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: rgba(128, 128, 128, 0.2); border: 1px solid var(--vscode-input-border); border-radius: 6px; color: var(--vscode-foreground); cursor: pointer; transition: all 0.2s ease; font-size: 13px; font-weight: 500; } .add-context-button:hover { background: rgba(128, 128, 128, 0.3); border-color: var(--vscode-focusBorder); } .add-context-button svg.icon { width: 16px; height: 16px; color: #409eff; } .add-context-button .dropdown-arrow { width: 12px; height: 12px; transition: transform 0.2s ease; } .add-context-button.active .dropdown-arrow { transform: rotate(180deg); } .add-context-label { white-space: nowrap; } /* 上拉菜单样式 */ .context-menu { position: absolute; bottom: calc(100% + 8px); left: 0; background: var(--vscode-dropdown-background); border: 1px solid var(--vscode-dropdown-border); border-radius: 6px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); min-width: 180px; z-index: 1000; display: none; overflow: hidden; } .context-menu.show { display: block; animation: slideUp 0.2s ease; } @keyframes slideUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .context-menu-item { display: flex; align-items: center; gap: 12px; padding: 10px 16px; cursor: pointer; transition: background 0.2s ease; color: var(--vscode-foreground); } .context-menu-item:hover { background: var(--vscode-list-hoverBackground); } .context-menu-item svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--vscode-foreground); opacity: 0.8; } .context-menu-item span { font-size: 13px; white-space: nowrap; flex: 1; } .context-menu-item .arrow-right { width: 14px; height: 14px; opacity: 0.6; margin-left: auto; } /* 列表视图样式 */ .context-menu-list { display: flex; flex-direction: column; max-height: 350px; } .context-menu-list-header { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--vscode-panel-border); } .context-menu-back { width: 28px; height: 28px; padding: 0; border: none; background: transparent; color: var(--vscode-foreground); cursor: pointer; border-radius: 4px; display: flex; align-items: center; justify-content: center; } .context-menu-back:hover { background: var(--vscode-toolbar-hoverBackground); } .context-menu-back svg { width: 16px; height: 16px; } .context-menu-list-header span { font-size: 14px; font-weight: 500; flex: 1; } .context-menu-list-body { flex: 1; overflow-y: auto; padding: 4px; } .context-menu-list-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; cursor: pointer; border-radius: 4px; transition: background 0.2s ease; } .context-menu-list-item:hover { background: var(--vscode-list-hoverBackground); } .context-menu-list-item.selected { background: var(--vscode-list-activeSelectionBackground); } .context-menu-list-item input[type="checkbox"] { width: 14px; height: 14px; flex-shrink: 0; pointer-events: none; } .context-menu-list-item label { flex: 1; font-size: 12px; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .context-menu-list-footer { padding: 8px 12px; border-top: 1px solid var(--vscode-panel-border); display: flex; flex-direction: column; gap: 8px; } .context-menu-list-footer input { width: 100%; padding: 6px 10px; background: var(--vscode-input-background); border: 1px solid var(--vscode-input-border); border-radius: 4px; color: var(--vscode-input-foreground); font-size: 12px; box-sizing: border-box; } .context-menu-list-actions { display: flex; justify-content: space-between; align-items: center; } .context-menu-list-footer span { font-size: 12px; color: var(--vscode-descriptionForeground); } .context-menu-list-footer button { padding: 4px 12px; background: var(--vscode-button-background); color: var(--vscode-button-foreground); border: none; border-radius: 4px; cursor: pointer; font-size: 12px; } .context-menu-list-footer button:hover { background: var(--vscode-button-hoverBackground); } `; } /** * 获取添加上下文按钮的脚本 */ export function getContextButtonScript(): string { return ` // 上下文菜单状态 let currentListData = []; let filteredListData = []; let currentListType = ''; let selectedItems = new Set(); // 切换上下文菜单显示/隐藏 function toggleContextMenu() { const menu = document.getElementById('contextMenu'); const button = document.querySelector('.add-context-button'); if (menu && button) { const isShown = menu.classList.contains('show'); if (isShown) { menu.classList.remove('show'); button.classList.remove('active'); backToMainMenu(); // 关闭时回到主菜单 } else { menu.classList.add('show'); button.classList.add('active'); } } } // 点击外部关闭菜单 document.addEventListener('click', function(event) { const wrapper = document.querySelector('.context-selector-wrapper'); const menu = document.getElementById('contextMenu'); const button = document.querySelector('.add-context-button'); if (wrapper && menu && button && !wrapper.contains(event.target)) { menu.classList.remove('show'); button.classList.remove('active'); backToMainMenu(); } }); // 显示文件列表 function showFileList() { vscode.postMessage({ command: 'addContextFile' }); } // 显示文件夹列表 function showFolderList() { vscode.postMessage({ command: 'addContextFolder' }); } // 返回主菜单 function backToMainMenu() { const mainMenu = document.getElementById('contextMenuMain'); const listView = document.getElementById('contextMenuList'); if (mainMenu && listView) { mainMenu.style.display = 'block'; listView.style.display = 'none'; } selectedItems.clear(); currentListData = []; filteredListData = []; clearContextSearchInput(); } function clearContextSearchInput() { const searchInput = document.getElementById('contextMenuSearch'); if (searchInput) { searchInput.value = ''; } } // 切换到列表视图 function switchToListView(title, type, data) { const mainMenu = document.getElementById('contextMenuMain'); const listView = document.getElementById('contextMenuList'); const titleEl = document.getElementById('contextMenuListTitle'); if (mainMenu && listView && titleEl) { mainMenu.style.display = 'none'; listView.style.display = 'flex'; titleEl.textContent = title; currentListType = type; currentListData = data || []; filteredListData = currentListData; selectedItems.clear(); clearContextSearchInput(); renderList(filteredListData); updateSelectedCount(); } } // 渲染列表 function renderList(data) { const body = document.getElementById('contextMenuListBody'); if (!body) return; filteredListData = data || []; body.innerHTML = filteredListData.map((item, index) => \`
\`).join(''); } // 切换项选择 function toggleItemSelection(index) { const selectedItem = filteredListData[index]; if (!selectedItem) return; const selectedPath = selectedItem.path; const checkbox = document.getElementById('item-' + index); const item = document.querySelectorAll('.context-menu-list-item')[index]; if (selectedItems.has(selectedPath)) { selectedItems.delete(selectedPath); if (checkbox) checkbox.checked = false; if (item) item.classList.remove('selected'); } else { selectedItems.add(selectedPath); if (checkbox) checkbox.checked = true; if (item) item.classList.add('selected'); } updateSelectedCount(); } // 更新选中数量 function updateSelectedCount() { const countEl = document.getElementById('contextMenuListCount'); if (countEl) { countEl.textContent = '已选择 ' + selectedItems.size + ' 项'; } } // 确认选择 function confirmSelection() { try { const selected = currentListData.filter(item => selectedItems.has(item.path)); if (selected.length > 0) { selected.forEach(item => { addContextItem(currentListType, item.path, item.relativePath || item.path); }); } } finally { const menu = document.getElementById('contextMenu'); const button = document.querySelector('.add-context-button'); if (menu) { menu.classList.remove('show'); } if (button) { button.classList.remove('active'); } backToMainMenu(); } } // 添加图片 function handleAddImage() { vscode.postMessage({ command: 'addContextImage' }); toggleContextMenu(); } // 添加文档 function handleAddDocument() { vscode.postMessage({ command: 'addContextDocument' }); toggleContextMenu(); } // 搜索功能 const searchInput = document.getElementById('contextMenuSearch'); if (searchInput) { searchInput.addEventListener('input', function(e) { const keyword = (e.target.value || '').toLowerCase().trim(); const filtered = currentListData.filter(item => (item.relativePath || item.path || '').toLowerCase().includes(keyword) ); renderList(filtered); }); } // 处理后端消息 window.addEventListener('message', event => { const message = event.data; if (message.command === 'showWorkspaceFileList') { switchToListView('选择文件', 'file', message.files); } else if (message.command === 'showWorkspaceFolderList') { switchToListView('选择文件夹', 'folder', message.folders); } }); `; }