summary refs log tree commit diff
path: root/src/ChatPage.cc
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-05-07 17:15:38 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-05-07 17:15:38 +0300
commit1f90c58076b9c40a609c88b9cdad51dd55da6954 (patch)
tree5a45ae1b5b1ca62cf8665aa892de904481dac215 /src/ChatPage.cc
parentAdd matrix::events namespace (diff)
downloadnheko-1f90c58076b9c40a609c88b9cdad51dd55da6954.tar.xz
Use timeline to retrieve state events
- Rooms without any history will be shown.
- Room's state will be kept in sync and any updates will be visible.
Diffstat (limited to 'src/ChatPage.cc')
-rw-r--r--src/ChatPage.cc160
1 files changed, 141 insertions, 19 deletions
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();