Skip to content

Commit 5edab52

Browse files
committed
fixed image issue
1 parent f89d768 commit 5edab52

File tree

7 files changed

+76
-14
lines changed

7 files changed

+76
-14
lines changed

src/core/webview/webviewMessageHandler.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,24 @@ export const webviewMessageHandler = async (
137137
/**
138138
* Handles message editing operations with user confirmation
139139
*/
140-
const handleEditOperation = async (messageTs: number, editedContent: string): Promise<void> => {
140+
const handleEditOperation = async (messageTs: number, editedContent: string, images?: string[]): Promise<void> => {
141141
// Send message to webview to show edit confirmation dialog
142142
await provider.postMessageToWebview({
143143
type: "showEditMessageDialog",
144144
messageTs,
145145
text: editedContent,
146+
images,
146147
})
147148
}
148149

149150
/**
150151
* Handles confirmed message editing from webview dialog
151152
*/
152-
const handleEditMessageConfirm = async (messageTs: number, editedContent: string): Promise<void> => {
153+
const handleEditMessageConfirm = async (
154+
messageTs: number,
155+
editedContent: string,
156+
images?: string[],
157+
): Promise<void> => {
153158
// Only proceed if we have a current cline
154159
if (provider.getCurrentCline()) {
155160
const currentCline = provider.getCurrentCline()!
@@ -168,6 +173,7 @@ export const webviewMessageHandler = async (
168173
type: "askResponse",
169174
askResponse: "messageResponse",
170175
text: editedContent,
176+
images,
171177
})
172178

173179
// Don't initialize with history item for edit operations
@@ -193,11 +199,12 @@ export const webviewMessageHandler = async (
193199
messageTs: number,
194200
operation: "delete" | "edit",
195201
editedContent?: string,
202+
images?: string[],
196203
): Promise<void> => {
197204
if (operation === "delete") {
198205
await handleDeleteOperation(messageTs)
199206
} else if (operation === "edit" && editedContent) {
200-
await handleEditOperation(messageTs, editedContent)
207+
await handleEditOperation(messageTs, editedContent, images)
201208
}
202209
}
203210

@@ -367,7 +374,12 @@ export const webviewMessageHandler = async (
367374
break
368375
case "selectImages":
369376
const images = await selectImages()
370-
await provider.postMessageToWebview({ type: "selectedImages", images })
377+
await provider.postMessageToWebview({
378+
type: "selectedImages",
379+
images,
380+
context: message.context,
381+
messageTs: message.messageTs,
382+
})
371383
break
372384
case "exportCurrentTask":
373385
const currentTaskId = provider.getCurrentCline()?.taskId
@@ -1144,7 +1156,12 @@ export const webviewMessageHandler = async (
11441156
message.value &&
11451157
message.editedMessageContent
11461158
) {
1147-
await handleMessageModificationsOperation(message.value, "edit", message.editedMessageContent)
1159+
await handleMessageModificationsOperation(
1160+
message.value,
1161+
"edit",
1162+
message.editedMessageContent,
1163+
message.images,
1164+
)
11481165
}
11491166
break
11501167
}
@@ -1484,7 +1501,7 @@ export const webviewMessageHandler = async (
14841501
break
14851502
case "editMessageConfirm":
14861503
if (message.messageTs && message.text) {
1487-
await handleEditMessageConfirm(message.messageTs, message.text)
1504+
await handleEditMessageConfirm(message.messageTs, message.text, message.images)
14881505
}
14891506
break
14901507
case "getListApiConfiguration":

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export interface ExtensionMessage {
160160
rulesFolderPath?: string
161161
settings?: any
162162
messageTs?: number
163+
context?: string
163164
}
164165

165166
export type ExtensionState = Pick<

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ export interface WebviewMessage {
199199
editedMessageContent?: string
200200
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
201201
disabled?: boolean
202+
context?: string
202203
dataUri?: string
203204
askResponse?: ClineAskResponse
204205
apiConfiguration?: ProviderSettings

webview-ui/src/App.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,12 @@ const App = () => {
7979
isOpen: boolean
8080
messageTs: number
8181
text: string
82+
images?: string[]
8283
}>({
8384
isOpen: false,
8485
messageTs: 0,
8586
text: "",
87+
images: [],
8688
})
8789

8890
const settingsRef = useRef<SettingsViewRef>(null)
@@ -145,7 +147,12 @@ const App = () => {
145147
}
146148

147149
if (message.type === "showEditMessageDialog" && message.messageTs && message.text) {
148-
setEditMessageDialogState({ isOpen: true, messageTs: message.messageTs, text: message.text })
150+
setEditMessageDialogState({
151+
isOpen: true,
152+
messageTs: message.messageTs,
153+
text: message.text,
154+
images: message.images || [],
155+
})
149156
}
150157

151158
if (message.type === "acceptInput") {
@@ -253,6 +260,7 @@ const App = () => {
253260
type: "editMessageConfirm",
254261
messageTs: editMessageDialogState.messageTs,
255262
text: editMessageDialogState.text,
263+
images: editMessageDialogState.images,
256264
})
257265
setEditMessageDialogState((prev) => ({ ...prev, isOpen: false }))
258266
}}

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"
2+
import { appendImages } from "@src/utils/imageUtils"
23
import { McpExecution } from "./McpExecution"
34
import { useSize } from "react-use"
45
import { useTranslation, Trans } from "react-i18next"
@@ -22,6 +23,7 @@ import { getLanguageFromPath } from "@src/utils/getLanguageFromPath"
2223
import { Button } from "@src/components/ui"
2324

2425
import ChatTextArea from "./ChatTextArea"
26+
import { MAX_IMAGES_PER_MESSAGE } from "./ChatView"
2527

2628
import { ToolUseBlock, ToolUseBlockHeader } from "../common/ToolUseBlock"
2729
import UpdateTodoListToolBlock from "./UpdateTodoListToolBlock"
@@ -122,6 +124,19 @@ export const ChatRowContent = ({
122124
const [editImages, setEditImages] = useState<string[]>([])
123125
const { copyWithFeedback } = useCopyToClipboard()
124126

127+
// Handle message events for image selection during edit mode
128+
useEffect(() => {
129+
const handleMessage = (event: MessageEvent) => {
130+
const msg = event.data
131+
if (msg.type === "selectedImages" && msg.context === "edit" && msg.messageTs === message.ts && isEditing) {
132+
setEditImages((prevImages) => appendImages(prevImages, msg.images, MAX_IMAGES_PER_MESSAGE))
133+
}
134+
}
135+
136+
window.addEventListener("message", handleMessage)
137+
return () => window.removeEventListener("message", handleMessage)
138+
}, [isEditing, message.ts])
139+
125140
// Memoized callback to prevent re-renders caused by inline arrow functions
126141
const handleToggleExpand = useCallback(() => {
127142
onToggleExpand(message.ts)
@@ -153,13 +168,14 @@ export const ChatRowContent = ({
153168
type: "submitEditedMessage",
154169
value: message.ts,
155170
editedMessageContent: editedContent,
171+
images: editImages,
156172
})
157-
}, [message.ts, editedContent])
173+
}, [message.ts, editedContent, editImages])
158174

159175
// Handle image selection for editing
160176
const handleSelectImages = useCallback(() => {
161-
vscode.postMessage({ type: "selectImages" })
162-
}, [])
177+
vscode.postMessage({ type: "selectImages", context: "edit", messageTs: message.ts })
178+
}, [message.ts])
163179

164180
const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => {
165181
if (message.text !== null && message.text !== undefined && message.say === "api_req_started") {
@@ -1073,7 +1089,7 @@ export const ChatRowContent = ({
10731089
<Button
10741090
variant="ghost"
10751091
size="icon"
1076-
className="shrink-0 hidden"
1092+
className="shrink-0"
10771093
disabled={isStreaming}
10781094
onClick={(e) => {
10791095
e.stopPropagation()

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import useSound from "use-sound"
99
import { LRUCache } from "lru-cache"
1010

1111
import { useDebounceEffect } from "@src/utils/useDebounceEffect"
12+
import { appendImages } from "@src/utils/imageUtils"
1213

1314
import type { ClineAsk, ClineMessage } from "@roo-code/types"
1415

@@ -712,10 +713,11 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
712713
}
713714
break
714715
case "selectedImages":
715-
const newImages = message.images ?? []
716-
if (newImages.length > 0) {
716+
// Only handle selectedImages if it's not for editing context
717+
// When context is "edit", ChatRow will handle the images
718+
if (message.context !== "edit") {
717719
setSelectedImages((prevImages) =>
718-
[...prevImages, ...newImages].slice(0, MAX_IMAGES_PER_MESSAGE),
720+
appendImages(prevImages, message.images, MAX_IMAGES_PER_MESSAGE),
719721
)
720722
}
721723
break

webview-ui/src/utils/imageUtils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Utility function to append new images to existing images array
3+
* while respecting the maximum image limit
4+
*
5+
* @param currentImages - The current array of images
6+
* @param newImages - The new images to append
7+
* @param maxImages - The maximum number of images allowed
8+
* @returns The updated images array
9+
*/
10+
export function appendImages(currentImages: string[], newImages: string[] | undefined, maxImages: number): string[] {
11+
const imagesToAdd = newImages ?? []
12+
if (imagesToAdd.length === 0) {
13+
return currentImages
14+
}
15+
16+
return [...currentImages, ...imagesToAdd].slice(0, maxImages)
17+
}

0 commit comments

Comments
 (0)