diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml
index d80d274d..c3957fec 100644
--- a/resources/qml/MessageView.qml
+++ b/resources/qml/MessageView.qml
@@ -49,7 +49,7 @@ ScrollView {
property var attachedPos: chat.contentY, attached ? chat.mapFromItem(attached, attached ? attached.width - width : 0, -height) : null
readonly property int padding: 4
- visible: Settings.buttonsInTimeline && !!attached && (attached.hovered || messageActionHover.hovered)
+ visible: !Settings.mobileMode && (Settings.buttonsInTimeline && !!attached && (attached.hovered || messageActionHover.hovered))
x: attached ? attachedPos.x : 0
y: attached ? attachedPos.y : 0
z: 10
@@ -134,6 +134,13 @@ ScrollView {
}
+ MobileMessageContextPopup {
+ id: mobileContextPopup
+
+ visible: false
+ anchors.fill: parent
+ }
+
ScrollHelper {
flickable: parent
anchors.fill: parent
@@ -477,7 +484,6 @@ ScrollView {
}
}
}
-
}
Connections {
@@ -544,6 +550,9 @@ ScrollView {
open();
}
+ // make sure that we close the popup when this menu is closed
+ onAboutToHide: if (mobileContextPopup.visible) mobileContextPopup.hide()
+
Platform.MenuItem {
visible: messageContextMenu.text
enabled: visible
diff --git a/resources/qml/MobileMessageContextPopup.qml b/resources/qml/MobileMessageContextPopup.qml
new file mode 100644
index 00000000..f65be5d5
--- /dev/null
+++ b/resources/qml/MobileMessageContextPopup.qml
@@ -0,0 +1,161 @@
+import QtQuick 2.12
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.12
+import im.nheko 1.0
+import "./emoji"
+import "./delegates"
+
+Item {
+ id: popupRoot
+
+ // TODO: make this use permissions etc. like the desktop menu
+ function show(attachment, messageModel) {
+ attached = attachment
+ model = messageModel
+ visible = true
+ popup.state = "shown"
+ }
+
+ function hide() {
+ popup.state = "hidden"
+ visible = false
+ attached = undefined
+ model = undefined
+ }
+
+ property Item attached: null
+ property alias model: row.model
+
+ Rectangle {
+ id: popup
+
+ radius: 20
+ z: 20
+ anchors.bottom: parent.bottom
+ height: 75
+ width: parent.width
+ color: colors.window
+
+ RowLayout {
+ id: row
+
+ property var model
+
+ spacing: 5
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.margins: 10
+ anchors.fill: parent
+
+ // without this, the buttons tend to hug the sides
+ anchors.leftMargin: 10
+ anchors.rightMargin: anchors.leftMargin
+
+ ImageButton {
+ id: editButton
+
+ visible: !!row.model && row.model.isEditable
+ buttonTextColor: colors.buttonText
+ Layout.minimumWidth: 20
+ Layout.preferredWidth: 35
+ Layout.preferredHeight: Layout.preferredWidth
+ Layout.minimumHeight: Layout.minimumWidth
+ height: width
+ Layout.alignment: Qt.AlignHCenter
+ hoverEnabled: true
+ image: ":/icons/icons/ui/edit.png"
+ ToolTip.visible: hovered
+ ToolTip.text: row.model && row.model.isEditable ? qsTr("Edit") : qsTr("Edited")
+ onClicked: {
+ if (row.model.isEditable)
+ TimelineManager.timeline.editAction(row.model.id);
+ popupRoot.hide()
+ }
+ }
+
+ EmojiButton {
+ id: reactButton
+
+ Layout.minimumWidth: 20
+ Layout.preferredWidth: 35
+ Layout.preferredHeight: Layout.preferredWidth
+ Layout.minimumHeight: Layout.minimumWidth
+ height: width
+ Layout.alignment: Qt.AlignHCenter
+ hoverEnabled: true
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("React")
+ emojiPicker: emojiPopup
+ event_id: row.model ? row.model.id : ""
+ }
+
+ ImageButton {
+ id: replyButton
+
+ Layout.minimumWidth: 20
+ Layout.preferredWidth: 35
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: Layout.preferredWidth
+ Layout.minimumHeight: Layout.minimumWidth
+ height: width
+ hoverEnabled: true
+ image: ":/icons/icons/ui/mail-reply.png"
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("Reply")
+ onClicked: {
+ TimelineManager.timeline.replyAction(row.model.id)
+ popupRoot.hide()
+ }
+ }
+
+ ImageButton {
+ id: optionsButton
+
+ Layout.minimumWidth: 20
+ Layout.preferredWidth: 35
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: Layout.preferredWidth
+ Layout.minimumHeight: Layout.minimumWidth
+ height: width
+ hoverEnabled: true
+ image: ":/icons/icons/ui/vertical-ellipsis.png"
+ ToolTip.visible: hovered
+ ToolTip.text: qsTr("Options")
+ onClicked: messageContextMenu.show(row.model.id, row.model.type, row.model.isEncrypted, row.model.isEditable, optionsButton)
+ }
+ }
+
+ Rectangle {
+ id: popupBottomBar
+
+ z: popup.z - 1
+ anchors.bottom: popup.bottom
+ height: popup.radius
+ width: popup.width
+ color: popup.color
+ }
+ }
+
+ Rectangle {
+ id: overlay
+ anchors.fill: parent
+ z: popupBottomBar.z - 1
+
+ color: "gray"
+ opacity: 0.5
+
+ TapHandler {
+ onTapped: popupRoot.hide()
+ }
+ }
+
+ // TODO: this needs some love
+ FastBlur {
+ z: overlay.z - 1
+ anchors.fill: parent
+ source: timelineRoot
+ radius: 50
+ }
+}
diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml
index c612479a..70ebf91d 100644
--- a/resources/qml/TimelineRow.qml
+++ b/resources/qml/TimelineRow.qml
@@ -65,7 +65,13 @@ Item {
}
TapHandler {
- onLongPressed: messageContextMenu.show(eventId, type, isSender, isEncrypted, isEditable, contentItem.child.hoveredLink, contentItem.child.copyText)
+ onLongPressed: {
+ if (Settings.mobileMode)
+ mobileContextPopup.show(r, model);
+ else
+ messageContextMenu.show(eventId, type, isSender, isEncrypted, isEditable, contentItem.child.hoveredLink, contentItem.child.copyText)
+
+ }
onDoubleTapped: chat.model.reply = eventId
gesturePolicy: TapHandler.ReleaseWithinBounds
}
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 91bbca5b..ad3f9518 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -273,3 +273,4 @@ Item {
}
}
+}
diff --git a/resources/res.qrc b/resources/res.qrc
index 3514ebca..b9e324c0 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -183,6 +183,7 @@
qml/InviteDialog.qml
qml/ReadReceipts.qml
qml/RawMessageDialog.qml
+ qml/MobileMessageContextPopup.qml
media/ring.ogg