Warning, /network/neochat/src/qml/RichLabel.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2020 Black Hat <bhat@encom.eu.org> 0002 // SPDX-License-Identifier: GPL-3.0-only 0003 0004 import QtQuick 0005 import QtQuick.Layouts 0006 0007 import org.kde.neochat 0008 import org.kde.kirigami as Kirigami 0009 0010 /** 0011 * @brief A component to show the rich display text of text message. 0012 */ 0013 TextEdit { 0014 id: root 0015 0016 /** 0017 * @brief The rich text message to display. 0018 */ 0019 property string textMessage 0020 0021 /** 0022 * @brief Whether this message is replying to another. 0023 */ 0024 property bool isReply 0025 0026 /** 0027 * @brief Regex for detecting a message with a single emoji. 0028 */ 0029 readonly property var isEmojiRegex: /^(<span style='.*'>)?(\u00a9|\u00ae|[\u20D0-\u2fff]|[\u3190-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/ 0030 0031 /** 0032 * @brief Whether the message is an emoji 0033 */ 0034 readonly property var isEmoji: isEmojiRegex.test(textMessage) 0035 0036 /** 0037 * @brief Regex for detecting a message with a spoiler. 0038 */ 0039 readonly property var hasSpoiler: /data-mx-spoiler/g 0040 0041 /** 0042 * @brief Whether a spoiler should be revealed. 0043 */ 0044 property bool spoilerRevealed: !hasSpoiler.test(textMessage) 0045 0046 ListView.onReused: Qt.binding(() => !hasSpoiler.test(textMessage)) 0047 0048 persistentSelection: true 0049 0050 // Work around QTBUG 93281 0051 Component.onCompleted: if (text.includes("<img")) { 0052 Controller.forceRefreshTextDocument(root.textDocument, root) 0053 } 0054 0055 text: "<style> 0056 table { 0057 width:100%; 0058 border-width: 1px; 0059 border-collapse: collapse; 0060 border-style: solid; 0061 } 0062 code { 0063 background-color:" + Kirigami.Theme.alternateBackgroundColor + "; 0064 } 0065 table th, 0066 table td { 0067 border: 1px solid black; 0068 padding: 3px; 0069 } 0070 blockquote { 0071 margin: 0; 0072 } 0073 blockquote table { 0074 width: 100%; 0075 border-width: 0; 0076 background-color:" + Kirigami.Theme.alternateBackgroundColor + "; 0077 } 0078 blockquote td { 0079 width: 100%; 0080 padding: " + Kirigami.Units.largeSpacing + "; 0081 } 0082 pre { 0083 white-space: pre-wrap 0084 } 0085 a{ 0086 color: " + Kirigami.Theme.linkColor + "; 0087 text-decoration: none; 0088 } 0089 " + (!spoilerRevealed ? " 0090 [data-mx-spoiler] a { 0091 color: transparent; 0092 background: " + Kirigami.Theme.textColor + "; 0093 } 0094 [data-mx-spoiler] { 0095 color: transparent; 0096 background: " + Kirigami.Theme.textColor + "; 0097 } 0098 " : "") + " 0099 </style>" + textMessage 0100 0101 color: Kirigami.Theme.textColor 0102 selectedTextColor: Kirigami.Theme.highlightedTextColor 0103 selectionColor: Kirigami.Theme.highlightColor 0104 font { 0105 pointSize: !root.isReply && root.isEmoji ? Kirigami.Theme.defaultFont.pointSize * 4 : Kirigami.Theme.defaultFont.pointSize 0106 family: root.isEmoji ? 'emoji' : Kirigami.Theme.defaultFont.family 0107 } 0108 selectByMouse: !Kirigami.Settings.isMobile 0109 readOnly: true 0110 wrapMode: Text.Wrap 0111 textFormat: Text.RichText 0112 0113 onLinkActivated: link => { 0114 spoilerRevealed = true 0115 RoomManager.resolveResource(link, "join") 0116 } 0117 onHoveredLinkChanged: if (hoveredLink.length > 0 && hoveredLink !== "1") { 0118 applicationWindow().hoverLinkIndicator.text = hoveredLink; 0119 } else { 0120 applicationWindow().hoverLinkIndicator.text = ""; 0121 } 0122 0123 HoverHandler { 0124 cursorShape: (parent.hoveredLink || !spoilerRevealed) ? Qt.PointingHandCursor : Qt.IBeamCursor 0125 } 0126 0127 TapHandler { 0128 enabled: !parent.hoveredLink && !spoilerRevealed 0129 onTapped: spoilerRevealed = true 0130 } 0131 }