diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index 0ddf0f8b..fbaf9ddd 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -25,6 +25,20 @@
#include "Sync.h"
#include "UserInfoWidget.h"
+#include "AliasesEventContent.h"
+#include "AvatarEventContent.h"
+#include "CanonicalAliasEventContent.h"
+#include "CreateEventContent.h"
+#include "HistoryVisibilityEventContent.h"
+#include "JoinRulesEventContent.h"
+#include "NameEventContent.h"
+#include "PowerLevelsEventContent.h"
+#include "TopicEventContent.h"
+
+#include "StateEvent.h"
+
+namespace events = matrix::events;
+
ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
: QWidget(parent)
, ui(new Ui::ChatPage)
@@ -55,16 +69,9 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
connect(user_info_widget_, SIGNAL(logout()), client_.data(), SLOT(logout()));
connect(client_.data(), SIGNAL(loggedOut()), this, SLOT(logout()));
- connect(room_list_,
- SIGNAL(roomChanged(const RoomInfo &)),
- this,
- SLOT(changeTopRoomInfo(const RoomInfo &)));
- connect(room_list_,
- SIGNAL(roomChanged(const RoomInfo &)),
- view_manager_,
- SLOT(setHistoryView(const RoomInfo &)));
+ connect(room_list_, &RoomList::roomChanged, this, &ChatPage::changeTopRoomInfo);
+ connect(room_list_, &RoomList::roomChanged, view_manager_, &TimelineViewManager::setHistoryView);
- // TODO: Better pass the whole RoomInfo struct instead of the roomid.
connect(view_manager_,
SIGNAL(unreadMessages(const QString &, int)),
room_list_,
@@ -161,7 +168,24 @@ void ChatPage::syncCompleted(const SyncResponse &response)
{
client_->setNextBatchToken(response.nextBatch());
- /* room_list_->sync(response.rooms()); */
+ auto joined = response.rooms().join();
+
+ for (auto it = joined.constBegin(); it != joined.constEnd(); it++) {
+ RoomState room_state;
+
+ if (state_manager_.contains(it.key()))
+ room_state = state_manager_[it.key()];
+
+ updateRoomState(room_state, it.value().state().events());
+ updateRoomState(room_state, it.value().timeline().events());
+
+ state_manager_.insert(it.key(), room_state);
+
+ if (it.key() == current_room_)
+ changeTopRoomInfo(it.key());
+ }
+
+ room_list_->sync(state_manager_);
view_manager_->sync(response.rooms());
sync_timer_->start(sync_interval_);
@@ -172,8 +196,19 @@ void ChatPage::initialSyncCompleted(const SyncResponse &response)
if (!response.nextBatch().isEmpty())
client_->setNextBatchToken(response.nextBatch());
+ auto joined = response.rooms().join();
+
+ for (auto it = joined.constBegin(); it != joined.constEnd(); it++) {
+ RoomState room_state;
+
+ updateRoomState(room_state, it.value().state().events());
+ updateRoomState(room_state, it.value().timeline().events());
+
+ state_manager_.insert(it.key(), room_state);
+ }
+
view_manager_->initialize(response.rooms());
- room_list_->setInitialRooms(response.rooms());
+ room_list_->setInitialRooms(state_manager_);
sync_timer_->start(sync_interval_);
}
@@ -182,7 +217,7 @@ void ChatPage::updateTopBarAvatar(const QString &roomid, const QPixmap &img)
{
room_avatars_.insert(roomid, img);
- if (current_room_.id() != roomid)
+ if (current_room_ != roomid)
return;
top_bar_->updateRoomAvatar(img.toImage());
@@ -199,17 +234,22 @@ void ChatPage::updateOwnProfileInfo(const QUrl &avatar_url, const QString &displ
client_->fetchOwnAvatar(avatar_url);
}
-void ChatPage::changeTopRoomInfo(const RoomInfo &info)
+void ChatPage::changeTopRoomInfo(const QString &room_id)
{
- top_bar_->updateRoomName(info.name());
- top_bar_->updateRoomTopic(info.topic());
+ if (!state_manager_.contains(room_id))
+ return;
- if (room_avatars_.contains(info.id()))
- top_bar_->updateRoomAvatar(room_avatars_.value(info.id()).toImage());
+ auto state = state_manager_[room_id];
+
+ top_bar_->updateRoomName(state.resolveName());
+ top_bar_->updateRoomTopic(state.resolveTopic());
+
+ if (room_avatars_.contains(room_id))
+ top_bar_->updateRoomAvatar(room_avatars_.value(room_id).toImage());
else
- top_bar_->updateRoomAvatarFromName(info.name());
+ top_bar_->updateRoomAvatarFromName(state.resolveName());
- current_room_ = info;
+ current_room_ = room_id;
}
void ChatPage::showUnreadMessageNotification(int count)
@@ -221,6 +261,88 @@ void ChatPage::showUnreadMessageNotification(int count)
emit changeWindowTitle(QString("nheko (%1)").arg(count));
}
+void ChatPage::updateRoomState(RoomState &room_state, const QJsonArray &events)
+{
+ events::EventType ty;
+
+ for (const auto &event : events) {
+ try {
+ ty = events::extractEventType(event.toObject());
+ } catch (const DeserializationException &e) {
+ qWarning() << e.what() << event;
+ continue;
+ }
+
+ if (!events::isStateEvent(ty))
+ continue;
+
+ try {
+ switch (ty) {
+ case events::EventType::RoomAliases: {
+ events::StateEvent<events::AliasesEventContent> aliases;
+ aliases.deserialize(event);
+ room_state.aliases = aliases;
+ break;
+ }
+ case events::EventType::RoomAvatar: {
+ events::StateEvent<events::AvatarEventContent> avatar;
+ avatar.deserialize(event);
+ room_state.avatar = avatar;
+ break;
+ }
+ case events::EventType::RoomCanonicalAlias: {
+ events::StateEvent<events::CanonicalAliasEventContent> canonical_alias;
+ canonical_alias.deserialize(event);
+ room_state.canonical_alias = canonical_alias;
+ break;
+ }
+ case events::EventType::RoomCreate: {
+ events::StateEvent<events::CreateEventContent> create;
+ create.deserialize(event);
+ room_state.create = create;
+ break;
+ }
+ case events::EventType::RoomHistoryVisibility: {
+ events::StateEvent<events::HistoryVisibilityEventContent> history_visibility;
+ history_visibility.deserialize(event);
+ room_state.history_visibility = history_visibility;
+ break;
+ }
+ case events::EventType::RoomJoinRules: {
+ events::StateEvent<events::JoinRulesEventContent> join_rules;
+ join_rules.deserialize(event);
+ room_state.join_rules = join_rules;
+ break;
+ }
+ case events::EventType::RoomName: {
+ events::StateEvent<events::NameEventContent> name;
+ name.deserialize(event);
+ room_state.name = name;
+ break;
+ }
+ case events::EventType::RoomPowerLevels: {
+ events::StateEvent<events::PowerLevelsEventContent> power_levels;
+ power_levels.deserialize(event);
+ room_state.power_levels = power_levels;
+ break;
+ }
+ case events::EventType::RoomTopic: {
+ events::StateEvent<events::TopicEventContent> topic;
+ topic.deserialize(event);
+ room_state.topic = topic;
+ break;
+ }
+ default: {
+ continue;
+ }
+ }
+ } catch (const DeserializationException &e) {
+ qWarning() << e.what() << event;
+ continue;
+ }
+ }
+}
+
ChatPage::~ChatPage()
{
sync_timer_->stop();
|