3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
+ import { DataTransfers } from '../../../../../base/browser/dnd.js' ;
6
7
import * as dom from '../../../../../base/browser/dom.js' ;
7
8
import { ButtonWithIcon } from '../../../../../base/browser/ui/button/button.js' ;
9
+ import { applyDragImage } from '../../../../../base/browser/ui/dnd/dnd.js' ;
8
10
import { assertNever } from '../../../../../base/common/assert.js' ;
9
11
import { VSBuffer } from '../../../../../base/common/buffer.js' ;
10
12
import { Codicon } from '../../../../../base/common/codicons.js' ;
@@ -32,6 +34,7 @@ import { ILabelService } from '../../../../../platform/label/common/label.js';
32
34
import { INotificationService } from '../../../../../platform/notification/common/notification.js' ;
33
35
import { IProgressService , ProgressLocation } from '../../../../../platform/progress/common/progress.js' ;
34
36
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js' ;
37
+ import { fillEditorsDragData } from '../../../../browser/dnd.js' ;
35
38
import { REVEAL_IN_EXPLORER_COMMAND_ID } from '../../../files/browser/fileConstants.js' ;
36
39
import { getAttachableImageExtension , IChatRequestVariableEntry , OmittedState } from '../../common/chatModel.js' ;
37
40
import { IChatRendererContent } from '../../common/chatViewModel.js' ;
@@ -55,6 +58,7 @@ export interface IChatCollapsibleIODataPart {
55
58
kind : 'data' ;
56
59
value : Uint8Array ;
57
60
mimeType : string ;
61
+ uri ?: URI ;
58
62
}
59
63
60
64
export interface IChatCollapsibleIOResourcePart {
@@ -211,7 +215,7 @@ export class ChatCollapsibleInputOutputContentPart extends Disposable {
211
215
212
216
const entries = parts . map ( ( part ) : IChatRequestVariableEntry => {
213
217
if ( part . kind === 'data' && getAttachableImageExtension ( part . mimeType ) ) {
214
- return { kind : 'image' , id : generateUuid ( ) , name : `image.${ getAttachableImageExtension ( part . mimeType ) } ` , value : part . value , mimeType : part . mimeType , isURL : false } ;
218
+ return { kind : 'image' , id : generateUuid ( ) , name : part . uri ? basename ( part . uri ) : `image.${ getAttachableImageExtension ( part . mimeType ) } ` , value : part . value , mimeType : part . mimeType , isURL : false } ;
215
219
} else if ( part . kind === 'resource' ) {
216
220
return { kind : 'file' , id : generateUuid ( ) , name : basename ( part . uri ) , fullName : part . uri . path , value : part . uri } ;
217
221
} else if ( part . kind === 'data' ) {
@@ -244,6 +248,23 @@ export class ChatCollapsibleInputOutputContentPart extends Disposable {
244
248
}
245
249
} ;
246
250
251
+ attachments . dragStartHandler = ( attachment , event , element ) => {
252
+ if ( ! event . dataTransfer ) {
253
+ return ;
254
+ }
255
+
256
+ const index = entries . indexOf ( attachment ) ;
257
+ const part = parts [ index ] ;
258
+ if ( ! part . uri ) {
259
+ return ;
260
+ }
261
+
262
+ applyDragImage ( event , element , attachment . name ) ;
263
+ event . dataTransfer . effectAllowed = 'copy' ;
264
+ event . dataTransfer . setData ( DataTransfers . TEXT , part . uri . toString ( ) ) ;
265
+ this . _instantiationService . invokeFunction ( accessor => fillEditorsDragData ( accessor , [ part . uri ! ] , event ) ) ;
266
+ } ;
267
+
247
268
el . items . appendChild ( attachments . domNode ! ) ;
248
269
249
270
const toolbar = this . _register ( this . _instantiationService . createInstance ( MenuWorkbenchToolBar , el . actions , MenuId . ChatToolOutputResourceToolbar , {
@@ -317,7 +338,7 @@ class SaveResourcesAction extends Action2 {
317
338
const defaultFilepath = await fileDialog . defaultFilePath ( ) ;
318
339
319
340
const partBasename = ( part : IChatCollapsibleIODataPart | IChatCollapsibleIOResourcePart ) =>
320
- part . kind === 'resource' ? basename ( part . uri ) : ( 'file' + ( getExtensionForMimeType ( part . mimeType ) || '' ) ) ;
341
+ ( part . kind === 'resource' || part . uri ) ? basename ( part . uri ! ) : ( 'file' + ( getExtensionForMimeType ( part . mimeType ) || '' ) ) ;
321
342
322
343
const savePart = async ( part : IChatCollapsibleIODataPart | IChatCollapsibleIOResourcePart , isFolder : boolean , uri : URI ) => {
323
344
const target = isFolder ? joinPath ( uri , partBasename ( part ) ) : uri ;
0 commit comments