Add /reset-state command

pull/928/head
Nicolas Werner 3 years ago
parent 1dacf327e1
commit b3221b09d6
  1. 4
      man/nheko.1.adoc
  2. 38
      src/Cache.cpp
  3. 1
      src/Cache_p.h
  4. 2
      src/MatrixClient.cpp
  5. 2
      src/timeline/InputBar.cpp
  6. 23
      src/timeline/TimelineModel.cpp
  7. 3
      src/timeline/TimelineModel.h

@ -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.

@ -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)
{ {

@ -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(); }

@ -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>();

@ -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")) {

@ -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
{ {
@ -2248,7 +2268,8 @@ 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"))

@ -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);

Loading…
Cancel
Save