Add /reset-state command

This commit is contained in:
Nicolas Werner 2022-02-05 08:40:56 +01:00
parent 1dacf327e1
commit b3221b09d6
7 changed files with 73 additions and 2 deletions

View file

@ -195,6 +195,10 @@ Inserts `ノ┬─┬ノ ︵ ( \\o°o)\\`
Removes all but the most recent messages from the currently rendered timeline Removes all but the most recent messages from the currently rendered timeline
and then refetches it from the server; can be used to fix some cache issues. and then refetches it from the server; can be used to fix some cache issues.
*/reset-state*::
Fetches all the state events in the current room again; can be used to fix some
cache issues.
*/rotate-megolm-session*:: */rotate-megolm-session*::
Rotates the encryption key used to send encrypted messages in a room. Rotates the encryption key used to send encrypted messages in a room.

View file

@ -1460,6 +1460,44 @@ Cache::calculateRoomReadStatus(const std::string &room_id)
return getEventIndex(room_id, last_event_id_) > getEventIndex(room_id, fullyReadEventId_); return getEventIndex(room_id, last_event_id_) > getEventIndex(room_id, fullyReadEventId_);
} }
void
Cache::updateState(const std::string &room, const mtx::responses::StateEvents &state)
{
auto txn = lmdb::txn::begin(env_);
auto statesdb = getStatesDb(txn, room);
auto stateskeydb = getStatesKeyDb(txn, room);
auto membersdb = getMembersDb(txn, room);
auto eventsDb = getEventsDb(txn, room);
saveStateEvents(txn, statesdb, stateskeydb, membersdb, eventsDb, room, state.events);
RoomInfo updatedInfo;
updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString();
updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString();
updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString();
updatedInfo.version = getRoomVersion(txn, statesdb).toStdString();
updatedInfo.is_space = getRoomIsSpace(txn, statesdb);
{
std::string_view data;
if (roomsDb_.get(txn, room, data)) {
try {
RoomInfo tmp = json::parse(std::string_view(data.data(), data.size()));
updatedInfo.tags = tmp.tags;
} catch (const json::exception &e) {
nhlog::db()->warn("failed to parse room info: room_id ({}), {}: {}",
room,
std::string(data.data(), data.size()),
e.what());
}
}
}
roomsDb_.put(txn, room, json(updatedInfo).dump());
updateSpaces(txn, {room}, {room});
txn.commit();
}
void void
Cache::saveState(const mtx::responses::Sync &res) Cache::saveState(const mtx::responses::Sync &res)
{ {

View file

@ -118,6 +118,7 @@ public:
std::size_t len = 30); std::size_t len = 30);
size_t memberCount(const std::string &room_id); size_t memberCount(const std::string &room_id);
void updateState(const std::string &room, const mtx::responses::StateEvents &state);
void saveState(const mtx::responses::Sync &res); void saveState(const mtx::responses::Sync &res);
bool isInitialized(); bool isInitialized();
bool isDatabaseReady() { return databaseReady_ && isInitialized(); } bool isDatabaseReady() { return databaseReady_ && isInitialized(); }

View file

@ -20,6 +20,7 @@ Q_DECLARE_METATYPE(mtx::responses::Messages)
Q_DECLARE_METATYPE(mtx::responses::Notifications) Q_DECLARE_METATYPE(mtx::responses::Notifications)
Q_DECLARE_METATYPE(mtx::responses::Rooms) Q_DECLARE_METATYPE(mtx::responses::Rooms)
Q_DECLARE_METATYPE(mtx::responses::Sync) Q_DECLARE_METATYPE(mtx::responses::Sync)
Q_DECLARE_METATYPE(mtx::responses::StateEvents)
Q_DECLARE_METATYPE(mtx::responses::JoinedGroups) Q_DECLARE_METATYPE(mtx::responses::JoinedGroups)
Q_DECLARE_METATYPE(mtx::responses::GroupProfile) Q_DECLARE_METATYPE(mtx::responses::GroupProfile)
@ -52,6 +53,7 @@ init()
qRegisterMetaType<mtx::responses::Notifications>(); qRegisterMetaType<mtx::responses::Notifications>();
qRegisterMetaType<mtx::responses::Rooms>(); qRegisterMetaType<mtx::responses::Rooms>();
qRegisterMetaType<mtx::responses::Sync>(); qRegisterMetaType<mtx::responses::Sync>();
qRegisterMetaType<mtx::responses::StateEvents>();
qRegisterMetaType<mtx::responses::JoinedGroups>(); qRegisterMetaType<mtx::responses::JoinedGroups>();
qRegisterMetaType<mtx::responses::GroupProfile>(); qRegisterMetaType<mtx::responses::GroupProfile>();
qRegisterMetaType<std::string>(); qRegisterMetaType<std::string>();

