Skip to content

Commit 5262cf2

Browse files
authored
Merge pull request #7908 from continuedev/revert-7205-fix-image-drop-from-main-editor
Revert "Fix image drop from main editor"
2 parents 37a4fb7 + 0ca4c03 commit 5262cf2

File tree

9 files changed

+59
-280
lines changed

9 files changed

+59
-280
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
],
1919
"pauseForSourceMap": false,
2020
"outFiles": ["${workspaceFolder}/extensions/vscode/out/extension.js"],
21-
"preLaunchTask": "vscode-extension:build-without-watch",
21+
"preLaunchTask": "vscode-extension:build-with-packages",
2222
"env": {
2323
// "CONTROL_PLANE_ENV": "local",
2424
"CONTINUE_GLOBAL_DIR": "${workspaceFolder}/extensions/.continue-debug"

.vscode/tasks.json

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,25 +174,6 @@
174174
}
175175
]
176176
},
177-
{
178-
"label": "gui:build",
179-
"type": "shell",
180-
"command": "npm",
181-
"options": {
182-
"cwd": "${workspaceFolder}/gui",
183-
"env": {
184-
"NODE_OPTIONS": "--max-old-space-size=4096"
185-
}
186-
},
187-
"args": ["run", "build"],
188-
"problemMatcher": ["$tsc"],
189-
"presentation": {
190-
"group": "build-tasks",
191-
"panel": "shared",
192-
"reveal": "silent",
193-
"close": true
194-
}
195-
},
196177
{
197178
"label": "binary:esbuild",
198179
"type": "shell",

core/protocol/ide.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export type ToIdeFromWebviewOrCoreProtocol = {
5151
getPinnedFiles: [undefined, string[]];
5252
showLines: [{ filepath: string; startLine: number; endLine: number }, void];
5353
readRangeInFile: [{ filepath: string; range: Range }, string];
54-
readFileAsDataUrl: [{ filepath: string }, string];
5554
getDiff: [{ includeUnstaged: boolean }, string[]];
5655
getTerminalContents: [undefined, string];
5756
getDebugLocals: [{ threadIndex: number }, string];

extensions/vscode/src/extension/VsCodeMessenger.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -295,18 +295,6 @@ export class VsCodeMessenger {
295295
});
296296
});
297297

298-
this.onWebviewOrCore("readFileAsDataUrl", async (msg) => {
299-
const { filepath } = msg.data;
300-
const fileUri = vscode.Uri.file(filepath);
301-
const fileContents = await vscode.workspace.fs.readFile(fileUri);
302-
const fileType =
303-
filepath.split(".").pop() === "png" ? "image/png" : "image/jpeg";
304-
const dataUrl = `data:${fileType};base64,${Buffer.from(
305-
fileContents,
306-
).toString("base64")}`;
307-
return dataUrl;
308-
});
309-
310298
this.onWebviewOrCore("getIdeSettings", async (msg) => {
311299
return ide.getIdeSettings();
312300
});

gui/src/components/mainInput/TipTapEditor/TipTapEditor.tsx

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,10 @@ function TipTapEditorInner(props: TipTapEditorProps) {
5757
const historyLength = useAppSelector((store) => store.session.history.length);
5858
const isInEdit = useAppSelector((store) => store.session.isInEdit);
5959

60-
const [showDragOverMsg, setShowDragOverMsg] = useState(false);
61-
6260
const { editor, onEnterRef } = createEditorConfig({
6361
props,
6462
ideMessenger,
6563
dispatch,
66-
setShowDragOverMsg,
6764
});
6865

6966
// Register the main editor with the provider
@@ -140,6 +137,8 @@ function TipTapEditorInner(props: TipTapEditorProps) {
140137
}
141138
}, [isStreaming, props.isMainInput]);
142139

140+
const [showDragOverMsg, setShowDragOverMsg] = useState(false);
141+
143142
const [activeKey, setActiveKey] = useState<string | null>(null);
144143

145144
const insertCharacterWithWhitespace = useCallback(
@@ -222,23 +221,40 @@ function TipTapEditorInner(props: TipTapEditorProps) {
222221
if (e.shiftKey) {
223222
setShowDragOverMsg(false);
224223
} else {
225-
setTimeout(() => {
226-
setShowDragOverMsg(false);
227-
}, 2000);
224+
setTimeout(() => setShowDragOverMsg(false), 2000);
228225
}
229226
}
230-
setShowDragOverMsg(false);
231227
}}
232228
onDragEnter={() => {
233229
setShowDragOverMsg(true);
234230
}}
235-
onDragEnd={() => {
236-
setShowDragOverMsg(false);
237-
}}
238231
onDrop={(event) => {
239-
// Just hide the drag overlay - ProseMirror handles the actual drop
240232
setShowDragOverMsg(false);
241-
// Let the event bubble to ProseMirror by not preventing default
233+
if (
234+
!defaultModel ||
235+
!modelSupportsImages(
236+
defaultModel.provider,
237+
defaultModel.model,
238+
defaultModel.title,
239+
defaultModel.capabilities,
240+
)
241+
) {
242+
return;
243+
}
244+
let file = event.dataTransfer.files[0];
245+
void handleImageFile(ideMessenger, file).then((result) => {
246+
if (!editor) {
247+
return;
248+
}
249+
if (result) {
250+
const [_, dataUrl] = result;
251+
const { schema } = editor.state;
252+
const node = schema.nodes.image.create({ src: dataUrl });
253+
const tr = editor.state.tr.insert(0, node);
254+
editor.view.dispatch(tr);
255+
}
256+
});
257+
event.preventDefault();
242258
}}
243259
>
244260
<div className="px-2.5 pb-1 pt-2">
@@ -283,7 +299,9 @@ function TipTapEditorInner(props: TipTapEditorProps) {
283299
defaultModel?.model || "",
284300
defaultModel?.title,
285301
defaultModel?.capabilities,
286-
) && <DragOverlay show={showDragOverMsg} />}
302+
) && (
303+
<DragOverlay show={showDragOverMsg} setShow={setShowDragOverMsg} />
304+
)}
287305
<div id={TIPPY_DIV_ID} className="fixed z-50" />
288306
</InputBoxDiv>
289307
);

