Create a mobile popup menu

This is much better suited to a mobile setting than a traditional context menu is.

Warning: this still is pretty basic and may be heavily modified in the future.
This commit is contained in:
Loren Burkholder 2021-03-30 23:04:42 -04:00
parent 5610529bac
commit 6a77e55c72
5 changed files with 181 additions and 3 deletions

View file

@ -49,7 +49,7 @@ ScrollView {
property var attachedPos: chat.contentY, attached ? chat.mapFromItem(attached, attached ? attached.width - width : 0, -height) : null property var attachedPos: chat.contentY, attached ? chat.mapFromItem(attached, attached ? attached.width - width : 0, -height) : null
readonly property int padding: 4 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 x: attached ? attachedPos.x : 0
y: attached ? attachedPos.y : 0 y: attached ? attachedPos.y : 0
z: 10 z: 10
@ -134,6 +134,13 @@ ScrollView {
} }
MobileMessageContextPopup {
id: mobileContextPopup
visible: false
anchors.fill: parent
}
ScrollHelper { ScrollHelper {
flickable: parent flickable: parent
anchors.fill: parent anchors.fill: parent
@ -477,7 +484,6 @@ ScrollView {
} }
} }
} }
} }
Connections { Connections {
@ -544,6 +550,9 @@ ScrollView {
open(); open();
} }
// make sure that we close the popup when this menu is closed
onAboutToHide: if (mobileContextPopup.visible) mobileContextPopup.hide()
Platform.MenuItem { Platform.MenuItem {
visible: messageContextMenu.text visible: messageContextMenu.text
enabled: visible enabled: visible

View file

@ -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
}
}

View file

@ -65,7 +65,13 @@ Item {
} }
TapHandler { 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 onDoubleTapped: chat.model.reply = eventId
gesturePolicy: TapHandler.ReleaseWithinBounds gesturePolicy: TapHandler.ReleaseWithinBounds
} }

View file

@ -273,3 +273,4 @@ Item {
} }
} }
}

View file

@ -183,6 +183,7 @@
<file>qml/InviteDialog.qml</file> <file>qml/InviteDialog.qml</file>
<file>qml/ReadReceipts.qml</file> <file>qml/ReadReceipts.qml</file>
<file>qml/RawMessageDialog.qml</file> <file>qml/RawMessageDialog.qml</file>
<file>qml/MobileMessageContextPopup.qml</file>
</qresource> </qresource>
<qresource prefix="/media"> <qresource prefix="/media">
<file>media/ring.ogg</file> <file>media/ring.ogg</file>