diff --git a/src/Cache.cpp b/src/Cache.cpp
index b55d53a6..9f3ada58 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -1461,6 +1461,44 @@ Cache::calculateRoomReadStatus(const std::string &room_id)
}
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
Cache::saveState(const mtx::responses::Sync &res)
{
using namespace mtx::events;
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 160ba626..8e5fa547 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -118,6 +118,7 @@ public:
std::size_t len = 30);
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);
bool isInitialized();
bool isDatabaseReady() { return databaseReady_ && isInitialized(); }
diff --git a/src/MatrixClient.cpp b/src/MatrixClient.cpp
index 1ef2bd3a..c565176e 100644
--- a/src/MatrixClient.cpp
+++ b/src/MatrixClient.cpp
@@ -20,6 +20,7 @@ Q_DECLARE_METATYPE(mtx::responses::Messages)
Q_DECLARE_METATYPE(mtx::responses::Notifications)
Q_DECLARE_METATYPE(mtx::responses::Rooms)
Q_DECLARE_METATYPE(mtx::responses::Sync)
+Q_DECLARE_METATYPE(mtx::responses::StateEvents)
Q_DECLARE_METATYPE(mtx::responses::JoinedGroups)
Q_DECLARE_METATYPE(mtx::responses::GroupProfile)
@@ -52,6 +53,7 @@ init()
qRegisterMetaType<mtx::responses::Notifications>();
qRegisterMetaType<mtx::responses::Rooms>();
qRegisterMetaType<mtx::responses::Sync>();
+ qRegisterMetaType<mtx::responses::StateEvents>();
qRegisterMetaType<mtx::responses::JoinedGroups>();
qRegisterMetaType<mtx::responses::GroupProfile>();
qRegisterMetaType<std::string>();
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index 18e224b2..cd7c4e0c 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -617,6 +617,8 @@ InputBar::command(const QString &command, QString args)
message(QStringLiteral("ノ┬─┬ノ ︵ ( \\o°o)\\"));
} else if (command == QLatin1String("clear-timeline")) {
room->clearTimeline();
+ } else if (command == QLatin1String("reset-state")) {
+ room->resetState();
} else if (command == QLatin1String("rotate-megolm-session")) {
cache::dropOutboundMegolmSession(room->roomId().toStdString());
} else if (command == QLatin1String("md")) {
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 6fc10142..719c7be6 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -440,6 +440,11 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj
cache::client(), &Cache::verificationStatusChanged, this, &TimelineModel::trustlevelChanged);
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>
@@ -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
TimelineModel::roomName() const
{
@@ -2247,8 +2267,9 @@ TimelineModel::widgetLinks() const
QStringList list;
- auto user = utils::localUser();
- auto av = QUrl::toPercentEncoding(QString::fromStdString(http::client()->mxc_to_download_url(avatarUrl(user).toStdString())));
+ auto user = utils::localUser();
+ auto av = QUrl::toPercentEncoding(
+ QString::fromStdString(http::client()->mxc_to_download_url(avatarUrl(user).toStdString())));
auto disp = QUrl::toPercentEncoding(displayName(user));
auto theme = UserSettings::instance()->theme();
if (theme == QStringLiteral("system"))
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index b4267e8d..f6cc1e6b 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -359,6 +359,7 @@ public slots:
void resetEdit();
void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; }
void clearTimeline() { events.clearTimeline(); }
+ void resetState();
void receivedSessionKey(const std::string &session_key)
{
events.receivedSessionKey(session_key);
@@ -401,6 +402,8 @@ signals:
void lastMessageChanged();
void notificationsChanged();
+ void newState(mtx::responses::StateEvents events);
+
void newMessageToSend(mtx::events::collections::TimelineEvents event);
void addPendingMessageToStore(mtx::events::collections::TimelineEvents event);
void updateFlowEventId(std::string event_id);
|