From 73dbd3c8dd78b41c8d93392eac74231e5b4a20d5 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Sat, 14 Jul 2018 12:08:16 +0300 Subject: [PATCH] Re-enable groups --- CMakeLists.txt | 1 - cmake/FindOlm.cmake | 4 ++ deps/CMakeLists.txt | 4 +- include/ChatPage.h | 6 +-- include/CommunitiesList.h | 12 ++--- include/CommunitiesListItem.h | 26 ++++++----- include/Community.h | 25 ----------- include/MatrixClient.h | 4 ++ src/Cache.cc | 6 ++- src/ChatPage.cc | 60 ++++++++----------------- src/CommunitiesList.cc | 82 ++++++++++++++++++++++++++--------- src/CommunitiesListItem.cc | 35 ++++++++++----- src/Community.cc | 33 -------------- src/MatrixClient.cc | 3 ++ 14 files changed, 142 insertions(+), 159 deletions(-) delete mode 100644 include/Community.h delete mode 100644 src/Community.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d739d0..e3b8defa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,7 +197,6 @@ set(SRC_FILES src/ChatPage.cc src/CommunitiesListItem.cc src/CommunitiesList.cc - src/Community.cc src/InviteeItem.cc src/LoginPage.cc src/Logging.cpp diff --git a/cmake/FindOlm.cmake b/cmake/FindOlm.cmake index aaccdb0c..da68dbf5 100644 --- a/cmake/FindOlm.cmake +++ b/cmake/FindOlm.cmake @@ -6,6 +6,10 @@ # OLM_LIBRARY = full path to the library # OLM_INCLUDE_DIR = where to find the library headers # +if(WIN32) + message(STATUS "FindOlm is not supported in Windows") + return() +endif() find_path(OLM_INCLUDE_DIR NAMES olm/olm.h diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 13426538..8d6df7a4 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -39,10 +39,10 @@ set(BOOST_SHA256 5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9) set(MATRIX_STRUCTS_URL https://github.com/mujx/matrix-structs) -set(MATRIX_STRUCTS_TAG 92a5e99db51301b5abf626aa872a1a87b7727634) +set(MATRIX_STRUCTS_TAG 8de04afea34e95c14d1dde82af390592dfde90dd) set(MTXCLIENT_URL https://github.com/mujx/mtxclient) -set(MTXCLIENT_TAG 708c8c6772b9bd99d77c5be6bb3ba58643258628) +set(MTXCLIENT_TAG 2f519d28b4521f7f234b2ed0f32360cbb1edd2f7) set(TWEENY_URL https://github.com/mobius3/tweeny) set(TWEENY_TAG b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf) diff --git a/include/ChatPage.h b/include/ChatPage.h index 39fb7565..6a70acf4 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -28,7 +28,6 @@ #include "Cache.h" #include "CommunitiesList.h" -#include "Community.h" #include "MatrixClient.h" #include "notifications/Manager.h" @@ -149,10 +148,11 @@ signals: const QString &message, const QImage &icon); + void updateGroupsInfo(const mtx::responses::JoinedGroups &groups); + private slots: void showUnreadMessageNotification(int count); void updateTopBarAvatar(const QString &roomid, const QPixmap &img); - void updateOwnCommunitiesInfo(const QList &own_communities); void changeTopRoomInfo(const QString &room_id); void logout(); void removeRoom(const QString &room_id); @@ -233,8 +233,6 @@ private: UserInfoWidget *user_info_widget_; - std::map> communities_; - // Keeps track of the users currently typing on each room. std::map> typingUsers_; QTimer *typingRefresher_; diff --git a/include/CommunitiesList.h b/include/CommunitiesList.h index 78b9602e..32a64bf2 100644 --- a/include/CommunitiesList.h +++ b/include/CommunitiesList.h @@ -5,7 +5,6 @@ #include #include "CommunitiesListItem.h" -#include "Community.h" #include "ui/Theme.h" class CommunitiesList : public QWidget @@ -15,26 +14,29 @@ class CommunitiesList : public QWidget public: CommunitiesList(QWidget *parent = nullptr); - void setCommunities(const std::map> &communities); void clear() { communities_.clear(); } - void addCommunity(QSharedPointer community, const QString &id); + void addCommunity(const std::string &id); void removeCommunity(const QString &id) { communities_.erase(id); }; + std::vector roomList(const QString &id) const; signals: void communityChanged(const QString &id); void avatarRetrieved(const QString &id, const QPixmap &img); + void groupProfileRetrieved(const QString &group_id, const mtx::responses::GroupProfile &); + void groupRoomsRetrieved(const QString &group_id, const std::vector &res); public slots: void updateCommunityAvatar(const QString &id, const QPixmap &img); void highlightSelectedCommunity(const QString &id); + void setCommunities(const mtx::responses::JoinedGroups &groups); private: void fetchCommunityAvatar(const QString &id, const QString &avatarUrl); - void addGlobalItem() { addCommunity(QSharedPointer(new Community), "world"); } + void addGlobalItem() { addCommunity("world"); } //! Check whether or not a community id is currently managed. - bool communityExists(const QString &id) + bool communityExists(const QString &id) const { return communities_.find(id) != communities_.end(); } diff --git a/include/CommunitiesListItem.h b/include/CommunitiesListItem.h index 6055d732..a9b6e333 100644 --- a/include/CommunitiesListItem.h +++ b/include/CommunitiesListItem.h @@ -6,7 +6,8 @@ #include #include -#include "Community.h" +#include + #include "Config.h" #include "ui/Theme.h" @@ -25,15 +26,15 @@ class CommunitiesListItem : public QWidget Q_PROPERTY(QColor avatarBgColor READ avatarBgColor WRITE setAvatarBgColor) public: - CommunitiesListItem(QSharedPointer community, - QString community_id, - QWidget *parent = nullptr); - - void setCommunity(QSharedPointer community) { community_ = community; }; + CommunitiesListItem(QString group_id, QWidget *parent = nullptr); + void setName(QString name) { name_ = name; } bool isPressed() const { return isPressed_; } void setAvatar(const QImage &img); + void setRooms(std::vector room_ids) { room_ids_ = std::move(room_ids); } + std::vector rooms() const { return room_ids_; } + QColor highlightedBackgroundColor() const { return highlightedBackgroundColor_; } QColor hoverBackgroundColor() const { return hoverBackgroundColor_; } QColor backgroundColor() const { return backgroundColor_; } @@ -54,7 +55,7 @@ public: } signals: - void clicked(const QString &community_id); + void clicked(const QString &group_id); public slots: void setPressedState(bool state); @@ -66,12 +67,13 @@ protected: private: const int IconSize = 36; - QSharedPointer community_; - QString communityId_; - QString communityName_; - QString communityShortDescription; + QString resolveName() const; - QPixmap communityAvatar_; + std::vector room_ids_; + + QString name_; + QString groupId_; + QPixmap avatar_; QColor highlightedBackgroundColor_; QColor hoverBackgroundColor_; diff --git a/include/Community.h b/include/Community.h deleted file mode 100644 index 6a398099..00000000 --- a/include/Community.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -struct Community -{ - void parseProfile(const QJsonObject &profile); - void parseRooms(const QJsonObject &rooms); - - QUrl getAvatar() const { return avatar_; } - QString getName() const { return name_; } - QString getShortDescription() const { return short_description_; } - QString getLongDescription() const { return long_description_; } - std::vector getRoomList() const { return rooms_; } - - QUrl avatar_; - QString name_; - QString short_description_; - QString long_description_; - - std::vector rooms_; -}; diff --git a/include/MatrixClient.h b/include/MatrixClient.h index 7ea5e0b7..cf1ee8ed 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -10,8 +11,11 @@ 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::JoinedGroups) +Q_DECLARE_METATYPE(mtx::responses::GroupProfile) Q_DECLARE_METATYPE(std::string) Q_DECLARE_METATYPE(std::vector) +Q_DECLARE_METATYPE(std::vector) namespace http { namespace v2 { diff --git a/src/Cache.cc b/src/Cache.cc index c1f25f63..614e8a90 100644 --- a/src/Cache.cc +++ b/src/Cache.cc @@ -987,7 +987,8 @@ Cache::getTimelineMessages(lmdb::txn &txn, const std::string &room_id) if (obj.count("event") == 0 || obj.count("token") == 0) continue; - mtx::events::collections::TimelineEvent event = obj.at("event"); + mtx::events::collections::TimelineEvent event; + mtx::events::collections::from_json(obj.at("event"), event); index += 1; @@ -1058,7 +1059,8 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) if (obj.count("event") == 0) continue; - mtx::events::collections::TimelineEvent event = obj.at("event"); + mtx::events::collections::TimelineEvent event; + mtx::events::collections::from_json(obj.at("event"), event); cursor.close(); return utils::getMessageDescription( diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 336ea7c3..7f6306f6 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -501,31 +501,8 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar); - // connect(http::client(), - // SIGNAL(getOwnCommunitiesResponse(QList)), - // this, - // SLOT(updateOwnCommunitiesInfo(QList))); - // connect(http::client(), - // &MatrixClient::communityProfileRetrieved, - // this, - // [this](QString communityId, QJsonObject profile) { - // communities_[communityId]->parseProfile(profile); - // }); - // connect(http::client(), - // &MatrixClient::communityRoomsRetrieved, - // this, - // [this](QString communityId, QJsonObject rooms) { - // communities_[communityId]->parseRooms(rooms); - - // if (communityId == current_community_) { - // if (communityId == "world") { - // room_list_->setFilterRooms(false); - // } else { - // room_list_->setRoomFilter( - // communities_[communityId]->getRoomList()); - // } - // } - // }); + connect( + this, &ChatPage::updateGroupsInfo, communitiesList_, &CommunitiesList::setCommunities); connect(this, &ChatPage::leftRoom, this, &ChatPage::removeRoom); connect(this, &ChatPage::notificationsRetrieved, this, &ChatPage::sendDesktopNotifications); @@ -533,13 +510,13 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) connect(communitiesList_, &CommunitiesList::communityChanged, this, - [this](const QString &communityId) { - current_community_ = communityId; + [this](const QString &groupId) { + current_community_ = groupId; - if (communityId == "world") + if (groupId == "world") room_list_->setFilterRooms(false); else - room_list_->setRoomFilter(communities_[communityId]->getRoomList()); + room_list_->setRoomFilter(communitiesList_->roomList(groupId)); }); connect(¬ificationsManager, @@ -758,18 +735,6 @@ ChatPage::updateTopBarAvatar(const QString &roomid, const QPixmap &img) top_bar_->updateRoomAvatar(img.toImage()); } -void -ChatPage::updateOwnCommunitiesInfo(const QList &own_communities) -{ - for (int i = 0; i < own_communities.size(); i++) { - QSharedPointer community = QSharedPointer(new Community()); - - communities_[own_communities[i]] = community; - } - - communitiesList_->setCommunities(communities_); -} - void ChatPage::changeTopRoomInfo(const QString &room_id) { @@ -1335,7 +1300,18 @@ ChatPage::getProfileInfo() QImage::fromData(QByteArray(data.data(), data.size()))); }); }); - // TODO http::client()->getOwnCommunities(); + + http::v2::client()->joined_groups( + [this](const mtx::responses::JoinedGroups &res, mtx::http::RequestErr err) { + if (err) { + nhlog::net()->critical("failed to retrieve joined groups: {} {}", + static_cast(err->status_code), + err->matrix_error.error); + return; + } + + emit updateGroupsInfo(res); + }); } void diff --git a/src/CommunitiesList.cc b/src/CommunitiesList.cc index 39e9a7fe..b2742f59 100644 --- a/src/CommunitiesList.cc +++ b/src/CommunitiesList.cc @@ -40,50 +40,81 @@ CommunitiesList::CommunitiesList(QWidget *parent) scrollArea_->setWidget(scrollAreaContents_); topLayout_->addWidget(scrollArea_); - // connect(http::client(), - // &MatrixClient::communityProfileRetrieved, - // this, - // [this](QString communityId, QJsonObject profile) { - // fetchCommunityAvatar(communityId, profile["avatar_url"].toString()); - // }); connect( this, &CommunitiesList::avatarRetrieved, this, &CommunitiesList::updateCommunityAvatar); } void -CommunitiesList::setCommunities(const std::map> &communities) +CommunitiesList::setCommunities(const mtx::responses::JoinedGroups &response) { communities_.clear(); addGlobalItem(); - for (const auto &community : communities) { - addCommunity(community.second, community.first); - - // http::client()->fetchCommunityProfile(community.first); - // http::client()->fetchCommunityRooms(community.first); - } + for (const auto &group : response.groups) + addCommunity(group); communities_["world"]->setPressedState(true); emit communityChanged("world"); } void -CommunitiesList::addCommunity(QSharedPointer community, const QString &community_id) +CommunitiesList::addCommunity(const std::string &group_id) { - CommunitiesListItem *list_item = - new CommunitiesListItem(community, community_id, scrollArea_); - - communities_.emplace(community_id, QSharedPointer(list_item)); - - fetchCommunityAvatar(community_id, community->getAvatar().toString()); + const auto id = QString::fromStdString(group_id); + CommunitiesListItem *list_item = new CommunitiesListItem(id, scrollArea_); + communities_.emplace(id, QSharedPointer(list_item)); contentsLayout_->insertWidget(contentsLayout_->count() - 1, list_item); + connect(this, + &CommunitiesList::groupProfileRetrieved, + this, + [this](const QString &id, const mtx::responses::GroupProfile &profile) { + if (communities_.find(id) == communities_.end()) + return; + + communities_.at(id)->setName(QString::fromStdString(profile.name)); + + if (!profile.avatar_url.empty()) + fetchCommunityAvatar(id, + QString::fromStdString(profile.avatar_url)); + }); + connect(this, + &CommunitiesList::groupRoomsRetrieved, + this, + [this](const QString &id, const std::vector &rooms) { + if (communities_.find(id) == communities_.end()) + return; + + communities_.at(id)->setRooms(rooms); + }); connect(list_item, &CommunitiesListItem::clicked, this, &CommunitiesList::highlightSelectedCommunity); + + http::v2::client()->group_profile( + group_id, [id, this](const mtx::responses::GroupProfile &res, mtx::http::RequestErr err) { + if (err) { + return; + } + + emit groupProfileRetrieved(id, res); + }); + + http::v2::client()->group_rooms( + group_id, [id, this](const nlohmann::json &res, mtx::http::RequestErr err) { + if (err) { + return; + } + + std::vector room_ids; + for (const auto &room : res.at("chunk")) + room_ids.push_back(QString::fromStdString(room.at("room_id"))); + + emit groupRoomsRetrieved(id, room_ids); + }); } void @@ -94,7 +125,7 @@ CommunitiesList::updateCommunityAvatar(const QString &community_id, const QPixma return; } - communities_.find(community_id)->second->setAvatar(img.toImage()); + communities_.at(community_id)->setAvatar(img.toImage()); } void @@ -153,3 +184,12 @@ CommunitiesList::fetchCommunityAvatar(const QString &id, const QString &avatarUr emit avatarRetrieved(id, pix); }); } + +std::vector +CommunitiesList::roomList(const QString &id) const +{ + if (communityExists(id)) + return communities_.at(id)->rooms(); + + return {}; +} diff --git a/src/CommunitiesListItem.cc b/src/CommunitiesListItem.cc index e5127050..df6c5393 100644 --- a/src/CommunitiesListItem.cc +++ b/src/CommunitiesListItem.cc @@ -4,12 +4,9 @@ #include "RippleOverlay.h" #include "Utils.h" -CommunitiesListItem::CommunitiesListItem(QSharedPointer community, - QString community_id, - QWidget *parent) +CommunitiesListItem::CommunitiesListItem(QString group_id, QWidget *parent) : QWidget(parent) - , community_(community) - , communityId_(community_id) + , groupId_(group_id) { setMouseTracking(true); setAttribute(Qt::WA_Hover); @@ -20,8 +17,8 @@ CommunitiesListItem::CommunitiesListItem(QSharedPointer community, rippleOverlay_->setClipPath(path); rippleOverlay_->setClipping(true); - if (communityId_ == "world") - communityAvatar_ = QPixmap(":/icons/icons/ui/world.svg"); + if (groupId_ == "world") + avatar_ = QPixmap(":/icons/icons/ui/world.svg"); } void @@ -41,7 +38,7 @@ CommunitiesListItem::mousePressEvent(QMouseEvent *event) return; } - emit clicked(communityId_); + emit clicked(groupId_); setPressedState(true); @@ -70,12 +67,12 @@ CommunitiesListItem::paintEvent(QPaintEvent *) else p.fillRect(rect(), backgroundColor_); - if (communityAvatar_.isNull()) { + if (avatar_.isNull()) { QFont font; font.setPixelSize(conf::roomlist::fonts::communityBubble); p.setFont(font); - p.drawLetterAvatar(utils::firstChar(community_->getName()), + p.drawLetterAvatar(utils::firstChar(resolveName()), avatarFgColor_, avatarBgColor_, width(), @@ -84,7 +81,7 @@ CommunitiesListItem::paintEvent(QPaintEvent *) } else { p.save(); - p.drawAvatar(communityAvatar_, width(), height(), IconSize); + p.drawAvatar(avatar_, width(), height(), IconSize); p.restore(); } } @@ -92,6 +89,20 @@ CommunitiesListItem::paintEvent(QPaintEvent *) void CommunitiesListItem::setAvatar(const QImage &img) { - communityAvatar_ = utils::scaleImageToPixmap(img, IconSize); + avatar_ = utils::scaleImageToPixmap(img, IconSize); update(); } + +QString +CommunitiesListItem::resolveName() const +{ + if (!name_.isEmpty()) + return name_; + + if (!groupId_.startsWith("+")) + return QString("Group"); // Group with no name or id. + + // Extract the localpart of the group. + auto firstPart = groupId_.split(':').at(0); + return firstPart.right(firstPart.size() - 1); +} diff --git a/src/Community.cc b/src/Community.cc deleted file mode 100644 index d563c151..00000000 --- a/src/Community.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "include/Community.h" - -#include -#include - -void -Community::parseProfile(const QJsonObject &profile) -{ - if (profile["name"].type() == QJsonValue::Type::String) - name_ = profile["name"].toString(); - else - name_ = "Unnamed Community"; // TODO: what is correct here? - - if (profile["avatar_url"].type() == QJsonValue::Type::String) - avatar_ = QUrl(profile["avatar_url"].toString()); - - if (profile["short_description"].type() == QJsonValue::Type::String) - short_description_ = profile["short_description"].toString(); - - if (profile["long_description"].type() == QJsonValue::Type::String) - long_description_ = profile["long_description"].toString(); -} - -void -Community::parseRooms(const QJsonObject &rooms) -{ - rooms_.clear(); - - for (auto const &room : rooms["chunk"].toArray()) { - if (room.toObject().contains("room_id")) - rooms_.emplace_back(room.toObject()["room_id"].toString()); - } -} diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index d4ab8e33..9e69dbbd 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -31,8 +31,11 @@ init() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); + qRegisterMetaType>(); } } // namespace http