mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Show redactions in qml timeline
This commit is contained in:
parent
4efac5a247
commit
a1c97fc8d6
5 changed files with 77 additions and 24 deletions
|
@ -23,7 +23,7 @@ Rectangle {
|
||||||
ListView {
|
ListView {
|
||||||
id: chat
|
id: chat
|
||||||
|
|
||||||
cacheBuffer: 4*parent.height
|
cacheBuffer: parent.height
|
||||||
|
|
||||||
visible: timelineManager.timeline != null
|
visible: timelineManager.timeline != null
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -65,6 +65,7 @@ Rectangle {
|
||||||
case MtxEvent.TextMessage: return "delegates/TextMessage.qml"
|
case MtxEvent.TextMessage: return "delegates/TextMessage.qml"
|
||||||
case MtxEvent.ImageMessage: return "delegates/ImageMessage.qml"
|
case MtxEvent.ImageMessage: return "delegates/ImageMessage.qml"
|
||||||
case MtxEvent.VideoMessage: return "delegates/VideoMessage.qml"
|
case MtxEvent.VideoMessage: return "delegates/VideoMessage.qml"
|
||||||
|
case MtxEvent.Redacted: return "delegates/Redacted.qml"
|
||||||
default: return "delegates/placeholder.qml"
|
default: return "delegates/placeholder.qml"
|
||||||
}
|
}
|
||||||
property variant eventData: model
|
property variant eventData: model
|
||||||
|
|
15
resources/qml/delegates/Redacted.qml
Normal file
15
resources/qml/delegates/Redacted.qml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 2.5
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("redacted")
|
||||||
|
color: inactiveColors.text
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
height: contentHeight * 1.2
|
||||||
|
width: contentWidth * 1.2
|
||||||
|
background: Rectangle {
|
||||||
|
radius: parent.height / 2
|
||||||
|
color: colors.dark
|
||||||
|
}
|
||||||
|
}
|
|
@ -120,5 +120,6 @@
|
||||||
<file>qml/delegates/TextMessage.qml</file>
|
<file>qml/delegates/TextMessage.qml</file>
|
||||||
<file>qml/delegates/NoticeMessage.qml</file>
|
<file>qml/delegates/NoticeMessage.qml</file>
|
||||||
<file>qml/delegates/ImageMessage.qml</file>
|
<file>qml/delegates/ImageMessage.qml</file>
|
||||||
|
<file>qml/delegates/Redacted.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "TimelineModel.h"
|
#include "TimelineModel.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
@ -160,6 +161,12 @@ toRoomEventType(const mtx::events::Event<mtx::events::msg::Video> &)
|
||||||
{
|
{
|
||||||
return qml_mtx_events::EventType::VideoMessage;
|
return qml_mtx_events::EventType::VideoMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qml_mtx_events::EventType
|
||||||
|
toRoomEventType(const mtx::events::Event<mtx::events::msg::Redacted> &)
|
||||||
|
{
|
||||||
|
return qml_mtx_events::EventType::Redacted;
|
||||||
|
}
|
||||||
// ::EventType::Type toRoomEventType(const Event<mtx::events::msg::Location> &e) { return
|
// ::EventType::Type toRoomEventType(const Event<mtx::events::msg::Location> &e) { return
|
||||||
// ::EventType::LocationMessage; }
|
// ::EventType::LocationMessage; }
|
||||||
|
|
||||||
|
@ -319,19 +326,9 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
|
||||||
if (timeline.events.empty())
|
if (timeline.events.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<QString> ids;
|
std::vector<QString> ids = internalAddEvents(timeline.events);
|
||||||
for (const auto &e : timeline.events) {
|
|
||||||
QString id =
|
|
||||||
boost::apply_visitor([](const auto &e) -> QString { return eventId(e); }, e);
|
|
||||||
|
|
||||||
if (this->events.contains(id))
|
if (ids.empty())
|
||||||
continue;
|
|
||||||
|
|
||||||
this->events.insert(id, e);
|
|
||||||
ids.push_back(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ids.empty)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
beginInsertRows(QModelIndex(),
|
beginInsertRows(QModelIndex(),
|
||||||
|
@ -341,6 +338,52 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<QString>
|
||||||
|
TimelineModel::internalAddEvents(
|
||||||
|
const std::vector<mtx::events::collections::TimelineEvents> &timeline)
|
||||||
|
{
|
||||||
|
std::vector<QString> ids;
|
||||||
|
for (const auto &e : timeline) {
|
||||||
|
QString id =
|
||||||
|
boost::apply_visitor([](const auto &e) -> QString { return eventId(e); }, e);
|
||||||
|
|
||||||
|
if (this->events.contains(id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (auto redaction =
|
||||||
|
boost::get<mtx::events::RedactionEvent<mtx::events::msg::Redaction>>(&e)) {
|
||||||
|
QString redacts = QString::fromStdString(redaction->redacts);
|
||||||
|
auto redacted = std::find(eventOrder.begin(), eventOrder.end(), redacts);
|
||||||
|
|
||||||
|
if (redacted != eventOrder.end()) {
|
||||||
|
auto redactedEvent = boost::apply_visitor(
|
||||||
|
[](const auto &ev)
|
||||||
|
-> mtx::events::RoomEvent<mtx::events::msg::Redacted> {
|
||||||
|
mtx::events::RoomEvent<mtx::events::msg::Redacted>
|
||||||
|
replacement = {};
|
||||||
|
replacement.event_id = ev.event_id;
|
||||||
|
replacement.room_id = ev.room_id;
|
||||||
|
replacement.sender = ev.sender;
|
||||||
|
replacement.origin_server_ts = ev.origin_server_ts;
|
||||||
|
replacement.type = ev.type;
|
||||||
|
return replacement;
|
||||||
|
},
|
||||||
|
e);
|
||||||
|
events.insert(redacts, redactedEvent);
|
||||||
|
|
||||||
|
int row = (int)std::distance(eventOrder.begin(), redacted);
|
||||||
|
emit dataChanged(index(row, 0), index(row, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
continue; // don't insert redaction into timeline
|
||||||
|
}
|
||||||
|
|
||||||
|
this->events.insert(id, e);
|
||||||
|
ids.push_back(id);
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineModel::fetchHistory()
|
TimelineModel::fetchHistory()
|
||||||
{
|
{
|
||||||
|
@ -373,17 +416,7 @@ TimelineModel::fetchHistory()
|
||||||
void
|
void
|
||||||
TimelineModel::addBackwardsEvents(const mtx::responses::Messages &msgs)
|
TimelineModel::addBackwardsEvents(const mtx::responses::Messages &msgs)
|
||||||
{
|
{
|
||||||
std::vector<QString> ids;
|
std::vector<QString> ids = internalAddEvents(msgs.chunk);
|
||||||
for (const auto &e : msgs.chunk) {
|
|
||||||
QString id =
|
|
||||||
boost::apply_visitor([](const auto &e) -> QString { return eventId(e); }, e);
|
|
||||||
|
|
||||||
if (this->events.contains(id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
this->events.insert(id, e);
|
|
||||||
ids.push_back(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ids.empty()) {
|
if (!ids.empty()) {
|
||||||
beginInsertRows(QModelIndex(), 0, static_cast<int>(ids.size() - 1));
|
beginInsertRows(QModelIndex(), 0, static_cast<int>(ids.size() - 1));
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum EventType
|
||||||
NoticeMessage,
|
NoticeMessage,
|
||||||
TextMessage,
|
TextMessage,
|
||||||
VideoMessage,
|
VideoMessage,
|
||||||
|
Redacted,
|
||||||
UnknownMessage,
|
UnknownMessage,
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(EventType)
|
Q_ENUM_NS(EventType)
|
||||||
|
@ -124,6 +125,8 @@ signals:
|
||||||
private:
|
private:
|
||||||
DecryptionResult decryptEvent(
|
DecryptionResult decryptEvent(
|
||||||
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e) const;
|
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e) const;
|
||||||
|
std::vector<QString> internalAddEvents(
|
||||||
|
const std::vector<mtx::events::collections::TimelineEvents> &timeline);
|
||||||
|
|
||||||
QHash<QString, mtx::events::collections::TimelineEvents> events;
|
QHash<QString, mtx::events::collections::TimelineEvents> events;
|
||||||
std::vector<QString> eventOrder;
|
std::vector<QString> eventOrder;
|
||||||
|
|
Loading…
Reference in a new issue