diff options
author | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-05-07 17:15:38 +0300 |
---|---|---|
committer | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-05-07 17:15:38 +0300 |
commit | 1f90c58076b9c40a609c88b9cdad51dd55da6954 (patch) | |
tree | 5a45ae1b5b1ca62cf8665aa892de904481dac215 /src/ChatPage.cc | |
parent | Add matrix::events namespace (diff) | |
download | nheko-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.cc | 160 |
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(); |