Use a component to display image link previews

This commit is contained in:
miruka
2019-09-03 03:04:57 -04:00
parent 3c4ca7d433
commit 5674d0c7b7
10 changed files with 147 additions and 100 deletions

View File

@@ -7,7 +7,6 @@ Row {
id: eventContent
spacing: theme.spacing / 2
readonly property string eventText: Utils.processedEventText(model)
readonly property string eventTime: Utils.formatTime(model.date)
readonly property int eventTimeSpaces: 2
@@ -29,8 +28,8 @@ Row {
HoverHandler { id: hover }
Item {
width: hideAvatar ? 0 : 48
height: hideAvatar ? 0 : collapseAvatar ? 1 : smallAvatar ? 28 : 48
width: hideAvatar ? 0 : 58
height: hideAvatar ? 0 : collapseAvatar ? 1 : smallAvatar ? 28 : 58
opacity: hideAvatar || collapseAvatar ? 0 : 1
visible: width > 0
@@ -39,8 +38,8 @@ Row {
userId: model.sender_id
displayName: model.sender_name
avatarUrl: model.sender_avatar
width: hideAvatar ? 0 : 48
height: hideAvatar ? 0 : collapseAvatar ? 1 : 48
width: hideAvatar ? 0 : 58
height: hideAvatar ? 0 : collapseAvatar ? 1 : 58
}
}
@@ -55,15 +54,18 @@ Row {
theme.fontSize.normal * 0.5 * 75, // 600 with 16px font
Math.max(
nameLabel.visible ? nameLabel.implicitWidth : 0,
contentLabel.implicitWidth
contentLabel.implicitWidth,
)
)
height: (nameLabel.visible ? nameLabel.height : 0) +
contentLabel.implicitHeight
height: childrenRect.height
y: parent.height / 2 - height / 2
Column {
anchors.fill: parent
id: mainColumn
width: parent.width
spacing: theme.spacing / 1.75
topPadding: theme.spacing / 1.75
bottomPadding: topPadding
HSelectableLabel {
id: nameLabel
@@ -71,6 +73,8 @@ Row {
visible: ! hideNameLine
container: selectableLabelContainer
selectable: ! unselectableNameLine
leftPadding: eventContent.spacing
rightPadding: leftPadding
// This is +0.1 and content is +0 instead of the opposite,
// because the eventList is reversed
@@ -81,10 +85,6 @@ Row {
// elide: Text.ElideRight
horizontalAlignment: onRight ? Text.AlignRight : Text.AlignLeft
leftPadding: theme.spacing
rightPadding: leftPadding
topPadding: theme.spacing / 2
function selectAllTextPlus() {
contentLabel.selectAllTextPlus()
}
@@ -97,6 +97,10 @@ Row {
width: parent.width
container: selectableLabelContainer
index: model.index
leftPadding: eventContent.spacing
rightPadding: leftPadding
bottomPadding: previewLinksRepeater.count > 0 ?
mainColumn.bottomPadding : 0
text: theme.chat.message.styleInclude +
eventContent.eventText +
@@ -115,12 +119,6 @@ Row {
wrapMode: Text.Wrap
textFormat: Text.RichText
leftPadding: theme.spacing
rightPadding: leftPadding
topPadding: nameLabel.visible ? 0 : bottomPadding
bottomPadding: theme.spacing / 2
function selectAllText() {
// Select the message body without the date or name
container.clearSelection()
@@ -142,6 +140,22 @@ Row {
HoverHandler { id: contentHover }
}
Repeater {
id: previewLinksRepeater
model: previewLinks
HLoader {
Component.onCompleted: {
if (modelData[0] == "image") {
setSource(
"EventImage.qml",
{ source: modelData[1] },
)
}
}
}
}
}
}
}

View File

@@ -1,9 +1,19 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
import "../../utils.js" as Utils
Column {
id: eventDelegate
width: eventList.width
topPadding:
model.event_type == "RoomCreateEvent" ? 0 :
dayBreak ? theme.spacing * 4 :
talkBreak ? theme.spacing * 6 :
combine ? theme.spacing / 2 :
theme.spacing * 2
// Remember timeline goes from newest message at index 0 to oldest
property var previousItem: eventList.model.get(model.index + 1)
@@ -38,14 +48,9 @@ Column {
readonly property bool unselectableNameLine:
hideNameLine && ! (onRight && ! combine)
width: eventList.width
readonly property var previewLinks: model.preview_links
topPadding:
model.event_type == "RoomCreateEvent" ? 0 :
dayBreak ? theme.spacing * 4 :
talkBreak ? theme.spacing * 6 :
combine ? theme.spacing / 2 :
theme.spacing * 2
property string hoveredImage: ""
Daybreak {
@@ -70,15 +75,8 @@ Column {
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: {
contextMenu.link = eventContent.hoveredLink
contextMenu.popup()
}
}
TapHandler {
acceptedButtons: Qt.LeftButton | Qt.RightButton
onLongPressed: {
contextMenu.link = eventContent.hoveredLink
contextMenu.link = eventContent.hoveredLink
contextMenu.image = eventDelegate.hoveredImage
contextMenu.popup()
}
}
@@ -87,8 +85,17 @@ Column {
id: contextMenu
property string link: ""
property string image: ""
onClosed: link = ""
onClosed: { link = ""; image = "" }
HMenuItem {
id: copyImage
icon.name: "copy-link"
text: qsTr("Copy image address")
visible: Boolean(contextMenu.image)
onTriggered: Utils.copyToClipboard(contextMenu.image)
}
HMenuItem {
id: copyLink
@@ -101,12 +108,25 @@ Column {
HMenuItem {
icon.name: "copy-text"
text: qsTr("Copy text")
visible: enabled || ! copyLink.visible
visible: enabled || (! copyLink.visible && ! copyImage.visible)
enabled: Boolean(selectableLabelContainer.joinedSelection)
onTriggered:
Utils.copyToClipboard(selectableLabelContainer.joinedSelection)
}
HMenuItem {
icon.name: "settings"
text: qsTr("Print event item")
visible: debugMode
onTriggered: print(JSON.stringify(Utils.getItem(
modelSources[[
"Event", chatPage.userId, chatPage.roomId
]],
"client_id",
model.client_id
), null, 4))
}
HMenuItem {
icon.name: "settings"
text: qsTr("Set as debug console target")
@@ -114,6 +134,6 @@ Column {
onTriggered: {
mainUI.debugConsole.target = [eventDelegate, eventContent]
}
}
}
}
}

View File

@@ -0,0 +1,31 @@
import QtQuick 2.12
import "../../Base"
HImage {
id: image
x: eventContent.spacing
sourceSize.width: maxDimension
sourceSize.height: maxDimension
width: Math.min(
mainColumn.width - eventContent.spacing * 2,
implicitWidth,
maxDimension,
)
property int maxDimension: window.settings.messageImageMaxThumbnailSize
TapHandler {
onTapped: Qt.openUrlExternally(image.source)
}
HoverHandler {
id: hover
onHoveredChanged: eventDelegate.hoveredImage = hovered ? image.source : ""
}
MouseArea {
anchors.fill: image
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
}
}

View File

@@ -177,7 +177,7 @@ Rectangle {
}
HNoticePage {
text: qsTr("No messages visible yet.")
text: qsTr("No messages visible yet")
visible: eventList.model.count < 1
anchors.fill: parent