gui/src/components/mainInput/TipTapEditor/components/DragOverlay.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
1-
import React from "react";
1+
import React, { useEffect } from "react";
22
import { HoverDiv, HoverTextDiv } from "./StyledComponents";
33

44
interface DragOverlayProps {
55
show: boolean;
6+
setShow: (show: boolean) => void;
67
}
78

8-
export const DragOverlay: React.FC<DragOverlayProps> = ({ show }) => {
9+
export const DragOverlay: React.FC<DragOverlayProps> = ({ show, setShow }) => {
10+
useEffect(() => {
11+
const overListener = (event: DragEvent) => {
12+
if (event.shiftKey) return;
13+
setShow(true);
14+
};
15+
window.addEventListener("dragover", overListener);
16+
17+
const leaveListener = (event: DragEvent) => {
18+
if (event.shiftKey) {
19+
setShow(false);
20+
} else {
21+
setTimeout(() => setShow(false), 2000);
22+
}
23+
};
24+
window.addEventListener("dragleave", leaveListener);
25+
26+
return () => {
27+
window.removeEventListener("dragover", overListener);
28+
window.removeEventListener("dragleave", leaveListener);
29+
};
30+
}, []);
31+
932
if (!show) return null;
1033

1134
return (

gui/src/components/mainInput/TipTapEditor/components/StyledComponents.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ export const HoverDiv = styled.div`
5656
display: flex;
5757
align-items: center;
5858
justify-content: center;
59-
pointer-events: none;
6059
`;
6160

6261
export const HoverTextDiv = styled.div`
@@ -69,5 +68,4 @@ export const HoverTextDiv = styled.div`
6968
display: flex;
7069
align-items: center;
7170
justify-content: center;
72-
pointer-events: none;
7371
`;

gui/src/components/mainInput/TipTapEditor/utils/editorConfig.ts

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
getContextProviderDropdownOptions,
2828
getSlashCommandDropdownOptions,
2929
} from "./getSuggestion";
30-
import { handleImageFile, handleVSCodeResourceFromHtml } from "./imageUtils";
30+
import { handleImageFile } from "./imageUtils";
3131

3232
export function getPlaceholderText(
3333
placeholder: TipTapEditorProps["placeholder"],
@@ -69,9 +69,8 @@ export function createEditorConfig(options: {
6969
props: TipTapEditorProps;
7070
ideMessenger: IIdeMessenger;
7171
dispatch: AppDispatch;
72-
setShowDragOverMsg: (show: boolean) => void;
7372
}) {
74-
const { props, ideMessenger, dispatch, setShowDragOverMsg } = options;
73+
const { props, ideMessenger, dispatch } = options;
7574

7675
const posthog = usePostHog();
7776

@@ -148,80 +147,6 @@ export function createEditorConfig(options: {
148147
const plugin = new Plugin({
149148
props: {
150149
handleDOMEvents: {
151-
drop(view, event) {
152-
// Hide drag overlay immediately when drop is handled
153-
setShowDragOverMsg(false);
154-
155-
// Get current model and check if it supports images
156-
const model = defaultModelRef.current;
157-
if (
158-
!model ||
159-
!modelSupportsImages(
160-
model.provider,
161-
model.model,
162-
model.title,
163-
model.capabilities,
164-
)
165-
) {
166-
event.preventDefault();
167-
event.stopPropagation();
168-
return true;
169-
}
170-
171-
event.preventDefault();
172-
event.stopPropagation();
173-
174-
// Check if dataTransfer exists
175-
if (!event.dataTransfer) {
176-
return true;
177-
}
178-
179-
// Handle file drop first
180-
if (event.dataTransfer.files.length > 0) {
181-
const file = event.dataTransfer.files[0];
182-
void handleImageFile(ideMessenger, file).then((result) => {
183-
if (result) {
184-
const [_, dataUrl] = result;
185-
const { schema } = view.state;
186-
const node = schema.nodes.image.create({
187-
src: dataUrl,
188-
});
189-
const tr = view.state.tr.insert(0, node);
190-
view.dispatch(tr);
191-
}
192-
});
193-
return true;
194-
}
195-
196-
// Handle drop of HTML content (including VS Code resource URLs)
197-
const html = event.dataTransfer.getData("text/html");
198-
if (html) {
199-
void handleVSCodeResourceFromHtml(ideMessenger, html)
200-
.then((dataUrl) => {
201-
if (dataUrl) {
202-
const { schema } = view.state;
203-
const node = schema.nodes.image.create({
204-
src: dataUrl,
205-
});
206-
const tr = view.state.tr.insert(0, node);
207-
view.dispatch(tr);
208-
}
209-
})
210-
.catch((err) =>
211-
console.error(
212-
"Failed to handle VS Code resource:",
213-
err,
214-
),
215-
);
216-
}
217-
218-
return true;
219-
},
220-
dragover(view, event) {
221-
// Allow dragover for proper drop handling
222-
event.preventDefault();
223-
return true;
224-
},
225150
paste(view, event) {
226151
const model = defaultModelRef.current;
227152
if (!model) return;

0 commit comments

Comments
 (0)