fix(images): fix second pasted image replaces the first one
Fixes #9966 Uses the validate function to paste images so that it concatenates the previous images. FIxes the validate function to also accept data images. Moves the size validation function to Utils to reuse the data path prefix constant and fix the possible crash when we try to get the size of a data image.
This commit is contained in:
parent
b580f0a810
commit
e5ff0b4a6a
|
@ -32,7 +32,7 @@ DropArea {
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed because drag.urls is not a normal js array
|
// needed because drag.urls is not a normal js array
|
||||||
rptDraggedPreviews.model = drag.urls.filter(img => Utils.hasDragNDropImageExtension(img))
|
rptDraggedPreviews.model = drag.urls.filter(img => Utils.isValidDragNDropImage(img))
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
rptDraggedPreviews.x = drag.x
|
rptDraggedPreviews.x = drag.x
|
||||||
|
|
|
@ -15,7 +15,7 @@ StatusChatImageValidator {
|
||||||
onImagesChanged: {
|
onImagesChanged: {
|
||||||
let isValid = true
|
let isValid = true
|
||||||
root.validImages = images.filter(img => {
|
root.validImages = images.filter(img => {
|
||||||
const isImage = Utils.hasDragNDropImageExtension(img)
|
const isImage = Utils.isValidDragNDropImage(img)
|
||||||
isValid = isValid && isImage
|
isValid = isValid && isImage
|
||||||
return isImage
|
return isImage
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,13 +4,11 @@ import utils 1.0
|
||||||
|
|
||||||
StatusChatImageValidator {
|
StatusChatImageValidator {
|
||||||
id: root
|
id: root
|
||||||
readonly property int maxImgSizeBytes: Constants.maxUploadFilesizeMB * 1048576 /* 1 MB in bytes */
|
|
||||||
|
|
||||||
onImagesChanged: {
|
onImagesChanged: {
|
||||||
let isValid = true
|
let isValid = true
|
||||||
root.validImages = images.filter(img => {
|
root.validImages = images.filter(img => {
|
||||||
let size = parseInt(globalUtils.getFileSize(img))
|
const isSmallEnough = Utils.isFilesizeValid(img)
|
||||||
const isSmallEnough = size <= maxImgSizeBytes
|
|
||||||
isValid = isValid && isSmallEnough
|
isValid = isValid && isSmallEnough
|
||||||
return isSmallEnough
|
return isSmallEnough
|
||||||
})
|
})
|
||||||
|
|
|
@ -436,7 +436,7 @@ Rectangle {
|
||||||
if (event.matches(StandardKey.Paste)) {
|
if (event.matches(StandardKey.Paste)) {
|
||||||
if (QClipboardProxy.hasImage) {
|
if (QClipboardProxy.hasImage) {
|
||||||
const clipboardImage = QClipboardProxy.imageBase64
|
const clipboardImage = QClipboardProxy.imageBase64
|
||||||
showImageArea([clipboardImage])
|
validateImagesAndShowImageArea([clipboardImage])
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (QClipboardProxy.hasText) {
|
} else if (QClipboardProxy.hasText) {
|
||||||
messageInputField.remove(messageInputField.selectionStart, messageInputField.selectionEnd)
|
messageInputField.remove(messageInputField.selectionStart, messageInputField.selectionEnd)
|
||||||
|
@ -883,11 +883,22 @@ Rectangle {
|
||||||
|
|
||||||
function showImageArea(imagePathsOrData) {
|
function showImageArea(imagePathsOrData) {
|
||||||
isImage = true;
|
isImage = true;
|
||||||
|
|
||||||
imageArea.imageSource = imagePathsOrData
|
imageArea.imageSource = imagePathsOrData
|
||||||
control.fileUrlsAndSources = imageArea.imageSource
|
control.fileUrlsAndSources = imageArea.imageSource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use this to validate and show the images. The concatanation of previous selected images is done automatically
|
||||||
|
// Returns true if the images were valid and added
|
||||||
|
function validateImagesAndShowImageArea(imagePaths) {
|
||||||
|
const validImages = validateImages(imagePaths)
|
||||||
|
|
||||||
|
if (validImages.length > 0) {
|
||||||
|
showImageArea(validImages)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
function showReplyArea(messageId, userName, message, contentType, image, sticker) {
|
function showReplyArea(messageId, userName, message, contentType, image, sticker) {
|
||||||
isReply = true
|
isReply = true
|
||||||
replyArea.userName = userName
|
replyArea.userName = userName
|
||||||
|
@ -908,9 +919,7 @@ Rectangle {
|
||||||
target: Global.dragArea
|
target: Global.dragArea
|
||||||
ignoreUnknownSignals: true
|
ignoreUnknownSignals: true
|
||||||
function onDroppedOnValidScreen(drop) {
|
function onDroppedOnValidScreen(drop) {
|
||||||
let validImages = validateImages(drop.urls)
|
if (validateImagesAndShowImageArea(drop.urls)) {
|
||||||
if (validImages.length > 0) {
|
|
||||||
showImageArea(validImages)
|
|
||||||
drop.acceptProposedAction()
|
drop.acceptProposedAction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -918,10 +927,7 @@ Rectangle {
|
||||||
|
|
||||||
// This is used by Squish tests to not have to access the file dialog
|
// This is used by Squish tests to not have to access the file dialog
|
||||||
function selectImageString(filePath) {
|
function selectImageString(filePath) {
|
||||||
let validImages = validateImages([filePath])
|
validateImagesAndShowImageArea([filePath])
|
||||||
if (validImages.length > 0) {
|
|
||||||
control.showImageArea(validImages)
|
|
||||||
}
|
|
||||||
messageInputField.forceActiveFocus();
|
messageInputField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,10 +941,7 @@ Rectangle {
|
||||||
]
|
]
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
imageBtn.highlighted = false
|
imageBtn.highlighted = false
|
||||||
let validImages = validateImages(imageDialog.fileUrls)
|
validateImagesAndShowImageArea(imageDialog.fileUrls)
|
||||||
if (validImages.length > 0) {
|
|
||||||
control.showImageArea(validImages)
|
|
||||||
}
|
|
||||||
messageInputField.forceActiveFocus();
|
messageInputField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
onRejected: {
|
onRejected: {
|
||||||
|
|
|
@ -797,6 +797,7 @@ QtObject {
|
||||||
|
|
||||||
readonly property int maxNumberOfPins: 3
|
readonly property int maxNumberOfPins: 3
|
||||||
|
|
||||||
|
readonly property string dataImagePrefix: "data:image"
|
||||||
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
||||||
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", ".tif", ".tiff"]
|
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", ".tif", ".tiff"]
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ QtObject {
|
||||||
property var mainModuleInst: typeof mainModule !== "undefined" ? mainModule : null
|
property var mainModuleInst: typeof mainModule !== "undefined" ? mainModule : null
|
||||||
property var globalUtilsInst: typeof globalUtils !== "undefined" ? globalUtils : null
|
property var globalUtilsInst: typeof globalUtils !== "undefined" ? globalUtils : null
|
||||||
|
|
||||||
|
readonly property int maxImgSizeBytes: Constants.maxUploadFilesizeMB * 1048576 /* 1 MB in bytes */
|
||||||
|
|
||||||
function isDigit(value) {
|
function isDigit(value) {
|
||||||
return /^\d$/.test(value);
|
return /^\d$/.test(value);
|
||||||
}
|
}
|
||||||
|
@ -320,8 +322,18 @@ QtObject {
|
||||||
return message.replace(/(?:https?|ftp):\/\/[\n\S]*(\.gif)+/gm, '');
|
return message.replace(/(?:https?|ftp):\/\/[\n\S]*(\.gif)+/gm, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasDragNDropImageExtension(url) {
|
function isValidDragNDropImage(url) {
|
||||||
return Constants.acceptedDragNDropImageExtensions.some(ext => url.toLowerCase().includes(ext))
|
let lowerCaseUrl = url.toLowerCase()
|
||||||
|
return Constants.acceptedDragNDropImageExtensions.some(ext => lowerCaseUrl.endsWith(ext)) ||
|
||||||
|
lowerCaseUrl.startsWith(Constants.dataImagePrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFilesizeValid(img) {
|
||||||
|
if (img.startsWith(Constants.dataImagePrefix)) {
|
||||||
|
return img.length < maxImgSizeBytes
|
||||||
|
}
|
||||||
|
let size = parseInt(globalUtils.getFileSize(img))
|
||||||
|
return size <= maxImgSizeBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
function deduplicate(array) {
|
function deduplicate(array) {
|
||||||
|
|
Loading…
Reference in New Issue