MessageEventModel media info improvements

Create a `messageeventmodel` role for media info and reply media info that is a QMap with all the required data.

This replaces the MediaUrlRole, FileMimeTypeRole and the ContentTypeRole. The reply role no longer needs the content role.

This also ensures mxc urls are now generated for replies. All the media parameters will now have default values assigned in the model so the QML no longer needs to do this.
This commit is contained in:
James Graham
2023-05-03 17:50:48 +00:00
parent a6f108d3b8
commit 10794628ed
9 changed files with 164 additions and 107 deletions

View File

@@ -18,9 +18,9 @@ Components.AlbumMaximizeComponent {
property list<Components.AlbumModelItem> items: [
Components.AlbumModelItem {
type: root.modelData.delegateType === MessageEventModel.Image ? Components.AlbumModelItem.Image : Components.AlbumModelItem.Video
source: root.modelData.delegateType === MessageEventModel.Video ? modelData.progressInfo.localPath : modelData.mediaUrl
tempSource: modelData.content.info["xyz.amorgan.blurhash"] ? ("image://blurhash/" + modelData.content.info["xyz.amorgan.blurhash"]) : ""
type: root.modelData.delegateType === MessageEventModel.Image || root.modelData.delegateType === MessageEventModel.Sticker ? Components.AlbumModelItem.Image : Components.AlbumModelItem.Video
source: root.modelData.delegateType === MessageEventModel.Video ? modelData.progressInfo.localPath : modelData.mediaInfo.source
tempSource: modelData.mediaInfo.blurhash
caption: modelData.display
}
]

View File

@@ -94,7 +94,7 @@ TimelineContainer {
visible: false
Layout.fillWidth: true
from: 0
to: model.content.info.size
to: model.mediaInfo.size
value: model.progressInfo.progress
}
RowLayout {

View File

@@ -103,7 +103,7 @@ TimelineContainer {
]
Kirigami.Icon {
source: model.fileMimetypeIcon
source: model.mediaInfo.mimeIcon
fallback: "unknown"
}
@@ -118,7 +118,7 @@ TimelineContainer {
QQC2.Label {
id: sizeLabel
Layout.fillWidth: true
text: Controller.formatByteSize(content.info ? content.info.size : 0)
text: Controller.formatByteSize(model.mediaInfo.size)
opacity: 0.7
elide: Text.ElideRight
maximumLineCount: 1

View File

@@ -16,17 +16,9 @@ TimelineContainer {
onOpenContextMenu: openFileContext(model, imageDelegate)
property var content: model.content
readonly property bool isAnimated: contentType === "image/gif"
property bool openOnFinished: false
readonly property bool downloaded: progressInfo && progressInfo.completed
readonly property bool isThumbnail: !(content.info.thumbnail_info == null || content.thumbnailMediaId == null)
// readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info
readonly property var info: content.info
readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId
readonly property var maxWidth: Kirigami.Units.gridUnit * 30
readonly property var maxHeight: Kirigami.Units.gridUnit * 30
@@ -34,8 +26,8 @@ TimelineContainer {
id: img
property var imageWidth: {
if (imageDelegate.info && imageDelegate.info.w && imageDelegate.info.w > 0) {
return imageDelegate.info.w;
if (model.mediaInfo.width > 0) {
return model.mediaInfo.width;
} else if (sourceSize.width && sourceSize.width > 0) {
return sourceSize.width;
} else {
@@ -43,8 +35,8 @@ TimelineContainer {
}
}
property var imageHeight: {
if (imageDelegate.info && imageDelegate.info.h && imageDelegate.info.h > 0) {
return imageDelegate.info.h;
if (model.mediaInfo.height > 0) {
return model.mediaInfo.height;
} else if (sourceSize.height && sourceSize.height > 0) {
return sourceSize.height;
} else {
@@ -78,11 +70,11 @@ TimelineContainer {
Layout.maximumHeight: maxSize.height
Layout.preferredWidth: imageWidth
Layout.preferredHeight: imageHeight
source: model.mediaUrl
source: model.mediaInfo.source
Image {
anchors.fill: parent
source: content.info["xyz.amorgan.blurhash"] ? ("image://blurhash/" + content.info["xyz.amorgan.blurhash"]) : ""
source: model.mediaInfo.blurhash
visible: parent.status !== Image.Ready
}

View File

@@ -18,6 +18,7 @@ Item {
property var name
property alias avatar: replyAvatar.source
property var color
property var mediaInfo
implicitWidth: mainLayout.implicitWidth
implicitHeight: mainLayout.implicitHeight
@@ -61,6 +62,7 @@ Item {
id: loader
Layout.fillWidth: true
Layout.maximumHeight: loader.item && (reply.type == MessageEventModel.Image || reply.type == MessageEventModel.Sticker) ? loader.item.height : -1
Layout.columnSpan: 2
sourceComponent: {
@@ -112,19 +114,35 @@ Item {
id: imageComponent
Image {
id: image
readonly property var content: reply.content
readonly property bool isThumbnail: !(content.info.thumbnail_info == null || content.thumbnailMediaId == null)
readonly property var info: content.info
readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId
source: "image://mxc/" + mediaId
property var imageWidth: {
if (replyComponent.mediaInfo.width > 0) {
return replyComponent.mediaInfo.width;
} else {
return sourceSize.width;
}
}
property var imageHeight: {
if (replyComponent.mediaInfo.height > 0) {
return replyComponent.mediaInfo.height;
} else {
return sourceSize.height;
}
}
readonly property var aspectRatio: imageWidth / imageHeight
height: width / aspectRatio
fillMode: Image.PreserveAspectFit
source: mediaInfo.source
}
}
Component {
id: mimeComponent
MimeComponent {
mimeIconSource: reply.content.info.mimetype.replace("/", "-")
mimeIconSource: replyComponent.mediaInfo.mimeIcon
label: reply.display
subLabel: reply.type === MessageEventModel.File ? Controller.formatByteSize(reply.content.info ? reply.content.info.size : 0) : Controller.formatDuration(reply.content.info.duration)
subLabel: reply.type === MessageEventModel.File ? Controller.formatByteSize(replyComponent.mediaInfo.size) : Controller.formatDuration(replyComponent.mediaInfo.duration)
}
}
Component {

View File

@@ -253,13 +253,14 @@ ColumnLayout {
Layout.maximumWidth: contentMaxWidth
active: model.reply !== undefined
active: model.isReply
visible: active
sourceComponent: ReplyComponent {
name: currentRoom.htmlSafeMemberName(model.replyAuthor.id)
avatar: model.replyAuthor.avatarSource
color: model.replyAuthor.color
mediaInfo: model.replyMediaInfo
}
Connections {

View File

@@ -22,8 +22,6 @@ TimelineContainer {
readonly property var maxWidth: Kirigami.Units.gridUnit * 30
readonly property var maxHeight: Kirigami.Units.gridUnit * 30
readonly property var info: model.content.info
onOpenContextMenu: openFileContext(model, vid)
onDownloadedChanged: {
@@ -41,8 +39,8 @@ TimelineContainer {
id: vid
property var videoWidth: {
if (videoDelegate.info && videoDelegate.info.w && videoDelegate.info.w > 0) {
return videoDelegate.info.w;
if (model.mediaInfo.width > 0) {
return model.mediaInfo.width;
} else if (metaData.resolution && metaData.resolution.width) {
return metaData.resolution.width;
} else {
@@ -50,8 +48,8 @@ TimelineContainer {
}
}
property var videoHeight: {
if (videoDelegate.info && videoDelegate.info.h && videoDelegate.info.h > 0) {
return videoDelegate.info.h;
if (model.mediaInfo.height > 0) {
return model.mediaInfo.height;
} else if (metaData.resolution && metaData.resolution.height) {
return metaData.resolution.height;
} else {
@@ -154,11 +152,9 @@ TimelineContainer {
Image {
id: mediaThumbnail
anchors.fill: parent
visible: false
source: model.content.thumbnailMediaId ? "image://mxc/" + model.content.thumbnailMediaId : ""
source: model.mediaInfo.thumbnailInfo.source
fillMode: Image.PreserveAspectFit
}