Skip to content

Commit d9f92e7

Browse files
committed
fix(textarea): handle removal of duplicate mentions
1 parent e45375e commit d9f92e7

File tree

4 files changed

+405
-125
lines changed

4 files changed

+405
-125
lines changed

webview-ui/src/components/chat/ChatContextBar.tsx

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ interface ContextItem {
1010
originalIndex: number
1111
iconAlt: string
1212
iconStyle?: React.CSSProperties
13+
nodeKey?: string // Only for mention items
1314
}
1415

1516
interface ChatContextBarProps {
@@ -50,6 +51,7 @@ export const ChatContextBar = ({
5051
displayName: mention.displayName,
5152
originalIndex: index,
5253
iconAlt,
54+
nodeKey: mention.nodeKey,
5355
})
5456
})
5557

@@ -86,38 +88,46 @@ export const ChatContextBar = ({
8688

8789
return (
8890
<div className="flex items-center flex-wrap gap-1 mb-2">
89-
{contextItems.map((item, index) => (
90-
<div
91-
key={`${item.type}-${item.originalIndex}`}
92-
className={cn(
93-
"relative flex items-center gap-1 px-2 py-1 border",
94-
"bg-vscode-input-background text-vscode-input-foreground",
95-
"rounded text-xs whitespace-nowrap flex-shrink-0 cursor-pointer",
96-
"hover:bg-vscode-list-hoverBackground",
97-
)}
98-
onMouseEnter={() => setHoveredIndex(index)}
99-
onMouseLeave={() => setHoveredIndex(null)}>
100-
{hoveredIndex === index ? (
101-
<button
102-
onClick={(e) => {
103-
e.stopPropagation()
104-
handleRemove(item)
105-
setHoveredIndex(null)
106-
}}
107-
className="flex shrink-0 items-center justify-center cursor-pointer">
108-
<X className="size-3 text-vscode-input-foreground" />
109-
</button>
110-
) : (
111-
<img
112-
src={item.icon}
113-
alt={item.iconAlt}
114-
className="size-3 shrink-0"
115-
style={{ ...item.iconStyle }}
116-
/>
117-
)}
118-
<span>{item.displayName}</span>
119-
</div>
120-
))}
91+
{contextItems.map((item, index) => {
92+
// Use nodeKey for mentions, fallback to type-index for images
93+
const uniqueKey =
94+
item.type === "mention" && item.nodeKey
95+
? `mention-${item.nodeKey}`
96+
: `${item.type}-${item.originalIndex}`
97+
98+
return (
99+
<div
100+
key={uniqueKey}
101+
className={cn(
102+
"relative flex items-center gap-1 px-2 py-1 border",
103+
"bg-vscode-input-background text-vscode-input-foreground",
104+
"rounded text-xs whitespace-nowrap flex-shrink-0 cursor-pointer",
105+
"hover:bg-vscode-list-hoverBackground",
106+
)}
107+
onMouseEnter={() => setHoveredIndex(index)}
108+
onMouseLeave={() => setHoveredIndex(null)}>
109+
{hoveredIndex === index ? (
110+
<button
111+
onClick={(e) => {
112+
e.stopPropagation()
113+
handleRemove(item)
114+
setHoveredIndex(null)
115+
}}
116+
className="flex shrink-0 items-center justify-center cursor-pointer">
117+
<X className="size-3 text-vscode-input-foreground" />
118+
</button>
119+
) : (
120+
<img
121+
src={item.icon}
122+
alt={item.iconAlt}
123+
className="size-3 shrink-0"
124+
style={{ ...item.iconStyle }}
125+
/>
126+
)}
127+
<span>{item.displayName}</span>
128+
</div>
129+
)
130+
})}
121131
</div>
122132
)
123133
}

0 commit comments

Comments
 (0)