Use a component to display image link previews
This commit is contained in:
@@ -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] },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
src/qml/Chat/Timeline/EventImage.qml
Normal file
31
src/qml/Chat/Timeline/EventImage.qml
Normal 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
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
Reference in New Issue
Block a user