status-desktop/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml

265 lines
9.3 KiB
QML
Raw Normal View History

import QtQuick 2.13
import QtGraphicalEffects 1.13
import "../../../../../shared"
import "../../../../../shared/status"
import "../../../../../imports"
Item {
property var clickMessage: function () {}
property int chatHorizontalPadding: Style.current.halfPadding
property int chatVerticalPadding: 7
property string linkUrls: ""
property int contentType: 2
property var container
feat: whitelist gifs (no url extension needed) Fixes #1377. Fixes #1479. Two sites have been added to the whitelist: giphy.com and tenor.com. `imageUrls` in its entirety has been removed and instead all links are being handle through the message `linkUrls`. This prevents double-handling of urls that may or may not be images. The logic to automatically show links previews works like this: 1. If the setting "display chat images" is enabled, all links that *contain* ".png", ".jpg", ".jpeg", ".svg", ".gif" will be automatically shown. If the URL doesn't contain the extension, we are not downloading it. This was meant to be somewhat of a security compromise as we do not want to download each and every link posted in a message just to find out its true content type. 2. If the above setting is *disabled*, then we follow the whitelist settings for tenor and giphy. This allows us to preview gifs that do not have a file extension in their url. feat: bump status-go to the commit that supports the new whitelist (https://github.com/status-im/status-go/pull/2094), and also lets us get link preview data from urls in the whitelist. NOTE: this commit was branched off status-go `develop`, so once it is merged, and we update this PR to the new commit, we will effectively be getting status-go develop changes. We *could* base that status-go PR off of master if it makes things easier. fix: height on settings update issue feat: move date/time of message below links fix: layout issues when changing setting `neverAskAboutUnfurlingAgain` feat: Add MessageBorder component to aid in showing rounded corners with different radius
2020-12-11 00:53:44 +00:00
property bool isCurrentUser: false
property bool isHovered: false
property bool isMessageActive: false
property bool headerRepeatCondition: (authorCurrentMsg !== authorPrevMsg || shouldRepeatHeader || dateGroupLbl.visible)
id: root
width: parent.width
height: messageContainer.height + messageContainer.anchors.topMargin
+ (dateGroupLbl.visible ? dateGroupLbl.height + dateGroupLbl.anchors.topMargin : 0)
MouseArea {
enabled: !placeholderMessage
anchors.fill: messageContainer
acceptedButtons: Qt.RightButton
onClicked: messageMouseArea.clicked(mouse)
}
ChatButtons {
contentType: root.contentType
parentIsHovered: root.isHovered
onHoverChanged: root.isHovered = hovered
anchors.right: parent.right
anchors.rightMargin: 20
anchors.top: messageContainer.top
// This is not exactly like the design because the hover becomes messed up with the buttons on top of another Message
anchors.topMargin: -Style.current.halfPadding
}
2020-07-20 17:34:20 +00:00
Loader {
active: typeof messageContextMenu !== "undefined"
2020-09-30 18:16:16 +00:00
sourceComponent: Component {
Connections {
enabled: root.isMessageActive
target: messageContextMenu
onClosed: root.isMessageActive = false
2020-09-30 18:16:16 +00:00
}
2020-07-20 17:34:20 +00:00
}
}
DateGroup {
id: dateGroupLbl
}
Rectangle {
property alias chatText: chatText
id: messageContainer
anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.topMargin: dateGroupLbl.visible ? Style.current.padding : 0
height: childrenRect.height
+ (chatName.visible || emojiReactionLoader.active ? Style.current.smallPadding : 0)
+ (chatName.visible && emojiReactionLoader.active ? 5 : 0)
+ (emojiReactionLoader.active ? emojiReactionLoader.height: 0)
+ (retry.visible && !chatTime.visible ? Style.current.smallPadding : 0)
width: parent.width
color: root.isHovered || isMessageActive ? (hasMention ? Style.current.mentionMessageHoverColor : Style.current.backgroundHoverLight) :
(hasMention ? Style.current.mentionMessageColor : Style.current.transparent)
UserImage {
id: chatImage
active: isMessage && headerRepeatCondition
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
}
UsernameLabel {
id: chatName
visible: isMessage && headerRepeatCondition
anchors.leftMargin: root.chatHorizontalPadding
anchors.top: chatImage.top
anchors.left: chatImage.right
}
ChatTime {
id: chatTime
visible: headerRepeatCondition
anchors.verticalCenter: chatName.verticalCenter
anchors.left: chatName.right
anchors.leftMargin: 4
color: Style.current.secondaryText
}
Item {
id: messageContent
height: childrenRect.height + Style.current.halfPadding
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.left: chatImage.right
anchors.leftMargin: root.chatHorizontalPadding
anchors.right: parent.right
anchors.rightMargin: root.chatHorizontalPadding
ChatReply {
id: chatReply
longReply: active && textFieldImplicitWidth > width
container: root.container
chatHorizontalPadding: root.chatHorizontalPadding
width: parent.width
}
ChatText {
readonly property int leftPadding: chatImage.anchors.leftMargin + chatImage.width + root.chatHorizontalPadding
id: chatText
anchors.top: chatReply.active ? chatReply.bottom : parent.top
anchors.left: parent.left
anchors.right: parent.right
// using a padding instead of a margin let's us select text more easily
anchors.leftMargin: -leftPadding
textField.leftPadding: leftPadding
textField.rightPadding: Style.current.bigPadding
}
Loader {
id: chatImageContent
active: isImage
anchors.top: chatReply.bottom
z: 51
sourceComponent: Component {
ChatImage {
imageSource: image
imageWidth: 200
onClicked: root.clickMessage(false, false, true, image)
container: root.container
}
}
}
Loader {
id: stickerLoader
active: contentType === Constants.stickerType
anchors.top: parent.top
anchors.topMargin: active ? Style.current.halfPadding : 0
sourceComponent: Component {
Rectangle {
id: stickerContainer
color: Style.current.transparent
border.color: root.isHovered ? Qt.darker(Style.current.darkGrey, 1.1) : Style.current.grey
border.width: 1
radius: 16
width: stickerId.width + 2 * root.chatVerticalPadding
height: stickerId.height + 2 * root.chatVerticalPadding
Sticker {
id: stickerId
anchors.top: parent.top
anchors.topMargin: root.chatVerticalPadding
anchors.left: parent.left
anchors.leftMargin: root.chatVerticalPadding
contentType: root.contentType
container: root.container
}
}
}
}
MessageMouseArea {
id: messageMouseArea
anchors.fill: stickerLoader.active ? stickerLoader : chatText
}
Loader {
id: linksLoader
active: !!root.linkUrls
anchors.top: chatText.bottom
anchors.topMargin: active ? Style.current.halfPadding : 0
sourceComponent: Component {
LinksMessage {
linkUrls: root.linkUrls
container: root.container
isCurrentUser: root.isCurrentUser
}
}
}
Loader {
id: audioPlayerLoader
active: isAudio
anchors.top: parent.top
anchors.topMargin: active ? Style.current.halfPadding : 0
sourceComponent: Component {
AudioPlayer {
audioSource: audio
}
}
}
Loader {
id: transactionBubbleLoader
active: contentType === Constants.transactionType
anchors.top: parent.top
anchors.topMargin: active ? (chatName.visible ? 4 : 6) : 0
sourceComponent: Component {
TransactionBubble {}
}
}
}
2020-07-14 15:35:21 +00:00
Retry {
id: retry
anchors.left: chatTime.visible ? chatTime.right : messageContent.left
anchors.leftMargin: chatTime.visible ? chatHorizontalPadding : 0
anchors.top: chatTime.visible ? undefined : messageContent.bottom
anchors.topMargin: chatTime.visible ? 0 : -4
anchors.verticalCenter: chatTime.visible ? chatTime.verticalCenter : undefined
2020-10-23 19:46:44 +00:00
}
}
2020-10-23 19:46:44 +00:00
Loader {
active: hasMention
height: messageContainer.height
anchors.left: messageContainer.left
2020-07-30 16:07:41 +00:00
sourceComponent: Component {
Rectangle {
id: mentionBorder
color: Style.current.mentionColor
width: 2
height: parent.height
2020-09-30 18:45:45 +00:00
}
2020-07-30 16:07:41 +00:00
}
}
2021-02-09 20:40:39 +00:00
HoverHandler {
fix(Chat): disable HoverHandler when profile popup or context menu are open Alright, this is an interesting one: As described in #1829, when the profile popup is opened within the chat view, users are still able to click *through* the popup on message, which then puts them in an active state. I've done a bunch of debugging as described [here](https://github.com/status-im/status-desktop/issues/1829#issuecomment-804748148) and after doing some further debugging, I found out that `isMessageActive` isn't really the culprit here. What causes this effect is the `HoverHandler` that's attached to the `CompactMessage` item. `HoverHandler` is a standard QML type that emits `hoverChanged` signals so one can do things like applying hover effects on elements, which is exactly what we do: ``` HoverHandler { onHoverChanged: { root.isHovered = hovered // `root` being the message item } } ``` I assume we went with this handler because putting a `MouseArea` in there instead, which fills the entire message component pretty much eliminates all existing mouse handlers attached to other child components, such as the profile image or the username of the message, which also open a message context menu. It turns out that, having a `HoverHandler` as described above, actually activates it when the user clicks with the left mouse button as well (not just on hover). That's what causes the "click-through" effect. This can be verified by setting `acceptedButtons` to `Qt.RightButton`, basically telling the handler that only right clicks will activate it. I then tried using `Qt.NoButtons` instead so that no button clicks and only hovers will activate the handler, but that didn't seem to have any effect at all. It still defaults to `Qt.LeftButton`. So the last resort was to disable the `HoverHandler` altogether, whenever either the profile popup, or the message context menu (for emojis etc) is open. Unfortunately, we don't have access to the profile popup in the compact message component, because it's detached from the component tree. Therefore, I've introduced a new property `profilePopupOpened` on the chat layout, which we can read from instead. Fixes #1829
2021-03-23 09:44:56 +00:00
enabled: !messageContextMenu.opened && !profilePopupOpened
2021-02-09 20:40:39 +00:00
onHoveredChanged: {
root.isHovered = hovered;
}
}
Loader {
id: emojiReactionLoader
active: emojiReactionsModel.length
anchors.bottom: messageContainer.bottom
anchors.bottomMargin: Style.current.smallPadding
anchors.left: messageContainer.left
anchors.leftMargin: messageContainer.chatText.textField.leftPadding
2020-09-30 18:45:45 +00:00
sourceComponent: Component {
EmojiReactions {
onHoverChanged: root.isHovered = hovered
}
2020-09-30 18:45:45 +00:00
}
}
}