feat(@desktop/wallet): Make images match their aspect ratio but still have min width and height in collectible details

Also make images zoom to cropped when visible in the collectibles list view

fixes #14203
This commit is contained in:
Khushboo Mehta 2024-04-11 11:00:42 +02:00 committed by Khushboo-dev-cpp
parent 195cb55e8d
commit 8d8268db2f
5 changed files with 54 additions and 16 deletions

View File

@ -71,6 +71,20 @@ StatusRoundedComponent {
*/
property url fallbackImageUrl
/*!
\qmlproperty url StatusRoundedMedia::fillMode
helps set fillModel for the Media file loaded
*/
property int fillMode: Image.PreserveAspectFit
/*!
\qmlproperty url StatusRoundedMedia::maxDimension
is used to set dimension for the image in case of portrait or landscape
when fillMode = Image.PreserveAspectFit
if not set the width/height of parent will be considered
*/
property int manualMaxDimension: 0
readonly property int componentMediaType: {
if (root.mediaType.startsWith("image")) {
return StatusRoundedMedia.MediaType.Image
@ -112,11 +126,19 @@ StatusRoundedComponent {
}
}
Loader {
id: mediaLoader
anchors.fill: parent
asynchronous: true
visible: !root.isError && !root.isLoading
implicitWidth: {
// Use Painted width so that the rectangle follow width of the image actually painted
if(!!mediaLoader.item && (mediaLoader.item.paintedWidth > 0 || mediaLoader.item.paintedHeight > 0)) {
return mediaLoader.item.paintedWidth
}
else return root.manualMaxDimension
}
implicitHeight: {
// Use Painted height so that the rectangle follows height of the image actually painted
if(!!mediaLoader.item && (mediaLoader.item.paintedWidth > 0 || mediaLoader.item.paintedHeight > 0)) {
return mediaLoader.item.paintedHeight
}
else return root.manualMaxDimension
}
Component.onCompleted: updateMediaLoader()
@ -124,19 +146,31 @@ StatusRoundedComponent {
onComponentMediaTypeChanged: updateMediaLoader()
onFallbackImageUrlChanged: updateMediaLoader()
Loader {
id: mediaLoader
anchors.centerIn: parent
// In case manualMaxDimension is not defined then use parent width and height instead
width: root.manualMaxDimension === 0 ? parent.width : root.manualMaxDimension
height: root.manualMaxDimension === 0 ? parent.height : root.manualMaxDimension
asynchronous: true
visible: !root.isError && !root.isLoading
}
function updateMediaLoader() {
d.reset()
if (root.mediaUrl !== "") {
if (componentMediaType === StatusRoundedMedia.MediaType.Image) {
mediaLoader.setSource("StatusAnimatedImage.qml",
{
"source": root.mediaUrl
"source": root.mediaUrl,
"fillMode": root.fillMode
});
return
} else if (componentMediaType === StatusRoundedMedia.MediaType.Video) {
mediaLoader.setSource("StatusVideo.qml",
{
"player.source": root.mediaUrl
"player.source": root.mediaUrl,
"fillMode": root.fillMode
});
return
}
@ -150,7 +184,8 @@ StatusRoundedComponent {
if (componentMediaType === StatusRoundedMedia.MediaType.Image && d.errorCounter <= 1) {
mediaLoader.setSource("StatusImage.qml",
{
"source": root.mediaUrl
"source": root.mediaUrl,
"fillMode": root.fillMode
})
return
} else if (root.fallbackImageUrl !== "") {
@ -165,14 +200,16 @@ StatusRoundedComponent {
d.isFallback = true
mediaLoader.setSource("StatusImage.qml",
{
"source": root.fallbackImageUrl
"source": root.fallbackImageUrl,
"fillMode": root.fillMode
})
}
function setEmptyComponent() {
mediaLoader.setSource("StatusImage.qml",
{
"source": ""
"source": "",
"fillMode": root.fillMode
});
}
}

View File

@ -33,6 +33,7 @@ Item {
property alias player: player
property alias output: output
property alias fillMode: output.fillMode
MediaPlayer {
id: player

View File

@ -16,6 +16,7 @@ Control {
property bool showTag: false
property int size: PrivilegedTokenArtworkPanel.Size.Small
property int fillMode: Image.PreserveAspectFit
property alias artwork: image.source
property alias color: icon.color
@ -86,7 +87,7 @@ Control {
anchors.centerIn: parent
width: d.imageSize
height: width
fillMode: Image.PreserveAspectFit
fillMode: root.fillMode
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {

View File

@ -292,15 +292,12 @@ Item {
StatusRoundedMedia {
id: collectibleImage
readonly property bool isEmpty: !mediaUrl.toString() && !fallbackImageUrl.toString()
width: 248
height: width
radius: Style.current.radius
color: isError || isEmpty ? Theme.palette.baseColor5 : collectible.backgroundColor
border.color: Theme.palette.directColor8
border.width: 1
mediaUrl: collectible.mediaUrl ?? ""
mediaType: modelIndex === 0 && !!collectible ? collectible.mediaType : ""
mediaType: !!collectible ? (modelIndex > 0 && collectible.mediaType.startsWith("video")) ? "" : collectible.mediaType: ""
fallbackImageUrl: collectible.imageUrl
manualMaxDimension: 240
Column {
anchors.centerIn: parent

View File

@ -92,6 +92,7 @@ Control {
fallbackImageUrl: root.fallbackImageUrl
showLoadingIndicator: true
color: root.isLoading ? "transparent" : root.backgroundColor
fillMode: Image.PreserveAspectCrop
Loader {
anchors.fill: parent
@ -119,6 +120,7 @@ Control {
size: PrivilegedTokenArtworkPanel.Size.Medium
artwork: root.fallbackImageUrl
color: root.ornamentColor
fillMode: Image.PreserveAspectCrop
isOwner: root.privilegesLevel === Constants.TokenPrivilegesLevel.Owner
Loader {