Render edits
This commit is contained in:
parent
2e77a1554f
commit
d6504812c7
@ -108,6 +108,11 @@ Cache::isHiddenEvent(lmdb::txn &txn,
|
|||||||
const std::string &room_id)
|
const std::string &room_id)
|
||||||
{
|
{
|
||||||
using namespace mtx::events;
|
using namespace mtx::events;
|
||||||
|
|
||||||
|
// Always hide edits
|
||||||
|
if (mtx::accessors::relations(e).replaces())
|
||||||
|
return true;
|
||||||
|
|
||||||
if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) {
|
if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) {
|
||||||
MegolmSessionIndex index;
|
MegolmSessionIndex index;
|
||||||
index.room_id = room_id;
|
index.room_id = room_id;
|
||||||
@ -1891,6 +1896,31 @@ Cache::getTimelineIndex(const std::string &room_id, std::string_view event_id)
|
|||||||
return *val.data<uint64_t>();
|
return *val.data<uint64_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<uint64_t>
|
||||||
|
Cache::getArrivalIndex(const std::string &room_id, std::string_view event_id)
|
||||||
|
{
|
||||||
|
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
|
||||||
|
|
||||||
|
lmdb::dbi orderDb{0};
|
||||||
|
try {
|
||||||
|
orderDb = getEventToOrderDb(txn, room_id);
|
||||||
|
} catch (lmdb::runtime_error &e) {
|
||||||
|
nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})",
|
||||||
|
room_id,
|
||||||
|
e.what());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
lmdb::val indexVal{event_id.data(), event_id.size()}, val;
|
||||||
|
|
||||||
|
bool success = lmdb::dbi_get(txn, orderDb, indexVal, val);
|
||||||
|
if (!success) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return *val.data<uint64_t>();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::string>
|
std::optional<std::string>
|
||||||
Cache::getTimelineEventId(const std::string &room_id, uint64_t index)
|
Cache::getTimelineEventId(const std::string &room_id, uint64_t index)
|
||||||
{
|
{
|
||||||
|
@ -205,6 +205,8 @@ public:
|
|||||||
std::optional<uint64_t> getTimelineIndex(const std::string &room_id,
|
std::optional<uint64_t> getTimelineIndex(const std::string &room_id,
|
||||||
std::string_view event_id);
|
std::string_view event_id);
|
||||||
std::optional<std::string> getTimelineEventId(const std::string &room_id, uint64_t index);
|
std::optional<std::string> getTimelineEventId(const std::string &room_id, uint64_t index);
|
||||||
|
std::optional<uint64_t> getArrivalIndex(const std::string &room_id,
|
||||||
|
std::string_view event_id);
|
||||||
|
|
||||||
std::string previousBatchToken(const std::string &room_id);
|
std::string previousBatchToken(const std::string &room_id);
|
||||||
uint64_t saveOldMessages(const std::string &room_id, const mtx::responses::Messages &res);
|
uint64_t saveOldMessages(const std::string &room_id, const mtx::responses::Messages &res);
|
||||||
|
@ -405,6 +405,41 @@ EventStore::handle_room_verification(mtx::events::collections::TimelineEvents ev
|
|||||||
event);
|
event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<mtx::events::collections::TimelineEvents>
|
||||||
|
EventStore::edits(const std::string &event_id)
|
||||||
|
{
|
||||||
|
auto event_ids = cache::client()->relatedEvents(room_id_, event_id);
|
||||||
|
|
||||||
|
auto original_event = get(event_id, "", false, false);
|
||||||
|
if (!original_event)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto original_sender = mtx::accessors::sender(*original_event);
|
||||||
|
|
||||||
|
std::vector<mtx::events::collections::TimelineEvents> edits;
|
||||||
|
for (const auto &id : event_ids) {
|
||||||
|
auto related_event = get(id, event_id, false, false);
|
||||||
|
if (!related_event)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto edit_rel = mtx::accessors::relations(*related_event);
|
||||||
|
if (edit_rel.replaces() == event_id &&
|
||||||
|
original_sender == mtx::accessors::sender(*related_event))
|
||||||
|
edits.push_back(*related_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto c = cache::client();
|
||||||
|
std::sort(edits.begin(),
|
||||||
|
edits.end(),
|
||||||
|
[this, c](const mtx::events::collections::TimelineEvents &a,
|
||||||
|
const mtx::events::collections::TimelineEvents &b) {
|
||||||
|
return c->getArrivalIndex(this->room_id_, mtx::accessors::event_id(a)) <
|
||||||
|
c->getArrivalIndex(this->room_id_, mtx::accessors::event_id(b));
|
||||||
|
});
|
||||||
|
|
||||||
|
return edits;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantList
|
QVariantList
|
||||||
EventStore::reactions(const std::string &event_id)
|
EventStore::reactions(const std::string &event_id)
|
||||||
{
|
{
|
||||||
@ -487,7 +522,13 @@ EventStore::get(int idx, bool decrypt)
|
|||||||
if (!event_id)
|
if (!event_id)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto event = cache::client()->getEvent(room_id_, *event_id);
|
std::optional<mtx::events::collections::TimelineEvent> event;
|
||||||
|
auto edits_ = edits(*event_id);
|
||||||
|
if (edits_.empty())
|
||||||
|
event = cache::client()->getEvent(room_id_, *event_id);
|
||||||
|
else
|
||||||
|
event = {edits_.back()};
|
||||||
|
|
||||||
if (!event)
|
if (!event)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
else
|
||||||
@ -714,7 +755,7 @@ EventStore::decryptEvent(const IdIndex &idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mtx::events::collections::TimelineEvents *
|
mtx::events::collections::TimelineEvents *
|
||||||
EventStore::get(std::string_view id, std::string_view related_to, bool decrypt)
|
EventStore::get(std::string_view id, std::string_view related_to, bool decrypt, bool resolve_edits)
|
||||||
{
|
{
|
||||||
if (this->thread() != QThread::currentThread())
|
if (this->thread() != QThread::currentThread())
|
||||||
nhlog::db()->warn("{} called from a different thread!", __func__);
|
nhlog::db()->warn("{} called from a different thread!", __func__);
|
||||||
@ -722,7 +763,14 @@ EventStore::get(std::string_view id, std::string_view related_to, bool decrypt)
|
|||||||
if (id.empty())
|
if (id.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
IdIndex index{room_id_, std::string(id.data(), id.size())};
|
std::string id_ = std::string(id);
|
||||||
|
if (resolve_edits) {
|
||||||
|
auto edits_ = edits(id_);
|
||||||
|
if (!edits_.empty())
|
||||||
|
id_ = mtx::accessors::event_id(edits_.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
IdIndex index{room_id_, id_};
|
||||||
|
|
||||||
auto event_ptr = events_by_id_.object(index);
|
auto event_ptr = events_by_id_.object(index);
|
||||||
if (!event_ptr) {
|
if (!event_ptr) {
|
||||||
|
@ -66,7 +66,8 @@ public:
|
|||||||
// relatedFetched event
|
// relatedFetched event
|
||||||
mtx::events::collections::TimelineEvents *get(std::string_view id,
|
mtx::events::collections::TimelineEvents *get(std::string_view id,
|
||||||
std::string_view related_to,
|
std::string_view related_to,
|
||||||
bool decrypt = true);
|
bool decrypt = true,
|
||||||
|
bool resolve_edits = true);
|
||||||
// always returns a proper event as long as the idx is valid
|
// always returns a proper event as long as the idx is valid
|
||||||
mtx::events::collections::TimelineEvents *get(int idx, bool decrypt = true);
|
mtx::events::collections::TimelineEvents *get(int idx, bool decrypt = true);
|
||||||
|
|
||||||
@ -110,6 +111,7 @@ public slots:
|
|||||||
void clearTimeline();
|
void clearTimeline();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<mtx::events::collections::TimelineEvents> edits(const std::string &event_id);
|
||||||
mtx::events::collections::TimelineEvents *decryptEvent(
|
mtx::events::collections::TimelineEvents *decryptEvent(
|
||||||
const IdIndex &idx,
|
const IdIndex &idx,
|
||||||
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e);
|
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e);
|
||||||
|
Loading…
Reference in New Issue
Block a user