fix(StatusMessageReply): Fixed reply text styling and behavior
This commit is contained in:
parent
263b1c01c6
commit
a69b3b5928
|
@ -80,6 +80,7 @@ Rectangle {
|
|||
signal profilePictureClicked(var sender, var mouse)
|
||||
signal senderNameClicked(var sender, var mouse)
|
||||
signal replyProfileClicked(var sender, var mouse)
|
||||
signal replyMessageClicked(var mouse)
|
||||
|
||||
signal addReactionClicked(var sender, var mouse)
|
||||
signal toggleReactionClicked(int emojiId)
|
||||
|
@ -219,11 +220,9 @@ Rectangle {
|
|||
sourceComponent: StatusMessageReply {
|
||||
replyDetails: root.replyDetails
|
||||
profileClickable: root.profileClickable
|
||||
onReplyProfileClicked: root.replyProfileClicked(sender, mouse)
|
||||
audioMessageInfoText: root.audioMessageInfoText
|
||||
onLinkActivated: {
|
||||
root.linkActivated(link);
|
||||
}
|
||||
onReplyProfileClicked: root.replyProfileClicked(sender, mouse)
|
||||
onMessageClicked: root.replyMessageClicked(mouse)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Layouts 1.14
|
|||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
Item {
|
||||
|
@ -15,14 +16,18 @@ Item {
|
|||
property bool profileClickable: true
|
||||
|
||||
signal replyProfileClicked(var sender, var mouse)
|
||||
signal linkActivated(string link)
|
||||
signal messageClicked(var mouse)
|
||||
|
||||
implicitHeight: layout.implicitHeight
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 16
|
||||
spacing: 8
|
||||
|
||||
Shape {
|
||||
id: replyCorner
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
@ -32,6 +37,7 @@ Item {
|
|||
Layout.preferredHeight: messageLayout.height - replyCorner.Layout.topMargin
|
||||
asynchronous: true
|
||||
antialiasing: true
|
||||
|
||||
ShapePath {
|
||||
strokeColor: Qt.hsla(Theme.palette.baseColor1.hslHue, Theme.palette.baseColor1.hslSaturation, Theme.palette.baseColor1.hslLightness, 0.4)
|
||||
strokeWidth: 3
|
||||
|
@ -50,86 +56,103 @@ Item {
|
|||
PathLine { x: 0; y: messageLayout.height}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: messageLayout
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: 4
|
||||
RowLayout {
|
||||
StatusSmartIdenticon {
|
||||
id: profileImage
|
||||
Layout.alignment: Qt.AlignTop
|
||||
name: replyDetails.sender.displayName
|
||||
asset: replyDetails.sender.profileImage.assetSettings
|
||||
ringSettings: replyDetails.sender.profileImage.ringSettings
|
||||
MouseArea {
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
enabled: root.profileClickable
|
||||
onClicked: replyProfileClicked(this, mouse)
|
||||
|
||||
implicitHeight: messageLayout.implicitHeight
|
||||
implicitWidth: messageLayout.implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: messageLayout
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
StatusSmartIdenticon {
|
||||
id: profileImage
|
||||
Layout.alignment: Qt.AlignTop
|
||||
name: replyDetails.sender.displayName
|
||||
asset: replyDetails.sender.profileImage.assetSettings
|
||||
ringSettings: replyDetails.sender.profileImage.ringSettings
|
||||
MouseArea {
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
enabled: root.profileClickable
|
||||
onClicked: replyProfileClicked(this, mouse)
|
||||
}
|
||||
}
|
||||
TextEdit {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: Theme.palette.baseColor1
|
||||
selectionColor: Theme.palette.primaryColor3
|
||||
selectedTextColor: Theme.palette.directColor1
|
||||
font.pixelSize: Theme.secondaryTextFontSize
|
||||
font.weight: Font.Medium
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
text: replyDetails.amISender ? qsTr("You") : replyDetails.sender.displayName
|
||||
}
|
||||
}
|
||||
TextEdit {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: Theme.palette.baseColor1
|
||||
selectionColor: Theme.palette.primaryColor3
|
||||
selectedTextColor: Theme.palette.directColor1
|
||||
font.pixelSize: Theme.secondaryTextFontSize
|
||||
font.weight: Font.Medium
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
text: replyDetails.amISender ? qsTr("You") : replyDetails.sender.displayName
|
||||
StatusTextMessage {
|
||||
Layout.fillWidth: true
|
||||
textField.font.pixelSize: Theme.secondaryTextFontSize
|
||||
textField.color: Theme.palette.baseColor1
|
||||
clip: true
|
||||
visible: !!replyDetails.messageText && replyDetails.contentType !== StatusMessage.ContentType.Sticker
|
||||
allowShowMore: false
|
||||
stripHtmlTags: true
|
||||
convertToSingleLine: true
|
||||
messageDetails: root.replyDetails
|
||||
}
|
||||
StatusImageMessage {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: imageAlias.paintedHeight
|
||||
imageWidth: 56
|
||||
source: replyDetails.contentType === StatusMessage.ContentType.Image ? replyDetails.messageContent : ""
|
||||
visible: source
|
||||
shapeType: StatusImageMessage.ShapeType.ROUNDED
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 48
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
visible: replyDetails.contentType === StatusMessage.ContentType.Sticker
|
||||
StatusSticker {
|
||||
asset.width: 48
|
||||
asset.height: 48
|
||||
asset.name: replyDetails.messageContent
|
||||
asset.isImage: true
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 22
|
||||
visible: replyDetails.contentType === StatusMessage.ContentType.Audio
|
||||
StatusAudioMessage {
|
||||
id: audioMessage
|
||||
anchors.left: parent.left
|
||||
width: 125
|
||||
height: 22
|
||||
isPreview: true
|
||||
audioSource: replyDetails.messageContent
|
||||
audioMessageInfoText: root.audioMessageInfoText
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusTextMessage {
|
||||
Layout.fillWidth: true
|
||||
textField.font.pixelSize: Theme.secondaryTextFontSize
|
||||
textField.color: Theme.palette.baseColor1
|
||||
convertToSingleLine: true
|
||||
clip: true
|
||||
visible: !!replyDetails.messageText && replyDetails.contentType !== StatusMessage.ContentType.Sticker
|
||||
allowShowMore: false
|
||||
messageDetails: root.replyDetails
|
||||
onLinkActivated: {
|
||||
root.linkActivated(link);
|
||||
}
|
||||
}
|
||||
StatusImageMessage {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: imageAlias.paintedHeight
|
||||
imageWidth: 56
|
||||
source: replyDetails.contentType === StatusMessage.ContentType.Image ? replyDetails.messageContent : ""
|
||||
visible: source
|
||||
shapeType: StatusImageMessage.ShapeType.ROUNDED
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 48
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
visible: replyDetails.contentType === StatusMessage.ContentType.Sticker
|
||||
StatusSticker {
|
||||
asset.width: 48
|
||||
asset.height: 48
|
||||
asset.name: replyDetails.messageContent
|
||||
asset.isImage: true
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 22
|
||||
visible: replyDetails.contentType === StatusMessage.ContentType.Audio
|
||||
StatusAudioMessage {
|
||||
id: audioMessage
|
||||
anchors.left: parent.left
|
||||
width: 125
|
||||
height: 22
|
||||
isPreview: true
|
||||
audioSource: replyDetails.messageContent
|
||||
audioMessageInfoText: root.audioMessageInfoText
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.messageClicked(mouse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ Item {
|
|||
property StatusMessageDetails messageDetails: StatusMessageDetails {}
|
||||
property bool isEdited: false
|
||||
property bool convertToSingleLine: false
|
||||
property bool stripHtmlTags: false
|
||||
|
||||
property alias textField: chatText
|
||||
property bool allowShowMore: true
|
||||
|
@ -25,16 +26,16 @@ Item {
|
|||
id: d
|
||||
property bool readMore: false
|
||||
readonly property bool veryLongChatText: chatText.length > 1000
|
||||
readonly property int showMoreHeight: showMoreLoader.visible ? showMoreLoader.height : 0
|
||||
readonly property int showMoreHeight: showMoreButtonLoader.visible ? showMoreButtonLoader.height : 0
|
||||
|
||||
readonly property string text: {
|
||||
if (root.messageDetails.contentType === StatusMessage.ContentType.Sticker)
|
||||
return "";
|
||||
|
||||
const formattedMessage = Utils.linkifyAndXSS(root.messageDetails.messageText);
|
||||
|
||||
if (root.messageDetails.contentType === StatusMessage.ContentType.Emoji)
|
||||
return Emoji.parse(formattedMessage, Emoji.size.middle, Emoji.format.png);
|
||||
return Emoji.parse(root.messageDetails.messageText, Emoji.size.middle, Emoji.format.png);
|
||||
|
||||
let formattedMessage = Utils.linkifyAndXSS(root.messageDetails.messageText);
|
||||
|
||||
if (root.isEdited) {
|
||||
const index = formattedMessage.endsWith("code>") ? formattedMessage.length : formattedMessage.length - 4;
|
||||
|
@ -44,12 +45,20 @@ Item {
|
|||
return Utils.getMessageWithStyle(Emoji.parse(editedMessage), chatText.hoveredLink)
|
||||
}
|
||||
|
||||
if (root.convertToSingleLine) {
|
||||
const singleLineMessage = Utils.convertToSingleLine(formattedMessage)
|
||||
return Utils.getMessageWithStyle(Emoji.parse(singleLineMessage), chatText.hoveredLink)
|
||||
}
|
||||
if (root.convertToSingleLine)
|
||||
formattedMessage = Utils.convertToSingleLine(formattedMessage)
|
||||
|
||||
return Utils.getMessageWithStyle(Emoji.parse(formattedMessage), chatText.hoveredLink)
|
||||
if (root.stripHtmlTags)
|
||||
formattedMessage = Utils.stripHtmlTags(formattedMessage)
|
||||
|
||||
// add emoji tags even after html striped
|
||||
formattedMessage = Emoji.parse(formattedMessage)
|
||||
|
||||
if (root.stripHtmlTags)
|
||||
// short return not to add styling when no html
|
||||
return formattedMessage
|
||||
|
||||
return Utils.getMessageWithStyle(formattedMessage, chatText.hoveredLink)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +72,7 @@ Item {
|
|||
|
||||
width: parent.width
|
||||
height: effectiveHeight + d.showMoreHeight / 2
|
||||
opacity: opMask.active ? 0 : 1
|
||||
opacity: !showMoreOpacityMask.active && !horizontalOpacityMask.active ? 1 : 0
|
||||
clip: true
|
||||
text: d.text
|
||||
selectedTextColor: Theme.palette.directColor1
|
||||
|
@ -72,7 +81,7 @@ Item {
|
|||
font.family: Theme.palette.baseFont.name
|
||||
font.pixelSize: Theme.primaryTextFontSize
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.Wrap
|
||||
wrapMode: root.convertToSingleLine ? Text.NoWrap : Text.Wrap
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
onLinkActivated: {
|
||||
|
@ -84,10 +93,40 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Horizontal crop mask
|
||||
|
||||
Loader {
|
||||
id: mask
|
||||
id: horizontalClipMask
|
||||
anchors.fill: chatText
|
||||
active: showMoreLoader.active && !d.readMore
|
||||
active: horizontalOpacityMask.active
|
||||
visible: false
|
||||
sourceComponent: LinearGradient {
|
||||
start: Qt.point(0, 0)
|
||||
end: Qt.point(chatText.width, 0)
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "white" }
|
||||
GradientStop { position: 0.85; color: "white" }
|
||||
GradientStop { position: 1; color: "transparent" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: horizontalOpacityMask
|
||||
active: root.convertToSingleLine && chatText.implicitWidth > chatText.width
|
||||
anchors.fill: chatText
|
||||
sourceComponent: OpacityMask {
|
||||
source: chatText
|
||||
maskSource: horizontalClipMask
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical "show more" mask
|
||||
|
||||
Loader {
|
||||
id: showMoreMaskGradient
|
||||
anchors.fill: chatText
|
||||
active: showMoreButtonLoader.active && !d.readMore
|
||||
visible: false
|
||||
sourceComponent: LinearGradient {
|
||||
start: Qt.point(0, 0)
|
||||
|
@ -101,17 +140,17 @@ Item {
|
|||
}
|
||||
|
||||
Loader {
|
||||
id: opMask
|
||||
active: showMoreLoader.active && !d.readMore
|
||||
id: showMoreOpacityMask
|
||||
active: showMoreButtonLoader.active && !d.readMore
|
||||
anchors.fill: chatText
|
||||
sourceComponent: OpacityMask {
|
||||
source: chatText
|
||||
maskSource: mask
|
||||
maskSource: showMoreMaskGradient
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: showMoreLoader
|
||||
id: showMoreButtonLoader
|
||||
active: root.allowShowMore && d.veryLongChatText
|
||||
visible: active
|
||||
anchors.verticalCenter: chatText.bottom
|
||||
|
|
|
@ -222,6 +222,10 @@ QtObject {
|
|||
return text.replace(/<br\s*\/>/gm, " ")
|
||||
}
|
||||
|
||||
function stripHtmlTags(text) {
|
||||
return text.replace(/<[^>]*>?/gm, '')
|
||||
}
|
||||
|
||||
function delegateModelSort(srcGroup, dstGroup, lessThan) {
|
||||
const insertPosition = (lessThan, item) => {
|
||||
let lower = 0
|
||||
|
|
|
@ -539,6 +539,10 @@ Loader {
|
|||
root.messageClickHandler(sender, Qt.point(mouse.x, mouse.y), true, false, false, null, false, false, true);
|
||||
}
|
||||
|
||||
onReplyMessageClicked: {
|
||||
root.messageStore.messageModule.jumpToMessage(root.responseToMessageWithId)
|
||||
}
|
||||
|
||||
onSenderNameClicked: {
|
||||
d.setMessageActive(root.messageId, true);
|
||||
root.messageClickHandler(sender, Qt.point(mouse.x, mouse.y), true);
|
||||
|
|
|
@ -58,23 +58,6 @@ QtObject {
|
|||
return Style.current.accountColors[colorIndex]
|
||||
}
|
||||
|
||||
function getReplyMessageStyle(msg, isCurrentUser) {
|
||||
return `<style type="text/css">`+
|
||||
`a {`+
|
||||
`color: ${Style.current.textColor};`+
|
||||
`}`+
|
||||
`a.mention {`+
|
||||
`color: ${isCurrentUser ? Style.current.mentionColor : Style.current.turquoise};`+
|
||||
`background-color: ${Style.current.mentionBgColor};` +
|
||||
`}`+
|
||||
`</style>`+
|
||||
`</head>`+
|
||||
`<body>`+
|
||||
`${msg}`+
|
||||
`</body>`+
|
||||
`</html>`
|
||||
}
|
||||
|
||||
function getLinkStyle(link, hoveredLink, textColor) {
|
||||
return `<style type="text/css">` +
|
||||
`a {` +
|
||||
|
|
Loading…
Reference in New Issue