refactor(vscode-ide-companion): 优化代码结构和性能

- 移除未使用的依赖项 qwen-code
- 优化 completion 刷新逻辑,避免渲染循环
- 更新 CompletionMenu 组件,增加空状态提示
This commit is contained in:
yiliang114
2025-11-28 10:04:29 +08:00
parent 9cc48f12da
commit 627f5fb43a
3 changed files with 30 additions and 29 deletions

View File

@@ -2323,12 +2323,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
License text not found.
============================================================
@qwen-code/qwen-code@undefined
(git+https://github.com/QwenLM/qwen-code.git)
License text not found.
============================================================
react@19.1.0
(https://github.com/facebook/react.git)

View File

@@ -138,11 +138,16 @@ export const App: React.FC = () => {
const completion = useCompletionTrigger(inputFieldRef, getCompletionItems);
// When workspace files update while menu open for @, refresh items so the first @ shows the list
// Note: Avoid depending on the entire `completion` object here, since its identity
// changes on every render which would retrigger this effect and can cause a refresh loop.
useEffect(() => {
if (completion.isOpen && completion.triggerChar === '@') {
// Only refresh items; do not change other completion state to avoid re-renders loops
completion.refreshCompletion();
}
}, [fileContext.workspaceFiles, completion]);
// Only re-run when the actual data source changes, not on every render
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fileContext.workspaceFiles, completion.isOpen, completion.triggerChar]);
// Message submission
const handleSubmit = useMessageSubmit({

View File

@@ -97,9 +97,7 @@ export const CompletionMenu: React.FC<CompletionMenuProps> = ({
}
}, [selected]);
if (items.length === 0) {
return null;
}
const isEmpty = items.length === 0;
return (
<div
@@ -111,27 +109,31 @@ export const CompletionMenu: React.FC<CompletionMenuProps> = ({
}}
>
<div className="completion-menu-items">
{items.map((item, index) => (
<div
key={item.id}
data-index={index}
className={`completion-menu-item ${index === selected ? 'selected' : ''}`}
onClick={() => onSelect(item)}
onMouseEnter={() => setSelected(index)}
>
{item.icon && (
<div className="completion-item-icon">{item.icon}</div>
)}
<div className="completion-item-content">
<div className="completion-item-label">{item.label}</div>
{item.description && (
<div className="completion-item-description">
{item.description}
</div>
{isEmpty ? (
<div className="completion-menu-empty">Type to search files</div>
) : (
items.map((item, index) => (
<div
key={item.id}
data-index={index}
className={`completion-menu-item ${index === selected ? 'selected' : ''}`}
onClick={() => onSelect(item)}
onMouseEnter={() => setSelected(index)}
>
{item.icon && (
<div className="completion-item-icon">{item.icon}</div>
)}
<div className="completion-item-content">
<div className="completion-item-label">{item.label}</div>
{item.description && (
<div className="completion-item-description">
{item.description}
</div>
)}
</div>
</div>
</div>
))}
))
)}
</div>
</div>
);