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 { TapHandler {
enabled: contextMenu.count > 0
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
onTapped: if (contextMenu.count > 0) contextMenu.popup() onTapped: contextMenu.popup()
} }
} }

View File

@ -7,26 +7,16 @@ Row {
id: eventContent id: eventContent
spacing: theme.spacing / 1.25 spacing: theme.spacing / 1.25
readonly property string eventText: Utils.processedEventText(model) readonly property string eventText: Utils.processedEventText(model)
readonly property string eventTime: Utils.formatTime(model.date, false) readonly property string eventTime: Utils.formatTime(model.date, false)
readonly property string hoveredLink: readonly property string hoveredLink:
nameLabel.hoveredLink || contentLabel.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 { Item {
width: hideAvatar ? 0 : 58 width: hideAvatar ? 0 : 58

View File

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

View File

@ -8,6 +8,12 @@ HTile {
theme.chat.message.thumbnailWidth, theme.chat.message.thumbnailWidth,
) )
onClicked: Qt.openUrlExternally(fileUrl)
onHoveredChanged:
eventDelegate.hoveredMediaTypeUrl =
hovered ? [EventDelegate.Media.File, fileUrl] : []
property url thumbnailUrl property url thumbnailUrl
property url fileUrl property url fileUrl
@ -23,16 +29,4 @@ HTile {
image: HIcon { image: HIcon {
svgName: "download" 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 { TapHandler {
onTapped: if (! image.animated) Qt.openUrlExternally(image.fullSource) onTapped: if (! image.animated) Qt.openUrlExternally(fullSource)
onDoubleTapped: Qt.openUrlExternally(image.fullSource) onDoubleTapped: Qt.openUrlExternally(fullSource)
} }
HoverHandler { HoverHandler {
id: hover id: hover
onHoveredChanged: onHoveredChanged:
eventContent.hoveredImage = hovered ? image.fullSource : "" eventDelegate.hoveredMediaTypeUrl =
} hovered ? [EventDelegate.Media.Image, fullSource] : []
MouseArea {
anchors.fill: image
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
} }
} }

View File

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