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:
parent
a80f294610
commit
c6395ff940
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 : ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user