3
3
4
4
package software.aws.toolkits.jetbrains.services.amazonq.toolwindow
5
5
6
- import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7
6
import com.intellij.idea.AppMode
8
7
import com.intellij.openapi.Disposable
9
8
import com.intellij.openapi.components.service
@@ -21,8 +20,6 @@ import kotlinx.coroutines.CoroutineScope
21
20
import kotlinx.coroutines.flow.first
22
21
import kotlinx.coroutines.launch
23
22
import kotlinx.coroutines.withContext
24
- import software.aws.toolkits.core.utils.error
25
- import software.aws.toolkits.core.utils.getLogger
26
23
import software.aws.toolkits.jetbrains.core.coroutines.EDT
27
24
import software.aws.toolkits.jetbrains.isDeveloperMode
28
25
import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext
@@ -47,12 +44,7 @@ import software.aws.toolkits.jetbrains.services.amazonqDoc.auth.isDocAvailable
47
44
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.auth.isFeatureDevAvailable
48
45
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.isCodeTransformAvailable
49
46
import software.aws.toolkits.resources.message
50
- import java.awt.datatransfer.DataFlavor
51
- import java.awt.dnd.DropTarget
52
- import java.awt.dnd.DropTargetDropEvent
53
- import java.io.File
54
47
import java.util.concurrent.CompletableFuture
55
- import javax.imageio.ImageIO.read
56
48
import javax.swing.JButton
57
49
58
50
class AmazonQPanel (val project : Project , private val scope : CoroutineScope ) : Disposable {
@@ -130,76 +122,12 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
130
122
131
123
withContext(EDT ) {
132
124
browser.complete(
133
- Browser (this @AmazonQPanel, webUri, project).also { browserInstance ->
134
- wrapper.setContent(browserInstance.component())
135
-
136
- // Add DropTarget to the browser component
137
- // JCEF does not propagate OS-level dragenter, dragOver and drop into DOM.
138
- // As an alternative, enabling the native drag in JCEF,
139
- // and let the native handling the drop event, and update the UI through JS bridge.
140
- val dropTarget = object : DropTarget () {
141
- override fun drop (dtde : DropTargetDropEvent ) {
142
- try {
143
- dtde.acceptDrop(dtde.dropAction)
144
- val transferable = dtde.transferable
145
- if (transferable.isDataFlavorSupported(DataFlavor .javaFileListFlavor)) {
146
- val fileList = transferable.getTransferData(DataFlavor .javaFileListFlavor) as List <* >
147
-
148
- val errorMessages = mutableListOf<String >()
149
- val validImages = mutableListOf<File >()
150
- val allowedTypes = setOf (" jpg" , " jpeg" , " png" , " gif" , " webp" )
151
- val maxFileSize = 3.75 * 1024 * 1024 // 3.75MB in bytes
152
- val maxDimension = 8000
153
-
154
- for (file in fileList as List <File >) {
155
- val validationResult = validateImageFile(file, allowedTypes, maxFileSize, maxDimension)
156
- if (validationResult != null ) {
157
- errorMessages.add(validationResult)
158
- } else {
159
- validImages.add(file)
160
- }
161
- }
162
-
163
- // File count restriction
164
- if (validImages.size > 20 ) {
165
- errorMessages.add(" A maximum of 20 images can be added to a single message." )
166
- validImages.subList(20 , validImages.size).clear()
167
- }
168
-
169
- val json = OBJECT_MAPPER .writeValueAsString(validImages)
170
- browserInstance.jcefBrowser.cefBrowser.executeJavaScript(
171
- " window.handleNativeDrop('$json ')" ,
172
- browserInstance.jcefBrowser.cefBrowser.url,
173
- 0
174
- )
175
-
176
- val errorJson = OBJECT_MAPPER .writeValueAsString(errorMessages)
177
- browserInstance.jcefBrowser.cefBrowser.executeJavaScript(
178
- " window.handleNativeNotify('$errorJson ')" ,
179
- browserInstance.jcefBrowser.cefBrowser.url,
180
- 0
181
- )
182
- dtde.dropComplete(true )
183
- } else {
184
- dtde.dropComplete(false )
185
- }
186
- } catch (e: Exception ) {
187
- LOG .error { " Failed to handle file drop operation: ${e.message} " }
188
- dtde.dropComplete(false )
189
- }
190
- }
191
- }
192
-
193
- // Set DropTarget on the browser component and its children
194
- browserInstance.component()?.let { component ->
195
- component.dropTarget = dropTarget
196
- // Also try setting on parent if needed
197
- component.parent?.dropTarget = dropTarget
198
- }
125
+ Browser (this @AmazonQPanel, webUri, project).also {
126
+ wrapper.setContent(it.component())
199
127
200
128
initConnections()
201
- connectUi(browserInstance )
202
- connectApps(browserInstance )
129
+ connectUi(it )
130
+ connectApps(it )
203
131
204
132
loadingPanel.stopLoading()
205
133
}
@@ -283,36 +211,6 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
283
211
}
284
212
}
285
213
286
- private fun validateImageFile (file : File , allowedTypes : Set <String >, maxFileSize : Double , maxDimension : Int ): String? {
287
- val fileName = file.name
288
- val ext = fileName.substringAfterLast(' .' , " " ).lowercase()
289
-
290
- if (ext !in allowedTypes) {
291
- return " $fileName : File must be an image in JPEG, PNG, GIF, or WebP format."
292
- }
293
-
294
- if (file.length() > maxFileSize) {
295
- return " $fileName : Image must be no more than 3.75MB in size."
296
- }
297
-
298
- return try {
299
- val img = read(file)
300
- when {
301
- img == null -> " $fileName : File could not be read as an image."
302
- img.width > maxDimension -> " $fileName : Image must be no more than 8,000px in width."
303
- img.height > maxDimension -> " $fileName : Image must be no more than 8,000px in height."
304
- else -> null
305
- }
306
- } catch (e: Exception ) {
307
- " $fileName : File could not be read as an image."
308
- }
309
- }
310
-
311
- companion object {
312
- private val LOG = getLogger<AmazonQPanel >()
313
- private val OBJECT_MAPPER = jacksonObjectMapper()
314
- }
315
-
316
214
override fun dispose () {
317
215
}
318
216
}
0 commit comments