mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Save account data and allow hiding events via account data
This commit is contained in:
parent
8d14a058c6
commit
c4e4938d35
4 changed files with 107 additions and 32 deletions
|
@ -341,7 +341,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
MatrixClient
|
MatrixClient
|
||||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
GIT_TAG d8666a3f1a5b709b78ccea2b545d540a8cb502ca
|
GIT_TAG ac680e971d437eb2135ef994dcb58c0bbb5bdf61
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(MatrixClient)
|
FetchContent_MakeAvailable(MatrixClient)
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -146,7 +146,7 @@
|
||||||
"name": "mtxclient",
|
"name": "mtxclient",
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"commit": "d8666a3f1a5b709b78ccea2b545d540a8cb502ca",
|
"commit": "ac680e971d437eb2135ef994dcb58c0bbb5bdf61",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Nheko-Reborn/mtxclient.git"
|
"url": "https://github.com/Nheko-Reborn/mtxclient.git"
|
||||||
}
|
}
|
||||||
|
|
121
src/Cache.cpp
121
src/Cache.cpp
|
@ -94,8 +94,10 @@ namespace {
|
||||||
std::unique_ptr<Cache> instance_ = nullptr;
|
std::unique_ptr<Cache> instance_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
bool
|
||||||
isHiddenEvent(mtx::events::collections::TimelineEvents e, const std::string &room_id)
|
Cache::isHiddenEvent(lmdb::txn &txn,
|
||||||
|
mtx::events::collections::TimelineEvents e,
|
||||||
|
const std::string &room_id)
|
||||||
{
|
{
|
||||||
using namespace mtx::events;
|
using namespace mtx::events;
|
||||||
if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) {
|
if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) {
|
||||||
|
@ -109,13 +111,27 @@ isHiddenEvent(mtx::events::collections::TimelineEvents e, const std::string &roo
|
||||||
e = result.event.value();
|
e = result.event.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::initializer_list<EventType> hiddenEvents = {
|
mtx::events::account_data::nheko_extensions::HiddenEvents hiddenEvents;
|
||||||
|
hiddenEvents.hidden_event_types = {
|
||||||
EventType::Reaction, EventType::CallCandidates, EventType::Unsupported};
|
EventType::Reaction, EventType::CallCandidates, EventType::Unsupported};
|
||||||
|
|
||||||
|
if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, ""))
|
||||||
|
hiddenEvents = std::move(
|
||||||
|
std::get<
|
||||||
|
mtx::events::Event<mtx::events::account_data::nheko_extensions::HiddenEvents>>(
|
||||||
|
*temp)
|
||||||
|
.content);
|
||||||
|
if (auto temp = getAccountData(txn, mtx::events::EventType::NhekoHiddenEvents, room_id))
|
||||||
|
hiddenEvents = std::move(
|
||||||
|
std::get<
|
||||||
|
mtx::events::Event<mtx::events::account_data::nheko_extensions::HiddenEvents>>(
|
||||||
|
*temp)
|
||||||
|
.content);
|
||||||
|
|
||||||
return std::visit(
|
return std::visit(
|
||||||
[](const auto &ev) {
|
[hiddenEvents](const auto &ev) {
|
||||||
return std::any_of(hiddenEvents.begin(),
|
return std::any_of(hiddenEvents.hidden_event_types.begin(),
|
||||||
hiddenEvents.end(),
|
hiddenEvents.hidden_event_types.end(),
|
||||||
[ev](EventType type) { return type == ev.type; });
|
[ev](EventType type) { return type == ev.type; });
|
||||||
},
|
},
|
||||||
e);
|
e);
|
||||||
|
@ -624,6 +640,7 @@ Cache::removeRoom(lmdb::txn &txn, const std::string &roomid)
|
||||||
{
|
{
|
||||||
lmdb::dbi_del(txn, roomsDb_, lmdb::val(roomid), nullptr);
|
lmdb::dbi_del(txn, roomsDb_, lmdb::val(roomid), nullptr);
|
||||||
lmdb::dbi_drop(txn, getStatesDb(txn, roomid), true);
|
lmdb::dbi_drop(txn, getStatesDb(txn, roomid), true);
|
||||||
|
lmdb::dbi_drop(txn, getAccountDataDb(txn, roomid), true);
|
||||||
lmdb::dbi_drop(txn, getMembersDb(txn, roomid), true);
|
lmdb::dbi_drop(txn, getMembersDb(txn, roomid), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,6 +999,19 @@ Cache::saveState(const mtx::responses::Sync &res)
|
||||||
|
|
||||||
setNextBatchToken(txn, res.next_batch);
|
setNextBatchToken(txn, res.next_batch);
|
||||||
|
|
||||||
|
if (!res.account_data.events.empty()) {
|
||||||
|
auto accountDataDb = getAccountDataDb(txn, "");
|
||||||
|
for (const auto &ev : res.account_data.events)
|
||||||
|
std::visit(
|
||||||
|
[&txn, &accountDataDb](const auto &event) {
|
||||||
|
lmdb::dbi_put(txn,
|
||||||
|
accountDataDb,
|
||||||
|
lmdb::val(to_string(event.type)),
|
||||||
|
lmdb::val(json(event).dump()));
|
||||||
|
},
|
||||||
|
ev);
|
||||||
|
}
|
||||||
|
|
||||||
// Save joined rooms
|
// Save joined rooms
|
||||||
for (const auto &room : res.rooms.join) {
|
for (const auto &room : res.rooms.join) {
|
||||||
auto statesdb = getStatesDb(txn, room.first);
|
auto statesdb = getStatesDb(txn, room.first);
|
||||||
|
@ -1001,30 +1031,43 @@ Cache::saveState(const mtx::responses::Sync &res)
|
||||||
updatedInfo.version = getRoomVersion(txn, statesdb).toStdString();
|
updatedInfo.version = getRoomVersion(txn, statesdb).toStdString();
|
||||||
|
|
||||||
// Process the account_data associated with this room
|
// Process the account_data associated with this room
|
||||||
bool has_new_tags = false;
|
if (!res.account_data.events.empty()) {
|
||||||
for (const auto &evt : room.second.account_data.events) {
|
auto accountDataDb = getAccountDataDb(txn, room.first);
|
||||||
// for now only fetch tag events
|
|
||||||
if (std::holds_alternative<Event<account_data::Tags>>(evt)) {
|
bool has_new_tags = false;
|
||||||
auto tags_evt = std::get<Event<account_data::Tags>>(evt);
|
for (const auto &evt : room.second.account_data.events) {
|
||||||
has_new_tags = true;
|
std::visit(
|
||||||
for (const auto &tag : tags_evt.content.tags) {
|
[&txn, &accountDataDb](const auto &event) {
|
||||||
updatedInfo.tags.push_back(tag.first);
|
lmdb::dbi_put(txn,
|
||||||
|
accountDataDb,
|
||||||
|
lmdb::val(to_string(event.type)),
|
||||||
|
lmdb::val(json(event).dump()));
|
||||||
|
},
|
||||||
|
evt);
|
||||||
|
|
||||||
|
// for tag events
|
||||||
|
if (std::holds_alternative<Event<account_data::Tags>>(evt)) {
|
||||||
|
auto tags_evt = std::get<Event<account_data::Tags>>(evt);
|
||||||
|
has_new_tags = true;
|
||||||
|
for (const auto &tag : tags_evt.content.tags) {
|
||||||
|
updatedInfo.tags.push_back(tag.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!has_new_tags) {
|
||||||
if (!has_new_tags) {
|
// retrieve the old tags, they haven't changed
|
||||||
// retrieve the old tags, they haven't changed
|
lmdb::val data;
|
||||||
lmdb::val data;
|
if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room.first), data)) {
|
||||||
if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room.first), data)) {
|
try {
|
||||||
try {
|
RoomInfo tmp = json::parse(
|
||||||
RoomInfo tmp =
|
std::string_view(data.data(), data.size()));
|
||||||
json::parse(std::string_view(data.data(), data.size()));
|
updatedInfo.tags = tmp.tags;
|
||||||
updatedInfo.tags = tmp.tags;
|
} catch (const json::exception &e) {
|
||||||
} catch (const json::exception &e) {
|
nhlog::db()->warn(
|
||||||
nhlog::db()->warn(
|
"failed to parse room info: room_id ({}), {}",
|
||||||
"failed to parse room info: room_id ({}), {}",
|
room.first,
|
||||||
room.first,
|
std::string(data.data(), data.size()));
|
||||||
std::string(data.data(), data.size()));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2439,7 +2482,7 @@ Cache::saveTimelineMessages(lmdb::txn &txn,
|
||||||
lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index)));
|
lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index)));
|
||||||
|
|
||||||
// TODO(Nico): Allow blacklisting more event types in UI
|
// TODO(Nico): Allow blacklisting more event types in UI
|
||||||
if (!isHiddenEvent(e, room_id)) {
|
if (!isHiddenEvent(txn, e, room_id)) {
|
||||||
++msgIndex;
|
++msgIndex;
|
||||||
lmdb::cursor_put(msgCursor.handle(),
|
lmdb::cursor_put(msgCursor.handle(),
|
||||||
lmdb::val(&msgIndex, sizeof(msgIndex)),
|
lmdb::val(&msgIndex, sizeof(msgIndex)),
|
||||||
|
@ -2522,7 +2565,7 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message
|
||||||
lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index)));
|
lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index)));
|
||||||
|
|
||||||
// TODO(Nico): Allow blacklisting more event types in UI
|
// TODO(Nico): Allow blacklisting more event types in UI
|
||||||
if (!isHiddenEvent(e, room_id)) {
|
if (!isHiddenEvent(txn, e, room_id)) {
|
||||||
--msgIndex;
|
--msgIndex;
|
||||||
lmdb::dbi_put(
|
lmdb::dbi_put(
|
||||||
txn, order2msgDb, lmdb::val(&msgIndex, sizeof(msgIndex)), event_id);
|
txn, order2msgDb, lmdb::val(&msgIndex, sizeof(msgIndex)), event_id);
|
||||||
|
@ -2840,6 +2883,24 @@ Cache::deleteOldData() noexcept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<mtx::events::collections::RoomAccountDataEvents>
|
||||||
|
Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto db = getAccountDataDb(txn, room_id);
|
||||||
|
|
||||||
|
lmdb::val data;
|
||||||
|
if (lmdb::dbi_get(txn, db, lmdb::val(to_string(type)), data)) {
|
||||||
|
mtx::responses::utils::RoomAccountDataEvents events;
|
||||||
|
mtx::responses::utils::parse_room_account_data_events(
|
||||||
|
std::string_view(data.data(), data.size()), events);
|
||||||
|
return events.front();
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Cache::hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
|
Cache::hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
|
||||||
const std::string &room_id,
|
const std::string &room_id,
|
||||||
|
|
|
@ -289,6 +289,14 @@ private:
|
||||||
const std::string &room_id,
|
const std::string &room_id,
|
||||||
const mtx::responses::Timeline &res);
|
const mtx::responses::Timeline &res);
|
||||||
|
|
||||||
|
//! retrieve a specific event from account data
|
||||||
|
//! pass empty room_id for global account data
|
||||||
|
std::optional<mtx::events::collections::RoomAccountDataEvents>
|
||||||
|
getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id);
|
||||||
|
bool isHiddenEvent(lmdb::txn &txn,
|
||||||
|
mtx::events::collections::TimelineEvents e,
|
||||||
|
const std::string &room_id);
|
||||||
|
|
||||||
//! Remove a room from the cache.
|
//! Remove a room from the cache.
|
||||||
// void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
|
// void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -498,6 +506,12 @@ private:
|
||||||
return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE);
|
return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id)
|
||||||
|
{
|
||||||
|
return lmdb::dbi::open(
|
||||||
|
txn, std::string(room_id + "/account_data").c_str(), MDB_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
lmdb::dbi getMembersDb(lmdb::txn &txn, const std::string &room_id)
|
lmdb::dbi getMembersDb(lmdb::txn &txn, const std::string &room_id)
|
||||||
{
|
{
|
||||||
return lmdb::dbi::open(txn, std::string(room_id + "/members").c_str(), MDB_CREATE);
|
return lmdb::dbi::open(txn, std::string(room_id + "/members").c_str(), MDB_CREATE);
|
||||||
|
|
Loading…
Reference in a new issue