feat(image-album): Display album of images in replies

Fixes: #9957
This commit is contained in:
Boris Melnik 2023-04-27 15:35:16 +03:00
parent cdbdae2d39
commit df88984b45
9 changed files with 117 additions and 81 deletions

View File

@ -297,59 +297,13 @@ Control {
Loader {
active: true
sourceComponent: messageDetails.album.length > 1 ? albumComp : imageComp
}
}
Component {
id: imageComp
StatusImageMessage {
source: root.messageDetails.messageContent
onClicked: root.imageClicked(image, mouse, imageSource)
shapeType: root.messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
}
}
Component {
id: albumComp
RowLayout {
width: messageLayout.width
spacing: 9
Repeater {
model: root.messageDetails.albumCount
delegate: Loader {
active: true
readonly property bool imageLoaded: index < root.messageDetails.album.length
readonly property string imagePath: imageLoaded ? root.messageDetails.album[index] : ""
sourceComponent: imageLoaded ? imageComponent : imagePlaceholderComponent
}
}
Component {
id: imageComponent
StatusImageMessage {
Layout.alignment: Qt.AlignLeft
imageWidth: Math.min(messageLayout.width / root.messageDetails.albumCount - 9 * (root.messageDetails.albumCount - 1), 144)
source: imagePath
onClicked: root.imageClicked(image, mouse, imageSource)
shapeType: root.messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
}
}
Component {
id: imagePlaceholderComponent
LoadingComponent {
radius: 4
height: 194
width: 144
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
sourceComponent: StatusMessageImageAlbum {
width: messageLayout.width
album: root.messageDetails.albumCount > 0 ? root.messageDetails.album : [root.messageDetails.messageContent]
albumCount: root.messageDetails.albumCount > 0 ? root.messageDetails.albumCount : 1
imageWidth: Math.min(messageLayout.width / root.messageDetails.albumCount - 9 * (root.messageDetails.albumCount - 1), 144)
shapeType: root.messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
onImageClicked: root.imageClicked(image, mouse, imageSource)
}
}
}

View File

@ -0,0 +1,4 @@
module StatusQ.Components.private
StatusImageMessage 0.1 statusMessage/StatusImageMessage.qml
StatusMessageImageAlbum 0.1 statusMessage/StatusMessageImageAlbum.qml

View File

@ -0,0 +1,57 @@
import QtQuick 2.15
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
RowLayout {
id: root
property var album: []
property int albumCount: 0
property real imageWidth: 144
property int shapeType: -1
property real loadingComponentHeight: 194
signal imageClicked(var image, var mouse, var imageSource)
spacing: 9
Repeater {
model: root.albumCount
delegate: Loader {
active: true
readonly property bool imageLoaded: index < root.album.length
readonly property string imagePath: imageLoaded ? root.album[index] : ""
sourceComponent: imageLoaded ? imageComponent : imagePlaceholderComponent
}
}
Component {
id: imageComponent
StatusImageMessage {
Layout.alignment: Qt.AlignLeft
imageWidth: root.imageWidth
source: imagePath
onClicked: root.imageClicked(image, mouse, imageSource)
shapeType: root.shapeType
}
}
Component {
id: imagePlaceholderComponent
LoadingComponent {
radius: 4
height: root.loadingComponentHeight
width: root.imageWidth
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
}

View File

@ -106,19 +106,25 @@ Item {
messageDetails: root.replyDetails
}
}
Loader {
Layout.fillWidth: true
asynchronous: true
active: replyDetails.contentType === StatusMessage.ContentType.Image
visible: active
sourceComponent: StatusImageMessage {
sourceComponent: StatusMessageImageAlbum {
Layout.fillWidth: true
Layout.preferredHeight: imageAlias.paintedHeight
Layout.preferredHeight: 56
album: replyDetails.albumCount > 0 ? replyDetails.album : [replyDetails.messageContent]
albumCount: replyDetails.albumCount > 0 ? replyDetails.albumCount : 1
imageWidth: 56
source: replyDetails.messageContent
loadingComponentHeight: 56
shapeType: StatusImageMessage.ShapeType.ROUNDED
}
}
StatusSticker {
asynchronous: true
active: replyDetails.contentType === StatusMessage.ContentType.Sticker

View File

@ -3,13 +3,16 @@
<file>StatusQ/Components/private/statusMessage/StatusAudioMessage.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusEditMessage.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusImageMessage.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusMessageQuickActions.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusMessageImageAlbum.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusMessageQuickActions.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusMessageReply.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusPinMessageDetails.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusSticker.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusTextMessage.qml</file>
<file>StatusQ/Components/private/statusMessage/StatusTimeStampLabel.qml</file>
<file>StatusQ/Components/qmldir</file>
<file>StatusQ/Components/private/qmldir</file>
<file>StatusQ/Components/StatusAddress.qml</file>
<file>StatusQ/Components/StatusAddressPanel.qml</file>
<file>StatusQ/Components/StatusAnimatedImage.qml</file>

View File

@ -152,7 +152,7 @@ ColumnLayout {
return
}
if (inputAreaLoader.item) {
inputAreaLoader.item.chatInput.showReplyArea(messageId, obj.senderDisplayName, obj.messageText, obj.contentType, obj.messageImage, obj.sticker)
inputAreaLoader.item.chatInput.showReplyArea(messageId, obj.senderDisplayName, obj.messageText, obj.contentType, obj.messageImage, obj.albumMessageImages, obj.albumImagesCount, obj.sticker)
}
}
}
@ -187,7 +187,7 @@ ColumnLayout {
return
}
if (inputAreaLoader.item) {
inputAreaLoader.item.chatInput.showReplyArea(messageId, obj.senderDisplayName, obj.messageText, obj.contentType, obj.messageImage, obj.sticker)
inputAreaLoader.item.chatInput.showReplyArea(messageId, obj.senderDisplayName, obj.messageText, obj.contentType, obj.messageImage, obj.albumMessageImages, obj.albumImagesCount, obj.sticker)
}
}
onOpenStickerPackPopup: {

View File

@ -930,7 +930,7 @@ Rectangle {
return false
}
function showReplyArea(messageId, userName, message, contentType, image, sticker) {
function showReplyArea(messageId, userName, message, contentType, image, album, albumCount, sticker) {
isReply = true
replyArea.userName = userName
replyArea.message = message
@ -938,6 +938,8 @@ Rectangle {
replyArea.image = image
replyArea.stickerData = sticker
replyArea.messageId = messageId
replyArea.album = album
replyArea.albumCount = albumCount
messageInputField.forceActiveFocus();
}

View File

@ -7,6 +7,7 @@ import shared.panels 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Components.private 0.1
Rectangle {
id: root
@ -26,6 +27,8 @@ Rectangle {
property string stickerData: ""
property string messageId: ""
property int contentType: -1
property var album: []
property int albumCount: 0
signal closeButtonClicked()
@ -73,16 +76,16 @@ Rectangle {
}
}
StatusChatImage {
StatusMessageImageAlbum {
id: imageThumbnail
anchors.left: replyToUsername.left
anchors.top: replyToUsername.bottom
anchors.topMargin: 2
imageWidth: 64
imageSource: root.image
chatHorizontalPadding: 0
visible: root.contentType === Constants.messageContentType.imageType
playing: false
album: root.albumCount > 0 ? root.album : [root.image]
albumCount: root.albumCount > 0 ? root.albumCount : 1
imageWidth: 56
loadingComponentHeight: 56
shapeType: StatusImageMessage.ShapeType.ROUNDED
}
StatusSticker {

View File

@ -608,30 +608,37 @@ Loader {
}
replyDetails: StatusMessageDetails {
readonly property var responseMessage: contentType === StatusMessage.ContentType.Sticker || contentType === StatusMessage.ContentType.Image
? root.messageStore.getMessageByIdAsJson(responseToMessageWithId)
: null
onResponseMessageChanged: {
if (!responseMessage)
return
switch (contentType) {
case StatusMessage.ContentType.Sticker:
messageContent = responseMessage.sticker;
return
case StatusMessage.ContentType.Image:
messageContent = responseMessage.messageImage;
albumCount = responseMessage.albumImagesCount
album = responseMessage.albumMessageImages
return
default:
messageContent = ""
}
}
messageText: {
if (root.quotedMessageDeleted) {
return qsTr("Message deleted")
}
if (!root.quotedMessageText) {
if (!root.quotedMessageText && contentType !== StatusMessage.ContentType.Image) {
return qsTr("Unknown message. Try fetching more messages")
}
return root.quotedMessageText
}
contentType: d.convertContentType(root.quotedMessageContentType)
messageContent: {
if (contentType !== StatusMessage.ContentType.Sticker && contentType !== StatusMessage.ContentType.Image) {
return ""
}
let message = root.messageStore.getMessageByIdAsJson(responseToMessageWithId)
switch (contentType) {
case StatusMessage.ContentType.Sticker:
return message.sticker;
case StatusMessage.ContentType.Image:
return message.messageImage;
}
return "";
}
amISender: root.quotedMessageFrom === userProfile.pubKey
sender.id: root.quotedMessageFrom
sender.isContact: quotedMessageAuthorDetailsIsContact