desktop: add image pasting from clipboard (#3378)

* first pass at desktop image pasting for multiplatform

* removed debug println

* fixed bug with pasting text

* temp files are deleted now following simplex conventions

* optimizations

---------

Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
This commit is contained in:
Jesse Horne 2023-11-21 14:37:15 -05:00 committed by GitHub
parent a8576c2340
commit 097242e7a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,12 +22,21 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import chat.simplex.common.views.chat.*
import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.delay
import java.awt.Image
import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.UnsupportedFlavorException
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.File
import java.net.URI
import java.util.*
import javax.imageio.ImageIO
import kotlin.collections.ArrayList
import kotlin.io.path.*
import kotlin.math.min
import kotlin.text.substring
@ -112,12 +121,45 @@ actual fun PlatformTextField(
onUpArrow()
true
} else if (it.key == Key.V &&
it.type == KeyEventType.KeyDown &&
((it.isCtrlPressed && !desktopPlatform.isMac()) || (it.isMetaPressed && desktopPlatform.isMac())) &&
parseToFiles(clipboard.getText()).isNotEmpty()) {
onFilesPasted(parseToFiles(clipboard.getText()))
true
}
it.type == KeyEventType.KeyDown &&
((it.isCtrlPressed && !desktopPlatform.isMac()) || (it.isMetaPressed && desktopPlatform.isMac()))) {
if (parseToFiles(clipboard.getText()).isNotEmpty()) {
onFilesPasted(parseToFiles(clipboard.getText()))
true
} else {
// It's much faster to getData instead of getting transferable first
val image = try {
Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.imageFlavor) as Image
} catch (e: UnsupportedFlavorException) {
null
}
if (image != null) {
try {
// create BufferedImage from Image
val bi = BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB)
val bgr = bi.createGraphics()
bgr.drawImage(image, 0, 0, null)
bgr.dispose()
// create byte array from BufferedImage
val baos = ByteArrayOutputStream()
ImageIO.write(bi, "png", baos)
val bytes = baos.toByteArray()
withBGApi {
val tempFile = File(tmpDir, "${UUID.randomUUID()}.png")
chatModel.filesToDelete.add(tempFile)
tempFile.writeBytes(bytes)
composeState.processPickedMedia(listOf(tempFile.toURI()), composeState.value.message)
}
} catch (e: Exception) {
Log.e(TAG, "Pasting image exception: ${e.stackTraceToString()}")
}
true
} else {
false
}
}
}
else false
},
cursorBrush = SolidColor(MaterialTheme.colors.secondary),