Init rich reply.

square-messages
Black Hat 2018-11-27 08:09:45 +08:00
parent 948da868a9
commit cc5ba20375
3 changed files with 120 additions and 26 deletions

View File

@ -93,40 +93,106 @@ ColumnLayout {
}
}
contentItem: TextEdit {
Layout.fillWidth: true
contentItem: ColumnLayout {
Control {
Layout.fillWidth: true
id: contentLabel
visible: replyEventId || ""
text: "<style>a{color: white;} .user-pill{}</style>" + display
background: MouseArea {
onClicked: goToEvent(replyEventId)
}
color: "white"
contentItem: RowLayout {
spacing: 4
font.family: CommonFont.font.family
font.pixelSize: 14
selectByMouse: true
readOnly: true
wrapMode: Label.Wrap
selectedTextColor: Material.accent
selectionColor: "white"
textFormat: Text.RichText
Rectangle {
Layout.preferredWidth: 2
Layout.fillHeight: true
onLinkActivated: {
if (link.startsWith("https://matrix.to/")) {
var result = link.replace(/\?.*/, "").match("https://matrix.to/#/(!.*:.*)/(\\$.*:.*)")
if (result.length < 3) return
if (result[1] != currentRoom.id) return
if (!result[2]) return
goToEvent(result[2])
} else {
Qt.openUrlExternally(link)
color: "white"
}
ColumnLayout {
Layout.fillWidth: true
spacing: 0
Control {
padding: 4
contentItem: RowLayout {
spacing: 4
ImageItem {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
source: replyAuthor ? replyAuthor.paintable : null
}
Label {
color: "white"
text: replyAuthor ? replyAuthor.displayName : ""
}
}
background: Rectangle {
color: "black"
opacity: 0.2
radius: height / 2
}
}
Label {
Layout.fillWidth: true
text: "<style>a{color: white;} .user-pill{}</style>" + (replyDisplay ? replyDisplay.replace(/<mx-reply>.*<\/mx-reply>/g, "") : "")
color: "white"
wrapMode: Label.Wrap
textFormat: Label.RichText
}
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
TextEdit {
Layout.fillWidth: true
id: contentLabel
text: "<style>a{color: white;} .user-pill{}</style>" + (replyEventId ? display.replace(/<mx-reply>.*<\/mx-reply>/g, "") : display)
color: "white"
font.family: CommonFont.font.family
font.pixelSize: 14
selectByMouse: true
readOnly: true
wrapMode: Label.Wrap
selectedTextColor: Material.accent
selectionColor: "white"
textFormat: Text.RichText
onLinkActivated: {
if (link.startsWith("https://matrix.to/")) {
var result = link.replace(/\?.*/, "").match("https://matrix.to/#/(!.*:.*)/(\\$.*:.*)")
if (result.length < 3) return
if (result[1] != currentRoom.id) return
if (!result[2]) return
goToEvent(result[2])
} else {
Qt.openUrlExternally(link)
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}
}

View File

@ -39,6 +39,9 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const {
roles[LongOperationRole] = "progressInfo";
roles[AnnotationRole] = "annotation";
roles[EventResolvedTypeRole] = "eventResolvedType";
roles[ReplyEventIdRole] = "replyEventId";
roles[ReplyAuthorRole] = "replyAuthor";
roles[ReplyDisplayRole] = "replyDisplay";
roles[UserMarkerRole] = "userMarker";
return roles;
}
@ -372,6 +375,28 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const {
return variantList;
}
if (role == ReplyEventIdRole || role == ReplyDisplayRole ||
role == ReplyAuthorRole) {
const QString &replyEventId = evt.contentJson()["m.relates_to"]
.toObject()["m.in_reply_to"]
.toObject()["event_id"]
.toString();
if (replyEventId.isEmpty()) return {};
const auto replyIt = m_currentRoom->findInTimeline(replyEventId);
if (replyIt == m_currentRoom->timelineEdge()) return {};
const auto& replyEvt = **replyIt;
switch (role) {
case ReplyEventIdRole:
return replyEventId;
case ReplyDisplayRole:
return utils::eventToString(replyEvt, m_currentRoom, Qt::RichText);
case ReplyAuthorRole:
return QVariant::fromValue(
m_currentRoom->user(replyEvt.senderId()));
}
return {};
}
if (role == AboveEventTypeRole || role == AboveSectionRole ||
role == AboveAuthorRole || role == AboveTimeRole)
for (auto r = row + 1; r < rowCount(); ++r) {

View File

@ -30,6 +30,9 @@ class MessageEventModel : public QAbstractListModel {
LongOperationRole,
AnnotationRole,
UserMarkerRole,
ReplyEventIdRole,
ReplyAuthorRole,
ReplyDisplayRole,
// For debugging
EventResolvedTypeRole,
};