feat: redisgn compact mode part 1

redesigns the compact mode to have a nice hover, easier replying and adding reactions and more

Missing parts are aligning chat command, images and unfurlings, redesigning mentions and the channel list and also trying to find a way to re-enable link hovers in the text
This commit is contained in:
Jonathan Rainville 2021-01-25 15:50:42 -05:00 committed by Iuri Matias
parent d1faf98f80
commit b245d858aa
13 changed files with 489 additions and 222 deletions

View File

@ -31,15 +31,17 @@ ScrollView {
ListView { ListView {
property string currentNotificationChatId property string currentNotificationChatId
property bool chatButtonsHovered: false
id: chatLogView id: chatLogView
anchors.fill: parent anchors.fill: parent
anchors.bottomMargin: Style.current.bigPadding anchors.bottomMargin: Style.current.bigPadding
spacing: 4 spacing: appSettings.compactMode ? 0 : 4
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 10000 flickDeceleration: 10000
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
verticalLayoutDirection: ListView.TopToBottom
Timer { Timer {
id: timer id: timer

View File

@ -0,0 +1,99 @@
import QtQuick 2.13
import QtGraphicalEffects 1.13
import "../../../../../shared"
import "../../../../../shared/status"
import "../../../../../imports"
Rectangle {
property bool parentIsHovered: false
signal hoverChanged(bool hovered)
property int containerMargin: 2
id: buttonsContainer
visible: buttonsContainer.parentIsHovered || isMessageActive
width: buttonRow.width + buttonsContainer.containerMargin * 2
height: 36
radius: Style.current.radius
color: Style.current.background
z: 52
layer.enabled: true
layer.effect: DropShadow {
width: buttonsContainer.width
height: buttonsContainer.height
x: buttonsContainer.x
y: buttonsContainer.y + 10
visible: buttonsContainer.visible
source: buttonsContainer
horizontalOffset: 0
verticalOffset: 2
radius: 10
samples: 15
color: "#22000000"
}
MouseArea {
anchors.fill: buttonsContainer
acceptedButtons: Qt.NoButton
hoverEnabled: true
onEntered: {
buttonsContainer.hoverChanged(true)
chatLogView.chatButtonsHovered = true
}
onExited: {
buttonsContainer.hoverChanged(false)
chatLogView.chatButtonsHovered = false
}
}
Row {
id: buttonRow
spacing: buttonsContainer.containerMargin
anchors.left: parent.left
anchors.leftMargin: buttonsContainer.containerMargin
anchors.verticalCenter: buttonsContainer.verticalCenter
height: parent.height - 2 * buttonsContainer.containerMargin
StatusIconButton {
id: emojiBtn
icon.name: "emoji"
width: 32
height: 32
onClicked: {
isMessageActive = true
clickMessage(false, false, false, null, true)
}
onHoveredChanged: {
chatLogView.chatButtonsHovered = this.hovered
buttonsContainer.hoverChanged(this.hovered)
}
StatusToolTip {
visible: emojiBtn.hovered
text: qsTr("Add reaction")
width: 115
}
}
StatusIconButton {
id: replyBtn
icon.name: "reply"
width: 32
height: 32
onClicked: {
SelectedMessage.set(messageId, fromAuthor);
showReplyArea()
}
onHoveredChanged: {
chatLogView.chatButtonsHovered = this.hovered
buttonsContainer.hoverChanged(this.hovered)
}
StatusToolTip {
visible: replyBtn.hovered
text: qsTr("Reply")
width: 75
}
}
}
}

View File

@ -105,7 +105,6 @@ Item {
} }
} }
Loader { Loader {
id: mask id: mask
anchors.fill: chatText anchors.fill: chatText

View File

@ -1,179 +1,240 @@
import QtQuick 2.13 import QtQuick 2.13
import QtGraphicalEffects 1.13
import "../../../../../shared" import "../../../../../shared"
import "../../../../../shared/status"
import "../../../../../imports" import "../../../../../imports"
Item { Item {
property var clickMessage: function () {} property var clickMessage: function () {}
property int chatHorizontalPadding: 12 property int chatHorizontalPadding: 8
property int chatVerticalPadding: 7 property int chatVerticalPadding: 7
property string linkUrls: "" property string linkUrls: ""
property int contentType: 2 property int contentType: 2
property var container property var container
property bool isCurrentUser: false property bool isCurrentUser: false
property bool isHovered: false
property bool isMessageActive: false
id: root id: root
anchors.top: parent.top
anchors.topMargin: authorCurrentMsg != authorPrevMsg ? Style.current.smallPadding : 0
height: childrenRect.height + this.anchors.topMargin
width: parent.width width: parent.width
height: messageContainer.height
// FIXME @jonathanr: Adding this breaks the first line. Need to fix the height somehow MouseArea {
// DateGroup { anchors.fill: messageContainer
// id: dateGroupLbl acceptedButtons: Qt.LeftButton | Qt.RightButton
// } onClicked: messageMouseArea.clicked(mouse)
UserImage {
id: chatImage
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
// anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.top: parent.top
} }
UsernameLabel { ChatButtons {
id: chatName parentIsHovered: root.isHovered
anchors.leftMargin: root.chatHorizontalPadding onHoverChanged: root.isHovered = hovered
// anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.top: parent.top
anchors.left: chatImage.right
}
ChatReply {
id: chatReply
// anchors.top: chatName.visible ? chatName.bottom : (dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top)
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.topMargin: chatName.visible && this.visible ? root.chatVerticalPadding : 0
anchors.left: chatImage.right
anchors.leftMargin: root.chatHorizontalPadding
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: root.chatHorizontalPadding anchors.rightMargin: 20
container: root.container anchors.top: parent.top
chatHorizontalPadding: root.chatHorizontalPadding // 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
ChatText {
id: chatText
anchors.top: chatReply.bottom
anchors.topMargin: chatName.visible && this.visible ? root.chatVerticalPadding : 0
anchors.left: chatImage.right
anchors.leftMargin: root.chatHorizontalPadding
anchors.right: parent.right
anchors.rightMargin: root.chatHorizontalPadding
} }
Loader { Loader {
id: chatImageContent active: typeof messageContextMenu !== "undefined"
active: isImage
anchors.left: chatText.left
anchors.leftMargin: 8
anchors.top: chatReply.bottom
z: 51
sourceComponent: Component { sourceComponent: Component {
ChatImage { Connections {
imageSource: image enabled: root.isMessageActive
imageWidth: 200 target: messageContextMenu
onClicked: root.clickMessage(false, false, true, image) onClosed: root.isMessageActive = false
container: root.container
} }
} }
} }
Loader { Rectangle {
id: stickerLoader property alias chatText: chatText
active: contentType === Constants.stickerType
anchors.left: chatText.left
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.topMargin: this.visible && chatName.visible ? root.chatVerticalPadding : 0
sourceComponent: Component { id: messageContainer
Rectangle { height: childrenRect.height + (chatName.visible || emojiReactionLoader.active ? Style.current.smallPadding : 0)
id: stickerContainer + (emojiReactionLoader.active ? emojiReactionLoader.height + Style.current.halfPadding : 0)
color: Style.current.transparent width: parent.width
border.color: Style.current.grey
border.width: 1
radius: 16
width: stickerId.width + 2 * root.chatVerticalPadding
height: stickerId.height + 2 * root.chatVerticalPadding
Sticker { color: root.isHovered || isMessageActive ? Style.current.backgroundHover : Style.current.transparent
id: stickerId
anchors.top: parent.top // FIXME @jonathanr: Adding this breaks the first line. Need to fix the height somehow
anchors.topMargin: root.chatVerticalPadding // DateGroup {
anchors.left: parent.left // id: dateGroupLbl
anchors.leftMargin: root.chatVerticalPadding // }
contentType: root.contentType
UserImage {
id: chatImage
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
// anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
}
UsernameLabel {
id: chatName
anchors.leftMargin: root.chatHorizontalPadding
// anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top
anchors.top: chatImage.top
anchors.left: chatImage.right
}
ChatReply {
id: chatReply
// anchors.top: chatName.visible ? chatName.bottom : (dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top)
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.topMargin: chatName.visible && this.visible ? root.chatVerticalPadding : 0
anchors.left: chatImage.right
anchors.leftMargin: root.chatHorizontalPadding
anchors.right: parent.right
anchors.rightMargin: root.chatHorizontalPadding
container: root.container
chatHorizontalPadding: root.chatHorizontalPadding
}
ChatText {
id: chatText
anchors.top: chatReply.active ? chatReply.bottom : chatName.visible ? chatName.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
textField.leftPadding: chatImage.anchors.leftMargin + chatImage.width + root.chatHorizontalPadding
textField.rightPadding: Style.current.bigPadding
}
Loader {
id: chatImageContent
active: isImage
anchors.left: chatText.left
anchors.leftMargin: 8
anchors.top: chatReply.bottom
z: 51
sourceComponent: Component {
ChatImage {
imageSource: image
imageWidth: 200
onClicked: root.clickMessage(false, false, true, image)
container: root.container container: root.container
} }
} }
} }
Loader {
id: stickerLoader
active: contentType === Constants.stickerType
anchors.left: chatText.left
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.topMargin: this.visible && chatName.visible ? root.chatVerticalPadding : 0
sourceComponent: Component {
Rectangle {
id: stickerContainer
color: Style.current.transparent
border.color: 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
}
ChatTime {
id: chatTime
visible: authorCurrentMsg != authorPrevMsg
anchors.verticalCenter: chatName.verticalCenter
anchors.left: chatName.right
anchors.leftMargin: 4
}
SentMessage {
id: sentMessage
visible: isCurrentUser && !timeout && !isExpired && isMessage && outgoingStatus !== "sent"
anchors.verticalCenter: chatTime.verticalCenter
anchors.left: chatTime.right
anchors.leftMargin: Style.current.halfPadding
}
Retry {
id: retry
anchors.right: chatTime.right
anchors.rightMargin: 5
}
Loader {
id: linksLoader
active: !!root.linkUrls
anchors.left: chatText.left
anchors.leftMargin: 8
anchors.top: chatText.bottom
sourceComponent: Component {
LinksMessage {
linkUrls: root.linkUrls
container: root.container
isCurrentUser: root.isCurrentUser
}
}
}
Loader {
id: audioPlayerLoader
active: isAudio
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.left: chatImage.right
sourceComponent: Component {
AudioPlayer {
audioSource: audio
}
}
}
} }
MessageMouseArea { // TODO find a way for this to not eat link hovers
anchors.fill: stickerLoader.active ? stickerLoader : chatText MouseArea {
} anchors.fill: root
acceptedButtons: Qt.NoButton
// TODO show date for not the first messsage (on hover maybe) hoverEnabled: true
ChatTime { onEntered: {
id: chatTime root.isHovered = true
visible: authorCurrentMsg != authorPrevMsg
anchors.verticalCenter: chatName.verticalCenter
anchors.left: chatName.right
anchors.leftMargin: Style.current.padding
}
SentMessage {
id: sentMessage
visible: isCurrentUser && !timeout && !isExpired && isMessage && outgoingStatus !== "sent"
anchors.verticalCenter: chatTime.verticalCenter
anchors.left: chatTime.right
anchors.leftMargin: 8
}
Retry {
id: retry
anchors.right: chatTime.right
anchors.rightMargin: 5
}
Loader {
id: linksLoader
active: !!root.linkUrls
anchors.left: chatText.left
anchors.leftMargin: 8
anchors.top: chatText.bottom
sourceComponent: Component {
LinksMessage {
linkUrls: root.linkUrls
container: root.container
isCurrentUser: root.isCurrentUser
}
} }
} onExited: {
if (chatLogView.chatButtonsHovered) {
Loader { return
id: audioPlayerLoader
active: isAudio
anchors.top: chatName.visible ? chatName.bottom : parent.top
anchors.left: chatImage.right
sourceComponent: Component {
AudioPlayer {
audioSource: audio
} }
root.isHovered = false
} }
} }
Loader { Loader {
id: emojiReactionLoader id: emojiReactionLoader
active: emojiReactions !== "" active: emojiReactions !== ""
anchors.top: chatText.bottom anchors.bottom: messageContainer.bottom
anchors.left: chatText.left anchors.bottomMargin: Style.current.smallPadding
anchors.topMargin: active ? 2 : 0 anchors.left: messageContainer.left
anchors.leftMargin: messageContainer.chatText.textField.leftPadding
sourceComponent: Component { sourceComponent: Component {
EmojiReactions {} EmojiReactions {
onHoverChanged: root.isHovered = hovered
}
} }
} }
} }

View File

@ -1,10 +1,14 @@
import QtQuick 2.3 import QtQuick 2.3
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import "../../../../../shared" import "../../../../../shared"
import "../../../../../shared/status"
import "../../../../../imports" import "../../../../../imports"
Item { Item {
property int imageMargin: 4 property int imageMargin: 4
signal hoverChanged(bool hovered)
id: root id: root
height: 20 height: 20
width: childrenRect.width width: childrenRect.width
@ -23,7 +27,7 @@ Item {
if (fromAccounts.length > 3) { if (fromAccounts.length > 3) {
leftNode = fromAccounts.slice(0, 3); leftNode = fromAccounts.slice(0, 3);
rightNode = fromAccounts.slice(3, fromAccounts.length); rightNode = fromAccounts.slice(3, fromAccounts.length);
return (rightNode.length == 1) ? return (rightNode.length === 1) ?
lastTwoItems([leftNode.join(", "), rightNode[0]]) : lastTwoItems([leftNode.join(", "), rightNode[0]]) :
lastTwoItems([leftNode.join(", "), qsTr("%1 more reacted.").arg(rightNode.length)]); lastTwoItems([leftNode.join(", "), qsTr("%1 more reacted.").arg(rightNode.length)]);
} }
@ -33,109 +37,198 @@ Item {
return lastTwoItems([leftNode.join(", "), rightNode[0]]); return lastTwoItems([leftNode.join(", "), rightNode[0]]);
} }
Repeater { Row {
id: reactionepeater spacing: root.imageMargin
model: {
if (!emojiReactions) { Repeater {
return [] id: reactionRepeater
width: childrenRect.width
model: {
if (!emojiReactions) {
return []
}
try {
// group by id
var allReactions = Object.values(JSON.parse(emojiReactions))
var byEmoji = {}
allReactions.forEach(function (reaction) {
if (!byEmoji[reaction.emojiId]) {
byEmoji[reaction.emojiId] = {
emojiId: reaction.emojiId,
fromAccounts: [],
count: 0,
currentUserReacted: false
}
}
byEmoji[reaction.emojiId].count++;
byEmoji[reaction.emojiId].fromAccounts.push(chatsModel.userNameOrAlias(reaction.from));
if (!byEmoji[reaction.emojiId].currentUserReacted && reaction.from === profileModel.profile.pubKey) {
byEmoji[reaction.emojiId].currentUserReacted = true
}
})
return Object.values(byEmoji)
} catch (e) {
console.error('Error parsing emoji reactions', e)
return []
}
} }
try { Rectangle {
// group by id property bool isHovered: false
var allReactions = Object.values(JSON.parse(emojiReactions))
var byEmoji = {} id: emojiContainer
allReactions.forEach(function (reaction) { width: emojiImage.width + emojiCount.width + (root.imageMargin * 2) + + 8
if (!byEmoji[reaction.emojiId]) { height: 20
byEmoji[reaction.emojiId] = { radius: 10
emojiId: reaction.emojiId, color: modelData.currentUserReacted ? Style.current.secondaryBackground :
fromAccounts: [], (isHovered ? Style.current.emojiReactionBackgroundHovered : Style.current.emojiReactionBackground)
count: 0,
currentUserReacted: false ToolTip {
visible: mouseArea.containsMouse
text: showReactionAuthors(modelData.fromAccounts)
}
// Rounded corner to cover one corner
Rectangle {
color: parent.color
width: 8
height: 8
anchors.top: parent.top
anchors.left: !isCurrentUser || appSettings.compactMode ? parent.left : undefined
anchors.leftMargin: 0
anchors.right: !isCurrentUser || appSettings.compactMode ? undefined : parent.right
anchors.rightMargin: 0
radius: 2
z: -1
}
// This is a workaround to get a "border" around the rectangle including the weird rectangle
Loader {
active: modelData.currentUserReacted
anchors.top: parent.top
anchors.topMargin: -1
anchors.left: parent.left
anchors.leftMargin: -1
z: -2
sourceComponent: Component {
Rectangle {
width: emojiContainer.width + 2
height: emojiContainer.height + 2
radius: emojiContainer.radius
color: Style.current.primary
Rectangle {
color: parent.color
width: 8
height: 8
anchors.top: parent.top
anchors.left: !isCurrentUser || appSettings.compactMode ? parent.left : undefined
anchors.leftMargin: 0
anchors.right: !isCurrentUser || appSettings.compactMode ? undefined : parent.right
anchors.rightMargin: 0
radius: 2
z: -1
}
} }
} }
byEmoji[reaction.emojiId].count++; }
byEmoji[reaction.emojiId].fromAccounts.push(chatsModel.userNameOrAlias(reaction.from));
if (!byEmoji[reaction.emojiId].currentUserReacted && reaction.from === profileModel.profile.pubKey) { SVGImage {
byEmoji[reaction.emojiId].currentUserReacted = true id: emojiImage
width: 15
fillMode: Image.PreserveAspectFit
source: {
const basePath = "../../../../img/emojiReactions/"
switch (modelData.emojiId) {
case 1: return basePath + "heart.svg"
case 2: return basePath + "thumbsUp.svg"
case 3: return basePath + "thumbsDown.svg"
case 4: return basePath + "laughing.svg"
case 5: return basePath + "sad.svg"
case 6: return basePath + "angry.svg"
default: return ""
}
} }
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: root.imageMargin
}
}) StyledText {
return Object.values(byEmoji) id: emojiCount
} catch (e) { text: modelData.count
console.error('Error parsing emoji reactions', e) anchors.verticalCenter: parent.verticalCenter
return [] anchors.left: emojiImage.right
} anchors.leftMargin: root.imageMargin
font.pixelSize: 12
color: modelData.currentUserReacted ? Style.current.textColorTertiary : Style.current.textColor
}
} MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
root.hoverChanged(true)
emojiContainer.isHovered = true
}
onExited: {
root.hoverChanged(false)
emojiContainer.isHovered = false
}
onClicked: {
chatsModel.toggleReaction(messageId, modelData.emojiId)
Rectangle {
width: emojiImage.width + emojiCount.width + (root.imageMargin * 2) + + 8
height: 20
radius: 10
anchors.left: (index === 0) ? parent.left: parent.children[index-1].right
anchors.leftMargin: (index === 0) ? 0 : root.imageMargin
color: modelData.currentUserReacted ? Style.current.primary : Style.current.inputBackground
ToolTip {
visible: mouseArea.containsMouse
text: showReactionAuthors(modelData.fromAccounts)
}
// Rounded corner to cover one corner
Rectangle {
color: parent.color
width: 8
height: 8
anchors.top: parent.top
anchors.left: !isCurrentUser || appSettings.compactMode ? parent.left : undefined
anchors.leftMargin: 0
anchors.right: !isCurrentUser || appSettings.compactMode ? undefined : parent.right
anchors.rightMargin: 0
radius: 2
z: -1
}
SVGImage {
id: emojiImage
width: 15
fillMode: Image.PreserveAspectFit
source: {
const basePath = "../../../../img/emojiReactions/"
switch (modelData.emojiId) {
case 1: return basePath + "heart.svg"
case 2: return basePath + "thumbsUp.svg"
case 3: return basePath + "thumbsDown.svg"
case 4: return basePath + "laughing.svg"
case 5: return basePath + "sad.svg"
case 6: return basePath + "angry.svg"
default: return ""
} }
} }
anchors.verticalCenter: parent.verticalCenter }
}
Item {
width: addEmojiBtn.width + addEmojiBtn.anchors.leftMargin // there is more margin between the button and the emojis than between each emoji
height: addEmojiBtn.height
SVGImage {
property bool isHovered: false
id: addEmojiBtn
source: "../../../../img/emoji.svg"
width: 16.5
height: 16.5
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: root.imageMargin anchors.leftMargin: 2.5
} }
StyledText { ColorOverlay {
id: emojiCount anchors.fill: addEmojiBtn
text: modelData.count antialiasing: true
anchors.verticalCenter: parent.verticalCenter source: addEmojiBtn
anchors.left: emojiImage.right color: addEmojiBtn.isHovered ? Style.current.primary : Style.current.secondaryText
anchors.leftMargin: root.imageMargin
font.pixelSize: 12
color: modelData.currentUserReacted ? Style.current.currentUserTextColor : Style.current.textColor
} }
MouseArea { MouseArea {
id: mouseArea anchors.fill: addEmojiBtn
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: addEmojiBtn.isHovered = true
onExited: addEmojiBtn.isHovered = false
onClicked: { onClicked: {
chatsModel.toggleReaction(messageId, modelData.emojiId) isMessageActive = true
clickMessage(false, false, false, null, true)
} }
} }
StatusToolTip {
visible: addEmojiBtn.isHovered
text: qsTr("Add reaction")
width: 115
}
} }
} }
} }

View File

@ -1,4 +1,4 @@
import QtQuick 2.3 import QtQuick 2.13
import "../../../../../shared" import "../../../../../shared"
import "../../../../../imports" import "../../../../../imports"

View File

@ -4,6 +4,7 @@ import "../../../../../imports"
Item { Item {
id: root id: root
property bool isHovered: false
height: childrenRect.height height: childrenRect.height
width: chatName.width + (ensOrAlias.visible ? ensOrAlias.width + ensOrAlias.anchors.leftMargin : 0) width: chatName.width + (ensOrAlias.visible ? ensOrAlias.width + ensOrAlias.anchors.leftMargin : 0)
property alias label: chatName property alias label: chatName
@ -28,6 +29,7 @@ Item {
color: text.startsWith("@") || isCurrentUser || localName !== "" ? Style.current.blue : Style.current.secondaryText color: text.startsWith("@") || isCurrentUser || localName !== "" ? Style.current.blue : Style.current.secondaryText
font.weight: Font.Medium font.weight: Font.Medium
font.pixelSize: Style.current.secondaryTextFontSize font.pixelSize: Style.current.secondaryTextFontSize
font.underline: root.isHovered
readOnly: true readOnly: true
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
selectByMouse: true selectByMouse: true
@ -37,10 +39,10 @@ Item {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
parent.font.underline = true root.isHovered = true
} }
onExited: { onExited: {
parent.font.underline = false root.isHovered = false
} }
onClicked: { onClicked: {
clickMessage(true) clickMessage(true)

3
ui/app/img/reply.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2361 9.43053C10.9676 9.16205 10.5323 9.16205 10.2638 9.43053C9.99536 9.69902 9.99536 10.1343 10.2638 10.4028L11.9744 12.1134C12.2632 12.4021 12.0587 12.8958 11.6504 12.8958L7.99998 12.8958C4.83585 12.8958 2.27081 10.3308 2.27081 7.16667C2.27081 4.00254 4.83585 1.4375 7.99998 1.4375C8.37967 1.4375 8.68748 1.1297 8.68748 0.75C8.68748 0.370305 8.37967 0.0625 7.99998 0.0625C4.07646 0.0624998 0.895812 3.24315 0.895813 7.16667C0.895813 11.0902 4.07646 14.2708 7.99998 14.2708H11.6504C12.0587 14.2708 12.2632 14.7645 11.9744 15.0533L10.2638 16.7639C9.99536 17.0324 9.99536 17.4677 10.2638 17.7361C10.5323 18.0046 10.9676 18.0046 11.2361 17.7361L14.9028 14.0695C15.1713 13.801 15.1713 13.3657 14.9028 13.0972L11.2361 9.43053Z" fill="#939BA1"/>
</svg>

After

Width:  |  Height:  |  Size: 856 B

View File

@ -51,6 +51,8 @@ Theme {
property color topBarChatInfoColor: evenDarkerGrey property color topBarChatInfoColor: evenDarkerGrey
property color codeBackground: "#2E386B" property color codeBackground: "#2E386B"
property color primarySelectionColor: "#b4c8ff" property color primarySelectionColor: "#b4c8ff"
property color emojiReactionBackground: "#2d2823"
property color emojiReactionBackgroundHovered: "#3a3632"
property color buttonForegroundColor: blue property color buttonForegroundColor: blue
property color buttonBackgroundColor: secondaryBackground property color buttonBackgroundColor: secondaryBackground

View File

@ -50,6 +50,8 @@ Theme {
property color topBarChatInfoColor: grey property color topBarChatInfoColor: grey
property color codeBackground: "#2E386B" property color codeBackground: "#2E386B"
property color primarySelectionColor: "#b4c8ff" property color primarySelectionColor: "#b4c8ff"
property color emojiReactionBackground: "#e2e6e9"
property color emojiReactionBackgroundHovered: "#d7dadd"
property color buttonForegroundColor: blue property color buttonForegroundColor: blue
property color buttonBackgroundColor: secondaryBackground property color buttonBackgroundColor: secondaryBackground

View File

@ -30,6 +30,7 @@ QtObject {
property color orange: "#FE8F59" property color orange: "#FE8F59"
property color background property color background
property color backgroundHover
property color border property color border
property color textColor property color textColor
property color secondaryText property color secondaryText
@ -38,6 +39,8 @@ QtObject {
property color modalBackground property color modalBackground
property color codeBackground property color codeBackground
property color primarySelectioncolor property color primarySelectioncolor
property color emojiReactionBackground
property color emojiReactionBackgroundHovered
property color buttonForegroundColor property color buttonForegroundColor
property color buttonBackgroundColor property color buttonBackgroundColor

View File

@ -145,6 +145,7 @@ DISTFILES += \
app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml \ app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml \
app/AppLayouts/Chat/ChatColumn/CompactMessage.qml \ app/AppLayouts/Chat/ChatColumn/CompactMessage.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChannelIdentifier.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/ChannelIdentifier.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatImage.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatImage.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply \ app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply \
app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply.qml \ app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply.qml \

View File

@ -36,7 +36,7 @@ ToolTip {
color: Style.current.tooltipForegroundColor color: Style.current.tooltipForegroundColor
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pixelSize: 13 font.pixelSize: 13
font.weight: Font.DemiBold font.weight: Font.Medium
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
} }