feat: Unfurl images (#11940)
This commit is contained in:
parent
7274e6156e
commit
3560786e2a
|
@ -9,24 +9,12 @@ type
|
|||
Hostname
|
||||
Title
|
||||
Description
|
||||
LinkType
|
||||
ThumbnailWidth
|
||||
ThumbnailHeight
|
||||
ThumbnailUrl
|
||||
ThumbnailDataUri
|
||||
|
||||
#
|
||||
# TODO:
|
||||
#
|
||||
# Consider adding a `LinkType` property, which would probably follow the way of unfurling:
|
||||
# - basic (maybe divide OpenGraph/oEmbed/...)
|
||||
# - image (contantType == "image/.*")
|
||||
# - status link (hostname == "status.app")
|
||||
#
|
||||
# In future, we can also unfurl other types, like PDF/audio/etc !
|
||||
#
|
||||
# This is needed on receiver side to know how to render the preview
|
||||
# and what to do on click.
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
|
@ -79,6 +67,7 @@ QtObject:
|
|||
ModelRole.Hostname.int:"hostname",
|
||||
ModelRole.Title.int:"title",
|
||||
ModelRole.Description.int:"description",
|
||||
ModelRole.LinkType.int:"linkType",
|
||||
ModelRole.ThumbnailWidth.int:"thumbnailWidth",
|
||||
ModelRole.ThumbnailHeight.int:"thumbnailHeight",
|
||||
ModelRole.ThumbnailUrl.int:"thumbnailUrl",
|
||||
|
@ -87,14 +76,16 @@ QtObject:
|
|||
|
||||
method allLinkPreviewRoles(self: Model): seq[int] =
|
||||
return @[
|
||||
Unfurled.int,
|
||||
Hostname.int,
|
||||
Title.int,
|
||||
Description.int,
|
||||
ThumbnailWidth.int,
|
||||
ThumbnailHeight.int,
|
||||
ThumbnailUrl.int,
|
||||
ThumbnailDataUri.int,
|
||||
ModelRole.Url.int,
|
||||
ModelRole.Unfurled.int,
|
||||
ModelRole.Hostname.int,
|
||||
ModelRole.Title.int,
|
||||
ModelRole.Description.int,
|
||||
ModelRole.LinkType.int,
|
||||
ModelRole.ThumbnailWidth.int,
|
||||
ModelRole.ThumbnailHeight.int,
|
||||
ModelRole.ThumbnailUrl.int,
|
||||
ModelRole.ThumbnailDataUri.int,
|
||||
]
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -118,6 +109,8 @@ QtObject:
|
|||
result = newQVariant(item.linkPreview.title)
|
||||
of ModelRole.Description:
|
||||
result = newQVariant(item.linkPreview.description)
|
||||
of ModelRole.LinkType:
|
||||
result = newQVariant(item.linkPreview.linkType.int)
|
||||
of ModelRole.ThumbnailWidth:
|
||||
result = newQVariant(item.linkPreview.thumbnail.width)
|
||||
of ModelRole.ThumbnailHeight:
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
import json, strformat, tables
|
||||
include ../../../common/json_utils
|
||||
|
||||
type
|
||||
LinkType* {.pure.} = enum
|
||||
Link = 0
|
||||
Image
|
||||
|
||||
proc toLinkType*(value: int): LinkType =
|
||||
try:
|
||||
return LinkType(value)
|
||||
except RangeDefect:
|
||||
return LinkType.Link
|
||||
|
||||
type
|
||||
LinkPreviewThumbnail* = object
|
||||
width*: int
|
||||
|
@ -15,6 +26,7 @@ type
|
|||
title*: string
|
||||
description*: string
|
||||
thumbnail*: LinkPreviewThumbnail
|
||||
linkType*: LinkType
|
||||
|
||||
proc delete*(self: LinkPreview) =
|
||||
discard
|
||||
|
@ -37,6 +49,7 @@ proc toLinkPreview*(jsonObj: JsonNode): LinkPreview =
|
|||
discard jsonObj.getProp("title", result.title)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("hostname", result.hostname)
|
||||
result.linkType = toLinkType(jsonObj["type"].getInt)
|
||||
|
||||
var thumbnail: JsonNode
|
||||
if jsonObj.getProp("thumbnail", thumbnail):
|
||||
|
@ -46,15 +59,27 @@ proc `$`*(self: LinkPreviewThumbnail): string =
|
|||
result = fmt"""LinkPreviewThumbnail(
|
||||
width: {self.width},
|
||||
height: {self.height},
|
||||
url: {self.url},
|
||||
dataUri: {self.dataUri}
|
||||
urlLength: {self.url.len},
|
||||
dataUriLength: {self.dataUri.len}
|
||||
)"""
|
||||
|
||||
proc `$`*(self: LinkPreview): string =
|
||||
result = fmt"""LinkPreview(
|
||||
type: {self.linkType},
|
||||
url: {self.url},
|
||||
hostname: {self.hostname},
|
||||
title: {self.title},
|
||||
description: {self.description},
|
||||
thumbnail: {self.thumbnail}
|
||||
)"""
|
||||
|
||||
# Custom JSON converter to force `linkType` integer instead of string
|
||||
proc `%`*(self: LinkPreview): JsonNode =
|
||||
result = %* {
|
||||
"type": self.linkType.int,
|
||||
"url": self.url,
|
||||
"hostname": self.hostname,
|
||||
"title": self.title,
|
||||
"description": self.description,
|
||||
"thumbnail": %self.thumbnail,
|
||||
}
|
||||
|
|
|
@ -32,36 +32,35 @@ ColumnLayout {
|
|||
id: linkMessageLoader
|
||||
|
||||
// properties from the model
|
||||
required property string url
|
||||
required property bool unfurled
|
||||
required property string hostname
|
||||
required property string title
|
||||
required property string description
|
||||
required property string hostname
|
||||
required property int linkType
|
||||
required property int thumbnailWidth
|
||||
required property int thumbnailHeight
|
||||
required property string thumbnailUrl
|
||||
required property string thumbnailDataUri
|
||||
|
||||
asynchronous: true
|
||||
sourceComponent: unfurledLinkComponent
|
||||
|
||||
StateGroup {
|
||||
//Using StateGroup as a warkardound for https://bugreports.qt.io/browse/QTBUG-47796
|
||||
states: [
|
||||
State {
|
||||
name: "loadLinkPreview"
|
||||
when: !linkMessageLoader.isImage && !linkMessageLoader.isStatusDeepLink
|
||||
when: linkMessageLoader.linkType === Constants.LinkPreviewType.Link
|
||||
PropertyChanges { target: linkMessageLoader; sourceComponent: unfurledLinkComponent }
|
||||
},
|
||||
State {
|
||||
name: "loadImage"
|
||||
when: linkMessageLoader.linkType === Constants.LinkPreviewType.Image
|
||||
PropertyChanges { target: linkMessageLoader; sourceComponent: unfurledImageComponent }
|
||||
}
|
||||
// NOTE: New unfurling not yet suppport images and status links.
|
||||
// NOTE: New unfurling not yet suppport status links.
|
||||
// Uncomment code below when implemented:
|
||||
// - https://github.com/status-im/status-go/issues/3761
|
||||
// - https://github.com/status-im/status-go/issues/3762
|
||||
|
||||
// State {
|
||||
// name: "loadImage"
|
||||
// when: linkMessageLoader.isImage
|
||||
// PropertyChanges { target: linkMessageLoader; sourceComponent: unfurledImageComponent }
|
||||
// },
|
||||
// State {
|
||||
// name: "statusInvitation"
|
||||
// when: linkMessageLoader.isStatusDeepLink
|
||||
|
@ -88,13 +87,13 @@ ColumnLayout {
|
|||
|
||||
objectName: "LinksMessageView_unfurledImageComponent_linkImage"
|
||||
anchors.centerIn: parent
|
||||
source: result.thumbnailUrl
|
||||
source: thumbnailUrl
|
||||
imageWidth: 300
|
||||
isCurrentUser: root.isCurrentUser
|
||||
playing: globalAnimationEnabled && localAnimationEnabled
|
||||
isOnline: root.store.mainModuleInst.isOnline
|
||||
asynchronous: true
|
||||
isAnimated: result.contentType ? result.contentType.toLowerCase().endsWith("gif") : false
|
||||
isAnimated: false // FIXME: GIFs are not supported with new unfurling yet
|
||||
onClicked: {
|
||||
if (isAnimated && !playing)
|
||||
localAnimationEnabled = true
|
||||
|
@ -190,7 +189,7 @@ ColumnLayout {
|
|||
isOnline: root.store.mainModuleInst.isOnline
|
||||
asynchronous: true
|
||||
onClicked: {
|
||||
Global.openLink(result.address)
|
||||
Global.openLink(url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +226,7 @@ ColumnLayout {
|
|||
anchors.bottom: linkSite.bottom
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Global.openLink(link)
|
||||
Global.openLink(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1181,4 +1181,9 @@ QtObject {
|
|||
For1min = 6,
|
||||
Unmuted = 7
|
||||
}
|
||||
|
||||
enum LinkPreviewType {
|
||||
Link = 0,
|
||||
Image = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3bf0bed78da660b0a361afd285ec229dcef7de70
|
||||
Subproject commit 09a988607deaa0282d4330f71bbc93053977d621
|
Loading…
Reference in New Issue