View file

@ -617,6 +617,8 @@ InputBar::command(const QString &command, QString args)
message(QStringLiteral("ノ┬─┬ノ ︵ ( \\o°o)\\")); message(QStringLiteral("ノ┬─┬ノ ︵ ( \\o°o)\\"));
} else if (command == QLatin1String("clear-timeline")) { } else if (command == QLatin1String("clear-timeline")) {
room->clearTimeline(); room->clearTimeline();
} else if (command == QLatin1String("reset-state")) {
room->resetState();
} else if (command == QLatin1String("rotate-megolm-session")) { } else if (command == QLatin1String("rotate-megolm-session")) {
cache::dropOutboundMegolmSession(room->roomId().toStdString()); cache::dropOutboundMegolmSession(room->roomId().toStdString());
} else if (command == QLatin1String("md")) { } else if (command == QLatin1String("md")) {

View file

@ -440,6 +440,11 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
cache::client(), &Cache::verificationStatusChanged, this, &TimelineModel::trustlevelChanged); cache::client(), &Cache::verificationStatusChanged, this, &TimelineModel::trustlevelChanged);
showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent); showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent);
connect(this, &TimelineModel::newState, this, [this](mtx::responses::StateEvents events_) {
cache::client()->updateState(room_id_.toStdString(), events_);
this->syncState({std::move(events_.events)});
});
} }
QHash<int, QByteArray> QHash<int, QByteArray>
@ -2170,6 +2175,21 @@ TimelineModel::resetEdit()
} }
} }
void
TimelineModel::resetState()
{
http::client()->get_state(
room_id_.toStdString(),
[this](const mtx::responses::StateEvents &events_, mtx::http::RequestErr e) {
if (e) {
nhlog::net()->error("Failed to retrive current room state: {}", *e);
return;
}
emit newState(events_);
});
}
QString QString
TimelineModel::roomName() const TimelineModel::roomName() const
{ {
@ -2247,8 +2267,9 @@ TimelineModel::widgetLinks() const
QStringList list; QStringList list;
auto user = utils::localUser(); auto user = utils::localUser();
auto av = QUrl::toPercentEncoding(QString::fromStdString(http::client()->mxc_to_download_url(avatarUrl(user).toStdString()))); auto av = QUrl::toPercentEncoding(
QString::fromStdString(http::client()->mxc_to_download_url(avatarUrl(user).toStdString())));
auto disp = QUrl::toPercentEncoding(displayName(user)); auto disp = QUrl::toPercentEncoding(displayName(user));
auto theme = UserSettings::instance()->theme(); auto theme = UserSettings::instance()->theme();
if (theme == QStringLiteral("system")) if (theme == QStringLiteral("system"))

View file

@ -359,6 +359,7 @@ public slots:
void resetEdit(); void resetEdit();
void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; } void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; }
void clearTimeline() { events.clearTimeline(); } void clearTimeline() { events.clearTimeline(); }
void resetState();
void receivedSessionKey(const std::string &session_key) void receivedSessionKey(const std::string &session_key)
{ {
events.receivedSessionKey(session_key); events.receivedSessionKey(session_key);
@ -401,6 +402,8 @@ signals:
void lastMessageChanged(); void lastMessageChanged();
void notificationsChanged(); void notificationsChanged();
void newState(mtx::responses::StateEvents events);
void newMessageToSend(mtx::events::collections::TimelineEvents event); void newMessageToSend(mtx::events::collections::TimelineEvents event);
void addPendingMessageToStore(mtx::events::collections::TimelineEvents event); void addPendingMessageToStore(mtx::events::collections::TimelineEvents event);
void updateFlowEventId(std::string event_id); void updateFlowEventId(std::string event_id);