Repository navigation
feat(chat): restructure user bubble, drop role labels #1984
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9e2a967
5890d61
53340bb
cf1eb83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -58,7 +58,6 @@ | |||
| Eye, | ||||
| FileDiff, | ||||
| ListTree, | ||||
| User, | ||||
| Edit, | ||||
| Trash2, | ||||
| MessageCircleQuestionMark, | ||||
|
|
@@ -67,7 +66,6 @@ | |||
| PocketKnife, | ||||
| FolderTree, | ||||
| SquareTerminal, | ||||
| MessageCircle, | ||||
| Repeat2, | ||||
| Split, | ||||
| ArrowRight, | ||||
|
|
@@ -1208,13 +1206,10 @@ | |||
| case "text": | ||||
| return ( | ||||
| <div className="group"> | ||||
| <div style={headerStyle}> | ||||
| <MessageCircle className="w-4 shrink-0" aria-label="Speech bubble icon" /> | ||||
| <span style={{ fontWeight: "bold" }}>{t("chat:text.rooSaid")}</span> | ||||
| <div style={{ flexGrow: 1 }} /> | ||||
| <OpenMarkdownPreviewButton markdown={message.text} /> | ||||
| </div> | ||||
| <div className="pl-6"> | ||||
| <div className="pl-6 relative"> | ||||
| <div className="absolute top-0 right-0 z-10"> | ||||
| <OpenMarkdownPreviewButton markdown={message.text} /> | ||||
| </div> | ||||
|
Comment on lines
+1210
to
+1212
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Reserve space for the preview button. When complex markdown starts with a long heading or line, its text can extend beneath this absolutely positioned, 🤖 Prompt for AI Agents |
||||
| <Markdown markdown={message.text} partial={message.partial} /> | ||||
| {message.images && message.images.length > 0 && ( | ||||
| <div style={{ marginTop: "10px" }}> | ||||
|
|
@@ -1228,17 +1223,13 @@ | |||
| ) | ||||
| case "user_feedback": | ||||
| return ( | ||||
| <div className="group"> | ||||
| <div style={headerStyle}> | ||||
| <User className="w-4 shrink-0" aria-label="User icon" /> | ||||
| <span style={{ fontWeight: "bold" }}>{t("chat:feedback.youSaid")}</span> | ||||
| </div> | ||||
| <div className="group w-fit max-w-[70%] ml-auto flex flex-col items-end gap-1"> | ||||
| <div | ||||
| className={cn( | ||||
| "ml-6 border rounded-sm overflow-hidden whitespace-pre-wrap", | ||||
| "border rounded-sm overflow-hidden whitespace-pre-wrap", | ||||
| isEditing | ||||
| ? "bg-vscode-editor-background text-vscode-editor-foreground" | ||||
| : "cursor-text p-1 bg-vscode-editor-foreground/70 text-vscode-editor-background", | ||||
| : "cursor-text p-1 bg-vscode-list-hoverBackground text-vscode-foreground", | ||||
| )}> | ||||
| {isEditing ? ( | ||||
| <div className="flex flex-col gap-2"> | ||||
|
|
@@ -1261,50 +1252,67 @@ | |||
| /> | ||||
| </div> | ||||
| ) : ( | ||||
| <div className="flex justify-between"> | ||||
| <div | ||||
| className="flex-grow px-2 py-1 wrap-anywhere rounded-lg transition-colors" | ||||
| onClick={(e) => { | ||||
| e.stopPropagation() | ||||
| if (!isStreaming) { | ||||
| handleEditClick() | ||||
| } | ||||
| }} | ||||
| title={t("chat:queuedMessages.clickToEdit")}> | ||||
| <Mention text={message.text} withShadow /> | ||||
| </div> | ||||
| <div className="flex gap-2 pr-1"> | ||||
| <div | ||||
| className="cursor-pointer shrink-0 opacity-0 group-hover:opacity-100 transition-opacity" | ||||
| style={{ visibility: isStreaming ? "hidden" : "visible" }} | ||||
| onClick={(e) => { | ||||
| e.stopPropagation() | ||||
| handleEditClick() | ||||
| }}> | ||||
| <Edit className="w-4 shrink-0" aria-label="Edit message icon" /> | ||||
| </div> | ||||
| <div | ||||
| className="cursor-pointer shrink-0 opacity-0 group-hover:opacity-100 transition-opacity" | ||||
| style={{ visibility: isStreaming ? "hidden" : "visible" }} | ||||
| onClick={(e) => { | ||||
| e.stopPropagation() | ||||
| vscode.postMessage({ type: "deleteMessage", value: message.ts }) | ||||
| }}> | ||||
| <Trash2 className="w-4 shrink-0" aria-label="Delete message icon" /> | ||||
| </div> | ||||
| </div> | ||||
| <div | ||||
| className="px-2 py-1 wrap-anywhere rounded-lg transition-colors" | ||||
| role="button" | ||||
| tabIndex={isStreaming ? -1 : 0} | ||||
|
Check warning on line 1258 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| aria-disabled={isStreaming || undefined} | ||||
|
Check warning on line 1259 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| aria-label={t("chat:queuedMessages.clickToEdit")} | ||||
|
Check warning on line 1260 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
The bubble has Remove Proposed fix--- "a/webview-ui/src/components/chat/ChatRow.tsx"
+++ "b/webview-ui/src/components/chat/ChatRow.tsx"
@@ -1256,8 +1256,7 @@
className="px-2 py-1 wrap-anywhere rounded-lg transition-colors"
role="button"
tabIndex={isStreaming ? -1 : 0}
aria-disabled={isStreaming || undefined}
- aria-label={t("chat:queuedMessages.clickToEdit")}
onClick={(e) => {
e.stopPropagation()
if (!isStreaming) {📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: mutation-diff[warning] 1260-1260: Mutation test advisory 🤖 Prompt for AI Agents |
||||
| onClick={(e) => { | ||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||
| e.stopPropagation() | ||||
|
Check warning on line 1262 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| if (!isStreaming) { | ||||
| handleEditClick() | ||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||
| } | ||||
| }} | ||||
| onKeyDown={(e) => { | ||||
|
Check warning on line 1267 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| if (isStreaming) { | ||||
|
Check warning on line 1268 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| return | ||||
| } | ||||
| if (e.key === "Enter" || e.key === " ") { | ||||
|
Check warning on line 1271 in webview-ui/src/components/chat/ChatRow.tsx
|
||||
| e.preventDefault() | ||||
| handleEditClick() | ||||
| } | ||||
| }} | ||||
| title={t("chat:queuedMessages.clickToEdit")}> | ||||
| <Mention text={message.text} withShadow /> | ||||
| </div> | ||||
| )} | ||||
| {!isEditing && message.images && message.images.length > 0 && ( | ||||
| <Thumbnails images={message.images} style={{ marginTop: "8px" }} /> | ||||
| )} | ||||
| </div> | ||||
| {!isEditing && ( | ||||
| <div className="flex gap-2 pr-1"> | ||||
| <button | ||||
| type="button" | ||||
| className="cursor-pointer shrink-0 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 transition-opacity rounded-sm focus-visible:outline focus-visible:outline-1 focus-visible:outline-vscode-focusBorder" | ||||
| style={{ visibility: isStreaming ? "hidden" : "visible" }} | ||||
| aria-label={t("common:confirmation.editMessage")} | ||||
| onClick={(e) => { | ||||
| e.stopPropagation() | ||||
| handleEditClick() | ||||
| }}> | ||||
| <Edit className="w-4 shrink-0" aria-hidden="true" /> | ||||
| </button> | ||||
| <button | ||||
| type="button" | ||||
| className="cursor-pointer shrink-0 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 transition-opacity rounded-sm focus-visible:outline focus-visible:outline-1 focus-visible:outline-vscode-focusBorder" | ||||
| style={{ visibility: isStreaming ? "hidden" : "visible" }} | ||||
| aria-label={t("common:confirmation.deleteMessage")} | ||||
| onClick={(e) => { | ||||
| e.stopPropagation() | ||||
| vscode.postMessage({ type: "deleteMessage", value: message.ts }) | ||||
| }}> | ||||
| <Trash2 className="w-4 shrink-0" aria-hidden="true" /> | ||||
| </button> | ||||
| </div> | ||||
| )} | ||||
| </div> | ||||
| ) | ||||
| case "user_feedback_diff": | ||||
| const tool = safeJsonParse<ClineSayTool>(message.text) | ||||
| return ( | ||||
| <div style={{ marginTop: -10, width: "100%" }}> | ||||
| <div className="max-w-[70%] ml-auto" style={{ marginTop: -10, width: "100%" }}> | ||||
| <CodeAccordion | ||||
| code={tool?.diff} | ||||
| language="diff" | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 6892
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 14364
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 3142
Add an accessible sender name to each unlabeled turn.
ChatRowwrapsChatRowContentin an unlabeleddiv, andChatViewrendersChatRowdirectly for each message. Thetextanduser_feedbackbranches also use unlabeleddivroots. After removing the visible headers, screen-reader users cannot identify the sender. Add a localized accessible name based onmessage.typewithout restoring the visible headers.🤖 Prompt for AI Agents
Source: Path instructions