mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-23 12:08:53 +00:00
feat: add ImageLoader to reuse Image loading mechanism
This commit is contained in:
parent
327552c33b
commit
a1585c8499
@ -9,29 +9,19 @@ Rectangle {
|
|||||||
property string imageSource: "data:image/jpeg;base64,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"
|
property string imageSource: "data:image/jpeg;base64,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"
|
||||||
|
|
||||||
id: imageChatBox
|
id: imageChatBox
|
||||||
height: imageMessage.paintedHeight
|
height: imageMessage.height
|
||||||
width: imageMessage.paintedWidth + 2 * chatHorizontalPadding
|
width: imageMessage.width + 2 * chatHorizontalPadding
|
||||||
radius: 16
|
radius: 16
|
||||||
visible: isImage
|
visible: isImage
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Image {
|
|
||||||
|
ImageLoader {
|
||||||
id: imageMessage
|
id: imageMessage
|
||||||
source: imageSource
|
verticalPadding: imageChatBox.chatVerticalPadding
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: imageChatBox.chatVerticalPadding
|
anchors.topMargin: imageChatBox.chatVerticalPadding
|
||||||
fillMode: Image.PreserveAspectFit
|
source: imageSource
|
||||||
width: sourceSize.width > imageWidth ? imageWidth : sourceSize.width
|
imageWidth: imageChatBox.imageWidth
|
||||||
onStatusChanged: {
|
|
||||||
if (imageMessage.status == Image.Error) {
|
|
||||||
imageMessage.height = 0
|
|
||||||
imageMessage.visible = false
|
|
||||||
imageChatBox.height = 0
|
|
||||||
imageChatBox.visible = false
|
|
||||||
} else if (imageMessage.status == Image.Ready) {
|
|
||||||
messageItem.scrollToBottom(true, messageItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,8 @@ Item {
|
|||||||
active: isImage
|
active: isImage
|
||||||
sourceComponent: chatImageComponent
|
sourceComponent: chatImageComponent
|
||||||
anchors.left: chatImage.right
|
anchors.left: chatImage.right
|
||||||
|
anchors.leftMargin: 8
|
||||||
|
anchors.top: chatReply.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import "../../../../../shared"
|
||||||
|
import "../../../../../imports"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property int verticalPadding: 0
|
||||||
|
property int imageWidth: 350
|
||||||
|
property url source
|
||||||
|
|
||||||
|
id: imageContainer
|
||||||
|
width: loadingImage.visible ? loadingImage.width : imageMessage.width
|
||||||
|
height: loadingImage.visible ? loadingImage.height : imageMessage.paintedHeight
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: loadingImage
|
||||||
|
property bool hasError: false
|
||||||
|
width: hasError ? 200 : imageContainer.imageWidth
|
||||||
|
height: hasError ? 75 : imageContainer.imageWidth
|
||||||
|
border.width: 1
|
||||||
|
border.color: Style.current.border
|
||||||
|
radius: Style.current.radius
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: loadingImage.hasError ? qsTr("Error loading the image") : qsTr("Loading image...")
|
||||||
|
color: loadingImage.hasError ? Style.current.red : Style.current.textColor
|
||||||
|
font.pixelSize: 15
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: imageMessage
|
||||||
|
width: sourceSize.width > imageWidth ? imageWidth : sourceSize.width
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: imageContainer.source
|
||||||
|
onStatusChanged: {
|
||||||
|
if (imageMessage.status === Image.Error) {
|
||||||
|
loadingImage.hasError = true
|
||||||
|
imageMessage.height = 0
|
||||||
|
imageMessage.source = ""
|
||||||
|
imageMessage.visible = false
|
||||||
|
} else if (imageMessage.status === Image.Ready) {
|
||||||
|
loadingImage.visible = false
|
||||||
|
scrollToBottom(true, messageItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ import "../../../../../imports"
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
property int chatVerticalPadding: 12
|
property int chatVerticalPadding: 12
|
||||||
property int chatHorizontalPadding: 12
|
property int chatHorizontalPadding: 12
|
||||||
property int imageWidth: 350
|
|
||||||
|
|
||||||
id: imageChatBox
|
id: imageChatBox
|
||||||
height: {
|
height: {
|
||||||
@ -17,7 +16,16 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
color: isCurrentUser ? Style.current.blue : Style.current.lightBlue
|
color: isCurrentUser ? Style.current.blue : Style.current.lightBlue
|
||||||
border.color: "transparent"
|
border.color: "transparent"
|
||||||
width: imageWidth + 2 * chatHorizontalPadding
|
width: {
|
||||||
|
let w = 0
|
||||||
|
for (let i = 0; i < imageRepeater.count; i++) {
|
||||||
|
if (imageRepeater.itemAt(i).width > w) {
|
||||||
|
w = imageRepeater.itemAt(i).width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w + 2 * chatHorizontalPadding
|
||||||
|
}
|
||||||
|
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
@ -30,47 +38,11 @@ Rectangle {
|
|||||||
return imageUrls.split(" ")
|
return imageUrls.split(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
ImageLoader {
|
||||||
id: imageContainer
|
verticalPadding: imageChatBox.chatVerticalPadding
|
||||||
width: loadingImage.visible ? loadingImage.width : imageMessage.width
|
anchors.top: (index === 0) ? parent.top: parent.children[index-1].bottom
|
||||||
height: loadingImage.visible ? loadingImage.height : imageMessage.paintedHeight
|
anchors.topMargin: verticalPadding
|
||||||
anchors.top: (index == 0) ? parent.top: parent.children[index-1].bottom
|
source: modelData
|
||||||
anchors.topMargin: imageChatBox.chatVerticalPadding
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: loadingImage
|
|
||||||
property bool hasError: false
|
|
||||||
width: hasError ? 200 : 400
|
|
||||||
height: hasError ? 75 : 400
|
|
||||||
border.width: 1
|
|
||||||
border.color: Style.current.border
|
|
||||||
radius: Style.current.radius
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: loadingImage.hasError ? qsTr("Error loading the image") : qsTr("Loading image...")
|
|
||||||
color: loadingImage.hasError ? Style.current.red : Style.current.textColor
|
|
||||||
font.pixelSize: 15
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: imageMessage
|
|
||||||
sourceSize.width: imageChatBox.imageWidth
|
|
||||||
source: modelData
|
|
||||||
onStatusChanged: {
|
|
||||||
if (imageMessage.status === Image.Error) {
|
|
||||||
loadingImage.hasError = true
|
|
||||||
imageMessage.height = 0
|
|
||||||
imageMessage.source = ""
|
|
||||||
imageMessage.visible = false
|
|
||||||
} else if (imageMessage.status === Image.Ready) {
|
|
||||||
loadingImage.visible = false
|
|
||||||
scrollToBottom(true, messageItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +123,7 @@ DISTFILES += \
|
|||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatTime.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatTime.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/DateGroup.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/DateGroup.qml \
|
||||||
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/ImageLoader.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/ImageMessage.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/ImageMessage.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml \
|
||||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml \
|
app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user