EventDelegate context menu, EventFile click

Improve/extend choosing the cursor shape, how context menu handles the
current hovered thing, and open link on EventFile click
This commit is contained in:
miruka 2019-09-14 18:33:32 -04:00
parent a80f294610
commit c6395ff940
6 changed files with 70 additions and 58 deletions

View File

@ -71,7 +71,8 @@ HButton {
TapHandler {
enabled: contextMenu.count > 0
acceptedButtons: Qt.RightButton
onTapped: if (contextMenu.count > 0) contextMenu.popup()
onTapped: contextMenu.popup()
}
}

View File

@ -7,26 +7,16 @@ Row {
id: eventContent
spacing: theme.spacing / 1.25
readonly property string eventText: Utils.processedEventText(model)
readonly property string eventTime: Utils.formatTime(model.date, false)
readonly property string hoveredLink:
nameLabel.hoveredLink || contentLabel.hoveredLink
property string hoveredImage: ""
readonly property bool hoveredSelectable:
nameHover.hovered || contentHover.hovered
readonly property int cursorShape:
hoveredLink || hoveredImage ? Qt.PointingHandCursor :
nameHover.hovered || contentHover.hovered ? Qt.IBeamCursor :
Qt.ArrowCursor
// Needed because of eventList's MouseArea which steals the
// HSelectableLabel's MouseArea hover events
onCursorShapeChanged: eventList.cursorShape = cursorShape
HoverHandler { id: hover }
Item {
width: hideAvatar ? 0 : 58

View File

@ -14,11 +14,14 @@ Column {
theme.spacing * 2
enum Media { Page, File, Image, Video, Audio }
property var hoveredMediaTypeUrl: []
// Remember timeline goes from newest message at index 0 to oldest
property var previousItem: eventList.model.get(model.index + 1)
property var nextItem: eventList.model.get(model.index - 1)
readonly property QtObject currentItem: model
property int modelIndex: model.index
onModelIndexChanged: {
previousItem = eventList.model.get(model.index + 1)
@ -48,6 +51,18 @@ Column {
readonly property bool unselectableNameLine:
hideNameLine && ! (onRight && ! combine)
readonly property int cursorShape:
eventContent.hoveredLink || hoveredMediaTypeUrl.length > 0 ?
Qt.PointingHandCursor :
eventContent.hoveredSelectable ? Qt.IBeamCursor :
Qt.ArrowCursor
// Needed because of eventList's MouseArea which steals the
// HSelectableLabel's MouseArea hover events
onCursorShapeChanged: eventList.cursorShape = cursorShape
function json() {
return JSON.stringify(
@ -84,8 +99,8 @@ Column {
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: {
contextMenu.media = eventDelegate.hoveredMediaTypeUrl
contextMenu.link = eventContent.hoveredLink
contextMenu.image = eventContent.hoveredImage
contextMenu.popup()
}
}
@ -93,17 +108,36 @@ Column {
HMenu {
id: contextMenu
property var media: []
property string link: ""
property string image: ""
onClosed: { link = ""; image = "" }
onClosed: { media = []; link = "" }
HMenuItem {
id: copyImage
id: copyMedia
icon.name: "copy-link"
text: qsTr("Copy image address")
visible: Boolean(contextMenu.image)
onTriggered: Utils.copyToClipboard(contextMenu.image)
text:
contextMenu.media.length < 1 ? "" :
contextMenu.media[0] === EventDelegate.Media.Page ?
qsTr("Copy page address") :
contextMenu.media[0] === EventDelegate.Media.File ?
qsTr("Copy file address") :
contextMenu.media[0] === EventDelegate.Media.Image ?
qsTr("Copy image address") :
contextMenu.media[0] === EventDelegate.Media.Video ?
qsTr("Copy video address") :
contextMenu.media[0] === EventDelegate.Media.Audio ?
qsTr("Copy audio address") :
qsTr("Copy media address")
visible: Boolean(text)
onTriggered: Utils.copyToClipboard(contextMenu.media[1])
}
HMenuItem {
@ -117,7 +151,7 @@ Column {
HMenuItem {
icon.name: "copy-text"
text: qsTr("Copy text")
visible: enabled || (! copyLink.visible && ! copyImage.visible)
visible: enabled || (! copyLink.visible && ! copyMedia.visible)
enabled: Boolean(selectableLabelContainer.joinedSelection)
onTriggered:
Utils.copyToClipboard(selectableLabelContainer.joinedSelection)

View File

@ -8,6 +8,12 @@ HTile {
theme.chat.message.thumbnailWidth,
)
onClicked: Qt.openUrlExternally(fileUrl)
onHoveredChanged:
eventDelegate.hoveredMediaTypeUrl =
hovered ? [EventDelegate.Media.File, fileUrl] : []
property url thumbnailUrl
property url fileUrl
@ -23,16 +29,4 @@ HTile {
image: HIcon {
svgName: "download"
}
TapHandler {
acceptedButtons: Qt.LeftButton
onTapped: Qt.openUrlExternally(file.fileUrl)
}
HoverHandler {
id: hover
onHoveredChanged:
eventContent.hoveredImage = hovered ? file.fileUrl : ""
}
}

View File

@ -17,19 +17,14 @@ HImage {
TapHandler {
onTapped: if (! image.animated) Qt.openUrlExternally(image.fullSource)
onDoubleTapped: Qt.openUrlExternally(image.fullSource)
onTapped: if (! image.animated) Qt.openUrlExternally(fullSource)
onDoubleTapped: Qt.openUrlExternally(fullSource)
}
HoverHandler {
id: hover
onHoveredChanged:
eventContent.hoveredImage = hovered ? image.fullSource : ""
}
MouseArea {
anchors.fill: image
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
eventDelegate.hoveredMediaTypeUrl =
hovered ? [EventDelegate.Media.Image, fullSource] : []
}
}

View File

@ -7,8 +7,6 @@ HLoader {
x: eventContent.spacing
enum Type { Page, File, Image, Video, Audio }
property QtObject info
property url mediaUrl
@ -30,35 +28,35 @@ HLoader {
readonly property int type: {
let main_type = info.media_mime.split("/")[0].toLowerCase()
if (main_type === "image") return EventMediaLoader.Type.Image
if (main_type === "video") return EventMediaLoader.Type.Video
if (main_type === "audio") return EventMediaLoader.Type.Audio
if (main_type === "image") return EventDelegate.Media.Image
if (main_type === "video") return EventDelegate.Media.Video
if (main_type === "audio") return EventDelegate.Media.Audio
if (info.event_type === "RoomMessageFile")
return EventMediaLoader.Type.File
return EventDelegate.Media.File
let ext = Utils.urlExtension(mediaUrl)
if (imageExtensions.includes(ext)) return EventMediaLoader.Type.Image
if (videoExtensions.includes(ext)) return EventMediaLoader.Type.Video
if (audioExtensions.includes(ext)) return EventMediaLoader.Type.Audio
if (imageExtensions.includes(ext)) return EventDelegate.Media.Image
if (videoExtensions.includes(ext)) return EventDelegate.Media.Video
if (audioExtensions.includes(ext)) return EventDelegate.Media.Audio
return EventMediaLoader.Type.Page
return EventDelegate.Media.Page
}
readonly property url previewUrl: (
type === EventMediaLoader.Type.File ||
type === EventMediaLoader.Type.Image ?
type === EventDelegate.Media.File ||
type === EventDelegate.Media.Image ?
info.thumbnail_url : ""
) || mediaUrl
onPreviewUrlChanged: {
if (type === EventMediaLoader.Type.Image) {
if (type === EventDelegate.Media.Image) {
var file = "EventImage.qml"
var props = { source: previewUrl, fullSource: mediaUrl }
} else if (type === EventMediaLoader.Type.File) {
} else if (type === EventDelegate.Media.File) {
var file = "EventFile.qml"
var props = {
thumbnailUrl: previewUrl,