From 12ce7686ce8a7cae411c280d30a12934b8707550 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 16 Jun 2021 00:09:45 +0200 Subject: Show some spaces in the community sidebar --- src/timeline/CommunitiesModel.cpp | 42 ++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 6c236784..88464bf9 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -44,8 +44,23 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::Id: return ""; } - } else if (index.row() - 1 < tags_.size()) { - auto tag = tags_.at(index.row() - 1); + } else if (index.row() - 1 < spaceOrder_.size()) { + auto id = spaceOrder_.at(index.row() - 1); + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString::fromStdString(spaces_.at(id).avatar_url); + case CommunitiesModel::Roles::DisplayName: + case CommunitiesModel::Roles::Tooltip: + return QString::fromStdString(spaces_.at(id).name); + case CommunitiesModel::Roles::ChildrenHidden: + return true; + case CommunitiesModel::Roles::Hidden: + return hiddentTagIds_.contains("space:" + id); + case CommunitiesModel::Roles::Id: + return "space:" + id; + } + } else if (index.row() - 1 < tags_.size() + spaceOrder_.size()) { + auto tag = tags_.at(index.row() - 1 - spaceOrder_.size()); if (tag == "m.favourite") { switch (role) { case CommunitiesModel::Roles::AvatarUrl: @@ -78,7 +93,6 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::AvatarUrl: return QString(":/icons/icons/ui/tag.png"); case CommunitiesModel::Roles::DisplayName: - return tag.mid(2); case CommunitiesModel::Roles::Tooltip: return tag.mid(2); } @@ -99,17 +113,27 @@ CommunitiesModel::data(const QModelIndex &index, int role) const void CommunitiesModel::initializeSidebar() { + beginResetModel(); + tags_.clear(); + spaceOrder_.clear(); + spaces_.clear(); + std::set ts; - for (const auto &e : cache::roomInfo()) { - for (const auto &t : e.tags) { - if (t.find("u.") == 0 || t.find("m." == 0)) { - ts.insert(t); + std::vector tempSpaces; + auto infos = cache::roomInfo(); + for (auto it = infos.begin(); it != infos.end(); it++) { + if (it.value().is_space) { + spaceOrder_.push_back(it.key()); + spaces_[it.key()] = it.value(); + } else { + for (const auto &t : it.value().tags) { + if (t.find("u.") == 0 || t.find("m." == 0)) { + ts.insert(t); + } } } } - beginResetModel(); - tags_.clear(); for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); -- cgit 1.5.1 From 6bfa6c4c793f1cd74df64d593ff2060ff94f176f Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 16 Jun 2021 22:59:41 +0200 Subject: Allow filtering by space --- src/Cache.cpp | 36 +++++++++++++++++++++++++----------- src/Cache_p.h | 12 +++++++++--- src/timeline/CommunitiesModel.cpp | 9 +++++++++ src/timeline/RoomlistModel.cpp | 24 ++++++++++++++++++++++++ src/timeline/RoomlistModel.h | 3 +++ 5 files changed, 70 insertions(+), 14 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 0bd6fe0d..8b1798d6 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -905,7 +905,9 @@ Cache::runMigrations() std::reverse(oldMessages.events.begin(), oldMessages.events.end()); // save messages using the new method - saveTimelineMessages(txn, room_id, oldMessages); + auto eventsDb = getEventsDb(txn, room_id); + saveTimelineMessages( + txn, eventsDb, room_id, oldMessages); } // delete old messages db @@ -1208,13 +1210,24 @@ Cache::saveState(const mtx::responses::Sync &res) auto statesdb = getStatesDb(txn, room.first); auto stateskeydb = getStatesKeyDb(txn, room.first); auto membersdb = getMembersDb(txn, room.first); - - saveStateEvents( - txn, statesdb, stateskeydb, membersdb, room.first, room.second.state.events); - saveStateEvents( - txn, statesdb, stateskeydb, membersdb, room.first, room.second.timeline.events); - - saveTimelineMessages(txn, room.first, room.second.timeline); + auto eventsDb = getEventsDb(txn, room.first); + + saveStateEvents(txn, + statesdb, + stateskeydb, + membersdb, + eventsDb, + room.first, + room.second.state.events); + saveStateEvents(txn, + statesdb, + stateskeydb, + membersdb, + eventsDb, + room.first, + room.second.timeline.events); + + saveTimelineMessages(txn, eventsDb, room.first, room.second.timeline); RoomInfo updatedInfo; updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString(); @@ -2634,11 +2647,12 @@ void Cache::savePendingMessage(const std::string &room_id, const mtx::events::collections::TimelineEvent &message) { - auto txn = lmdb::txn::begin(env_); + auto txn = lmdb::txn::begin(env_); + auto eventsDb = getEventsDb(txn, room_id); mtx::responses::Timeline timeline; timeline.events.push_back(message.data); - saveTimelineMessages(txn, room_id, timeline); + saveTimelineMessages(txn, eventsDb, room_id, timeline); auto pending = getPendingMessagesDb(txn, room_id); @@ -2706,13 +2720,13 @@ Cache::removePendingStatus(const std::string &room_id, const std::string &txn_id void Cache::saveTimelineMessages(lmdb::txn &txn, + lmdb::dbi &eventsDb, const std::string &room_id, const mtx::responses::Timeline &res) { if (res.events.empty()) return; - auto eventsDb = getEventsDb(txn, room_id); auto relationsDb = getRelationsDb(txn, room_id); auto orderDb = getEventOrderDb(txn, room_id); diff --git a/src/Cache_p.h b/src/Cache_p.h index 064f4882..e35e78ec 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -335,6 +335,7 @@ private: std::string getLastEventId(lmdb::txn &txn, const std::string &room_id); DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id); void saveTimelineMessages(lmdb::txn &txn, + lmdb::dbi &eventsDb, const std::string &room_id, const mtx::responses::Timeline &res); @@ -353,11 +354,12 @@ private: lmdb::dbi &statesdb, lmdb::dbi &stateskeydb, lmdb::dbi &membersdb, + lmdb::dbi &eventsDb, const std::string &room_id, const std::vector &events) { for (const auto &e : events) - saveStateEvent(txn, statesdb, stateskeydb, membersdb, room_id, e); + saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e); } template @@ -365,6 +367,7 @@ private: lmdb::dbi &statesdb, lmdb::dbi &stateskeydb, lmdb::dbi &membersdb, + lmdb::dbi &eventsDb, const std::string &room_id, const T &event) { @@ -401,8 +404,10 @@ private: } std::visit( - [&txn, &statesdb, &stateskeydb](auto e) { - if constexpr (isStateEvent(e)) + [&txn, &statesdb, &stateskeydb, &eventsDb](auto e) { + if constexpr (isStateEvent(e)) { + eventsDb.put(txn, e.event_id, json(e).dump()); + if (e.type != EventType::Unsupported) { if (e.state_key.empty()) statesdb.put( @@ -417,6 +422,7 @@ private: }) .dump()); } + } }, event); } diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 88464bf9..6ff953d2 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -185,6 +185,15 @@ CommunitiesModel::setCurrentTagId(QString tagId) return; } } + } else if (tagId.startsWith("space:")) { + auto tag = tagId.mid(6); + for (const auto &t : spaceOrder_) { + if (t == tag) { + this->currentTagId_ = tagId; + emit currentTagIdChanged(currentTagId_); + return; + } + } } this->currentTagId_ = ""; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 0f980c6c..3b6ad54a 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -530,6 +530,30 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons return false; } return true; + } else if (filterType == FilterBy::Space) { + auto roomid = sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) + .toString(); + auto tags = sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + auto contains = [](const std::vector &v, const std::string &str) { + for (const auto &e : v) + if (e == str) + return true; + return false; + }; + auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); + + if (!contains(parents, filterStr.toStdString())) + return false; + else if (!hiddenTags.empty()) { + for (const auto &t : tags) + if (hiddenTags.contains(t)) + return false; + } + return true; } else { return true; } diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index b0244886..5f8b8bd8 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -134,6 +134,9 @@ public slots: if (tagId.startsWith("tag:")) { filterType = FilterBy::Tag; filterStr = tagId.mid(4); + } else if (tagId.startsWith("space:")) { + filterType = FilterBy::Space; + filterStr = tagId.mid(6); } else { filterType = FilterBy::Nothing; filterStr.clear(); -- cgit 1.5.1 From 0ec7be3090814c7a61273cfe88e5dff9fbaccd91 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 18 Jun 2021 12:10:13 +0200 Subject: Fix hiding rooms from a space --- src/timeline/CommunitiesModel.cpp | 8 +++++- src/timeline/RoomlistModel.cpp | 54 ++++++++++++++++++++++++++++++--------- src/timeline/RoomlistModel.h | 1 + 3 files changed, 50 insertions(+), 13 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index 6ff953d2..c66d5949 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -214,7 +214,13 @@ CommunitiesModel::toggleTagId(QString tagId) if (tagId.startsWith("tag:")) { auto idx = tags_.indexOf(tagId.mid(4)); if (idx != -1) - emit dataChanged(index(idx), index(idx), {Hidden}); + emit dataChanged(index(idx + 1 + spaceOrder_.size()), + index(idx + 1 + spaceOrder_.size()), + {Hidden}); + } else if (tagId.startsWith("space:")) { + auto idx = spaceOrder_.indexOf(tagId.mid(6)); + if (idx != -1) + emit dataChanged(index(idx + 1), index(idx + 1), {Hidden}); } emit hiddenTagsChanged(); diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 3b6ad54a..0d9ec66b 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -51,6 +51,7 @@ RoomlistModel::roleNames() const {IsInvite, "isInvite"}, {IsSpace, "isSpace"}, {Tags, "tags"}, + {ParentSpaces, "parentSpaces"}, }; } @@ -93,6 +94,14 @@ RoomlistModel::data(const QModelIndex &index, int role) const list.push_back(QString::fromStdString(t)); return list; } + case Roles::ParentSpaces: { + auto parents = + cache::client()->getParentRoomIds(roomid.toStdString()); + QStringList list; + for (const auto &t : parents) + list.push_back(QString::fromStdString(t)); + return list; + } default: return {}; } @@ -122,6 +131,14 @@ RoomlistModel::data(const QModelIndex &index, int role) const return false; case Roles::Tags: return QStringList(); + case Roles::ParentSpaces: { + auto parents = + cache::client()->getParentRoomIds(roomid.toStdString()); + QStringList list; + for (const auto &t : parents) + list.push_back(QString::fromStdString(t)); + return list; + } default: return {}; } @@ -514,6 +531,14 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : tags) if (hiddenTags.contains(t)) return false; + } else if (!hiddenSpaces.empty()) { + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; } return true; @@ -528,30 +553,35 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : tags) if (t != filterStr && hiddenTags.contains(t)) return false; + } else if (!hiddenSpaces.empty()) { + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; } return true; } else if (filterType == FilterBy::Space) { - auto roomid = sourceModel() - ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) - .toString(); + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); auto tags = sourceModel() ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) .toStringList(); - auto contains = [](const std::vector &v, const std::string &str) { - for (const auto &e : v) - if (e == str) - return true; - return false; - }; - auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); - - if (!contains(parents, filterStr.toStdString())) + if (!parents.contains(filterStr)) return false; else if (!hiddenTags.empty()) { for (const auto &t : tags) if (hiddenTags.contains(t)) return false; + } else if (!hiddenSpaces.empty()) { + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; } return true; } else { diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index 5f8b8bd8..d6cbb462 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -38,6 +38,7 @@ public: IsInvite, IsSpace, Tags, + ParentSpaces, }; RoomlistModel(TimelineViewManager *parent = nullptr); -- cgit 1.5.1 From f349b0cce0335c2c9f6aaabfad9315e80bc72677 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 18 Jun 2021 14:05:52 +0200 Subject: Hide spaces by default, unless they are in the current space filter --- src/timeline/CommunitiesModel.cpp | 19 +++++++++++++++++++ src/timeline/RoomlistModel.cpp | 34 ++++++++++++++++++++++++++++++---- src/timeline/TimelineModel.cpp | 4 ++++ src/timeline/TimelineModel.h | 9 ++++++--- 4 files changed, 59 insertions(+), 7 deletions(-) (limited to 'src/timeline/CommunitiesModel.cpp') diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index c66d5949..97bfa76d 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -167,6 +167,25 @@ CommunitiesModel::sync(const mtx::responses::Rooms &rooms) mtx::events::AccountDataEvent>(e)) { tagsUpdated = true; } + for (const auto &e : room.state.events) + if (std::holds_alternative< + mtx::events::StateEvent>(e) || + std::holds_alternative< + mtx::events::StateEvent>(e)) { + tagsUpdated = true; + } + for (const auto &e : room.timeline.events) + if (std::holds_alternative< + mtx::events::StateEvent>(e) || + std::holds_alternative< + mtx::events::StateEvent>(e)) { + tagsUpdated = true; + } + } + for (const auto &[roomid, room] : rooms.leave) { + (void)room; + if (spaceOrder_.contains(QString::fromStdString(roomid))) + tagsUpdated = true; } if (tagsUpdated) diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 0d9ec66b..e4014333 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -85,8 +85,9 @@ RoomlistModel::data(const QModelIndex &index, int role) const case Roles::NotificationCount: return room->notificationCount(); case Roles::IsInvite: - case Roles::IsSpace: return false; + case Roles::IsSpace: + return room->isSpace(); case Roles::Tags: { auto info = cache::singleRoomInfo(roomid.toStdString()); QStringList list; @@ -429,7 +430,9 @@ enum NotificationImportance : short AllEventsRead = 0, NewMessage = 1, NewMentions = 2, - Invite = 3 + Invite = 3, + SubSpace = 4, + CurrentSpace = 5, }; } @@ -439,7 +442,13 @@ FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const // Returns the degree of importance of the unread messages in the room. // If sorting by importance is disabled in settings, this only ever // returns ImportanceDisabled or Invite - if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) { + if (sourceModel()->data(idx, RoomlistModel::IsSpace).toBool()) { + if (filterType == FilterBy::Space && + filterStr == sourceModel()->data(idx, RoomlistModel::RoomId).toString()) + return CurrentSpace; + else + return SubSpace; + } else if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) { return Invite; } else if (!this->sortByImportance) { return ImportanceDisabled; @@ -539,6 +548,10 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : parents) if (hiddenSpaces.contains(t)) return false; + } else if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; } return true; @@ -561,6 +574,10 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : parents) if (hiddenSpaces.contains(t)) return false; + } else if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; } return true; } else if (filterType == FilterBy::Space) { @@ -572,7 +589,11 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) .toStringList(); - if (!parents.contains(filterStr)) + if (filterStr == sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) + .toString()) + return true; + else if (!parents.contains(filterStr)) return false; else if (!hiddenTags.empty()) { for (const auto &t : tags) @@ -582,6 +603,11 @@ FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) cons for (const auto &t : parents) if (hiddenSpaces.contains(t)) return false; + } else if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool() && + !parents.contains(filterStr)) { + return false; } return true; } else { diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 99547b15..1ecb6cdf 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -320,6 +320,10 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj { lastMessage_.timestamp = 0; + if (auto create = + cache::client()->getStateEvent(room_id.toStdString())) + this->isSpace_ = create->content.type == mtx::events::state::room_type::space; + connect( this, &TimelineModel::redactionFailed, diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 3ebbe120..42aa136f 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -161,6 +161,7 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) + Q_PROPERTY(bool isSpace READ isSpace CONSTANT) Q_PROPERTY(InputBar *input READ input CONSTANT) Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged) @@ -262,6 +263,7 @@ public: RelatedInfo relatedInfo(QString id); DescInfo lastMessage() const { return lastMessage_; } + bool isSpace() const { return isSpace_; } public slots: void setCurrentIndex(int index); @@ -366,9 +368,6 @@ private: QString room_id_; - bool decryptDescription = true; - bool m_paginationInProgress = false; - QString currentId, currentReadId; QString reply_, edit_; QString textBeforeEdit, replyBeforeEdit; @@ -388,6 +387,10 @@ private: friend struct SendMessageVisitor; int notification_count = 0, highlight_count = 0; + + bool decryptDescription = true; + bool m_paginationInProgress = false; + bool isSpace_ = false; }; template -- cgit 1.5.1