diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml
index a459fe5a..f01911bb 100644
--- a/resources/qml/Avatar.qml
+++ b/resources/qml/Avatar.qml
@@ -90,4 +90,9 @@ Rectangle {
}
}
+ CursorShape {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ }
+
}
diff --git a/resources/qml/EncryptionIndicator.qml b/resources/qml/EncryptionIndicator.qml
index 46ca62c5..00efe9e4 100644
--- a/resources/qml/EncryptionIndicator.qml
+++ b/resources/qml/EncryptionIndicator.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.5
+import QtQuick 2.12
import QtQuick.Controls 2.1
import im.nheko 1.0
@@ -24,14 +24,11 @@ Rectangle {
color: "transparent"
width: 16
height: 16
- ToolTip.visible: ma.containsMouse && indicator.visible
+ ToolTip.visible: ma.hovered && indicator.visible
ToolTip.text: getEncryptionTooltip()
- MouseArea {
+ HoverHandler {
id: ma
-
- anchors.fill: parent
- hoverEnabled: true
}
Image {
diff --git a/resources/qml/ImageButton.qml b/resources/qml/ImageButton.qml
index 9c0faef3..159c750f 100644
--- a/resources/qml/ImageButton.qml
+++ b/resources/qml/ImageButton.qml
@@ -1,6 +1,7 @@
import "./ui"
import QtQuick 2.3
import QtQuick.Controls 2.3
+import im.nheko 1.0 // for cursor shape
AbstractButton {
id: button
@@ -23,11 +24,10 @@ AbstractButton {
source: image != "" ? ("image://colorimage/" + image + "?" + ((button.hovered && changeColorOnHover) ? highlightColor : buttonTextColor)) : ""
}
- MouseArea {
+ CursorShape {
id: mouseArea
anchors.fill: parent
- onPressed: mouse.accepted = false
cursorShape: Qt.PointingHandCursor
}
diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml
index bb3b4296..4ea15518 100644
--- a/resources/qml/MatrixText.qml
+++ b/resources/qml/MatrixText.qml
@@ -8,6 +8,7 @@ TextEdit {
focus: false
wrapMode: Text.Wrap
selectByMouse: !Settings.mobileMode
+ enabled: selectByMouse
color: colors.text
onLinkActivated: {
if (/^https:\/\/matrix.to\/#\/(@.*)$/.test(link)) {
@@ -25,12 +26,9 @@ TextEdit {
ToolTip.visible: hoveredLink
ToolTip.text: hoveredLink
- MouseArea {
- id: ma
-
+ CursorShape {
anchors.fill: parent
- acceptedButtons: Qt.NoButton
- cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
+ cursorShape: hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index 5d335872..b5c96660 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -139,6 +139,7 @@ Rectangle {
if (TimelineManager.timeline)
TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text);
+ forceActiveFocus();
}
onCursorRectangleChanged: textInput.ensureVisible(cursorRectangle)
onCursorPositionChanged: {
@@ -163,6 +164,10 @@ Rectangle {
TimelineManager.timeline.input.paste(false);
event.accepted = true;
} else if (event.key == Qt.Key_Space) {
+ // close popup if user enters space after colon
+ if (cursorPosition == completerTriggeredAt + 1)
+ popup.close();
+
if (popup.opened && popup.count <= 0)
popup.close();
@@ -256,16 +261,28 @@ Rectangle {
Connections {
ignoreUnknownSignals: true
- onInsertText: messageInput.insert(messageInput.cursorPosition, text)
+ onInsertText: {
+ messageInput.insert(messageInput.cursorPosition, text);
+ }
+ onTextChanged: {
+ messageInput.text = newText;
+ messageInput.cursorPosition = newText.length;
+ }
target: TimelineManager.timeline ? TimelineManager.timeline.input : null
}
Connections {
ignoreUnknownSignals: true
onReplyChanged: messageInput.forceActiveFocus()
+ onEditChanged: messageInput.forceActiveFocus()
target: TimelineManager.timeline
}
+ Connections {
+ target: TimelineManager
+ onFocusInput: messageInput.forceActiveFocus()
+ }
+
MouseArea {
// workaround for wrong cursor shape on some platforms
anchors.fill: parent
@@ -293,6 +310,7 @@ Rectangle {
ToolTip.text: qsTr("Emoji")
onClicked: emojiPopup.visible ? emojiPopup.close() : emojiPopup.show(emojiButton, function(emoji) {
messageInput.insert(messageInput.cursorPosition, emoji);
+ TimelineManager.focusMessageInput();
})
}
diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml
index 29115b00..e1641a36 100644
--- a/resources/qml/MessageView.qml
+++ b/resources/qml/MessageView.qml
@@ -1,200 +1,230 @@
import "./delegates"
import QtGraphicalEffects 1.0
-import QtQuick 2.9
+import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
import im.nheko 1.0
-ListView {
- id: chat
+ScrollView {
+ contentWidth: availableWidth
+ clip: false
+ palette: colors
+ padding: 8
- property int delegateMaxWidth: (Settings.timelineMaxWidth > 100 && (parent.width - Settings.timelineMaxWidth) > scrollbar.width * 2) ? Settings.timelineMaxWidth : (parent.width - scrollbar.width * 2 - 8)
+ ListView {
+ id: chat
- Layout.fillWidth: true
- Layout.fillHeight: true
- cacheBuffer: 400
- model: TimelineManager.timeline
- boundsBehavior: Flickable.StopAtBounds
- pixelAligned: true
- spacing: 4
- verticalLayoutDirection: ListView.BottomToTop
- onCountChanged: {
- // Mark timeline as read
- if (atYEnd)
- model.currentIndex = 0;
+ property int delegateMaxWidth: ((Settings.timelineMaxWidth > 100 && Settings.timelineMaxWidth < parent.availableWidth) ? Settings.timelineMaxWidth : parent.availableWidth) - parent.padding
- }
+ model: TimelineManager.timeline
+ boundsBehavior: Flickable.StopAtBounds
+ pixelAligned: true
+ spacing: 4
+ verticalLayoutDirection: ListView.BottomToTop
+ onCountChanged: {
+ // Mark timeline as read
+ if (atYEnd)
+ model.currentIndex = 0;
- ScrollHelper {
- flickable: parent
- anchors.fill: parent
- enabled: !Settings.mobileMode
- }
+ }
- Shortcut {
- sequence: StandardKey.MoveToPreviousPage
- onActivated: {
- chat.contentY = chat.contentY - chat.height / 2;
- chat.returnToBounds();
+ ScrollHelper {
+ flickable: parent
+ anchors.fill: parent
+ enabled: !Settings.mobileMode
}
- }
- Shortcut {
- sequence: StandardKey.MoveToNextPage
- onActivated: {
- chat.contentY = chat.contentY + chat.height / 2;
- chat.returnToBounds();
+ Shortcut {
+ sequence: StandardKey.MoveToPreviousPage
+ onActivated: {
+ chat.contentY = chat.contentY - chat.height / 2;
+ chat.returnToBounds();
+ }
}
- }
- Shortcut {
- sequence: StandardKey.Cancel
- onActivated: chat.model.reply = undefined
- }
+ Shortcut {
+ sequence: StandardKey.MoveToNextPage
+ onActivated: {
+ chat.contentY = chat.contentY + chat.height / 2;
+ chat.returnToBounds();
+ }
+ }
- Shortcut {
- sequence: "Alt+Up"
- onActivated: chat.model.reply = chat.model.indexToId(chat.model.reply ? chat.model.idToIndex(chat.model.reply) + 1 : 0)
- }
+ Shortcut {
+ sequence: StandardKey.Cancel
+ onActivated: {
+ if (chat.model.reply)
+ chat.model.reply = undefined;
+ else
+ chat.model.edit = undefined;
+ }
+ }
- Shortcut {
- sequence: "Alt+Down"
- onActivated: {
- var idx = chat.model.reply ? chat.model.idToIndex(chat.model.reply) - 1 : -1;
- chat.model.reply = idx >= 0 ? chat.model.indexToId(idx) : undefined;
+ Shortcut {
+ sequence: "Alt+Up"
+ onActivated: chat.model.reply = chat.model.indexToId(chat.model.reply ? chat.model.idToIndex(chat.model.reply) + 1 : 0)
}
- }
- Component {
- id: sectionHeader
-
- Column {
- topPadding: 4
- bottomPadding: 4
- spacing: 8
- visible: modelData && (modelData.previousMessageUserId !== modelData.userId || modelData.previousMessageDay !== modelData.day)
- width: parentWidth
- height: ((modelData && modelData.previousMessageDay !== modelData.day) ? dateBubble.height + 8 + userName.height : userName.height) + 8
-
- Label {
- id: dateBubble
-
- anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
- visible: modelData && modelData.previousMessageDay !== modelData.day
- text: modelData ? chat.model.formatDateSeparator(modelData.timestamp) : ""
- color: colors.text
- height: Math.round(fontMetrics.height * 1.4)
- width: contentWidth * 1.2
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- background: Rectangle {
- radius: parent.height / 2
- color: colors.window
- }
+ Shortcut {
+ sequence: "Alt+Down"
+ onActivated: {
+ var idx = chat.model.reply ? chat.model.idToIndex(chat.model.reply) - 1 : -1;
+ chat.model.reply = idx >= 0 ? chat.model.indexToId(idx) : undefined;
+ }
+ }
+ Shortcut {
+ sequence: "Ctrl+E"
+ onActivated: {
+ chat.model.edit = chat.model.reply;
}
+ }
- Row {
- height: userName.height
- spacing: 8
+ Connections {
+ target: TimelineManager
+ onFocusChanged: readTimer.running = TimelineManager.isWindowFocused
+ }
- Avatar {
- id: messageUserAvatar
- width: avatarSize
- height: avatarSize
- url: modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : ""
- displayName: modelData ? modelData.userName : ""
- userid: modelData ? modelData.userId : ""
- onClicked: chat.model.openUserProfile(modelData.userId)
- }
+ Timer {
+ id: readTimer
- Connections {
- target: chat.model
- onRoomAvatarUrlChanged: {
- messageUserAvatar.url = modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : ""
+ // force current read index to update
+ onTriggered: chat.model.setCurrentIndex(chat.model.currentIndex)
+ interval: 1000
+ }
+
+ Component {
+ id: sectionHeader
+
+ Column {
+ topPadding: 4
+ bottomPadding: 4
+ spacing: 8
+ visible: modelData && (modelData.previousMessageUserId !== modelData.userId || modelData.previousMessageDay !== modelData.day)
+ width: parentWidth
+ height: ((modelData && modelData.previousMessageDay !== modelData.day) ? dateBubble.height + 8 + userName.height : userName.height) + 8
+
+ Label {
+ id: dateBubble
+
+ anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
+ visible: modelData && modelData.previousMessageDay !== modelData.day
+ text: modelData ? chat.model.formatDateSeparator(modelData.timestamp) : ""
+ color: colors.text
+ height: Math.round(fontMetrics.height * 1.4)
+ width: contentWidth * 1.2
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ background: Rectangle {
+ radius: parent.height / 2
+ color: colors.window
}
+
}
- Label {
- id: userName
+ Row {
+ height: userName.height
+ spacing: 8
- text: modelData ? TimelineManager.escapeEmoji(modelData.userName) : ""
- color: TimelineManager.userColor(modelData ? modelData.userId : "", colors.window)
- textFormat: Text.RichText
+ Avatar {
+ id: messageUserAvatar
- MouseArea {
- anchors.fill: parent
- Layout.alignment: Qt.AlignHCenter
+ width: avatarSize
+ height: avatarSize
+ url: modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : ""
+ displayName: modelData ? modelData.userName : ""
+ userid: modelData ? modelData.userId : ""
onClicked: chat.model.openUserProfile(modelData.userId)
- cursorShape: Qt.PointingHandCursor
- propagateComposedEvents: true
}
- }
+ Connections {
+ target: chat.model
+ onRoomAvatarUrlChanged: {
+ messageUserAvatar.url = modelData ? chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") : "";
+ }
+ }
- Label {
- color: colors.buttonText
- text: modelData ? TimelineManager.userStatus(modelData.userId) : ""
- textFormat: Text.PlainText
- elide: Text.ElideRight
- width: chat.delegateMaxWidth - parent.spacing * 2 - userName.implicitWidth - avatarSize
- font.italic: true
- }
+ Label {
+ id: userName
- }
+ text: modelData ? TimelineManager.escapeEmoji(modelData.userName) : ""
+ color: TimelineManager.userColor(modelData ? modelData.userId : "", colors.window)
+ textFormat: Text.RichText
- }
+ TapHandler {
+ //cursorShape: Qt.PointingHandCursor
- }
+ onSingleTapped: chat.model.openUserProfile(modelData.userId)
+ }
- ScrollBar.vertical: ScrollBar {
- id: scrollbar
- }
+ CursorShape {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ }
- delegate: Item {
- id: wrapper
+ }
- anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
- width: chat.delegateMaxWidth
- height: section ? section.height + timelinerow.height : timelinerow.height
+ Label {
+ color: colors.buttonText
+ text: modelData ? TimelineManager.userStatus(modelData.userId) : ""
+ textFormat: Text.PlainText
+ elide: Text.ElideRight
+ width: chat.delegateMaxWidth - parent.spacing * 2 - userName.implicitWidth - avatarSize
+ font.italic: true
+ }
- Loader {
- id: section
+ }
- property var modelData: model
- property int parentWidth: parent.width
+ }
- active: model.previousMessageUserId !== undefined && model.previousMessageUserId !== model.userId || model.previousMessageDay !== model.day
- //asynchronous: true
- sourceComponent: sectionHeader
- visible: status == Loader.Ready
}
- TimelineRow {
- id: timelinerow
+ delegate: Item {
+ id: wrapper
- y: section.active && section.visible ? section.y + section.height : 0
- }
+ anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
+ width: chat.delegateMaxWidth
+ height: section ? section.height + timelinerow.height : timelinerow.height
- Connections {
- target: chat
- onMovementEnded: {
- if (y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height)
- chat.model.currentIndex = index;
+ Loader {
+ id: section
+ property var modelData: model
+ property int parentWidth: parent.width
+
+ active: model.previousMessageUserId !== undefined && model.previousMessageUserId !== model.userId || model.previousMessageDay !== model.day
+ //asynchronous: true
+ sourceComponent: sectionHeader
+ visible: status == Loader.Ready
}
+
+ TimelineRow {
+ id: timelinerow
+
+ y: section.active && section.visible ? section.y + section.height : 0
+ }
+
+ Connections {
+ target: chat
+ onMovementEnded: {
+ if (y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height)
+ chat.model.currentIndex = index;
+
+ }
+ }
+
}
- }
+ footer: BusyIndicator {
+ anchors.horizontalCenter: parent.horizontalCenter
+ running: chat.model && chat.model.paginationInProgress
+ height: 50
+ width: 50
+ z: 3
+ }
- footer: BusyIndicator {
- anchors.horizontalCenter: parent.horizontalCenter
- running: chat.model && chat.model.paginationInProgress
- height: 50
- width: 50
- z: 3
}
}
diff --git a/resources/qml/ReplyPopup.qml b/resources/qml/ReplyPopup.qml
index 4659e075..c07c2c44 100644
--- a/resources/qml/ReplyPopup.qml
+++ b/resources/qml/ReplyPopup.qml
@@ -10,15 +10,16 @@ Rectangle {
property var room: TimelineManager.timeline
Layout.fillWidth: true
- visible: room && room.reply
+ visible: room && (room.reply || room.edit)
// Height of child, plus margins, plus border
- implicitHeight: replyPreview.height + 10
+ implicitHeight: (room && room.reply ? replyPreview.height : closeEditButton.height) + 10
color: colors.window
z: 3
Reply {
id: replyPreview
+ visible: room && room.reply
anchors.left: parent.left
anchors.leftMargin: 2 * 22 + 3 * 16
anchors.right: closeReplyButton.left
@@ -32,8 +33,9 @@ Rectangle {
ImageButton {
id: closeReplyButton
+ visible: room && room.reply
anchors.right: parent.right
- anchors.rightMargin: 15
+ anchors.rightMargin: 16
anchors.top: replyPreview.top
hoverEnabled: true
width: 16
@@ -44,4 +46,17 @@ Rectangle {
onClicked: room.reply = undefined
}
+ Button {
+ id: closeEditButton
+
+ visible: room && room.edit
+ anchors.left: parent.left
+ anchors.rightMargin: 16
+ anchors.topMargin: 10
+ anchors.top: parent.top
+ //height: 16
+ text: qsTr("Cancel edit")
+ onClicked: room.edit = undefined
+ }
+
}
diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml
index 95a025cf..b731d29d 100644
--- a/resources/qml/TimelineRow.qml
+++ b/resources/qml/TimelineRow.qml
@@ -1,6 +1,6 @@
import "./delegates"
import "./emoji"
-import QtQuick 2.6
+import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
@@ -12,27 +12,24 @@ Item {
height: row.height
Rectangle {
- color: (Settings.messageHoverHighlight && hoverHandler.containsMouse) ? colors.alternateBase : "transparent"
+ color: (Settings.messageHoverHighlight && hoverHandler.hovered) ? colors.alternateBase : "transparent"
anchors.fill: row
}
- MouseArea {
+ HoverHandler {
id: hoverHandler
- anchors.fill: parent
- propagateComposedEvents: true
- preventStealing: false
- hoverEnabled: true
- acceptedButtons: Qt.AllButtons
- onClicked: {
- if (mouse.button === Qt.RightButton)
- messageContextMenu.show(model.id, model.type, model.isEncrypted, row);
- else
- mouse.accepted = false;
- }
- onPressAndHold: {
- messageContextMenu.show(model.id, model.type, model.isEncrypted, row, mapToItem(timelineRoot, mouse.x, mouse.y));
- }
+ acceptedDevices: PointerDevice.GenericPointer
+ }
+
+ TapHandler {
+ acceptedButtons: Qt.RightButton
+ onSingleTapped: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row, mapToItem(timelineRoot, eventPoint.position.x, eventPoint.position.y))
+ }
+
+ TapHandler {
+ onLongPressed: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, row, mapToItem(timelineRoot, point.position.x, point.position.y))
+ onDoubleTapped: chat.model.reply = model.id
}
RowLayout {
@@ -85,6 +82,25 @@ Item {
width: 16
}
+ ImageButton {
+ id: editButton
+
+ visible: (Settings.buttonsInTimeline && model.isEditable) || model.isEdited
+ buttonTextColor: chat.model.edit == model.id ? colors.highlight : colors.buttonText
+ Layout.alignment: Qt.AlignRight | Qt.AlignTop
+ Layout.preferredHeight: 16
+ width: 16
+ hoverEnabled: true
+ image: ":/icons/icons/ui/edit.png"
+ ToolTip.visible: hovered
+ ToolTip.text: model.isEditable ? qsTr("Edit") : qsTr("Edited")
+ onClicked: {
+ if (model.isEditable)
+ chat.model.editAction(model.id);
+
+ }
+ }
+
EmojiButton {
id: reactButton
@@ -124,7 +140,7 @@ Item {
image: ":/icons/icons/ui/vertical-ellipsis.png"
ToolTip.visible: hovered
ToolTip.text: qsTr("Options")
- onClicked: messageContextMenu.show(model.id, model.type, model.isEncrypted, optionsButton)
+ onClicked: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, optionsButton)
}
Label {
@@ -132,15 +148,11 @@ Item {
text: model.timestamp.toLocaleTimeString("HH:mm")
width: Math.max(implicitWidth, text.length * fontMetrics.maximumCharacterWidth)
color: inactiveColors.text
- ToolTip.visible: ma.containsMouse
+ ToolTip.visible: ma.hovered
ToolTip.text: Qt.formatDateTime(model.timestamp, Qt.DefaultLocaleLongDate)
- MouseArea {
+ HoverHandler {
id: ma
-
- anchors.fill: parent
- hoverEnabled: true
- propagateComposedEvents: true
}
}
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 7a33f25f..7db9d041 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -74,11 +74,13 @@ Page {
property string eventId
property int eventType
property bool isEncrypted
+ property bool isEditable
- function show(eventId_, eventType_, isEncrypted_, showAt_, position) {
+ function show(eventId_, eventType_, isEncrypted_, isEditable_, showAt_, position) {
eventId = eventId_;
eventType = eventType_;
isEncrypted = isEncrypted_;
+ isEditable = isEditable_;
if (position)
popup(position, showAt_);
else
@@ -100,6 +102,13 @@ Page {
}
MenuItem {
+ visible: messageContextMenu.isEditable
+ height: visible ? implicitHeight : 0
+ text: qsTr("Edit")
+ onClicked: TimelineManager.timeline.editAction(messageContextMenu.eventId)
+ }
+
+ MenuItem {
text: qsTr("Read receipts")
onTriggered: TimelineManager.timeline.readReceiptsAction(messageContextMenu.eventId)
}
diff --git a/resources/qml/UserProfile.qml b/resources/qml/UserProfile.qml
index e8d41073..003f6b3a 100644
--- a/resources/qml/UserProfile.qml
+++ b/resources/qml/UserProfile.qml
@@ -49,6 +49,7 @@ ApplicationWindow {
Text {
id: errorText
+
text: "Error Text"
color: "red"
visible: opacity > 0
@@ -58,24 +59,28 @@ ApplicationWindow {
SequentialAnimation {
id: hideErrorAnimation
+
running: false
+
PauseAnimation {
duration: 4000
}
+
NumberAnimation {
target: errorText
property: 'opacity'
to: 0
duration: 1000
}
+
}
- Connections{
+ Connections {
target: profile
onDisplayError: {
- errorText.text = errorMessage
- errorText.opacity = 1
- hideErrorAnimation.restart()
+ errorText.text = errorMessage;
+ errorText.opacity = 1;
+ hideErrorAnimation.restart();
}
}
diff --git a/resources/qml/delegates/FileMessage.qml b/resources/qml/delegates/FileMessage.qml
index ffd1e82b..4bc202eb 100644
--- a/resources/qml/delegates/FileMessage.qml
+++ b/resources/qml/delegates/FileMessage.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.6
+import QtQuick 2.12
import QtQuick.Layouts 1.2
import im.nheko 1.0
@@ -31,7 +31,15 @@ Item {
MouseArea {
anchors.fill: parent
- onClicked: TimelineManager.timeline.saveMedia(model.data.id)
+ cursorShape: Qt.PointingHandCursor
+ }
+
+ TapHandler {
+ onSingleTapped: TimelineManager.timeline.saveMedia(model.data.id)
+ }
+
+ CursorShape {
+ anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}
diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml
index e8e325f0..3bb9eb05 100644
--- a/resources/qml/delegates/ImageMessage.qml
+++ b/resources/qml/delegates/ImageMessage.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.6
+import QtQuick 2.12
import im.nheko 1.0
Item {
@@ -32,20 +32,20 @@ Item {
smooth: true
mipmap: true
- MouseArea {
- id: mouseArea
-
+ TapHandler {
enabled: model.data.type == MtxEvent.ImageMessage && img.status == Image.Ready
- hoverEnabled: true
- anchors.fill: parent
- onClicked: TimelineManager.openImageOverlay(model.data.url, model.data.id)
+ onSingleTapped: TimelineManager.openImageOverlay(model.data.url, model.data.id)
+ }
+
+ HoverHandler {
+ id: mouseArea
}
Item {
id: overlay
anchors.fill: parent
- visible: mouseArea.containsMouse
+ visible: mouseArea.hovered
Rectangle {
id: container
diff --git a/resources/qml/delegates/NoticeMessage.qml b/resources/qml/delegates/NoticeMessage.qml
index 67a69055..c38cb555 100644
--- a/resources/qml/delegates/NoticeMessage.qml
+++ b/resources/qml/delegates/NoticeMessage.qml
@@ -1,6 +1,6 @@
TextMessage {
font.italic: true
color: colors.buttonText
- height: isReply ? Math.min(chat.height / 8, implicitHeight) : undefined
+ height: isReply ? Math.min(timelineRoot.height / 8, implicitHeight) : undefined
clip: isReply
}
diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml
index 1534da2e..70f39e43 100644
--- a/resources/qml/delegates/PlayableMediaMessage.qml
+++ b/resources/qml/delegates/PlayableMediaMessage.qml
@@ -1,5 +1,5 @@
import QtMultimedia 5.6
-import QtQuick 2.6
+import QtQuick 2.12
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2
import im.nheko 1.0
@@ -140,9 +140,8 @@ Rectangle {
fillMode: Image.Pad
}
- MouseArea {
- anchors.fill: parent
- onClicked: {
+ TapHandler {
+ onSingleTapped: {
switch (button.state) {
case "":
TimelineManager.timeline.cacheMedia(model.data.id);
@@ -159,6 +158,10 @@ Rectangle {
break;
}
}
+ }
+
+ CursorShape {
+ anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}
diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml
index ff1fa657..28c4bf6e 100644
--- a/resources/qml/delegates/Reply.qml
+++ b/resources/qml/delegates/Reply.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.6
+import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
@@ -13,10 +13,12 @@ Item {
width: parent.width
height: replyContainer.height
- MouseArea {
+ TapHandler {
+ onSingleTapped: chat.positionViewAtIndex(chat.model.idToIndex(modelData.id), ListView.Contain)
+ }
+
+ CursorShape {
anchors.fill: parent
- preventStealing: false
- onClicked: chat.positionViewAtIndex(chat.model.idToIndex(modelData.id), ListView.Contain)
cursorShape: Qt.PointingHandCursor
}
@@ -43,10 +45,8 @@ Item {
color: replyComponent.userColor
textFormat: Text.RichText
- MouseArea {
- anchors.fill: parent
- onClicked: chat.model.openUserProfile(reply.modelData.userId)
- cursorShape: Qt.PointingHandCursor
+ TapHandler {
+ onSingleTapped: chat.model.openUserProfile(reply.modelData.userId)
}
}
diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml
index 3ff771dc..82d0d0e4 100644
--- a/resources/qml/delegates/TextMessage.qml
+++ b/resources/qml/delegates/TextMessage.qml
@@ -4,9 +4,10 @@ import im.nheko 1.0
MatrixText {
property string formatted: model.data.formattedBody
- text: "<span style='white-space: pre-wrap'><style type=\"text/css\">a { color:" + colors.link + ";}\ncode { background-color: " + colors.alternateBase + ";}</style>" + formatted.replace("<pre>", "<pre style='white-space: pre-wrap; background-color: " + colors.alternateBase + "'>") + "</span>"
+ text: "<style type=\"text/css\">a { color:" + colors.link + ";}\ncode { background-color: " + colors.alternateBase + ";}</style>" + formatted.replace("<pre>", "<pre style='white-space: pre-wrap; background-color: " + colors.alternateBase + "'>")
width: parent ? parent.width : undefined
height: isReply ? Math.round(Math.min(timelineRoot.height / 8, implicitHeight)) : undefined
clip: isReply
+ selectByMouse: !Settings.mobileMode && !isReply
font.pointSize: (Settings.enlargeEmojiOnlyMessages && model.data.isOnlyEmoji > 0 && model.data.isOnlyEmoji < 4) ? Settings.fontSize * 3 : Settings.fontSize
}
diff --git a/resources/qml/emoji/EmojiButton.qml b/resources/qml/emoji/EmojiButton.qml
index 928d6226..dd7530a6 100644
--- a/resources/qml/emoji/EmojiButton.qml
+++ b/resources/qml/emoji/EmojiButton.qml
@@ -14,5 +14,6 @@ ImageButton {
image: ":/icons/icons/ui/smile.png"
onClicked: emojiPicker.visible ? emojiPicker.close() : emojiPicker.show(emojiButton, function(emoji) {
TimelineManager.queueReactionMessage(event_id, emoji);
+ TimelineManager.focusMessageInput();
})
}
|